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

2

5

I'm on OSX Yosemite running Emacs 24.5 and R 3.2

I have this in my ~/.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

this in my emacs settings:

(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)))

And I've even set the following system-wide:

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

When I run R from the command line or in RStudio, it uses the correct locale. When I run an R process in emacs though, I get the following warning:

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" 

And any non-ASCII characters are malformed producing errors. How can I set the correct locale?

Eocene answered 15/5, 2015 at 16:33 Comment(1)
The problem doesn't appear when running Emacs from Terminal, which led me to the solution, see belowEocene
E
6

Ok, so the problem is not in Emacs, ESS or R it is that in OSX processes launched through launchd do not inherit any environment variables in .profile, .bash_profile or .bashrc. Instead, one must set the environment through launchd.

Doing this solved my problem:

/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

To persist the environment variables across reboots, add an entry in /Library/LaunchDaemons/ (OSX > 10.9). For earlier versions add it in /etc/launchd.conf instead.

The above will set the environment variables for all processes started via launchd. If this is not desirable one can edit the Info.plist file in an individual .app file and set the variables as key-values in a dict with key LSEnvironment

For example, to solve the problem in Emacs I edited the file:

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

Adding the following entry in the top-level dict:

<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>

(Not all variables are strictly required of course)

Eocene answered 16/5, 2015 at 6:14 Comment(1)
Would just setting the variables on emacs do the trick? like so ";; -- environment set (setenv "LANG" "UTF-8") (setenv "LC_CTYPE" "UTF-8") (setenv "LC_NUMERIC" "UTF-8") (setenv "LC_TIME" "UTF-8") (setenv "LC_COLLATE" "UTF-8") (setenv "LC_MONETARY" "UTF-8") (setenv "LC_MESSAGES" "UTF-8")Fugato
C
3

I just found out that you just have to add

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

to your .emacs.el file.

This sets the environmental variable LANG in emacs if it is not set already. This seems to be all that is required by R.

This is a much less intrusive approach and works from within emacs.

Calen answered 23/10, 2015 at 11:48 Comment(1)
Adding additional (unless (getenv "LC_ALL") (setenv "LC_ALL" "en_US.UTF-8")) works for me.Tug

© 2022 - 2024 — McMap. All rights reserved.