diff options
Diffstat (limited to 'src/nvim/move.c')
-rw-r--r-- | src/nvim/move.c | 365 |
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; } } |