patch 9.0.1309: scrolling two lines with even line count and 'scrolloff' set
Problem: Scrolling two lines with even line count and 'scrolloff' set.
Solution: Adjust how the topline is computed. (closes #10545)
diff --git a/src/move.c b/src/move.c
index 3c50d25..921fec6 100644
--- a/src/move.c
+++ b/src/move.c
@@ -396,7 +396,7 @@
// 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 @@
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 @@
* in a small window.
*/
if (used > curwin->w_height)
- scroll_cursor_halfway(FALSE);
+ scroll_cursor_halfway(FALSE, FALSE);
else
{
/*
@@ -2720,7 +2720,7 @@
* 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 @@
* 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 @@
// 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;
+ // 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 (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;
- 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;
+ }
+ 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