diff options
| author | zeertzjq <zeertzjq@outlook.com> | 2023-03-03 14:50:37 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-03 14:50:37 +0800 |
| commit | 5311c9048a638fecdc066810bb68b60c3048e326 (patch) | |
| tree | 57e64940efbb05dcd62a23ecc47c299bb4ed1b83 /src/nvim | |
| parent | 1dd2424b126f507402840321df012dbd94739044 (diff) | |
| download | rneovim-5311c9048a638fecdc066810bb68b60c3048e326.tar.gz rneovim-5311c9048a638fecdc066810bb68b60c3048e326.tar.bz2 rneovim-5311c9048a638fecdc066810bb68b60c3048e326.zip | |
refactor(win_line): move some variables into a struct (#22490)
This reduces the number of arguments to helpers functions.
N/A patches for version.c:
vim-patch:9.0.0152: warning for unused argument in small build
Co-authored-by: Bram Moolenaar <Bram@vim.org>
Diffstat (limited to 'src/nvim')
| -rw-r--r-- | src/nvim/drawline.c | 1294 |
1 files changed, 651 insertions, 643 deletions
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index e9ff299d68..9a56477d83 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -68,6 +68,43 @@ typedef enum { WL_LINE, // text in the line } LineDrawState; +/// structure with variables passed between win_line() and other functions +typedef struct { + LineDrawState draw_state; ///< what to draw next + + linenr_T lnum; ///< line number to be drawn + + int startrow; ///< first row in the window to be drawn + int row; ///< row in the window, excl w_winrow + + colnr_T vcol; ///< virtual column, before wrapping + int col; ///< visual column on screen, after wrapping + int boguscols; ///< nonexistent columns added to "col" to force wrapping + int vcol_off; ///< offset for concealed characters + + int off; ///< offset relative start of line + + int cul_attr; ///< set when 'cursorline' active + int line_attr; ///< attribute for the whole line + int line_attr_lowprio; ///< low-priority attribute for the line + + int char_attr; ///< attributes for next character + + int n_extra; ///< number of extra bytes + char *p_extra; ///< string of extra chars, plus NUL, only used + ///< when c_extra and c_final are NUL + char *p_extra_free; ///< p_extra buffer that needs to be freed + int extra_attr; ///< attributes for p_extra + int c_extra; ///< extra chars, all the same + int c_final; ///< final char, mandatory if set + + char extra[57]; ///< sign, line number and 'fdc' must fit in here + + int filler_lines; ///< nr of filler lines to be drawn + int filler_todo; ///< nr of filler lines still to do + 1 + SignTextAttrs sattrs[SIGN_SHOW_MAX]; ///< sign attributes for the sign column +} winlinevars_T; + /// for line_putchar. Contains the state that needs to be remembered from /// putting one character to the next. typedef struct { @@ -307,93 +344,87 @@ static bool use_cursor_line_sign(win_T *wp, linenr_T lnum) && (wp->w_p_culopt_flags & CULOPT_NBR); } -// Get information needed to display the sign in line 'lnum' in window 'wp'. -// If 'nrcol' is true, the sign is going to be displayed in the number column. -// Otherwise the sign is going to be displayed in the sign column. -// -// @param count max number of signs -// @param[out] n_extrap number of characters from pp_extra to display -// @param sign_idxp Index of the displayed sign -static void get_sign_display_info(bool nrcol, win_T *wp, linenr_T lnum, SignTextAttrs sattrs[], - int row, int startrow, int filler_lines, int filler_todo, - int *c_extrap, int *c_finalp, char *extra, size_t extra_size, - char **pp_extra, int *n_extrap, int *char_attrp, int sign_idx, - int cul_attr) +/// Get information needed to display the sign in line "wlv->lnum" in window "wp". +/// If "nrcol" is true, the sign is going to be displayed in the number column. +/// Otherwise the sign is going to be displayed in the sign column. +static void get_sign_display_info(bool nrcol, win_T *wp, winlinevars_T *wlv, int sign_idx, + int sign_cul_attr) { // Draw cells with the sign value or blank. - *c_extrap = ' '; - *c_finalp = NUL; + wlv->c_extra = ' '; + wlv->c_final = NUL; if (nrcol) { - *n_extrap = number_width(wp) + 1; + wlv->n_extra = number_width(wp) + 1; } else { - if (use_cursor_line_sign(wp, lnum)) { - *char_attrp = win_hl_attr(wp, HLF_CLS); + if (use_cursor_line_sign(wp, wlv->lnum)) { + wlv->char_attr = win_hl_attr(wp, HLF_CLS); } else { - *char_attrp = win_hl_attr(wp, HLF_SC); + wlv->char_attr = win_hl_attr(wp, HLF_SC); } - *n_extrap = win_signcol_width(wp); + wlv->n_extra = win_signcol_width(wp); } - if (row == startrow + filler_lines && filler_todo <= 0) { - SignTextAttrs *sattr = sign_get_attr(sign_idx, sattrs, wp->w_scwidth); + if (wlv->row == wlv->startrow + wlv->filler_lines && wlv->filler_todo <= 0) { + SignTextAttrs *sattr = sign_get_attr(sign_idx, wlv->sattrs, wp->w_scwidth); if (sattr != NULL) { - *pp_extra = sattr->text; - if (*pp_extra != NULL) { - *c_extrap = NUL; - *c_finalp = NUL; + wlv->p_extra = sattr->text; + if (wlv->p_extra != NULL) { + wlv->c_extra = NUL; + wlv->c_final = NUL; if (nrcol) { int n, width = number_width(wp) - 2; for (n = 0; n < width; n++) { - extra[n] = ' '; + wlv->extra[n] = ' '; } - extra[n] = NUL; - STRCAT(extra, *pp_extra); - STRCAT(extra, " "); - *pp_extra = extra; - *n_extrap = (int)strlen(*pp_extra); + wlv->extra[n] = NUL; + STRCAT(wlv->extra, wlv->p_extra); + STRCAT(wlv->extra, " "); + wlv->p_extra = wlv->extra; + wlv->n_extra = (int)strlen(wlv->p_extra); } else { - size_t symbol_blen = strlen(*pp_extra); + size_t symbol_blen = strlen(wlv->p_extra); // TODO(oni-link): Is sign text already extended to // full cell width? - assert((size_t)win_signcol_width(wp) >= mb_string2cells((char *)(*pp_extra))); + assert((size_t)win_signcol_width(wp) >= mb_string2cells(wlv->p_extra)); // symbol(s) bytes + (filling spaces) (one byte each) - *n_extrap = (int)symbol_blen + win_signcol_width(wp) - - (int)mb_string2cells(*pp_extra); + wlv->n_extra = (int)symbol_blen + win_signcol_width(wp) - + (int)mb_string2cells(wlv->p_extra); - assert(extra_size > symbol_blen); - memset(extra, ' ', extra_size); - memcpy(extra, *pp_extra, symbol_blen); + assert(sizeof(wlv->extra) > symbol_blen); + memset(wlv->extra, ' ', sizeof(wlv->extra)); + memcpy(wlv->extra, wlv->p_extra, symbol_blen); - *pp_extra = extra; - (*pp_extra)[*n_extrap] = NUL; + wlv->p_extra = wlv->extra; + wlv->p_extra[wlv->n_extra] = NUL; } } - if (use_cursor_line_sign(wp, lnum) && cul_attr > 0) { - *char_attrp = cul_attr; + if (use_cursor_line_sign(wp, wlv->lnum) && sign_cul_attr > 0) { + wlv->char_attr = sign_cul_attr; } else { - *char_attrp = sattr->hl_attr_id; + wlv->char_attr = sattr->hl_attr_id; } } } } -static int get_sign_attrs(buf_T *buf, linenr_T lnum, SignTextAttrs *sattrs, int *line_attr, - int *num_attr, int *cul_attr) +static int get_sign_attrs(buf_T *buf, winlinevars_T *wlv, int *sign_num_attrp, int *sign_cul_attrp) { - HlPriAttr line_attrs = { *line_attr, 0 }; - HlPriAttr num_attrs = { *num_attr, 0 }; - HlPriAttr cul_attrs = { *cul_attr, 0 }; + HlPriAttr line_attrs = { wlv->line_attr, 0 }; + HlPriAttr num_attrs = { *sign_num_attrp, 0 }; + HlPriAttr cul_attrs = { *sign_cul_attrp, 0 }; // TODO(bfredl, vigoux): line_attr should not take priority over decoration! - int num_signs = buf_get_signattrs(buf, lnum, sattrs, &num_attrs, &line_attrs, &cul_attrs); - decor_redraw_signs(buf, lnum - 1, &num_signs, sattrs, &num_attrs, &line_attrs, &cul_attrs); + int num_signs = buf_get_signattrs(buf, wlv->lnum, wlv->sattrs, &num_attrs, &line_attrs, + &cul_attrs); + decor_redraw_signs(buf, wlv->lnum - 1, &num_signs, wlv->sattrs, &num_attrs, &line_attrs, + &cul_attrs); - *line_attr = line_attrs.attr_id; - *num_attr = num_attrs.attr_id; - *cul_attr = cul_attrs.attr_id; + wlv->line_attr = line_attrs.attr_id; + *sign_num_attrp = num_attrs.attr_id; + *sign_cul_attrp = cul_attrs.attr_id; return num_signs; } @@ -449,30 +480,30 @@ static void get_statuscol_str(win_T *wp, linenr_T lnum, int virtnum, statuscol_T } /// Get information needed to display the next segment in the 'statuscolumn'. -/// If not yet at the end, prepare for next segment and decrement "draw_state". +/// If not yet at the end, prepare for next segment and decrement "wlv->draw_state". /// /// @param stcp Status column attributes -/// @param[out] draw_state Current draw state in win_line() -static void get_statuscol_display_info(statuscol_T *stcp, LineDrawState *draw_state, int *char_attr, - int *n_extrap, int *c_extrap, int *c_finalp, char **pp_extra) +/// @param[in,out] wlv +static void get_statuscol_display_info(statuscol_T *stcp, winlinevars_T *wlv) { - *c_extrap = NUL; - *c_finalp = NUL; + wlv->c_extra = NUL; + wlv->c_final = NUL; do { - *draw_state = WL_STC; - *char_attr = stcp->cur_attr; - *pp_extra = stcp->textp; - *n_extrap = (int)((stcp->hlrecp->start ? stcp->hlrecp->start : stcp->text_end) - stcp->textp); + wlv->draw_state = WL_STC; + wlv->char_attr = stcp->cur_attr; + wlv->p_extra = stcp->textp; + wlv->n_extra = + (int)((stcp->hlrecp->start ? stcp->hlrecp->start : stcp->text_end) - stcp->textp); // Prepare for next highlight section if not yet at the end - if (stcp->textp + *n_extrap < stcp->text_end) { + if (stcp->textp + wlv->n_extra < stcp->text_end) { int hl = stcp->hlrecp->userhl; stcp->textp = stcp->hlrecp->start; stcp->cur_attr = hl < 0 ? syn_id2attr(-hl) : hl > 0 ? hl : stcp->num_attr; stcp->hlrecp++; - *draw_state = WL_STC - 1; + wlv->draw_state = WL_STC - 1; } // Skip over empty highlight sections - } while (*n_extrap == 0 && stcp->textp < stcp->text_end); + } while (wlv->n_extra == 0 && stcp->textp < stcp->text_end); } /// Return true if CursorLineNr highlight is to be used for the number column. @@ -484,13 +515,13 @@ static void get_statuscol_display_info(statuscol_T *stcp, LineDrawState *draw_st /// - When line is wrapped and 'cursorlineopt' does not have "line", only highlight the line number /// itself on the first screenline of the wrapped line, otherwise highlight the number column of /// all screenlines of the wrapped line. -static bool use_cursor_line_nr(win_T *wp, linenr_T lnum, int row, int startrow, int filler_lines) +static bool use_cursor_line_nr(win_T *wp, winlinevars_T *wlv) { return wp->w_p_cul - && lnum == wp->w_cursorline + && wlv->lnum == wp->w_cursorline && (wp->w_p_culopt_flags & CULOPT_NBR) - && (row == startrow + filler_lines - || (row > startrow + filler_lines + && (wlv->row == wlv->startrow + wlv->filler_lines + || (wlv->row > wlv->startrow + wlv->filler_lines && (wp->w_p_culopt_flags & CULOPT_LINE))); } @@ -515,20 +546,20 @@ static inline void get_line_number_str(win_T *wp, linenr_T lnum, char *buf, size snprintf(buf, buf_len, fmt, number_width(wp), num); } -static int get_line_number_attr(win_T *wp, linenr_T lnum, int row, int startrow, int filler_lines) +static int get_line_number_attr(win_T *wp, winlinevars_T *wlv) { - if (use_cursor_line_nr(wp, lnum, row, startrow, filler_lines)) { + if (use_cursor_line_nr(wp, wlv)) { // TODO(vim): Can we use CursorLine instead of CursorLineNr // when CursorLineNr isn't set? return win_hl_attr(wp, HLF_CLN); } if (wp->w_p_rnu) { - if (lnum < wp->w_cursor.lnum) { + if (wlv->lnum < wp->w_cursor.lnum) { // Use LineNrAbove return win_hl_attr(wp, HLF_LNA); } - if (lnum > wp->w_cursor.lnum) { + if (wlv->lnum > wp->w_cursor.lnum) { // Use LineNrBelow return win_hl_attr(wp, HLF_LNB); } @@ -537,22 +568,21 @@ static int get_line_number_attr(win_T *wp, linenr_T lnum, int row, int startrow, return win_hl_attr(wp, HLF_N); } -static void apply_cursorline_highlight(win_T *wp, linenr_T lnum, int *line_attr, int *cul_attr, - int *line_attr_lowprio) +static void apply_cursorline_highlight(win_T *wp, winlinevars_T *wlv) { - *cul_attr = win_hl_attr(wp, HLF_CUL); - HlAttrs ae = syn_attr2entry(*cul_attr); + wlv->cul_attr = win_hl_attr(wp, HLF_CUL); + HlAttrs ae = syn_attr2entry(wlv->cul_attr); // We make a compromise here (#7383): // * low-priority CursorLine if fg is not set // * high-priority ("same as Vim" priority) CursorLine if fg is set if (ae.rgb_fg_color == -1 && ae.cterm_fg_color == 0) { - *line_attr_lowprio = *cul_attr; + wlv->line_attr_lowprio = wlv->cul_attr; } else { if (!(State & MODE_INSERT) && bt_quickfix(wp->w_buffer) - && qf_current_entry(wp) == lnum) { - *line_attr = hl_combine_attr(*cul_attr, *line_attr); + && qf_current_entry(wp) == wlv->lnum) { + wlv->line_attr = hl_combine_attr(wlv->cul_attr, wlv->line_attr); } else { - *line_attr = *cul_attr; + wlv->line_attr = wlv->cul_attr; } } } @@ -604,6 +634,20 @@ static colnr_T get_leadcol(win_T *wp, const char *ptr, const char *line) return leadcol; } +/// Start a screen line at column zero. +static void win_line_start(win_T *wp, winlinevars_T *wlv) +{ + wlv->col = 0; + wlv->off = 0; + if (wp->w_p_rl) { + // Rightleft window: process the text in the normal direction, but put + // it in linebuf_char[wlv.off] from right to left. Start at the + // rightmost column of the window. + wlv->col = wp->w_grid.cols - 1; + wlv->off += wlv->col; + } +} + /// Display line "lnum" of window 'wp' on the screen. /// wp->w_virtcol needs to be valid. /// @@ -621,23 +665,15 @@ static colnr_T get_leadcol(win_T *wp, const char *ptr, const char *line) int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, bool number_only, foldinfo_T foldinfo, DecorProviders *providers, char **provider_err) { + winlinevars_T wlv; // variables passed between functions + int c = 0; // init for GCC - colnr_T vcol = 0; // virtual column (for tabs) long vcol_sbr = -1; // virtual column after showbreak - long vcol_prev = -1; // "vcol" of previous character + long vcol_prev = -1; // "wlv.vcol" of previous character char *line; // current line char *ptr; // current position in "line" - int row; // row in the window, excl w_winrow ScreenGrid *grid = &wp->w_grid; // grid specific to the window - char extra[57]; // sign, line number and 'fdc' must - // fit in here - int n_extra = 0; // number of extra chars - char *p_extra = NULL; // string of extra chars, plus NUL - char *p_extra_free = NULL; // p_extra needs to be freed - int c_extra = NUL; // extra chars, all the same - int c_final = NUL; // final char, mandatory if set - int extra_attr = 0; // attributes when n_extra != 0 static char *at_end_str = ""; // used for p_extra when displaying curwin->w_p_lcs_chars.eol // at end-of-line bool has_fold = foldinfo.fi_level != 0 && foldinfo.fi_lines > 0; @@ -664,7 +700,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, pos_T pos; ptrdiff_t v; - int char_attr = 0; // attributes for next character bool attr_pri = false; // char_attr has priority bool area_highlighting = false; // Visual or incsearch highlighting in this line int vi_attr = 0; // attributes for Visual and incsearch highlighting @@ -697,17 +732,13 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, int mb_c = 0; // decoded multi-byte character bool mb_utf8 = false; // screen char is UTF-8 char int u8cc[MAX_MCO]; // composing UTF-8 chars - int filler_lines; // nr of filler lines to be drawn - int filler_todo; // nr of filler lines still to do + 1 hlf_T diff_hlf = (hlf_T)0; // type of diff highlighting int change_start = MAXCOL; // first col of changed area int change_end = -1; // last col of changed area bool in_multispace = false; // in multiple consecutive spaces int multispace_pos = 0; // position in lcs-multispace string bool need_showbreak = false; // overlong line, skip first x chars - int line_attr = 0; // attribute for the whole line int line_attr_save; - int line_attr_lowprio = 0; // low-priority attribute for the line int line_attr_lowprio_save; int prev_c = 0; // previous Arabic character int prev_c1 = 0; // first composing char for prev_c @@ -720,7 +751,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, bool area_active = false; - int cul_attr = 0; // set when 'cursorline' active // 'cursorlineopt' has "screenline" and cursor is in this line bool cul_screenline = false; // margin columns for the screen line, needed for when 'cursorlineopt' @@ -728,8 +758,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, int left_curline_col = 0; int right_curline_col = 0; - LineDrawState draw_state = WL_START; // what to draw next - int match_conc = 0; ///< cchar for match functions bool on_last_col = false; int syntax_flags = 0; @@ -737,27 +765,28 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, int prev_syntax_id = 0; int conceal_attr = win_hl_attr(wp, HLF_CONCEAL); bool is_concealing = false; - int boguscols = 0; ///< nonexistent columns added to - ///< force wrapping - int vcol_off = 0; ///< offset for concealed characters int did_wcol = false; int old_boguscols = 0; -#define VCOL_HLC (vcol - vcol_off) +#define VCOL_HLC (wlv.vcol - wlv.vcol_off) #define FIX_FOR_BOGUSCOLS \ { \ - n_extra += vcol_off; \ - vcol -= vcol_off; \ - vcol_off = 0; \ - col -= boguscols; \ - old_boguscols = boguscols; \ - boguscols = 0; \ + wlv.n_extra += wlv.vcol_off; \ + wlv.vcol -= wlv.vcol_off; \ + wlv.vcol_off = 0; \ + wlv.col -= wlv.boguscols; \ + old_boguscols = wlv.boguscols; \ + wlv.boguscols = 0; \ } if (startrow > endrow) { // past the end already! return startrow; } - row = startrow; + CLEAR_FIELD(wlv); + + wlv.lnum = lnum; + wlv.startrow = startrow; + wlv.row = startrow; buf_T *buf = wp->w_buffer; bool end_fill = (lnum == buf->b_ml.ml_line_count + 1); @@ -935,9 +964,9 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, int bg_attr = win_bg_attr(wp); int linestatus = 0; - filler_lines = diff_check_with_linestatus(wp, lnum, &linestatus); - if (filler_lines < 0 || linestatus < 0) { - if (filler_lines == -1 || linestatus == -1) { + wlv.filler_lines = diff_check_with_linestatus(wp, lnum, &linestatus); + if (wlv.filler_lines < 0 || linestatus < 0) { + if (wlv.filler_lines == -1 || linestatus == -1) { if (diff_find_change(wp, lnum, &change_start, &change_end)) { diff_hlf = HLF_ADD; // added line } else if (change_start == 0) { @@ -949,18 +978,18 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, diff_hlf = HLF_ADD; // added line } if (linestatus == 0) { - filler_lines = 0; + wlv.filler_lines = 0; } area_highlighting = true; } VirtLines virt_lines = KV_INITIAL_VALUE; int n_virt_lines = decor_virt_lines(wp, lnum, &virt_lines, has_fold); - filler_lines += n_virt_lines; + wlv.filler_lines += n_virt_lines; if (lnum == wp->w_topline) { - filler_lines = wp->w_topfill; - n_virt_lines = MIN(n_virt_lines, filler_lines); + wlv.filler_lines = wp->w_topfill; + n_virt_lines = MIN(n_virt_lines, wlv.filler_lines); } - filler_todo = filler_lines; + wlv.filler_todo = wlv.filler_lines; // Cursor line highlighting for 'cursorline' in the current window. if (wp->w_p_cul && wp->w_p_culopt_flags != CULOPT_NBR && lnum == wp->w_cursorline @@ -969,31 +998,29 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, && !(wp == curwin && VIsual_active)) { cul_screenline = (wp->w_p_wrap && (wp->w_p_culopt_flags & CULOPT_SCRLINE)); if (!cul_screenline) { - apply_cursorline_highlight(wp, lnum, &line_attr, &cul_attr, &line_attr_lowprio); + apply_cursorline_highlight(wp, &wlv); } else { margin_columns_win(wp, &left_curline_col, &right_curline_col); } area_highlighting = true; } - SignTextAttrs sattrs[SIGN_SHOW_MAX]; // sign attributes for the sign column int sign_num_attr = 0; // sign attribute for the number column int sign_cul_attr = 0; // sign attribute for cursorline - CLEAR_FIELD(sattrs); - int num_signs = get_sign_attrs(buf, lnum, sattrs, &line_attr, &sign_num_attr, &sign_cul_attr); + int num_signs = get_sign_attrs(buf, &wlv, &sign_num_attr, &sign_cul_attr); // Highlight the current line in the quickfix window. if (bt_quickfix(wp->w_buffer) && qf_current_entry(wp) == lnum) { - line_attr = win_hl_attr(wp, HLF_QFL); + wlv.line_attr = win_hl_attr(wp, HLF_QFL); } - if (line_attr_lowprio || line_attr) { + if (wlv.line_attr_lowprio || wlv.line_attr) { area_highlighting = true; } if (cul_screenline) { - line_attr_save = line_attr; - line_attr_lowprio_save = line_attr_lowprio; + line_attr_save = wlv.line_attr; + line_attr_lowprio_save = wlv.line_attr_lowprio; } line = end_fill ? "" : ml_get_buf(wp->w_buffer, lnum, false); @@ -1061,14 +1088,14 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, chartabsize_T cts; int charsize; - init_chartabsize_arg(&cts, wp, lnum, vcol, line, ptr); + init_chartabsize_arg(&cts, wp, lnum, wlv.vcol, line, ptr); while (cts.cts_vcol < v && *cts.cts_ptr != NUL) { charsize = win_lbr_chartabsize(&cts, NULL); cts.cts_vcol += charsize; prev_ptr = cts.cts_ptr; MB_PTR_ADV(cts.cts_ptr); } - vcol = cts.cts_vcol; + wlv.vcol = cts.cts_vcol; ptr = cts.cts_ptr; clear_chartabsize_arg(&cts); @@ -1078,31 +1105,31 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, // - 'virtualedit' is set, or // - the visual mode is active, // the end of the line may be before the start of the displayed part. - if (vcol < v && (wp->w_p_cuc - || draw_color_col - || virtual_active() - || (VIsual_active && wp->w_buffer == curwin->w_buffer))) { - vcol = (colnr_T)v; + if (wlv.vcol < v && (wp->w_p_cuc + || draw_color_col + || virtual_active() + || (VIsual_active && wp->w_buffer == curwin->w_buffer))) { + wlv.vcol = (colnr_T)v; } // Handle a character that's not completely on the screen: Put ptr at // that character but skip the first few screen characters. - if (vcol > v) { - vcol -= charsize; + if (wlv.vcol > v) { + wlv.vcol -= charsize; ptr = prev_ptr; // If the character fits on the screen, don't need to skip it. // Except for a TAB. if (utf_ptr2cells(ptr) >= charsize || *ptr == TAB) { - n_skip = (int)(v - vcol); + n_skip = (int)(v - wlv.vcol); } } // Adjust for when the inverted text is before the screen, // and when the start of the inverted text is before the screen. - if (tocol <= vcol) { + if (tocol <= wlv.vcol) { fromcol = 0; - } else if (fromcol >= 0 && fromcol < vcol) { - fromcol = vcol; + } else if (fromcol >= 0 && fromcol < wlv.vcol) { + fromcol = wlv.vcol; } // When w_skipcol is non-zero, first line needs 'showbreak' @@ -1176,15 +1203,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, ptr = line + v; // "line" may have been updated } - int off = 0; // Offset relative start of line - int col = 0; // Visual column on screen. - if (wp->w_p_rl) { - // Rightleft window: process the text in the normal direction, but put - // it in linebuf_char[off] from right to left. Start at the - // rightmost column of the window. - col = grid->cols - 1; - off += col; - } + win_line_start(wp, &wlv); // won't highlight after TERM_ATTRS_MAX columns int term_attrs[TERM_ATTRS_MAX] = { 0 }; @@ -1197,13 +1216,12 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, if (*wp->w_p_stc != NUL) { // Draw the 'statuscolumn' if option is set. statuscol.draw = true; - statuscol.sattrs = sattrs; + statuscol.sattrs = wlv.sattrs; statuscol.foldinfo = foldinfo; statuscol.width = win_col_off(wp) - (cmdwin_type != 0 && wp == curwin); statuscol.use_cul = use_cursor_line_sign(wp, lnum); statuscol.sign_cul_attr = statuscol.use_cul ? sign_cul_attr : 0; - statuscol.num_attr = sign_num_attr ? sign_num_attr - : get_line_number_attr(wp, lnum, row, startrow, filler_lines); + statuscol.num_attr = sign_num_attr ? sign_num_attr : get_line_number_attr(wp, &wlv); } int sign_idx = 0; @@ -1217,27 +1235,27 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, bool did_decrement_ptr = false; // Skip this quickly when working on the text. - if (draw_state != WL_LINE) { + if (wlv.draw_state != WL_LINE) { if (cul_screenline) { - cul_attr = 0; - line_attr = line_attr_save; - line_attr_lowprio = line_attr_lowprio_save; + wlv.cul_attr = 0; + wlv.line_attr = line_attr_save; + wlv.line_attr_lowprio = line_attr_lowprio_save; } - if (draw_state == WL_CMDLINE - 1 && n_extra == 0) { - draw_state = WL_CMDLINE; + if (wlv.draw_state == WL_CMDLINE - 1 && wlv.n_extra == 0) { + wlv.draw_state = WL_CMDLINE; if (cmdwin_type != 0 && wp == curwin) { // Draw the cmdline character. - n_extra = 1; - c_extra = cmdwin_type; - c_final = NUL; - char_attr = win_hl_attr(wp, HLF_AT); + wlv.n_extra = 1; + wlv.c_extra = cmdwin_type; + wlv.c_final = NUL; + wlv.char_attr = win_hl_attr(wp, HLF_AT); } } - if (draw_state == WL_FOLD - 1 && n_extra == 0) { - if (filler_todo > 0) { - int index = filler_todo - (filler_lines - n_virt_lines); + if (wlv.draw_state == WL_FOLD - 1 && wlv.n_extra == 0) { + if (wlv.filler_todo > 0) { + int index = wlv.filler_todo - (wlv.filler_lines - n_virt_lines); if (index > 0) { virt_line_index = (int)kv_size(virt_lines) - index; assert(virt_line_index >= 0); @@ -1246,152 +1264,143 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, } if (!virt_line_offset) { // Skip the column states if there is a "virt_left_col" line. - draw_state = WL_BRI - 1; + wlv.draw_state = WL_BRI - 1; } else if (statuscol.draw) { // Skip fold, sign and number states if 'statuscolumn' is set. - draw_state = WL_STC - 1; + wlv.draw_state = WL_STC - 1; } } - if (draw_state == WL_FOLD - 1 && n_extra == 0) { + if (wlv.draw_state == WL_FOLD - 1 && wlv.n_extra == 0) { int fdc = compute_foldcolumn(wp, 0); - draw_state = WL_FOLD; + wlv.draw_state = WL_FOLD; if (fdc > 0) { - // Draw the 'foldcolumn'. Allocate a buffer, "extra" may - // already be in use. - xfree(p_extra_free); - p_extra_free = xmalloc(MAX_MCO * (size_t)fdc + 1); - n_extra = (int)fill_foldcolumn(p_extra_free, wp, foldinfo, lnum); - p_extra_free[n_extra] = NUL; - p_extra = p_extra_free; - c_extra = NUL; - c_final = NUL; + // Draw the 'foldcolumn'. + // Allocate a buffer, "wlv->extra[]" may already be in use. + xfree(wlv.p_extra_free); + wlv.p_extra_free = xmalloc(MAX_MCO * (size_t)fdc + 1); + wlv.n_extra = (int)fill_foldcolumn(wlv.p_extra_free, wp, foldinfo, lnum); + wlv.p_extra_free[wlv.n_extra] = NUL; + wlv.p_extra = wlv.p_extra_free; + wlv.c_extra = NUL; + wlv.c_final = NUL; if (use_cursor_line_sign(wp, lnum)) { - char_attr = win_hl_attr(wp, HLF_CLF); + wlv.char_attr = win_hl_attr(wp, HLF_CLF); } else { - char_attr = win_hl_attr(wp, HLF_FC); + wlv.char_attr = win_hl_attr(wp, HLF_FC); } } } // sign column, this is hit until sign_idx reaches count - if (draw_state == WL_SIGN - 1 && n_extra == 0) { - draw_state = WL_SIGN; + if (wlv.draw_state == WL_SIGN - 1 && wlv.n_extra == 0) { + wlv.draw_state = WL_SIGN; // Show the sign column when there are any signs in this buffer if (wp->w_scwidth > 0) { - get_sign_display_info(false, wp, lnum, sattrs, row, - startrow, filler_lines, filler_todo, - &c_extra, &c_final, extra, sizeof(extra), - &p_extra, &n_extra, &char_attr, sign_idx, - sign_cul_attr); + get_sign_display_info(false, wp, &wlv, sign_idx, sign_cul_attr); sign_idx++; if (sign_idx < wp->w_scwidth) { - draw_state = WL_SIGN - 1; + wlv.draw_state = WL_SIGN - 1; } else { sign_idx = 0; } } } - if (draw_state == WL_NR - 1 && n_extra == 0) { - draw_state = WL_NR; + if (wlv.draw_state == WL_NR - 1 && wlv.n_extra == 0) { + wlv.draw_state = WL_NR; // Display the absolute or relative line number. After the // first fill with blanks when the 'n' flag isn't in 'cpo' if ((wp->w_p_nu || wp->w_p_rnu) - && (row == startrow + filler_lines + && (wlv.row == startrow + wlv.filler_lines || vim_strchr(p_cpo, CPO_NUMCOL) == NULL)) { // If 'signcolumn' is set to 'number' and a sign is present // in 'lnum', then display the sign instead of the line // number. if (*wp->w_p_scl == 'n' && *(wp->w_p_scl + 1) == 'u' && num_signs > 0) { - get_sign_display_info(true, wp, lnum, sattrs, row, - startrow, filler_lines, filler_todo, - &c_extra, &c_final, extra, sizeof(extra), - &p_extra, &n_extra, &char_attr, sign_idx, - sign_cul_attr); + get_sign_display_info(true, wp, &wlv, sign_idx, sign_cul_attr); } else { // Draw the line number (empty space after wrapping). - if (row == startrow + filler_lines) { - get_line_number_str(wp, lnum, extra, sizeof(extra)); + if (wlv.row == startrow + wlv.filler_lines) { + get_line_number_str(wp, lnum, wlv.extra, sizeof(wlv.extra)); if (wp->w_skipcol > 0) { - for (p_extra = extra; *p_extra == ' '; p_extra++) { - *p_extra = '-'; + for (wlv.p_extra = wlv.extra; *wlv.p_extra == ' '; wlv.p_extra++) { + *wlv.p_extra = '-'; } } if (wp->w_p_rl) { // reverse line numbers // like rl_mirror(), but keep the space at the end - char *p2 = skipwhite(extra); + char *p2 = skipwhite(wlv.extra); p2 = skiptowhite(p2) - 1; - for (char *p1 = skipwhite(extra); p1 < p2; p1++, p2--) { + for (char *p1 = skipwhite(wlv.extra); p1 < p2; p1++, p2--) { const char t = *p1; *p1 = *p2; *p2 = t; } } - p_extra = extra; - c_extra = NUL; + wlv.p_extra = wlv.extra; + wlv.c_extra = NUL; } else { - c_extra = ' '; + wlv.c_extra = ' '; } - c_final = NUL; - n_extra = number_width(wp) + 1; + wlv.c_final = NUL; + wlv.n_extra = number_width(wp) + 1; if (sign_num_attr > 0) { - char_attr = sign_num_attr; + wlv.char_attr = sign_num_attr; } else { - char_attr = get_line_number_attr(wp, lnum, row, startrow, filler_lines); + wlv.char_attr = get_line_number_attr(wp, &wlv); } } } } - if (draw_state == WL_STC - 1 && n_extra == 0) { - draw_state = WL_STC; + if (wlv.draw_state == WL_STC - 1 && wlv.n_extra == 0) { + wlv.draw_state = WL_STC; // Draw the 'statuscolumn' if option is set. if (statuscol.draw) { if (statuscol.textp == NULL) { - get_statuscol_str(wp, lnum, row - startrow - filler_lines, &statuscol); + get_statuscol_str(wp, lnum, wlv.row - startrow - wlv.filler_lines, &statuscol); if (wp->w_redr_statuscol) { break; } } - get_statuscol_display_info(&statuscol, &draw_state, &char_attr, - &n_extra, &c_extra, &c_final, &p_extra); + get_statuscol_display_info(&statuscol, &wlv); } } - if (draw_state == WL_STC && n_extra == 0) { - win_col_offset = off; + if (wlv.draw_state == WL_STC && wlv.n_extra == 0) { + win_col_offset = wlv.off; } - if (wp->w_briopt_sbr && draw_state == WL_BRI - 1 - && n_extra == 0 && *get_showbreak_value(wp) != NUL) { + if (wp->w_briopt_sbr && wlv.draw_state == WL_BRI - 1 + && wlv.n_extra == 0 && *get_showbreak_value(wp) != NUL) { // draw indent after showbreak value - draw_state = WL_BRI; - } else if (wp->w_briopt_sbr && draw_state == WL_SBR && n_extra == 0) { + wlv.draw_state = WL_BRI; + } else if (wp->w_briopt_sbr && wlv.draw_state == WL_SBR && wlv.n_extra == 0) { // after the showbreak, draw the breakindent - draw_state = WL_BRI - 1; + wlv.draw_state = WL_BRI - 1; } // draw 'breakindent': indent wrapped text accordingly - if (draw_state == WL_BRI - 1 && n_extra == 0) { - draw_state = WL_BRI; + if (wlv.draw_state == WL_BRI - 1 && wlv.n_extra == 0) { + wlv.draw_state = WL_BRI; // if need_showbreak is set, breakindent also applies - if (wp->w_p_bri && (row != startrow || need_showbreak) - && filler_lines == 0) { - char_attr = 0; + if (wp->w_p_bri && (wlv.row != startrow || need_showbreak) + && wlv.filler_lines == 0) { + wlv.char_attr = 0; if (diff_hlf != (hlf_T)0) { - char_attr = win_hl_attr(wp, (int)diff_hlf); + wlv.char_attr = win_hl_attr(wp, (int)diff_hlf); } - p_extra = NULL; - c_extra = ' '; - c_final = NUL; - n_extra = + wlv.p_extra = NULL; + wlv.c_extra = ' '; + wlv.c_final = NUL; + wlv.n_extra = get_breakindent_win(wp, ml_get_buf(wp->w_buffer, lnum, false)); - if (row == startrow) { - n_extra -= win_col_off2(wp); - if (n_extra < 0) { - n_extra = 0; + if (wlv.row == startrow) { + wlv.n_extra -= win_col_off2(wp); + if (wlv.n_extra < 0) { + wlv.n_extra = 0; } } if (wp->w_skipcol > 0 && wp->w_p_wrap && wp->w_briopt_sbr) { @@ -1399,174 +1408,174 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, |