From 4268d9a2b6bc96c0ae2448c6694bbd765fc577a7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Miha=20Rihtar=C5=A1i=C4=8D?= Date: Mon, 8 Nov 2021 00:10:03 +0100 Subject: [PATCH] Improve undoing of RET in comint and eshell * lisp/comint.el (comint-send-input): (comint-accumulate): * lisp/eshell/esh-mode.el (eshell-send-input): Before sending input to the process, delete it and reinsert it again. Undoing this insertion with 'C-/' will delete the region, moving the process mark back to its original position (bug#49484). --- lisp/comint.el | 24 +++++++++++++++++++++++- lisp/eshell/esh-mode.el | 8 ++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/lisp/comint.el b/lisp/comint.el index adae971eff2..544f0b8b820 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -1907,6 +1907,14 @@ Similarly for Soar, Scheme, etc." (delete-region pmark start) copy)))) + ;; Delete and reinsert input. This seems like a no-op, except + ;; for the resulting entries in the undo list: undoing this + ;; insertion will delete the region, moving the process mark + ;; back to its original position. + (let ((inhibit-read-only t)) + (delete-region pmark (point)) + (insert input)) + (unless no-newline (insert ?\n)) @@ -1950,7 +1958,7 @@ Similarly for Soar, Scheme, etc." ;; in case we get output amidst sending the input. (set-marker comint-last-input-start pmark) (set-marker comint-last-input-end (point)) - (set-marker (process-mark proc) (point)) + (set-marker pmark (point)) ;; clear the "accumulation" marker (set-marker comint-accum-marker nil) (let ((comint-input-sender-no-newline no-newline)) @@ -3520,6 +3528,20 @@ to send all the accumulated input, at once. The entire accumulated text becomes one item in the input history when you send it." (interactive) + (when-let* ((proc (get-buffer-process (current-buffer))) + (pmark (process-mark proc)) + ((or (marker-position comint-accum-marker) + (set-marker comint-accum-marker pmark) + t)) + ((>= (point) comint-accum-marker pmark))) + ;; Delete and reinsert input. This seems like a no-op, except for + ;; the resulting entries in the undo list: undoing this insertion + ;; will delete the region, moving the accumulation marker back to + ;; its original position. + (let ((text (buffer-substring comint-accum-marker (point))) + (inhibit-read-only t)) + (delete-region comint-accum-marker (point)) + (insert text))) (insert "\n") (set-marker comint-accum-marker (point)) (if comint-input-ring-index diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el index 2b5a4647e06..a054cd66e27 100644 --- a/lisp/eshell/esh-mode.el +++ b/lisp/eshell/esh-mode.el @@ -616,6 +616,14 @@ newline." (and eshell-send-direct-to-subprocesses proc-running-p)) (insert-before-markers-and-inherit ?\n)) + ;; Delete and reinsert input. This seems like a no-op, except + ;; for the resulting entries in the undo list: undoing this + ;; insertion will delete the region, moving the process mark + ;; back to its original position. + (let ((text (buffer-substring eshell-last-output-end (point))) + (inhibit-read-only t)) + (delete-region eshell-last-output-end (point)) + (insert text)) (if proc-running-p (progn (eshell-update-markers eshell-last-output-end) -- 2.39.2