Problem: not possible to anchor specific lines in diff mode
Solution: Add support for the anchoring lines in diff mode using the
'diffanchor' option (Yee Cheng Chin).
Adds support for anchoring specific lines to each other while viewing a
diff. While lines are anchored, they are guaranteed to be aligned to
each other in a diff view, allowing the user to control and inform the
diff algorithm what the desired alignment is. Internally, this is done
by splitting up the buffer at each anchor and run the diff algorithm on
each split section separately, and then merge the results back for a
logically consistent diff result.
To do this, add a new "diffanchors" option that takes a list of
`{address}`, and a new "diffopt" option value "anchor". Each address
specified will be an anchor, and the user can choose to use any type of
address, including marks, line numbers, or pattern search. Anchors are
sorted by line number in each file, and it's possible to have multiple
anchors on the same line (this is useful when doing multi-buffer diff).
Update documentation to provide examples.
This is similar to Git diff's `--anchored` flag. Other diff tools like
Meld/Araxis Merge also have similar features (called "synchronization
points" or "synchronization links"). We are not using Git/Xdiff's
`--anchored` implementation here because it has a very limited API
(it requires usage of the Patience algorithm, and can only anchor
unique lines that are the same across both files).
Because the user could anchor anywhere, diff anchors could result in
adjacent diff blocks (one block is directly touching another without a
gap), if there is a change right above the anchor point. We don't want
to merge these diff blocks because we want to line up the change at the
anchor. Adjacent diff blocks were first allowed when linematch was
added, but the existing code had a lot of branched paths where
line-matched diff blocks were handled differently. As a part of this
change, refactor them to have a more unified code path that is
generalized enough to handle adjacent diff blocks correctly and without
needing to carve in exceptions all over the place.
closes: vim/vim#176150d9160e11c
Co-authored-by: Yee Cheng Chin <ychin.git@gmail.com>
Problem: inconsistent range arg for :diffget/diffput
Solution: fix the range specification, place the cursor for :diffput and
:diffget consistently on the last line (Yee Cheng Chin)
Previously, `:<range>diffget` only allowed using 1 or above in the range
value, making it impossible to use the command for a diff block at the
beginning of the file. Fix the range specification so the user can now
use 0 to specify the space before the first line. This allows
`:0,$+1diffget` to work to retrieve all the changes from the other file
instead of missing the first diff block. Also do this for `:diffput`.
Also, make `:diffput` work more similar to `:diffget`. Make it so that
if the cursor is on the last line and a new line is inserted in the
other file, doing `:diffput` will select that diff block below the line,
just like `:diffget` would.
Also clean up the logic a little bit for edge cases and for handling
line matched diff blocks better.
closes: vim/vim#17579d75ab0cbf5
Co-authored-by: Yee Cheng Chin <ychin.git@gmail.com>
Problem: Typos in code and docs related to 'diffopt' "inline:".
(after v9.1.1243)
Solution: Fix typos and slightly improve the docs.
(zeertzjq)
closes: vim/vim#169975a307c361c
Problem: Diff mode's inline highlighting is lackluster. It only
performs a line-by-line comparison, and calculates a single
shortest range within a line that could encompass all the
changes. In lines with multiple changes, or those that span
multiple lines, this approach tends to end up highlighting
much more than necessary.
Solution: Implement new inline highlighting modes by doing per-character
or per-word diff within the diff block, and highlight only the
relevant parts, add "inline:simple" to the defaults (which is
the old behaviour)
This change introduces a new diffopt option "inline:<type>". Setting to
"none" will disable all inline highlighting, "simple" (the default) will
use the old behavior, "char" / "word" will perform a character/word-wise
diff of the texts within each diff block and only highlight the
differences.
The new char/word inline diff only use the internal xdiff, and will
respect diff options such as algorithm choice, icase, and misc iwhite
options. indent-heuristics is always on to perform better sliding.
For character highlight, a post-process of the diff results is first
applied before we show the highlight. This is because a naive diff will
create a result with a lot of small diff chunks and gaps, due to the
repetitive nature of individual characters. The post-process is a
heuristic-based refinement that attempts to merge adjacent diff blocks
if they are separated by a short gap (1-3 characters), and can be
further tuned in the future for better results. This process results in
more characters than necessary being highlighted but overall less visual
noise.
For word highlight, always use first buffer's iskeyword definition.
Otherwise if each buffer has different iskeyword settings we would not
be able to group words properly.
The char/word diffing is always per-diff block, not per line, meaning
that changes that span multiple lines will show up correctly.
Added/removed newlines are not shown by default, but if the user has
'list' set (with "eol" listchar defined), the eol character will be be
highlighted correctly for the specific newline characters.
Also, add a new "DiffTextAdd" highlight group linked to "DiffText" by
default. It allows color schemes to use different colors for texts that
have been added within a line versus modified.
This doesn't interact with linematch perfectly currently. The linematch
feature splits up diff blocks into multiple smaller blocks for better
visual matching, which makes inline highlight less useful especially for
multi-line change (e.g. a line is broken into two lines). This could be
addressed in the future.
As a side change, this also removes the bounds checking introduced to
diff_read() as they were added to mask existing logic bugs that were
properly fixed in vim/vim#16768.
closes: vim/vim#168819943d4790e
Co-authored-by: Yee Cheng Chin <ychin.git@gmail.com>
Problem: It is not easy to use a script-local function for an option.
Solution: recognize s: and <SID> at the start of the expression. (Yegappan
Lakshmanan, closesvim/vim#9401)
8bb65f230d
Omit duplicate docs in fold.txt: removed in a later runtime update.
Cherry-pick test_diffmode.vim changes from patch 8.2.1432.
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Problem: Using an external diff program is slow and inflexible.
Solution: Include the xdiff library. (Christian Brabandt)
Use it by default.
e828b7621c
vim-patch:8.1.0360
vim-patch:8.1.0364
vim-patch:8.1.0366
vim-patch:8.1.0370
vim-patch:8.1.0377
vim-patch:8.1.0378
vim-patch:8.1.0381
vim-patch:8.1.0396
vim-patch:8.1.0432
Updated runtime files.
b4ff518d95
Missing files: runtime/doc/tags, runtime/doc/todo.txt. Changes to
runtime/doc/if_pyth.txt, runtime/doc/options.txt and runtime/doc/quickref.txt
did not aply. Excluded runtime/syntax/vim.vim.
Note about ~/.local/share/nvim/site used in one usr_\* file: this one talks
about user-local installation of third-party plugins, and
~/.local/share/nvim/site is the proper place for them. Most other files talk
about user own configuration and this is ~/.config.
Vim runtime files based on 7.4.384 / hg changeset 7090d7f160f7
Excluding:
Amiga icons (*.info, icons/)
doc/hangulin.txt
tutor/
spell/
lang/ (only used for menu translations)
macros/maze/, macros/hanoi/, macros/life/, macros/urm/
These were used to test vi compatibility.
termcap
"Demonstration of a termcap file (for the Amiga and Archimedes)"
Helped-by: Rich Wareham <rjw57@cam.ac.uk>
Helped-by: John <john.schmidt.h@gmail.com>
Helped-by: Yann <yann@yann-salaun.com>
Helped-by: Christophe Badoit <c.badoit@lesiteimmo.com>
Helped-by: drasill <github@tof2k.com>
Helped-by: Tae Sandoval Murgan <taecilla@gmail.com>
Helped-by: Lowe Thiderman <lowe.thiderman@gmail.com>