emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master a836e8bf0c: Make revert-buffer ('g') keep point in VC diff buffer


From: Lars Ingebrigtsen
Subject: master a836e8bf0c: Make revert-buffer ('g') keep point in VC diff buffers
Date: Sat, 29 Jan 2022 10:49:08 -0500 (EST)

branch: master
commit a836e8bf0c818e081cdf81d1b5bdadfe6b0df85f
Author: Charles A. Roelli <charles@aurox.ch>
Commit: Lars Ingebrigtsen <larsi@gnus.org>

    Make revert-buffer ('g') keep point in VC diff buffers
    
    * lisp/vc/vc.el (vc-diff-restore-buffer): New function.
    (vc-diff-finish): Update its calling convention to include an
    optional 'oldbuf' parameter, and handle it.
    (vc-diff-internal): Pass a clone of the incumbent vc-diff
    buffer to 'vc-diff-finish' (bug#28852).
---
 lisp/vc/vc.el | 31 +++++++++++++++++++++++++++----
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index 54457a2143..0096a5fcb3 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -1742,7 +1742,20 @@ BUFFER defaults to the current buffer."
   "Functions run at the end of the diff command.
 Each function runs in the diff output buffer without args.")
 
-(defun vc-diff-finish (buffer messages)
+(defun vc-diff-restore-buffer (original new)
+  "Restore point in buffer NEW to where it was in ORIGINAL.
+
+This function works by updating buffer ORIGINAL with the contents
+of NEW (without destroying existing markers), swapping their text
+objects, and finally killing buffer ORIGINAL."
+  (with-current-buffer original
+    (let ((inhibit-read-only t))
+      (replace-buffer-contents new)))
+  (with-current-buffer new
+    (buffer-swap-text original))
+  (kill-buffer original))
+
+(defun vc-diff-finish (buffer messages &optional oldbuf)
   ;; The empty sync output case has already been handled, so the only
   ;; possibility of an empty output is for an async process.
   (when (buffer-live-p buffer)
@@ -1754,7 +1767,11 @@ Each function runs in the diff output buffer without 
args.")
               (message "%s" (cdr messages))))
        (diff-setup-whitespace)
        (diff-setup-buffer-type)
-       (goto-char (point-min))
+        ;; `oldbuf' is the buffer that used to show this diff.  Make
+        ;; sure that we restore point in it if it's given.
+       (if oldbuf
+            (vc-diff-restore-buffer oldbuf buffer)
+          (goto-char (point-min)))
        (run-hooks 'vc-diff-finish-functions))
       (when (and messages (not emptyp))
        (message "%sdone" (car messages))))))
@@ -1779,7 +1796,12 @@ Return t if the buffer had changes, nil otherwise."
         ;; but the only way to set it for each file included would
         ;; be to call the back end separately for each file.
         (coding-system-for-read
-         (if files (vc-coding-system-for-diff (car files)) 'undecided)))
+         (if files (vc-coding-system-for-diff (car files)) 'undecided))
+         (orig-diff-buffer-clone
+          (if (and (get-buffer buffer) revert-buffer-in-progress-p)
+              (with-current-buffer buffer
+                (clone-buffer
+                 (generate-new-buffer-name " *vc-diff-clone*") nil)))))
     ;; On MS-Windows and MS-DOS, Diff is likely to produce DOS-style
     ;; EOLs, which will look ugly if (car files) happens to have Unix
     ;; EOLs.
@@ -1840,7 +1862,8 @@ Return t if the buffer had changes, nil otherwise."
       ;; after `pop-to-buffer'; the former assumes the diff buffer is
       ;; shown in some window.
       (let ((buf (current-buffer)))
-        (vc-run-delayed (vc-diff-finish buf (when verbose messages))))
+        (vc-run-delayed (vc-diff-finish buf (when verbose messages)
+                                        orig-diff-buffer-clone)))
       ;; In the async case, we return t even if there are no differences
       ;; because we don't know that yet.
       t)))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]