From 6e05f8afff39a83402784b92272c70361a144159 Mon Sep 17 00:00:00 2001 From: Jaehwang Jung Date: Tue, 5 Dec 2023 09:40:48 +0900 Subject: [PATCH 1/2] fix(change): update fold after on_bytes Problem: With vim.treesitter.foldexpr, `o`-ing two lines above a folded region opens the fold. This does not happen with legacy foldexprs. For example, make a markdown file with the following text (without indentation), enable treesitter fold, and follow the instruction in the text. put cursor on this line and type zoo initially folded, revealed by zo # then this fold will be opened initially folded, revealed by o Analysis: * `o` updates folds first (done in `changed_lines`), evaluating foldexpr, and then invokes `on_bytes` (done in `extmark_splice`). * Treesitter fold allocates the foldinfo for added lines (`add_range`) on `on_bytes`. * Therefore, when treesitter foldexpr is invoked while running `o`, it sees outdated foldinfo. Solution: `extmark_splice`, and then `changed_lines`. This seems to be the standard order in other places, e.g., `nvim_buf_set_lines`. --- src/nvim/change.c | 2 +- test/functional/lua/buffer_updates_spec.lua | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/nvim/change.c b/src/nvim/change.c index f3f685f1b1..0b87fdafd8 100644 --- a/src/nvim/change.c +++ b/src/nvim/change.c @@ -1814,11 +1814,11 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment) curwin->w_cursor.lnum = old_cursor.lnum + 1; } if (did_append) { - changed_lines(curwin->w_cursor.lnum, 0, curwin->w_cursor.lnum, 1L, true); // bail out and just get the final length of the line we just manipulated bcount_t extra = (bcount_t)strlen(ml_get(curwin->w_cursor.lnum)); extmark_splice(curbuf, (int)curwin->w_cursor.lnum - 1, 0, 0, 0, 0, 1, 0, 1 + extra, kExtmarkUndo); + changed_lines(curwin->w_cursor.lnum, 0, curwin->w_cursor.lnum, 1L, true); } curbuf_splice_pending--; diff --git a/test/functional/lua/buffer_updates_spec.lua b/test/functional/lua/buffer_updates_spec.lua index 4938a42957..d6e93f1bf8 100644 --- a/test/functional/lua/buffer_updates_spec.lua +++ b/test/functional/lua/buffer_updates_spec.lua @@ -418,7 +418,7 @@ describe('lua: nvim_buf_attach on_bytes', function() -- meths.buf_set_option(0, 'autoindent', true) feed 'Go' check_events { - { "test1", "bytes", 1, 4, 7, 0, 114, 0, 0, 0, 1, 0, 1 }; + { "test1", "bytes", 1, 3, 7, 0, 114, 0, 0, 0, 1, 0, 1 }; } feed '' check_events { @@ -431,7 +431,7 @@ describe('lua: nvim_buf_attach on_bytes', function() meths.buf_set_option(0, 'autoindent', true) feed 'Go' check_events { - { "test1", "bytes", 1, 4, 7, 0, 114, 0, 0, 0, 1, 0, 5 }; + { "test1", "bytes", 1, 3, 7, 0, 114, 0, 0, 0, 1, 0, 5 }; } feed '' check_events { @@ -476,7 +476,7 @@ describe('lua: nvim_buf_attach on_bytes', function() feed 'ggo' -- goto first line to continue testing check_events { - { "test1", "bytes", 1, 6, 1, 0, 11, 0, 0, 0, 1, 0, 4 }; + { "test1", "bytes", 1, 5, 1, 0, 11, 0, 0, 0, 1, 0, 4 }; } feed '' From 26016ab47a29f2ee371d8564648fb8d87add2409 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 6 Dec 2023 07:21:11 +0800 Subject: [PATCH 2/2] vim-patch:9.0.2151: 'breakindent' is not drawn after diff filler lines Problem: 'breakindent' is not drawn after diff filler lines. Solution: Correct check for whether 'breakindent' should be drawn. closes: vim/vim#13624 https://github.com/vim/vim/commit/588f20decebebedba3ad733f4f443a597e9747c3 --- src/nvim/drawline.c | 4 +-- test/functional/ui/diff_spec.lua | 41 ++++++++++++++++++++++----- test/old/testdir/test_diffmode.vim | 45 +++++++++++++++++++++--------- 3 files changed, 68 insertions(+), 22 deletions(-) diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index 2b78f245e0..6c9dfe93c3 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -751,8 +751,8 @@ static void handle_breakindent(win_T *wp, winlinevars_T *wlv) if (wlv->draw_state == WL_BRI - 1 && wlv->n_extra == 0) { wlv->draw_state = WL_BRI; // if wlv->need_showbreak is set, breakindent also applies - if (wp->w_p_bri && (wlv->row != wlv->startrow || wlv->need_showbreak) - && wlv->filler_lines == 0) { + if (wp->w_p_bri && (wlv->row > wlv->startrow + wlv->filler_lines + || wlv->need_showbreak)) { wlv->char_attr = 0; if (wlv->diff_hlf != (hlf_T)0) { wlv->char_attr = win_hl_attr(wp, (int)wlv->diff_hlf); diff --git a/test/functional/ui/diff_spec.lua b/test/functional/ui/diff_spec.lua index dbdf3823ec..caee7ca490 100644 --- a/test/functional/ui/diff_spec.lua +++ b/test/functional/ui/diff_spec.lua @@ -11,6 +11,8 @@ local exec = helpers.exec local eq = helpers.eq local meths = helpers.meths +before_each(clear) + describe('Diff mode screen', function() local fname = 'Xtest-functional-diff-screen-1' local fname_2 = fname .. '.2' @@ -21,7 +23,6 @@ describe('Diff mode screen', function() end setup(function() - clear() os.remove(fname) os.remove(fname_2) end) @@ -32,7 +33,6 @@ describe('Diff mode screen', function() end) before_each(function() - clear() feed(':e ' .. fname_2 .. '') feed(':vnew ' .. fname .. '') feed(':diffthis') @@ -1255,7 +1255,6 @@ end) it('win_update redraws lines properly', function() local screen - clear() screen = Screen.new(50, 10) screen:attach() screen:set_default_attr_ids({ @@ -1325,8 +1324,8 @@ it('win_update redraws lines properly', function() ]]} end) +-- oldtest: Test_diff_rnu() it('diff updates line numbers below filler lines', function() - clear() local screen = Screen.new(40, 14) screen:attach() screen:set_default_attr_ids({ @@ -1401,8 +1400,8 @@ it('diff updates line numbers below filler lines', function() ]]) end) +-- oldtest: Test_diff_with_scroll_and_change() it('Align the filler lines when changing text in diff mode', function() - clear() local screen = Screen.new(40, 20) screen:attach() screen:set_default_attr_ids({ @@ -1494,7 +1493,6 @@ it('Align the filler lines when changing text in diff mode', function() end) it("diff mode doesn't restore invalid 'foldcolumn' value #21647", function() - clear() local screen = Screen.new(60, 6) screen:set_default_attr_ids({ [0] = {foreground = Screen.colors.Blue, bold = true}; @@ -1515,7 +1513,6 @@ end) -- oldtest: Test_diff_binary() it('diff mode works properly if file contains NUL bytes vim-patch:8.2.3925', function() - clear() local screen = Screen.new(40, 20) screen:set_default_attr_ids({ [1] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.Gray}; @@ -1640,3 +1637,33 @@ it('diff mode works properly if file contains NUL bytes vim-patch:8.2.3925', fun | ]]) end) + +-- oldtest: Test_diff_breakindent_after_filler() +it("diff mode draws 'breakindent' correctly after filler lines", function() + local screen = Screen.new(45, 8) + screen:attach() + screen:set_default_attr_ids({ + [1] = {background = Screen.colors.Grey, foreground = Screen.colors.DarkBlue}; + [2] = {background = Screen.colors.LightBlue}; + [3] = {background = Screen.colors.LightCyan, bold = true, foreground = Screen.colors.Blue}; + [4] = {foreground = Screen.colors.Blue, bold = true}; + }) + exec([[ + set laststatus=0 diffopt+=followwrap breakindent + call setline(1, ['a', ' ' .. repeat('c', 50)]) + vnew + call setline(1, ['a', 'b', ' ' .. repeat('c', 50)]) + windo diffthis + norm! G$ + ]]) + screen:expect([[ + {1: }a │{1: }a | + {1: }{2:b }│{1: }{3:--------------------}| + {1: } cccccccccccccccccc│{1: } cccccccccccccccccc| + {1: } cccccccccccccccccc│{1: } cccccccccccccccccc| + {1: } cccccccccccccc │{1: } ccccccccccccc^c | + {4:~ }│{4:~ }| + {4:~ }│{4:~ }| + | + ]]) +end) diff --git a/test/old/testdir/test_diffmode.vim b/test/old/testdir/test_diffmode.vim index 0049398776..eb00d3bbf7 100644 --- a/test/old/testdir/test_diffmode.vim +++ b/test/old/testdir/test_diffmode.vim @@ -1086,18 +1086,19 @@ endfunc func Test_diff_with_cursorline_breakindent() CheckScreendump - call writefile([ - \ 'hi CursorLine ctermbg=red ctermfg=white', - \ 'set noequalalways wrap diffopt=followwrap cursorline breakindent', - \ '50vnew', - \ 'call setline(1, [" "," "," "," "])', - \ 'exe "norm 20Afoo\j20Afoo\j20Afoo\j20Abar\"', - \ 'vnew', - \ 'call setline(1, [" "," "," "," "])', - \ 'exe "norm 20Abee\j20Afoo\j20Afoo\j20Abaz\"', - \ 'windo diffthis', - \ '2wincmd w', - \ ], 'Xtest_diff_cursorline_breakindent') + let lines =<< trim END + hi CursorLine ctermbg=red ctermfg=white + set noequalalways wrap diffopt=followwrap cursorline breakindent + 50vnew + call setline(1, [' ', ' ', ' ', ' ']) + exe "norm! 20Afoo\j20Afoo\j20Afoo\j20Abar\" + vnew + call setline(1, [' ', ' ', ' ', ' ']) + exe "norm! 20Abee\j20Afoo\j20Afoo\j20Abaz\" + windo diffthis + 2wincmd w + END + call writefile(lines, 'Xtest_diff_cursorline_breakindent', 'D') let buf = RunVimInTerminal('-S Xtest_diff_cursorline_breakindent', {}) call term_sendkeys(buf, "gg0") @@ -1111,7 +1112,25 @@ func Test_diff_with_cursorline_breakindent() " clean up call StopVimInTerminal(buf) - call delete('Xtest_diff_cursorline_breakindent') +endfunc + +func Test_diff_breakindent_after_filler() + CheckScreendump + + let lines =<< trim END + set laststatus=0 diffopt+=followwrap breakindent + call setline(1, ['a', ' ' .. repeat('c', 50)]) + vnew + call setline(1, ['a', 'b', ' ' .. repeat('c', 50)]) + windo diffthis + norm! G$ + END + call writefile(lines, 'Xtest_diff_breakindent_after_filler', 'D') + let buf = RunVimInTerminal('-S Xtest_diff_breakindent_after_filler', #{rows: 8, cols: 45}) + call VerifyScreenDump(buf, 'Test_diff_breakindent_after_filler', {}) + + " clean up + call StopVimInTerminal(buf) endfunc func Test_diff_with_syntax()