]> git.eshelyaron.com Git - emacs.git/commitdiff
; (completion-preview-partial-insert): Avoid no-op undo entries
authorEshel Yaron <me@eshelyaron.com>
Fri, 28 Jun 2024 10:57:32 +0000 (12:57 +0200)
committerEshel Yaron <me@eshelyaron.com>
Fri, 28 Jun 2024 10:57:32 +0000 (12:57 +0200)
* lisp/completion-preview.el
(completion-preview-partial-insert): Abort change group
rather than deleting entire temporary insertion, so as to
avoid recording no-op undo entries.  Move 'deactivate-mark'
let-binding outside of 'catch' form.

lisp/completion-preview.el

index 2a0d193e6f6cb75fc7fe6950a52670e7e4813c09..f0a094864b4a6ae3ee7da2316d8c374a012d6ff9 100644 (file)
@@ -573,23 +573,27 @@ Beyond moving point, FUN should not modify the current buffer."
   (let* ((end (completion-preview--get 'completion-preview-end))
          (aft (completion-preview--get 'after-string))
          (eoc (+ end (length aft))))
-    ;; Partially insert current completion candidate.
-    (atomic-change-group
-      (let ((change-group (prepare-change-group))
-            ;; Keep region active, if it is already.  This allows
-            ;; commands such as `completion-preview-insert-word' to
-            ;; interact correctly with `shift-select-mode'.
-            (deactivate-mark nil))
-        (save-excursion
-          (goto-char end)
-          ;; Temporarily insert the full completion candidate.
-          (insert (substring-no-properties aft)))
-        ;; Set point to the end of the prefix that we want to keep.
-        (apply fun args)
-        ;; Delete the rest.
-        (delete-region (min (max end (point)) eoc) eoc)
-        ;; Combine into one change group
-        (undo-amalgamate-change-group change-group)))
+    ;; Keep region active, if it is already.  This lets commands that
+    ;; call this function interact correctly with `shift-select-mode'.
+    (let ((deactivate-mark nil))
+      ;; Partially insert current completion candidate.
+      (catch 'abort-atomic-change
+        (atomic-change-group
+          (let ((change-group (prepare-change-group)))
+            (save-excursion
+              (goto-char end)
+              ;; Temporarily insert the full completion candidate.
+              (insert (substring-no-properties aft)))
+            ;; Set point to the end of the prefix that we want to keep.
+            (apply fun args)
+            (unless (< end (point))
+              ;; Point didn't advance into the completion, so abort change
+              ;; to avoid littering `buffer-undo-list' with a nop entry.
+              (throw 'abort-atomic-change nil))
+            ;; Delete the rest.
+            (delete-region (min (point) eoc) eoc)
+            ;; Combine into one change group.
+            (undo-amalgamate-change-group change-group)))))
     ;; Cleanup.
     (cond
      ;; If we kept the entire completion candidate, call :exit-function.