summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2023-02-14 17:41:20 +0000
committerBram Moolenaar <Bram@vim.org>2023-02-14 17:41:20 +0000
commit1d6539cf36a7b6d1afe76fb6316fe662f543bf60 (patch)
treeb6e26e7756faf7847863510790cd4c2138635c72
parent1a6476428f63e9fa0c2cbea296e475e60363af11 (diff)
downloadvim-git-1d6539cf36a7b6d1afe76fb6316fe662f543bf60.tar.gz
patch 9.0.1309: scrolling two lines with even line count and 'scrolloff' setv9.0.1309
Problem: Scrolling two lines with even line count and 'scrolloff' set. Solution: Adjust how the topline is computed. (closes #10545)
-rw-r--r--src/buffer.c2
-rw-r--r--src/move.c85
-rw-r--r--src/normal.c2
-rw-r--r--src/proto/move.pro2
-rw-r--r--src/testdir/dumps/Test_popupwin_previewpopup_2.dump8
-rw-r--r--src/testdir/dumps/Test_popupwin_previewpopup_3.dump8
-rw-r--r--src/testdir/dumps/Test_popupwin_previewpopup_4.dump8
-rw-r--r--src/testdir/dumps/Test_popupwin_previewpopup_5.dump8
-rw-r--r--src/testdir/test_scroll_opt.vim17
-rw-r--r--src/testdir/test_scrollbind.vim4
-rw-r--r--src/version.c2
11 files changed, 92 insertions, 54 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 0d523bd05..8fd81be86 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1953,7 +1953,7 @@ enter_buffer(buf_T *buf)
maketitle();
// when autocmds didn't change it
if (curwin->w_topline == 1 && !curwin->w_topline_was_set)
- scroll_cursor_halfway(FALSE); // redisplay at correct position
+ scroll_cursor_halfway(FALSE, FALSE); // redisplay at correct position
#ifdef FEAT_NETBEANS_INTG
// Send fileOpened event because we've changed buffers.
diff --git a/src/move.c b/src/move.c
index 3c50d258c..921fec6fb 100644
--- a/src/move.c
+++ b/src/move.c
@@ -396,7 +396,7 @@ update_topline(void)
// cursor in the middle of the window. Otherwise put the cursor
// near the top of the window.
if (n >= halfheight)
- scroll_cursor_halfway(FALSE);
+ scroll_cursor_halfway(FALSE, FALSE);
else
{
scroll_cursor_top(scrolljump_value(), FALSE);
@@ -499,7 +499,7 @@ update_topline(void)
if (line_count <= curwin->w_height + 1)
scroll_cursor_bot(scrolljump_value(), FALSE);
else
- scroll_cursor_halfway(FALSE);
+ scroll_cursor_halfway(FALSE, FALSE);
}
}
}
@@ -2383,7 +2383,7 @@ scroll_cursor_top(int min_scroll, int always)
* in a small window.
*/
if (used > curwin->w_height)
- scroll_cursor_halfway(FALSE);
+ scroll_cursor_halfway(FALSE, FALSE);
else
{
/*
@@ -2720,7 +2720,7 @@ scroll_cursor_bot(int min_scroll, int set_topbot)
* Otherwise put it at 1/2 of the screen.
*/
if (line_count >= curwin->w_height && line_count > min_scroll)
- scroll_cursor_halfway(FALSE);
+ scroll_cursor_halfway(FALSE, TRUE);
else
{
// With 'smoothscroll' scroll at least the height of the cursor line,
@@ -2760,7 +2760,7 @@ scroll_cursor_bot(int min_scroll, int set_topbot)
* If "atend" is TRUE, also put it halfway at the end of the file.
*/
void
-scroll_cursor_halfway(int atend)
+scroll_cursor_halfway(int atend, int prefer_above)
{
int above = 0;
linenr_T topline;
@@ -2841,43 +2841,62 @@ scroll_cursor_halfway(int atend)
// If not using smoothscroll, we have to iteratively find how many
// lines to scroll down to roughly fit the cursor.
- // This may not be right in the middle if the lines' physical height >
- // 1 (e.g. 'wrap' is on).
+ // This may not be right in the middle if the lines'
+ // physical height > 1 (e.g. 'wrap' is on).
- if (below <= above) // add a line below the cursor first
+ // Depending on "prefer_above" we add a line above or below first.
+ // Loop twice to avoid duplicating code.
+ int done = FALSE;
+ for (int round = 1; round <= 2; ++round)
{
- if (boff.lnum < curbuf->b_ml.ml_line_count)
+ if (prefer_above ? (round == 2 && below < above)
+ : (round == 1 && below <= above))
{
- botline_forw(&boff);
- used += boff.height;
- if (used > curwin->w_height)
- break;
- below += boff.height;
- }
- else
- {
- ++below; // count a "~" line
- if (atend)
- ++used;
+ // add a line below the cursor
+ if (boff.lnum < curbuf->b_ml.ml_line_count)
+ {
+ botline_forw(&boff);
+ used += boff.height;
+ if (used > curwin->w_height)
+ {
+ done = TRUE;
+ break;
+ }
+ below += boff.height;
+ }
+ else
+ {
+ ++below; // count a "~" line
+ if (atend)
+ ++used;
+ }
}
- }
- if (below > above) // add a line above the cursor
- {
- topline_back(&loff);
- if (loff.height == MAXCOL)
- used = MAXCOL;
- else
- used += loff.height;
- if (used > curwin->w_height)
- break;
- above += loff.height;
- topline = loff.lnum;
+ if (prefer_above ? (round == 1 && below >= above)
+ : (round == 1 && below > above))
+ {
+ // add a line above the cursor
+ topline_back(&loff);
+ if (loff.height == MAXCOL)
+ used = MAXCOL;
+ else
+ used += loff.height;
+ if (used > curwin->w_height)
+ {
+ done = TRUE;
+ break;
+ }
+ above += loff.height;
+ topline = loff.lnum;
#ifdef FEAT_DIFF
- topfill = loff.fill;
+ topfill = loff.fill;
#endif
+ }
}
+ if (done)
+ break;
}
+
#ifdef FEAT_FOLDING
if (!hasFolding(topline, &curwin->w_topline, NULL))
#endif
diff --git a/src/normal.c b/src/normal.c
index 9a3006705..f5a85ac44 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -2712,7 +2712,7 @@ nv_zet(cmdarg_T *cap)
case '.': beginline(BL_WHITE | BL_FIX);
// FALLTHROUGH
- case 'z': scroll_cursor_halfway(TRUE);
+ case 'z': scroll_cursor_halfway(TRUE, FALSE);
redraw_later(UPD_VALID);
set_fraction(curwin);
break;
diff --git a/src/proto/move.pro b/src/proto/move.pro
index 00b4d2933..0858e26b0 100644
--- a/src/proto/move.pro
+++ b/src/proto/move.pro
@@ -43,7 +43,7 @@ void scrollup_clamp(void);
void scroll_cursor_top(int min_scroll, int always);
void set_empty_rows(win_T *wp, int used);
void scroll_cursor_bot(int min_scroll, int set_topbot);
-void scroll_cursor_halfway(int atend);
+void scroll_cursor_halfway(int atend, int prefer_above);
void cursor_correct(void);
int onepage(int dir, long count);
void halfpage(int flag, linenr_T Prenum);
diff --git a/src/testdir/dumps/Test_popupwin_previewpopup_2.dump b/src/testdir/dumps/Test_popupwin_previewpopup_2.dump
index 0f8be327e..99934efa6 100644
--- a/src/testdir/dumps/Test_popupwin_previewpopup_2.dump
+++ b/src/testdir/dumps/Test_popupwin_previewpopup_2.dump
@@ -2,10 +2,10 @@
|#|i|n|c|l|u|d|e| |"|X|h|e|a|d|e|r|.|h|"| @54
|t|h|r|e@1| @69
|f|o|u|r| @3|╔+0&#afffff255| |X|t|a|g|f|i|l|e| |═@30|X| +0&#ffffff0@23
-|f|i|v|e| @3|║+0&#afffff255|2|7| @37| +0&#a8a8a8255|║+0&#afffff255| +0&#ffffff0@23
-|s|i|x| @4|║+0&#afffff255|t|h|i|s| |i|s| |a|n|o|t|h|e|r| |p|l|a|c|e| @18| +0&#a8a8a8255|║+0&#afffff255| +0&#ffffff0@23
-|s|e|v|e|n| @2|║+0&#afffff255|2|9| @37| +0&#0000001|║+0&#afffff255| +0&#ffffff0@23
-|f|i|n|d| |t|h|e|║+0&#afffff255|3|0| @37| +0&#a8a8a8255|║+0&#afffff255| +0&#ffffff0@23
+|f|i|v|e| @3|║+0&#afffff255|2|6| @37| +0&#a8a8a8255|║+0&#afffff255| +0&#ffffff0@23
+|s|i|x| @4|║+0&#afffff255|2|7| @37| +0&#a8a8a8255|║+0&#afffff255| +0&#ffffff0@23
+|s|e|v|e|n| @2|║+0&#afffff255|t|h|i|s| |i|s| |a|n|o|t|h|e|r| |p|l|a|c|e| @18| +0&#0000001|║+0&#afffff255| +0&#ffffff0@23
+|f|i|n|d| |t|h|e|║+0&#afffff255|2|9| @37| +0&#a8a8a8255|║+0&#afffff255| +0&#ffffff0@23
|n|i|n|e| @3|╚+0&#afffff255|═@40|⇲| +0&#ffffff0@23
|t|h|i|s| |i|s| >a|n|o|t|h|e|r| |w|o|r|d| @54
|v|e|r|y| |l|o|n|g| |l|i|n|e| |w|h|e|r|e| |t|h|e| |w|o|r|d| |i|s| |a|l|s|o| |a|n|o|t|h|e|r| @29
diff --git a/src/testdir/dumps/Test_popupwin_previewpopup_3.dump b/src/testdir/dumps/Test_popupwin_previewpopup_3.dump
index 03457b35d..d1e77e9ef 100644
--- a/src/testdir/dumps/Test_popupwin_previewpopup_3.dump
+++ b/src/testdir/dumps/Test_popupwin_previewpopup_3.dump
@@ -2,10 +2,10 @@
|#|i|n|c|l|u|d|e| |"|X|h|e|a|d|e|r|.|h|"| @54
|t|h|r|e@1| @69
|f|o|u|r| @9|╔+0&#afffff255| |X|t|a|g|f|i|l|e| |═@30|X| +0&#ffffff0@17
-|f|i|v|e| @9|║+0&#afffff255|2|7| @37| +0&#a8a8a8255|║+0&#afffff255| +0&#ffffff0@17
-|s|i|x| @10|║+0&#afffff255|t|h|i|s| |i|s| |a|n|o|t|h|e|r| |p|l|a|c|e| @18| +0&#a8a8a8255|║+0&#afffff255| +0&#ffffff0@17
-|s|e|v|e|n| @8|║+0&#afffff255|2|9| @37| +0&#0000001|║+0&#afffff255| +0&#ffffff0@17
-|f|i|n|d| |t|h|e|w|o|r|d| |s|║+0&#afffff255|3|0| @37| +0&#a8a8a8255|║+0&#afffff255| +0&#ffffff0@17
+|f|i|v|e| @9|║+0&#afffff255|2|6| @37| +0&#a8a8a8255|║+0&#afffff255| +0&#ffffff0@17
+|s|i|x| @10|║+0&#afffff255|2|7| @37| +0&#a8a8a8255|║+0&#afffff255| +0&#ffffff0@17
+|s|e|v|e|n| @8|║+0&#afffff255|t|h|i|s| |i|s| |a|n|o|t|h|e|r| |p|l|a|c|e| @18| +0&#0000001|║+0&#afffff255| +0&#ffffff0@17
+|f|i|n|d| |t|h|e|w|o|r|d| |s|║+0&#afffff255|2|9| @37| +0&#a8a8a8255|║+0&#afffff255| +0&#ffffff0@17
|n|i|n|e| @9|╚+0&#afffff255|═@40|⇲| +0&#ffffff0@17
|t|h|i|s| |i|s| >a|n|o|t|h|e|r| |w|o|r|d| @54
|v|e|r|y| |l|o|n|g| |l|i|n|e| |w|h|e|r|e| |t|h|e| |w|o|r|d| |i|s| |a|l|s|o| |a|n|o|t|h|e|r| @29
diff --git a/src/testdir/dumps/Test_popupwin_previewpopup_4.dump b/src/testdir/dumps/Test_popupwin_previewpopup_4.dump
index dcec4edda..f8d411dad 100644
--- a/src/testdir/dumps/Test_popupwin_previewpopup_4.dump
+++ b/src/testdir/dumps/Test_popupwin_previewpopup_4.dump
@@ -3,10 +3,10 @@
|t|h|r|e@1| @69
|f|o|u|r| @70
|f|i|v|e| @27|╔+0&#afffff255| |X|t|a|g|f|i|l|e| |═@30|X
-|s+0&#ffffff0|i|x| @28|║+0&#afffff255|2|7| @37| +0&#a8a8a8255|║+0&#afffff255
-|s+0&#ffffff0|e|v|e|n| @26|║+0&#afffff255|t|h|i|s| |i|s| |a|n|o|t|h|e|r| |p|l|a|c|e| @18| +0&#a8a8a8255|║+0&#afffff255
-|f+0&#ffffff0|i|n|d| |t|h|e|w|o|r|d| |s|o|m|e|w|h|e|r|e| @9|║+0&#afffff255|2|9| @37| +0&#0000001|║+0&#afffff255
-|n+0&#ffffff0|i|n|e| @27|║+0&#afffff255|3|0| @37| +0&#a8a8a8255|║+0&#afffff255
+|s+0&#ffffff0|i|x| @28|║+0&#afffff255|2|6| @37| +0&#a8a8a8255|║+0&#afffff255
+|s+0&#ffffff0|e|v|e|n| @26|║+0&#afffff255|2|7| @37| +0&#a8a8a8255|║+0&#afffff255
+|f+0&#ffffff0|i|n|d| |t|h|e|w|o|r|d| |s|o|m|e|w|h|e|r|e| @9|║+0&#afffff255|t|h|i|s| |i|s| |a|n|o|t|h|e|r| |p|l|a|c|e| @18| +0&#0000001|║+0&#afffff255
+|n+0&#ffffff0|i|n|e| @27|║+0&#afffff255|2|9| @37| +0&#a8a8a8255|║+0&#afffff255
|t+0&#ffffff0|h|i|s| |i|s| |a|n|o|t|h|e|r| |w|o|r|d| @11|╚+0&#afffff255|═@40|⇲
|v+0&#ffffff0|e|r|y| |l|o|n|g| |l|i|n|e| |w|h|e|r|e| |t|h|e| |w|o|r|d| |i|s| |a|l|s|o| >a|n|o|t|h|e|r| @29
|~+0#4040ff13&| @73
diff --git a/src/testdir/dumps/Test_popupwin_previewpopup_5.dump b/src/testdir/dumps/Test_popupwin_previewpopup_5.dump
index d26a7ed18..8f1b98f48 100644
--- a/src/testdir/dumps/Test_popupwin_previewpopup_5.dump
+++ b/src/testdir/dumps/Test_popupwin_previewpopup_5.dump
@@ -3,10 +3,10 @@
|t|h|r|e@1| @69
|f|o|u|r| @70
|f|i|v|e| @27|╔+0&#afffff255| |t|e|s|t|d|i|r|/|X|t|a|g|f|i|l|e| |═@22|X
-|s+0&#ffffff0|i|x| @28|║+0&#afffff255|2|7| @37| +0&#a8a8a8255|║+0&#afffff255
-|s+0&#ffffff0|e|v|e|n| @26|║+0&#afffff255|t|h|i|s| |i|s| |a|n|o|t|h|e|r| |p|l|a|c|e| @18| +0&#a8a8a8255|║+0&#afffff255
-|f+0&#ffffff0|i|n|d| |t|h|e|w|o|r|d| |s|o|m|e|w|h|e|r|e| @9|║+0&#afffff255|2|9| @37| +0&#0000001|║+0&#afffff255
-|n+0&#ffffff0|i|n|e| @27|║+0&#afffff255|3|0| @37| +0&#a8a8a8255|║+0&#afffff255
+|s+0&#ffffff0|i|x| @28|║+0&#afffff255|2|6| @37| +0&#a8a8a8255|║+0&#afffff255
+|s+0&#ffffff0|e|v|e|n| @26|║+0&#afffff255|2|7| @37| +0&#a8a8a8255|║+0&#afffff255
+|f+0&#ffffff0|i|n|d| |t|h|e|w|o|r|d| |s|o|m|e|w|h|e|r|e| @9|║+0&#afffff255|t|h|i|s| |i|s| |a|n|o|t|h|e|r| |p|l|a|c|e| @18| +0&#0000001|║+0&#afffff255
+|n+0&#ffffff0|i|n|e| @27|║+0&#afffff255|2|9| @37| +0&#a8a8a8255|║+0&#afffff255
|t+0&#ffffff0|h|i|s| |i|s| |a|n|o|t|h|e|r| |w|o|r|d| @11|╚+0&#afffff255|═@40|⇲
|v+0&#ffffff0|e|r|y| |l|o|n|g| |l|i|n|e| |w|h|e|r|e| |t|h|e| |w|o|r|d| |i|s| |a|l|s|o| >a|n|o|t|h|e|r| @29
|~+0#4040ff13&| @73
diff --git a/src/testdir/test_scroll_opt.vim b/src/testdir/test_scroll_opt.vim
index c146c018a..01b1dafe3 100644
--- a/src/testdir/test_scroll_opt.vim
+++ b/src/testdir/test_scroll_opt.vim
@@ -38,6 +38,23 @@ func Test_reset_scroll()
quit!
endfunc
+func Test_scolloff_even_line_count()
+ new
+ resize 6
+ setlocal scrolloff=3
+ call setline(1, range(20))
+ normal 2j
+ call assert_equal(1, getwininfo(win_getid())[0].topline)
+ normal j
+ call assert_equal(1, getwininfo(win_getid())[0].topline)
+ normal j
+ call assert_equal(2, getwininfo(win_getid())[0].topline)
+ normal j
+ call assert_equal(3, getwininfo(win_getid())[0].topline)
+
+ bwipe!
+endfunc
+
func Test_CtrlE_CtrlY_stop_at_end()
enew
call setline(1, ['one', 'two'])
diff --git a/src/testdir/test_scrollbind.vim b/src/testdir/test_scrollbind.vim
index 8074fdae4..211b05ea0 100644
--- a/src/testdir/test_scrollbind.vim
+++ b/src/testdir/test_scrollbind.vim
@@ -218,8 +218,8 @@ end of window 2
\ '7 line 02 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02',
\ '56789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02',
\ 'UTSRQPONMLKJIHGREDCBA9876543210 02',
- \ '. line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11',
- \ '. line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11',
+ \ '. line 10 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 10',
+ \ '. line 10 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 10',
\ ''], getline(1, '$'))
enew!
diff --git a/src/version.c b/src/version.c
index be98fc855..3303bef4a 100644
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1309,
+/**/
1308,
/**/
1307,