Subject: Re: bug#65039: 30.0.50; [PATCH] Add bookmark handler for M-x shell

From: Visuwesh <[email-masked]>
Date: Fri, 04 Aug 2023 18:31:16 +0530

[வெள்ளி ஆகஸ்ட் 04, 2023] Protesilaos Stavrou wrote:

> The code is adapted from Eshell, which has the capability you describe.
> I do not have the means to test an SSH connection.  Though I tried the
> 'sudo' TRAMP method and the bookmarking correctly logs me in as root
> when I do 'bookmark-jump'.  This works even if I kill the shell buffer
> and all TRAMP buffers.

I see that `shell' sets the value of `explicit-shell-file-name' to the
filename of the remote shell chosen but unfortunately this gets set to
nil once `make-comint-in-buffer' function is called since `comint-mode'
kills all local variables.  :-(

I don't know how reliable of a solution

    (executable-find shell--start-prog)

is to get the absolute filename of the shell being used.

If that is an acceptable solution, then the following diff works fine
for both remote and local shells.

diff --git a/lisp/shell.el b/lisp/shell.el
index 5cf108bfa3..8396870a67 100644
--- a/lisp/shell.el
+++ b/lisp/shell.el
@@ -637,6 +637,7 @@ shell-mode
 
   (setq comint-prompt-regexp shell-prompt-pattern)
   (shell-completion-vars)
+  (setq-local bookmark-make-record-function #'shell-bookmark-make-record)
   (setq-local paragraph-separate "\\'")
   (setq-local paragraph-start comint-prompt-regexp)
   (setq-local font-lock-defaults '(shell-font-lock-keywords t))
@@ -1770,6 +1771,32 @@ shell-highlight-undef-mode-restart
   (when shell-highlight-undef-mode
     (shell-highlight-undef-mode 1)))
 
+;;; Bookmark support
+
+;; Adapted from esh-mode.el
+(declare-function bookmark-prop-get "bookmark" (bookmark prop))
+
+(defun shell-bookmark-name ()
+  (format "shell-%s"
+          (file-name-nondirectory
+           (directory-file-name
+            (file-name-directory default-directory)))))
+
+(defun shell-bookmark-make-record ()
+  "Create a bookmark for the current Shell buffer."
+  `(,(shell-bookmark-name)
+    (location . ,default-directory)
+    (shell-filename . ,(executable-find shell--start-prog))
+    (handler . shell-bookmark-jump)))
+
+;;;###autoload
+(defun shell-bookmark-jump (bookmark)
+  "Default bookmark handler for Shell buffers."
+  (let ((default-directory (bookmark-prop-get bookmark 'location)))
+    (shell nil (bookmark-prop-get bookmark 'shell-filename))))
+
+(put 'shell-bookmark-jump 'bookmark-handler-type "Shell")
+
 (provide 'shell)
 
 ;;; shell.el ends here