dir-env-process-environment
Table of Contents
Introduction
Making shell commands is one of the great joys of emacs.
An advanced use case is that you want to set up a process environment for everything you do inside some project.
What I show here works for compile
, shell-command
, and even cider connections.
The setup
.dir-locals.el
:
((nil . ((eval progn (make-local-variable 'process-environment) (setq process-environment (copy-sequence process-environment)) (setenv "FOO" "hurr")))))
Yes, it is a bit convoluted but for a reason.
We need to copy the list, else if somebody modifies the cdr locally,
that would modify the global value.
(In the case that FOO
is an element in the list somewhere already).
The answer mentions setq-local
. I tried that without success.
Shell-command
and friends will inherit the process environmen. It pretty much just works.
From the project I currently work on:
((nil . ((eval progn (make-local-variable 'process-environment) (setq process-environment (copy-sequence process-environment)) (setenv "AWS_PROFILE" "datalake-deployer") (setq-local cider-clojure-cli-aliases (concat cider-clojure-cli-aliases ":dev"))))))
Now I start cider connections with AWS_PROFILE
set correctly.
Also I have a babashka task for deploying that needs this env and it all just works.
Non-file-buffer
By default, .dir-locals.el
does not apply to buffers without file names.
(When the local variable buffer-file-name
is not set).
There is a function hack-dir-local-variables-non-file-buffer
for this purpose.
This is called by dired
, also magit
.
I usually start processes from either a (source) file buffer or dired.
revert with grace
When you make a change to your .dir-locals
, call revert-buffer
in
whatever buffer you want to have the effect.
It hacks the local variables again for the buffer.