diff options
Diffstat (limited to 'src/nvim/move.c')
-rw-r--r-- | src/nvim/move.c | 164 |
1 files changed, 93 insertions, 71 deletions
diff --git a/src/nvim/move.c b/src/nvim/move.c index 9ed3978490..551aa1bd4d 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -15,6 +15,7 @@ #include "nvim/ascii_defs.h" #include "nvim/buffer.h" +#include "nvim/buffer_defs.h" #include "nvim/cursor.h" #include "nvim/diff.h" #include "nvim/drawscreen.h" @@ -22,14 +23,14 @@ #include "nvim/eval/typval.h" #include "nvim/eval/window.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/getchar.h" -#include "nvim/gettext.h" +#include "nvim/gettext_defs.h" #include "nvim/globals.h" #include "nvim/grid.h" #include "nvim/highlight.h" +#include "nvim/highlight_defs.h" #include "nvim/macros_defs.h" -#include "nvim/mark.h" +#include "nvim/mark_defs.h" #include "nvim/mbyte.h" #include "nvim/memline.h" #include "nvim/message.h" @@ -41,7 +42,6 @@ #include "nvim/popupmenu.h" #include "nvim/pos_defs.h" #include "nvim/search.h" -#include "nvim/sign_defs.h" #include "nvim/strings.h" #include "nvim/types_defs.h" #include "nvim/vim_defs.h" @@ -135,29 +135,55 @@ static void comp_botline(win_T *wp) win_check_anchored_floats(wp); } -/// Redraw when w_virtcol changes and 'cursorcolumn' is set or 'cursorlineopt' -/// contains "screenline" or when the "CurSearch" highlight is in use. -/// Also when concealing is on and 'concealcursor' is active. +/// Redraw when w_cline_row changes and 'relativenumber' or 'cursorline' is set. +/// Also when concealing is on and 'concealcursor' is not active. +static void redraw_for_cursorline(win_T *wp) + FUNC_ATTR_NONNULL_ALL +{ + if ((wp->w_valid & VALID_CROW) == 0 && !pum_visible() + && (wp->w_p_rnu || win_cursorline_standout(wp))) { + // win_line() will redraw the number column and cursorline only. + redraw_later(wp, UPD_VALID); + } +} + +/// Redraw when w_virtcol changes and +/// - 'cursorcolumn' is set, or +/// - 'cursorlineopt' contains "screenline", or +/// - "CurSearch" highlight is in use, or +/// - 'concealcursor' is active, or +/// - Visual mode is active. static void redraw_for_cursorcolumn(win_T *wp) FUNC_ATTR_NONNULL_ALL { - if ((wp->w_valid & VALID_VIRTCOL) == 0 && !pum_visible()) { - if (wp->w_p_cuc - || (win_hl_attr(wp, HLF_LC) != win_hl_attr(wp, HLF_L) && using_hlsearch())) { - // When 'cursorcolumn' is set or "CurSearch" is in use - // need to redraw with UPD_SOME_VALID. - redraw_later(wp, UPD_SOME_VALID); - } else if (wp->w_p_cul && (wp->w_p_culopt_flags & CULOPT_SCRLINE)) { - // When 'cursorlineopt' contains "screenline" need to redraw with UPD_VALID. - redraw_later(wp, UPD_VALID); - } + if (wp->w_valid & VALID_VIRTCOL) { + return; } + // If the cursor moves horizontally when 'concealcursor' is active, then the - // current line needs to be redrawn in order to calculate the correct - // cursor position. - if ((wp->w_valid & VALID_VIRTCOL) == 0 && wp->w_p_cole > 0 && conceal_cursor_line(wp)) { + // current line needs to be redrawn to calculate the correct cursor position. + if (wp->w_p_cole > 0 && conceal_cursor_line(wp)) { redrawWinline(wp, wp->w_cursor.lnum); } + + if (pum_visible()) { + return; + } + + if (wp->w_p_cuc + || (win_hl_attr(wp, HLF_LC) != win_hl_attr(wp, HLF_L) && using_hlsearch())) { + // When 'cursorcolumn' is set or "CurSearch" is in use + // need to redraw with UPD_SOME_VALID. + redraw_later(wp, UPD_SOME_VALID); + } else if (wp->w_p_cul && (wp->w_p_culopt_flags & CULOPT_SCRLINE)) { + // When 'cursorlineopt' contains "screenline" need to redraw with UPD_VALID. + redraw_later(wp, UPD_VALID); + } + + // When current buffer's cursor moves in Visual mode, redraw it with UPD_INVERTED. + if (VIsual_active && wp->w_buffer == curbuf) { + redraw_curbuf_later(UPD_INVERTED); + } } /// Calculates how much the 'listchars' "precedes" or 'smoothscroll' "<<<" @@ -201,14 +227,16 @@ static int skipcol_from_plines(win_T *wp, int plines_off) /// Set wp->w_skipcol to zero and redraw later if needed. static void reset_skipcol(win_T *wp) { - if (wp->w_skipcol != 0) { - wp->w_skipcol = 0; - - // Should use the least expensive way that displays all that changed. - // UPD_NOT_VALID is too expensive, UPD_REDRAW_TOP does not redraw - // enough when the top line gets another screen line. - redraw_later(wp, UPD_SOME_VALID); + if (wp->w_skipcol == 0) { + return; } + + wp->w_skipcol = 0; + + // Should use the least expensive way that displays all that changed. + // UPD_NOT_VALID is too expensive, UPD_REDRAW_TOP does not redraw + // enough when the top line gets another screen line. + redraw_later(wp, UPD_SOME_VALID); } // Update curwin->w_topline to move the cursor onto the screen. @@ -304,7 +332,7 @@ void update_topline(win_T *wp) if (lnum >= wp->w_buffer->b_ml.ml_line_count || n >= halfheight) { break; } - (void)hasFoldingWin(wp, lnum, NULL, &lnum, true, NULL); + hasFoldingWin(wp, lnum, NULL, &lnum, true, NULL); } } else { n = wp->w_topline + *so_ptr - wp->w_cursor.lnum; @@ -321,7 +349,7 @@ void update_topline(win_T *wp) } } else { // Make sure topline is the first line of a fold. - (void)hasFoldingWin(wp, wp->w_topline, &wp->w_topline, NULL, true, NULL); + hasFoldingWin(wp, wp->w_topline, &wp->w_topline, NULL, true, NULL); check_botline = true; } } @@ -349,7 +377,7 @@ void update_topline(win_T *wp) int n = wp->w_empty_rows; loff.lnum = wp->w_cursor.lnum; // In a fold go to its last line. - (void)hasFoldingWin(wp, loff.lnum, NULL, &loff.lnum, true, NULL); + hasFoldingWin(wp, loff.lnum, NULL, &loff.lnum, true, NULL); loff.fill = 0; n += wp->w_filler_rows; loff.height = 0; @@ -383,7 +411,7 @@ void update_topline(win_T *wp) if (lnum <= 0 || line_count > wp->w_height_inner + 1) { break; } - (void)hasFolding(lnum, &lnum, NULL); + hasFolding(lnum, &lnum, NULL); } } else { line_count = wp->w_cursor.lnum - wp->w_botline + 1 + (int)(*so_ptr); @@ -527,7 +555,7 @@ void set_topline(win_T *wp, linenr_T lnum) linenr_T prev_topline = wp->w_topline; // go to first of folded lines - (void)hasFoldingWin(wp, lnum, &lnum, NULL, true, NULL); + hasFoldingWin(wp, lnum, &lnum, NULL, true, NULL); // Approximate the value of w_botline wp->w_botline += lnum - wp->w_topline; wp->w_topline = lnum; @@ -567,19 +595,6 @@ void changed_line_abv_curs_win(win_T *wp) |VALID_CHEIGHT|VALID_TOPLINE); } -/// Display of line has changed for "buf", invalidate cursor position and -/// w_botline. -void changed_line_display_buf(buf_T *buf) -{ - FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - if (wp->w_buffer == buf) { - wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL - |VALID_CROW|VALID_CHEIGHT - |VALID_TOPLINE|VALID_BOTLINE|VALID_BOTLINE_AP); - } - } -} - // Make sure the value of curwin->w_botline is valid. void validate_botline(win_T *wp) { @@ -760,8 +775,8 @@ int win_col_off(win_T *wp) { return ((wp->w_p_nu || wp->w_p_rnu || *wp->w_p_stc != NUL) ? (number_width(wp) + (*wp->w_p_stc == NUL)) : 0) - + ((cmdwin_type == 0 || wp != curwin) ? 0 : 1) - + win_fdccol_count(wp) + (win_signcol_count(wp) * SIGN_WIDTH); + + ((wp != cmdwin_win) ? 0 : 1) + + win_fdccol_count(wp) + (wp->w_scwidth * SIGN_WIDTH); } int curwin_col_off(void) @@ -1038,7 +1053,9 @@ void curs_columns(win_T *wp, int may_scroll) void textpos2screenpos(win_T *wp, pos_T *pos, int *rowp, int *scolp, int *ccolp, int *ecolp, bool local) { - colnr_T scol = 0, ccol = 0, ecol = 0; + colnr_T scol = 0; + colnr_T ccol = 0; + colnr_T ecol = 0; int row = 0; colnr_T coloff = 0; bool visible_row = false; @@ -1126,8 +1143,13 @@ void f_screenpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) semsg(_(e_invalid_line_number_nr), pos.lnum); return; } + if (pos.col < 0) { + pos.col = 0; + } int row = 0; - int scol = 0, ccol = 0, ecol = 0; + int scol = 0; + int ccol = 0; + int ecol = 0; textpos2screenpos(wp, &pos, &row, &scol, &ccol, &ecol, false); tv_dict_add_nr(dict, S_LEN("row"), row); @@ -1202,7 +1224,7 @@ bool scrolldown(linenr_T line_count, int byfold) } // Make sure w_topline is at the first of a sequence of folded lines. - (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL); + hasFolding(curwin->w_topline, &curwin->w_topline, NULL); validate_cursor(); // w_wrow needs to be valid for (int todo = line_count; todo > 0; todo--) { if (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline) @@ -1327,11 +1349,11 @@ bool scrolldown(linenr_T line_count, int byfold) /// /// @param line_count number of lines to scroll /// @param byfold if true, count a closed fold as one line -bool scrollup(linenr_T line_count, int byfold) +bool scrollup(linenr_T line_count, bool byfold) { linenr_T topline = curwin->w_topline; linenr_T botline = curwin->w_botline; - int do_sms = curwin->w_p_wrap && curwin->w_p_sms; + bool do_sms = curwin->w_p_wrap && curwin->w_p_sms; if (do_sms || (byfold && hasAnyFolding(curwin)) || win_may_fill(curwin)) { int width1 = curwin->w_width_inner - curwin_col_off(); @@ -1354,7 +1376,7 @@ bool scrollup(linenr_T line_count, int byfold) linenr_T lnum = curwin->w_topline; if (byfold) { // for a closed fold: go to the last line in the fold - (void)hasFolding(lnum, NULL, &lnum); + hasFolding(lnum, NULL, &lnum); } if (lnum == curwin->w_topline && do_sms) { // 'smoothscroll': increase "w_skipcol" until it goes over @@ -1410,7 +1432,7 @@ bool scrollup(linenr_T line_count, int byfold) if (hasAnyFolding(curwin)) { // Make sure w_topline is at the first of a sequence of folded lines. - (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL); + hasFolding(curwin->w_topline, &curwin->w_topline, NULL); } curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE); @@ -1572,7 +1594,7 @@ static void max_topfill(void) // cursor off the screen. void scrolldown_clamp(void) { - int can_fill = (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline)); + bool can_fill = (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline)); if (curwin->w_topline <= 1 && !can_fill) { @@ -1604,7 +1626,7 @@ void scrolldown_clamp(void) curwin->w_topline--; curwin->w_topfill = 0; } - (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL); + hasFolding(curwin->w_topline, &curwin->w_topline, NULL); curwin->w_botline--; // approximate w_botline curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE); } @@ -1635,7 +1657,7 @@ void scrollup_clamp(void) if (curwin->w_topfill > 0) { curwin->w_topfill--; } else { - (void)hasFolding(curwin->w_topline, NULL, &curwin->w_topline); + hasFolding(curwin->w_topline, NULL, &curwin->w_topline); curwin->w_topline++; } curwin->w_botline++; // approximate w_botline @@ -1864,7 +1886,7 @@ void set_empty_rows(win_T *wp, int used) /// When scrolling scroll at least "min_scroll" lines. /// If "set_topbot" is true, set topline and botline first (for "zb"). /// This is messy stuff!!! -void scroll_cursor_bot(int min_scroll, int set_topbot) +void scroll_cursor_bot(int min_scroll, bool set_topbot) { lineoff_T loff; linenr_T old_topline = curwin->w_topline; @@ -1874,7 +1896,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) int old_valid = curwin->w_valid; int old_empty_rows = curwin->w_empty_rows; linenr_T cln = curwin->w_cursor.lnum; // Cursor Line Number - int do_sms = curwin->w_p_wrap && curwin->w_p_sms; + bool do_sms = curwin->w_p_wrap && curwin->w_p_sms; if (set_topbot) { bool set_skipcol = false; @@ -2093,7 +2115,7 @@ void scroll_cursor_halfway(bool atend, bool prefer_above) linenr_T old_topline = curwin->w_topline; lineoff_T loff = { .lnum = curwin->w_cursor.lnum }; lineoff_T boff = { .lnum = curwin->w_cursor.lnum }; - (void)hasFolding(loff.lnum, &loff.lnum, &boff.lnum); + hasFolding(loff.lnum, &loff.lnum, &boff.lnum); int used = plines_win_nofill(curwin, loff.lnum, true); loff.fill = 0; boff.fill = 0; @@ -2439,7 +2461,7 @@ int onepage(Direction dir, int count) botline_forw(curwin, &loff); botline_topline(&loff); // We're at the wrong end of a fold now. - (void)hasFoldingWin(curwin, loff.lnum, &loff.lnum, NULL, true, NULL); + hasFoldingWin(curwin, loff.lnum, &loff.lnum, NULL, true, NULL); // Always scroll at least one line. Avoid getting stuck on // very long lines. @@ -2486,10 +2508,10 @@ int onepage(Direction dir, int count) 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); + 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); + hasFolding(curwin->w_topline, &curwin->w_topline, NULL); } } @@ -2588,7 +2610,7 @@ void halfpage(bool flag, linenr_T Prenum) if (n < 0 && scrolled > 0) { break; } - (void)hasFolding(curwin->w_topline, NULL, &curwin->w_topline); + hasFolding(curwin->w_topline, NULL, &curwin->w_topline); curwin->w_topline++; curwin->w_topfill = win_get_fill(curwin, curwin->w_topline); @@ -2612,7 +2634,7 @@ void halfpage(bool flag, linenr_T Prenum) if (i > room) { break; } - (void)hasFolding(curwin->w_botline, NULL, &curwin->w_botline); + hasFolding(curwin->w_botline, NULL, &curwin->w_botline); curwin->w_botline++; room -= i; } while (curwin->w_botline <= curbuf->b_ml.ml_line_count); @@ -2624,8 +2646,8 @@ void halfpage(bool flag, linenr_T Prenum) if (hasAnyFolding(curwin)) { while (--n >= 0 && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) { - (void)hasFolding(curwin->w_cursor.lnum, NULL, - &curwin->w_cursor.lnum); + hasFolding(curwin->w_cursor.lnum, NULL, + &curwin->w_cursor.lnum); curwin->w_cursor.lnum++; } } else { @@ -2647,7 +2669,7 @@ void halfpage(bool flag, linenr_T Prenum) break; } curwin->w_topline--; - (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL); + hasFolding(curwin->w_topline, &curwin->w_topline, NULL); curwin->w_topfill = 0; } curwin->w_valid &= ~(VALID_CROW|VALID_WROW| @@ -2666,8 +2688,8 @@ void halfpage(bool flag, linenr_T Prenum) } else if (hasAnyFolding(curwin)) { while (--n >= 0 && curwin->w_cursor.lnum > 1) { curwin->w_cursor.lnum--; - (void)hasFolding(curwin->w_cursor.lnum, - &curwin->w_cursor.lnum, NULL); + hasFolding(curwin->w_cursor.lnum, + &curwin->w_cursor.lnum, NULL); } } else { curwin->w_cursor.lnum -= n; @@ -2697,7 +2719,7 @@ void do_check_cursorbind(void) colnr_T col = curwin->w_cursor.col; colnr_T coladd = curwin->w_cursor.coladd; colnr_T curswant = curwin->w_curswant; - int set_curswant = curwin->w_set_curswant; + bool set_curswant = curwin->w_set_curswant; win_T *old_curwin = curwin; buf_T *old_curbuf = curbuf; int old_VIsual_select = VIsual_select; |