aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/move.c
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-02-16 07:25:16 +0800
committerzeertzjq <zeertzjq@outlook.com>2023-02-16 08:09:41 +0800
commit968cd1ed933c039b8d60b0110bc6b539c71e387d (patch)
tree07100b51218fc9888becb0613a00eebe76ff7d4a /src/nvim/move.c
parentf1c5887377c9ae547a7564ec4fc52d72656a974f (diff)
downloadrneovim-968cd1ed933c039b8d60b0110bc6b539c71e387d.tar.gz
rneovim-968cd1ed933c039b8d60b0110bc6b539c71e387d.tar.bz2
rneovim-968cd1ed933c039b8d60b0110bc6b539c71e387d.zip
vim-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 vim/vim#10545) https://github.com/vim/vim/commit/1d6539cf36a7b6d1afe76fb6316fe662f543bf60 Cherry-pick test_scroll_opt.vim changes from patch 8.2.1432. Co-authored-by: Bram Moolenaar <Bram@vim.org>
Diffstat (limited to 'src/nvim/move.c')
-rw-r--r--src/nvim/move.c79
1 files changed, 50 insertions, 29 deletions
diff --git a/src/nvim/move.c b/src/nvim/move.c
index a946633bf6..8fda73cbec 100644
--- a/src/nvim/move.c
+++ b/src/nvim/move.c
@@ -235,7 +235,7 @@ void update_topline(win_T *wp)
// 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);
check_botline = true;
@@ -314,7 +314,7 @@ void update_topline(win_T *wp)
if (line_count <= wp->w_height_inner + 1) {
scroll_cursor_bot(scrolljump_value(), false);
} else {
- scroll_cursor_halfway(false);
+ scroll_cursor_halfway(false, false);
}
}
}
@@ -1464,7 +1464,7 @@ void scroll_cursor_top(int min_scroll, int always)
// This makes sure we get the same position when using "k" and "j"
// in a small window.
if (used > curwin->w_height_inner) {
- scroll_cursor_halfway(false);
+ scroll_cursor_halfway(false, false);
} else {
// If "always" is false, only adjust topline to a lower value, higher
// value may happen with wrapping lines
@@ -1669,7 +1669,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
// Scroll up if the cursor is off the bottom of the screen a bit.
// Otherwise put it at 1/2 of the screen.
if (line_count >= curwin->w_height_inner && line_count > min_scroll) {
- scroll_cursor_halfway(false);
+ scroll_cursor_halfway(false, true);
} else {
scrollup(line_count, true);
}
@@ -1690,7 +1690,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
///
/// @param atend if true, also put the cursor halfway to the end of the file.
///
-void scroll_cursor_halfway(int atend)
+void scroll_cursor_halfway(bool atend, bool prefer_above)
{
int above = 0;
int topfill = 0;
@@ -1705,38 +1705,59 @@ void scroll_cursor_halfway(int atend)
loff.fill = 0;
boff.fill = 0;
linenr_T topline = loff.lnum;
+
while (topline > 1) {
- if (below <= above) { // add a line below the cursor first
- if (boff.lnum < curbuf->b_ml.ml_line_count) {
- botline_forw(curwin, &boff);
- used += boff.height;
+ // This may not be right in the middle if the lines'
+ // physical height > 1 (e.g. 'wrap' is on).
+
+ // Depending on "prefer_above" we add a line above or below first.
+ // Loop twice to avoid duplicating code.
+ bool done = false;
+ for (int round = 1; round <= 2; round++) {
+ if (prefer_above
+ ? (round == 2 && below < above)
+ : (round == 1 && below <= above)) {
+ // add a line below the cursor
+ if (boff.lnum < curbuf->b_ml.ml_line_count) {
+ botline_forw(curwin, &boff);
+ used += boff.height;
+ if (used > curwin->w_height_inner) {
+ 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(curwin, &loff);
+ if (loff.height == MAXCOL) {
+ used = MAXCOL;
+ } else {
+ used += loff.height;
+ }
if (used > curwin->w_height_inner) {
+ done = true;
break;
}
- below += boff.height;
- } else {
- below++; // count a "~" line
- if (atend) {
- used++;
- }
+ above += loff.height;
+ topline = loff.lnum;
+ topfill = loff.fill;
}
}
-
- if (below > above) { // add a line above the cursor
- topline_back(curwin, &loff);
- if (loff.height == MAXCOL) {
- used = MAXCOL;
- } else {
- used += loff.height;
- }
- if (used > curwin->w_height_inner) {
- break;
- }
- above += loff.height;
- topline = loff.lnum;
- topfill = loff.fill;
+ if (done) {
+ break;
}
}
+
if (!hasFolding(topline, &curwin->w_topline, NULL)) {
curwin->w_topline = topline;
}