From 5a690fc54fa58b0443ab8b6cb65e6588d5b5e9ec Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Mon, 30 Jun 2025 20:54:21 +0200 Subject: [PATCH] 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 --- lisp/doom-ui.el | 14 ++++++++++++++ modules/term/eshell/config.el | 17 ++++++++--------- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/lisp/doom-ui.el b/lisp/doom-ui.el index dbc83ae68..b93cfda64 100644 --- a/lisp/doom-ui.el +++ b/lisp/doom-ui.el @@ -350,6 +350,20 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original (after! comint (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 IELM’s wilderness. + (buffer-enable-undo) + (setq buffer-undo-list nil)))) + ;; Protect prompts from accidental modifications. (setq-default comint-prompt-read-only t) diff --git a/modules/term/eshell/config.el b/modules/term/eshell/config.el index 00b0130a3..aafa0fcac 100644 --- a/modules/term/eshell/config.el +++ b/modules/term/eshell/config.el @@ -85,15 +85,14 @@ You should use `set-eshell-alias!' to change this.") (add-hook 'eshell-mode-hook #'+eshell-init-h) (add-hook 'eshell-exit-hook #'+eshell-cleanup-h) - ;; UX: Temporarily disable undo history between command executions. Undo can - ;; destroy output while it's being printed to stdout. - (let (old-undo-list) - (add-hook! 'eshell-pre-command-hook - (setq old-undo-list buffer-undo-list - buffer-undo-list nil)) - (add-hook! 'eshell-post-command-hook - (setq buffer-undo-list old-undo-list) - (clrhash undo-equiv-table))) + ;; 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 'eshell-pre-command-hook #'buffer-disable-undo) + (add-hook! 'eshell-post-command-hook + (defun +eshell--enable-undo-h () + (buffer-enable-undo (current-buffer)) + (setq buffer-undo-list nil))) ;; 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