为什么我的 ESS R 会话会退回到 C 语言环境?

Why does my ESS R session fall back to C locale?

我正在 OSX Yosemite 运行宁 Emacs 24.5 和 R 3.2

我的 ~/.bash_profile:

里有这个
export LANG=en_US.UTF-8
export LANGUAGE=en_US:en
export LC_CTYPE="en_US.UTF-8"
export LC_NUMERIC="en_US.UTF-8"
export LC_TIME="en_US.UTF-8"
export LC_COLLATE="en_US.UTF-8"
export LC_MONETARY="en_US.UTF-8"
export LC_MESSAGES="en_US.UTF-8"
export LC_PAPER="en_US.UTF-8"
export LC_NAME="en_US.UTF-8"
export LC_ADDRESS="en_US.UTF-8"
export LC_TELEPHONE="en_US.UTF-8"
export LC_MEASUREMENT="en_US.UTF-8"
export LC_IDENTIFICATION="en_US.UTF-8"
export LC_ALL=en_US.UTF-8

在我的 emacs 设置中:

(setq current-language-environment "UTF-8")

(add-hook 'ess-R-post-run-hook
      (lambda () (set-buffer-process-coding-system
                  'utf-8-nfd-unix 'utf-8-nfd-unix)))

我什至在系统范围内设置了以下内容:

defaults write org.R-project.R force.LANG en_US.UTF-8

当我从命令行或 RStudio 运行 R 时,它使用正确的语言环境。但是,当我在 emacs 中 运行 一个 R 进程时,我收到以下警告:

During startup - Warning messages:
1: Setting LC_CTYPE failed, using "C" 
2: Setting LC_COLLATE failed, using "C" 
3: Setting LC_TIME failed, using "C" 
4: Setting LC_MESSAGES failed, using "C" 
5: Setting LC_MONETARY failed, using "C" 

并且任何非 ASCII 字符的格式不正确都会产生错误。如何设置正确的语言环境?

好的,所以问题不在 Emacs、ESS 或 R 中,而是在 OSX 中通过 launchd 启动的进程不继承 .profile、.bash_profile 或 .bashrc 中的任何环境变量.相反,必须通过 launchd 设置环境。

这样做解决了我的问题:

/bin/launchctl setenv LANG en_US.UTF-8
/bin/launchctl setenv LC_ALL en_US.UTF-8
/bin/launchctl setenv LC_CTYPE en_US.UTF-8
/bin/launchctl setenv LC_COLLATE en_US.UTF-8
/bin/launchctl setenv LC_MESSAGES en_US.UTF-8
/bin/launchctl setenv LC_TIME en_US.UTF-8
/bin/launchctl setenv LC_MONETARY en_US.UTF-8

要在重新启动后保留环境变量,请在 /Library/LaunchDaemons/ 中添加一个条目 (OSX > 10.9)。 对于早期版本,将其添加到 /etc/launchd.conf 中。

以上将为通过 launchd 启动的 所有 进程设置环境变量。如果这是不可取的,可以在单个 .app 文件中编辑 Info.plist 文件,并将变量设置为字典中的键值,键为 LSEnvironment

例如,为了解决 Emacs 中的问题,我编辑了文件:

/usr/local/Cellar/emacs/24.5/Emacs.app/Contents/Info.plist

在顶级字典中添加以下条目:

<key>LSEnvironment</key>
<dict>
  <key>LANG</key>
  <string>en_US.UTF-8</string>
  <key>LC_ALL</key>
  <string>en_US.UTF-8</string>
  <key>LC_CTYPE</key>
  <string>en_US.UTF-8</string>
  <key>LC_COLLATE</key>
  <string>en_US.UTF-8</string>
  <key>LC_PAPER</key>
  <string>en_US.UTF-8</string>
  <key>LC_ADDRESS</key>
  <string>en_US.UTF-8</string>
  <key>LC_MONETARY</key>
  <string>en_US.UTF-8</string>
  <key>LC_NUMERIC</key>
  <string>en_US.UTF-8</string>
  <key>LC_TELEPHONE</key>
  <string>en_US.UTF-8</string>
  <key>LC_MESSAGES</key>
  <string>en_US.UTF-8</string>
  <key>LC_IDENTIFICATION</key>
  <string>en_US.UTF-8</string>
  <key>LC_MEASUREMENT</key>
  <string>en_US.UTF-8</string>
  <key>LC_TIME</key>
  <string>en_US.UTF-8</string>
  <key>LC_NAME</key>
  <string>en_US.UTF-8</string>
</dict>

(当然不是所有的变量都是严格要求的)

我刚发现你只需要添加

(unless (getenv "LANG") (setenv "LANG" "en_US.UTF-8"))

到您的 .emacs.el 文件。

这会在 emacs 中设置环境变量 LANG(如果尚未设置的话)。这似乎是 R.

所需要的全部

这是一种侵入性小得多的方法,可以在 emacs 中使用。