diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2025-02-05 23:09:29 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2025-02-05 23:09:29 +0000 |
commit | d5f194ce780c95821a855aca3c19426576d28ae0 (patch) | |
tree | d45f461b19f9118ad2bb1f440a7a08973ad18832 /src/nvim/drawline.c | |
parent | c5d770d311841ea5230426cc4c868e8db27300a8 (diff) | |
parent | 44740e561fc93afe3ebecfd3618bda2d2abeafb0 (diff) | |
download | rneovim-rahm.tar.gz rneovim-rahm.tar.bz2 rneovim-rahm.zip |
Diffstat (limited to 'src/nvim/drawline.c')
-rw-r--r-- | src/nvim/drawline.c | 240 |
1 files changed, 157 insertions, 83 deletions
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index 79f3298eb4..37a42917b0 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -31,6 +31,7 @@ #include "nvim/highlight_defs.h" #include "nvim/highlight_group.h" #include "nvim/indent.h" +#include "nvim/insexpand.h" #include "nvim/mark_defs.h" #include "nvim/marktree_defs.h" #include "nvim/match.h" @@ -80,6 +81,8 @@ typedef struct { 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 sign_num_attr; ///< line number attribute (sign numhl) + int sign_cul_attr; ///< cursorline sign attribute (sign culhl) int fromcol; ///< start of inverting int tocol; ///< end of inverting @@ -251,12 +254,20 @@ static int line_putchar(buf_T *buf, const char **pp, schar_T *dest, int maxcells static void draw_virt_text(win_T *wp, buf_T *buf, int col_off, int *end_col, int win_row) { - DecorState *state = &decor_state; - const int max_col = wp->w_grid.cols; + DecorState *const state = &decor_state; + int const max_col = wp->w_grid.cols; int right_pos = max_col; - bool do_eol = state->eol_col > -1; - for (size_t i = 0; i < kv_size(state->active); i++) { - DecorRange *item = &kv_A(state->active, i); + bool const do_eol = state->eol_col > -1; + + int const end = state->current_end; + int *const indices = state->ranges_i.items; + DecorRangeSlot *const slots = state->slots.items; + + /// Total width of all virtual text with "eol_right_align" alignment + int totalWidthOfEolRightAlignedVirtText = 0; + + for (int i = 0; i < end; i++) { + DecorRange *item = &slots[indices[i]].range; if (!(item->start_row == state->row && decor_virt_pos(item))) { continue; } @@ -269,7 +280,44 @@ static void draw_virt_text(win_T *wp, buf_T *buf, int col_off, int *end_col, int if (decor_virt_pos(item) && item->draw_col == -1) { bool updated = true; VirtTextPos pos = decor_virt_pos_kind(item); - if (pos == kVPosRightAlign) { + + if (do_eol && pos == kVPosEndOfLineRightAlign) { + int eolOffset = 0; + if (totalWidthOfEolRightAlignedVirtText == 0) { + // Look ahead to the remaining decor items + for (int j = i; j < end; j++) { + /// A future decor to be handled in this function's call + DecorRange *lookaheadItem = &slots[indices[j]].range; + + if (lookaheadItem->start_row != state->row + || !decor_virt_pos(lookaheadItem) + || lookaheadItem->draw_col != -1) { + continue; + } + + /// The Virtual Text of the decor item we're looking ahead to + DecorVirtText *lookaheadVt = NULL; + if (item->kind == kDecorKindVirtText) { + assert(item->data.vt); + lookaheadVt = item->data.vt; + } + + if (decor_virt_pos_kind(lookaheadItem) == kVPosEndOfLineRightAlign) { + // An extra space is added for single character spacing in EOL alignment + totalWidthOfEolRightAlignedVirtText += (lookaheadVt->width + 1); + } + } + + // Remove one space from the total width since there's no single space after the last entry + totalWidthOfEolRightAlignedVirtText--; + + if (totalWidthOfEolRightAlignedVirtText <= (right_pos - state->eol_col)) { + eolOffset = right_pos - totalWidthOfEolRightAlignedVirtText - state->eol_col; + } + } + + item->draw_col = state->eol_col + eolOffset; + } else if (pos == kVPosRightAlign) { right_pos -= vt->width; item->draw_col = right_pos; } else if (pos == kVPosEndOfLine && do_eol) { @@ -296,7 +344,7 @@ static void draw_virt_text(win_T *wp, buf_T *buf, int col_off, int *end_col, int int vcol = item->draw_col - col_off; int col = draw_virt_text_item(buf, item->draw_col, vt->data.virt_text, vt->hl_mode, max_col, vcol); - if (vt->pos == kVPosEndOfLine && do_eol) { + if (do_eol && ((vt->pos == kVPosEndOfLine) || (vt->pos == kVPosEndOfLineRightAlign))) { state->eol_col = col + 1; } *end_col = MAX(*end_col, col); @@ -360,14 +408,14 @@ static int draw_virt_text_item(buf_T *buf, int col, VirtText vt, HlMode hl_mode, // TODO(bfredl): integrate with grid.c linebuf code? madness? static void draw_col_buf(win_T *wp, winlinevars_T *wlv, const char *text, size_t len, int attr, - bool vcol) + const colnr_T *fold_vcol, bool inc_vcol) { const char *ptr = text; while (ptr < text + len && wlv->off < wp->w_grid.cols) { int cells = line_putchar(wp->w_buffer, &ptr, &linebuf_char[wlv->off], wp->w_grid.cols - wlv->off, wlv->off); int myattr = attr; - if (vcol) { + if (inc_vcol) { advance_color_col(wlv, wlv->vcol); if (wlv->color_cols && wlv->vcol == *wlv->color_cols) { myattr = hl_combine_attr(win_hl_attr(wp, HLF_MC), myattr); @@ -375,7 +423,7 @@ static void draw_col_buf(win_T *wp, winlinevars_T *wlv, const char *text, size_t } for (int c = 0; c < cells; c++) { linebuf_attr[wlv->off] = myattr; - linebuf_vcol[wlv->off] = vcol ? wlv->vcol++ : -1; + linebuf_vcol[wlv->off] = inc_vcol ? wlv->vcol++ : fold_vcol ? *(fold_vcol++) : -1; wlv->off++; } } @@ -391,11 +439,11 @@ static void draw_col_fill(winlinevars_T *wlv, schar_T fillchar, int width, int a } /// Return true if CursorLineSign highlight is to be used. -static bool use_cursor_line_highlight(win_T *wp, linenr_T lnum) +bool use_cursor_line_highlight(win_T *wp, linenr_T lnum) { return wp->w_p_cul && lnum == wp->w_cursorline - && (wp->w_p_culopt_flags & CULOPT_NBR); + && (wp->w_p_culopt_flags & kOptCuloptFlagNumber); } /// Setup for drawing the 'foldcolumn', if there is one. @@ -404,7 +452,7 @@ static void draw_foldcolumn(win_T *wp, winlinevars_T *wlv) int fdc = compute_foldcolumn(wp, 0); if (fdc > 0) { int attr = win_hl_attr(wp, use_cursor_line_highlight(wp, wlv->lnum) ? HLF_CLF : HLF_FC); - fill_foldcolumn(wp, wlv->foldinfo, wlv->lnum, attr, fdc, &wlv->off, NULL); + fill_foldcolumn(wp, wlv->foldinfo, wlv->lnum, attr, fdc, &wlv->off, NULL, NULL); } } @@ -413,8 +461,9 @@ static void draw_foldcolumn(win_T *wp, winlinevars_T *wlv) /// @param fdc Current width of the foldcolumn /// @param[out] wlv_off Pointer to linebuf offset, incremented for default column /// @param[out] out_buffer Char array to fill, only used for 'statuscolumn' +/// @param[out] out_vcol vcol array to fill, only used for 'statuscolumn' void fill_foldcolumn(win_T *wp, foldinfo_T foldinfo, linenr_T lnum, int attr, int fdc, int *wlv_off, - schar_T *out_buffer) + colnr_T *out_vcol, schar_T *out_buffer) { bool closed = foldinfo.fi_level != 0 && foldinfo.fi_lines > 0; int level = foldinfo.fi_level; @@ -440,10 +489,12 @@ void fill_foldcolumn(win_T *wp, foldinfo_T foldinfo, linenr_T lnum, int attr, in symbol = schar_from_ascii('>'); } + int vcol = i >= level ? -1 : (i == closedcol - 1 && closed) ? -2 : -3; if (out_buffer) { + out_vcol[i] = vcol; out_buffer[i] = symbol; } else { - linebuf_vcol[*wlv_off] = i >= level ? -1 : (i == closedcol - 1 && closed) ? -2 : -3; + linebuf_vcol[*wlv_off] = vcol; linebuf_attr[*wlv_off] = attr; linebuf_char[(*wlv_off)++] = symbol; } @@ -454,14 +505,15 @@ void fill_foldcolumn(win_T *wp, foldinfo_T foldinfo, linenr_T lnum, int attr, in /// 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. If there is no /// sign, draw blank cells instead. -static void draw_sign(bool nrcol, win_T *wp, winlinevars_T *wlv, int sign_idx, int sign_cul_attr) +static void draw_sign(bool nrcol, win_T *wp, winlinevars_T *wlv, int sign_idx) { SignTextAttrs sattr = wlv->sattrs[sign_idx]; + int scl_attr = win_hl_attr(wp, use_cursor_line_highlight(wp, wlv->lnum) ? HLF_CLS : HLF_SC); if (sattr.text[0] && wlv->row == wlv->startrow + wlv->filler_lines && wlv->filler_todo <= 0) { - int attr = (use_cursor_line_highlight(wp, wlv->lnum) && sign_cul_attr) - ? sign_cul_attr : sattr.hl_id ? syn_id2attr(sattr.hl_id) : 0; int fill = nrcol ? number_width(wp) + 1 : SIGN_WIDTH; + int attr = wlv->sign_cul_attr ? wlv->sign_cul_attr : sattr.hl_id ? syn_id2attr(sattr.hl_id) : 0; + attr = hl_combine_attr(scl_attr, attr); draw_col_fill(wlv, schar_from_ascii(' '), fill, attr); int sign_pos = wlv->off - SIGN_WIDTH - (int)nrcol; assert(sign_pos >= 0); @@ -469,8 +521,7 @@ static void draw_sign(bool nrcol, win_T *wp, winlinevars_T *wlv, int sign_idx, i linebuf_char[sign_pos + 1] = sattr.text[1]; } else { assert(!nrcol); // handled in draw_lnum_col() - int attr = win_hl_attr(wp, use_cursor_line_highlight(wp, wlv->lnum) ? HLF_CLS : HLF_SC); - draw_col_fill(wlv, schar_from_ascii(' '), SIGN_WIDTH, attr); + draw_col_fill(wlv, schar_from_ascii(' '), SIGN_WIDTH, scl_attr); } } @@ -507,10 +558,10 @@ static bool use_cursor_line_nr(win_T *wp, winlinevars_T *wlv) { return wp->w_p_cul && wlv->lnum == wp->w_cursorline - && (wp->w_p_culopt_flags & CULOPT_NBR) + && (wp->w_p_culopt_flags & kOptCuloptFlagNumber) && (wlv->row == wlv->startrow + wlv->filler_lines || (wlv->row > wlv->startrow + wlv->filler_lines - && (wp->w_p_culopt_flags & CULOPT_LINE))); + && (wp->w_p_culopt_flags & kOptCuloptFlagLine))); } static int get_line_number_attr(win_T *wp, winlinevars_T *wlv) @@ -537,7 +588,7 @@ static int get_line_number_attr(win_T *wp, winlinevars_T *wlv) /// Display the absolute or relative line number. After the first row fill with /// blanks when the 'n' flag isn't in 'cpo'. -static void draw_lnum_col(win_T *wp, winlinevars_T *wlv, int sign_num_attr, int sign_cul_attr) +static void draw_lnum_col(win_T *wp, winlinevars_T *wlv) { bool has_cpo_n = vim_strchr(p_cpo, CPO_NUMCOL) != NULL; @@ -550,12 +601,12 @@ static void draw_lnum_col(win_T *wp, winlinevars_T *wlv, int sign_num_attr, int // then display the sign instead of the line number. if (wp->w_minscwidth == SCL_NUM && wlv->sattrs[0].text[0] && wlv->row == wlv->startrow + wlv->filler_lines && wlv->filler_todo <= 0) { - draw_sign(true, wp, wlv, 0, sign_cul_attr); + draw_sign(true, wp, wlv, 0); } else { // Draw the line number (empty space after wrapping). int width = number_width(wp) + 1; - int attr = (sign_num_attr > 0 && wlv->filler_todo <= 0) - ? sign_num_attr : get_line_number_attr(wp, wlv); + int attr = hl_combine_attr(get_line_number_attr(wp, wlv), + wlv->filler_todo <= 0 ? wlv->sign_num_attr : 0); if (wlv->row == wlv->startrow + wlv->filler_lines && (wp->w_skipcol == 0 || wlv->row > 0 || (wp->w_p_nu && wp->w_p_rnu))) { char buf[32]; @@ -569,7 +620,7 @@ static void draw_lnum_col(win_T *wp, winlinevars_T *wlv, int sign_num_attr, int char *num = skipwhite(buf); rl_mirror_ascii(num, skiptowhite(num)); } - draw_col_buf(wp, wlv, buf, (size_t)width, attr, false); + draw_col_buf(wp, wlv, buf, (size_t)width, attr, NULL, false); } else { draw_col_fill(wlv, schar_from_ascii(' '), width, attr); } @@ -624,22 +675,27 @@ static void draw_statuscol(win_T *wp, winlinevars_T *wlv, linenr_T lnum, int vir char *p = buf; char transbuf[MAXPATHL]; - int attr = stcp->num_attr; + colnr_T *fold_vcol = NULL; size_t len = strlen(buf); + int scl_attr = win_hl_attr(wp, use_cursor_line_highlight(wp, wlv->lnum) ? HLF_CLS : HLF_SC); + int num_attr = hl_combine_attr(get_line_number_attr(wp, wlv), + wlv->filler_todo <= 0 ? wlv->sign_num_attr : 0); + int cur_attr = num_attr; // Draw each segment with the specified highlighting. for (stl_hlrec_t *sp = stcp->hlrec; sp->start != NULL; sp++) { ptrdiff_t textlen = sp->start - p; // Make all characters printable. size_t translen = transstr_buf(p, textlen, transbuf, MAXPATHL, true); - draw_col_buf(wp, wlv, transbuf, translen, attr, false); + draw_col_buf(wp, wlv, transbuf, translen, cur_attr, fold_vcol, false); + int attr = sp->item == STL_SIGNCOL ? scl_attr : sp->item == STL_FOLDCOL ? 0 : num_attr; + cur_attr = hl_combine_attr(attr, sp->userhl < 0 ? syn_id2attr(-sp->userhl) : 0); + fold_vcol = sp->item == STL_FOLDCOL ? stcp->fold_vcol : NULL; p = sp->start; - int hl = sp->userhl; - attr = hl < 0 ? syn_id2attr(-hl) : stcp->num_attr; } size_t translen = transstr_buf(p, buf + len - p, transbuf, MAXPATHL, true); - draw_col_buf(wp, wlv, transbuf, translen, attr, false); - draw_col_fill(wlv, schar_from_ascii(' '), stcp->width - width, stcp->num_attr); + draw_col_buf(wp, wlv, transbuf, translen, cur_attr, fold_vcol, false); + draw_col_fill(wlv, schar_from_ascii(' '), stcp->width - width, cur_attr); } static void handle_breakindent(win_T *wp, winlinevars_T *wlv) @@ -711,7 +767,7 @@ static void handle_showbreak_and_filler(win_T *wp, winlinevars_T *wlv) // Combine 'showbreak' with 'cursorline', prioritizing 'showbreak'. int attr = hl_combine_attr(wlv->cul_attr, win_hl_attr(wp, HLF_AT)); colnr_T vcol_before = wlv->vcol; - draw_col_buf(wp, wlv, sbr, strlen(sbr), attr, true); + draw_col_buf(wp, wlv, sbr, strlen(sbr), attr, NULL, true); wlv->vcol_sbr = wlv->vcol; // Correct start of highlighted area for 'showbreak'. @@ -756,17 +812,28 @@ static bool has_more_inline_virt(winlinevars_T *wlv, ptrdiff_t v) if (wlv->virt_inline_i < kv_size(wlv->virt_inline)) { return true; } - DecorState *state = &decor_state; - for (size_t i = 0; i < kv_size(state->active); i++) { - DecorRange *item = &kv_A(state->active, i); - if (item->start_row != state->row - || item->kind != kDecorKindVirtText - || item->data.vt->pos != kVPosInline - || item->data.vt->width == 0) { - continue; - } - if (item->draw_col >= -1 && item->start_col >= v) { - return true; + + int const count = (int)kv_size(decor_state.ranges_i); + int const cur_end = decor_state.current_end; + int const fut_beg = decor_state.future_begin; + int *const indices = decor_state.ranges_i.items; + DecorRangeSlot *const slots = decor_state.slots.items; + + int const beg_pos[] = { 0, fut_beg }; + int const end_pos[] = { cur_end, count }; + + for (int pos_i = 0; pos_i < 2; pos_i++) { + for (int i = beg_pos[pos_i]; i < end_pos[pos_i]; i++) { + DecorRange *item = &slots[indices[i]].range; + if (item->start_row != decor_state.row + || item->kind != kDecorKindVirtText + || item->data.vt->pos != kVPosInline + || item->data.vt->width == 0) { + continue; + } + if (item->draw_col >= -1 && item->start_col >= v) { + return true; + } } } return false; @@ -780,8 +847,12 @@ static void handle_inline_virtual_text(win_T *wp, winlinevars_T *wlv, ptrdiff_t wlv->virt_inline = VIRTTEXT_EMPTY; wlv->virt_inline_i = 0; DecorState *state = &decor_state; - for (size_t i = 0; i < kv_size(state->active); i++) { - DecorRange *item = &kv_A(state->active, i); + int const end = state->current_end; + int *const indices = state->ranges_i.items; + DecorRangeSlot *const slots = state->slots.items; + + for (int i = 0; i < end; i++) { + DecorRange *item = &slots[indices[i]].range; if (item->draw_col == -3) { // No more inline virtual text before this non-inline virtual text item, // so its position can be decided now. @@ -913,6 +984,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s colnr_T vcol_prev = -1; // "wlv.vcol" of previous character ScreenGrid *grid = &wp->w_grid; // grid specific to the window + const bool in_curline = wp == curwin && lnum == curwin->w_cursor.lnum; const bool has_fold = foldinfo.fi_level != 0 && foldinfo.fi_lines > 0; const bool has_foldtext = has_fold && *wp->w_p_fdt != NUL; @@ -932,7 +1004,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s bool area_highlighting = false; // Visual or incsearch highlighting in this line int vi_attr = 0; // attributes for Visual and incsearch highlighting int area_attr = 0; // attributes desired by highlighting - int search_attr = 0; // attributes desired by 'hlsearch' + int search_attr = 0; // attributes desired by 'hlsearch' or ComplMatchIns int vcol_save_attr = 0; // saved attr for 'cursorcolumn' int decor_attr = 0; // attributes desired by syntax and extmarks bool has_syntax = false; // this buffer has syntax highl. @@ -946,7 +1018,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s int spell_attr = 0; // attributes desired by spelling int word_end = 0; // last byte with same spell_attr int cur_checked_col = 0; // checked column for current line - bool extra_check = 0; // has syntax or linebreak + bool extra_check = false; // has extra highlighting int multi_attr = 0; // attributes desired by multibyte int mb_l = 1; // multi-byte byte length int mb_c = 0; // decoded multi-byte character @@ -1028,12 +1100,12 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s } } - has_decor = decor_redraw_line(wp, lnum - 1, &decor_state); - if (!end_fill) { - decor_providers_invoke_line(wp, lnum - 1, &has_decor); + decor_providers_invoke_line(wp, lnum - 1); } + has_decor = decor_redraw_line(wp, lnum - 1, &decor_state); + if (has_decor) { extra_check = true; } @@ -1096,7 +1168,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s } // Check if the char under the cursor should be inverted (highlighted). - if (!highlight_match && lnum == curwin->w_cursor.lnum && wp == curwin + if (!highlight_match && in_curline && cursor_is_block_during_visual(*p_sel == 'e')) { noinvcur = true; } @@ -1165,11 +1237,11 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s 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 + if (wp->w_p_cul && wp->w_p_culopt_flags != kOptCuloptFlagNumber && lnum == wp->w_cursorline // Do not show the cursor line in the text when Visual mode is active, // because it's not clear what is selected then. && !(wp == curwin && VIsual_active)) { - cul_screenline = (is_wrapped && (wp->w_p_culopt_flags & CULOPT_SCRLINE)); + cul_screenline = (is_wrapped && (wp->w_p_culopt_flags & kOptCuloptFlagScreenline)); if (!cul_screenline) { apply_cursorline_highlight(wp, &wlv); } else { @@ -1178,11 +1250,10 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s area_highlighting = true; } - int line_attr = 0; - int sign_cul_attr = 0; - int sign_num_attr = 0; + int sign_line_attr = 0; // TODO(bfredl, vigoux): line_attr should not take priority over decoration! - decor_redraw_signs(wp, buf, wlv.lnum - 1, wlv.sattrs, &line_attr, &sign_cul_attr, &sign_num_attr); + decor_redraw_signs(wp, buf, wlv.lnum - 1, wlv.sattrs, + &sign_line_attr, &wlv.sign_cul_attr, &wlv.sign_num_attr); statuscol_T statuscol = { 0 }; if (*wp->w_p_stc != NUL) { @@ -1191,19 +1262,15 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s statuscol.sattrs = wlv.sattrs; statuscol.foldinfo = foldinfo; statuscol.width = win_col_off(wp) - (wp == cmdwin_win); - statuscol.use_cul = use_cursor_line_highlight(wp, lnum); - statuscol.sign_cul_id = statuscol.use_cul ? sign_cul_attr : 0; - statuscol.num_attr = sign_num_attr > 0 ? syn_id2attr(sign_num_attr) : 0; - } else { - if (sign_cul_attr > 0) { - sign_cul_attr = syn_id2attr(sign_cul_attr); - } - if (sign_num_attr > 0) { - sign_num_attr = syn_id2attr(sign_num_attr); - } + statuscol.sign_cul_id = use_cursor_line_highlight(wp, lnum) ? wlv.sign_cul_attr : 0; + } else if (wlv.sign_cul_attr > 0) { + wlv.sign_cul_attr = use_cursor_line_highlight(wp, lnum) ? syn_id2attr(wlv.sign_cul_attr) : 0; + } + if (wlv.sign_num_attr > 0) { + wlv.sign_num_attr = syn_id2attr(wlv.sign_num_attr); } - if (line_attr > 0) { - wlv.line_attr = syn_id2attr(line_attr); + if (sign_line_attr > 0) { + wlv.line_attr = syn_id2attr(sign_line_attr); } // Highlight the current line in the quickfix window. @@ -1472,6 +1539,10 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s ptr = line + v; // "line" may have been updated } + if ((State & MODE_INSERT) && in_curline && ins_compl_win_active(wp)) { + area_highlighting = true; + } + win_line_start(wp, &wlv); bool draw_cols = true; int leftcols_width = 0; @@ -1522,9 +1593,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s // skip columns } else if (statuscol.draw) { // Draw 'statuscolumn' if it is set. - if (sign_num_attr == 0) { - statuscol.num_attr = get_line_number_attr(wp, &wlv); - } const int v = (int)(ptr - line); draw_statuscol(wp, &wlv, lnum, wlv.row - startrow - wlv.filler_lines, col_rows, &statuscol); if (wp->w_redr_statuscol) { @@ -1541,10 +1609,10 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s // wp->w_scwidth is zero if signcol=number is used for (int sign_idx = 0; sign_idx < wp->w_scwidth; sign_idx++) { - draw_sign(false, wp, &wlv, sign_idx, sign_cul_attr); + draw_sign(false, wp, &wlv, sign_idx); } - draw_lnum_col(wp, &wlv, sign_num_attr, sign_cul_attr); + draw_lnum_col(wp, &wlv); } win_col_offset = wlv.off; @@ -1608,8 +1676,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s } // When still displaying '$' of change command, stop at cursor. - if (dollar_vcol >= 0 && wp == curwin - && lnum == wp->w_cursor.lnum && wlv.vcol >= wp->w_virtcol) { + if (dollar_vcol >= 0 && in_curline && wlv.vcol >= wp->w_virtcol) { draw_virt_text(wp, buf, win_col_offset, &wlv.col, wlv.row); // don't clear anything after wlv.col wlv_put_linebuf(wp, &wlv, wlv.col, false, bg_attr, 0); @@ -1718,6 +1785,14 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s if (*ptr == NUL) { has_match_conc = 0; } + + // Check if ComplMatchIns highlight is needed. + if ((State & MODE_INSERT) && in_curline && ins_compl_win_active(wp)) { + int ins_match_attr = ins_compl_col_range_attr((int)(ptr - line)); + if (ins_match_attr > 0) { + search_attr = hl_combine_attr(search_attr, ins_match_attr); + } + } } if (wlv.diff_hlf != (hlf_T)0) { @@ -1949,7 +2024,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s decor_attr = 0; if (extra_check) { - const bool no_plain_buffer = (wp->w_s->b_p_spo_flags & SPO_NPBUFFER) != 0; + const bool no_plain_buffer = (wp->w_s->b_p_spo_flags & kOptSpoFlagNoplainbuffer) != 0; bool can_spell = !no_plain_buffer; // Get extmark and syntax attributes, unless still at the start of the line @@ -2324,7 +2399,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s if (wlv.n_extra == 0) { wlv.n_extra = byte2cells(mb_c) - 1; } - if ((dy_flags & DY_UHEX) && wp->w_p_rl) { + if ((dy_flags & kOptDyFlagUhex) && wp->w_p_rl) { rl_mirror_ascii(wlv.p_extra, NULL); // reverse "<12>" } wlv.sc_extra = NUL; @@ -2425,8 +2500,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s // With 'virtualedit' we may never reach cursor position, but we still // need to correct the cursor column, so do that at end of line. if (!did_wcol && wlv.filler_todo <= 0 - && wp == curwin && lnum == wp->w_cursor.lnum - && conceal_cursor_line(wp) + && in_curline && conceal_cursor_line(wp) && (wlv.vcol + wlv.skip_cells >= wp->w_virtcol || mb_schar == NUL)) { wp->w_wcol = wlv.col - wlv.boguscols; if (wlv.vcol + wlv.skip_cells < wp->w_virtcol) { @@ -2619,7 +2693,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s // Update w_cline_height and w_cline_folded if the cursor line was // updated (saves a call to plines_win() later). - if (wp == curwin && lnum == curwin->w_cursor.lnum) { + if (in_curline) { curwin->w_cline_row = startrow; curwin->w_cline_height = wlv.row - startrow; curwin->w_cline_folded = has_fold; |