emacs-mac 在英文语言但是中国时区时的 macOS 上的一个坑

emacs-mac 从 macOS 系统获取到一个非法的 en_CN.UTF-8 作为 LANG,这对于 fish、sh、bash 等都是非法的,导致在 emacs vterm 里 shell 提示符输入中文会乱码。

解决办法很简单,在 ~/.doom.d/config.el 里加一句 (setenv "LANG" "en_US.UTF-8") 即可。

看了一下,我这没有你这个问题。也是英文+中文时区。 我看这个 locale 根本不存在,我感觉是不是你装的什么软件导致的。

你可能是在某个 terminal emulator 里启动的 Emacs 从而继承了 terminal emulator 或者 bashrc 之类设定的 LANG、LC_* 设置,或者 ~/.emacs* 啥地方设置了(比如 spacemacs 和 doom emacs 都有 env file)?? 你试试把 ~/.emacs* 全重命名,然后在 spotlight 启动 Emacs,然后 M-x eshell 里执行 locale 看看。

这个 en_CN 是 macOS 自己的,如果你的输出不是这样的,那么就不会中招。

$ defaults read | grep en_CN
        AppleLocale = "en_CN";
            "en_CN",
        AppleLocale = "en_CN";
        AppleLocale = "en_CN";
            "en_CN"
                url = "https://api-glb-sel.smoot.apple.com/qi_features_url?locale=en_CN&version=00000000000000000000000000000014";
        OSLocale = "en_CN";
        OSLocale = "en_CN";
        OSLocale = "en_CN";
        OSLocale = "en_CN";
        OSLocale = "en_CN";
        OSLocale = "en_CN";

我就是用 alfred 启动的。

defaults read | grep en_CN
            "en_CN",

 defaults read | grep en_US
        AppleLocale = "en_US";
            "en_US",
            Locale = "en_US";
                "en_US",
                        "en_US" = "Add to TickTick";
                        "en_US" = "Create Service";
                        "en_US" = "Create Workflow";
                        "en_US" = "Send File To Bluetooth Device";
                        "en_US" = "$^@C";
                        "en_US" = "Convert Text to Traditional Chinese";
                        "en_US" = "$^~@C";
                        "en_US" = "Convert Text to Simplified Chinese";
                        "en_US" = "Convert Text to Full Width";
                        "en_US" = "Convert Text to Half Width";
                        "en_US" = "Look Up in Dictionary";
                        "en_US" = "Folder Actions Setup\\U2026";
                        "en_US" = "Font Book/Create Font Library From Text";
                        "en_US" = "Font Book/Create Collection From Text";
                        "en_US" = "Font Book/Display Font Information";
                        "en_US" = "Preview/Open images";
                        "en_US" = "Encode Selected Audio Files";
                        "en_US" = "Search With %WebSearchProvider@";
                        "en_US" = "Add to Reading List";
                        "en_US" = "Script Editor/Make New AppleScript";
                        "en_US" = "Script Editor/Run as AppleScript";
                        "en_US" = "*";
                        "en_US" = "Script Editor/Get Result of AppleScript";
                        "en_US" = Spotlight;
                        "en_US" = Y;
                        "en_US" = "Make New Sticky Note";
                        "en_US" = Summarize;
                        "en_US" = "New Terminal at Folder";
                        "en_US" = "New Terminal Tab at Folder";
                        "en_US" = "Open man Page in Terminal";
                        "en_US" = "Search man Page Index in Terminal";
                        "en_US" = "New TextEdit Window Containing Selection";
                        "en_US" = "Open Selected File in TextEdit";
                        "en_US" = "Finder/Open";
                        "en_US" = "Finder/Show in Finder";
                        "en_US" = "Finder/Show Info in Finder";
                        "en_US" = "Mail/New Email With Selection";
                        "en_US" = "Mail/New Email To Address";
                        "en_US" = "Add to Music as a Spoken Track";
                        "en_US" = "Encode Selected Video Files";
                        "en_US" = "Set Desktop Picture";
                        "en_US" = "Show Map";
                        "en_US" = "Speech/Start Speaking Text";
                        "en_US" = "Speech/Stop Speaking";
                        "en_US" = "Open URL";
        AppleLocale = "en_US";
        AppleLocale = "en_US";
        loc = "en_US:US";
                url = "https://api-aka.smoot.apple.com/lookup_hints_url/en_US/monthly.json?disable=1&version=51";
                url = "https://api-aka.smoot.apple.com/lookup_hints_url/en_US/weekly.json?disable=1&version=51";
                url = "https://api-aka.smoot.apple.com/qi_features_url?locale=en_US&version=00000000000000000000000000000014";

另外,我的配置是基于 prelude emacs 的。不是 doom 或者 spacemacs.

1赞

我之前也遇到过这个问题,但我系统设置的语言是中文,终端设置的是英文。终端下正常,GUI 就会有字符显示问题。

我标题说的不对,是「中国地区」,不是「中国时区」。

你的 region 设置的 US,所以你的 AppleLocale 是 en_US,而我的 Region 是 China Mainland,所以我的 AppleLocale 是 en_CN,后者不是个合法的 locale。

终端模拟器会有自己的设置,能改 locale,另外你 shell 的 profile、rc 之类初始化文件也可能改 locale。

看起来 en_CN 这个奇葩 locale 是这么来的:en 是你的首选语言(preferred language),CN 是你的地区(region),本来是合乎规则的,比如 en_GB 和 en_US 就是英式英语和美式英语,但是并不存在 en_CN 这样的「中式英语」:rofl:

这个提到 set-locale-system,看起来是设置 Emacs 自己 locale 的推荐方式,它会自动从 LC_ALL, LC_CTYPE, LANG 优先级获取(优先级依次降低),如果没找到的话,不知道它啥逻辑获取的。

实际上我的都是中文优先,不过还是 en_CN :joy:

最后我是通过 exec-path-from-shell 这个插件里的一个函数解决的

这很神奇,你这种配置应该是 zh_CN 才对。

用 (setenv “LANG” “zh_CN.UTF-8”) 加上(set-locale-environment “zh_CN.UTF-8”) 应该是最完备的了,把 Emacs 的子进程和 Emacs 自己的 locale 设置都显式设置了。

有点奇怪的是 (set-locale-environment “zh_CN.UTF-8”) 后,Emacs 用的 language environment 居然是 Chinese-GBK,似乎 Mule 选择 language environment 只看 locale 中 encoding 前面的部分。

1赞