diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/api/ui.c | 26 | ||||
-rw-r--r-- | src/nvim/api/vim.c | 22 | ||||
-rw-r--r-- | src/nvim/buffer_defs.h | 62 | ||||
-rw-r--r-- | src/nvim/cmdexpand.c | 2 | ||||
-rw-r--r-- | src/nvim/drawline.c | 241 | ||||
-rw-r--r-- | src/nvim/drawscreen.c | 53 | ||||
-rw-r--r-- | src/nvim/eval/funcs.c | 19 | ||||
-rw-r--r-- | src/nvim/grid.c | 61 | ||||
-rw-r--r-- | src/nvim/match.c | 4 | ||||
-rw-r--r-- | src/nvim/message.c | 106 | ||||
-rw-r--r-- | src/nvim/option.c | 8 | ||||
-rw-r--r-- | src/nvim/optionstr.c | 181 | ||||
-rw-r--r-- | src/nvim/optionstr.h | 5 | ||||
-rw-r--r-- | src/nvim/popupmenu.c | 8 | ||||
-rw-r--r-- | src/nvim/statusline.c | 68 | ||||
-rw-r--r-- | src/nvim/window.c | 6 |
16 files changed, 426 insertions, 446 deletions
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 82d42d652d..271e58b851 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -41,7 +41,7 @@ static PMap(uint64_t) connected_uis = MAP_INIT; -#define mpack_w(b, byte) *(*b)++ = (char)(byte); +#define mpack_w(b, byte) *(*(b))++ = (char)(byte); static void mpack_w2(char **b, uint32_t v) { *(*b)++ = (char)((v >> 8) & 0xff); @@ -98,10 +98,9 @@ static char *mpack_array_dyn16(char **buf) return pos; } -static void mpack_str(char **buf, const char *str) +static void mpack_str(char **buf, const char *str, size_t len) { assert(sizeof(schar_T) - 1 < 0x20); - size_t len = strlen(str); mpack_w(buf, 0xa0 | len); memcpy(*buf, str, len); *buf += len; @@ -566,7 +565,7 @@ static void flush_event(UIData *data) // [2, "redraw", [...]] mpack_array(buf, 3); mpack_uint(buf, 2); - mpack_str(buf, "redraw"); + mpack_str(buf, S_LEN("redraw")); data->nevents_pos = mpack_array_dyn16(buf); } } @@ -607,7 +606,7 @@ static bool prepare_call(UI *ui, const char *name) data->cur_event = name; char **buf = &data->buf_wptr; data->ncalls_pos = mpack_array_dyn16(buf); - mpack_str(buf, name); + mpack_str(buf, name, strlen(name)); data->nevents++; data->ncalls = 1; return true; @@ -640,17 +639,18 @@ static void push_call(UI *ui, const char *name, Array args) remote_ui_flush_buf(ui); } - if (data->pack_totlen > UI_BUF_SIZE - strlen(name) - 20) { + size_t name_len = strlen(name); + if (data->pack_totlen > UI_BUF_SIZE - name_len - 20) { // TODO(bfredl): manually testable by setting UI_BUF_SIZE to 1024 (mode_info_set) - data->temp_buf = xmalloc(20 + strlen(name) + data->pack_totlen); + data->temp_buf = xmalloc(20 + name_len + data->pack_totlen); data->buf_wptr = data->temp_buf; char **buf = &data->buf_wptr; mpack_array(buf, 3); mpack_uint(buf, 2); - mpack_str(buf, "redraw"); + mpack_str(buf, S_LEN("redraw")); mpack_array(buf, 1); mpack_array(buf, 2); - mpack_str(buf, name); + mpack_str(buf, name, name_len); } else { prepare_call(ui, name); } @@ -895,9 +895,9 @@ void remote_ui_raw_line(UI *ui, Integer grid, Integer row, Integer startcol, Int uint32_t csize = (repeat > 1) ? 3 : ((attrs[i] != last_hl) ? 2 : 1); nelem++; mpack_array(buf, csize); - char sc_buf[MAX_SCHAR_SIZE]; - schar_get(sc_buf, chunk[i]); - mpack_str(buf, sc_buf); + char *size_byte = (*buf)++; + size_t len = schar_get_adv(buf, chunk[i]); + *size_byte = (char)(0xa0 | len); if (csize >= 2) { mpack_uint(buf, (uint32_t)attrs[i]); if (csize >= 3) { @@ -916,7 +916,7 @@ void remote_ui_raw_line(UI *ui, Integer grid, Integer row, Integer startcol, Int nelem++; data->ncells_pending += 1; mpack_array(buf, 3); - mpack_str(buf, " "); + mpack_str(buf, S_LEN(" ")); mpack_uint(buf, (uint32_t)clearattr); mpack_uint(buf, (uint32_t)(clearcol - endcol)); } diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 2bb3f0fac7..f683789945 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -2132,7 +2132,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * Dictionary result = ARRAY_DICT_INIT; int maxwidth; - int fillchar = 0; + schar_T fillchar = 0; int statuscol_lnum = 0; Window window = 0; @@ -2148,11 +2148,13 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * } if (HAS_KEY(opts, eval_statusline, fillchar)) { VALIDATE_EXP((*opts->fillchar.data != 0 - && ((size_t)utf_ptr2len(opts->fillchar.data) == opts->fillchar.size)), + && ((size_t)utfc_ptr2len(opts->fillchar.data) == opts->fillchar.size)), "fillchar", "single character", NULL, { return result; }); - fillchar = utf_ptr2char(opts->fillchar.data); + int c; + fillchar = utfc_ptr2schar(opts->fillchar.data, &c); + // TODO(bfredl): actually check c is single width } int use_bools = (int)opts->use_winbar + (int)opts->use_tabline; @@ -2181,7 +2183,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * SignTextAttrs sattrs[SIGN_SHOW_MAX] = { 0 }; if (opts->use_tabline) { - fillchar = ' '; + fillchar = schar_from_ascii(' '); } else { if (fillchar == 0) { if (opts->use_winbar) { @@ -2242,16 +2244,8 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * int p_crb_save = wp->w_p_crb; wp->w_p_crb = false; - int width = build_stl_str_hl(wp, - buf, - sizeof(buf), - str.data, - -1, - 0, - fillchar, - maxwidth, - opts->highlights ? &hltab : NULL, - NULL, + int width = build_stl_str_hl(wp, buf, sizeof(buf), str.data, -1, 0, fillchar, maxwidth, + opts->highlights ? &hltab : NULL, NULL, statuscol_lnum ? &statuscol : NULL); PUT(result, "width", INTEGER_OBJ(width)); diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index c6bd5691b1..085070fc4a 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -971,41 +971,41 @@ typedef struct { /// Characters from the 'listchars' option. typedef struct { - int eol; - int ext; - int prec; - int nbsp; - int space; - int tab1; ///< first tab character - int tab2; ///< second tab character - int tab3; ///< third tab character - int lead; - int trail; - int *multispace; - int *leadmultispace; - int conceal; + schar_T eol; + schar_T ext; + schar_T prec; + schar_T nbsp; + schar_T space; + schar_T tab1; ///< first tab character + schar_T tab2; ///< second tab character + schar_T tab3; ///< third tab character + schar_T lead; + schar_T trail; + schar_T *multispace; + schar_T *leadmultispace; + schar_T conceal; } lcs_chars_T; /// Characters from the 'fillchars' option. typedef struct { - int stl; - int stlnc; - int wbr; - int horiz; - int horizup; - int horizdown; - int vert; - int vertleft; - int vertright; - int verthoriz; - int fold; - int foldopen; ///< when fold is open - int foldclosed; ///< when fold is closed - int foldsep; ///< continuous fold marker - int diff; - int msgsep; - int eob; - int lastline; + schar_T stl; + schar_T stlnc; + schar_T wbr; + schar_T horiz; + schar_T horizup; + schar_T horizdown; + schar_T vert; + schar_T vertleft; + schar_T vertright; + schar_T verthoriz; + schar_T fold; + schar_T foldopen; ///< when fold is open + schar_T foldclosed; ///< when fold is closed + schar_T foldsep; ///< continuous fold marker + schar_T diff; + schar_T msgsep; + schar_T eob; + schar_T lastline; } fcs_chars_T; /// Structure which contains all information that belongs to a window. diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c index 2d66526f33..968081c6ac 100644 --- a/src/nvim/cmdexpand.c +++ b/src/nvim/cmdexpand.c @@ -508,7 +508,7 @@ static void redraw_wildmenu(expand_T *xp, int num_matches, char **matches, int m } } - int fillchar = fillchar_status(&attr, curwin); + schar_T fillchar = fillchar_status(&attr, curwin); if (first_match == 0) { *buf = NUL; diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index 22eb0b9c31..dc4ef72e38 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -64,6 +64,7 @@ typedef struct { 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 old_boguscols; ///< bogus boguscols int vcol_off; ///< offset for concealed characters int off; ///< offset relative start of line @@ -83,10 +84,10 @@ typedef struct { int n_extra; ///< number of extra bytes int n_attr; ///< chars with special attr char *p_extra; ///< string of extra chars, plus NUL, only used - ///< when c_extra and c_final are NUL + ///< when sc_extra and sc_final are NUL int extra_attr; ///< attributes for p_extra - int c_extra; ///< extra chars, all the same - int c_final; ///< final char, mandatory if set + schar_T sc_extra; ///< extra chars, all the same + schar_T sc_final; ///< final char, mandatory if set bool extra_for_extmark; ///< n_extra set for inline virtual text @@ -409,9 +410,9 @@ void fill_foldcolumn(win_T *wp, foldinfo_T foldinfo, linenr_T lnum, int attr, in int closedcol = MIN(fdc, level); for (int i = 0; i < fdc; i++) { - int symbol = 0; + schar_T symbol = 0; if (i >= level) { - symbol = ' '; + symbol = schar_from_ascii(' '); } else if (i == closedcol - 1 && closed) { symbol = wp->w_p_fcs_chars.foldclosed; } else if (foldinfo.fi_lnum == lnum && first_level + i >= foldinfo.fi_low_level) { @@ -419,17 +420,17 @@ void fill_foldcolumn(win_T *wp, foldinfo_T foldinfo, linenr_T lnum, int attr, in } else if (first_level == 1) { symbol = wp->w_p_fcs_chars.foldsep; } else if (first_level + i <= 9) { - symbol = '0' + first_level + i; + symbol = schar_from_ascii('0' + first_level + i); } else { - symbol = '>'; + symbol = schar_from_ascii('>'); } if (out_buffer) { - out_buffer[i] = schar_from_char(symbol); + out_buffer[i] = symbol; } else { linebuf_vcol[*wlv_off] = i >= level ? -1 : (i == closedcol - 1 && closed) ? -2 : -3; linebuf_attr[*wlv_off] = attr; - linebuf_char[(*wlv_off)++] = schar_from_char(symbol); + linebuf_char[(*wlv_off)++] = symbol; } } } @@ -441,7 +442,6 @@ void fill_foldcolumn(win_T *wp, foldinfo_T foldinfo, linenr_T lnum, int attr, in static void draw_sign(bool nrcol, win_T *wp, winlinevars_T *wlv, int sign_idx, int sign_cul_attr) { SignTextAttrs sattr = wlv->sattrs[sign_idx]; - wlv->c_final = NUL; 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) @@ -453,7 +453,6 @@ 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() - wlv->c_extra = ' '; 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); } @@ -680,8 +679,8 @@ static void handle_showbreak_and_filler(win_T *wp, winlinevars_T *wlv) draw_col_fill(wlv, schar_from_ascii(' '), remaining, 0); } else if (wlv->filler_todo > 0) { // Draw "deleted" diff line(s) - int c = (char2cells(wp->w_p_fcs_chars.diff) > 1) ? '-' : wp->w_p_fcs_chars.diff; - draw_col_fill(wlv, schar_from_char(c), remaining, win_hl_attr(wp, HLF_DED)); + schar_T c = wp->w_p_fcs_chars.diff; + draw_col_fill(wlv, c, remaining, win_hl_attr(wp, HLF_DED)); } char *const sbr = get_showbreak_value(wp); @@ -790,8 +789,8 @@ static void handle_inline_virtual_text(win_T *wp, winlinevars_T *wlv, ptrdiff_t if (wlv->n_extra == 0) { continue; } - wlv->c_extra = NUL; - wlv->c_final = NUL; + wlv->sc_extra = NUL; + wlv->sc_final = NUL; wlv->extra_attr = attr; wlv->n_attr = mb_charlen(text); // If the text didn't reach until the first window @@ -871,6 +870,16 @@ static void win_line_start(win_T *wp, winlinevars_T *wlv, bool save_extra) memset(linebuf_vcol, -1, (size_t)wp->w_grid.cols * sizeof(*linebuf_vcol)); } +static void fix_for_boguscols(winlinevars_T *wlv) +{ + wlv->n_extra += wlv->vcol_off; + wlv->vcol -= wlv->vcol_off; + wlv->vcol_off = 0; + wlv->col -= wlv->boguscols; + wlv->old_boguscols = wlv->boguscols; + wlv->boguscols = 0; +} + /// Display line "lnum" of window "wp" on the screen. /// wp->w_virtcol needs to be valid. /// @@ -932,7 +941,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl int multi_attr = 0; // attributes desired by multibyte int mb_l = 1; // multi-byte byte length int mb_c = 0; // decoded multi-byte character - schar_T mb_schar; // complete screen char + schar_T mb_schar = 0; // complete screen char 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 @@ -971,17 +980,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl int conceal_attr = win_hl_attr(wp, HLF_CONCEAL); bool is_concealing = false; bool did_wcol = false; - int old_boguscols = 0; #define vcol_hlc(wlv) ((wlv).vcol - (wlv).vcol_off) -#define FIX_FOR_BOGUSCOLS \ - { \ - 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; \ - } assert(startrow < endrow); @@ -994,6 +993,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl wlv.fromcol = -10; wlv.tocol = MAXCOL; wlv.vcol_sbr = -1; + wlv.old_boguscols = 0; buf_T *buf = wp->w_buffer; const bool end_fill = (lnum == buf->b_ml.ml_line_count + 1); @@ -1276,8 +1276,9 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl colnr_T trailcol = MAXCOL; // start of trailing spaces colnr_T leadcol = 0; // start of leading spaces - int lcs_eol_one = wp->w_p_lcs_chars.eol; // 'eol' until it's been used - int lcs_prec_todo = wp->w_p_lcs_chars.prec; // 'prec' until it's been used + bool lcs_eol_todo = true; // need to keep track of this even if lcs_eol is NUL + const schar_T lcs_eol = wp->w_p_lcs_chars.eol; // 'eol' value + schar_T lcs_prec_todo = wp->w_p_lcs_chars.prec; // 'prec' until it's been used, then NUL if (wp->w_p_list && !has_fold && !end_fill) { if (wp->w_p_lcs_chars.space @@ -1644,7 +1645,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl // When another match, have to check for start again. v = ptr - line; search_attr = update_search_hl(wp, lnum, (colnr_T)v, &line, &screen_search_hl, - &has_match_conc, &match_conc, lcs_eol_one, + &has_match_conc, &match_conc, lcs_eol_todo, &on_last_col, &search_attr_from_match); ptr = line + v; // "line" may have been changed @@ -1715,8 +1716,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl if (wlv.p_extra != buf_fold) { foldtext_free = wlv.p_extra; } - wlv.c_extra = NUL; - wlv.c_final = NUL; + wlv.sc_extra = NUL; + wlv.sc_final = NUL; wlv.p_extra[wlv.n_extra] = NUL; // Get the line again as evaluating 'foldtext' may free it. @@ -1726,8 +1727,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl if (draw_folded && wlv.n_extra == 0 && wlv.col < grid->cols) { // Fill rest of line with 'fold'. - wlv.c_extra = wp->w_p_fcs_chars.fold; - wlv.c_final = NUL; + wlv.sc_extra = wp->w_p_fcs_chars.fold; + wlv.sc_final = NUL; wlv.n_extra = grid->cols - wlv.col; } @@ -1740,15 +1741,15 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl // // The "p_extra" points to the extra stuff that is inserted to // represent special characters (non-printable stuff) and other - // things. When all characters are the same, c_extra is used. - // If c_final is set, it will compulsorily be used at the end. + // things. When all characters are the same, sc_extra is used. + // If sc_final is set, it will compulsorily be used at the end. // "p_extra" must end in a NUL to avoid utfc_ptr2len() reads past // "p_extra[n_extra]". // For the '$' of the 'list' option, n_extra == 1, p_extra == "". if (wlv.n_extra > 0) { - if (wlv.c_extra != NUL || (wlv.n_extra == 1 && wlv.c_final != NUL)) { - mb_c = (wlv.n_extra == 1 && wlv.c_final != NUL) ? wlv.c_final : wlv.c_extra; - mb_schar = schar_from_char(mb_c); + if (wlv.sc_extra != NUL || (wlv.n_extra == 1 && wlv.sc_final != NUL)) { + mb_schar = (wlv.n_extra == 1 && wlv.sc_final != NUL) ? wlv.sc_final : wlv.sc_extra; + mb_c = schar_get_first_codepoint(mb_schar); wlv.n_extra--; } else { assert(wlv.p_extra != NULL); @@ -1809,7 +1810,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl mb_schar = schar_from_ascii(' '); } else if (has_fold) { // skip writing the buffer line itself - mb_c = NUL; + mb_schar = NUL; } else { char *prev_ptr = ptr; @@ -1844,8 +1845,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl mb_c = mb_ptr2char_adv((const char **)&wlv.p_extra); mb_schar = schar_from_char(mb_c); wlv.n_extra = (int)strlen(wlv.p_extra); - wlv.c_extra = NUL; - wlv.c_final = NUL; + wlv.sc_extra = NUL; + wlv.sc_final = NUL; if (area_attr == 0 && search_attr == 0) { wlv.n_attr = wlv.n_extra + 1; wlv.extra_attr = win_hl_attr(wp, HLF_8); @@ -1858,9 +1859,9 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl // last column; the character is displayed at the start of the // next line. if (wlv.col >= grid->cols - 1 && utf_char2cells(mb_c) == 2) { + mb_schar = schar_from_ascii('>'); mb_c = '>'; mb_l = 1; - mb_schar = schar_from_ascii(mb_c); multi_attr = win_hl_attr(wp, HLF_AT); // Put pointer back so that the character will be // displayed at the start of the next line. @@ -1874,11 +1875,11 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl // the first column. Don't do this for unprintable characters. if (wlv.skip_cells > 0 && mb_l > 1 && wlv.n_extra == 0) { wlv.n_extra = 1; - wlv.c_extra = MB_FILLER_CHAR; - wlv.c_final = NUL; + wlv.sc_extra = schar_from_ascii(MB_FILLER_CHAR); + wlv.sc_final = NUL; + mb_schar = schar_from_ascii(' '); mb_c = ' '; mb_l = 1; - mb_schar = schar_from_ascii(mb_c); if (area_attr == 0 && search_attr == 0) { wlv.n_attr = wlv.n_extra + 1; wlv.extra_attr = win_hl_attr(wp, HLF_AT); @@ -1922,7 +1923,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl // no concealing past the end of the line, it interferes // with line highlighting. - syntax_flags = (mb_c == 0) ? 0 : get_syntax_info(&syntax_seqnr); + syntax_flags = (mb_schar == 0) ? 0 : get_syntax_info(&syntax_seqnr); } if (has_decor && v > 0) { @@ -1957,7 +1958,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl spell_attr = 0; // do not calculate cap_col at the end of the line or when // only white space is following - if (mb_c != 0 && (*skipwhite(prev_ptr) != NUL) && can_spell) { + if (mb_schar != 0 && (*skipwhite(prev_ptr) != NUL) && can_spell) { char *p; hlf_T spell_hlf = HLF_COUNT; v -= mb_l - 1; @@ -2031,7 +2032,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl // // So only allow to linebreak, once we have found chars not in // 'breakat' in the line. - if (wp->w_p_lbr && !wlv.need_lbr && mb_c != NUL + if (wp->w_p_lbr && !wlv.need_lbr && mb_schar != NUL && !vim_isbreak((uint8_t)(*ptr))) { wlv.need_lbr = true; } @@ -2059,12 +2060,12 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl wlv.n_extra = tabstop_padding(wlv.vcol, wp->w_buffer->b_p_ts, wp->w_buffer->b_p_vts_array) - 1; } - wlv.c_extra = mb_off > 0 ? MB_FILLER_CHAR : ' '; - wlv.c_final = NUL; + wlv.sc_extra = schar_from_ascii(mb_off > 0 ? MB_FILLER_CHAR : ' '); + wlv.sc_final = NUL; if (mb_c < 128 && ascii_iswhite(mb_c)) { if (mb_c == TAB) { // See "Tab alignment" below. - FIX_FOR_BOGUSCOLS; + fix_for_boguscols(&wlv); } if (!wp->w_p_list) { mb_c = ' '; @@ -2093,39 +2094,39 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl && ptr - line >= leadcol && ptr - line <= trailcol))) { if (in_multispace && wp->w_p_lcs_chars.multispace != NULL) { - mb_c = wp->w_p_lcs_chars.multispace[multispace_pos++]; + mb_schar = wp->w_p_lcs_chars.multispace[multispace_pos++]; if (wp->w_p_lcs_chars.multispace[multispace_pos] == NUL) { multispace_pos = 0; } } else { - mb_c = (mb_c == ' ') ? wp->w_p_lcs_chars.space : wp->w_p_lcs_chars.nbsp; + mb_schar = (mb_c == ' ') ? wp->w_p_lcs_chars.space : wp->w_p_lcs_chars.nbsp; } wlv.n_attr = 1; wlv.extra_attr = win_hl_attr(wp, HLF_0); saved_attr2 = wlv.char_attr; // save current attr - mb_schar = schar_from_char(mb_c); + mb_c = schar_get_first_codepoint(mb_schar); } if (mb_c == ' ' && mb_l == 1 && ((trailcol != MAXCOL && ptr > line + trailcol) || (leadcol != 0 && ptr < line + leadcol))) { if (leadcol != 0 && in_multispace && ptr < line + leadcol && wp->w_p_lcs_chars.leadmultispace != NULL) { - mb_c = wp->w_p_lcs_chars.leadmultispace[multispace_pos++]; + mb_schar = wp->w_p_lcs_chars.leadmultispace[multispace_pos++]; if (wp->w_p_lcs_chars.leadmultispace[multispace_pos] == NUL) { multispace_pos = 0; } } else if (ptr > line + trailcol && wp->w_p_lcs_chars.trail) { - mb_c = wp->w_p_lcs_chars.trail; + mb_schar = wp->w_p_lcs_chars.trail; } else if (ptr < line + leadcol && wp->w_p_lcs_chars.lead) { - mb_c = wp->w_p_lcs_chars.lead; + mb_schar = wp->w_p_lcs_chars.lead; } else if (leadcol != 0 && wp->w_p_lcs_chars.space) { - mb_c = wp->w_p_lcs_chars.space; + mb_schar = wp->w_p_lcs_chars.space; } wlv.n_attr = 1; wlv.extra_attr = win_hl_attr(wp, HLF_0); saved_attr2 = wlv.char_attr; // save current attr - mb_schar = schar_from_char(mb_c); + mb_c = schar_get_first_codepoint(mb_schar); } } @@ -2157,8 +2158,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl // there are characters to conceal tab_len += wlv.vcol_off; } - // boguscols before FIX_FOR_BOGUSCOLS macro from above. - if (wp->w_p_lcs_chars.tab1 && old_boguscols > 0 + // boguscols before fix_for_boguscols() from above. + if (wp->w_p_lcs_chars.tab1 && wlv.old_boguscols > 0 && wlv.n_extra > tab_len) { tab_len += wlv.n_extra - tab_len; } @@ -2167,35 +2168,35 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl // If wlv.n_extra > 0, it gives the number of chars // to use for a tab, else we need to calculate the // width for a tab. - int tab2_len = utf_char2len(wp->w_p_lcs_chars.tab2); - int len = tab_len * tab2_len; + size_t tab2_len = schar_len(wp->w_p_lcs_chars.tab2); + size_t len = (size_t)tab_len * tab2_len; if (wp->w_p_lcs_chars.tab3) { - len += utf_char2len(wp->w_p_lcs_chars.tab3) - tab2_len; + len += schar_len(wp->w_p_lcs_chars.tab3) - tab2_len; } if (wlv.n_extra > 0) { - len += wlv.n_extra - tab_len; + len += (size_t)(wlv.n_extra - tab_len); } - mb_c = wp->w_p_lcs_chars.tab1; - char *p = get_extra_buf((size_t)len + 1); - memset(p, ' ', (size_t)len); - p[len] = NUL; + mb_schar = wp->w_p_lcs_chars.tab1; + mb_c = schar_get_first_codepoint(mb_schar); + char *p = get_extra_buf(len + 1); + memset(p, ' ', len); wlv.p_extra = p; for (int i = 0; i < tab_len; i++) { if (*p == NUL) { tab_len = i; break; } - int lcs = wp->w_p_lcs_chars.tab2; + schar_T lcs = wp->w_p_lcs_chars.tab2; // if tab3 is given, use it for the last char if (wp->w_p_lcs_chars.tab3 && i == tab_len - 1) { lcs = wp->w_p_lcs_chars.tab3; } - p += utf_char2bytes(lcs, p); - wlv.n_extra += utf_char2len(lcs) - (saved_nextra > 0 ? 1 : 0); + size_t slen = schar_get_adv(&p, lcs); + wlv.n_extra += (int)slen - (saved_nextra > 0 ? 1 : 0); } - // n_extra will be increased by FIX_FOX_BOGUSCOLS + // n_extra will be increased by fix_for_boguscols() // macro below, so need to adjust for that here if (wlv.vcol_off > 0) { wlv.n_extra -= wlv.vcol_off; @@ -2212,7 +2213,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl // vcol_off and boguscols accumulated so far in the // line. Note that the tab can be longer than // 'tabstop' when there are concealed characters. - FIX_FOR_BOGUSCOLS; + fix_for_boguscols(&wlv); // Make sure, the highlighting for the tab char will be // correctly set further below (effectively reverts the @@ -2224,24 +2225,24 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl } if (wp->w_p_list) { - mb_c = (wlv.n_extra == 0 && wp->w_p_lcs_chars.tab3) - ? wp->w_p_lcs_chars.tab3 : wp->w_p_lcs_chars.tab1; + mb_schar = (wlv.n_extra == 0 && wp->w_p_lcs_chars.tab3) + ? wp->w_p_lcs_chars.tab3 : wp->w_p_lcs_chars.tab1; if (wp->w_p_lbr && wlv.p_extra != NULL && *wlv.p_extra != NUL) { - wlv.c_extra = NUL; // using p_extra from above + wlv.sc_extra = NUL; // using p_extra from above } else { - wlv.c_extra = wp->w_p_lcs_chars.tab2; + wlv.sc_extra = wp->w_p_lcs_chars.tab2; } - wlv.c_final = wp->w_p_lcs_chars.tab3; + wlv.sc_final = wp->w_p_lcs_chars.tab3; wlv.n_attr = tab_len + 1; wlv.extra_attr = win_hl_attr(wp, HLF_0); saved_attr2 = wlv.char_attr; // save current attr } else { - wlv.c_final = NUL; - wlv.c_extra = ' '; - mb_c = ' '; + wlv.sc_final = NUL; + wlv.sc_extra = schar_from_ascii(' '); + mb_schar = schar_from_ascii(' '); } - mb_schar = schar_from_char(mb_c); - } else if (mb_c == NUL + mb_c = schar_get_first_codepoint(mb_schar); + } else if (mb_schar == NUL && (wp->w_p_list || ((wlv.fromcol >= 0 || fromcol_prev >= 0) && wlv.tocol > wlv.vcol @@ -2250,7 +2251,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl && !(noinvcur && lnum == wp->w_cursor.lnum && wlv.vcol == wp->w_virtcol))) - && lcs_eol_one > 0) { + && lcs_eol_todo && lcs_eol != NUL) { // Display a '$' after the line or highlight an extra // character if the line break is included. // For a diff line the highlighting continues after the "$". @@ -2265,16 +2266,16 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl wlv.n_extra = 0; } if (wp->w_p_list && wp->w_p_lcs_chars.eol > 0) { - mb_c = wp->w_p_lcs_chars.eol; + mb_schar = wp->w_p_lcs_chars.eol; } else { - mb_c = ' '; + mb_schar = schar_from_ascii(' '); } - lcs_eol_one = -1; + lcs_eol_todo = false; ptr--; // put it back at the NUL wlv.extra_attr = win_hl_attr(wp, HLF_AT); wlv.n_attr = 1; - mb_schar = schar_from_char(mb_c); - } else if (mb_c != NUL) { + mb_c = schar_get_first_codepoint(mb_schar); + } else if (mb_schar != NUL) { wlv.p_extra = transchar_buf(wp->w_buffer, mb_c); if (wlv.n_extra == 0) { wlv.n_extra = byte2cells(mb_c) - 1; @@ -2282,8 +2283,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl if ((dy_flags & DY_UHEX) && wp->w_p_rl) { rl_mirror_ascii(wlv.p_extra, NULL); // reverse "<12>" } - wlv.c_extra = NUL; - wlv.c_final = NUL; + wlv.sc_extra = NUL; + wlv.sc_final = NUL; if (wp->w_p_lbr) { mb_c = (uint8_t)(*wlv.p_extra); char *p = get_extra_buf((size_t)wlv.n_extra + 1); @@ -2316,7 +2317,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl && ((syntax_flags & HL_CONCEAL) != 0 || has_match_conc > 0 || decor_conceal > 0) && !(lnum_in_visual_area && vim_strchr(wp->w_p_cocu, 'v') == NULL)) { wlv.char_attr = conceal_attr; - bool is_conceal_char = false; if (((prev_syntax_id != syntax_seqnr && (syntax_flags & HL_CONCEAL) != 0) || has_match_conc > 1 || decor_conceal > 1) && (syn_get_sub_char() != NUL @@ -2327,21 +2327,20 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl // First time at this concealed item: display one // character. if (has_match_conc && match_conc) { - mb_c = match_conc; + mb_schar = schar_from_char(match_conc); } else if (decor_conceal && decor_state.conceal_char) { mb_schar = decor_state.conceal_char; - mb_c = schar_get_first_codepoint(mb_schar); - is_conceal_char = true; if (decor_state.conceal_attr) { wlv.char_attr = decor_state.conceal_attr; } } else if (syn_get_sub_char() != NUL) { - mb_c = syn_get_sub_char(); + mb_schar = schar_from_char(syn_get_sub_char()); } else if (wp->w_p_lcs_chars.conceal != NUL) { - mb_c = wp->w_p_lcs_chars.conceal; + mb_schar = wp->w_p_lcs_chars.conceal; } else { - mb_c = ' '; + mb_schar = schar_from_ascii(' '); } + mb_c = schar_get_first_codepoint(mb_schar); prev_syntax_id = syntax_seqnr; @@ -2359,9 +2358,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl is_concealing = true; wlv.skip_cells = 1; } - if (!is_conceal_char) { - mb_schar = schar_from_char(mb_c); - } } else { prev_syntax_id = 0; is_concealing = false; @@ -2403,26 +2399,26 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl && wp->w_p_list && (wp->w_p_wrap ? (wp->w_skipcol > 0 && wlv.row == 0) : wp->w_leftcol > 0) && wlv.filler_todo <= 0 - && mb_c != NUL) { - mb_c = wp->w_p_lcs_chars.prec; + && mb_schar != NUL) { + mb_schar = wp->w_p_lcs_chars.prec; lcs_prec_todo = NUL; if (utf_char2cells(mb_c) > 1) { // Double-width character being overwritten by the "precedes" // character, need to fill up half the character. - wlv.c_extra = MB_FILLER_CHAR; - wlv.c_final = NUL; + wlv.sc_extra = schar_from_ascii(MB_FILLER_CHAR); + wlv.sc_final = NUL; wlv.n_extra = 1; wlv.n_attr = 2; wlv.extra_attr = win_hl_attr(wp, HLF_AT); } - mb_schar = schar_from_char(mb_c); + mb_c = schar_get_first_codepoint(mb_schar); saved_attr3 = wlv.char_attr; // save current attr wlv.char_attr = win_hl_attr(wp, HLF_AT); // overwriting char_attr n_attr3 = 1; } // At end of the text line or just after the last character. - if (mb_c == NUL && eol_hl_off == 0) { + if (mb_schar == NUL && eol_hl_off == 0) { // flag to indicate whether prevcol equals startcol of search_hl or // one of the matches bool prevcol_hl_flag = get_prevcol_hl_flag(wp, &screen_search_hl, @@ -2432,7 +2428,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl // highlight match at end of line. If it's beyond the last // char on the screen, just overwrite that one (tricky!) Not // needed when a '$' was displayed for 'list'. - if (wp->w_p_lcs_chars.eol == lcs_eol_one + if (lcs_eol_todo && ((area_attr != 0 && wlv.vcol == wlv.fromcol && (VIsual_mode != Ctrl_V || lnum == VIsual.lnum @@ -2476,7 +2472,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl } // At end of the text line. - if (mb_c == NUL) { + if (mb_schar == NUL) { // Highlight 'cursorcolumn' & 'colorcolumn' past end of the line. if (wp->w_p_wrap) { v = wlv.startrow == 0 ? wp->w_skipcol : 0; @@ -2498,8 +2494,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl bool has_virttext = false; // Make sure alignment is the same regardless // if listchars=eol:X is used or not. - int eol_skip = (wp->w_p_lcs_chars.eol == lcs_eol_one && eol_hl_off == 0 - ? 1 : 0); + int eol_skip = (lcs_eol_todo && eol_hl_off == 0 ? 1 : 0); if (has_decor) { has_virttext = decor_redraw_eol(wp, &decor_state, &wlv.line_attr, wlv.col + eol_skip); @@ -2601,7 +2596,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl // When the window is too narrow draw all "@" lines. if (leftcols_width >= wp->w_grid.cols && wp->w_p_wrap) { - win_draw_end(wp, '@', ' ', true, wlv.row, wp->w_grid.rows, HLF_AT); + win_draw_end(wp, schar_from_ascii('@'), schar_from_ascii(' '), true, wlv.row, + wp->w_grid.rows, HLF_AT); set_empty_rows(wp, wlv.row); wlv.row = endrow; } @@ -2617,17 +2613,17 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl && wlv.filler_todo <= 0 && wlv.col == grid->cols - 1 && !has_fold) { - if (has_decor && *ptr == NUL && lcs_eol_one == 0) { + if (has_decor && *ptr == NUL && lcs_eol == 0 && lcs_eol_todo) { // Tricky: there might be a virtual text just _after_ the last char decor_redraw_col(wp, (colnr_T)(ptr - line), wlv.off, false, &decor_state); } if (*ptr != NUL - || lcs_eol_one > 0 - || (wlv.n_extra > 0 && (wlv.c_extra != NUL || *wlv.p_extra != NUL)) + || (lcs_eol > 0 && lcs_eol_todo) + || (wlv.n_extra > 0 && (wlv.sc_extra != NUL || *wlv.p_extra != NUL)) || has_more_inline_virt(&wlv, ptr - line)) { - mb_c = wp->w_p_lcs_chars.ext; + mb_schar = wp->w_p_lcs_chars.ext; wlv.char_attr = win_hl_attr(wp, HLF_AT); - mb_schar = schar_from_char(mb_c); + mb_c = schar_get_first_codepoint(mb_schar); } } @@ -2784,11 +2780,11 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl || wlv.filler_todo > 0 || (wp->w_p_list && wp->w_p_lcs_chars.eol != NUL && wlv.p_extra != at_end_str) - || (wlv.n_extra != 0 && (wlv.c_extra != NUL || *wlv.p_extra != NUL)) + || (wlv.n_extra != 0 && (wlv.sc_extra != NUL || *wlv.p_extra != NUL)) || has_more_inline_virt(&wlv, ptr - line))) { bool wrap = wp->w_p_wrap // Wrapping enabled. && wlv.filler_todo <= 0 // Not drawing diff filler lines. - && lcs_eol_one != -1 // Haven't printed the lcs_eol character. + && lcs_eol_todo // Haven't printed the lcs_eol character. && wlv.row != endrow - 1 // Not the last line being displayed. && (grid->cols == Columns // Window spans the width of the screen, || ui_has(kUIMultigrid)) // or has dedicated grid. @@ -2819,13 +2815,14 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl // When not wrapping and finished diff lines, or when displayed // '$' and highlighting until last column, break here. - if ((!wp->w_p_wrap && wlv.filler_todo <= 0) || lcs_eol_one == -1) { + if ((!wp->w_p_wrap && wlv.filler_todo <= 0) || !lcs_eol_todo) { break; } // When the window is too narrow draw all "@" lines. if (wlv.col <= leftcols_width) { - win_draw_end(wp, '@', ' ', true, wlv.row, wp->w_grid.rows, HLF_AT); + win_draw_end(wp, schar_from_ascii('@'), schar_from_ascii(' '), true, wlv.row, + wp->w_grid.rows, HLF_AT); set_empty_rows(wp, wlv.row); wlv.row = endrow; } diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index 9dec2ce1e3..12f06e13cc 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -546,7 +546,7 @@ int update_screen(void) // might need to clear space on default_grid for the message area. if (type == UPD_NOT_VALID && clear_cmdline && !ui_has(kUIMessages)) { - grid_fill(&default_grid, Rows - (int)p_ch, Rows, 0, Columns, ' ', ' ', 0); + grid_clear(&default_grid, Rows - (int)p_ch, Rows, 0, Columns, 0); } ui_comp_set_screen_valid(true); @@ -1297,9 +1297,8 @@ static void draw_vsep_win(win_T *wp) // draw the vertical separator right of this window int hl = win_hl_attr(wp, HLF_C); - int c = wp->w_p_fcs_chars.vert; - grid_fill(&default_grid, wp->w_winrow, W_ENDROW(wp), - W_ENDCOL(wp), W_ENDCOL(wp) + 1, c, ' ', hl); + schar_T c = wp->w_p_fcs_chars.vert; + grid_fill(&default_grid, wp->w_winrow, W_ENDROW(wp), W_ENDCOL(wp), W_ENDCOL(wp) + 1, c, c, hl); } /// Draw the horizontal separator below window "wp" @@ -1311,9 +1310,8 @@ static void draw_hsep_win(win_T *wp) // draw the horizontal separator below this window int hl = win_hl_attr(wp, HLF_C); - int c = wp->w_p_fcs_chars.horiz; - grid_fill(&default_grid, W_ENDROW(wp), W_ENDROW(wp) + 1, - wp->w_wincol, W_ENDCOL(wp), c, c, hl); + schar_T c = wp->w_p_fcs_chars.horiz; + grid_fill(&default_grid, W_ENDROW(wp), W_ENDROW(wp) + 1, wp->w_wincol, W_ENDCOL(wp), c, c, hl); } /// Get the separator connector for specified window corner of window "wp" @@ -1321,21 +1319,19 @@ static schar_T get_corner_sep_connector(win_T *wp, WindowCorner corner) { // It's impossible for windows to be connected neither vertically nor horizontally // So if they're not vertically connected, assume they're horizontally connected - int c; if (vsep_connected(wp, corner)) { if (hsep_connected(wp, corner)) { - c = wp->w_p_fcs_chars.verthoriz; + return wp->w_p_fcs_chars.verthoriz; } else if (corner == WC_TOP_LEFT || corner == WC_BOTTOM_LEFT) { - c = wp->w_p_fcs_chars.vertright; + return wp->w_p_fcs_chars.vertright; } else { - c = wp->w_p_fcs_chars.vertleft; + return wp->w_p_fcs_chars.vertleft; } } else if (corner == WC_TOP_LEFT || corner == WC_TOP_RIGHT) { - c = wp->w_p_fcs_chars.horizdown; + return wp->w_p_fcs_chars.horizdown; } else { - c = wp->w_p_fcs_chars.horizup; + return wp->w_p_fcs_chars.horizup; } - return schar_from_char(c); } /// Draw separator connecting characters on the corners of window "wp" @@ -2384,7 +2380,7 @@ static void win_update(win_T *wp) // Last line isn't finished: Display "@@@" in the last screen line. grid_line_start(&wp->w_grid, wp->w_grid.rows - 1); grid_line_fill(0, MIN(wp->w_grid.cols, 3), wp->w_p_fcs_chars.lastline, at_attr); - grid_line_fill(3, wp->w_grid.cols, ' ', at_attr); + grid_line_fill(3, wp->w_grid.cols, schar_from_ascii(' '), at_attr); grid_line_flush(); set_empty_rows(wp, srow); wp->w_botline = lnum; @@ -2399,7 +2395,8 @@ static void win_update(win_T *wp) set_empty_rows(wp, srow); wp->w_botline = lnum; } else { - win_draw_end(wp, wp->w_p_fcs_chars.lastline, ' ', true, srow, wp->w_grid.rows, HLF_AT); + win_draw_end(wp, wp->w_p_fcs_chars.lastline, schar_from_ascii(' '), true, srow, + wp->w_grid.rows, HLF_AT); set_empty_rows(wp, srow); wp->w_botline = lnum; } @@ -2432,7 +2429,8 @@ static void win_update(win_T *wp) lastline = 0; } - win_draw_end(wp, wp->w_p_fcs_chars.eob, ' ', false, MAX(lastline, row), wp->w_grid.rows, + win_draw_end(wp, wp->w_p_fcs_chars.eob, schar_from_ascii(' '), false, MAX(lastline, row), + wp->w_grid.rows, HLF_EOB); set_empty_rows(wp, row); } @@ -2519,10 +2517,9 @@ void win_scroll_lines(win_T *wp, int row, int line_count) } } -/// Call grid_fill() with columns adjusted for 'rightleft' if needed. +/// Call grid_clear() with columns adjusted for 'rightleft' if needed. /// Return the new offset. -static int win_fill_end(win_T *wp, int c1, int c2, int off, int width, int row, int endrow, - int attr) +static int win_clear_end(win_T *wp, int off, int width, int row, int endrow, int attr) { int nn = off + width; const int endcol = wp->w_grid.cols; @@ -2532,9 +2529,9 @@ static int win_fill_end(win_T *wp, int c1, int c2, int off, int width, int row, } if (wp->w_p_rl) { - grid_fill(&wp->w_grid, row, endrow, endcol - nn, endcol - off, c1, c2, attr); + grid_clear(&wp->w_grid, row, endrow, endcol - nn, endcol - off, attr); } else { - grid_fill(&wp->w_grid, row, endrow, off, nn, c1, c2, attr); + grid_clear(&wp->w_grid, row, endrow, off, nn, attr); } return nn; @@ -2543,7 +2540,8 @@ static int win_fill_end(win_T *wp, int c1, int c2, int off, int width, int row, /// Clear lines near the end of the window and mark the unused lines with "c1". /// Use "c2" as filler character. /// When "draw_margin" is true, then draw the sign/fold/number columns. -void win_draw_end(win_T *wp, int c1, int c2, bool draw_margin, int row, int endrow, hlf_T hl) +void win_draw_end(win_T *wp, schar_T c1, schar_T c2, bool draw_margin, int row, int endrow, + hlf_T hl) { assert(hl >= 0 && hl < HLF_COUNT); int n = 0; @@ -2552,19 +2550,16 @@ void win_draw_end(win_T *wp, int c1, int c2, bool draw_margin, int row, int endr // draw the fold column int fdc = compute_foldcolumn(wp, 0); if (fdc > 0) { - n = win_fill_end(wp, ' ', ' ', n, fdc, row, endrow, - win_hl_attr(wp, HLF_FC)); + n = win_clear_end(wp, n, fdc, row, endrow, win_hl_attr(wp, HLF_FC)); } // draw the sign column int count = wp->w_scwidth; if (count > 0) { - n = win_fill_end(wp, ' ', ' ', n, SIGN_WIDTH * count, row, - endrow, win_hl_attr(wp, HLF_SC)); + n = win_clear_end(wp, n, SIGN_WIDTH * count, row, endrow, win_hl_attr(wp, HLF_SC)); } // draw the number column if ((wp->w_p_nu || wp->w_p_rnu) && vim_strchr(p_cpo, CPO_NUMCOL) == NULL) { - n = win_fill_end(wp, ' ', ' ', n, number_width(wp) + 1, row, endrow, - win_hl_attr(wp, HLF_N)); + n = win_clear_end(wp, n, number_width(wp) + 1, row, endrow, win_hl_attr(wp, HLF_N)); } } diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 6fae90134a..d843c37082 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -6881,15 +6881,8 @@ static void f_screenchar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) ScreenGrid *grid; screenchar_adjust(&grid, &row, &col); - int c; - if (row < 0 || row >= grid->rows || col < 0 || col >= grid->cols) { - c = -1; - } else { - char buf[MAX_SCHAR_SIZE + 1]; - schar_get(buf, grid_getchar(grid, row, col, NULL)); - c = utf_ptr2char(buf); - } - rettv->vval.v_number = c; + rettv->vval.v_number = (row < 0 || row >= grid->rows || col < 0 || col >= grid->cols) + ? -1 : schar_get_first_codepoint(grid_getchar(grid, row, col, NULL)); } /// "screenchars()" function @@ -8383,7 +8376,6 @@ static void f_synIDtrans(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) static void f_synconcealed(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { int syntax_flags = 0; - int cchar; int matchid = 0; char str[NUMBUFLEN]; @@ -8402,14 +8394,13 @@ static void f_synconcealed(typval_T *argvars, typval_T *rettv, EvalFuncData fptr // get the conceal character if ((syntax_flags & HL_CONCEAL) && curwin->w_p_cole < 3) { - cchar = syn_get_sub_char(); + schar_T cchar = schar_from_char(syn_get_sub_char()); if (cchar == NUL && curwin->w_p_cole == 1) { cchar = (curwin->w_p_lcs_chars.conceal == NUL) - ? ' ' - : curwin->w_p_lcs_chars.conceal; + ? schar_from_ascii(' ') : curwin->w_p_lcs_chars.conceal; } if (cchar != NUL) { - utf_char2bytes(cchar, str); + schar_get(str, cchar); } } } diff --git a/src/nvim/grid.c b/src/nvim/grid.c index b4a6987213..f529e14b35 100644 --- a/src/nvim/grid.c +++ b/src/nvim/grid.c @@ -27,6 +27,7 @@ #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/option_vars.h" +#include "nvim/optionstr.h" #include "nvim/types_defs.h" #include "nvim/ui.h" @@ -67,7 +68,7 @@ void grid_adjust(ScreenGrid **grid, int *row_off, int *col_off) } } -schar_T schar_from_str(char *str) +schar_T schar_from_str(const char *str) { if (str == NULL) { return 0; @@ -120,6 +121,13 @@ void schar_cache_clear(void) { decor_check_invalid_glyphs(); set_clear(glyph, &glyph_cache); + + // for char options we have stored the original strings. Regenerate + // the parsed schar_T values with the new clean cache. + // This must not return an error as cell widths have not changed. + if (check_chars_options()) { + abort(); + } } bool schar_high(schar_T sc) @@ -137,15 +145,39 @@ bool schar_high(schar_T sc) # define schar_idx(sc) (sc >> 8) #endif -void schar_get(char *buf_out, schar_T sc) +/// sets final NUL +size_t schar_get(char *buf_out, schar_T sc) +{ + size_t len = schar_get_adv(&buf_out, sc); + *buf_out = NUL; + return len; +} + +/// advance buf_out. do NOT set final NUL +size_t schar_get_adv(char **buf_out, schar_T sc) +{ + size_t len; + if (schar_high(sc)) { + uint32_t idx = schar_idx(sc); + assert(idx < glyph_cache.h.n_keys); + len = strlen(&glyph_cache.keys[idx]); + memcpy(*buf_out, &glyph_cache.keys[idx], len); + } else { + len = strnlen((char *)&sc, 4); + memcpy(*buf_out, (char *)&sc, len); + } + *buf_out += len; + return len; +} + +size_t schar_len(schar_T sc) { if (schar_high(sc)) { uint32_t idx = schar_idx(sc); assert(idx < glyph_cache.h.n_keys); - xstrlcpy(buf_out, &glyph_cache.keys[idx], 32); + return strlen(&glyph_cache.keys[idx]); } else { - memcpy(buf_out, (char *)&sc, 4); - buf_out[4] = NUL; + return strnlen((char *)&sc, 4); } } @@ -433,14 +465,13 @@ int grid_line_puts(int col, const char *text, int textlen, int attr) return col - start_col; } -void grid_line_fill(int start_col, int end_col, int c, int attr) +void grid_line_fill(int start_col, int end_col, schar_T sc, int attr) { end_col = MIN(end_col, grid_line_maxcol); if (start_col >= end_col) { return; } - schar_T sc = schar_from_char(c); for (int col = start_col; col < end_col; col++) { linebuf_char[col] = sc; linebuf_attr[col] = attr; @@ -532,11 +563,17 @@ void grid_line_flush_if_valid_row(void) grid_line_flush(); } +void grid_clear(ScreenGrid *grid, int start_row, int end_row, int start_col, int end_col, int attr) +{ + grid_fill(grid, start_row, end_row, start_col, end_col, schar_from_ascii(' '), + schar_from_ascii(' '), attr); +} + /// Fill the grid from "start_row" to "end_row" (exclusive), from "start_col" /// to "end_col" (exclusive) with character "c1" in first column followed by /// "c2" in the other columns. Use attributes "attr". -void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int end_col, int c1, - int c2, int attr) +void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int end_col, schar_T c1, + schar_T c2, int attr) { int row_off = 0; int col_off = 0; @@ -582,7 +619,7 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int } int col = start_col; - schar_T sc = schar_from_char(c1); + schar_T sc = c1; for (col = start_col; col < end_col; col++) { size_t off = lineoff + (size_t)col; if (grid->chars[off] != sc || grid->attrs[off] != attr || rdb_flags & RDB_NODELTA) { @@ -595,7 +632,7 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int } grid->vcols[off] = -1; if (col == start_col) { - sc = schar_from_char(c2); + sc = c2; } } if (dirty_last > dirty_first) { @@ -683,7 +720,7 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol col++; } if (col <= endcol) { - grid_fill(grid, row, row + 1, col + coloff, endcol + coloff + 1, ' ', ' ', bg_attr); + grid_clear(grid, row, row + 1, col + coloff, endcol + coloff + 1, bg_attr); } } col = endcol + 1; diff --git a/src/nvim/match.c b/src/nvim/match.c index 013ab3e6f0..3e77546800 100644 --- a/src/nvim/match.c +++ b/src/nvim/match.c @@ -666,7 +666,7 @@ bool prepare_search_hl_line(win_T *wp, linenr_T lnum, colnr_T mincol, char **lin /// is endcol. /// Return the updated search_attr. int update_search_hl(win_T *wp, linenr_T lnum, colnr_T col, char **line, match_T *search_hl, - int *has_match_conc, int *match_conc, int lcs_eol_one, bool *on_last_col, + int *has_match_conc, int *match_conc, bool lcs_eol_todo, bool *on_last_col, bool *search_attr_from_match) { matchitem_T *cur = wp->w_match_head; // points to the match list @@ -787,7 +787,7 @@ int update_search_hl(win_T *wp, linenr_T lnum, colnr_T col, char **line, match_T } } // Only highlight one character after the last column. - if (*(*line + col) == NUL && (wp->w_p_list && lcs_eol_one == -1)) { + if (*(*line + col) == NUL && (wp->w_p_list && !lcs_eol_todo)) { search_attr = 0; } return search_attr; diff --git a/src/nvim/message.c b/src/nvim/message.c index 7527349e5e..2b668db7cd 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -143,9 +143,8 @@ static int msg_grid_pos_at_flush = 0; static void ui_ext_msg_set_pos(int row, bool scrolled) { - char buf[MB_MAXCHAR + 1]; - size_t size = (size_t)utf_char2bytes(curwin->w_p_fcs_chars.msgsep, buf); - buf[size] = '\0'; + char buf[MAX_SCHAR_SIZE]; + size_t size = schar_get(buf, curwin->w_p_fcs_chars.msgsep); ui_call_msg_set_pos(msg_grid.handle, row, scrolled, (String){ .data = buf, .size = size }); } @@ -1798,12 +1797,12 @@ void str2specialbuf(const char *sp, char *buf, size_t len) /// print line for :print or :list command void msg_prt_line(const char *s, bool list) { - int c; + schar_T sc; int col = 0; int n_extra = 0; - int c_extra = 0; - int c_final = 0; - const char *p_extra = NULL; // init to make SASC shut up + schar_T sc_extra = 0; + schar_T sc_final = 0; + const char *p_extra = NULL; // init to make SASC shut up. ASCII only! int n; int attr = 0; const char *lead = NULL; @@ -1845,13 +1844,13 @@ void msg_prt_line(const char *s, bool list) while (!got_int) { if (n_extra > 0) { n_extra--; - if (n_extra == 0 && c_final) { - c = c_final; - } else if (c_extra) { - c = c_extra; + if (n_extra == 0 && sc_final) { + sc = sc_final; + } else if (sc_extra) { + sc = sc_extra; } else { assert(p_extra != NULL); - c = (unsigned char)(*p_extra++); + sc = schar_from_ascii((unsigned char)(*p_extra++)); } } else if ((l = utfc_ptr2len(s)) > 1) { col += utf_ptr2cells(s); @@ -1859,10 +1858,8 @@ void msg_prt_line(const char *s, bool list) if (l >= MB_MAXBYTES) { xstrlcpy(buf, "?", sizeof(buf)); } else if (curwin->w_p_lcs_chars.nbsp != NUL && list - && (utf_ptr2char(s) == 160 - || utf_ptr2char(s) == 0x202f)) { - int len = utf_char2bytes(curwin->w_p_lcs_chars.nbsp, buf); - buf[len] = NUL; + && (utf_ptr2char(s) == 160 || utf_ptr2char(s) == 0x202f)) { + schar_get(buf, curwin->w_p_lcs_chars.nbsp); } else { memmove(buf, s, (size_t)l); buf[l] = NUL; @@ -1872,7 +1869,9 @@ void msg_prt_line(const char *s, bool list) continue; } else { attr = 0; - c = (uint8_t)(*s++); + int c = (uint8_t)(*s++); + sc_extra = NUL; + sc_final = NUL; if (list) { in_multispace = c == ' ' && (*s == ' ' || (col > 0 && s[-2] == ' ')); @@ -1882,74 +1881,72 @@ void msg_prt_line(const char *s, bool list) } if (c == TAB && (!list || curwin->w_p_lcs_chars.tab1)) { // tab amount depends on current column - n_extra = tabstop_padding(col, - curbuf->b_p_ts, + n_extra = tabstop_padding(col, curbuf->b_p_ts, curbuf->b_p_vts_array) - 1; if (!list) { - c = ' '; - c_extra = ' '; - c_final = NUL; + sc = schar_from_ascii(' '); + sc_extra = schar_from_ascii(' '); } else { - c = (n_extra == 0 && curwin->w_p_lcs_chars.tab3) - ? curwin->w_p_lcs_chars.tab3 - : curwin->w_p_lcs_chars.tab1; - c_extra = curwin->w_p_lcs_chars.tab2; - c_final = curwin->w_p_lcs_chars.tab3; + sc = (n_extra == 0 && curwin->w_p_lcs_chars.tab3) + ? curwin->w_p_lcs_chars.tab3 + : curwin->w_p_lcs_chars.tab1; + sc_extra = curwin->w_p_lcs_chars.tab2; + sc_final = curwin->w_p_lcs_chars.tab3; attr = HL_ATTR(HLF_0); } - } else if (c == 160 && list && curwin->w_p_lcs_chars.nbsp != NUL) { - c = curwin->w_p_lcs_chars.nbsp; - attr = HL_ATTR(HLF_0); } else if (c == NUL && list && curwin->w_p_lcs_chars.eol != NUL) { p_extra = ""; - c_extra = NUL; - c_final = NUL; n_extra = 1; - c = curwin->w_p_lcs_chars.eol; + sc = curwin->w_p_lcs_chars.eol; attr = HL_ATTR(HLF_AT); s--; } else if (c != NUL && (n = byte2cells(c)) > 1) { n_extra = n - 1; p_extra = transchar_byte_buf(NULL, c); - c_extra = NUL; - c_final = NUL; - c = (unsigned char)(*p_extra++); + sc = schar_from_ascii(*p_extra++); // Use special coloring to be able to distinguish <hex> from // the same in plain text. attr = HL_ATTR(HLF_0); } else if (c == ' ') { if (lead != NULL && s <= lead && in_multispace && curwin->w_p_lcs_chars.leadmultispace != NULL) { - c = curwin->w_p_lcs_chars.leadmultispace[multispace_pos++]; + sc = curwin->w_p_lcs_chars.leadmultispace[multispace_pos++]; if (curwin->w_p_lcs_chars.leadmultispace[multispace_pos] == NUL) { multispace_pos = 0; } attr = HL_ATTR(HLF_0); } else if (lead != NULL && s <= lead && curwin->w_p_lcs_chars.lead != NUL) { - c = curwin->w_p_lcs_chars.lead; + sc = curwin->w_p_lcs_chars.lead; attr = HL_ATTR(HLF_0); } else if (trail != NULL && s > trail) { - c = curwin->w_p_lcs_chars.trail; + sc = curwin->w_p_lcs_chars.trail; attr = HL_ATTR(HLF_0); } else if (in_multispace && curwin->w_p_lcs_chars.multispace != NULL) { - c = curwin->w_p_lcs_chars.multispace[multispace_pos++]; + sc = curwin->w_p_lcs_chars.multispace[multispace_pos++]; if (curwin->w_p_lcs_chars.multispace[multispace_pos] == NUL) { multispace_pos = 0; } attr = HL_ATTR(HLF_0); } else if (list && curwin->w_p_lcs_chars.space != NUL) { - c = curwin->w_p_lcs_chars.space; + sc = curwin->w_p_lcs_chars.space; attr = HL_ATTR(HLF_0); + } else { + sc = schar_from_ascii(' '); // SPACE! } + } else { + sc = schar_from_ascii(c); } } - if (c == NUL) { + if (sc == NUL) { break; } - msg_putchar_attr(c, attr); + // TODO(bfredl): this is such baloney. need msg_put_schar + char buf[MAX_SCHAR_SIZE]; + schar_get(buf, sc); + msg_puts_attr(buf, attr); col++; } msg_clr_eos(); @@ -2308,7 +2305,7 @@ void msg_scroll_up(bool may_throttle, bool zerocmd) msg_grid.dirty_col[msg_grid.rows - 1] = 0; } - grid_fill(&msg_grid_adj, Rows - 1, Rows, 0, Columns, ' ', ' ', HL_ATTR(HLF_MSG)); + grid_clear(&msg_grid_adj, Rows - 1, Rows, 0, Columns, HL_ATTR(HLF_MSG)); } /// Send throttled message output to UI clients @@ -2823,16 +2820,14 @@ static bool do_more_prompt(int typed_char) if (toscroll == -1 && !to_redraw) { grid_ins_lines(&msg_grid_adj, 0, 1, Rows, 0, Columns); - grid_fill(&msg_grid_adj, 0, 1, 0, Columns, ' ', ' ', - HL_ATTR(HLF_MSG)); + grid_clear(&msg_grid_adj, 0, 1, 0, Columns, HL_ATTR(HLF_MSG)); // display line at top disp_sb_line(0, mp); } else { // redisplay all lines // TODO(bfredl): this case is not optimized (though only concerns // event fragmentation, not unnecessary scroll events). - grid_fill(&msg_grid_adj, 0, Rows, 0, Columns, ' ', ' ', - HL_ATTR(HLF_MSG)); + grid_clear(&msg_grid_adj, 0, Rows, 0, Columns, HL_ATTR(HLF_MSG)); for (int i = 0; mp != NULL && i < Rows - 1; i++) { mp = disp_sb_line(i, mp); msg_scrolled++; @@ -2858,8 +2853,7 @@ static bool do_more_prompt(int typed_char) // scroll up, display line at bottom msg_scroll_up(true, false); inc_msg_scrolled(); - grid_fill(&msg_grid_adj, Rows - 2, Rows - 1, 0, Columns, ' ', ' ', - HL_ATTR(HLF_MSG)); + grid_clear(&msg_grid_adj, Rows - 2, Rows - 1, 0, Columns, HL_ATTR(HLF_MSG)); mp_last = disp_sb_line(Rows - 2, mp_last); toscroll--; } @@ -2867,8 +2861,7 @@ static bool do_more_prompt(int typed_char) if (toscroll <= 0) { // displayed the requested text, more prompt again - grid_fill(&msg_grid_adj, Rows - 1, Rows, 0, Columns, ' ', ' ', - HL_ATTR(HLF_MSG)); + grid_clear(&msg_grid_adj, Rows - 1, Rows, 0, Columns, HL_ATTR(HLF_MSG)); msg_moremsg(false); continue; } @@ -2881,8 +2874,7 @@ static bool do_more_prompt(int typed_char) } // clear the --more-- message - grid_fill(&msg_grid_adj, Rows - 1, Rows, 0, Columns, ' ', ' ', - HL_ATTR(HLF_MSG)); + grid_clear(&msg_grid_adj, Rows - 1, Rows, 0, Columns, HL_ATTR(HLF_MSG)); redraw_cmdline = true; clear_cmdline = false; mode_displayed = false; @@ -2966,10 +2958,8 @@ void msg_clr_eos_force(void) } } - grid_fill(&msg_grid_adj, msg_row, msg_row + 1, msg_startcol, msg_endcol, - ' ', ' ', HL_ATTR(HLF_MSG)); - grid_fill(&msg_grid_adj, msg_row + 1, Rows, 0, Columns, - ' ', ' ', HL_ATTR(HLF_MSG)); + grid_clear(&msg_grid_adj, msg_row, msg_row + 1, msg_startcol, msg_endcol, HL_ATTR(HLF_MSG)); + grid_clear(&msg_grid_adj, msg_row + 1, Rows, 0, Columns, HL_ATTR(HLF_MSG)); redraw_cmdline = true; // overwritten the command line if (msg_row < Rows - 1 || msg_col == 0) { diff --git a/src/nvim/option.c b/src/nvim/option.c index 495a6819f9..a46e6fed34 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -1696,10 +1696,10 @@ static void didset_options2(void) highlight_changed(); // Parse default for 'fillchars'. - set_fillchars_option(curwin, curwin->w_p_fcs, true); + set_chars_option(curwin, curwin->w_p_fcs, kFillchars, true); // Parse default for 'listchars'. - set_listchars_option(curwin, curwin->w_p_lcs, true); + set_chars_option(curwin, curwin->w_p_lcs, kListchars, true); // Parse default for 'wildmode'. check_opt_wim(); @@ -4991,8 +4991,8 @@ void didset_window_options(win_T *wp, bool valid_cursor) check_colorcolumn(wp); briopt_check(wp); fill_culopt_flags(NULL, wp); - set_fillchars_option(wp, wp->w_p_fcs, true); - set_listchars_option(wp, wp->w_p_lcs, true); + set_chars_option(wp, wp->w_p_fcs, kFillchars, true); + set_chars_option(wp, wp->w_p_lcs, kListchars, true); parse_winhl_opt(wp); // sets w_hl_needs_update also for w_p_winbl check_blending(wp); set_winbar_win(wp, false, valid_cursor); diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c index 9e4c0e6b0f..a1f2d69761 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -21,6 +21,7 @@ #include "nvim/fold.h" #include "nvim/gettext.h" #include "nvim/globals.h" +#include "nvim/grid.h" #include "nvim/highlight_group.h" #include "nvim/indent.h" #include "nvim/indent_c.h" @@ -876,18 +877,15 @@ int expand_set_casemap(optexpand_T *args, int *numMatches, char ***matches) } /// The global 'listchars' or 'fillchars' option is changed. -static const char *did_set_global_listfillchars(win_T *win, char *val, bool opt_lcs, int opt_flags) +static const char *did_set_global_chars_option(win_T *win, char *val, CharsOption what, + int opt_flags) { const char *errmsg = NULL; - char **local_ptr = opt_lcs ? &win->w_p_lcs : &win->w_p_fcs; + char **local_ptr = (what == kListchars) ? &win->w_p_lcs : &win->w_p_fcs; // only apply the global value to "win" when it does not have a // local value - if (opt_lcs) { - errmsg = set_listchars_option(win, val, **local_ptr == NUL || !(opt_flags & OPT_GLOBAL)); - } else { - errmsg = set_fillchars_option(win, val, **local_ptr == NUL || !(opt_flags & OPT_GLOBAL)); - } + errmsg = set_chars_option(win, val, what, **local_ptr == NUL || !(opt_flags & OPT_GLOBAL)); if (errmsg != NULL) { return errmsg; } @@ -903,14 +901,9 @@ static const char *did_set_global_listfillchars(win_T *win, char *val, bool opt_ // again, it was changed when setting the global value. // If no error was returned above, we don't expect an error // here, so ignore the return value. - if (opt_lcs) { - if (*wp->w_p_lcs == NUL) { - set_listchars_option(wp, wp->w_p_lcs, true); - } - } else { - if (*wp->w_p_fcs == NUL) { - set_fillchars_option(wp, wp->w_p_fcs, true); - } + char *opt = (what == kListchars) ? wp->w_p_lcs : wp->w_p_fcs; + if (*opt == NUL) { + set_chars_option(wp, opt, what, true); } } @@ -926,13 +919,14 @@ const char *did_set_chars_option(optset_T *args) char **varp = (char **)args->os_varp; const char *errmsg = NULL; - if (varp == &p_lcs // global 'listchars' - || varp == &p_fcs) { // global 'fillchars' - errmsg = did_set_global_listfillchars(win, *varp, varp == &p_lcs, args->os_flags); + if (varp == &p_lcs) { // global 'listchars' + errmsg = did_set_global_chars_option(win, *varp, kListchars, args->os_flags); + } else if (varp == &p_fcs) { // global 'fillchars' + errmsg = did_set_global_chars_option(win, *varp, kFillchars, args->os_flags); } else if (varp == &win->w_p_lcs) { // local 'listchars' - errmsg = set_listchars_option(win, *varp, true); + errmsg = set_chars_option(win, *varp, kListchars, true); } else if (varp == &win->w_p_fcs) { // local 'fillchars' - errmsg = set_fillchars_option(win, *varp, true); + errmsg = set_chars_option(win, *varp, kFillchars, true); } return errmsg; @@ -2603,7 +2597,7 @@ static const char e_conflicts_with_value_of_fillchars[] /// Calls mb_cptr2char_adv(p) and returns the character. /// If "p" starts with "\x", "\u" or "\U" the hex or unicode value is used. /// Returns 0 for invalid hex or invalid UTF-8 byte. -static int get_encoded_char_adv(const char **p) +static schar_T get_encoded_char_adv(const char **p) { const char *s = *p; @@ -2618,71 +2612,69 @@ static int get_encoded_char_adv(const char **p) num = num * 256 + n; } *p += 2; - return (int)num; + return (char2cells((int)num) > 1) ? 0 : schar_from_char((int)num); } - // TODO(bfredl): use schar_T representation and utfc_ptr2len - int clen = utf_ptr2len(s); - int c = mb_cptr2char_adv(p); - if (clen == 1 && c > 127) { // Invalid UTF-8 byte - return 0; - } - return c; + int clen = utfc_ptr2len(s); + int firstc; + schar_T c = utfc_ptr2schar(s, &firstc); + *p += clen; + // Invalid UTF-8 byte or doublewidth not allowed + return ((clen == 1 && firstc > 127) || char2cells(firstc) > 1) ? 0 : c; } struct chars_tab { - int *cp; ///< char value + schar_T *cp; ///< char value const char *name; ///< char id - int def; ///< default value - int fallback; ///< default value when "def" isn't single-width + const char *def; ///< default value + const char *fallback; ///< default value when "def" isn't single-width }; static fcs_chars_T fcs_chars; static const struct chars_tab fcs_tab[] = { - { &fcs_chars.stl, "stl", ' ', NUL }, - { &fcs_chars.stlnc, "stlnc", ' ', NUL }, - { &fcs_chars.wbr, "wbr", ' ', NUL }, - { &fcs_chars.horiz, "horiz", 0x2500, '-' }, // ─ - { &fcs_chars.horizup, "horizup", 0x2534, '-' }, // ┴ - { &fcs_chars.horizdown, "horizdown", 0x252c, '-' }, // ┬ - { &fcs_chars.vert, "vert", 0x2502, '|' }, // │ - { &fcs_chars.vertleft, "vertleft", 0x2524, '|' }, // ┤ - { &fcs_chars.vertright, "vertright", 0x251c, '|' }, // ├ - { &fcs_chars.verthoriz, "verthoriz", 0x253c, '+' }, // ┼ - { &fcs_chars.fold, "fold", 0x00b7, '-' }, // · - { &fcs_chars.foldopen, "foldopen", '-', NUL }, - { &fcs_chars.foldclosed, "foldclose", '+', NUL }, - { &fcs_chars.foldsep, "foldsep", 0x2502, '|' }, // │ - { &fcs_chars.diff, "diff", '-', NUL }, - { &fcs_chars.msgsep, "msgsep", ' ', NUL }, - { &fcs_chars.eob, "eob", '~', NUL }, - { &fcs_chars.lastline, "lastline", '@', NUL }, + { &fcs_chars.stl, "stl", " ", NULL }, + { &fcs_chars.stlnc, "stlnc", " ", NULL }, + { &fcs_chars.wbr, "wbr", " ", NULL }, + { &fcs_chars.horiz, "horiz", "─", "-" }, + { &fcs_chars.horizup, "horizup", "┴", "-" }, + { &fcs_chars.horizdown, "horizdown", "┬", "-" }, + { &fcs_chars.vert, "vert", "│", "|" }, + { &fcs_chars.vertleft, "vertleft", "┤", "|" }, + { &fcs_chars.vertright, "vertright", "├", "|" }, + { &fcs_chars.verthoriz, "verthoriz", "┼", "+" }, + { &fcs_chars.fold, "fold", "·", "-" }, + { &fcs_chars.foldopen, "foldopen", "-", NULL }, + { &fcs_chars.foldclosed, "foldclose", "+", NULL }, + { &fcs_chars.foldsep, "foldsep", "│", "|" }, + { &fcs_chars.diff, "diff", "-", NULL }, + { &fcs_chars.msgsep, "msgsep", " ", NULL }, + { &fcs_chars.eob, "eob", "~", NULL }, + { &fcs_chars.lastline, "lastline", "@", NULL }, }; static lcs_chars_T lcs_chars; static const struct chars_tab lcs_tab[] = { - { &lcs_chars.eol, "eol", NUL, NUL }, - { &lcs_chars.ext, "extends", NUL, NUL }, - { &lcs_chars.nbsp, "nbsp", NUL, NUL }, - { &lcs_chars.prec, "precedes", NUL, NUL }, - { &lcs_chars.space, "space", NUL, NUL }, - { &lcs_chars.tab2, "tab", NUL, NUL }, - { &lcs_chars.lead, "lead", NUL, NUL }, - { &lcs_chars.trail, "trail", NUL, NUL }, - { &lcs_chars.conceal, "conceal", NUL, NUL }, - { NULL, "multispace", NUL, NUL }, - { NULL, "leadmultispace", NUL, NUL }, + { &lcs_chars.eol, "eol", NULL, NULL }, + { &lcs_chars.ext, "extends", NULL, NULL }, + { &lcs_chars.nbsp, "nbsp", NULL, NULL }, + { &lcs_chars.prec, "precedes", NULL, NULL }, + { &lcs_chars.space, "space", NULL, NULL }, + { &lcs_chars.tab2, "tab", NULL, NULL }, + { &lcs_chars.lead, "lead", NULL, NULL }, + { &lcs_chars.trail, "trail", NULL, NULL }, + { &lcs_chars.conceal, "conceal", NULL, NULL }, + { NULL, "multispace", NULL, NULL }, + { NULL, "leadmultispace", NULL, NULL }, }; /// Handle setting 'listchars' or 'fillchars'. /// Assume monocell characters /// /// @param value points to either the global or the window-local value. -/// @param is_listchars is true for "listchars" and false for "fillchars". +/// @param what kListchars or kFillchars /// @param apply if false, do not store the flags, only check for errors. /// @return error message, NULL if it's OK. -static const char *set_chars_option(win_T *wp, const char *value, const bool is_listchars, - const bool apply) +const char *set_chars_option(win_T *wp, const char *value, CharsOption what, bool apply) { const char *last_multispace = NULL; // Last occurrence of "multispace:" const char *last_lmultispace = NULL; // Last occurrence of "leadmultispace:" @@ -2691,7 +2683,7 @@ static const char *set_chars_option(win_T *wp, const char *value, const bool is_ const struct chars_tab *tab; int entries; - if (is_listchars) { + if (what == kListchars) { tab = lcs_tab; entries = ARRAY_SIZE(lcs_tab); if (wp->w_p_lcs[0] == NUL) { @@ -2713,23 +2705,24 @@ static const char *set_chars_option(win_T *wp, const char *value, const bool is_ if (tab[i].cp != NULL) { // XXX: Characters taking 2 columns is forbidden (TUI limitation?). // Set old defaults in this case. - *(tab[i].cp) = char2cells(tab[i].def) == 1 ? tab[i].def : tab[i].fallback; + *(tab[i].cp) = schar_from_str((tab[i].def && ptr2cells(tab[i].def) == 1) + ? tab[i].def : tab[i].fallback); } } - if (is_listchars) { + if (what == kListchars) { lcs_chars.tab1 = NUL; lcs_chars.tab3 = NUL; if (multispace_len > 0) { - lcs_chars.multispace = xmalloc(((size_t)multispace_len + 1) * sizeof(int)); + lcs_chars.multispace = xmalloc(((size_t)multispace_len + 1) * sizeof(schar_T)); lcs_chars.multispace[multispace_len] = NUL; } else { lcs_chars.multispace = NULL; } if (lead_multispace_len > 0) { - lcs_chars.leadmultispace = xmalloc(((size_t)lead_multispace_len + 1) * sizeof(int)); + lcs_chars.leadmultispace = xmalloc(((size_t)lead_multispace_len + 1) * sizeof(schar_T)); lcs_chars.leadmultispace[lead_multispace_len] = NUL; } else { lcs_chars.leadmultispace = NULL; @@ -2748,15 +2741,15 @@ static const char *set_chars_option(win_T *wp, const char *value, const bool is_ continue; } - if (is_listchars && strcmp(tab[i].name, "multispace") == 0) { + if (what == kListchars && strcmp(tab[i].name, "multispace") == 0) { const char *s = p + len + 1; if (round == 0) { // Get length of lcs-multispace string in the first round last_multispace = p; multispace_len = 0; while (*s != NUL && *s != ',') { - int c1 = get_encoded_char_adv(&s); - if (c1 == 0 || char2cells(c1) > 1) { + schar_T c1 = get_encoded_char_adv(&s); + if (c1 == 0) { return e_invarg; } multispace_len++; @@ -2769,7 +2762,7 @@ static const char *set_chars_option(win_T *wp, const char *value, const bool is_ } else { int multispace_pos = 0; while (*s != NUL && *s != ',') { - int c1 = get_encoded_char_adv(&s); + schar_T c1 = get_encoded_char_adv(&s); if (p == last_multispace) { lcs_chars.multispace[multispace_pos++] = c1; } @@ -2779,15 +2772,15 @@ static const char *set_chars_option(win_T *wp, const char *value, const bool is_ break; } - if (is_listchars && strcmp(tab[i].name, "leadmultispace") == 0) { + if (what == kListchars && strcmp(tab[i].name, "leadmultispace") == 0) { const char *s = p + len + 1; if (round == 0) { // get length of lcs-leadmultispace string in first round last_lmultispace = p; lead_multispace_len = 0; while (*s != NUL && *s != ',') { - int c1 = get_encoded_char_adv(&s); - if (c1 == 0 || char2cells(c1) > 1) { + schar_T c1 = get_encoded_char_adv(&s); + if (c1 == 0) { return e_invarg; } lead_multispace_len++; @@ -2800,7 +2793,7 @@ static const char *set_chars_option(win_T *wp, const char *value, const bool is_ } else { int multispace_pos = 0; while (*s != NUL && *s != ',') { - int c1 = get_encoded_char_adv(&s); + schar_T c1 = get_encoded_char_adv(&s); if (p == last_lmultispace) { lcs_chars.leadmultispace[multispace_pos++] = c1; } @@ -2811,23 +2804,23 @@ static const char *set_chars_option(win_T *wp, const char *value, const bool is_ } const char *s = p + len + 1; - int c1 = get_encoded_char_adv(&s); - if (c1 == 0 || char2cells(c1) > 1) { + schar_T c1 = get_encoded_char_adv(&s); + if (c1 == 0) { return e_invarg; } - int c2 = 0; - int c3 = 0; + schar_T c2 = 0; + schar_T c3 = 0; if (tab[i].cp == &lcs_chars.tab2) { if (*s == NUL) { return e_invarg; } c2 = get_encoded_char_adv(&s); - if (c2 == 0 || char2cells(c2) > 1) { + if (c2 == 0) { return e_invarg; } if (!(*s == ',' || *s == NUL)) { c3 = get_encoded_char_adv(&s); - if (c3 == 0 || char2cells(c3) > 1) { + if (c3 == 0) { return e_invarg; } } @@ -2859,7 +2852,7 @@ static const char *set_chars_option(win_T *wp, const char *value, const bool is_ } if (apply) { - if (is_listchars) { + if (what == kListchars) { xfree(wp->w_p_lcs_chars.multispace); xfree(wp->w_p_lcs_chars.leadmultispace); wp->w_p_lcs_chars = lcs_chars; @@ -2871,18 +2864,6 @@ static const char *set_chars_option(win_T *wp, const char *value, const bool is_ return NULL; // no error } -/// Handle the new value of 'fillchars'. -const char *set_fillchars_option(win_T *wp, char *val, bool apply) -{ - return set_chars_option(wp, val, false, apply); -} - -/// Handle the new value of 'listchars'. -const char *set_listchars_option(win_T *wp, char *val, bool apply) -{ - return set_chars_option(wp, val, true, apply); -} - /// Function given to ExpandGeneric() to obtain possible arguments of the /// 'fillchars' option. char *get_fillchars_name(expand_T *xp FUNC_ATTR_UNUSED, int idx) @@ -2911,17 +2892,17 @@ char *get_listchars_name(expand_T *xp FUNC_ATTR_UNUSED, int idx) /// @return an untranslated error message if any of them is invalid, NULL otherwise. const char *check_chars_options(void) { - if (set_listchars_option(curwin, p_lcs, false) != NULL) { + if (set_chars_option(curwin, p_lcs, kListchars, false) != NULL) { return e_conflicts_with_value_of_listchars; } - if (set_fillchars_option(curwin, p_fcs, false) != NULL) { + if (set_chars_option(curwin, p_fcs, kFillchars, false) != NULL) { return e_conflicts_with_value_of_fillchars; } FOR_ALL_TAB_WINDOWS(tp, wp) { - if (set_listchars_option(wp, wp->w_p_lcs, true) != NULL) { + if (set_chars_option(wp, wp->w_p_lcs, kListchars, true) != NULL) { return e_conflicts_with_value_of_listchars; } - if (set_fillchars_option(wp, wp->w_p_fcs, true) != NULL) { + if (set_chars_option(wp, wp->w_p_fcs, kFillchars, true) != NULL) { return e_conflicts_with_value_of_fillchars; } } diff --git a/src/nvim/optionstr.h b/src/nvim/optionstr.h index ae35d706aa..7001f18098 100644 --- a/src/nvim/optionstr.h +++ b/src/nvim/optionstr.h @@ -6,6 +6,11 @@ #include "nvim/option_defs.h" // IWYU pragma: keep #include "nvim/types_defs.h" // IWYU pragma: keep +typedef enum { + kFillchars, + kListchars, +} CharsOption; + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "optionstr.h.generated.h" #endif diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c index 04d95e1dc1..a5669d6202 100644 --- a/src/nvim/popupmenu.c +++ b/src/nvim/popupmenu.c @@ -629,19 +629,19 @@ void pum_redraw(void) } if (pum_rl) { - grid_line_fill(col_off - pum_base_width - n + 1, grid_col + 1, ' ', attr); + grid_line_fill(col_off - pum_base_width - n + 1, grid_col + 1, schar_from_ascii(' '), attr); grid_col = col_off - pum_base_width - n + 1; } else { - grid_line_fill(grid_col, col_off + pum_base_width + n, ' ', attr); + grid_line_fill(grid_col, col_off + pum_base_width + n, schar_from_ascii(' '), attr); grid_col = col_off + pum_base_width + n; } totwidth = pum_base_width + n; } if (pum_rl) { - grid_line_fill(col_off - pum_width + 1, grid_col + 1, ' ', attr); + grid_line_fill(col_off - pum_width + 1, grid_col + 1, schar_from_ascii(' '), attr); } else { - grid_line_fill(grid_col, col_off + pum_width, ' ', attr); + grid_line_fill(grid_col, col_off + pum_width, schar_from_ascii(' '), attr); } if (pum_scrollbar > 0) { diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index 2a5514b56e..1fd10f0b6b 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -58,7 +58,6 @@ typedef enum { /// If inversion is possible we use it. Else '=' characters are used. void win_redr_status(win_T *wp) { - int fillchar; int attr; bool is_stl_global = global_stl_height() > 0; static bool busy = false; @@ -84,7 +83,7 @@ void win_redr_status(win_T *wp) // redraw custom status line redraw_custom_statusline(wp); } else { - fillchar = fillchar_status(&attr, wp); + schar_T fillchar = fillchar_status(&attr, wp); const int stl_width = is_stl_global ? Columns : wp->w_width; get_trans_bufname(wp->w_buffer); @@ -169,6 +168,7 @@ void win_redr_status(win_T *wp) // May need to draw the character below the vertical separator. if (wp->w_vsep_width != 0 && wp->w_status_height != 0 && redrawing()) { + schar_T fillchar; if (stl_connected(wp)) { fillchar = fillchar_status(&attr, wp); } else { @@ -176,7 +176,7 @@ void win_redr_status(win_T *wp) fillchar = wp->w_p_fcs_chars.vert; } grid_line_start(&default_grid, W_ENDROW(wp)); - grid_line_put_schar(W_ENDCOL(wp), schar_from_char(fillchar), attr); + grid_line_put_schar(W_ENDCOL(wp), fillchar, attr); grid_line_flush(); } busy = false; @@ -291,7 +291,7 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) int row; int col = 0; int maxwidth; - int fillchar; + schar_T fillchar; char buf[MAXPATHL]; char transbuf[MAXPATHL]; char *stl; @@ -316,7 +316,7 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) // Use 'tabline'. Always at the first line of the screen. stl = p_tal; row = 0; - fillchar = ' '; + fillchar = schar_from_ascii(' '); attr = HL_ATTR(HLF_TPF); maxwidth = Columns; opt_idx = kOptTabline; @@ -374,7 +374,7 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) grid = &msg_grid_adj; row = Rows - 1; maxwidth--; // writing in last column may cause scrolling - fillchar = ' '; + fillchar = schar_from_ascii(' '); attr = HL_ATTR(HLF_MSG); } } else { @@ -513,7 +513,7 @@ void win_redr_ruler(win_T *wp) && *ml_get_buf(wp->w_buffer, wp->w_cursor.lnum) == NUL; int width; - int fillchar; + schar_T fillchar; int attr; int off; bool part_of_status = false; @@ -529,7 +529,7 @@ void win_redr_ruler(win_T *wp) width = Columns; part_of_status = true; } else { - fillchar = ' '; + fillchar = schar_from_ascii(' '); attr = HL_ATTR(HLF_MSG); width = Columns; off = 0; @@ -577,7 +577,7 @@ void win_redr_ruler(win_T *wp) if (this_ru_col + o < width) { // Need at least 3 chars left for get_rel_pos() + NUL. while (this_ru_col + o < width && RULER_BUF_LEN > i + 4) { - i += utf_char2bytes(fillchar, buffer + i); + i += (int)schar_get(buffer + i, fillchar); o++; } get_rel_pos(wp, buffer + i, RULER_BUF_LEN - i); @@ -612,18 +612,15 @@ void win_redr_ruler(win_T *wp) } /// Get the character to use in a status line. Get its attributes in "*attr". -int fillchar_status(int *attr, win_T *wp) +schar_T fillchar_status(int *attr, win_T *wp) { - int fill; - bool is_curwin = (wp == curwin); - if (is_curwin) { + if (wp == curwin) { *attr = win_hl_attr(wp, HLF_S); - fill = wp->w_p_fcs_chars.stl; + return wp->w_p_fcs_chars.stl; } else { *attr = win_hl_attr(wp, HLF_SNC); - fill = wp->w_p_fcs_chars.stlnc; + return wp->w_p_fcs_chars.stlnc; } - return fill; } /// Redraw the status line according to 'statusline' and take care of any @@ -724,7 +721,6 @@ void draw_tabline(void) int col = 0; win_T *cwp; int wincount; - int c; grid_line_start(&default_grid, 0); FOR_ALL_TABS(tp) { tabcount++; @@ -826,12 +822,8 @@ void draw_tabline(void) } } - if (use_sep_chars) { - c = '_'; - } else { - c = ' '; - } - grid_line_fill(col, Columns, c, attr_fill); + char c = use_sep_chars ? '_' : ' '; + grid_line_fill(col, Columns, schar_from_ascii(c), attr_fill); // Draw the 'showcmd' information if 'showcmdloc' == "tabline". if (p_sc && *p_sloc == 't') { @@ -878,7 +870,7 @@ int build_statuscol_str(win_T *wp, linenr_T lnum, linenr_T relnum, char *buf, st StlClickRecord *clickrec; char *stc = xstrdup(wp->w_p_stc); - int width = build_stl_str_hl(wp, buf, MAXPATHL, stc, kOptStatuscolumn, OPT_LOCAL, ' ', + int width = build_stl_str_hl(wp, buf, MAXPATHL, stc, kOptStatuscolumn, OPT_LOCAL, 0, stcp->width, &stcp->hlrec, fillclick ? &clickrec : NULL, stcp); xfree(stc); @@ -920,7 +912,7 @@ int build_statuscol_str(win_T *wp, linenr_T lnum, linenr_T relnum, char *buf, st /// /// @return The final width of the statusline int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex opt_idx, - int opt_scope, int fillchar, int maxwidth, stl_hlrec_t **hltab, + int opt_scope, schar_T fillchar, int maxwidth, stl_hlrec_t **hltab, StlClickRecord **tabtab, statuscol_T *stcp) { static size_t stl_items_len = 20; // Initial value, grows as needed. @@ -977,7 +969,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op } if (fillchar == 0) { - fillchar = ' '; + fillchar = schar_from_ascii(' '); } // The cursor in windows other than the current one isn't always @@ -1175,7 +1167,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op out_p = out_p - n + 1; // Fill up space left over by half a double-wide char. while (++group_len < stl_items[stl_groupitems[groupdepth]].minwid) { - out_p += utf_char2bytes(fillchar, out_p); + schar_get_adv(&out_p, fillchar); } // } @@ -1198,13 +1190,13 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op if (min_group_width < 0) { min_group_width = 0 - min_group_width; while (group_len++ < min_group_width && out_p < out_end_p) { - out_p += utf_char2bytes(fillchar, out_p); + schar_get_adv(&out_p, fillchar); } // If the group is right-aligned, shift everything to the right and // prepend with filler characters. } else { // { Move the group to the right - group_len = (min_group_width - group_len) * utf_char2len(fillchar); + group_len = (min_group_width - group_len) * (int)schar_len(fillchar); memmove(t + group_len, t, (size_t)(out_p - t)); if (out_p + group_len >= (out_end_p + 1)) { group_len = out_end_p - out_p; @@ -1219,7 +1211,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op // Prepend the fill characters for (; group_len > 0; group_len--) { - t += utf_char2bytes(fillchar, t); + schar_get_adv(&t, fillchar); } } } @@ -1647,8 +1639,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op // TODO(bfredl): this is very backwards. we must support schar_T // being used directly in 'statuscolumn' for (int i = 0; i < fdc; i++) { - schar_get(out_p + buflen, fold_buf[i]); - buflen += strlen(out_p + buflen); + buflen += schar_get(out_p + buflen, fold_buf[i]); } p = out_p; } @@ -1813,7 +1804,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op if (l + 1 == minwid && fillchar == '-' && ascii_isdigit(*t)) { *out_p++ = ' '; } else { - out_p += utf_char2bytes(fillchar, out_p); + schar_get_adv(&out_p, fillchar); } } minwid = 0; @@ -1836,7 +1827,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op // digit follows. if (fillable && *t == ' ' && (!ascii_isdigit(*(t + 1)) || fillchar != '-')) { - out_p += utf_char2bytes(fillchar, out_p); + schar_get_adv(&out_p, fillchar); } else { *out_p++ = *t; } @@ -1853,7 +1844,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op // For left-aligned items, fill any remaining space with the fillchar for (; l < minwid && out_p < out_end_p; l++) { - out_p += utf_char2bytes(fillchar, out_p); + schar_get_adv(&out_p, fillchar); } // Otherwise if the item is a number, copy that to the output buffer. @@ -2070,8 +2061,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op // Fill up for half a double-wide character. while (++width < maxwidth) { - trunc_p += utf_char2bytes(fillchar, trunc_p); - *trunc_p = NUL; + schar_get_adv(&trunc_p, fillchar); } } width = maxwidth; @@ -2100,12 +2090,12 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op for (int l = 0; l < num_separators; l++) { int dislocation = (l == (num_separators - 1)) ? final_spaces : standard_spaces; - dislocation *= utf_char2len(fillchar); + dislocation *= (int)schar_len(fillchar); char *start = stl_items[stl_separator_locations[l]].start; char *seploc = start + dislocation; STRMOVE(seploc, start); for (char *s = start; s < seploc;) { - s += utf_char2bytes(fillchar, s); + schar_get_adv(&s, fillchar); } for (int item_idx = stl_separator_locations[l] + 1; diff --git a/src/nvim/window.c b/src/nvim/window.c index c123de0f77..6a305f9b2f 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5662,7 +5662,7 @@ void win_setheight_win(int height, win_T *win) // If there is extra space created between the last window and the command // line, clear it. if (full_screen && msg_scrolled == 0 && row < cmdline_row) { - grid_fill(&default_grid, row, cmdline_row, 0, Columns, ' ', ' ', 0); + grid_clear(&default_grid, row, cmdline_row, 0, Columns, 0); if (msg_grid.chars) { clear_cmdline = true; } @@ -6145,7 +6145,7 @@ void win_drag_status_line(win_T *dragwin, int offset) } } int row = win_comp_pos(); - grid_fill(&default_grid, row, cmdline_row, 0, Columns, ' ', ' ', 0); + grid_clear(&default_grid, row, cmdline_row, 0, Columns, 0); if (msg_grid.chars) { clear_cmdline = true; } @@ -6640,7 +6640,7 @@ void command_height(void) // clear the lines added to cmdline if (full_screen) { - grid_fill(&default_grid, cmdline_row, Rows, 0, Columns, ' ', ' ', 0); + grid_clear(&default_grid, cmdline_row, Rows, 0, Columns, 0); } msg_row = cmdline_row; redraw_cmdline = true; |