envel
is a utility to record environment variables in a form that can be
easily read by Emacs. It’s written in C++ so that it can be run during shell
initialization without noticable impact.
It’s used to make Emacs load shell environment variables even when it is not launched from a shell. See this article for an explanation.
You need a recent version of cmake
and a C++ compiler to compile envel
:
scripts/configure-release
scripts/build
Then copy build/src/gen-envel
to a directory in your $PATH
, for example
~/.local/bin
.
Add the following to your shell initialization file (assuming gen-envel
is
in your $PATH
). Change the --vars=
list to the variables you need in
Emacs.
if command -v gen-envel >/dev/null 2>&1; then
gen-envel --vars PATH http_proxy https_proxy all_proxy SSH_AUTH_SOCK \
SSH_AGENT_PID --output ~/.emacs.d/.local/env.el
fi
Add the following snippet to your Emacs initialization file:
(defun load-env-file (file)
"Read and set envvars from FILE."
(if (null (file-exists-p file))
(signal 'file-error
(list "No envvar file exists." file
"See https://github.com/hjiang/envel."))
(with-temp-buffer
(insert-file-contents file)
(when-let (env (read (current-buffer)))
(let ((tz (getenv-internal "TZ")))
(setq-default
process-environment
(append env (default-value 'process-environment))
exec-path
(append (split-string (getenv "PATH") path-separator t)
(list exec-directory))
shell-file-name
(or (getenv "SHELL")
(default-value 'shell-file-name)))
(when-let (newtz (getenv-internal "TZ"))
(unless (equal tz newtz)
(set-time-zone-rule newtz))))
env))))
(let ((env-file "~/.emacs.d/.local/env.el"))
(when (file-readable-p env-file)
(defun reload-env ()
"Reload environment variables"
(interactive)
(load-env-file env-file))
(reload-env)))
If ~/.emacs.d/.local/
does not exist, you have to create it first. During a
long-running Emacs session, you can use M-x reload-env
to reload the env file.