I often use subordinate shells within Emacs. (I instantiate these shells with M-x shell.)

I put all these shells under auto-save-mode (through my shell-mode-hook; see below).

Is there some way that I can have Emacs set an environment variable in a subordinate shell equal to the value of buffer-auto-save-file-name?

For what it's worth, below is the hook code I use to put my subordinate shells under auto-save-mode:

;; NB: I define the global variable auto-saves-dir elsewhere in my init file.

(defun cd-to-auto-saves-dir ()
  (unless (file-directory-p auto-saves-dir)
    (make-directory auto-saves-dir t))
  (cd auto-saves-dir))

    (lambda ()    
        ;; the silliness with cd-ing to/fro auto-saves-dir is the
        ;; only way I've found to trick Emacs into putting the
        ;; auto-save'd file in auto-saves-dir
        (let ((orig-dir default-directory))
           (cd orig-dir))
  • 1
    I hack comint-exec-1 to create a custom buffer-local process-environment containing the environmental variables that I like. You might want to consider doing something similar.
    – lawlist
    Nov 23, 2016 at 19:48
  • 1
    By the way, (let ((default-directory auto-saves-dir)) (auto-save-mode)) should work fine, assuming auto-saves-dir exists.
    – npostavs
    Mar 1, 2017 at 20:10

4 Answers 4


After (re)reading the code of the shell function, here's what I'd do:

(advice-add 'make-comint-in-buffer :around

(defun my-enable-auto-save-in-shell (origfun procname &rest args)
  (if (not (equal procname "shell"))
      (apply origfun procname args)   ;; Not a shell, nothing to do.
    ;; Enable auto-save-mode.
    (let ((default-directory auto-saves-dir)) (auto-save-mode))
    ;; Pass the auto-save file name to the subprocess.
    (let ((process-environment
           `(,(concat "EMACS_AUTO_SAVE_FILE_NAME="
             . ,process-environment)))
      (apply origfun procname args))))

You can use the with-environment-variables macro.

(let ((buffer-auto-save-file-name "test-file.txt"))
  (with-environment-variables (("BUFFER_AUTO_SAVE_FILE_NAME" buffer-auto-save-file-name))

Add the following to the end of your lambda() routine:

(goto-char (point-max))
(insert (concat "export EMACS_AS_FILE=" buffer-auto-save-file-name))

The shell command to assign your variable will automatically appear on the command line; simply hit enter to set it.

(let ((process-environment
       `(,(concat "BUFFER_AUTO_SAVE_FILE_NAME="
  • I don't think this will cut it because this uses the buffer-auto-save-file-name of the buffer from which we run shell not the value inside that buffer.
    – Stefan
    Mar 7, 2017 at 14:47
  • Yeah, right. 34
    – politza
    Mar 7, 2017 at 16:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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