[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#28852: make revert-buffer ('g') in VC diff buffers keep point
From: |
Charles A. Roelli |
Subject: |
bug#28852: make revert-buffer ('g') in VC diff buffers keep point |
Date: |
Tue, 17 Oct 2017 19:58:00 +0200 |
> Date: Sun, 15 Oct 2017 21:07:30 +0200
> From: charles@aurox.ch (Charles A. Roelli)
>
> At the moment, when you hit 'g' in a *vc-diff* buffer, the cursor is
> moved back to (point-min), which can be annoying. Attached is an
> attempt at fixing that (using 'replace-buffer-contents' to keep
> markers/point in the same place).
Hm, I'll try again:
>From 48e3febfee28276b3eb7d9af58342c70d2d798f9 Mon Sep 17 00:00:00 2001
From: "Charles A. Roelli" <charles@aurox.ch>
Date: Sun, 15 Oct 2017 20:58:01 +0200
Subject: [PATCH] Make revert-buffer ('g') keep point in VC diff buffers
(Bug#28852)
* 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'.
---
lisp/vc/vc.el | 33 +++++++++++++++++++++++++++++----
1 file changed, 29 insertions(+), 4 deletions(-)
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index b80f0e6..57d5a50 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -1654,7 +1654,20 @@ vc-diff-switches-list
(declare (obsolete vc-switches "22.1"))
`(vc-switches ',backend 'diff))
-(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)
@@ -1666,7 +1679,13 @@ vc-diff-finish
(insert (cdr messages) ".\n")
(message "%s" (cdr messages))))
(diff-setup-whitespace)
- (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
+ (progn
+ (vc-diff-restore-buffer oldbuf buffer)
+ (diff-mode))
+ (goto-char (point-min)))
(when window
(shrink-window-if-larger-than-buffer window)))
(when (and messages (not emptyp))
@@ -1692,7 +1711,12 @@ vc-diff-internal
;; 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.
@@ -1752,7 +1776,8 @@ vc-diff-internal
;; 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)))
--
2.9.4