Allow old input to include continuation lines in shell-mode

* lisp/shell.el (shell-get-old-input-include-continuation-lines): New
defcustom (default nil).
(shell-get-old-input): New function.  Like
'comint-get-old-input-default' but include all continuation lines if
'shell-get-old-input-include-continuation-lines' is non-nil.
(shell-mode): Install shell-get-old-input.  (Bug#61069)

* etc/NEWS: Advertise the new defcustom.
This commit is contained in:
Bob Rogers 2023-03-31 09:57:32 +02:00 committed by Robert Pluim
parent c96bd1bf88
commit 6f496105e3
2 changed files with 48 additions and 0 deletions

View file

@ -174,6 +174,14 @@ correctly unloads Eshell and all of its modules.
After manually editing 'eshell-aliases-file', you can use this command
to load the edited aliases.
** Shell Mode
+++
*** New user option 'shell-get-old-input-include-continuation-lines'.
When this user option is non-nil, 'shell-get-old-input' (C-RET)
includes multiple shell "\" continuation lines from command output.
Default is nil.
** Prog Mode
+++

View file

@ -366,6 +366,12 @@ Useful for shells like zsh that has this feature."
:group 'shell-directories
:version "28.1")
(defcustom shell-get-old-input-include-continuation-lines nil
"Whether `shell-get-old-input' includes \"\\\" lines."
:type 'boolean
:group 'shell
:version "30.1")
(defcustom shell-kill-buffer-on-exit nil
"Kill a shell buffer after the shell process terminates."
:type 'boolean
@ -506,6 +512,39 @@ Useful for shells like zsh that has this feature."
(push (mapconcat #'identity (nreverse arg) "") args)))
(cons (nreverse args) (nreverse begins)))))
(defun shell-get-old-input ()
"Default for `comint-get-old-input' in `shell-mode'.
If `comint-use-prompt-regexp' is nil, then either
return the current input field (if point is on an input field), or the
current line (if point is on an output field).
If `comint-use-prompt-regexp' is non-nil, then return
the current line, with any initial string matching the regexp
`comint-prompt-regexp' removed.
In either case, if `shell-get-old-input-include-continuation-lines'
is non-nil and the current line ends with a backslash, the next
line is also included and examined for a backslash, ending with a
final line without a backslash."
(let (field-prop bof)
(if (and (not comint-use-prompt-regexp)
;; Make sure we're in an input rather than output field.
(not (setq field-prop (get-char-property
(setq bof (field-beginning)) 'field))))
(field-string-no-properties bof)
(comint-bol)
(let ((start (point)))
(cond ((or comint-use-prompt-regexp
(eq field-prop 'output))
(goto-char (line-end-position))
(when shell-get-old-input-include-continuation-lines
;; Include continuation lines as long as the current
;; line ends with a backslash.
(while (and (not (eobp))
(= (char-before) ?\\))
(goto-char (line-end-position 2)))))
(t
(goto-char (field-end))))
(buffer-substring-no-properties start (point))))))
;;;###autoload
(defun split-string-shell-command (string)
"Split STRING (a shell command) into a list of strings.
@ -642,6 +681,7 @@ command."
(setq-local font-lock-defaults '(shell-font-lock-keywords t))
(setq-local shell-dirstack nil)
(setq-local shell-last-dir nil)
(setq-local comint-get-old-input #'shell-get-old-input)
;; People expect Shell mode to keep the last line of output at
;; window bottom.
(setq-local scroll-conservatively 101)