feat(:term): confine undo to comint/eshell prompts

Otherwise, undo could delete entire chunks of a shell buffer. This
addresses the issue in eshell, comint shells, and derivatives (like
ielm, shell, or inferior-* shells).

Ref: #8410
This commit is contained in:
Henrik Lissner
2025-06-30 20:54:21 +02:00
parent 1b125ddf7b
commit 5a690fc54f
2 changed files with 22 additions and 9 deletions

View File

@ -350,6 +350,20 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
(after! comint (after! comint
(setq-default comint-buffer-maximum-size 2048) ; double the default (setq-default comint-buffer-maximum-size 2048) ; double the default
;; UX: Temporarily disable undo history between command executions. Otherwise,
;; undo could destroy output while it's being printed or delete buffer
;; contents past the boundaries of the current prompt.
(add-hook 'comint-exec-hook #'buffer-disable-undo)
(defadvice! doom--comint-enable-undo-a (process _string)
:after #'comint-output-filter
(let ((start-marker comint-last-output-start))
(when (and (< start-marker
(or (if process (process-mark process))
(point-max-marker)))
(eq (char-before start-marker) ?\n)) ;; Account for some of the IELMs wilderness.
(buffer-enable-undo)
(setq buffer-undo-list nil))))
;; Protect prompts from accidental modifications. ;; Protect prompts from accidental modifications.
(setq-default comint-prompt-read-only t) (setq-default comint-prompt-read-only t)

View File

@ -85,15 +85,14 @@ You should use `set-eshell-alias!' to change this.")
(add-hook 'eshell-mode-hook #'+eshell-init-h) (add-hook 'eshell-mode-hook #'+eshell-init-h)
(add-hook 'eshell-exit-hook #'+eshell-cleanup-h) (add-hook 'eshell-exit-hook #'+eshell-cleanup-h)
;; UX: Temporarily disable undo history between command executions. Undo can ;; UX: Temporarily disable undo history between command executions. Otherwise,
;; destroy output while it's being printed to stdout. ;; undo could destroy output while it's being printed or delete buffer
(let (old-undo-list) ;; contents past the boundaries of the current prompt.
(add-hook! 'eshell-pre-command-hook (add-hook 'eshell-pre-command-hook #'buffer-disable-undo)
(setq old-undo-list buffer-undo-list (add-hook! 'eshell-post-command-hook
buffer-undo-list nil)) (defun +eshell--enable-undo-h ()
(add-hook! 'eshell-post-command-hook (buffer-enable-undo (current-buffer))
(setq buffer-undo-list old-undo-list) (setq buffer-undo-list nil)))
(clrhash undo-equiv-table)))
;; UX: Prior output in eshell buffers should be read-only. Otherwise, it's ;; UX: Prior output in eshell buffers should be read-only. Otherwise, it's
;; trivial to make edits in visual modes (like evil's or term's ;; trivial to make edits in visual modes (like evil's or term's