From 33e97ff350e1184f97c2867bd689a77291a2c7fd Mon Sep 17 00:00:00 2001 From: Davide Masserut Date: Wed, 30 Aug 2023 21:34:08 +0200 Subject: [PATCH] Display the exit code if the last command failed in Eshell * doc/misc/eshell.texi (Invocation): Document change. * etc/NEWS: Announce change. * lisp/eshell/esh-io.el (eshell-last-command-status): Make it buffer-local. * lisp/eshell/esh-mode.el (compile): Require it for a face. (eshell-mode): Update mode-line-process based on the exit code of the last command. * test/lisp/eshell/esh-io-tests.el (eshell) (esh-io-test/modeline-after-failure): Add test. --- doc/misc/eshell.texi | 3 +++ etc/NEWS | 3 +++ lisp/eshell/esh-io.el | 2 +- lisp/eshell/esh-mode.el | 12 ++++++++++++ test/lisp/eshell/esh-io-tests.el | 16 ++++++++++++++++ 5 files changed, 35 insertions(+), 1 deletion(-) diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index f8f60bae13a..b544e0cda41 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi @@ -234,6 +234,9 @@ Invocation can be controlled the same way as any other background process in Emacs. +If a command exits abnormally, Eshell displays the command's exit code +on the mode line. + @subsection Command form Command form looks much the same as in other shells. A command consists of arguments separated by spaces; the first argument is the diff --git a/etc/NEWS b/etc/NEWS index 9a98db8c83a..fe81cfc2477 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -370,6 +370,9 @@ to load the edited aliases. Running 'rgrep' in Eshell now uses the Emacs grep facility instead of calling external rgrep. ++++ +*** If a command exits abnormally, Eshell now displays the command's exit code on the mode line. + ** Pcomplete --- diff --git a/lisp/eshell/esh-io.el b/lisp/eshell/esh-io.el index c07f871dd37..cd0cee6e21d 100644 --- a/lisp/eshell/esh-io.el +++ b/lisp/eshell/esh-io.el @@ -170,7 +170,7 @@ eshell-redirection-operators-alist (defvar eshell-current-handles nil) -(defvar eshell-last-command-status 0 +(defvar-local eshell-last-command-status 0 "The exit code from the last command. 0 if successful.") (defvar eshell-last-command-result nil diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el index 0c381dbb86a..71ff901c764 100644 --- a/lisp/eshell/esh-mode.el +++ b/lisp/eshell/esh-mode.el @@ -69,6 +69,8 @@ (require 'esh-util) (require 'esh-var) +(require 'compile) + (defgroup eshell-mode nil "This module contains code for handling input from the user." :tag "User interface" @@ -369,6 +371,16 @@ eshell-mode ;; strong R2L character. (setq bidi-paragraph-direction 'left-to-right) + (setq-local + mode-line-process + '(:eval + (when (> eshell-last-command-status 0) + (propertize + (format ":[%s]" eshell-last-command-status) + 'help-echo (format "Last command exited with code %s" + eshell-last-command-status) + 'face 'compilation-mode-line-fail)))) + ;; load extension modules into memory. This will cause any global ;; variables they define to be visible, since some of the core ;; modules sometimes take advantage of their functionality if used. diff --git a/test/lisp/eshell/esh-io-tests.el b/test/lisp/eshell/esh-io-tests.el index ce80f3a8f08..349c4332d82 100644 --- a/test/lisp/eshell/esh-io-tests.el +++ b/test/lisp/eshell/esh-io-tests.el @@ -23,6 +23,7 @@ (require 'ert-x) (require 'esh-mode) (require 'eshell) +(require 'compile) (require 'eshell-tests-helpers (expand-file-name "eshell-tests-helpers" @@ -370,4 +371,19 @@ esh-io-test/virtual/dev-kill (eshell-insert-command "echo three >> /dev/kill") (should (equal (car kill-ring) "twothree")))) +(ert-deftest esh-io-test/modeline-after-failure () + "Check that exit code is displayed after a failure." + (with-temp-eshell + (let ((debug-on-error nil)) + (eshell-insert-command "(zerop \"foo\")")) ; A failed command. + (should (equal-including-properties + mode-line-process + '(:eval + (when (> eshell-last-command-status 0) + (propertize + (format ":[%s]" eshell-last-command-status) + 'help-echo (format "Last command exited with code %s" + eshell-last-command-status) + 'face 'compilation-mode-line-fail))))))) + ;;; esh-io-tests.el ends here -- 2.42.0