branch: externals/diff-hl
commit dafdfcfcaf9cf83187990f4dd604740a8e4d81d9
Author: James Cherti <[email protected]>
Commit: James Cherti <[email protected]>
Support indirect buffers by resolving base buffer file names
- Add diff-hl--buffer-file-name helper to retrieve the file name of the
current buffer or its base buffer.
- Replace direct accesses of the buffer-file-name variable with the new
helper
changes to all live buffers sharing the same base buffer.
---
diff-hl-amend.el | 4 +--
diff-hl-flydiff.el | 7 ++--
diff-hl-show-hunk.el | 11 +++---
diff-hl.el | 100 ++++++++++++++++++++++++++++-----------------------
test/diff-hl-test.el | 16 ++++-----
5 files changed, 76 insertions(+), 62 deletions(-)
diff --git a/diff-hl-amend.el b/diff-hl-amend.el
index 95f2b384a0..c2996c38f0 100644
--- a/diff-hl-amend.el
+++ b/diff-hl-amend.el
@@ -44,7 +44,7 @@ Currently only supports Git, Mercurial and Bazaar."
(diff-hl-update)))
(defun diff-hl-amend-setup ()
- (let ((backend (vc-backend buffer-file-name)))
+ (let ((backend (vc-backend (diff-hl--buffer-file-name))))
(when backend
(setq-local diff-hl-reference-revision
(cl-case backend
@@ -62,7 +62,7 @@ Currently only supports Git, Mercurial and Bazaar."
(defun turn-on-diff-hl-amend-mode ()
"Turn on `diff-hl-amend-mode' in a buffer if appropriate."
- (and buffer-file-name (diff-hl-amend-mode 1)))
+ (and (diff-hl--buffer-file-name) (diff-hl-amend-mode 1)))
(provide 'diff-hl-amend)
diff --git a/diff-hl-flydiff.el b/diff-hl-flydiff.el
index 4e9748146a..4afc3e191b 100644
--- a/diff-hl-flydiff.el
+++ b/diff-hl-flydiff.el
@@ -52,9 +52,10 @@
(unless (or
(not diff-hl-mode)
(eq diff-hl-flydiff-modified-tick (buffer-chars-modified-tick))
- (not buffer-file-name)
- (file-remote-p default-directory)
- (not (file-exists-p buffer-file-name)))
+ (let ((file (diff-hl--buffer-file-name)))
+ (or (not file)
+ (file-remote-p default-directory)
+ (not (file-exists-p file)))))
(diff-hl-update)))
(defun diff-hl-flydiff/modified-p (state)
diff --git a/diff-hl-show-hunk.el b/diff-hl-show-hunk.el
index 641683d702..947a1eb257 100644
--- a/diff-hl-show-hunk.el
+++ b/diff-hl-show-hunk.el
@@ -134,10 +134,11 @@ buffer."
(line (line-number-at-pos))
(dest-buffer diff-hl-show-hunk-diff-buffer-name))
(with-current-buffer buffer
- (if (buffer-modified-p)
- (diff-hl-diff-buffer-with-reference buffer-file-name dest-buffer)
- (diff-hl-changes-buffer buffer-file-name (vc-backend buffer-file-name)
- nil dest-buffer))
+ (let ((file (diff-hl--buffer-file-name)))
+ (if (buffer-modified-p)
+ (diff-hl-diff-buffer-with-reference file dest-buffer)
+ (diff-hl-changes-buffer file (vc-backend file)
+ nil dest-buffer)))
(switch-to-buffer dest-buffer)
(diff-hl-diff-skip-to line)
(setq vc-sentinel-movepoint (point)))
@@ -303,7 +304,7 @@ end of the OVERLAY, so posframe/inline is placed below the
hunk."
The backend is determined by `diff-hl-show-hunk-function'."
(interactive)
- (unless (vc-backend buffer-file-name)
+ (unless (vc-backend (diff-hl--buffer-file-name))
(user-error "The buffer is not under version control"))
(diff-hl-find-current-hunk)
diff --git a/diff-hl.el b/diff-hl.el
index d628d260d2..0fcb207640 100644
--- a/diff-hl.el
+++ b/diff-hl.el
@@ -314,6 +314,15 @@ It can be a relative expression as well, such as \"HEAD^\"
with Git, or
(lambda (value)
(or (null value) (stringp value))))
+(defun diff-hl--buffer-file-name (&optional buffer)
+ "Return the file name of the BUFFER or its base buffer.
+BUFFER defaults to the current buffer."
+ (let* ((buffer (or buffer (current-buffer)))
+ (base-buffer (buffer-base-buffer buffer)))
+ (if base-buffer
+ (buffer-file-name base-buffer)
+ (buffer-file-name buffer))))
+
(defun diff-hl-define-bitmaps ()
(let* ((scale (if (and (boundp 'text-scale-mode-amount)
(numberp text-scale-mode-amount))
@@ -485,7 +494,7 @@ It can be a relative expression as well, such as \"HEAD^\"
with Git, or
buffer)
(defun diff-hl-changes ()
- (let* ((file buffer-file-name)
+ (let* ((file (diff-hl--buffer-file-name))
(backend (vc-backend file))
(hide-staged (and (eq backend 'Git) (not
diff-hl-show-staged-changes))))
(when backend
@@ -530,7 +539,7 @@ It can be a relative expression as well, such as \"HEAD^\"
with Git, or
(or (assoc-default backend diff-hl-head-revision-alist)
;; It's usually cached already (e.g. for mode-line).
;; So this is basically an optimization for rare cases.
- (vc-working-revision buffer-file-name backend)))
+ (vc-working-revision (diff-hl--buffer-file-name) backend)))
(defun diff-hl-adjust-changes (old new)
"Adjust changesets in OLD using changes in NEW.
@@ -895,8 +904,9 @@ buffer will show the position corresponding to its current
line."
(setq rootdir (vc-call-backend backend 'root default-directory)
default-directory rootdir
fileset `(,backend (,rootdir))
- relname (if buffer-file-name (file-relative-name
buffer-file-name
- rootdir)))
+ relname (let ((file (diff-hl--buffer-file-name)))
+ (when file
+ (file-relative-name file rootdir))))
(error "Directory is not version controlled"))
(setq fileset (or fileset (vc-deduce-fileset)))
(vc-buffer-sync-fileset fileset t)
@@ -911,7 +921,7 @@ buffer will show the position corresponding to its current
line."
(setq vc-sentinel-movepoint (point))))))))
(defun diff-hl-diff-read-revisions (rev1-default)
- (let* ((file buffer-file-name)
+ (let* ((file (diff-hl--buffer-file-name))
(files (list file))
(backend (vc-backend file))
(rev2-default nil))
@@ -1011,7 +1021,7 @@ that file, if it's present."
(line (save-excursion
(diff-hl-find-current-hunk)
(line-number-at-pos)))
- (file buffer-file-name)
+ (file (diff-hl--buffer-file-name))
(backend (vc-backend file)))
(unwind-protect
(progn
@@ -1147,7 +1157,7 @@ its end position."
(push-mark (overlay-end hunk) nil t)))
(defun diff-hl--ensure-staging-supported ()
- (let ((backend (vc-backend buffer-file-name)))
+ (let ((backend (vc-backend (diff-hl--buffer-file-name))))
(unless (eq backend 'Git)
(user-error "Only Git supports staging; this file is controlled by %s"
backend))))
@@ -1174,7 +1184,7 @@ Only supported with Git."
(diff-hl--ensure-staging-supported)
(diff-hl-find-current-hunk)
(let* ((line (line-number-at-pos))
- (file buffer-file-name)
+ (file (diff-hl--buffer-file-name))
(dest-buffer (get-buffer-create " *diff-hl-stage*"))
(orig-buffer (current-buffer))
;; FIXME: If the file name has double quotes, these need to be quoted.
@@ -1215,13 +1225,14 @@ Only supported with Git."
Only supported with Git."
(interactive)
- (unless buffer-file-name
- (user-error "No current file"))
- (diff-hl--ensure-staging-supported)
- (vc-git-command nil 0 buffer-file-name "reset")
- (message "Unstaged all")
- (unless diff-hl-show-staged-changes
- (diff-hl-update)))
+ (let ((file (diff-hl--buffer-file-name)))
+ (unless file
+ (user-error "No current file"))
+ (diff-hl--ensure-staging-supported)
+ (vc-git-command nil 0 file "reset")
+ (message "Unstaged all")
+ (unless diff-hl-show-staged-changes
+ (diff-hl-update))))
(defun diff-hl-stage-dwim (&optional with-edit)
"Stage the current hunk or choose the hunks to stage.
@@ -1248,7 +1259,7 @@ Pops up a diff buffer that can be edited to choose the
changes to stage."
(diff-hl--ensure-staging-supported)
(let* ((line-beg (and beg (line-number-at-pos beg t)))
(line-end (and end (line-number-at-pos end t)))
- (file buffer-file-name)
+ (file (diff-hl--buffer-file-name))
(dest-buffer (get-buffer-create "*diff-hl-stage-some*"))
(orig-buffer (current-buffer))
(diff-hl-update-async nil)
@@ -1426,26 +1437,26 @@ The value of this variable is a mode line template as in
(magit-git-items "diff-tree" "-z" "--name-only" "-r" "HEAD~"
"HEAD"))
(unmodified-states '(up-to-date ignored unregistered)))
(dolist (buf (buffer-list))
- (when (and (buffer-local-value 'diff-hl-mode buf)
- (not (buffer-modified-p buf))
- ;; Solve the "cloned indirect buffer" problem
- ;; (diff-hl-mode could be non-nil there, even if
- ;; buffer-file-name is nil):
- (buffer-file-name buf)
- (file-in-directory-p (buffer-file-name buf) topdir)
- (file-exists-p (buffer-file-name buf)))
- (with-current-buffer buf
- (let* ((file buffer-file-name)
- (backend (vc-backend file)))
- (when backend
- (cond
- ((member file modified-files)
- (when (memq (vc-state file) unmodified-states)
- (vc-state-refresh file backend))
- (diff-hl-update))
- ((not (memq (vc-state file backend) unmodified-states))
- (vc-state-refresh file backend)
- (diff-hl-update)))))))))))
+ (let ((file (diff-hl--buffer-file-name buf)))
+ (when (and (buffer-local-value 'diff-hl-mode buf)
+ (not (buffer-modified-p buf))
+ ;; Solve the "cloned indirect buffer" problem
+ ;; (diff-hl-mode could be non-nil there, even if
+ ;; buffer-file-name is nil):
+ file
+ (file-in-directory-p file topdir)
+ (file-exists-p file))
+ (with-current-buffer buf
+ (let* ((backend (vc-backend file)))
+ (when backend
+ (cond
+ ((member file modified-files)
+ (when (memq (vc-state file) unmodified-states)
+ (vc-state-refresh file backend))
+ (diff-hl-update))
+ ((not (memq (vc-state file backend) unmodified-states))
+ (vc-state-refresh file backend)
+ (diff-hl-update))))))))))))
(defun diff-hl-dir-update ()
(dolist (pair (if (vc-dir-marked-files)
@@ -1538,7 +1549,7 @@ CONTEXT-LINES is the size of the unified diff context,
defaults to 0."
backend
(or diff-hl-reference-revision
(assoc-default backend diff-hl-head-revision-alist)))
- (diff-hl-working-revision buffer-file-name backend)))))
+ (diff-hl-working-revision (diff-hl--buffer-file-name)
backend)))))
(switches (format "-U %d --strip-trailing-cr" (or context-lines
0))))
(diff-no-select rev (current-buffer) switches (not
(diff-hl--use-async-p))
(get-buffer-create dest-buffer))
@@ -1606,13 +1617,14 @@ CONTEXT-LINES is the size of the unified diff context,
defaults to 0."
;;;###autoload
(defun turn-on-diff-hl-mode ()
"Turn on `diff-hl-mode' or `diff-hl-dir-mode' in a buffer if appropriate."
- (cond
- (buffer-file-name
- (unless (and diff-hl-disable-on-remote
- (file-remote-p buffer-file-name))
- (diff-hl-mode 1)))
- ((eq major-mode 'vc-dir-mode)
- (diff-hl-dir-mode 1))))
+ (let ((file (diff-hl--buffer-file-name)))
+ (cond
+ (file
+ (unless (and diff-hl-disable-on-remote
+ (file-remote-p file))
+ (diff-hl-mode 1)))
+ ((eq major-mode 'vc-dir-mode)
+ (diff-hl-dir-mode 1)))))
;;;###autoload
(defun diff-hl--global-turn-on ()
diff --git a/test/diff-hl-test.el b/test/diff-hl-test.el
index a143fbe16f..db6ce19c5e 100644
--- a/test/diff-hl-test.el
+++ b/test/diff-hl-test.el
@@ -50,11 +50,11 @@
(erase-buffer)
(insert diff-hl-test-initial-content)
(save-buffer)
- (pcase (vc-backend buffer-file-name)
+ (pcase (vc-backend (diff-hl--buffer-file-name))
(`Git
- (vc-git-command nil 0 buffer-file-name "reset"))
+ (vc-git-command nil 0 (diff-hl--buffer-file-name) "reset"))
(`Hg
- (vc-hg-command nil 0 buffer-file-name "revert")))))
+ (vc-hg-command nil 0 (diff-hl--buffer-file-name) "revert")))))
(defun diff-hl-test-compute-diff-lines ()
(diff-hl-test-in-source
@@ -160,7 +160,7 @@
(goto-char (point-min))
(insert "new line 1\n")
(save-buffer)
- (vc-git-command nil 0 buffer-file-name "add")
+ (vc-git-command nil 0 (diff-hl--buffer-file-name) "add")
(goto-char (point-max))
(insert "new line 2\n")
(save-buffer)
@@ -180,19 +180,19 @@
(goto-char (point-min))
(insert "new line 1\n")
(save-buffer)
- (vc-git-command nil 0 buffer-file-name "add")
+ (vc-git-command nil 0 (diff-hl--buffer-file-name) "add")
(goto-char (point-max))
(insert "new line 2\n")
(let ((diff-hl-show-staged-changes t))
(should
(equal (diff-hl-changes-from-buffer
- (diff-hl-diff-buffer-with-reference buffer-file-name))
+ (diff-hl-diff-buffer-with-reference
(diff-hl--buffer-file-name)))
'((1 1 0 insert)
(12 1 0 insert)))))
(let ((diff-hl-show-staged-changes nil))
(should
(equal (diff-hl-changes-from-buffer
- (diff-hl-diff-buffer-with-reference buffer-file-name))
+ (diff-hl-diff-buffer-with-reference
(diff-hl--buffer-file-name)))
'((12 1 0 insert)))))))
(diff-hl-deftest diff-hl-can-split-away-no-trailing-newline ()
@@ -202,7 +202,7 @@
(search-backward "}")
(insert " ")
(save-buffer)
- (let ((file buffer-file-name)
+ (let ((file (diff-hl--buffer-file-name))
(dest-buffer (get-buffer-create " *diff-hl-test*")))
(diff-hl-diff-buffer-with-reference file dest-buffer nil 3)
(with-current-buffer dest-buffer