Skip to content

Commit 91fcd4f

Browse files
authored
Merge pull request #266 from ultronozm/ediff
Add Ediff support
2 parents 2d7d071 + c200d62 commit 91fcd4f

4 files changed

Lines changed: 74 additions & 7 deletions

File tree

diff-hl-show-hunk-inline.el

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ BUFFER is a buffer with the hunk."
378378
(when smart-lines
379379
(when (not (eq 0 original-lines-number))
380380
original-lines-number)))
381-
(footer "(q)Quit (p)Previous (n)Next (r)Revert (c)Copy original"))
381+
(footer "(q)Quit (p)Previous (n)Next (e)Ediff (r)Revert (c)Copy original"))
382382
(unless diff-hl-show-staged-changes
383383
(setq footer (concat footer " (S)Stage")))
384384
(diff-hl-show-hunk-inline-show

diff-hl-show-hunk-posframe.el

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,11 @@ The button calls an ACTION."
145145
"Copy original (\\[diff-hl-show-hunk-copy-original-text])"
146146
#'diff-hl-show-hunk-copy-original-text)
147147

148+
(diff-hl-show-hunk--posframe-button
149+
"⇄ Ediff"
150+
"Ediff (\\[diff-hl-show-hunk-ediff])"
151+
#'diff-hl-show-hunk-ediff)
152+
148153
(diff-hl-show-hunk--posframe-button
149154
"♻ Revert hunk"
150155
"Revert hunk (\\[diff-hl-show-hunk-revert-hunk])"

diff-hl-show-hunk.el

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ Returns a list with the buffer and the line number of the clicked line."
220220
(define-key map (kbd "p") #'diff-hl-show-hunk-previous)
221221
(define-key map (kbd "n") #'diff-hl-show-hunk-next)
222222
(define-key map (kbd "c") #'diff-hl-show-hunk-copy-original-text)
223+
(define-key map (kbd "e") #'diff-hl-show-hunk-ediff)
223224
(define-key map (kbd "r") #'diff-hl-show-hunk-revert-hunk)
224225
(define-key map (kbd "[") #'diff-hl-show-hunk-previous)
225226
(define-key map (kbd "]") #'diff-hl-show-hunk-next)
@@ -247,6 +248,12 @@ Returns a list with the buffer and the line number of the clicked line."
247248
(diff-hl-show-hunk-hide)
248249
(diff-hl-stage-current-hunk))
249250

251+
(defun diff-hl-show-hunk-ediff ()
252+
"Dismiss the popup and run Ediff for the current hunk."
253+
(interactive)
254+
(diff-hl-show-hunk-hide)
255+
(diff-hl-ediff-current-hunk))
256+
250257
;;;###autoload
251258
(defun diff-hl-show-hunk-previous ()
252259
"Go to previous hunk/change and show it."

diff-hl.el

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,17 @@ BUFFER defaults to the current buffer."
450450
(declare-function vc-git--rev-parse "vc-git")
451451
(declare-function vc-hg-command "vc-hg")
452452
(declare-function vc-bzr-command "vc-bzr")
453+
(declare-function vc-find-revision-no-save "vc")
454+
(declare-function ediff-buffers "ediff")
455+
(declare-function ediff-diff-at-point "ediff-util")
456+
(declare-function ediff-jump-to-difference "ediff-util")
457+
(defvar ediff-number-of-differences)
458+
459+
(defun diff-hl--use-git-index-base-p (backend)
460+
"Whether diff-hl should use the Git index as the reference base."
461+
(and (eq backend 'Git)
462+
(not diff-hl-reference-revision)
463+
(not diff-hl-show-staged-changes)))
453464

454465
(defun diff-hl-changes-buffer (file backend &optional new-rev bufname)
455466
(diff-hl-with-diff-switches
@@ -458,9 +469,7 @@ BUFFER defaults to the current buffer."
458469
(defun diff-hl-diff-against-reference (file backend buffer &optional new-rev)
459470
(cond
460471
((and (not new-rev)
461-
(not diff-hl-reference-revision)
462-
(not diff-hl-show-staged-changes)
463-
(eq backend 'Git))
472+
(diff-hl--use-git-index-base-p backend))
464473
(apply #'vc-git-command buffer
465474
(if (diff-hl--use-async-p) 'async 1)
466475
(list file)
@@ -922,6 +931,54 @@ buffer will show the position corresponding to its current line."
922931
(diff-hl-diff-skip-to line relname)
923932
(setq vc-sentinel-movepoint (point))))))))
924933

934+
(defun diff-hl--ediff-reference-buffer (file)
935+
"Return the reference buffer for FILE used in Ediff."
936+
(unless file
937+
(user-error "No current file"))
938+
(let ((backend (vc-backend file)))
939+
(unless backend
940+
(user-error "The buffer is not under version control"))
941+
(let* ((reference diff-hl-reference-revision)
942+
;; Use the index snapshot only when diff-hl hides staged changes.
943+
(use-index (and (diff-hl--use-git-index-base-p backend)
944+
(not diff-hl-highlight-reference-function)))
945+
(buf
946+
(if use-index
947+
(let ((obj (diff-hl-git-index-object-name file)))
948+
(unless obj
949+
(user-error "No index entry for %s" file))
950+
(let ((filename (diff-hl-git-index-revision file obj)))
951+
(find-file-noselect filename)))
952+
(let ((rev (or reference
953+
(assoc-default backend diff-hl-head-revision-alist)
954+
(diff-hl-working-revision file backend))))
955+
(unless rev
956+
(user-error "No reference revision specified"))
957+
(setq rev (diff-hl-resolved-revision backend rev))
958+
(vc-find-revision-no-save file rev backend)))))
959+
(with-current-buffer buf
960+
(set-buffer-modified-p nil)
961+
(read-only-mode 1))
962+
buf)))
963+
964+
;;;###autoload
965+
(defun diff-hl-ediff-current-hunk ()
966+
"Run Ediff against current comparison base. Jump to hunk at point."
967+
(interactive)
968+
(require 'ediff)
969+
(let* ((pos (point))
970+
(file (or buffer-file-name
971+
(and-let* ((base (buffer-base-buffer)))
972+
(buffer-file-name base))))
973+
(refbuf (diff-hl--ediff-reference-buffer file))
974+
(startup
975+
(list
976+
(lambda ()
977+
(unless (zerop ediff-number-of-differences)
978+
(ediff-jump-to-difference
979+
(max 1 (ediff-diff-at-point 'B pos))))))))
980+
(ediff-buffers refbuf (current-buffer) startup)))
981+
925982
(defun diff-hl-diff-read-revisions (rev1-default)
926983
(let* ((file (diff-hl--buffer-file-name))
927984
(files (list file))
@@ -1541,9 +1598,7 @@ CONTEXT-LINES is the size of the unified diff context, defaults to 0."
15411598
(temporary-file-directory diff-hl-temporary-directory)
15421599
(enable-local-variables nil)
15431600
(rev
1544-
(if (and (eq backend 'Git)
1545-
(not diff-hl-reference-revision)
1546-
(not diff-hl-show-staged-changes))
1601+
(if (diff-hl--use-git-index-base-p backend)
15471602
(diff-hl-git-index-revision
15481603
file
15491604
(diff-hl-git-index-object-name file))

0 commit comments

Comments
 (0)