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

Reply via email to