aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/move.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/move.c')
-rw-r--r--src/nvim/move.c365
1 files changed, 207 insertions, 158 deletions
diff --git a/src/nvim/move.c b/src/nvim/move.c
index b129c5cb7a..07b355e603 100644
--- a/src/nvim/move.c
+++ b/src/nvim/move.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
/*
* move.c: Functions for moving the cursor and scrolling text.
*
@@ -13,7 +16,6 @@
#include <inttypes.h>
#include <stdbool.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/move.h"
#include "nvim/charset.h"
@@ -24,7 +26,7 @@
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
+#include "nvim/option.h"
#include "nvim/popupmnu.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
@@ -81,8 +83,9 @@ static void comp_botline(win_T *wp)
redraw_for_cursorline(wp);
wp->w_valid |= (VALID_CROW|VALID_CHEIGHT);
}
- if (done + n > wp->w_height)
+ if (done + n > wp->w_grid.Rows) {
break;
+ }
done += n;
lnum = last;
}
@@ -94,16 +97,34 @@ static void comp_botline(win_T *wp)
set_empty_rows(wp, done);
}
-/*
-* Redraw when w_cline_row changes and 'relativenumber' or 'cursorline' is
-* set.
-*/
+void reset_cursorline(void)
+{
+ curwin->w_last_cursorline = 0;
+}
+
+// Redraw when w_cline_row changes and 'relativenumber' or 'cursorline' is set.
static void redraw_for_cursorline(win_T *wp)
{
- if ((wp->w_p_rnu || wp->w_p_cul)
+ if ((wp->w_p_rnu || win_cursorline_standout(wp))
&& (wp->w_valid & VALID_CROW) == 0
&& !pum_visible()) {
- redraw_win_later(wp, SOME_VALID);
+ if (wp->w_p_rnu) {
+ // win_line() will redraw the number column only.
+ redraw_win_later(wp, VALID);
+ }
+ if (win_cursorline_standout(wp)) {
+ if (wp->w_redr_type <= VALID && wp->w_last_cursorline != 0) {
+ // "w_last_cursorline" may be outdated, worst case we redraw
+ // too much. This is optimized for moving the cursor around in
+ // the current window.
+ redrawWinline(wp, wp->w_last_cursorline);
+ redrawWinline(wp, wp->w_cursor.lnum);
+ redraw_win_later(wp, VALID);
+ } else {
+ redraw_win_later(wp, SOME_VALID);
+ }
+ wp->w_last_cursorline = wp->w_cursor.lnum;
+ }
}
}
@@ -129,11 +150,12 @@ void update_topline(void)
bool check_botline = false;
long save_so = p_so;
- if (!screen_valid(true))
- return;
+ // need to have w_grid.Rows/Columns updated
+ win_grid_alloc(curwin);
- // If the window height is zero, just use the cursor line.
- if (curwin->w_height == 0) {
+ // If there is no valid screen and when the window height is zero just use
+ // the cursor line.
+ if (!screen_valid(true) || curwin->w_grid.Rows == 0) {
curwin->w_topline = curwin->w_cursor.lnum;
curwin->w_botline = curwin->w_topline;
curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
@@ -152,12 +174,11 @@ void update_topline(void)
old_topline = curwin->w_topline;
old_topfill = curwin->w_topfill;
- /*
- * If the buffer is empty, always set topline to 1.
- */
- if (bufempty()) { /* special case - file is empty */
- if (curwin->w_topline != 1)
+ // If the buffer is empty, always set topline to 1.
+ if (BUFEMPTY()) { // special case - file is empty
+ if (curwin->w_topline != 1) {
redraw_later(NOT_VALID);
+ }
curwin->w_topline = 1;
curwin->w_botline = 2;
curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
@@ -183,9 +204,10 @@ void update_topline(void)
check_topline = true;
if (check_topline) {
- int halfheight = curwin->w_height / 2 - 1;
- if (halfheight < 2)
+ int halfheight = curwin->w_grid.Rows / 2 - 1;
+ if (halfheight < 2) {
halfheight = 2;
+ }
long n;
if (hasAnyFolding(curwin)) {
/* Count the number of logical lines between the cursor and
@@ -272,20 +294,22 @@ void update_topline(void)
* botline - p_so (approximation of how much will be
* scrolled). */
for (linenr_T lnum = curwin->w_cursor.lnum;
- lnum >= curwin->w_botline - p_so; --lnum) {
- ++line_count;
- /* stop at end of file or when we know we are far off */
- if (lnum <= 0 || line_count > curwin->w_height + 1)
+ lnum >= curwin->w_botline - p_so; lnum--) {
+ line_count++;
+ // stop at end of file or when we know we are far off
+ if (lnum <= 0 || line_count > curwin->w_grid.Rows + 1) {
break;
+ }
(void)hasFolding(lnum, &lnum, NULL);
}
} else
line_count = curwin->w_cursor.lnum - curwin->w_botline
+ 1 + p_so;
- if (line_count <= curwin->w_height + 1)
+ if (line_count <= curwin->w_grid.Rows + 1) {
scroll_cursor_bot(scrolljump_value(), false);
- else
+ } else {
scroll_cursor_halfway(false);
+ }
}
}
}
@@ -329,7 +353,7 @@ void update_topline_win(win_T* win)
*/
static int scrolljump_value(void)
{
- long result = p_sj >= 0 ? p_sj : (curwin->w_height * -p_sj) / 100;
+ long result = p_sj >= 0 ? p_sj : (curwin->w_grid.Rows * -p_sj) / 100;
assert(result <= INT_MAX);
return (int)result;
}
@@ -505,6 +529,7 @@ int cursor_valid(void)
*/
void validate_cursor(void)
{
+ win_grid_alloc(curwin); // we need to have w_grid.Rows/Columns updated
check_cursor_moved(curwin);
if ((curwin->w_valid & (VALID_WCOL|VALID_WROW)) != (VALID_WCOL|VALID_WROW))
curs_columns(true);
@@ -643,18 +668,19 @@ void validate_cursor_col(void)
colnr_T col = curwin->w_virtcol;
colnr_T off = curwin_col_off();
col += off;
- int width = curwin->w_width - off + curwin_col_off2();
-
- /* long line wrapping, adjust curwin->w_wrow */
- if (curwin->w_p_wrap
- && col >= (colnr_T)curwin->w_width
- && width > 0)
- /* use same formula as what is used in curs_columns() */
- col -= ((col - curwin->w_width) / width + 1) * width;
- if (col > (int)curwin->w_leftcol)
+ int width = curwin->w_grid.Columns - off + curwin_col_off2();
+
+ // long line wrapping, adjust curwin->w_wrow
+ if (curwin->w_p_wrap && col >= (colnr_T)curwin->w_grid.Columns
+ && width > 0) {
+ // use same formula as what is used in curs_columns()
+ col -= ((col - curwin->w_grid.Columns) / width + 1) * width;
+ }
+ if (col > (int)curwin->w_leftcol) {
col -= curwin->w_leftcol;
- else
+ } else {
col = 0;
+ }
curwin->w_wcol = col;
curwin->w_valid |= VALID_WCOL;
@@ -670,8 +696,7 @@ int win_col_off(win_T *wp)
return ((wp->w_p_nu || wp->w_p_rnu) ? number_width(wp) + 1 : 0)
+ (cmdwin_type == 0 || wp != curwin ? 0 : 1)
+ (int)wp->w_p_fdc
- + (wp->w_buffer->b_signlist != NULL ? 2 : 0)
- ;
+ + (signcolumn_on(wp) ? win_signcol_width(wp) : 0);
}
int curwin_col_off(void)
@@ -744,20 +769,20 @@ void curs_columns(
*/
curwin->w_wrow = curwin->w_cline_row;
- int textwidth = curwin->w_width - extra;
+ int textwidth = curwin->w_grid.Columns - extra;
if (textwidth <= 0) {
- /* No room for text, put cursor in last char of window. */
- curwin->w_wcol = curwin->w_width - 1;
- curwin->w_wrow = curwin->w_height - 1;
+ // No room for text, put cursor in last char of window.
+ curwin->w_wcol = curwin->w_grid.Columns - 1;
+ curwin->w_wrow = curwin->w_grid.Rows - 1;
} else if (curwin->w_p_wrap
- && curwin->w_width != 0
+ && curwin->w_grid.Columns != 0
) {
width = textwidth + curwin_col_off2();
- /* long line wrapping, adjust curwin->w_wrow */
- if (curwin->w_wcol >= curwin->w_width) {
- /* this same formula is used in validate_cursor_col() */
- n = (curwin->w_wcol - curwin->w_width) / width + 1;
+ // long line wrapping, adjust curwin->w_wrow
+ if (curwin->w_wcol >= curwin->w_grid.Columns) {
+ // this same formula is used in validate_cursor_col()
+ n = (curwin->w_wcol - curwin->w_grid.Columns) / width + 1;
curwin->w_wcol -= n * width;
curwin->w_wrow += n;
@@ -784,7 +809,7 @@ void curs_columns(
assert(p_siso <= INT_MAX);
int off_left = startcol - curwin->w_leftcol - (int)p_siso;
int off_right =
- endcol - curwin->w_leftcol - curwin->w_width + (int)p_siso + 1;
+ endcol - curwin->w_leftcol - curwin->w_grid.Columns + (int)p_siso + 1;
if (off_left < 0 || off_right > 0) {
int diff = (off_left < 0) ? -off_left: off_right;
@@ -827,17 +852,16 @@ void curs_columns(
prev_skipcol = curwin->w_skipcol;
int p_lines = 0;
- if ((curwin->w_wrow >= curwin->w_height
+ if ((curwin->w_wrow >= curwin->w_grid.Rows
|| ((prev_skipcol > 0
- || curwin->w_wrow + p_so >= curwin->w_height)
+ || curwin->w_wrow + p_so >= curwin->w_grid.Rows)
&& (p_lines =
- plines_win_nofill
- (curwin, curwin->w_cursor.lnum, false))
- - 1 >= curwin->w_height))
- && curwin->w_height != 0
+ plines_win_nofill(curwin, curwin->w_cursor.lnum, false)) - 1
+ >= curwin->w_grid.Rows))
+ && curwin->w_grid.Rows != 0
&& curwin->w_cursor.lnum == curwin->w_topline
&& width > 0
- && curwin->w_width != 0
+ && curwin->w_grid.Columns != 0
) {
/* Cursor past end of screen. Happens with a single line that does
* not fit on screen. Find a skipcol to show the text around the
@@ -859,19 +883,22 @@ void curs_columns(
}
else
n = p_lines;
- if ((colnr_T)n >= curwin->w_height + curwin->w_skipcol / width)
+ if ((colnr_T)n >= curwin->w_grid.Rows + curwin->w_skipcol / width) {
extra += 2;
+ }
if (extra == 3 || p_lines < p_so * 2) {
- /* not enough room for 'scrolloff', put cursor in the middle */
+ // not enough room for 'scrolloff', put cursor in the middle
n = curwin->w_virtcol / width;
- if (n > curwin->w_height / 2)
- n -= curwin->w_height / 2;
- else
+ if (n > curwin->w_grid.Rows / 2) {
+ n -= curwin->w_grid.Rows / 2;
+ } else {
n = 0;
- /* don't skip more than necessary */
- if (n > p_lines - curwin->w_height + 1)
- n = p_lines - curwin->w_height + 1;
+ }
+ // don't skip more than necessary
+ if (n > p_lines - curwin->w_grid.Rows + 1) {
+ n = p_lines - curwin->w_grid.Rows + 1;
+ }
curwin->w_skipcol = n * width;
} else if (extra == 1) {
/* less then 'scrolloff' lines above, decrease skipcol */
@@ -884,27 +911,29 @@ void curs_columns(
curwin->w_skipcol -= extra * width;
}
} else if (extra == 2) {
- /* less then 'scrolloff' lines below, increase skipcol */
- endcol = (n - curwin->w_height + 1) * width;
- while (endcol > curwin->w_virtcol)
+ // less then 'scrolloff' lines below, increase skipcol
+ endcol = (n - curwin->w_grid.Rows + 1) * width;
+ while (endcol > curwin->w_virtcol) {
endcol -= width;
- if (endcol > curwin->w_skipcol)
+ }
+ if (endcol > curwin->w_skipcol) {
curwin->w_skipcol = endcol;
+ }
}
curwin->w_wrow -= curwin->w_skipcol / width;
- if (curwin->w_wrow >= curwin->w_height) {
- /* small window, make sure cursor is in it */
- extra = curwin->w_wrow - curwin->w_height + 1;
+ if (curwin->w_wrow >= curwin->w_grid.Rows) {
+ // small window, make sure cursor is in it
+ extra = curwin->w_wrow - curwin->w_grid.Rows + 1;
curwin->w_skipcol += extra * width;
curwin->w_wrow -= extra;
}
extra = ((int)prev_skipcol - (int)curwin->w_skipcol) / width;
if (extra > 0) {
- win_ins_lines(curwin, 0, extra, false, false);
+ win_ins_lines(curwin, 0, extra);
} else if (extra < 0) {
- win_del_lines(curwin, 0, -extra, false, false);
+ win_del_lines(curwin, 0, -extra);
}
} else {
curwin->w_skipcol = 0;
@@ -937,9 +966,9 @@ scrolldown (
validate_cursor(); /* w_wrow needs to be valid */
while (line_count-- > 0) {
if (curwin->w_topfill < diff_check(curwin, curwin->w_topline)
- && curwin->w_topfill < curwin->w_height - 1) {
- ++curwin->w_topfill;
- ++done;
+ && curwin->w_topfill < curwin->w_grid.Rows - 1) {
+ curwin->w_topfill++;
+ done++;
} else {
if (curwin->w_topline == 1)
break;
@@ -972,15 +1001,15 @@ scrolldown (
*/
int wrow = curwin->w_wrow;
if (curwin->w_p_wrap
- && curwin->w_width != 0
+ && curwin->w_grid.Columns != 0
) {
validate_virtcol();
validate_cheight();
wrow += curwin->w_cline_height - 1 -
- curwin->w_virtcol / curwin->w_width;
+ curwin->w_virtcol / curwin->w_grid.Columns;
}
bool moved = false;
- while (wrow >= curwin->w_height && curwin->w_cursor.lnum > 1) {
+ while (wrow >= curwin->w_grid.Rows && curwin->w_cursor.lnum > 1) {
linenr_T first;
if (hasFolding(curwin->w_cursor.lnum, &first, NULL)) {
--wrow;
@@ -1065,14 +1094,15 @@ check_topfill (
{
if (wp->w_topfill > 0) {
int n = plines_win_nofill(wp, wp->w_topline, true);
- if (wp->w_topfill + n > wp->w_height) {
+ if (wp->w_topfill + n > wp->w_grid.Rows) {
if (down && wp->w_topline > 1) {
--wp->w_topline;
wp->w_topfill = 0;
} else {
- wp->w_topfill = wp->w_height - n;
- if (wp->w_topfill < 0)
+ wp->w_topfill = wp->w_grid.Rows - n;
+ if (wp->w_topfill < 0) {
wp->w_topfill = 0;
+ }
}
}
}
@@ -1085,12 +1115,13 @@ check_topfill (
static void max_topfill(void)
{
int n = plines_nofill(curwin->w_topline);
- if (n >= curwin->w_height)
+ if (n >= curwin->w_grid.Rows) {
curwin->w_topfill = 0;
- else {
+ } else {
curwin->w_topfill = diff_check_fill(curwin, curwin->w_topline);
- if (curwin->w_topfill + n > curwin->w_height)
- curwin->w_topfill = curwin->w_height - n;
+ if (curwin->w_topfill + n > curwin->w_grid.Rows) {
+ curwin->w_topfill = curwin->w_grid.Rows - n;
+ }
}
}
@@ -1121,14 +1152,14 @@ void scrolldown_clamp(void)
else
end_row += plines_nofill(curwin->w_topline - 1);
if (curwin->w_p_wrap
- && curwin->w_width != 0
+ && curwin->w_grid.Columns != 0
) {
validate_cheight();
validate_virtcol();
end_row += curwin->w_cline_height - 1 -
- curwin->w_virtcol / curwin->w_width;
+ curwin->w_virtcol / curwin->w_grid.Columns;
}
- if (end_row < curwin->w_height - p_so) {
+ if (end_row < curwin->w_grid.Rows - p_so) {
if (can_fill) {
++curwin->w_topfill;
check_topfill(curwin, true);
@@ -1163,10 +1194,10 @@ void scrollup_clamp(void)
int start_row = curwin->w_wrow - plines_nofill(curwin->w_topline)
- curwin->w_topfill;
if (curwin->w_p_wrap
- && curwin->w_width != 0
+ && curwin->w_grid.Columns != 0
) {
validate_virtcol();
- start_row -= curwin->w_virtcol / curwin->w_width;
+ start_row -= curwin->w_virtcol / curwin->w_grid.Columns;
}
if (start_row >= p_so) {
if (curwin->w_topfill > 0)
@@ -1320,10 +1351,12 @@ void scroll_cursor_top(int min_scroll, int always)
else
used += plines(bot);
}
- if (used > curwin->w_height)
+ if (used > curwin->w_grid.Rows) {
break;
- if (top < curwin->w_topline)
+ }
+ if (top < curwin->w_topline) {
scrolled += i;
+ }
/*
* If scrolling is needed, scroll at least 'sj' lines.
@@ -1343,7 +1376,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) {
+ if (used > curwin->w_grid.Rows) {
scroll_cursor_halfway(false);
} else {
/*
@@ -1377,10 +1410,10 @@ void scroll_cursor_top(int min_scroll, int always)
void set_empty_rows(win_T *wp, int used)
{
wp->w_filler_rows = 0;
- if (used == 0)
- wp->w_empty_rows = 0; /* single line that doesn't fit */
- else {
- wp->w_empty_rows = wp->w_height - used;
+ if (used == 0) {
+ wp->w_empty_rows = 0; // single line that doesn't fit
+ } else {
+ wp->w_empty_rows = wp->w_grid.Rows - used;
if (wp->w_botline <= wp->w_buffer->b_ml.ml_line_count) {
wp->w_filler_rows = diff_check_fill(wp, wp->w_botline);
if (wp->w_empty_rows > wp->w_filler_rows)
@@ -1423,8 +1456,9 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
curwin->w_topline = loff.lnum) {
loff.lnum = curwin->w_topline;
topline_back(&loff);
- if (loff.height == MAXCOL || used + loff.height > curwin->w_height)
+ if (loff.height == MAXCOL || used + loff.height > curwin->w_grid.Rows) {
break;
+ }
used += loff.height;
curwin->w_topfill = loff.fill;
}
@@ -1481,12 +1515,14 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
/* Add one line above */
topline_back(&loff);
- if (loff.height == MAXCOL)
+ if (loff.height == MAXCOL) {
used = MAXCOL;
- else
+ } else {
used += loff.height;
- if (used > curwin->w_height)
+ }
+ if (used > curwin->w_grid.Rows) {
break;
+ }
if (loff.lnum >= curwin->w_botline
&& (loff.lnum > curwin->w_botline
|| loff.fill <= fill_below_window)
@@ -1503,8 +1539,9 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
/* Add one line below */
botline_forw(&boff);
used += boff.height;
- if (used > curwin->w_height)
+ if (used > curwin->w_grid.Rows) {
break;
+ }
if (extra < (
mouse_dragging > 0 ? mouse_dragging - 1 :
p_so) || scrolled < min_scroll) {
@@ -1525,14 +1562,14 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
}
linenr_T line_count;
- /* curwin->w_empty_rows is larger, no need to scroll */
- if (scrolled <= 0)
+ // curwin->w_empty_rows is larger, no need to scroll
+ if (scrolled <= 0) {
line_count = 0;
- /* more than a screenfull, don't scroll but redraw */
- else if (used > curwin->w_height)
+ // more than a screenfull, don't scroll but redraw
+ } else if (used > curwin->w_grid.Rows) {
line_count = used;
- /* scroll minimal number of lines */
- else {
+ // scroll minimal number of lines
+ } else {
line_count = 0;
boff.fill = curwin->w_topfill;
boff.lnum = curwin->w_topline - 1;
@@ -1550,10 +1587,11 @@ 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 && line_count > min_scroll)
+ if (line_count >= curwin->w_grid.Rows && line_count > min_scroll) {
scroll_cursor_halfway(false);
- else
+ } else {
scrollup(line_count, true);
+ }
/*
* If topline didn't change we need to restore w_botline and w_empty_rows
@@ -1592,8 +1630,9 @@ void scroll_cursor_halfway(int atend)
if (boff.lnum < curbuf->b_ml.ml_line_count) {
botline_forw(&boff);
used += boff.height;
- if (used > curwin->w_height)
+ if (used > curwin->w_grid.Rows) {
break;
+ }
below += boff.height;
} else {
++below; /* count a "~" line */
@@ -1608,8 +1647,9 @@ void scroll_cursor_halfway(int atend)
used = MAXCOL;
else
used += loff.height;
- if (used > curwin->w_height)
+ if (used > curwin->w_grid.Rows) {
break;
+ }
above += loff.height;
topline = loff.lnum;
topfill = loff.fill;
@@ -1618,8 +1658,9 @@ void scroll_cursor_halfway(int atend)
if (!hasFolding(topline, &curwin->w_topline, NULL))
curwin->w_topline = topline;
curwin->w_topfill = topfill;
- if (old_topline > curwin->w_topline + curwin->w_height)
+ if (old_topline > curwin->w_topline + curwin->w_grid.Rows) {
curwin->w_botfill = false;
+ }
check_topfill(curwin, false);
curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
curwin->w_valid |= VALID_TOPLINE;
@@ -1646,18 +1687,20 @@ void cursor_correct(void)
}
if (curwin->w_topline == 1) {
above_wanted = 0;
- int max_off = curwin->w_height / 2;
- if (below_wanted > max_off)
+ int max_off = curwin->w_grid.Rows / 2;
+ if (below_wanted > max_off) {
below_wanted = max_off;
+ }
}
validate_botline();
if (curwin->w_botline == curbuf->b_ml.ml_line_count + 1
&& mouse_dragging == 0
) {
below_wanted = 0;
- int max_off = (curwin->w_height - 1) / 2;
- if (above_wanted > max_off)
+ int max_off = (curwin->w_grid.Rows - 1) / 2;
+ if (above_wanted > max_off) {
above_wanted = max_off;
+ }
}
/*
@@ -1727,7 +1770,7 @@ void cursor_correct(void)
*
* return FAIL for failure, OK otherwise
*/
-int onepage(int dir, long count)
+int onepage(Direction dir, long count)
{
long n;
int retval = OK;
@@ -1761,7 +1804,7 @@ int onepage(int dir, long count)
loff.fill = 0;
if (dir == FORWARD) {
- if (firstwin == lastwin && p_window > 0 && p_window < Rows - 1) {
+ if (ONE_WINDOW && p_window > 0 && p_window < Rows - 1) {
/* Vi compatible scrolling */
if (p_window <= 2)
++curwin->w_topline;
@@ -1795,7 +1838,7 @@ int onepage(int dir, long count)
max_topfill();
continue;
}
- if (firstwin == lastwin && p_window > 0 && p_window < Rows - 1) {
+ if (ONE_WINDOW && p_window > 0 && p_window < Rows - 1) {
/* Vi compatible scrolling (sort of) */
if (p_window <= 2)
--curwin->w_topline;
@@ -1828,7 +1871,7 @@ int onepage(int dir, long count)
/* Find the line just above the new topline to get the right line
* at the bottom of the window. */
n = 0;
- while (n <= curwin->w_height && loff.lnum >= 1) {
+ while (n <= curwin->w_grid.Rows && loff.lnum >= 1) {
topline_back(&loff);
if (loff.height == MAXCOL)
n = MAXCOL;
@@ -1879,20 +1922,24 @@ int onepage(int dir, long count)
}
foldAdjustCursor();
cursor_correct();
- if (retval == OK)
+ check_cursor_col();
+ if (retval == OK) {
beginline(BL_SOL | BL_FIX);
+ }
curwin->w_valid &= ~(VALID_WCOL|VALID_WROW|VALID_VIRTCOL);
- /*
- * Avoid the screen jumping up and down when 'scrolloff' is non-zero.
- * But make sure we scroll at least one line (happens with mix of long
- * wrapping lines and non-wrapping line).
- */
- if (retval == OK && dir == FORWARD && check_top_offset()) {
- scroll_cursor_top(1, false);
- if (curwin->w_topline <= old_topline
- && old_topline < curbuf->b_ml.ml_line_count) {
- curwin->w_topline = old_topline + 1;
+ if (retval == OK && dir == FORWARD) {
+ // Avoid the screen jumping up and down when 'scrolloff' is non-zero.
+ // But make sure we scroll at least one line (happens with mix of long
+ // wrapping lines and non-wrapping line).
+ if (check_top_offset()) {
+ scroll_cursor_top(1, false);
+ if (curwin->w_topline <= old_topline
+ && old_topline < curbuf->b_ml.ml_line_count) {
+ curwin->w_topline = old_topline + 1;
+ (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
+ }
+ } else if (curwin->w_botline > curbuf->b_ml.ml_line_count) {
(void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
}
}
@@ -1915,7 +1962,7 @@ int onepage(int dir, long count)
*/
static void get_scroll_overlap(lineoff_T *lp, int dir)
{
- int min_height = curwin->w_height - 2;
+ int min_height = curwin->w_grid.Rows - 2;
if (lp->fill > 0)
lp->height = 1;
@@ -1969,13 +2016,15 @@ void halfpage(bool flag, linenr_T Prenum)
long scrolled = 0;
int i;
- if (Prenum)
- curwin->w_p_scr = (Prenum > curwin->w_height) ?
- curwin->w_height : Prenum;
+ if (Prenum) {
+ curwin->w_p_scr = (Prenum > curwin->w_grid.Rows) ? curwin->w_grid.Rows
+ : Prenum;
+ }
assert(curwin->w_p_scr <= INT_MAX);
- int n = curwin->w_p_scr <= curwin->w_height ? (int)curwin->w_p_scr
- : curwin->w_height;
+ int n = curwin->w_p_scr <= curwin->w_grid.Rows ? (int)curwin->w_p_scr
+ : curwin->w_grid.Rows;
+ update_topline();
validate_botline();
int room = curwin->w_empty_rows + curwin->w_filler_rows;
if (flag) {
@@ -1985,9 +2034,8 @@ void halfpage(bool flag, linenr_T Prenum)
while (n > 0 && curwin->w_botline <= curbuf->b_ml.ml_line_count) {
if (curwin->w_topfill > 0) {
i = 1;
- if (--n < 0 && scrolled > 0)
- break;
- --curwin->w_topfill;
+ n--;
+ curwin->w_topfill--;
} else {
i = plines_nofill(curwin->w_topline);
n -= i;
@@ -2063,9 +2111,8 @@ void halfpage(bool flag, linenr_T Prenum)
while (n > 0 && curwin->w_topline > 1) {
if (curwin->w_topfill < diff_check_fill(curwin, curwin->w_topline)) {
i = 1;
- if (--n < 0 && scrolled > 0)
- break;
- ++curwin->w_topfill;
+ n--;
+ curwin->w_topfill++;
} else {
i = plines_nofill(curwin->w_topline - 1);
n -= i;
@@ -2138,18 +2185,17 @@ void do_check_cursorbind(void)
* loop through the cursorbound windows
*/
VIsual_select = VIsual_active = 0;
- for (curwin = firstwin; curwin; curwin = curwin->w_next) {
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ curwin = wp;
curbuf = curwin->w_buffer;
/* skip original window and windows with 'noscrollbind' */
if (curwin != old_curwin && curwin->w_p_crb) {
- if (curwin->w_p_diff)
- curwin->w_cursor.lnum
- = diff_get_corresponding_line(old_curbuf,
- line,
- curbuf,
- curwin->w_cursor.lnum);
- else
+ if (curwin->w_p_diff) {
+ curwin->w_cursor.lnum =
+ diff_get_corresponding_line(old_curbuf, line);
+ } else {
curwin->w_cursor.lnum = line;
+ }
curwin->w_cursor.col = col;
curwin->w_cursor.coladd = coladd;
curwin->w_curswant = curswant;
@@ -2161,16 +2207,19 @@ void do_check_cursorbind(void)
int restart_edit_save = restart_edit;
restart_edit = true;
check_cursor();
+ if (win_cursorline_standout(curwin) || curwin->w_p_cuc) {
+ validate_cursor();
+ }
restart_edit = restart_edit_save;
}
- /* Correct cursor for multi-byte character. */
- if (has_mbyte)
- mb_adjust_cursor();
+ // Correct cursor for multi-byte character.
+ mb_adjust_cursor();
redraw_later(VALID);
- /* Only scroll when 'scrollbind' hasn't done this. */
- if (!curwin->w_p_scb)
+ // Only scroll when 'scrollbind' hasn't done this.
+ if (!curwin->w_p_scb) {
update_topline();
+ }
curwin->w_redr_status = true;
}
}