mirror of
https://github.com/neovim/neovim.git
synced 2025-10-17 15:21:47 +00:00
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:
@@ -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
|
||||
|
@@ -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=
|
||||
|
Reference in New Issue
Block a user