aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/drawline.c
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2025-02-05 23:09:29 +0000
committerJosh Rahm <joshuarahm@gmail.com>2025-02-05 23:09:29 +0000
commitd5f194ce780c95821a855aca3c19426576d28ae0 (patch)
treed45f461b19f9118ad2bb1f440a7a08973ad18832 /src/nvim/drawline.c
parentc5d770d311841ea5230426cc4c868e8db27300a8 (diff)
parent44740e561fc93afe3ebecfd3618bda2d2abeafb0 (diff)
downloadrneovim-rahm.tar.gz
rneovim-rahm.tar.bz2
rneovim-rahm.zip
Merge remote-tracking branch 'upstream/master' into mix_20240309HEADrahm
Diffstat (limited to 'src/nvim/drawline.c')
-rw-r--r--src/nvim/drawline.c240
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;