aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/move.c
diff options
context:
space:
mode:
authorJames McCoy <jamessan@jamessan.com>2020-08-08 08:57:35 -0400
committerJames McCoy <jamessan@jamessan.com>2020-08-08 08:57:35 -0400
commit840c12c10741d8f70e1787534fb6ea6d2b70edee (patch)
treef89ad27acbbf0b36db7ac08eeae0b8362da1fabb /src/nvim/move.c
parente813ec79c201c85c5af3b10c051ae92ab5cb8606 (diff)
parentf26df8bb66158baacb79c79822babaf137607cd6 (diff)
downloadrneovim-840c12c10741d8f70e1787534fb6ea6d2b70edee.tar.gz
rneovim-840c12c10741d8f70e1787534fb6ea6d2b70edee.tar.bz2
rneovim-840c12c10741d8f70e1787534fb6ea6d2b70edee.zip
Merge remote-tracking branch 'upstream/master' into libcallnr
Diffstat (limited to 'src/nvim/move.c')
-rw-r--r--src/nvim/move.c197
1 files changed, 98 insertions, 99 deletions
diff --git a/src/nvim/move.c b/src/nvim/move.c
index e6fee9999f..8a8a639a52 100644
--- a/src/nvim/move.c
+++ b/src/nvim/move.c
@@ -65,17 +65,10 @@ static void comp_botline(win_T *wp)
done = 0;
}
- for (; lnum <= wp->w_buffer->b_ml.ml_line_count; ++lnum) {
- int n;
+ for (; lnum <= wp->w_buffer->b_ml.ml_line_count; lnum++) {
linenr_T last = lnum;
- bool folded = hasFoldingWin(wp, lnum, NULL, &last, true, NULL);
- if (folded) {
- n = 1;
- } else if (lnum == wp->w_topline) {
- n = plines_win_nofill(wp, lnum, true) + wp->w_topfill;
- } else {
- n = plines_win(wp, lnum, true);
- }
+ bool folded;
+ int n = plines_win_full(wp, lnum, &last, &folded, true);
if (lnum <= wp->w_cursor.lnum && last >= wp->w_cursor.lnum) {
wp->w_cline_row = done;
wp->w_cline_height = n;
@@ -93,6 +86,7 @@ static void comp_botline(win_T *wp)
/* wp->w_botline is the line that is just below the window */
wp->w_botline = lnum;
wp->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
+ wp->w_viewport_invalid = true;
set_empty_rows(wp, done);
@@ -149,7 +143,8 @@ void update_topline(void)
int old_topfill;
bool check_topline = false;
bool check_botline = false;
- long save_so = p_so;
+ long *so_ptr = curwin->w_p_so >= 0 ? &curwin->w_p_so : &p_so;
+ long save_so = *so_ptr;
// If there is no valid screen and when the window height is zero just use
// the cursor line.
@@ -157,6 +152,7 @@ void update_topline(void)
curwin->w_topline = curwin->w_cursor.lnum;
curwin->w_botline = curwin->w_topline;
curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
+ curwin->w_viewport_invalid = true;
curwin->w_scbind_pos = 1;
return;
}
@@ -165,9 +161,10 @@ void update_topline(void)
if (curwin->w_valid & VALID_TOPLINE)
return;
- /* When dragging with the mouse, don't scroll that quickly */
- if (mouse_dragging > 0)
- p_so = mouse_dragging - 1;
+ // When dragging with the mouse, don't scroll that quickly
+ if (mouse_dragging > 0) {
+ *so_ptr = mouse_dragging - 1;
+ }
old_topline = curwin->w_topline;
old_topfill = curwin->w_topfill;
@@ -180,6 +177,7 @@ void update_topline(void)
curwin->w_topline = 1;
curwin->w_botline = 2;
curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
+ curwin->w_viewport_invalid = true;
curwin->w_scbind_pos = 1;
}
/*
@@ -213,15 +211,17 @@ void update_topline(void)
* scrolled). */
n = 0;
for (linenr_T lnum = curwin->w_cursor.lnum;
- lnum < curwin->w_topline + p_so; ++lnum) {
- ++n;
- /* stop at end of file or when we know we are far off */
- if (lnum >= curbuf->b_ml.ml_line_count || n >= halfheight)
+ lnum < curwin->w_topline + *so_ptr; lnum++) {
+ n++;
+ // stop at end of file or when we know we are far off
+ if (lnum >= curbuf->b_ml.ml_line_count || n >= halfheight) {
break;
+ }
(void)hasFolding(lnum, NULL, &lnum);
}
- } else
- n = curwin->w_topline + p_so - curwin->w_cursor.lnum;
+ } else {
+ n = curwin->w_topline + *so_ptr - curwin->w_cursor.lnum;
+ }
/* If we weren't very close to begin with, we scroll to put the
* cursor in the middle of the window. Otherwise put the cursor
@@ -254,7 +254,7 @@ void update_topline(void)
if (curwin->w_botline <= curbuf->b_ml.ml_line_count) {
if (curwin->w_cursor.lnum < curwin->w_botline) {
if (((long)curwin->w_cursor.lnum
- >= (long)curwin->w_botline - p_so
+ >= (long)curwin->w_botline - *so_ptr
|| hasAnyFolding(curwin)
)) {
lineoff_T loff;
@@ -273,13 +273,15 @@ void update_topline(void)
&& (loff.lnum + 1 < curwin->w_botline || loff.fill == 0)
) {
n += loff.height;
- if (n >= p_so)
+ if (n >= *so_ptr) {
break;
+ }
botline_forw(&loff);
}
- if (n >= p_so)
- /* sufficient context, no need to scroll */
+ if (n >= *so_ptr) {
+ // sufficient context, no need to scroll
check_botline = false;
+ }
} else {
/* sufficient context, no need to scroll */
check_botline = false;
@@ -292,7 +294,7 @@ 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--) {
+ lnum >= curwin->w_botline - *so_ptr; lnum--) {
line_count++;
// stop at end of file or when we know we are far off
if (lnum <= 0 || line_count > curwin->w_height_inner + 1) {
@@ -302,7 +304,7 @@ void update_topline(void)
}
} else
line_count = curwin->w_cursor.lnum - curwin->w_botline
- + 1 + p_so;
+ + 1 + *so_ptr;
if (line_count <= curwin->w_height_inner + 1) {
scroll_cursor_bot(scrolljump_value(), false);
} else {
@@ -312,6 +314,7 @@ void update_topline(void)
}
}
curwin->w_valid |= VALID_TOPLINE;
+ curwin->w_viewport_invalid = true;
win_check_anchored_floats(curwin);
/*
@@ -331,7 +334,7 @@ void update_topline(void)
validate_cursor();
}
- p_so = save_so;
+ *so_ptr = save_so;
}
/*
@@ -363,25 +366,28 @@ static int scrolljump_value(void)
*/
static bool check_top_offset(void)
{
- if (curwin->w_cursor.lnum < curwin->w_topline + p_so
+ long so = get_scrolloff_value();
+ if (curwin->w_cursor.lnum < curwin->w_topline + so
|| hasAnyFolding(curwin)
) {
lineoff_T loff;
loff.lnum = curwin->w_cursor.lnum;
loff.fill = 0;
- int n = curwin->w_topfill; /* always have this context */
- /* Count the visible screen lines above the cursor line. */
- while (n < p_so) {
+ int n = curwin->w_topfill; // always have this context
+ // Count the visible screen lines above the cursor line.
+ while (n < so) {
topline_back(&loff);
- /* Stop when included a line above the window. */
+ // Stop when included a line above the window.
if (loff.lnum < curwin->w_topline
|| (loff.lnum == curwin->w_topline && loff.fill > 0)
- )
+ ) {
break;
+ }
n += loff.height;
}
- if (n < p_so)
+ if (n < so) {
return true;
+ }
}
return false;
}
@@ -405,6 +411,7 @@ void check_cursor_moved(win_T *wp)
|VALID_CHEIGHT|VALID_CROW|VALID_TOPLINE);
wp->w_valid_cursor = wp->w_cursor;
wp->w_valid_leftcol = wp->w_leftcol;
+ wp->w_viewport_invalid = true;
} else if (wp->w_cursor.col != wp->w_valid_cursor.col
|| wp->w_leftcol != wp->w_valid_leftcol
|| wp->w_cursor.coladd != wp->w_valid_cursor.coladd
@@ -413,6 +420,7 @@ void check_cursor_moved(win_T *wp)
wp->w_valid_cursor.col = wp->w_cursor.col;
wp->w_valid_leftcol = wp->w_leftcol;
wp->w_valid_cursor.coladd = wp->w_cursor.coladd;
+ wp->w_viewport_invalid = true;
}
}
@@ -571,18 +579,14 @@ static void curs_rows(win_T *wp)
break;
wp->w_cline_row += wp->w_lines[i].wl_size;
} else {
- long fold_count = foldedCount(wp, lnum, NULL);
- if (fold_count) {
- lnum += fold_count;
- if (lnum > wp->w_cursor.lnum)
- break;
- ++wp->w_cline_row;
- } else if (lnum == wp->w_topline) {
- wp->w_cline_row += plines_win_nofill(wp, lnum++, true)
- + wp->w_topfill;
- } else {
- wp->w_cline_row += plines_win(wp, lnum++, true);
+ linenr_T last = lnum;
+ bool folded;
+ int n = plines_win_full(wp, lnum, &last, &folded, false);
+ lnum = last + 1;
+ if (folded && lnum > wp->w_cursor.lnum) {
+ break;
}
+ wp->w_cline_row += n;
}
}
@@ -593,18 +597,13 @@ static void curs_rows(win_T *wp)
|| (i < wp->w_lines_valid
&& (!wp->w_lines[i].wl_valid
|| wp->w_lines[i].wl_lnum != wp->w_cursor.lnum))) {
- if (wp->w_cursor.lnum == wp->w_topline)
- wp->w_cline_height = plines_win_nofill(wp, wp->w_cursor.lnum,
- true) + wp->w_topfill;
- else
- wp->w_cline_height = plines_win(wp, wp->w_cursor.lnum, true);
- wp->w_cline_folded = hasFoldingWin(wp, wp->w_cursor.lnum,
- NULL, NULL, true, NULL);
+ wp->w_cline_height = plines_win_full(wp, wp->w_cursor.lnum, NULL,
+ &wp->w_cline_folded, true);
} else if (i > wp->w_lines_valid) {
/* a line that is too long to fit on the last screen line */
wp->w_cline_height = 0;
- wp->w_cline_folded = hasFoldingWin(wp, wp->w_cursor.lnum,
- NULL, NULL, true, NULL);
+ wp->w_cline_folded = hasFoldingWin(wp, wp->w_cursor.lnum, NULL,
+ NULL, true, NULL);
} else {
wp->w_cline_height = wp->w_lines[i].wl_size;
wp->w_cline_folded = wp->w_lines[i].wl_folded;
@@ -646,12 +645,9 @@ static void validate_cheight(void)
{
check_cursor_moved(curwin);
if (!(curwin->w_valid & VALID_CHEIGHT)) {
- if (curwin->w_cursor.lnum == curwin->w_topline)
- curwin->w_cline_height = plines_nofill(curwin->w_cursor.lnum)
- + curwin->w_topfill;
- else
- curwin->w_cline_height = plines(curwin->w_cursor.lnum);
- curwin->w_cline_folded = hasFolding(curwin->w_cursor.lnum, NULL, NULL);
+ curwin->w_cline_height = plines_win_full(curwin, curwin->w_cursor.lnum,
+ NULL, &curwin->w_cline_folded,
+ true);
curwin->w_valid |= VALID_CHEIGHT;
}
}
@@ -693,7 +689,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
+ + win_fdccol_count(wp)
+ (win_signcol_count(wp) * win_signcol_width(wp));
}
@@ -733,6 +729,8 @@ void curs_columns(
colnr_T startcol;
colnr_T endcol;
colnr_T prev_skipcol;
+ long so = get_scrolloff_value();
+ long siso = get_sidescrolloff_value();
/*
* First make sure that w_topline is valid (after moving the cursor).
@@ -804,10 +802,10 @@ void curs_columns(
* If we get closer to the edge than 'sidescrolloff', scroll a little
* extra
*/
- assert(p_siso <= INT_MAX);
- int off_left = startcol - curwin->w_leftcol - (int)p_siso;
+ assert(siso <= INT_MAX);
+ int off_left = startcol - curwin->w_leftcol - (int)siso;
int off_right =
- endcol - curwin->w_leftcol - curwin->w_width_inner + (int)p_siso + 1;
+ endcol - curwin->w_leftcol - curwin->w_width_inner + (int)siso + 1;
if (off_left < 0 || off_right > 0) {
int diff = (off_left < 0) ? -off_left: off_right;
@@ -853,7 +851,7 @@ void curs_columns(
int plines = 0;
if ((curwin->w_wrow >= curwin->w_height_inner
|| ((prev_skipcol > 0
- || curwin->w_wrow + p_so >= curwin->w_height_inner)
+ || curwin->w_wrow + so >= curwin->w_height_inner)
&& (plines =
plines_win_nofill(curwin, curwin->w_cursor.lnum, false)) - 1
>= curwin->w_height_inner))
@@ -869,17 +867,18 @@ void curs_columns(
* 2: Less than "p_so" lines below
* 3: both of them */
extra = 0;
- if (curwin->w_skipcol + p_so * width > curwin->w_virtcol)
+ if (curwin->w_skipcol + so * width > curwin->w_virtcol) {
extra = 1;
- /* Compute last display line of the buffer line that we want at the
- * bottom of the window. */
+ }
+ // Compute last display line of the buffer line that we want at the
+ // bottom of the window.
if (plines == 0) {
plines = plines_win(curwin, curwin->w_cursor.lnum, false);
}
plines--;
- if (plines > curwin->w_wrow + p_so) {
- assert(p_so <= INT_MAX);
- n = curwin->w_wrow + (int)p_so;
+ if (plines > curwin->w_wrow + so) {
+ assert(so <= INT_MAX);
+ n = curwin->w_wrow + (int)so;
} else {
n = plines;
}
@@ -887,7 +886,7 @@ void curs_columns(
extra += 2;
}
- if (extra == 3 || plines < p_so * 2) {
+ if (extra == 3 || plines < so * 2) {
// not enough room for 'scrolloff', put cursor in the middle
n = curwin->w_virtcol / width;
if (n > curwin->w_height_inner / 2) {
@@ -901,9 +900,9 @@ void curs_columns(
}
curwin->w_skipcol = n * width;
} else if (extra == 1) {
- /* less then 'scrolloff' lines above, decrease skipcol */
- assert(p_so <= INT_MAX);
- extra = (curwin->w_skipcol + (int)p_so * width - curwin->w_virtcol
+ // less then 'scrolloff' lines above, decrease skipcol
+ assert(so <= INT_MAX);
+ extra = (curwin->w_skipcol + (int)so * width - curwin->w_virtcol
+ width - 1) / width;
if (extra > 0) {
if ((colnr_T)(extra * width) > curwin->w_skipcol)
@@ -997,7 +996,7 @@ void textpos2screenpos(win_T *wp, pos_T *pos, int *rowp, int *scolp,
col -= wp->w_leftcol;
- if (col >= 0 && col < width) {
+ if (col >= 0 && col < wp->w_width) {
coloff = col - scol + (local ? 0 : wp->w_wincol) + 1;
} else {
scol = ccol = ecol = 0;
@@ -1225,7 +1224,7 @@ void scrolldown_clamp(void)
end_row += curwin->w_cline_height - 1 -
curwin->w_virtcol / curwin->w_width_inner;
}
- if (end_row < curwin->w_height_inner - p_so) {
+ if (end_row < curwin->w_height_inner - get_scrolloff_value()) {
if (can_fill) {
++curwin->w_topfill;
check_topfill(curwin, true);
@@ -1265,14 +1264,14 @@ void scrollup_clamp(void)
validate_virtcol();
start_row -= curwin->w_virtcol / curwin->w_width_inner;
}
- if (start_row >= p_so) {
- if (curwin->w_topfill > 0)
- --curwin->w_topfill;
- else {
+ if (start_row >= get_scrolloff_value()) {
+ if (curwin->w_topfill > 0) {
+ curwin->w_topfill--;
+ } else {
(void)hasFolding(curwin->w_topline, NULL, &curwin->w_topline);
- ++curwin->w_topline;
+ curwin->w_topline++;
}
- ++curwin->w_botline; /* approximate w_botline */
+ curwin->w_botline++; // approximate w_botline
curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE);
}
}
@@ -1368,8 +1367,7 @@ void scroll_cursor_top(int min_scroll, int always)
linenr_T old_topline = curwin->w_topline;
linenr_T old_topfill = curwin->w_topfill;
linenr_T new_topline;
- assert(p_so <= INT_MAX);
- int off = (int)p_so;
+ int off = (int)get_scrolloff_value();
if (mouse_dragging > 0)
off = mouse_dragging - 1;
@@ -1466,6 +1464,7 @@ void scroll_cursor_top(int min_scroll, int always)
curwin->w_valid &=
~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
curwin->w_valid |= VALID_TOPLINE;
+ curwin->w_viewport_invalid = true;
}
}
@@ -1511,7 +1510,8 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
linenr_T old_botline = curwin->w_botline;
int old_valid = curwin->w_valid;
int old_empty_rows = curwin->w_empty_rows;
- linenr_T cln = curwin->w_cursor.lnum; /* Cursor Line Number */
+ linenr_T cln = curwin->w_cursor.lnum; // Cursor Line Number
+ long so = get_scrolloff_value();
if (set_topbot) {
used = 0;
@@ -1570,15 +1570,14 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
/* Stop when scrolled nothing or at least "min_scroll", found "extra"
* context for 'scrolloff' and counted all lines below the window. */
if ((((scrolled <= 0 || scrolled >= min_scroll)
- && extra >= (
- mouse_dragging > 0 ? mouse_dragging - 1 :
- p_so))
+ && extra >= (mouse_dragging > 0 ? mouse_dragging - 1 : so))
|| boff.lnum + 1 > curbuf->b_ml.ml_line_count)
&& loff.lnum <= curwin->w_botline
&& (loff.lnum < curwin->w_botline
|| loff.fill >= fill_below_window)
- )
+ ) {
break;
+ }
/* Add one line above */
topline_back(&loff);
@@ -1609,9 +1608,8 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
if (used > curwin->w_height_inner) {
break;
}
- if (extra < (
- mouse_dragging > 0 ? mouse_dragging - 1 :
- p_so) || scrolled < min_scroll) {
+ if (extra < (mouse_dragging > 0 ? mouse_dragging - 1 : so)
+ || scrolled < min_scroll) {
extra += boff.height;
if (boff.lnum >= curwin->w_botline
|| (boff.lnum + 1 == curwin->w_botline
@@ -1671,6 +1669,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
curwin->w_valid = old_valid;
}
curwin->w_valid |= VALID_TOPLINE;
+ curwin->w_viewport_invalid = true;
}
/// Recompute topline to put the cursor halfway across the window
@@ -1745,9 +1744,8 @@ void cursor_correct(void)
* How many lines we would like to have above/below the cursor depends on
* whether the first/last line of the file is on screen.
*/
- assert(p_so <= INT_MAX);
- int above_wanted = (int)p_so;
- int below_wanted = (int)p_so;
+ int above_wanted = (int)get_scrolloff_value();
+ int below_wanted = (int)get_scrolloff_value();
if (mouse_dragging > 0) {
above_wanted = mouse_dragging - 1;
below_wanted = mouse_dragging - 1;
@@ -1761,8 +1759,7 @@ void cursor_correct(void)
}
validate_botline();
if (curwin->w_botline == curbuf->b_ml.ml_line_count + 1
- && mouse_dragging == 0
- ) {
+ && mouse_dragging == 0) {
below_wanted = 0;
int max_off = (curwin->w_height_inner - 1) / 2;
if (above_wanted > max_off) {
@@ -1829,6 +1826,7 @@ void cursor_correct(void)
}
}
curwin->w_valid |= VALID_TOPLINE;
+ curwin->w_viewport_invalid = true;
}
@@ -1843,6 +1841,7 @@ int onepage(Direction dir, long count)
int retval = OK;
lineoff_T loff;
linenr_T old_topline = curwin->w_topline;
+ long so = get_scrolloff_value();
if (curbuf->b_ml.ml_line_count == 1) { /* nothing to do */
beep_flush();
@@ -1858,7 +1857,7 @@ int onepage(Direction dir, long count)
* last line.
*/
if (dir == FORWARD
- ? ((curwin->w_topline >= curbuf->b_ml.ml_line_count - p_so)
+ ? ((curwin->w_topline >= curbuf->b_ml.ml_line_count - so)
&& curwin->w_botline > curbuf->b_ml.ml_line_count)
: (curwin->w_topline == 1
&& curwin->w_topfill ==