3

I'm using emacs for many different projects. For some of them, I need, for example, different entries in $PATH, or different $MAKEFLAGS, whatever, you name it...

I thought this would be possible somehow like this in .dir-locals:

((c++-mode
  (c-basic-offset . 4)
  (tab-width . 4)
  (eval progn
          (make-local-variable 'process-environment)
          (setenv "gna" "gnagna3")))
 (c-mode
  (c-basic-offset . 4)
  (tab-width . 4)))

Bit with this approach, "gna" is set in all buffers.

What am I missing?

3

Both the buffer-local and the global variable are initially pointing to the same cons cell / list. If setenv pushes a new value to the front of the list, that would only be reflected in the local list value (the global value would effectively point to the cdr of the local value) in which case your code should work as desired; however if setenv is modifying an existing element further down the list, that change will be reflected in both values.

You can avoid this by making a copy of the list.

(eval . (progn
          (make-local-variable 'process-environment)
          (setq process-environment (copy-sequence process-environment))
          (setenv "gna" "gnagna3")))

You could also shorten that by using setq-local

  • Of course, if you do this, it will cause problems, at least it did for me. If you start a shell from a buffer that has a buffer-local process-environment the sell will not inherit your changes to the process-environment. See emacs.stackexchange.com/questions/45563/…. – Ben Key Nov 14 '18 at 5:17
  • That is because in general non-file-visiting buffers do not see directory-local variables. So it's not that this approach is "causing problems", but rather that it's not having any effect in the shell buffer. I've added an answer to the linked question. – phils Nov 14 '18 at 6:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.