vim-patch:9.1.1009: diff feature can be improved

Problem:  diff feature can be improved
Solution: include the linematch diff alignment algorithm
          (Jonathon)

closes: vim/vim#9661

7c7a4e6d1a

Co-authored-by: Jonathon <jonathonwhite@protonmail.com>
This commit is contained in:
zeertzjq 2025-02-03 21:52:53 +08:00
parent 5a7cf85c2c
commit 290bb4c64b
7 changed files with 614 additions and 159 deletions

View File

@ -184,6 +184,7 @@ information.
mch_memmove memmove
vim_memset copy_chars copy_spaces memset
vim_strbyte strchr
vim_strnchr strnchr
vim_strncpy strncpy xstrlcpy/xmemcpyz
vim_strcat strncat xstrlcat
VIM_ISWHITE ascii_iswhite

View File

@ -2037,11 +2037,20 @@ A jump table for the options with a short description can be found at |Q_op|.
Option settings for diff mode. It can consist of the following items.
All are optional. Items must be separated by a comma.
filler Show filler lines, to keep the text
synchronized with a window that has inserted
lines at the same position. Mostly useful
when windows are side-by-side and 'scrollbind'
is set.
algorithm:{text} Use the specified diff algorithm with the
internal diff engine. Currently supported
algorithms are:
myers the default algorithm
minimal spend extra time to generate the
smallest possible diff
patience patience diff algorithm
histogram histogram diff algorithm
closeoff When a window is closed where 'diff' is set
and there is only one window remaining in the
same tab page with 'diff' set, execute
`:diffoff` in that window. This undoes a
`:diffsplit` command.
context:{n} Use a context of {n} lines between a change
and a fold that contains unchanged lines.
@ -2052,6 +2061,23 @@ A jump table for the options with a short description can be found at |Q_op|.
value (999999) to disable folding completely.
See |fold-diff|.
filler Show filler lines, to keep the text
synchronized with a window that has inserted
lines at the same position. Mostly useful
when windows are side-by-side and 'scrollbind'
is set.
foldcolumn:{n} Set the 'foldcolumn' option to {n} when
starting diff mode. Without this 2 is used.
followwrap Follow the 'wrap' option and leave as it is.
horizontal Start diff mode with horizontal splits (unless
explicitly specified otherwise).
hiddenoff Do not use diff mode for a buffer when it
becomes hidden.
iblank Ignore changes where lines are all blank. Adds
the "-B" flag to the "diff" command if
'diffexpr' is empty. Check the documentation
@ -2065,6 +2091,17 @@ A jump table for the options with a short description can be found at |Q_op|.
are considered the same. Adds the "-i" flag
to the "diff" command if 'diffexpr' is empty.
indent-heuristic
Use the indent heuristic for the internal
diff library.
internal Use the internal diff library. This is
ignored when 'diffexpr' is set. *E960*
When running out of memory when writing a
buffer this item will be ignored for diffs
involving that buffer. Set the 'verbose'
option to see when this happens.
iwhite Ignore changes in amount of white space. Adds
the "-b" flag to the "diff" command if
'diffexpr' is empty. Check the documentation
@ -2084,56 +2121,19 @@ A jump table for the options with a short description can be found at |Q_op|.
of the "diff" command for what this does
exactly.
horizontal Start diff mode with horizontal splits (unless
explicitly specified otherwise).
linematch:{n} Align and mark changes between the most
similar lines between the buffers. When the
total number of lines in the diff hunk exceeds
{n}, the lines will not be aligned because for
very large diff hunks there will be a
noticeable lag. A reasonable setting is
"linematch:60", as this will enable alignment
for a 2 buffer diff hunk of 30 lines each,
or a 3 buffer diff hunk of 20 lines each.
vertical Start diff mode with vertical splits (unless
explicitly specified otherwise).
closeoff When a window is closed where 'diff' is set
and there is only one window remaining in the
same tab page with 'diff' set, execute
`:diffoff` in that window. This undoes a
`:diffsplit` command.
hiddenoff Do not use diff mode for a buffer when it
becomes hidden.
foldcolumn:{n} Set the 'foldcolumn' option to {n} when
starting diff mode. Without this 2 is used.
followwrap Follow the 'wrap' option and leave as it is.
internal Use the internal diff library. This is
ignored when 'diffexpr' is set. *E960*
When running out of memory when writing a
buffer this item will be ignored for diffs
involving that buffer. Set the 'verbose'
option to see when this happens.
indent-heuristic
Use the indent heuristic for the internal
diff library.
linematch:{n} Enable a second stage diff on each generated
hunk in order to align lines. When the total
number of lines in a hunk exceeds {n}, the
second stage diff will not be performed as
very large hunks can cause noticeable lag. A
recommended setting is "linematch:60", as this
will enable alignment for a 2 buffer diff with
hunks of up to 30 lines each, or a 3 buffer
diff with hunks of up to 20 lines each.
algorithm:{text} Use the specified diff algorithm with the
internal diff engine. Currently supported
algorithms are:
myers the default algorithm
minimal spend extra time to generate the
smallest possible diff
patience patience diff algorithm
histogram histogram diff algorithm
Examples: >vim
set diffopt=internal,filler,context:4
set diffopt=

View File

@ -351,7 +351,6 @@ Options:
- 'autoread' works in the terminal (if it supports "focus" events)
- 'background' cannot be set to empty.
- 'cpoptions' flags: |cpo-_|
- 'diffopt' "linematch" feature
- 'eadirection' cannot be set to empty.
- 'exrc' searches for ".nvim.lua", ".nvimrc", or ".exrc" files. The
user is prompted whether to trust the file.
@ -466,6 +465,7 @@ Upstreamed features *nvim-upstreamed*
These Nvim features were later integrated into Vim.
- 'diffopt' "linematch" feature
- 'fillchars' flags: "eob"
- 'jumpoptions' "stack" behavior
- 'wildoptions' flags: "pum" enables popupmenu for wildmode completion

View File

@ -1631,11 +1631,20 @@ vim.go.dex = vim.go.diffexpr
--- Option settings for diff mode. It can consist of the following items.
--- All are optional. Items must be separated by a comma.
---
--- filler Show filler lines, to keep the text
--- synchronized with a window that has inserted
--- lines at the same position. Mostly useful
--- when windows are side-by-side and 'scrollbind'
--- is set.
--- algorithm:{text} Use the specified diff algorithm with the
--- internal diff engine. Currently supported
--- algorithms are:
--- myers the default algorithm
--- minimal spend extra time to generate the
--- smallest possible diff
--- patience patience diff algorithm
--- histogram histogram diff algorithm
---
--- closeoff When a window is closed where 'diff' is set
--- and there is only one window remaining in the
--- same tab page with 'diff' set, execute
--- `:diffoff` in that window. This undoes a
--- `:diffsplit` command.
---
--- context:{n} Use a context of {n} lines between a change
--- and a fold that contains unchanged lines.
@ -1646,6 +1655,23 @@ vim.go.dex = vim.go.diffexpr
--- value (999999) to disable folding completely.
--- See `fold-diff`.
---
--- filler Show filler lines, to keep the text
--- synchronized with a window that has inserted
--- lines at the same position. Mostly useful
--- when windows are side-by-side and 'scrollbind'
--- is set.
---
--- foldcolumn:{n} Set the 'foldcolumn' option to {n} when
--- starting diff mode. Without this 2 is used.
---
--- followwrap Follow the 'wrap' option and leave as it is.
---
--- horizontal Start diff mode with horizontal splits (unless
--- explicitly specified otherwise).
---
--- hiddenoff Do not use diff mode for a buffer when it
--- becomes hidden.
---
--- iblank Ignore changes where lines are all blank. Adds
--- the "-B" flag to the "diff" command if
--- 'diffexpr' is empty. Check the documentation
@ -1659,6 +1685,17 @@ vim.go.dex = vim.go.diffexpr
--- are considered the same. Adds the "-i" flag
--- to the "diff" command if 'diffexpr' is empty.
---
--- indent-heuristic
--- Use the indent heuristic for the internal
--- diff library.
---
--- internal Use the internal diff library. This is
--- ignored when 'diffexpr' is set. *E960*
--- When running out of memory when writing a
--- buffer this item will be ignored for diffs
--- involving that buffer. Set the 'verbose'
--- option to see when this happens.
---
--- iwhite Ignore changes in amount of white space. Adds
--- the "-b" flag to the "diff" command if
--- 'diffexpr' is empty. Check the documentation
@ -1678,56 +1715,19 @@ vim.go.dex = vim.go.diffexpr
--- of the "diff" command for what this does
--- exactly.
---
--- horizontal Start diff mode with horizontal splits (unless
--- explicitly specified otherwise).
--- linematch:{n} Align and mark changes between the most
--- similar lines between the buffers. When the
--- total number of lines in the diff hunk exceeds
--- {n}, the lines will not be aligned because for
--- very large diff hunks there will be a
--- noticeable lag. A reasonable setting is
--- "linematch:60", as this will enable alignment
--- for a 2 buffer diff hunk of 30 lines each,
--- or a 3 buffer diff hunk of 20 lines each.
---
--- vertical Start diff mode with vertical splits (unless
--- explicitly specified otherwise).
---
--- closeoff When a window is closed where 'diff' is set
--- and there is only one window remaining in the
--- same tab page with 'diff' set, execute
--- `:diffoff` in that window. This undoes a
--- `:diffsplit` command.
---
--- hiddenoff Do not use diff mode for a buffer when it
--- becomes hidden.
---
--- foldcolumn:{n} Set the 'foldcolumn' option to {n} when
--- starting diff mode. Without this 2 is used.
---
--- followwrap Follow the 'wrap' option and leave as it is.
---
--- internal Use the internal diff library. This is
--- ignored when 'diffexpr' is set. *E960*
--- When running out of memory when writing a
--- buffer this item will be ignored for diffs
--- involving that buffer. Set the 'verbose'
--- option to see when this happens.
---
--- indent-heuristic
--- Use the indent heuristic for the internal
--- diff library.
---
--- linematch:{n} Enable a second stage diff on each generated
--- hunk in order to align lines. When the total
--- number of lines in a hunk exceeds {n}, the
--- second stage diff will not be performed as
--- very large hunks can cause noticeable lag. A
--- recommended setting is "linematch:60", as this
--- will enable alignment for a 2 buffer diff with
--- hunks of up to 30 lines each, or a 3 buffer
--- diff with hunks of up to 20 lines each.
---
--- algorithm:{text} Use the specified diff algorithm with the
--- internal diff engine. Currently supported
--- algorithms are:
--- myers the default algorithm
--- minimal spend extra time to generate the
--- smallest possible diff
--- patience patience diff algorithm
--- histogram histogram diff algorithm
---
--- Examples:
---
--- ```vim

View File

@ -1820,7 +1820,8 @@ static void find_top_diff_block(diff_T **thistopdiff, diff_T **nextblockblock, i
topdiffchange = 0;
}
// check if the fromwin topline is matched by the current diff. if so, set it to the top of the diff block
// check if the fromwin topline is matched by the current diff. if so,
// set it to the top of the diff block
if (topline >= topdiff->df_lnum[fromidx] && topline <=
(topdiff->df_lnum[fromidx] + topdiff->df_count[fromidx])) {
// this line is inside the current diff block, so we will save the
@ -2021,10 +2022,15 @@ static void run_linematch_algorithm(diff_T *dp)
size_t ndiffs = 0;
for (int i = 0; i < DB_COUNT; i++) {
if (curtab->tp_diffbuf[i] != NULL) {
// write the contents of the entire buffer to
// diffbufs_mm[diffbuffers_count]
diff_write_buffer(curtab->tp_diffbuf[i], &diffbufs_mm[ndiffs],
dp->df_lnum[i], dp->df_lnum[i] + dp->df_count[i] - 1);
if (dp->df_count[i] > 0) {
// write the contents of the entire buffer to
// diffbufs_mm[diffbuffers_count]
diff_write_buffer(curtab->tp_diffbuf[i], &diffbufs_mm[ndiffs],
dp->df_lnum[i], dp->df_lnum[i] + dp->df_count[i] - 1);
} else {
diffbufs_mm[ndiffs].size = 0;
diffbufs_mm[ndiffs].ptr = NULL;
}
diffbufs[ndiffs] = &diffbufs_mm[ndiffs];
@ -2060,6 +2066,12 @@ static void run_linematch_algorithm(diff_T *dp)
/// Returns > 0 for inserting that many filler lines above it (never happens
/// when 'diffopt' doesn't contain "filler").
/// This should only be used for windows where 'diff' is set.
/// When diffopt contains linematch, a changed/added/deleted line
/// may also have filler lines above it. In such a case, the possibilities
/// are no longer mutually exclusive. The number of filler lines is
/// returned from diff_check, and the integer 'linestatus' passed by
/// pointer is set to -1 to indicate a changed line, and -2 to indicate an
/// added line
///
/// @param wp
/// @param lnum

View File

@ -2178,11 +2178,20 @@ local options = {
Option settings for diff mode. It can consist of the following items.
All are optional. Items must be separated by a comma.
filler Show filler lines, to keep the text
synchronized with a window that has inserted
lines at the same position. Mostly useful
when windows are side-by-side and 'scrollbind'
is set.
algorithm:{text} Use the specified diff algorithm with the
internal diff engine. Currently supported
algorithms are:
myers the default algorithm
minimal spend extra time to generate the
smallest possible diff
patience patience diff algorithm
histogram histogram diff algorithm
closeoff When a window is closed where 'diff' is set
and there is only one window remaining in the
same tab page with 'diff' set, execute
`:diffoff` in that window. This undoes a
`:diffsplit` command.
context:{n} Use a context of {n} lines between a change
and a fold that contains unchanged lines.
@ -2193,6 +2202,23 @@ local options = {
value (999999) to disable folding completely.
See |fold-diff|.
filler Show filler lines, to keep the text
synchronized with a window that has inserted
lines at the same position. Mostly useful
when windows are side-by-side and 'scrollbind'
is set.
foldcolumn:{n} Set the 'foldcolumn' option to {n} when
starting diff mode. Without this 2 is used.
followwrap Follow the 'wrap' option and leave as it is.
horizontal Start diff mode with horizontal splits (unless
explicitly specified otherwise).
hiddenoff Do not use diff mode for a buffer when it
becomes hidden.
iblank Ignore changes where lines are all blank. Adds
the "-B" flag to the "diff" command if
'diffexpr' is empty. Check the documentation
@ -2206,6 +2232,17 @@ local options = {
are considered the same. Adds the "-i" flag
to the "diff" command if 'diffexpr' is empty.
indent-heuristic
Use the indent heuristic for the internal
diff library.
internal Use the internal diff library. This is
ignored when 'diffexpr' is set. *E960*
When running out of memory when writing a
buffer this item will be ignored for diffs
involving that buffer. Set the 'verbose'
option to see when this happens.
iwhite Ignore changes in amount of white space. Adds
the "-b" flag to the "diff" command if
'diffexpr' is empty. Check the documentation
@ -2225,56 +2262,19 @@ local options = {
of the "diff" command for what this does
exactly.
horizontal Start diff mode with horizontal splits (unless
explicitly specified otherwise).
linematch:{n} Align and mark changes between the most
similar lines between the buffers. When the
total number of lines in the diff hunk exceeds
{n}, the lines will not be aligned because for
very large diff hunks there will be a
noticeable lag. A reasonable setting is
"linematch:60", as this will enable alignment
for a 2 buffer diff hunk of 30 lines each,
or a 3 buffer diff hunk of 20 lines each.
vertical Start diff mode with vertical splits (unless
explicitly specified otherwise).
closeoff When a window is closed where 'diff' is set
and there is only one window remaining in the
same tab page with 'diff' set, execute
`:diffoff` in that window. This undoes a
`:diffsplit` command.
hiddenoff Do not use diff mode for a buffer when it
becomes hidden.
foldcolumn:{n} Set the 'foldcolumn' option to {n} when
starting diff mode. Without this 2 is used.
followwrap Follow the 'wrap' option and leave as it is.
internal Use the internal diff library. This is
ignored when 'diffexpr' is set. *E960*
When running out of memory when writing a
buffer this item will be ignored for diffs
involving that buffer. Set the 'verbose'
option to see when this happens.
indent-heuristic
Use the indent heuristic for the internal
diff library.
linematch:{n} Enable a second stage diff on each generated
hunk in order to align lines. When the total
number of lines in a hunk exceeds {n}, the
second stage diff will not be performed as
very large hunks can cause noticeable lag. A
recommended setting is "linematch:60", as this
will enable alignment for a 2 buffer diff with
hunks of up to 30 lines each, or a 3 buffer
diff with hunks of up to 20 lines each.
algorithm:{text} Use the specified diff algorithm with the
internal diff engine. Currently supported
algorithms are:
myers the default algorithm
minimal spend extra time to generate the
smallest possible diff
patience patience diff algorithm
histogram histogram diff algorithm
Examples: >vim
set diffopt=internal,filler,context:4
set diffopt=

View File

@ -1017,6 +1017,41 @@ func Test_diff_screen()
call WriteDiffFiles(buf, [], [0])
call VerifyBoth(buf, "Test_diff_22", "")
call WriteDiffFiles(buf, ['?a', '?b', '?c'], ['!b'])
call VerifyInternal(buf, 'Test_diff_23', " diffopt+=linematch:30")
call WriteDiffFiles(buf, ['',
\ 'common line',
\ 'common line',
\ '',
\ 'DEFabc',
\ 'xyz',
\ 'xyz',
\ 'xyz',
\ 'DEFabc',
\ 'DEFabc',
\ 'DEFabc',
\ 'common line',
\ 'common line',
\ 'DEF',
\ 'common line',
\ 'DEF',
\ 'something' ],
\ ['',
\ 'common line',
\ 'common line',
\ '',
\ 'ABCabc',
\ 'ABCabc',
\ 'ABCabc',
\ 'ABCabc',
\ 'common line',
\ 'common line',
\ 'common line',
\ 'something'])
call VerifyInternal(buf, 'Test_diff_24', " diffopt+=linematch:30")
" clean up
call StopVimInTerminal(buf)
call delete('Xdifile1')
@ -2040,4 +2075,411 @@ func Test_diff_topline_noscroll()
call StopVimInTerminal(buf)
endfunc
func Test_diffget_diffput_linematch()
CheckScreendump
call delete('.Xdifile1.swp')
call delete('.Xdifile2.swp')
call WriteDiffFiles(0, [], [])
let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {})
call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
" enable linematch
call term_sendkeys(buf, ":set diffopt+=linematch:30\<CR>")
call WriteDiffFiles(buf, ['',
\ 'common line',
\ 'common line',
\ '',
\ 'ABCabc',
\ 'ABCabc',
\ 'ABCabc',
\ 'ABCabc',
\ 'common line',
\ 'common line',
\ 'common line',
\ 'something' ],
\ ['',
\ 'common line',
\ 'common line',
\ '',
\ 'DEFabc',
\ 'xyz',
\ 'xyz',
\ 'xyz',
\ 'DEFabc',
\ 'DEFabc',
\ 'DEFabc',
\ 'common line',
\ 'common line',
\ 'DEF',
\ 'common line',
\ 'DEF',
\ 'something'])
call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_1', {})
" get from window 1 from line 5 to 9
call term_sendkeys(buf, "1\<c-w>w")
call term_sendkeys(buf, ":5,9diffget\<CR>")
call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_2', {})
" undo the last diffget
call term_sendkeys(buf, "u")
" get from window 2 from line 5 to 10
call term_sendkeys(buf, "2\<c-w>w")
call term_sendkeys(buf, ":5,10diffget\<CR>")
call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_3', {})
" undo the last diffget
call term_sendkeys(buf, "u")
" get all from window 2
call term_sendkeys(buf, "2\<c-w>w")
call term_sendkeys(buf, ":4,17diffget\<CR>")
call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_4', {})
" undo the last diffget
call term_sendkeys(buf, "u")
" get all from window 1
call term_sendkeys(buf, "1\<c-w>w")
call term_sendkeys(buf, ":4,12diffget\<CR>")
call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_5', {})
" undo the last diffget
call term_sendkeys(buf, "u")
" get from window 1 using do 1 line 5
call term_sendkeys(buf, "1\<c-w>w")
call term_sendkeys(buf, "5gg")
call term_sendkeys(buf, ":diffget\<CR>")
call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_6', {})
" undo the last diffget
call term_sendkeys(buf, "u")
" get from window 1 using do 2 line 6
call term_sendkeys(buf, "1\<c-w>w")
call term_sendkeys(buf, "6gg")
call term_sendkeys(buf, ":diffget\<CR>")
call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_7', {})
" undo the last diffget
call term_sendkeys(buf, "u")
" get from window 1 using do 2 line 7
call term_sendkeys(buf, "1\<c-w>w")
call term_sendkeys(buf, "7gg")
call term_sendkeys(buf, ":diffget\<CR>")
call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_8', {})
" undo the last diffget
call term_sendkeys(buf, "u")
" get from window 1 using do 2 line 11
call term_sendkeys(buf, "1\<c-w>w")
call term_sendkeys(buf, "11gg")
call term_sendkeys(buf, ":diffget\<CR>")
call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_9', {})
" undo the last diffget
call term_sendkeys(buf, "u")
" get from window 1 using do 2 line 12
call term_sendkeys(buf, "1\<c-w>w")
call term_sendkeys(buf, "12gg")
call term_sendkeys(buf, ":diffget\<CR>")
call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_10', {})
" undo the last diffget
call term_sendkeys(buf, "u")
" put from window 1 using dp 1 line 5
call term_sendkeys(buf, "1\<c-w>w")
call term_sendkeys(buf, "5gg")
call term_sendkeys(buf, ":diffput\<CR>")
call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_11', {})
" undo the last diffput
call term_sendkeys(buf, "2\<c-w>w")
call term_sendkeys(buf, "u")
" put from window 1 using dp 2 line 6
call term_sendkeys(buf, "1\<c-w>w")
call term_sendkeys(buf, "6gg")
call term_sendkeys(buf, ":diffput\<CR>")
call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_12', {})
" undo the last diffput
call term_sendkeys(buf, "2\<c-w>w")
call term_sendkeys(buf, "u")
" put from window 1 using dp 2 line 7
call term_sendkeys(buf, "1\<c-w>w")
call term_sendkeys(buf, "7gg")
call term_sendkeys(buf, ":diffput\<CR>")
call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_13', {})
" undo the last diffput
call term_sendkeys(buf, "2\<c-w>w")
call term_sendkeys(buf, "u")
" put from window 1 using dp 2 line 11
call term_sendkeys(buf, "1\<c-w>w")
call term_sendkeys(buf, "11gg")
call term_sendkeys(buf, ":diffput\<CR>")
call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_14', {})
" undo the last diffput
call term_sendkeys(buf, "2\<c-w>w")
call term_sendkeys(buf, "u")
" put from window 1 using dp 2 line 12
call term_sendkeys(buf, "1\<c-w>w")
call term_sendkeys(buf, "12gg")
call term_sendkeys(buf, ":diffput\<CR>")
call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_15', {})
" undo the last diffput
call term_sendkeys(buf, "2\<c-w>w")
call term_sendkeys(buf, "u")
" put from window 2 using dp line 6
call term_sendkeys(buf, "2\<c-w>w")
call term_sendkeys(buf, "6gg")
call term_sendkeys(buf, ":diffput\<CR>")
call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_16', {})
" undo the last diffput
call term_sendkeys(buf, "1\<c-w>w")
call term_sendkeys(buf, "u")
" put from window 2 using dp line 8
call term_sendkeys(buf, "2\<c-w>w")
call term_sendkeys(buf, "8gg")
call term_sendkeys(buf, ":diffput\<CR>")
call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_17', {})
" undo the last diffput
call term_sendkeys(buf, "1\<c-w>w")
call term_sendkeys(buf, "u")
" put from window 2 using dp line 9
call term_sendkeys(buf, "2\<c-w>w")
call term_sendkeys(buf, "9gg")
call term_sendkeys(buf, ":diffput\<CR>")
call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_18', {})
" undo the last diffput
call term_sendkeys(buf, "1\<c-w>w")
call term_sendkeys(buf, "u")
" put from window 2 using dp line 17
call term_sendkeys(buf, "2\<c-w>w")
call term_sendkeys(buf, "17gg")
call term_sendkeys(buf, ":diffput\<CR>")
call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_19', {})
endfunc
func Test_linematch_diff()
CheckScreendump
call delete('.Xdifile1.swp')
call delete('.Xdifile2.swp')
call WriteDiffFiles(0, [], [])
let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {})
call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
" enable linematch
call term_sendkeys(buf, ":set diffopt+=linematch:30\<CR>")
call WriteDiffFiles(buf, ['// abc d?',
\ '// d?',
\ '// d?' ],
\ ['!',
\ 'abc d!',
\ 'd!'])
call VerifyScreenDump(buf, 'Test_linematch_diff1', {})
endfunc
func Test_linematch_diff_iwhite()
CheckScreendump
call delete('.Xdifile1.swp')
call delete('.Xdifile2.swp')
call WriteDiffFiles(0, [], [])
let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {})
call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
" setup a diff with 2 files and set linematch:30, with ignore white
call term_sendkeys(buf, ":set diffopt+=linematch:30\<CR>")
call WriteDiffFiles(buf, ['void testFunction () {',
\ ' for (int i = 0; i < 10; i++) {',
\ ' for (int j = 0; j < 10; j++) {',
\ ' }',
\ ' }',
\ '}' ],
\ ['void testFunction () {',
\ ' // for (int j = 0; j < 10; i++) {',
\ ' // }',
\ '}'])
call VerifyScreenDump(buf, 'Test_linematch_diff_iwhite1', {})
call term_sendkeys(buf, ":set diffopt+=iwhiteall\<CR>")
call VerifyScreenDump(buf, 'Test_linematch_diff_iwhite2', {})
endfunc
func Test_linematch_diff_grouping()
CheckScreendump
call delete('.Xdifile1.swp')
call delete('.Xdifile2.swp')
call WriteDiffFiles(0, [], [])
let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {})
call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
" a diff that would result in multiple groups before grouping optimization
call term_sendkeys(buf, ":set diffopt+=linematch:30\<CR>")
call WriteDiffFiles(buf, ['!A',
\ '!B',
\ '!C' ],
\ ['?Z',
\ '?A',
\ '?B',
\ '?C',
\ '?A',
\ '?B',
\ '?B',
\ '?C'])
call VerifyScreenDump(buf, 'Test_linematch_diff_grouping1', {})
call WriteDiffFiles(buf, ['!A',
\ '!B',
\ '!C' ],
\ ['?A',
\ '?Z',
\ '?B',
\ '?C',
\ '?A',
\ '?B',
\ '?C',
\ '?C'])
call VerifyScreenDump(buf, 'Test_linematch_diff_grouping2', {})
endfunc
func Test_linematch_diff_scroll()
CheckScreendump
call delete('.Xdifile1.swp')
call delete('.Xdifile2.swp')
call WriteDiffFiles(0, [], [])
let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {})
call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
" a diff that would result in multiple groups before grouping optimization
call term_sendkeys(buf, ":set diffopt+=linematch:30\<CR>")
call WriteDiffFiles(buf, ['!A',
\ '!B',
\ '!C' ],
\ ['?A',
\ '?Z',
\ '?B',
\ '?C',
\ '?A',
\ '?B',
\ '?C',
\ '?C'])
" scroll down to show calculation of top fill and scroll to correct line in
" both windows
call VerifyScreenDump(buf, 'Test_linematch_diff_grouping_scroll0', {})
call term_sendkeys(buf, "3\<c-e>")
call VerifyScreenDump(buf, 'Test_linematch_diff_grouping_scroll1', {})
call term_sendkeys(buf, "3\<c-e>")
call VerifyScreenDump(buf, 'Test_linematch_diff_grouping_scroll2', {})
endfunc
func Test_linematch_line_limit_exceeded()
CheckScreendump
call delete('.Xdifile1.swp')
call delete('.Xdifile2.swp')
call WriteDiffFiles(0, [], [])
let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {})
call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
call term_sendkeys(buf, ":set diffopt+=linematch:10\<CR>")
" a diff block will not be aligned with linematch because it's contents
" exceed 10 lines
call WriteDiffFiles(buf,
\ ['common line',
\ 'HIL',
\ '',
\ 'aABCabc',
\ 'aABCabc',
\ 'aABCabc',
\ 'aABCabc',
\ 'common line',
\ 'HIL',
\ 'common line',
\ 'something'],
\ ['common line',
\ 'DEF',
\ 'GHI',
\ 'something',
\ '',
\ 'aDEFabc',
\ 'xyz',
\ 'xyz',
\ 'xyz',
\ 'aDEFabc',
\ 'aDEFabc',
\ 'aDEFabc',
\ 'common line',
\ 'DEF',
\ 'GHI',
\ 'something else',
\ 'common line',
\ 'something'])
call VerifyScreenDump(buf, 'Test_linematch_line_limit_exceeded1', {})
" after increasing the count to 30, the limit is not exceeded, and the
" alignment algorithm will run on the largest diff block here
call term_sendkeys(buf, ":set diffopt+=linematch:30\<CR>")
call VerifyScreenDump(buf, 'Test_linematch_line_limit_exceeded2', {})
endfunc
func Test_linematch_3diffs()
CheckScreendump
call delete('.Xdifile1.swp')
call delete('.Xdifile2.swp')
call delete('.Xdifile3.swp')
call WriteDiffFiles3(0, [], [], [])
let buf = RunVimInTerminal('-d Xdifile1 Xdifile2 Xdifile3', {})
call term_sendkeys(buf, "1\<c-w>w:set autoread\<CR>")
call term_sendkeys(buf, "2\<c-w>w:set autoread\<CR>")
call term_sendkeys(buf, "3\<c-w>w:set autoread\<CR>")
call term_sendkeys(buf, ":set diffopt+=linematch:30\<CR>")
call WriteDiffFiles3(buf,
\ ["",
\ " common line",
\ " AAA",
\ " AAA",
\ " AAA"],
\ ["",
\ " common line",
\ " <<<<<<< HEAD",
\ " AAA",
\ " AAA",
\ " AAA",
\ " =======",
\ " BBB",
\ " BBB",
\ " BBB",
\ " >>>>>>> branch1"],
\ ["",
\ " common line",
\ " BBB",
\ " BBB",
\ " BBB"])
call VerifyScreenDump(buf, 'Test_linematch_3diffs1', {})
endfunc
" vim: shiftwidth=2 sts=2 expandtab