]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix a race condition when running Eshell startup scripts
authorJim Porter <jporterbugs@gmail.com>
Mon, 21 Oct 2024 21:21:50 +0000 (14:21 -0700)
committerEshel Yaron <me@eshelyaron.com>
Tue, 22 Oct 2024 19:02:35 +0000 (21:02 +0200)
Previously, these scripts could run before all the Eshell modules had
fully-initialized.

* lisp/eshell/esh-mode.el (eshell-after-initialize-hook): New hook...
(eshell-mode): ... run it.

* lisp/eshell/em-script.el (eshell-run-startup-scripts): New function...
(eshell-script-initialize): ... add it to
'eshell-after-initialize-hook'.

* etc/NEWS: Announce 'eshell-after-initialize-hook'.

(cherry picked from commit 605f26cf70ab3d7c5ea635c19cd2a280812a4ddc)

etc/NEWS
lisp/eshell/em-script.el
lisp/eshell/esh-mode.el

index bda55a049ae4897f4d9df8e11b9887431d965f53..47e01ebb1d2f66c8a94794ac9f219131b288d435 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -226,6 +226,12 @@ By passing '-t' or '--timeout', you can specify a maximum time to wait
 for the processes to exit.  Additionally, you can now wait for external
 processes by passing their PIDs.
 
+---
+*** New hook 'eshell-after-initialize-hook'.
+This hook runs after an Eshell session has been fully initialized,
+immediately before running 'eshell-post-command-hook' for the first
+time.
+
 ** SHR
 
 +++
index 03d9a88e32e8ff9a581986f76ca176e1b67f5442..f426afb5d2868a315ee441d489228d68e045daa8 100644 (file)
@@ -68,22 +68,24 @@ This includes when running `eshell-command'."
                           'eshell/source)
                     eshell-interpreter-alist))
   (setq-local eshell-complex-commands
-       (append '("source" ".") eshell-complex-commands))
-  ;; these two variables are changed through usage, but we don't want
-  ;; to ruin it for other modules
-  (let (eshell-inside-quote-regexp
-       eshell-outside-quote-regexp)
-    (and (not (bound-and-true-p eshell-non-interactive-p))
-        eshell-login-script
-        (file-readable-p eshell-login-script)
-        (eshell-do-eval
-         `(eshell-commands ,(eshell--source-file eshell-login-script))
-          t))
-    (and eshell-rc-script
-        (file-readable-p eshell-rc-script)
-        (eshell-do-eval
-         `(eshell-commands ,(eshell--source-file eshell-rc-script))
-          t))))
+             (append '("source" ".") eshell-complex-commands))
+  ;; Run our startup scripts once this Eshell session has finished
+  ;; initialization.
+  (add-hook 'eshell-after-initialize-hook #'eshell-run-startup-scripts 90 t))
+
+(defun eshell-run-startup-scripts ()
+  "Run any necessary startup scripts for the current Eshell session."
+  (when (and (not (bound-and-true-p eshell-non-interactive-p))
+             eshell-login-script
+            (file-readable-p eshell-login-script))
+    (eshell-do-eval
+     `(eshell-commands ,(eshell--source-file eshell-login-script))
+     t))
+  (when (and eshell-rc-script
+            (file-readable-p eshell-rc-script))
+    (eshell-do-eval
+     `(eshell-commands ,(eshell--source-file eshell-rc-script))
+     t)))
 
 (defun eshell--source-file (file &optional args subcommand-p)
   "Return a Lisp form for executing the Eshell commands in FILE, passing ARGS.
index ead5a20bec82cf1a2b071f62d92806171ecd5de4..37a88fce790a6bf8e4fe759c0d15d0b028276b74 100644 (file)
 That is to say, the first time during an Emacs session."
   :type 'hook)
 
+(defcustom eshell-after-initialize-hook nil
+  "A hook that gets run after an Eshell session has been fully initialized."
+  :type 'hook)
+
 (defcustom eshell-exit-hook nil
   "A hook that is run whenever `eshell' is exited.
 This hook is only run if exiting actually kills the buffer."
@@ -406,7 +410,7 @@ and the hook `eshell-exit-hook'."
   (when eshell-first-time-p
     (setq eshell-first-time-p nil)
     (run-hooks 'eshell-first-time-mode-hook))
-
+  (run-hooks 'eshell-after-initialize-hook)
   (run-hooks 'eshell-post-command-hook))
 
 (put 'eshell-mode 'mode-class 'special)