diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 9b62b45817..6ba1834d82 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -160,6 +160,7 @@ BUILD DEFAULTS +• 'diffopt' default value now includes "indent-heuristic" and "inline:char". • 'statusline' default is exposed as a statusline expression (previously it was implemented as an internal C routine). • 'statusline' includes |vim.diagnostic.status()| diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index a262e09b43..d87fdd005f 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -2182,7 +2182,7 @@ A jump table for the options with a short description can be found at |Q_op|. security reasons. *'diffopt'* *'dip'* -'diffopt' 'dip' string (default "internal,filler,closeoff,inline:simple,linematch:40") +'diffopt' 'dip' string (default "internal,filler,closeoff,indent-heuristic,inline:char,linematch:40") global Option settings for diff mode. It can consist of the following items. All are optional. Items must be separated by a comma. diff --git a/runtime/lua/vim/_meta/options.lua b/runtime/lua/vim/_meta/options.lua index 1eb03dad36..62ae1d36d9 100644 --- a/runtime/lua/vim/_meta/options.lua +++ b/runtime/lua/vim/_meta/options.lua @@ -1936,7 +1936,7 @@ vim.go.dex = vim.go.diffexpr --- --- --- @type string -vim.o.diffopt = "internal,filler,closeoff,inline:simple,linematch:40" +vim.o.diffopt = "internal,filler,closeoff,indent-heuristic,inline:char,linematch:40" vim.o.dip = vim.o.diffopt vim.go.diffopt = vim.o.diffopt vim.go.dip = vim.go.diffopt diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 5aa7e33325..02c7049e83 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -95,9 +95,10 @@ static bool diff_need_update = false; // ex_diffupdate needs to be called #define ALL_WHITE_DIFF (DIFF_IWHITE | DIFF_IWHITEALL | DIFF_IWHITEEOL) #define ALL_INLINE (DIFF_INLINE_NONE | DIFF_INLINE_SIMPLE | DIFF_INLINE_CHAR | DIFF_INLINE_WORD) #define ALL_INLINE_DIFF (DIFF_INLINE_CHAR | DIFF_INLINE_WORD) -static int diff_flags = DIFF_INTERNAL | DIFF_FILLER | DIFF_CLOSE_OFF | DIFF_LINEMATCH; +static int diff_flags = DIFF_INTERNAL | DIFF_FILLER | DIFF_CLOSE_OFF + | DIFF_LINEMATCH | DIFF_INLINE_CHAR; -static int diff_algorithm = 0; +static int diff_algorithm = XDF_INDENT_HEURISTIC; static int linematch_lines = 40; #define LBUFLEN 50 // length of line in diff file diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 4c10557541..a81dd83639 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -2374,7 +2374,7 @@ local options = { { abbreviation = 'dip', cb = 'did_set_diffopt', - defaults = 'internal,filler,closeoff,inline:simple,linematch:40', + defaults = 'internal,filler,closeoff,indent-heuristic,inline:char,linematch:40', -- Keep this in sync with diffopt_changed(). values = { 'filler', diff --git a/test/functional/ui/diff_spec.lua b/test/functional/ui/diff_spec.lua index 1eed0672db..44711d174f 100644 --- a/test/functional/ui/diff_spec.lua +++ b/test/functional/ui/diff_spec.lua @@ -1249,7 +1249,7 @@ end) it('diff updates line numbers below filler lines', function() local screen = Screen.new(40, 14) exec([[ - set diffopt=internal,filler,closeoff + set diffopt=internal,filler call setline(1, ['a', 'a', 'a', 'y', 'b', 'b', 'b', 'b', 'b']) vnew call setline(1, ['a', 'a', 'a', 'x', 'x', 'x', 'b', 'b', 'b', 'b', 'b']) diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua index 22cd601f2f..5e23492424 100644 --- a/test/functional/ui/highlight_spec.lua +++ b/test/functional/ui/highlight_spec.lua @@ -1220,7 +1220,7 @@ describe('CursorLine and CursorLineNr highlights', function() command('windo diffthis') screen:expect([[ {7: }{9:line 1 some text }│{7: }{9:^line 1 some text }| - {7: }{4:line 2 mo}{27:Re text!}{4: }│{7: }{4:line 2 mo}{27:re text}{4: }| + {7: }{4:line 2 mo}{27:R}{4:e text}{27:!}{4: }│{7: }{4:line 2 mo}{27:r}{4:e text }| {7: }{22:extra line! }│{7: }{23:----------------------}| {7: }extra line! │{7: }extra line! |*2 {7: }last line ... │{7: }last line ... | @@ -1232,7 +1232,7 @@ describe('CursorLine and CursorLineNr highlights', function() feed('jjjjj') screen:expect([[ {7: }line 1 some text │{7: }line 1 some text | - {7: }{4:line 2 mo}{27:Re text!}{4: }│{7: }{4:line 2 mo}{27:re text}{4: }| + {7: }{4:line 2 mo}{27:R}{4:e text}{27:!}{4: }│{7: }{4:line 2 mo}{27:r}{4:e text }| {7: }{22:extra line! }│{7: }{23:----------------------}| {7: }extra line! │{7: }extra line! |*2 {7: }last line ... │{7: }last line ... | @@ -1248,7 +1248,7 @@ describe('CursorLine and CursorLineNr highlights', function() feed('kkkk') screen:expect([[ {7: }line 1 some text │{7: }line 1 some text | - {7: }{100:line 2 mo}{101:Re text!}{100: }│{7: }{100:^line 2 mo}{101:re text}{100: }| + {7: }{100:line 2 mo}{101:R}{100:e text}{101:!}{100: }│{7: }{100:^line 2 mo}{101:r}{100:e text }| {7: }{22:extra line! }│{7: }{23:----------------------}| {7: }extra line! │{7: }extra line! |*2 {7: }last line ... │{7: }last line ... | diff --git a/test/functional/ui/linematch_spec.lua b/test/functional/ui/linematch_spec.lua index ee0c32e161..520de31c40 100644 --- a/test/functional/ui/linematch_spec.lua +++ b/test/functional/ui/linematch_spec.lua @@ -31,7 +31,7 @@ describe('Diff mode screen with 3 diffs open', function() before_each(function() clear() - feed(':set diffopt+=linematch:30') + feed(':set diffopt=internal,filler,linematch:30') feed(':e ' .. fname .. '') feed(':vnew ' .. fname_2 .. '') feed(':vnew ' .. fname_3 .. '') @@ -218,7 +218,7 @@ describe('Diff mode screen with 2 diffs open', function() describe('setup a diff with 2 files and set linematch:30', function() before_each(function() - feed(':set diffopt+=linematch:30') + feed(':set diffopt=internal,filler,linematch:30') local f1 = [[ common line @@ -701,7 +701,7 @@ something end) describe('setup a diff with 2 files and set linematch:30', function() before_each(function() - feed(':set diffopt+=linematch:30') + feed(':set diffopt=internal,filler,linematch:30') local f1 = [[ // abc d // d @@ -731,7 +731,7 @@ d end) describe('setup a diff with 2 files and set linematch:30, with ignore white', function() before_each(function() - feed(':set diffopt+=linematch:30:set diffopt+=iwhiteall') + feed(':set diffopt=internal,filler,linematch:30,iwhiteall') local f1 = [[ void testFunction () { for (int i = 0; i < 10; i++) { @@ -767,7 +767,7 @@ void testFunction () { end) describe('a diff that would result in multiple groups before grouping optimization', function() before_each(function() - feed(':set diffopt+=linematch:30') + feed(':set diffopt=internal,filler,linematch:30') local f1 = [[ !A !B @@ -806,7 +806,7 @@ void testFunction () { end) describe('a diff that would result in multiple groups before grouping optimization', function() before_each(function() - feed(':set diffopt+=linematch:30') + feed(':set diffopt=internal,filler,linematch:30') local f1 = [[ !A !B @@ -845,7 +845,7 @@ void testFunction () { end) describe('setup a diff with 2 files and set linematch:10', function() before_each(function() - feed(':set diffopt+=linematch:10') + feed(':set diffopt=internal,filler,linematch:10') local f1 = [[ common line HIL @@ -1024,7 +1024,7 @@ describe('regressions', function() it("doesn't crash with long lines", function() clear() - feed(':set diffopt+=linematch:30') + feed(':set diffopt=internal.filler,linematch:30') screen = Screen.new(100, 20) -- line must be greater than MATCH_CHAR_MAX_LEN n.api.nvim_buf_set_lines(0, 0, -1, false, { string.rep('a', 1000) .. 'hello' }) @@ -1035,7 +1035,7 @@ describe('regressions', function() it('properly computes filler lines for hunks bigger than linematch limit', function() clear() - feed(':set diffopt+=linematch:10') + feed(':set diffopt=internal,filler,linematch:10') screen = Screen.new(100, 20) local lines = {} for i = 0, 29 do @@ -1093,7 +1093,7 @@ describe('regressions', function() n.exec('rightbelow vnew') n.api.nvim_buf_set_lines(0, 0, -1, false, { 'hijklm', 'nopqr', 'stuv' }) n.exec([[ - set diffopt+=linematch:60 + set diffopt=internal,filler,linematch:60 windo diffthis | wincmd t call feedkeys("Aq\") call feedkeys("GAklm\") diff --git a/test/old/testdir/setup.vim b/test/old/testdir/setup.vim index 6938e12906..81aa3f1552 100644 --- a/test/old/testdir/setup.vim +++ b/test/old/testdir/setup.vim @@ -6,7 +6,7 @@ if exists('s:did_load') set completeopt=menu,preview endif set define=^\\s*#\\s*define - set diffopt=internal,filler,closeoff,inline:simple + set diffopt=internal,filler,closeoff,indent-heuristic,inline:char set directory^=. set display= set fillchars=vert:\|,foldsep:\|,fold:- diff --git a/test/old/testdir/test_diffmode.vim b/test/old/testdir/test_diffmode.vim index 62e57bf42b..ca3714cfc4 100644 --- a/test/old/testdir/test_diffmode.vim +++ b/test/old/testdir/test_diffmode.vim @@ -850,6 +850,7 @@ func Test_diff_nomodifiable() endfunc func Test_diff_hlID() + set diffopt=internal,filler new call setline(1, [1, 2, 3, 'Yz', 'a dxxg',]) diffthis @@ -892,6 +893,7 @@ func Test_diff_hlID() call assert_equal(synIDattr(diff_hlID(3, 1), "name"), "") %bwipe! + set diffopt& endfunc func Test_diff_filler() @@ -1060,18 +1062,18 @@ func Test_diff_screen() call term_sendkeys(buf, ":set diffopt+=algorithm:histogram\") call VerifyScreenDump(buf, 'Test_diff_09', {}) - " Test 10-11: normal/indent-heuristic + " Test 10-11: with/without indent-heuristic call term_sendkeys(buf, ":set diffopt&vim\") call WriteDiffFiles(buf, ['', ' def finalize(values)', '', ' values.each do |v|', ' v.finalize', ' end'], \ ['', ' def finalize(values)', '', ' values.each do |v|', ' v.prepare', ' end', '', \ ' values.each do |v|', ' v.finalize', ' end']) call term_sendkeys(buf, ":diffupdate!\") - call term_sendkeys(buf, ":set diffopt+=internal\") - call VerifyScreenDump(buf, 'Test_diff_10', {}) + call term_sendkeys(buf, ":set diffopt+=internal\:\") + call VerifyScreenDump(buf, 'Test_diff_11', {}) " Leave trailing : at commandline! - call term_sendkeys(buf, ":set diffopt+=indent-heuristic\:\") - call VerifyScreenDump(buf, 'Test_diff_11', {}, 'one') + call term_sendkeys(buf, ":set diffopt-=indent-heuristic\:\") + call VerifyScreenDump(buf, 'Test_diff_10', {}, 'one') " shouldn't matter, if indent-algorithm comes before or after the algorithm call term_sendkeys(buf, ":set diffopt&\") call term_sendkeys(buf, ":set diffopt+=indent-heuristic,algorithm:patience\:\") @@ -1312,6 +1314,7 @@ func Test_diff_with_syntax() call writefile(lines, 'Xprogram2.c', 'D') let lines =<< trim END + set diffopt=internal,filler edit Xprogram1.c diffsplit Xprogram2.c END @@ -1454,9 +1457,7 @@ func Test_diff_rnu() CheckScreendump let content =<< trim END - call setline(1, ['a', 'a', 'a', 'y', 'b', 'b', 'b', 'b', 'b']) - vnew - call setline(1, ['a', 'a', 'a', 'x', 'x', 'x', 'b', 'b', 'b', 'b', 'b']) + set diffopt=internal,filler call setline(1, ['a', 'a', 'a', 'y', 'b', 'b', 'b', 'b', 'b']) vnew call setline(1, ['a', 'a', 'a', 'x', 'x', 'x', 'b', 'b', 'b', 'b', 'b']) @@ -1544,6 +1545,7 @@ endfunc " Test for adding/removing lines inside diff chunks, between diff chunks " and before diff chunks func Test_diff_modify_chunks() + set diffopt=internal,filler enew! let w2_id = win_getid() call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']) @@ -1623,6 +1625,7 @@ func Test_diff_modify_chunks() call assert_equal(['', '', '', '', '', '', '', '', ''], hl) %bw! + set diffopt& endfunc func Test_diff_binary() @@ -2616,7 +2619,7 @@ func Test_linematch_diff() call term_sendkeys(buf, ":set autoread\\w:set autoread\\w") " enable linematch - call term_sendkeys(buf, ":set diffopt+=linematch:30\") + call term_sendkeys(buf, ":set diffopt=internal,filler,linematch:30\") call WriteDiffFiles(buf, ['// abc d?', \ '// d?', \ '// d?' ], @@ -2644,7 +2647,7 @@ func Test_linematch_diff_iwhite() call term_sendkeys(buf, ":set autoread\\w:set autoread\\w") " setup a diff with 2 files and set linematch:30, with ignore white - call term_sendkeys(buf, ":set diffopt+=linematch:30\") + call term_sendkeys(buf, ":set diffopt=internal,filler,linematch:30\") call WriteDiffFiles(buf, ['void testFunction () {', \ ' for (int i = 0; i < 10; i++) {', \ ' for (int j = 0; j < 10; j++) {', @@ -2671,7 +2674,7 @@ func Test_linematch_diff_grouping() call term_sendkeys(buf, ":set autoread\\w:set autoread\\w") " a diff that would result in multiple groups before grouping optimization - call term_sendkeys(buf, ":set diffopt+=linematch:30\") + call term_sendkeys(buf, ":set diffopt=internal,filler,linematch:30\") call WriteDiffFiles(buf, ['!A', \ '!B', \ '!C' ], @@ -2709,7 +2712,7 @@ func Test_linematch_diff_scroll() call term_sendkeys(buf, ":set autoread\\w:set autoread\\w") " a diff that would result in multiple groups before grouping optimization - call term_sendkeys(buf, ":set diffopt+=linematch:30\") + call term_sendkeys(buf, ":set diffopt=internal,filler,linematch:30\") call WriteDiffFiles(buf, ['!A', \ '!B', \ '!C' ], @@ -2740,7 +2743,7 @@ func Test_linematch_line_limit_exceeded() let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {}) call term_sendkeys(buf, ":set autoread\\w:set autoread\\w") - call term_sendkeys(buf, ":set diffopt+=linematch:10\") + call term_sendkeys(buf, ":set diffopt=internal,filler,linematch:10\") " a diff block will not be aligned with linematch because it's contents " exceed 10 lines call WriteDiffFiles(buf, @@ -2792,7 +2795,7 @@ func Test_linematch_3diffs() call term_sendkeys(buf, "1\w:set autoread\") call term_sendkeys(buf, "2\w:set autoread\") call term_sendkeys(buf, "3\w:set autoread\") - call term_sendkeys(buf, ":set diffopt+=linematch:30\") + call term_sendkeys(buf, ":set diffopt=internal,filler,linematch:30\") call WriteDiffFiles3(buf, \ ["", \ " common line", @@ -2827,7 +2830,7 @@ func Test_linematch_3diffs_sanity_check() call delete('.Xfile_linematch2.swp') call delete('.Xfile_linematch3.swp') let lines =<< trim END - set diffopt+=linematch:60 + set diffopt=internal,filler,linematch:60 call feedkeys("Aq\") call feedkeys("GAklm\") call feedkeys("o") diff --git a/test/old/testdir/test_scroll_opt.vim b/test/old/testdir/test_scroll_opt.vim index 14092757a1..4408c448ba 100644 --- a/test/old/testdir/test_scroll_opt.vim +++ b/test/old/testdir/test_scroll_opt.vim @@ -302,11 +302,43 @@ func Test_smoothscroll_diff_mode() call StopVimInTerminal(buf) endfunc +func Test_smoothscroll_diff_change_line_default() + CheckScreendump + + " Uses the new diffopt default with indent-heuristic and inline:char + let lines =<< trim END + set diffopt=internal,filler,closeoff,indent-heuristic,inline:char,followwrap smoothscroll + call setline(1, repeat(' abc', &columns)) + call setline(2, 'bar') + call setline(3, repeat(' abc', &columns)) + vnew + call setline(1, repeat(' abc', &columns)) + call setline(2, 'foo') + call setline(3, 'bar') + call setline(4, repeat(' abc', &columns)) + windo exe "normal! 2gg5\" + windo diffthis + END + call writefile(lines, 'XSmoothDiffChangeLine', 'D') + let buf = RunVimInTerminal('-S XSmoothDiffChangeLine', #{rows: 20, columns: 55}) + + call VerifyScreenDump(buf, 'Test_smooth_diff_change_line_1', {}) + call term_sendkeys(buf, "Abar") + call VerifyScreenDump(buf, 'Test_smooth_diff_change_line_2', {}) + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_smooth_diff_change_line_3a', {}) + call term_sendkeys(buf, "yyp") + call VerifyScreenDump(buf, 'Test_smooth_diff_change_line_4', {}) + + call StopVimInTerminal(buf) +endfunc + func Test_smoothscroll_diff_change_line() CheckScreendump + " Uses the old diffopt default let lines =<< trim END - set diffopt+=followwrap smoothscroll + set diffopt=internal,filler,closeoff,followwrap,inline:simple smoothscroll call setline(1, repeat(' abc', &columns)) call setline(2, 'bar') call setline(3, repeat(' abc', &columns))