diff --git a/docs/changelog.rst b/docs/changelog.rst index b48d6f92b..0be59d85e 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -12,6 +12,9 @@ To update |kitty|, :doc:`follow the instructions `. keymaps on new keyboard events that only change geometry (:iss:`2787`). Better handling of multiple keyboards with incompatible layouts (:iss:`2726`) +- macOS: Fix the LC_TYPE env var being set to UTF-8 on systems in which the + language and country code do not form a valid locale (:iss:`1233`) + 0.18.1 [2020-06-23] -------------------- diff --git a/kitty/child.py b/kitty/child.py index dfdeab985..2230cb1d1 100644 --- a/kitty/child.py +++ b/kitty/child.py @@ -210,6 +210,8 @@ class Child: env: Optional[Dict[str, str]] = getattr(self, '_final_env', None) if env is None: env = self._final_env = default_env().copy() + if is_macos and env.get('LC_CTYPE') == 'UTF-8' and not sys._xoptions.get('lc_ctype_before_python'): + del env['LC_CTYPE'] env.update(self.env) env['TERM'] = self.opts.term env['COLORTERM'] = 'truecolor' diff --git a/launcher.c b/launcher.c index 090564693..443aeade3 100644 --- a/launcher.c +++ b/launcher.c @@ -42,14 +42,18 @@ safe_realpath(const char* src, char *buf, size_t buf_sz) { #endif static inline void -set_bundle_exe_dir(const wchar_t *exe_dir) { +set_xoptions(const wchar_t *exe_dir, const char *lc_ctype) { wchar_t buf[PATH_MAX+1] = {0}; swprintf(buf, PATH_MAX, L"bundle_exe_dir=%ls", exe_dir); PySys_AddXOption(buf); + if (lc_ctype) { + swprintf(buf, PATH_MAX, L"lc_ctype_before_python=%ls", lc_ctype); + PySys_AddXOption(buf); + } } #ifdef FOR_BUNDLE -static int run_embedded(const char* exe_dir_, const char *libpath, int argc, wchar_t **argv) { +static int run_embedded(const char* exe_dir_, const char *libpath, int argc, wchar_t **argv, const char *lc_ctype) { int num; Py_NoSiteFlag = 1; Py_FrozenFlag = 1; @@ -62,7 +66,7 @@ static int run_embedded(const char* exe_dir_, const char *libpath, int argc, wch int ret = 1; wchar_t *exe_dir = Py_DecodeLocale(exe_dir_, NULL); if (exe_dir == NULL) { fprintf(stderr, "Fatal error: cannot decode exe_dir\n"); return 1; } - set_bundle_exe_dir(exe_dir); + set_xoptions(exe_dir, lc_ctype); wchar_t stdlib[PATH_MAX+1] = {0}; #ifdef __APPLE__ const char *python_relpath = "../Resources/Python/lib"; @@ -96,11 +100,11 @@ end: return ret; } #else -static int run_embedded(const char* exe_dir_, const char *libpath, int argc, wchar_t **argv) { +static int run_embedded(const char* exe_dir_, const char *libpath, int argc, wchar_t **argv, const char *lc_ctype) { (void)libpath; wchar_t *exe_dir = Py_DecodeLocale(exe_dir_, NULL); if (exe_dir == NULL) { fprintf(stderr, "Fatal error: cannot decode exe_dir: %s\n", exe_dir_); return 1; } - set_bundle_exe_dir(exe_dir); + set_xoptions(exe_dir, lc_ctype); #ifdef FROM_SOURCE PySys_AddXOption(L"kitty_from_source=1"); #endif @@ -155,6 +159,10 @@ read_exe_path(char *exe, size_t buf_sz) { int main(int argc, char *argv[]) { char exe[PATH_MAX+1] = {0}; + const char *lc_ctype = NULL; +#ifdef __APPLE__ + lc_ctype = getenv("LC_CTYPE"); +#endif if (!read_exe_path(exe, sizeof(exe))) return 1; char *exe_dir = dirname(exe); @@ -182,7 +190,9 @@ int main(int argc, char *argv[]) { ret = 1; goto end; } } - ret = run_embedded(exe_dir, lib, num_args, argvw); + if (lc_ctype) lc_ctype = strdup(lc_ctype); + ret = run_embedded(exe_dir, lib, num_args, argvw, lc_ctype); + if (lc_ctype) free((void*)lc_ctype); end: for (i = 0; i < num_args; i++) { if(argvw[i]) PyMem_RawFree(argvw[i]); } return ret;