aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Porter2024-10-21 14:21:50 -0700
committerJim Porter2024-10-21 14:21:50 -0700
commit605f26cf70ab3d7c5ea635c19cd2a280812a4ddc (patch)
tree5970d844fe2e18c0f715e34db9ef5b9e26d2dd1b
parent1f8fbae8df764e9d24f1b824de7369d82e36abae (diff)
downloademacs-605f26cf70ab3d7c5ea635c19cd2a280812a4ddc.tar.gz
emacs-605f26cf70ab3d7c5ea635c19cd2a280812a4ddc.zip
Fix a race condition when running Eshell startup scripts
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'.
-rw-r--r--etc/NEWS6
-rw-r--r--lisp/eshell/em-script.el34
-rw-r--r--lisp/eshell/esh-mode.el6
3 files changed, 29 insertions, 17 deletions
diff --git a/etc/NEWS b/etc/NEWS
index cfc5a8e1785..3a8ee7ccacb 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -276,6 +276,12 @@ By passing '-t' or '--timeout', you can specify a maximum time to wait
276for the processes to exit. Additionally, you can now wait for external 276for the processes to exit. Additionally, you can now wait for external
277processes by passing their PIDs. 277processes by passing their PIDs.
278 278
279---
280*** New hook 'eshell-after-initialize-hook'.
281This hook runs after an Eshell session has been fully initialized,
282immediately before running 'eshell-post-command-hook' for the first
283time.
284
279** SHR 285** SHR
280 286
281+++ 287+++
diff --git a/lisp/eshell/em-script.el b/lisp/eshell/em-script.el
index 03d9a88e32e..f426afb5d28 100644
--- a/lisp/eshell/em-script.el
+++ b/lisp/eshell/em-script.el
@@ -68,22 +68,24 @@ This includes when running `eshell-command'."
68 'eshell/source) 68 'eshell/source)
69 eshell-interpreter-alist)) 69 eshell-interpreter-alist))
70 (setq-local eshell-complex-commands 70 (setq-local eshell-complex-commands
71 (append '("source" ".") eshell-complex-commands)) 71 (append '("source" ".") eshell-complex-commands))
72 ;; these two variables are changed through usage, but we don't want 72 ;; Run our startup scripts once this Eshell session has finished
73 ;; to ruin it for other modules 73 ;; initialization.
74 (let (eshell-inside-quote-regexp 74 (add-hook 'eshell-after-initialize-hook #'eshell-run-startup-scripts 90 t))
75 eshell-outside-quote-regexp) 75
76 (and (not (bound-and-true-p eshell-non-interactive-p)) 76(defun eshell-run-startup-scripts ()
77 eshell-login-script 77 "Run any necessary startup scripts for the current Eshell session."
78 (file-readable-p eshell-login-script) 78 (when (and (not (bound-and-true-p eshell-non-interactive-p))
79 (eshell-do-eval 79 eshell-login-script
80 `(eshell-commands ,(eshell--source-file eshell-login-script)) 80 (file-readable-p eshell-login-script))
81 t)) 81 (eshell-do-eval
82 (and eshell-rc-script 82 `(eshell-commands ,(eshell--source-file eshell-login-script))
83 (file-readable-p eshell-rc-script) 83 t))
84 (eshell-do-eval 84 (when (and eshell-rc-script
85 `(eshell-commands ,(eshell--source-file eshell-rc-script)) 85 (file-readable-p eshell-rc-script))
86 t)))) 86 (eshell-do-eval
87 `(eshell-commands ,(eshell--source-file eshell-rc-script))
88 t)))
87 89
88(defun eshell--source-file (file &optional args subcommand-p) 90(defun eshell--source-file (file &optional args subcommand-p)
89 "Return a Lisp form for executing the Eshell commands in FILE, passing ARGS. 91 "Return a Lisp form for executing the Eshell commands in FILE, passing ARGS.
diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el
index ead5a20bec8..37a88fce790 100644
--- a/lisp/eshell/esh-mode.el
+++ b/lisp/eshell/esh-mode.el
@@ -90,6 +90,10 @@
90That is to say, the first time during an Emacs session." 90That is to say, the first time during an Emacs session."
91 :type 'hook) 91 :type 'hook)
92 92
93(defcustom eshell-after-initialize-hook nil
94 "A hook that gets run after an Eshell session has been fully initialized."
95 :type 'hook)
96
93(defcustom eshell-exit-hook nil 97(defcustom eshell-exit-hook nil
94 "A hook that is run whenever `eshell' is exited. 98 "A hook that is run whenever `eshell' is exited.
95This hook is only run if exiting actually kills the buffer." 99This hook is only run if exiting actually kills the buffer."
@@ -406,7 +410,7 @@ and the hook `eshell-exit-hook'."
406 (when eshell-first-time-p 410 (when eshell-first-time-p
407 (setq eshell-first-time-p nil) 411 (setq eshell-first-time-p nil)
408 (run-hooks 'eshell-first-time-mode-hook)) 412 (run-hooks 'eshell-first-time-mode-hook))
409 413 (run-hooks 'eshell-after-initialize-hook)
410 (run-hooks 'eshell-post-command-hook)) 414 (run-hooks 'eshell-post-command-hook))
411 415
412(put 'eshell-mode 'mode-class 'special) 416(put 'eshell-mode 'mode-class 'special)