]> granicus.if.org Git - vim/commitdiff
patch 9.0.1309: scrolling two lines with even line count and 'scrolloff' set v9.0.1309
authorBram Moolenaar <Bram@vim.org>
Tue, 14 Feb 2023 17:41:20 +0000 (17:41 +0000)
committerBram Moolenaar <Bram@vim.org>
Tue, 14 Feb 2023 17:41:20 +0000 (17:41 +0000)
Problem:    Scrolling two lines with even line count and 'scrolloff' set.
Solution:   Adjust how the topline is computed. (closes #10545)

src/buffer.c
src/move.c
src/normal.c
src/proto/move.pro
src/testdir/dumps/Test_popupwin_previewpopup_2.dump
src/testdir/dumps/Test_popupwin_previewpopup_3.dump
src/testdir/dumps/Test_popupwin_previewpopup_4.dump
src/testdir/dumps/Test_popupwin_previewpopup_5.dump
src/testdir/test_scroll_opt.vim
src/testdir/test_scrollbind.vim
src/version.c

index 0d523bd05662a835e45e5bc2d993c74efbc36f3a..8fd81be869a417840292f1c115f1d3201acd24e7 100644 (file)
@@ -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.
index 3c50d258c56335ba8edc13bc4361529dedae9375..921fec6fbfc9728ecc15500ae0b17b815e7adf80 100644 (file)
@@ -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
index 9a3006705cb4ce33b27757a4ed68026fff4c3394..f5a85ac447c80c3762829e93b5b68ee63786f046 100644 (file)
@@ -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;
index 00b4d2933ab5fe154de66aeaed5662d50dca1324..0858e26b0d4a566d6d8a43bc5d58d99371f39f6c 100644 (file)
@@ -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);
index 0f8be327e465a7b884daadfc617864d666887707..99934efa6d9f3600ef64f95da84f0c4f41efb60b 100644 (file)
@@ -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
index 03457b35d53b260dcce201a81216bccc40929afa..d1e77e9ef7862e3875c97318d659bbf78044ed34 100644 (file)
@@ -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
index dcec4eddabca167913031c19ffd902a6deed9328..f8d411dadb0f81ed97a9b6e9f2ef549e868aab05 100644 (file)
@@ -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
index d26a7ed18aabda8eeea0d4e572ae4343ebc7e3fc..8f1b98f489c80fe647126e5112913c70453e0511 100644 (file)
@@ -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
index c146c018a68f2c71d52397c79b1b749e204bee3d..01b1dafe36419016e80ee69d3d840e838fd88ea3 100644 (file)
@@ -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'])
index 8074fdae4b5602c952654c291551b0abe29a548e..211b05ea0d9155ff1055aa7f845d71054250a167 100644 (file)
@@ -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!
 
index be98fc855a18f52c56598134dfb27083bf13c689..3303bef4a6c4a6782eabb0f92425c472c94bf4ac 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1309,
 /**/
     1308,
 /**/