Improve diff-mode navigation/manipulation
commit2c8a7e50d24daf19ea7d86f1cfeaa98a41c56085
authorDima Kogan <Dmitriy.Kogan@jpl.nasa.gov>
Wed, 14 Sep 2016 22:25:06 +0000 (14 15:25 -0700)
committerNoam Postavsky <npostavs@gmail.com>
Tue, 29 Nov 2016 03:40:03 +0000 (28 22:40 -0500)
tree66ce90e9b87ee861f9f8faac4820855375a95637
parent753c565df6aa693c75c38816059051a1aebbcbb1
Improve diff-mode navigation/manipulation

This is Bug #17544.

Navigation and use of diff buffers had several annoying corner cases
that this patch fixes.  These corner cases were largely due to
inconsistent treatment of file headers.  Say you have a diff such as
this:

 --- aaa
 +++ bbb
 @@ -52,7 +52,7 @@
 hunk1
 @@ -74,7 +74,7 @@
 hunk2
 --- ccc
 +++ ddd
 @@ -608,6 +608,6 @@
 hunk3
 @@ -654,7 +654,7 @@
 hunk4

The file headers here are the '---' and '+++' lines.  With the point on
such a line, hunk operations would sometimes refer to the next hunk and
sometimes to the previous hunk.  Most of the time it would be the
previous hunk, which is not what the user would expect.  This patch
consistently treats such headers as the next hunk.  So with this patch,
if the point is on the '--- ccc' line, the point is seen as referring to
hunk3.

Specific behaviors this fixes are:

1. It should be possible to place the point in the middle of a diff
buffer, and press M-k repeatedly to kill hunks in the order they appear
in the buffer.  With the point on hunk1, M-k M-k would kill hunk1 then
hunk2.  With the point on hunk3, it would kill hunk3 then hunk4; this is
fine.  However, with the point on hunk2, it'd kill hunk2 then hunk1.
This is fixed by this patch.

2. Similarly, it should be possible to apply hunks in order.  Previously
with the point at the start, C-c C-a would apply the hunk1, then move
the point to the first @@ header, and thus C-c C-a would try to apply
the same hunk again.

* lisp/vc/diff-mode.el (diff--wrap-navigation): New function to add better
navigation logic to diff-{hunk,file}-{next,prev}.
(diff-hunk-next, diff-hunk-prev):
(diff-file-next, diff-file-prev): Better navigation logic if
skip-hunk-start is true, which happens when called interactively.
(diff-bounds-of-hunk, diff-find-source-location):
(diff-apply-hunk, diff-current-defun, diff-refine-hunk): Small tweaks to
improve hunk navigation.
lisp/vc/diff-mode.el