aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuuk van Baal <luukvbaal@gmail.com>2023-05-09 17:09:43 +0200
committerLuuk van Baal <luukvbaal@gmail.com>2023-05-09 22:40:24 +0200
commit1caad791b4655c412c35279003641e5c4d9ed28d (patch)
treea78d66b8e85b31ea6c3e8b003f41bf392dc27f46
parent84378c4dd56db9846b70a333530505a8048bd26e (diff)
downloadrneovim-1caad791b4655c412c35279003641e5c4d9ed28d.tar.gz
rneovim-1caad791b4655c412c35279003641e5c4d9ed28d.tar.bz2
rneovim-1caad791b4655c412c35279003641e5c4d9ed28d.zip
vim-patch:9.0.1530: cursor moves to wrong line when 'foldmethod' is "diff"
Problem: Cursor moves to wrong line when 'foldmethod' is "diff". (Rick Howe) Solution: Adjust logic for scrolling. (Luuk van Baal, closes vim/vim#12364, closes vim/vim#12218) https://github.com/vim/vim/commit/aa6ba308a1498dc8da04d1d30ec0470018bf782a
-rw-r--r--src/nvim/move.c47
-rw-r--r--test/functional/legacy/normal_spec.lua41
-rw-r--r--test/old/testdir/test_normal.vim18
3 files changed, 69 insertions, 37 deletions
diff --git a/src/nvim/move.c b/src/nvim/move.c
index cff3e264f8..9e053b2db5 100644
--- a/src/nvim/move.c
+++ b/src/nvim/move.c
@@ -1318,14 +1318,6 @@ bool scrolldown(long line_count, int byfold)
return moved;
}
-/// Return TRUE if scrollup() will scroll by screen line rather than text line.
-static int scrolling_screenlines(bool byfold)
-{
- return (curwin->w_p_wrap && curwin->w_p_sms)
- || (byfold && hasAnyFolding(curwin))
- || (curwin->w_p_diff && !curwin->w_p_wrap);
-}
-
/// Scroll the current window up by "line_count" logical lines. "CTRL-E"
///
/// @param line_count number of lines to scroll
@@ -1336,7 +1328,7 @@ bool scrollup(long line_count, int byfold)
linenr_T botline = curwin->w_botline;
int do_sms = curwin->w_p_wrap && curwin->w_p_sms;
- if (scrolling_screenlines(byfold) || win_may_fill(curwin)) {
+ if (do_sms || (byfold && hasAnyFolding(curwin)) || win_may_fill(curwin)) {
int width1 = curwin->w_width_inner - curwin_col_off();
int width2 = width1 + curwin_col_off2();
unsigned size = 0;
@@ -1873,6 +1865,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
int old_valid = curwin->w_valid;
int old_empty_rows = curwin->w_empty_rows;
linenr_T cln = curwin->w_cursor.lnum; // Cursor Line Number
+ int do_sms = curwin->w_p_wrap && curwin->w_p_sms;
if (set_topbot) {
bool set_skipcol = false;
@@ -1889,7 +1882,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
break;
}
if (used + loff.height > curwin->w_height_inner) {
- if (curwin->w_p_sms && curwin->w_p_wrap) {
+ if (do_sms) {
// 'smoothscroll' and 'wrap' are set. The above line is
// too long to show in its entirety, so we show just a part
// of it.
@@ -1928,7 +1921,6 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
used = plines_win_nofill(curwin, cln, true);
int scrolled = 0;
- int min_scrolled = 1;
// If the cursor is on or below botline, we will at least scroll by the
// height of the cursor line, which is "used". Correct for empty lines,
// which are really part of botline.
@@ -1937,16 +1929,8 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
if (cln == curwin->w_botline) {
scrolled -= curwin->w_empty_rows;
}
- min_scrolled = scrolled;
- if (curwin->w_p_sms && curwin->w_p_wrap) {
- // 'smoothscroll' and 'wrap' are set
- if (cln > curwin->w_botline) {
- // add screen lines below w_botline
- for (linenr_T lnum = curwin->w_botline + 1; lnum <= cln; lnum++) {
- min_scrolled += plines_win_nofill(curwin, lnum, true);
- }
- }
-
+ if (do_sms) {
+ // 'smoothscroll' and 'wrap' are set.
// Calculate how many screen lines the current top line of window
// occupies. If it is occupying more than the entire window, we
// need to scroll the additional clipped lines to scroll past the
@@ -1965,7 +1949,6 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
top_plines -= skip_lines;
if (top_plines > curwin->w_height_inner) {
scrolled += (top_plines - curwin->w_height_inner);
- min_scrolled += (top_plines - curwin->w_height_inner);
}
}
}
@@ -2070,21 +2053,11 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
// Otherwise put it at 1/2 of the screen.
if (line_count >= curwin->w_height_inner && line_count > min_scroll) {
scroll_cursor_halfway(false, true);
- } else {
- // With 'smoothscroll' scroll at least the height of the cursor line,
- // unless it would move the cursor.
- if (curwin->w_p_wrap && curwin->w_p_sms && line_count < min_scrolled
- && (curwin->w_cursor.lnum < curwin->w_topline
- || (curwin->w_virtcol - curwin->w_skipcol >=
- curwin->w_width_inner - curwin_col_off()))) {
- line_count = min_scrolled;
- }
- if (line_count > 0) {
- if (scrolling_screenlines(true)) {
- scrollup(scrolled, true); // TODO(vim):
- } else {
- scrollup(line_count, true);
- }
+ } else if (line_count > 0) {
+ if (do_sms) {
+ scrollup(scrolled, true); // TODO(vim):
+ } else {
+ scrollup(line_count, true);
}
}
diff --git a/test/functional/legacy/normal_spec.lua b/test/functional/legacy/normal_spec.lua
new file mode 100644
index 0000000000..ba875460f5
--- /dev/null
+++ b/test/functional/legacy/normal_spec.lua
@@ -0,0 +1,41 @@
+local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
+local clear = helpers.clear
+local exec = helpers.exec
+
+before_each(clear)
+
+describe('normal', function()
+ -- oldtest: Test_normal_j_below_botline()
+ it([["j" does not skip lines when scrolling below botline and 'foldmethod' is not "manual"]], function()
+ local screen = Screen.new(40, 19)
+ screen:attach()
+ screen:set_default_attr_ids({{foreground = Screen.colors.Brown}})
+ exec([[
+ set number foldmethod=diff scrolloff=0
+ call setline(1, map(range(1, 9), 'repeat(v:val, 200)'))
+ norm Lj
+ ]])
+ screen:expect([[
+ {1: 2 }222222222222222222222222222222222222|
+ {1: }222222222222222222222222222222222222|
+ {1: }222222222222222222222222222222222222|
+ {1: }222222222222222222222222222222222222|
+ {1: }222222222222222222222222222222222222|
+ {1: }22222222222222222222 |
+ {1: 3 }333333333333333333333333333333333333|
+ {1: }333333333333333333333333333333333333|
+ {1: }333333333333333333333333333333333333|
+ {1: }333333333333333333333333333333333333|
+ {1: }333333333333333333333333333333333333|
+ {1: }33333333333333333333 |
+ {1: 4 }^444444444444444444444444444444444444|
+ {1: }444444444444444444444444444444444444|
+ {1: }444444444444444444444444444444444444|
+ {1: }444444444444444444444444444444444444|
+ {1: }444444444444444444444444444444444444|
+ {1: }44444444444444444444 |
+ |
+ ]])
+ end)
+end)
diff --git a/test/old/testdir/test_normal.vim b/test/old/testdir/test_normal.vim
index a854c9538f..23baebb78c 100644
--- a/test/old/testdir/test_normal.vim
+++ b/test/old/testdir/test_normal.vim
@@ -3993,4 +3993,22 @@ func Test_mouse_shape_after_cancelling_gr()
call delete('Xmouseshapes')
endfunc
+" Test that "j" does not skip lines when scrolling below botline and
+" 'foldmethod' is not "manual".
+func Test_normal_j_below_botline()
+ CheckScreendump
+
+ let lines =<< trim END
+ set number foldmethod=diff scrolloff=0
+ call setline(1, map(range(1, 9), 'repeat(v:val, 200)'))
+ norm Lj
+ END
+ call writefile(lines, 'XNormalJBelowBotline', 'D')
+ let buf = RunVimInTerminal('-S XNormalJBelowBotline', #{rows: 19, cols: 40})
+
+ call VerifyScreenDump(buf, 'Test_normal_j_below_botline', {})
+
+ call StopVimInTerminal(buf)
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab