aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/diff.c14
-rw-r--r--src/nvim/move.c8
-rw-r--r--src/nvim/testdir/test_diffmode.vim96
-rw-r--r--test/functional/ui/diff_spec.lua89
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)