Improve intra-line change highlighting

Handle two insertions and two deletions.
This commit is contained in:
Andy Stewart
2019-09-23 15:59:37 +01:00
parent ae9edf0602
commit 68e735b92c
2 changed files with 88 additions and 9 deletions

View File

@@ -1,7 +1,12 @@
" Calculates the changed portions of lines. Based closely on diff-highlight
" (included with git) - please note its caveats.
" Calculates the changed portions of lines.
"
" Based on:
"
" - diff-highlight (included with git)
" https://github.com/git/git/blob/master/contrib/diff-highlight/DiffHighlight.pm
"
" - Diff Strategies, Neil Fraser
" https://neil.fraser.name/writing/diff/
" Returns a list of intra-line changed regions.
@@ -40,10 +45,49 @@ function! gitgutter#diff_highlight#process(hunk_body)
let prefix = s:common_prefix(rline, aline)
let [rsuffix, asuffix] = s:common_suffix(rline, aline, prefix+1)
let rtext = rline[prefix+1:rsuffix-1]
let atext = aline[prefix+1:asuffix-1]
" singular insertion
if empty(rtext)
if len(atext) != len(aline) " not whole line
call add(regions, [i+1+removed, '+', prefix+1+1, asuffix+1-1])
endif
continue
endif
" singular deletion
if empty(atext)
if len(rtext) != len(rline) " not whole line
call add(regions, [i+1, '-', prefix+1+1, rsuffix+1-1])
endif
continue
endif
" two insertions
let j = stridx(atext, rtext)
if j != -1
call add(regions, [i+1+removed, '+', prefix+1+1, prefix+j+1])
call add(regions, [i+1+removed, '+', prefix+1+1+j+len(rtext), asuffix+1-1])
continue
endif
" two deletions
let j = stridx(rtext, atext)
if j != -1
call add(regions, [i+1, '-', prefix+1+1, prefix+j+1])
call add(regions, [i+1, '-', prefix+1+1+j+len(atext), rsuffix+1-1])
continue
endif
" fall back to highlighting entire changed area
" if a change (but not the whole line)
if (prefix != 0 || rsuffix != len(rline)) && prefix+1 < rsuffix
call add(regions, [i+1, '-', prefix+1+1, rsuffix+1-1])
endif
" if a change (but not the whole line)
if (prefix != 0 || asuffix != len(aline)) && prefix+1 < asuffix
call add(regions, [i+1+removed, '+', prefix+1+1, asuffix+1-1])
endif

View File

@@ -953,18 +953,18 @@ function Test_diff_highlight()
call assert_equal(expected, gitgutter#diff_highlight#process(hunk))
" change in middle
let hunk = ['-foo bar baz', '+foo (bar) baz']
let expected = [[1, '-', 6, 8], [2, '+', 6, 10]]
let hunk = ['-foo bar baz', '+foo zip baz']
let expected = [[1, '-', 6, 8], [2, '+', 6, 8]]
call assert_equal(expected, gitgutter#diff_highlight#process(hunk))
" change at start
let hunk = ['-foo bar baz', '+(foo) bar baz']
let expected = [[1, '-', 2, 4], [2, '+', 2, 6]]
let hunk = ['-foo bar baz', '+zip bar baz']
let expected = [[1, '-', 2, 4], [2, '+', 2, 4]]
call assert_equal(expected, gitgutter#diff_highlight#process(hunk))
" change at end
let hunk = ['-foo bar baz', '+foo bar (baz)']
let expected = [[1, '-', 10, 12], [2, '+', 10, 14]]
let hunk = ['-foo bar baz', '+foo bar zip']
let expected = [[1, '-', 10, 12], [2, '+', 10, 12]]
call assert_equal(expected, gitgutter#diff_highlight#process(hunk))
" removed in middle
@@ -976,4 +976,39 @@ function Test_diff_highlight()
let hunk = ['-foo baz', '+foo bar baz']
let expected = [[2, '+', 8, 11]]
call assert_equal(expected, gitgutter#diff_highlight#process(hunk))
" two insertions at start
let hunk = ['-foo bar baz', '+(foo) bar baz']
let expected = [[2, '+', 2, 2], [2, '+', 6, 6]]
call assert_equal(expected, gitgutter#diff_highlight#process(hunk))
" two insertions in middle
let hunk = ['-foo bar baz', '+foo (bar) baz']
let expected = [[2, '+', 6, 6], [2, '+', 10, 10]]
call assert_equal(expected, gitgutter#diff_highlight#process(hunk))
" two insertions at end
let hunk = ['-foo bar baz', '+foo bar (baz)']
let expected = [[2, '+', 10, 10], [2, '+', 14, 14]]
call assert_equal(expected, gitgutter#diff_highlight#process(hunk))
" singular insertion
let hunk = ['-The cat in the hat.', '+The furry cat in the hat.']
call assert_equal([[2, '+', 6, 11]], gitgutter#diff_highlight#process(hunk))
" singular deletion
let hunk = ['-The cat in the hat.', '+The cat.']
call assert_equal([[1, '-', 9, 19]], gitgutter#diff_highlight#process(hunk))
" two insertions
let hunk = ['-The cat in the hat.', '+The furry cat in the teal hat.']
call assert_equal([[2, '+', 6, 11], [2, '+', 22, 26]], gitgutter#diff_highlight#process(hunk))
" two deletions
let hunk = ['-The furry cat in the teal hat.', '+The cat in the hat.']
call assert_equal([[1, '-', 6, 11], [1, '-', 22, 26]], gitgutter#diff_highlight#process(hunk))
" two edits
let hunk = ['-The cat in the hat.', '+The ox in the box.']
call assert_equal([[1, '-', 6, 8], [1, '-', 17, 19], [2, '+', 6, 7], [2, '+', 16, 18]], gitgutter#diff_highlight#process(hunk))
endfunction