diff options
Diffstat (limited to 'src/nvim/screen.c')
-rw-r--r-- | src/nvim/screen.c | 146 |
1 files changed, 98 insertions, 48 deletions
diff --git a/src/nvim/screen.c b/src/nvim/screen.c index a78f905a70..20e3cc0a2e 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -143,7 +143,7 @@ long tab_page_click_defs_size = 0; // for line_putchar. Contains the state that needs to be remembered from // putting one character to the next. typedef struct { - const char_u *p; + const char *p; int prev_c; // previous Arabic character int prev_c1; // first composing char for prev_c } LineState; @@ -1857,7 +1857,7 @@ static int compute_foldcolumn(win_T *wp, int col) /// Handles composing chars and arabic shaping state. static int line_putchar(LineState *s, schar_T *dest, int maxcells, bool rl) { - const char_u *p = s->p; + const char_u *p = (char_u *)s->p; int cells = utf_ptr2cells(p); int c_len = utfc_ptr2len(p); int u8c, u8cc[MAX_MCO]; @@ -2082,7 +2082,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int line_attr_lowprio = 0; // low-priority attribute for the line matchitem_T *cur; // points to the match list match_T *shl; // points to search_hl or a match - int shl_flag; // flag to indicate whether search_hl + bool shl_flag; // flag to indicate whether search_hl // has been processed or not bool prevcol_hl_flag; // flag to indicate whether prevcol // equals startcol of search_hl or one @@ -2870,6 +2870,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, && vcol >= (long)wp->w_virtcol) || (number_only && draw_state > WL_NR)) && filler_todo <= 0) { + draw_virt_text(buf, &col, grid->Columns); grid_put_linebuf(grid, row, 0, col, -grid->Columns, wp->w_p_rl, wp, wp->w_hl_attr_normal, false); // Pretend we have finished updating the window. Except when @@ -2950,16 +2951,15 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, */ v = (long)(ptr - line); cur = wp->w_match_head; - shl_flag = FALSE; - while (cur != NULL || shl_flag == FALSE) { - if (shl_flag == FALSE - && ((cur != NULL - && cur->priority > SEARCH_HL_PRIORITY) - || cur == NULL)) { + shl_flag = false; + while (cur != NULL || !shl_flag) { + if (!shl_flag + && (cur == NULL || cur->priority > SEARCH_HL_PRIORITY)) { shl = &search_hl; - shl_flag = TRUE; - } else + shl_flag = true; + } else { shl = &cur->hl; + } if (cur != NULL) { cur->pos.cur = 0; } @@ -2984,7 +2984,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, has_match_conc = v == (long)shl->startcol ? 2 : 1; match_conc = cur->conceal_char; } else { - has_match_conc = match_conc = 0; + has_match_conc = 0; } } else if (v == (long)shl->endcol) { shl->attr_cur = 0; @@ -3026,16 +3026,15 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, search_attr_from_match = false; search_attr = search_hl.attr_cur; cur = wp->w_match_head; - shl_flag = FALSE; - while (cur != NULL || shl_flag == FALSE) { - if (shl_flag == FALSE - && ((cur != NULL - && cur->priority > SEARCH_HL_PRIORITY) - || cur == NULL)) { + shl_flag = false; + while (cur != NULL || !shl_flag) { + if (!shl_flag + && (cur == NULL || cur->priority > SEARCH_HL_PRIORITY)) { shl = &search_hl; - shl_flag = TRUE; - } else + shl_flag = true; + } else { shl = &cur->hl; + } if (shl->attr_cur != 0) { search_attr = shl->attr_cur; search_attr_from_match = shl != &search_hl; @@ -3048,6 +3047,12 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, && (wp->w_p_list && lcs_eol_one == -1)) { search_attr = 0; } + + // Do not allow a conceal over EOL otherwise EOL will be missed + // and bad things happen. + if (*ptr == NUL) { + has_match_conc = 0; + } } if (diff_hlf != (hlf_T)0) { @@ -3393,7 +3398,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, } if (has_decor && v > 0) { - int extmark_attr = decor_redraw_col(wp->w_buffer, (colnr_T)v-1, + int extmark_attr = decor_redraw_col(wp->w_buffer, (colnr_T)v-1, off, &decor_state); if (extmark_attr != 0) { if (!attr_pri) { @@ -3672,12 +3677,13 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, && vim_strchr(wp->w_p_cocu, 'v') == NULL)) { char_attr = conceal_attr; if ((prev_syntax_id != syntax_seqnr || has_match_conc > 1) - && (syn_get_sub_char() != NUL || match_conc + && (syn_get_sub_char() != NUL + || (has_match_conc && match_conc) || wp->w_p_cole == 1) && wp->w_p_cole != 3) { // First time at this concealed item: display one // character. - if (match_conc) { + if (has_match_conc && match_conc) { c = match_conc; } else if (syn_get_sub_char() != NUL) { c = syn_get_sub_char(); @@ -3837,16 +3843,15 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, // 'search_hl' and the match list. char_attr = search_hl.attr; cur = wp->w_match_head; - shl_flag = FALSE; - while (cur != NULL || shl_flag == FALSE) { - if (shl_flag == FALSE - && ((cur != NULL - && cur->priority > SEARCH_HL_PRIORITY) - || cur == NULL)) { + shl_flag = false; + while (cur != NULL || !shl_flag) { + if (!shl_flag + && (cur == NULL || cur->priority > SEARCH_HL_PRIORITY)) { shl = &search_hl; - shl_flag = TRUE; - } else + shl_flag = true; + } else { shl = &cur->hl; + } if ((ptr - line) - 1 == (long)shl->startcol && (shl == &search_hl || !shl->is_addpos)) { char_attr = shl->attr; @@ -3915,7 +3920,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int i; size_t virt_pos = 0; - LineState s = LINE_STATE((char_u *)""); + LineState s = LINE_STATE(""); int virt_attr = 0; // Make sure alignment is the same regardless @@ -3959,7 +3964,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, if (do_virttext && !delay_virttext) { if (*s.p == NUL) { if (virt_pos < virt_text.size) { - s.p = (char_u *)kv_A(virt_text, virt_pos).text; + s.p = kv_A(virt_text, virt_pos).text; int hl_id = kv_A(virt_text, virt_pos).hl_id; virt_attr = hl_id > 0 ? syn_id2attr(hl_id) : 0; virt_pos++; @@ -4025,6 +4030,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, col += n; } } + + draw_virt_text(buf, &col, grid->Columns); grid_put_linebuf(grid, row, 0, col, grid->Columns, wp->w_p_rl, wp, wp->w_hl_attr_normal, false); row++; @@ -4243,7 +4250,10 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, && (grid->Columns == Columns // Window spans the width of the screen, || ui_has(kUIMultigrid)) // or has dedicated grid. && !wp->w_p_rl; // Not right-to-left. - grid_put_linebuf(grid, row, 0, col - boguscols, grid->Columns, wp->w_p_rl, + + int draw_col = col - boguscols; + draw_virt_text(buf, &draw_col, grid->Columns); + grid_put_linebuf(grid, row, 0, draw_col, grid->Columns, wp->w_p_rl, wp, wp->w_hl_attr_normal, wrap); if (wrap) { ScreenGrid *current_grid = grid; @@ -4319,6 +4329,43 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, return row; } +void draw_virt_text(buf_T *buf, int *end_col, int max_col) +{ + DecorState *state = &decor_state; + for (size_t i = 0; i < kv_size(state->active); i++) { + HlRange *item = &kv_A(state->active, i); + if (item->start_row == state->row && item->virt_text + && item->virt_text_pos == kVTOverlay + && item->virt_col >= 0) { + VirtText vt = *item->virt_text; + LineState s = LINE_STATE(""); + int virt_attr = 0; + int col = item->virt_col; + size_t virt_pos = 0; + item->virt_col = -2; // deactivate + + while (col < max_col) { + if (!*s.p) { + if (virt_pos == kv_size(vt)) { + break; + } + s.p = kv_A(vt, virt_pos).text; + int hl_id = kv_A(vt, virt_pos).hl_id; + virt_attr = hl_id > 0 ? syn_id2attr(hl_id) : 0; + virt_pos++; + continue; + } + int cells = line_putchar(&s, &linebuf_char[col], 2, false); + linebuf_attr[col++] = virt_attr; + if (cells > 1) { + linebuf_attr[col++] = virt_attr; + } + } + *end_col = MAX(*end_col, col); + } + } +} + /// Determine if dedicated window grid should be used or the default_grid /// /// If UI did not request multigrid support, draw all windows on the @@ -5092,9 +5139,9 @@ static void redraw_custom_statusline(win_T *wp) // When there is an error disable the statusline, otherwise the // display is messed up with errors and a redraw triggers the problem // again and again. - set_string_option_direct((char_u *)"statusline", -1, - (char_u *)"", OPT_FREE | (*wp->w_p_stl != NUL - ? OPT_LOCAL : OPT_GLOBAL), SID_ERROR); + set_string_option_direct("statusline", -1, (char_u *)"", + OPT_FREE | (*wp->w_p_stl != NUL + ? OPT_LOCAL : OPT_GLOBAL), SID_ERROR); } did_emsg |= saved_did_emsg; entered = false; @@ -5175,7 +5222,7 @@ get_keymap_str ( static void win_redr_custom ( win_T *wp, - int draw_ruler /* TRUE or FALSE */ + bool draw_ruler ) { static int entered = FALSE; @@ -6852,7 +6899,7 @@ void draw_tabline(void) did_emsg = false; win_redr_custom(NULL, false); if (did_emsg) { - set_string_option_direct((char_u *)"tabline", -1, + set_string_option_direct("tabline", -1, (char_u *)"", OPT_FREE, SID_ERROR); } did_emsg |= saved_did_emsg; @@ -7105,20 +7152,23 @@ static void win_redr_ruler(win_T *wp, int always) if (wp->w_cursor.lnum > wp->w_buffer->b_ml.ml_line_count) return; - /* Don't draw the ruler while doing insert-completion, it might overwrite - * the (long) mode message. */ - if (wp == lastwin && lastwin->w_status_height == 0) - if (edit_submode != NULL) + // Don't draw the ruler while doing insert-completion, it might overwrite + // the (long) mode message. + if (wp == lastwin && lastwin->w_status_height == 0) { + if (edit_submode != NULL) { return; + } + } if (*p_ruf) { int save_called_emsg = called_emsg; - called_emsg = FALSE; - win_redr_custom(wp, TRUE); - if (called_emsg) - set_string_option_direct((char_u *)"rulerformat", -1, - (char_u *)"", OPT_FREE, SID_ERROR); + called_emsg = false; + win_redr_custom(wp, true); + if (called_emsg) { + set_string_option_direct("rulerformat", -1, (char_u *)"", + OPT_FREE, SID_ERROR); + } called_emsg |= save_called_emsg; return; } |