1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-30 20:32:00 -08:00

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'.
This commit is contained in:
Jim Porter 2024-10-21 14:21:50 -07:00
parent 1f8fbae8df
commit 605f26cf70
3 changed files with 29 additions and 17 deletions

View file

@ -276,6 +276,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
+++

View 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.

View file

@ -90,6 +90,10 @@
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)