emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Make 'shell honor local variables


From: Juan José García-Ripoll
Subject: Make 'shell honor local variables
Date: Tue, 24 Mar 2020 23:30:05 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (windows-nt)

Hi,

I am trying to build an org-mode file with #+begin_src blocks that I
want to execute with MSYS's bash.exe. I want this to be a local choice
and for that I defined shell-file-name as a local variable, with
something like this:
   # Local Variables:
   # shell-file-name: "c:/msys64/usr/bin/bash.exe"
   # explicit-bash.exe-args: ("--noediting" "-i" "-l")
   # End:

Unfortunately, the function "shell" does not honor local variables in
the buffer where the function is invoked, because it quickly jumps to
the buffer it creates for the shell.

There is a minor fix to this, which I attach. In the new version 'shell
only switches to the buffer once it has everything computed: program
name, arguments, etc.

I believe the change is not disruptive. Could you consider it for
inclusion? If there is an alternative process for this, please let me
know.

Best,

Juanjo

-- 
Juan José García Ripoll
http://juanjose.garciaripoll.com
http://quinfog.hbar.es
diff --git a/lisp/shell.el b/lisp/shell.el
index ecebf93..4a13d22 100644
--- a/lisp/shell.el
+++ b/lisp/shell.el
@@ -736,39 +736,42 @@ shell
                    (get-buffer-create (or buffer "*shell*"))
                  ;; If the current buffer is a dead shell buffer, use it.
                  (current-buffer)))
-  ;; The buffer's window must be correctly set when we call comint
-  ;; (so that comint sets the COLUMNS env var properly).
-  (pop-to-buffer buffer)
-
-  (with-connection-local-variables
-   ;; On remote hosts, the local `shell-file-name' might be useless.
-   (when (file-remote-p default-directory)
-     (if (and (called-interactively-p 'any)
-              (null explicit-shell-file-name)
-              (null (getenv "ESHELL")))
-         (set (make-local-variable 'explicit-shell-file-name)
-              (file-local-name
-              (expand-file-name
-                (read-file-name
-                 "Remote shell path: " default-directory shell-file-name
-                 t shell-file-name))))))
-
-   ;; Rain or shine, BUFFER must be current by now.
-   (unless (comint-check-proc buffer)
-     (let* ((prog (or explicit-shell-file-name
-                      (getenv "ESHELL") shell-file-name))
-            (name (file-name-nondirectory prog))
-            (startfile (concat "~/.emacs_" name))
-            (xargs-name (intern-soft (concat "explicit-" name "-args"))))
-       (unless (file-exists-p startfile)
-         (setq startfile (concat user-emacs-directory "init_" name ".sh")))
-       (setq-local shell--start-prog (file-name-nondirectory prog))
-       (apply #'make-comint-in-buffer "shell" buffer prog
-              (if (file-exists-p startfile) startfile)
-              (if (and xargs-name (boundp xargs-name))
-                  (symbol-value xargs-name)
-                '("-i")))
-       (shell-mode))))
+
+  (if (commint-check-proc buffer)
+      (pop-to-buffer buffer)
+    ;; The determination of the shell happens in the original buffer
+    ;; so that local variables can override [explicit-]shell-file-name
+    (let* ((prog (or explicit-shell-file-name
+                     (getenv "ESHELL") shell-file-name)))
+       (with-connection-local-variables
+        ;; On remote hosts, the local `shell-file-name' might be useless.
+        (when (file-remote-p default-directory)
+          (when (and (called-interactively-p 'any)
+                     (null explicit-shell-file-name)
+                     (null (getenv "ESHELL")))
+            (setq prog (file-local-name
+                        (expand-file-name
+                         (read-file-name
+                          "Remote shell path: " default-directory 
shell-file-name
+                          t shell-file-name))))
+            (with-current-buffer buffer
+              (set (make-local-variable 'explicit-shell-file-name) prog)))))
+       (let* ((name (file-name-nondirectory prog))
+              (startfile (concat "~/.emacs_" name))
+              (xargs-name (intern-soft (concat "explicit-" name "-args")))
+              (args (if (and xargs-name (boundp xargs-name))
+                        (symbol-value xargs-name)
+                      '("-i"))))
+         (unless (file-exists-p startfile)
+           (setq startfile (concat user-emacs-directory "init_" name ".sh"))
+           (unless (file-exists-p startfile)
+             (setq startfile nil)))
+         ;; The buffer's window must be correctly set when we call comint
+         ;; (so that comint sets the COLUMNS env var properly).
+         (pop-to-buffer buffer)
+         (setq-local shell--start-prog (file-name-nondirectory prog))
+         (apply #'make-comint-in-buffer "shell" buffer prog startfile args)
+         (shell-mode))))
   buffer)

 ;;; Directory tracking

reply via email to

[Prev in Thread] Current Thread [Next in Thread]