aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/ui.c26
-rw-r--r--src/nvim/api/vim.c22
-rw-r--r--src/nvim/buffer_defs.h62
-rw-r--r--src/nvim/cmdexpand.c2
-rw-r--r--src/nvim/drawline.c241
-rw-r--r--src/nvim/drawscreen.c53
-rw-r--r--src/nvim/eval/funcs.c19
-rw-r--r--src/nvim/grid.c61
-rw-r--r--src/nvim/match.c4
-rw-r--r--src/nvim/message.c106
-rw-r--r--src/nvim/option.c8
-rw-r--r--src/nvim/optionstr.c181
-rw-r--r--src/nvim/optionstr.h5
-rw-r--r--src/nvim/popupmenu.c8
-rw-r--r--src/nvim/statusline.c68
-rw-r--r--src/nvim/window.c6
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;