aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/screen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/screen.c')
-rw-r--r--src/nvim/screen.c320
1 files changed, 177 insertions, 143 deletions
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index e036c49be4..34eef83164 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -387,14 +387,15 @@ void update_screen(int type)
if (wp->w_buffer->b_mod_set) {
win_T *wwp;
- /* Check if we already did this buffer. */
- for (wwp = firstwin; wwp != wp; wwp = wwp->w_next)
- if (wwp->w_buffer == wp->w_buffer)
+ // Check if we already did this buffer.
+ for (wwp = firstwin; wwp != wp; wwp = wwp->w_next) {
+ if (wwp->w_buffer == wp->w_buffer) {
break;
- if (
- wwp == wp &&
- syntax_present(wp))
+ }
+ }
+ if (wwp == wp && syntax_present(wp)) {
syn_stack_apply_changes(wp->w_buffer);
+ }
}
}
@@ -1231,16 +1232,16 @@ static void win_update(win_T *wp)
|| did_update == DID_FOLD
|| (did_update == DID_LINE
&& syntax_present(wp)
- && (
- (foldmethodIsSyntax(wp)
- && hasAnyFolding(wp)) ||
- syntax_check_changed(lnum)))
+ && ((foldmethodIsSyntax(wp)
+ && hasAnyFolding(wp))
+ || syntax_check_changed(lnum)))
// match in fixed position might need redraw
// if lines were inserted or deleted
- || (wp->w_match_head != NULL && buf->b_mod_xlines != 0)
- ))))) {
- if (lnum == mod_top)
- top_to_mod = FALSE;
+ || (wp->w_match_head != NULL
+ && buf->b_mod_xlines != 0)))))) {
+ if (lnum == mod_top) {
+ top_to_mod = false;
+ }
/*
* When at start of changed lines: May scroll following lines
@@ -2184,6 +2185,10 @@ win_line (
int prev_c1 = 0; /* first composing char for prev_c */
int did_line_attr = 0;
+ bool has_bufhl = false; // this buffer has highlight matches
+ int bufhl_attr = 0; // attributes desired by bufhl
+ bufhl_lineinfo_T bufhl_info; // bufhl data for this line
+
/* draw_state: items that are drawn in sequence: */
#define WL_START 0 /* nothing done yet */
# define WL_CMDLINE WL_START + 1 /* cmdline window column */
@@ -2199,11 +2204,13 @@ win_line (
int syntax_seqnr = 0;
int prev_syntax_id = 0;
int conceal_attr = hl_attr(HLF_CONCEAL);
- int 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 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 match_conc = false; ///< cchar for match functions
+ int has_match_conc = false; ///< match wants to conceal
int old_boguscols = 0;
# define VCOL_HLC (vcol - vcol_off)
# define FIX_FOR_BOGUSCOLS \
@@ -2242,6 +2249,11 @@ win_line (
}
}
+ if (bufhl_start_line(wp->w_buffer, lnum, &bufhl_info)) {
+ has_bufhl = true;
+ extra_check = true;
+ }
+
/* Check for columns to display for 'colorcolumn'. */
color_cols = wp->w_buffer->terminal ? NULL : wp->w_p_cc_cols;
if (color_cols != NULL)
@@ -2430,13 +2442,18 @@ win_line (
}
}
- /* find start of trailing whitespace */
- if (wp->w_p_list && lcs_trail) {
- trailcol = (colnr_T)STRLEN(ptr);
- while (trailcol > (colnr_T)0 && ascii_iswhite(ptr[trailcol - 1]))
- --trailcol;
- trailcol += (colnr_T) (ptr - line);
- extra_check = TRUE;
+ if (wp->w_p_list) {
+ if (lcs_space || lcs_trail) {
+ extra_check = true;
+ }
+ // find start of trailing whitespace
+ if (lcs_trail) {
+ trailcol = (colnr_T)STRLEN(ptr);
+ while (trailcol > (colnr_T)0 && ascii_iswhite(ptr[trailcol - 1])) {
+ trailcol--;
+ }
+ trailcol += (colnr_T) (ptr - line);
+ }
}
/*
@@ -2456,21 +2473,16 @@ win_line (
mb_ptr_adv(ptr);
}
- /* When:
- * - 'cuc' is set, or
- * - 'colorcolumn' is set, or
- * - '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)
- )) {
+ // When:
+ // - 'cuc' is set, or
+ // - 'colorcolumn' is set, or
+ // - '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 = v;
}
@@ -2633,11 +2645,10 @@ win_line (
extra_check = true;
}
- /*
- * Repeat for the whole displayed line.
- */
+ // Repeat for the whole displayed line.
for (;; ) {
- /* Skip this quickly when working on the text. */
+ has_match_conc = false;
+ // Skip this quickly when working on the text.
if (draw_state != WL_LINE) {
if (draw_state == WL_CMDLINE - 1 && n_extra == 0) {
draw_state = WL_CMDLINE;
@@ -2884,8 +2895,16 @@ win_line (
shl->endcol = tmp_col;
}
shl->attr_cur = shl->attr;
+ if (cur != NULL && syn_name2id((char_u *)"Conceal")
+ == cur->hlg_id) {
+ has_match_conc = true;
+ match_conc = cur->conceal_char;
+ } else {
+ has_match_conc = match_conc = false;
+ }
} else if (v == (long)shl->endcol) {
shl->attr_cur = 0;
+ prev_syntax_id = 0;
next_search_hl(wp, shl, lnum, (colnr_T)v, cur);
pos_inprogress = !(cur == NULL || cur->pos.cur == 0);
@@ -3201,27 +3220,7 @@ win_line (
}
}
- ++ptr;
-
- // 'list': change char 160 to lcs_nbsp and space to lcs_space.
- if (wp->w_p_list
- && (((c == 160 || (mb_utf8 && (mb_c == 160 || mb_c == 0x202f)))
- && lcs_nbsp)
- || (c == ' ' && lcs_space && ptr - line <= trailcol))) {
- c = (c == ' ') ? lcs_space : lcs_nbsp;
- if (area_attr == 0 && search_attr == 0) {
- n_attr = 1;
- extra_attr = hl_attr(HLF_8);
- saved_attr2 = char_attr; /* save current attr */
- }
- mb_c = c;
- if (enc_utf8 && (*mb_char2len)(c) > 1) {
- mb_utf8 = TRUE;
- u8cc[0] = 0;
- c = 0xc0;
- } else
- mb_utf8 = FALSE;
- }
+ ptr++;
if (extra_check) {
bool can_spell = true;
@@ -3270,12 +3269,12 @@ win_line (
* contains the @Spell cluster. */
if (has_spell && v >= word_end && v > cur_checked_col) {
spell_attr = 0;
- if (!attr_pri)
+ if (!attr_pri) {
char_attr = syntax_attr;
- if (c != 0 && (
- !has_syntax ||
- can_spell)) {
- char_u *prev_ptr, *p;
+ }
+ if (c != 0 && (!has_syntax || can_spell)) {
+ char_u *prev_ptr;
+ char_u *p;
int len;
hlf_T spell_hlf = HLF_COUNT;
if (has_mbyte) {
@@ -3341,6 +3340,17 @@ win_line (
char_attr = hl_combine_attr(spell_attr, char_attr);
}
+ if (has_bufhl && v > 0) {
+ bufhl_attr = bufhl_get_attr(&bufhl_info, (colnr_T)v);
+ if (bufhl_attr != 0) {
+ if (!attr_pri) {
+ char_attr = hl_combine_attr(char_attr, bufhl_attr);
+ } else {
+ char_attr = hl_combine_attr(bufhl_attr, char_attr);
+ }
+ }
+ }
+
if (wp->w_buffer->terminal) {
char_attr = hl_combine_attr(char_attr, term_attrs[vcol]);
}
@@ -3368,13 +3378,31 @@ win_line (
}
}
+ // 'list': change char 160 to lcs_nbsp and space to lcs_space.
+ if (wp->w_p_list
+ && (((c == 160
+ || (mb_utf8 && (mb_c == 160 || mb_c == 0x202f)))
+ && lcs_nbsp)
+ || (c == ' ' && lcs_space && ptr - line <= trailcol))) {
+ c = (c == ' ') ? lcs_space : lcs_nbsp;
+ n_attr = 1;
+ extra_attr = hl_attr(HLF_8);
+ saved_attr2 = char_attr; // save current attr
+ mb_c = c;
+ if (enc_utf8 && (*mb_char2len)(c) > 1) {
+ mb_utf8 = true;
+ u8cc[0] = 0;
+ c = 0xc0;
+ } else {
+ mb_utf8 = false;
+ }
+ }
+
if (trailcol != MAXCOL && ptr > line + trailcol && c == ' ') {
c = lcs_trail;
- if (!attr_pri) {
- n_attr = 1;
- extra_attr = hl_attr(HLF_8);
- saved_attr2 = char_attr; /* save current attr */
- }
+ n_attr = 1;
+ extra_attr = hl_attr(HLF_8);
+ saved_attr2 = char_attr; // save current attr
mb_c = c;
if (enc_utf8 && (*mb_char2len)(c) > 1) {
mb_utf8 = TRUE;
@@ -3522,11 +3550,9 @@ win_line (
c = ' ';
}
lcs_eol_one = -1;
- --ptr; /* put it back at the NUL */
- if (!attr_pri) {
- extra_attr = hl_attr(HLF_AT);
- n_attr = 1;
- }
+ ptr--; // put it back at the NUL
+ extra_attr = hl_attr(HLF_AT);
+ n_attr = 1;
mb_c = c;
if (enc_utf8 && (*mb_char2len)(c) > 1) {
mb_utf8 = TRUE;
@@ -3555,12 +3581,10 @@ win_line (
n_extra = byte2cells(c) - 1;
c = *p_extra++;
}
- if (!attr_pri) {
- n_attr = n_extra + 1;
- extra_attr = hl_attr(HLF_8);
- saved_attr2 = char_attr; /* save current attr */
- }
- mb_utf8 = FALSE; /* don't draw as UTF-8 */
+ n_attr = n_extra + 1;
+ extra_attr = hl_attr(HLF_8);
+ saved_attr2 = char_attr; // save current attr
+ mb_utf8 = false; // don't draw as UTF-8
} else if (VIsual_active
&& (VIsual_mode == Ctrl_V
|| VIsual_mode == 'v')
@@ -3571,25 +3595,22 @@ win_line (
wp->w_p_rl ? (col >= 0) :
(col < wp->w_width))) {
c = ' ';
- --ptr; /* put it back at the NUL */
- } else if ((
- diff_hlf != (hlf_T)0 ||
- line_attr != 0
- ) && (
- wp->w_p_rl ? (col >= 0) :
- (col
- - boguscols
- < wp->w_width))) {
- /* Highlight until the right side of the window */
+ ptr--; // put it back at the NUL
+ } else if ((diff_hlf != (hlf_T)0 || line_attr != 0)
+ && (wp->w_p_rl
+ ? (col >= 0)
+ : (col - boguscols < wp->w_width))) {
+ // Highlight until the right side of the window
c = ' ';
- --ptr; /* put it back at the NUL */
+ ptr--; // put it back at the NUL
- /* Remember we do the char for line highlighting. */
- ++did_line_attr;
+ // Remember we do the char for line highlighting.
+ did_line_attr++;
- /* don't do search HL for the rest of the line */
- if (line_attr != 0 && char_attr == search_attr && col > 0)
+ // don't do search HL for the rest of the line
+ if (line_attr != 0 && char_attr == search_attr && col > 0) {
char_attr = line_attr;
+ }
if (diff_hlf == HLF_TXD) {
diff_hlf = HLF_CHD;
if (attr == 0 || char_attr != attr) {
@@ -3602,24 +3623,28 @@ win_line (
}
}
- if ( wp->w_p_cole > 0
- && (wp != curwin || lnum != wp->w_cursor.lnum ||
- conceal_cursor_line(wp))
- && (syntax_flags & HL_CONCEAL) != 0
- && !(lnum_in_visual_area
- && vim_strchr(wp->w_p_cocu, 'v') == NULL)) {
+ if (wp->w_p_cole > 0
+ && (wp != curwin || lnum != wp->w_cursor.lnum
+ || conceal_cursor_line(wp))
+ && ((syntax_flags & HL_CONCEAL) != 0 || has_match_conc)
+ && !(lnum_in_visual_area
+ && vim_strchr(wp->w_p_cocu, 'v') == NULL)) {
char_attr = conceal_attr;
if (prev_syntax_id != syntax_seqnr
- && (syn_get_sub_char() != NUL || wp->w_p_cole == 1)
+ && (syn_get_sub_char() != NUL || match_conc
+ || wp->w_p_cole == 1)
&& wp->w_p_cole != 3) {
- /* First time at this concealed item: display one
- * character. */
- if (syn_get_sub_char() != NUL)
+ // First time at this concealed item: display one
+ // character.
+ if (match_conc) {
+ c = match_conc;
+ } else if (syn_get_sub_char() != NUL) {
c = syn_get_sub_char();
- else if (lcs_conceal != NUL)
+ } else if (lcs_conceal != NUL) {
c = lcs_conceal;
- else
+ } else {
c = ' ';
+ }
prev_syntax_id = syntax_seqnr;
@@ -3660,16 +3685,19 @@ win_line (
&& wp == curwin && lnum == wp->w_cursor.lnum
&& conceal_cursor_line(wp)
&& (int)wp->w_virtcol <= vcol + n_skip) {
- wp->w_wcol = col - boguscols;
+ if (wp->w_p_rl) {
+ wp->w_wcol = wp->w_width - col + boguscols - 1;
+ } else {
+ wp->w_wcol = col - boguscols;
+ }
wp->w_wrow = row;
- did_wcol = TRUE;
+ did_wcol = true;
}
- /* Don't override visual selection highlighting. */
- if (n_attr > 0
- && draw_state == WL_LINE
- && !attr_pri)
- char_attr = extra_attr;
+ // Don't override visual selection highlighting.
+ if (n_attr > 0 && draw_state == WL_LINE) {
+ char_attr = hl_combine_attr(char_attr, extra_attr);
+ }
/*
* Handle the case where we are in column 0 but not on the first
@@ -3697,13 +3725,12 @@ win_line (
mb_utf8 = TRUE;
u8cc[0] = 0;
c = 0xc0;
- } else
- mb_utf8 = FALSE; /* don't draw as UTF-8 */
- if (!attr_pri) {
- saved_attr3 = char_attr; /* save current attr */
- char_attr = hl_attr(HLF_AT); /* later copied to char_attr */
- n_attr3 = 1;
+ } else {
+ mb_utf8 = false; // don't draw as UTF-8
}
+ saved_attr3 = char_attr; // save current attr
+ char_attr = hl_attr(HLF_AT); // later copied to char_attr
+ n_attr3 = 1;
}
/*
@@ -6740,8 +6767,8 @@ int showmode(void)
if (Recording
&& edit_submode == NULL /* otherwise it gets too long */
) {
- MSG_PUTS_ATTR(_("recording"), attr);
- need_clear = TRUE;
+ recording_mode(attr);
+ need_clear = true;
}
mode_displayed = TRUE;
@@ -6780,26 +6807,33 @@ static void msg_pos_mode(void)
msg_row = Rows - 1;
}
-/*
- * Delete mode message. Used when ESC is typed which is expected to end
- * Insert mode (but Insert mode didn't end yet!).
- * Caller should check "mode_displayed".
- */
-void unshowmode(int force)
+/// Delete mode message. Used when ESC is typed which is expected to end
+/// Insert mode (but Insert mode didn't end yet!).
+/// Caller should check "mode_displayed".
+void unshowmode(bool force)
{
- /*
- * Don't delete it right now, when not redrawing or inside a mapping.
- */
- if (!redrawing() || (!force && char_avail() && !KeyTyped))
- redraw_cmdline = TRUE; /* delete mode later */
- else {
+ // Don't delete it right now, when not redrawing or inside a mapping.
+ if (!redrawing() || (!force && char_avail() && !KeyTyped)) {
+ redraw_cmdline = true; // delete mode later
+ } else {
msg_pos_mode();
- if (Recording)
- MSG_PUTS_ATTR(_("recording"), hl_attr(HLF_CM));
+ if (Recording) {
+ recording_mode(hl_attr(HLF_CM));
+ }
msg_clr_eos();
}
}
+static void recording_mode(int attr)
+{
+ MSG_PUTS_ATTR(_("recording"), attr);
+ if (!shortmess(SHM_RECORDING)) {
+ char_u s[4];
+ vim_snprintf((char *)s, ARRAY_SIZE(s), " @%c", Recording);
+ MSG_PUTS_ATTR(s, attr);
+ }
+}
+
/*
* Draw the tab pages line at the top of the Vim window.
*/