aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
-rw-r--r--test/functional/options/chars_spec.lua35
-rw-r--r--test/unit/statusline_spec.lua24
18 files changed, 474 insertions, 457 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_asci