Subject: bug#41370: 27.0.91; Eshell and exit-minibuffer

From: Noam Postavsky <[email-masked]>
Date: Wed, 20 May 2020 13:31:12 -0400

tags 41370 + confirmed
quit

André Alexandre Gomes <[email-masked]> writes:

> - M-x eshell-command
> - M-n (empty input ring)
> - M-x eshell
> - pwd
> - nothing happens 
>
> This message appears:
> "exit-minibuffer: No catch for tag: exit, nil"

This is because eshell-command calls eshell-return-exits-minibuffer
which does

    (define-key eshell-mode-map [(control ?m)] 'exit-minibuffer)

This was okay in 26.3 because eshell-mode created its keymap from
scratch every time.  That's no longer the case since [1: 1ee0192b792]
(bugs #22792 and #33808).

[1: 1ee0192b792]: 2019-08-15 20:49:15 -0400
  Fix eshell-mode-map initialization
  https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=1ee0192b792124663a0a40a729dd83c047d21535

I think that should be reverted from emacs-27, and the patch below can
fix it for master:

--- i/lisp/eshell/eshell.el
+++ w/lisp/eshell/eshell.el
@@ -265,14 +265,18 @@ eshell
       (eshell-mode))
     buf))
 
-(defun eshell-return-exits-minibuffer ()
-  ;; This is supposedly run after enabling esh-mode, when eshell-mode-map
-  ;; already exists.
-  (defvar eshell-mode-map)
-  (define-key eshell-mode-map [(control ?g)] 'abort-recursive-edit)
-  (define-key eshell-mode-map [(control ?m)] 'exit-minibuffer)
-  (define-key eshell-mode-map [(control ?j)] 'exit-minibuffer)
-  (define-key eshell-mode-map [(meta control ?m)] 'exit-minibuffer))
+(define-minor-mode eshell-command-mode
+  "Minor mode for `eshell-command' input.
+\\{eshell-command-mode-map}"
+  :keymap (let ((map (make-sparse-keymap)))
+            (define-key map [(control ?g)] 'abort-recursive-edit)
+            (define-key map [(control ?m)] 'exit-minibuffer)
+            (define-key map [(control ?j)] 'exit-minibuffer)
+            (define-key map [(meta control ?m)] 'exit-minibuffer)
+            map))
+
+(define-obsolete-function-alias 'eshell-return-exits-minibuffer
+  #'eshell-command-mode "28.1")
 
 (defvar eshell-non-interactive-p nil
   "A variable which is non-nil when Eshell is not running interactively.
@@ -292,7 +296,7 @@ eshell-command
     ;; Enable `eshell-mode' only in this minibuffer.
     (minibuffer-with-setup-hook #'(lambda ()
                                     (eshell-mode)
-                                    (eshell-return-exits-minibuffer))
+                                    (eshell-command-mode +1))
       (unless command
         (setq command (read-from-minibuffer "Emacs shell command: "))
 	(if (eshell-using-module 'eshell-hist)