diff options
-rw-r--r-- | src/nvim/diff.c | 14 | ||||
-rw-r--r-- | src/nvim/move.c | 8 | ||||
-rw-r--r-- | src/nvim/testdir/test_diffmode.vim | 96 | ||||
-rw-r--r-- | test/functional/ui/diff_spec.lua | 89 |
4 files changed, 199 insertions, 8 deletions
diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 75021e90d6..55d8b7e36b 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -115,7 +115,10 @@ void diff_buf_delete(buf_T *buf) tp->tp_diff_invalid = true; if (tp == curtab) { - diff_redraw(true); + // don't redraw right away, more might change or buffer state + // is invalid right now + need_diff_redraw = true; + redraw_later(curwin, VALID); } } } @@ -369,9 +372,8 @@ static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1, linenr_T // 2. 3. 4. 5.: inserted/deleted lines touching this diff. if (deleted > 0) { + off = 0; if (dp->df_lnum[idx] >= line1) { - off = dp->df_lnum[idx] - lnum_deleted; - if (last <= line2) { // 4. delete all lines of diff if ((dp->df_next != NULL) @@ -388,14 +390,13 @@ static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1, linenr_T dp->df_count[idx] = 0; } else { // 5. delete lines at or just before top of diff + off = dp->df_lnum[idx] - lnum_deleted; n = off; dp->df_count[idx] -= line2 - dp->df_lnum[idx] + 1; check_unchanged = true; } dp->df_lnum[idx] = line1; } else { - off = 0; - if (last < line2) { // 2. delete at end of diff dp->df_count[idx] -= last - lnum_deleted + 1; @@ -648,7 +649,8 @@ void diff_redraw(bool dofold) need_diff_redraw = false; FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - if (!wp->w_p_diff) { + // when closing windows or wiping buffers skip invalid window + if (!wp->w_p_diff || !buf_valid(wp->w_buffer)) { continue; } redraw_later(wp, SOME_VALID); diff --git a/src/nvim/move.c b/src/nvim/move.c index bd68ad6f97..6d4eb8ef49 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -2271,7 +2271,13 @@ void do_check_cursorbind(void) int restart_edit_save = restart_edit; restart_edit = true; check_cursor(); - validate_cursor(); + + // Avoid a scroll here for the cursor position, 'scrollbind' is + // more important. + if (!curwin->w_p_scb) { + validate_cursor(); + } + restart_edit = restart_edit_save; } // Correct cursor for multi-byte character. diff --git a/src/nvim/testdir/test_diffmode.vim b/src/nvim/testdir/test_diffmode.vim index 007b7e0f14..bc931b1e1b 100644 --- a/src/nvim/testdir/test_diffmode.vim +++ b/src/nvim/testdir/test_diffmode.vim @@ -33,7 +33,8 @@ func Test_diff_fold_sync() call win_gotoid(winone) call assert_equal(23, getcurpos()[1]) - call assert_equal(1, g:update_count) + " depending on how redraw is done DiffUpdated may be triggered once or twice + call assert_inrange(1, 2, g:update_count) au! DiffUpdated windo diffoff @@ -1378,4 +1379,97 @@ func Test_diff_foldinvert() set scrollbind& endfunc +" This was scrolling for 'cursorbind' but 'scrollbind' is more important +func Test_diff_scroll() + CheckScreendump + + let left =<< trim END + line 1 + line 2 + line 3 + line 4 + + // Common block + // one + // containing + // four lines + + // Common block + // two + // containing + // four lines + END + call writefile(left, 'Xleft') + let right =<< trim END + line 1 + line 2 + line 3 + line 4 + + Lorem + ipsum + dolor + sit + amet, + consectetur + adipiscing + elit. + Etiam + luctus + lectus + sodales, + dictum + + // Common block + // one + // containing + // four lines + + Vestibulum + tincidunt + aliquet + nulla. + + // Common block + // two + // containing + // four lines + END + call writefile(right, 'Xright') + let buf = RunVimInTerminal('-d Xleft Xright', {'rows': 12}) + call term_sendkeys(buf, "\<C-W>\<C-W>jjjj") + call VerifyScreenDump(buf, 'Test_diff_scroll_1', {}) + call term_sendkeys(buf, "j") + call VerifyScreenDump(buf, 'Test_diff_scroll_2', {}) + + call StopVimInTerminal(buf) + call delete('Xleft') + call delete('Xright') +endfunc + +" This was trying to update diffs for a buffer being closed +func Test_diff_only() + silent! lfile + set diff + lopen + norm o + silent! norm o + + set nodiff + %bwipe! +endfunc + +" This was causing invalid diff block values +" FIXME: somehow this causes a valgrind error when run directly but not when +" run as a test. +func Test_diff_manipulations() + set diff + split 0 + sil! norm R
doobdeuR
doobdeuR
doobdeu + + set nodiff + %bwipe! +endfunc + + " vim: shiftwidth=2 sts=2 expandtab diff --git a/test/functional/ui/diff_spec.lua b/test/functional/ui/diff_spec.lua index 5d056cd6c3..36dc5addcd 100644 --- a/test/functional/ui/diff_spec.lua +++ b/test/functional/ui/diff_spec.lua @@ -6,6 +6,7 @@ local clear = helpers.clear local command = helpers.command local insert = helpers.insert local write_file = helpers.write_file +local dedent = helpers.dedent local exec = helpers.exec describe('Diff mode screen', function() @@ -985,6 +986,93 @@ int main(int argc, char **argv) ]]) end) end) + + -- oldtest: Test_diff_scroll() + -- This was scrolling for 'cursorbind' but 'scrollbind' is more important + it('scrolling works correctly vim-patch:8.2.5155', function() + screen:try_resize(40, 12) + write_file(fname, dedent([[ + line 1 + line 2 + line 3 + line 4 + + // Common block + // one + // containing + // four lines + + // Common block + // two + // containing + // four lines]]), false) + write_file(fname_2, dedent([[ + line 1 + line 2 + line 3 + line 4 + + Lorem + ipsum + dolor + sit + amet, + consectetur + adipiscing + elit. + Etiam + luctus + lectus + sodales, + dictum + + // Common block + // one + // containing + // four lines + + Vestibulum + tincidunt + aliquet + nulla. + + // Common block + // two + // containing + // four lines]]), false) + reread() + + feed('<C-W><C-W>jjjj') + screen:expect([[ + {1: }line 1 │{1: }line 1 | + {1: }line 2 │{1: }line 2 | + {1: }line 3 │{1: }line 3 | + {1: }line 4 │{1: }line 4 | + {1: } │{1: }^ | + {1: }{2:-----------------}│{1: }{4:Lorem }| + {1: }{2:-----------------}│{1: }{4:ipsum }| + {1: }{2:-----------------}│{1: }{4:dolor }| + {1: }{2:-----------------}│{1: }{4:sit }| + {1: }{2:-----------------}│{1: }{4:amet, }| + {3:<nal-diff-screen-1 }{7:<al-diff-screen-1.2 }| + :e | + ]]) + feed('j') + screen:expect([[ + {1: }line 1 │{1: }line 1 | + {1: }line 2 │{1: }line 2 | + {1: }line 3 │{1: }line 3 | + {1: }line 4 │{1: }line 4 | + {1: } │{1: } | + {1: }{2:-----------------}│{1: }{4:^Lorem }| + {1: }{2:-----------------}│{1: }{4:ipsum }| + {1: }{2:-----------------}│{1: }{4:dolor }| + {1: }{2:-----------------}│{1: }{4:sit }| + {1: }{2:-----------------}│{1: }{4:amet, }| + {3:<nal-diff-screen-1 }{7:<al-diff-screen-1.2 }| + :e | + ]]) + end) end) it('win_update redraws lines properly', function() @@ -1227,6 +1315,7 @@ it('Align the filler lines when changing text in diff mode', function() ]]} 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) |