Emacs: Environment Variables
This page shows you how to set environment variables in emacs, especially if you have problems in Windows emacs of getting linux commands to run.
where emacs gets environment variable
Windows
- Emacs inherit environment variables, regardless starting from terminal or clicking icon in GUI. (perm env var is stored in the Registry. 〔see Windows Environment Variable Tutorial〕).
- You can start emacs from PowerShell. Like this
~/bin/emacs-28.1/bin/runemacs.exe
Mac
- If emacs is started from a text terminal, it inherits shell's environment variables.
- If emacs is started from clicking icon in GUI, it does not inherit environment variables from your shell, but does inherit the environment variables from
~/.MacOSX/environment.plist
. - You can start emacs from shell, like this:
/Applications/Emacs.app/Contents/MacOS/Emacs &
Linux
- If emacs is started from a text terminal, it inherits shell's environment variables.
- On linux, you should not start emacs from clicking icon created by the linux desktop. If you want to click icon to launch emacs, create a bash script that launch emacs. That way, it'll inherit environment variable. Or, best, setup a key to launch emacs.
Get Environment Variable Within Emacs
;; get value of env var PATH (getenv "PATH")
〔see Evaluate Emacs Lisp Code〕
Set Environment Variable within Emacs
You can set environment variables within emacs.
This lets emacs to have environment variables independent of the operating system.
;; set env var PATH, by appending a new path to existing PATH value (setenv "PATH" (concat "C:/cygwin/usr/local/bin" path-separator "C:/cygwin/usr/bin" path-separator "C:/cygwin/bin" path-separator (getenv "PATH")))
- You can use slash
/
for dir separator, works in Microsoft Windows too. - Dir path may end with a path separator
/
, or without. - The builtin variable path-separator can be used instead of
;
.
Emacs exec-path
Emacs has a variable named exec-path. Its value is a list of dir paths. Emacs uses exec-path to find executable binary programs.
For example,
- Alt+x
diff
tries to find unixdiff
- Alt+x
grep
tries to find unixgrep
- Alt+x
shell
tries to find unixbash
if emacs is on linux. - Alt+x
dired-do-compress
tries to find unixgzip
- Alt+x
ispell-word
tries to find unixispell
oraspell
If emacs complains that it cannot find these programs, the problem is probably with your exec-path.
By default, emacs copies the value of (getenv "PATH")
to exec-path. So, their values should be identical.
Here's a example of setting exec-path:
(when (eq system-type 'windows-nt) (setq exec-path '( "C:/Program Files (x86)/Emacs/emacs/bin/" "C:/Program Files (x86)/Emacs/EmacsW32/gnuwin32/bin/" "C:/Windows/system32/" "C:/Windows/" "C:/Windows/System32/Wbem/" "C:/Windows/system32/WindowsPowerShell/v1.0/" )))
〔see Elisp: Get System Info〕
Difference between exec-path and PATH
- The value of environment variable “PATH” is used by emacs when you are trying to call a linux command from a shell in emacs.
- The exec-path is used by emacs itself to find programs it needs for its features, such as spell checking, file compression, compiling, grep, diff, etc.
The value of (getenv "PATH")
and exec-path do not need to be the same.
Emacs Lisp Code for Setting PATH and exec-path
Here's emacs lisp code template to set both PATH and exec-path in sync.
(when (eq system-type 'windows-nt) (let ((xPaths '( "C:/Python27" "C:/strawberry/c/bin" "C:/strawberry/perl/site/bin" "C:/strawberry/perl/bin" "C:/Program Files (x86)/nodejs/" "C:/cygwin/usr/local/bin" "C:/cygwin/usr/bin" "C:/cygwin/bin" ))) (setenv "PATH" (mapconcat 'identity xPaths ";")) (setq exec-path (append xPaths (list "." exec-directory)))))
Reference
2012-07-31 Thanks to Steve Purcell ❮https://twitter.com/sanityinc❯ for path-separator.