diff options
Diffstat (limited to 'src/nvim/indent.c')
-rw-r--r-- | src/nvim/indent.c | 433 |
1 files changed, 213 insertions, 220 deletions
diff --git a/src/nvim/indent.c b/src/nvim/indent.c index 348f3a6528..14247b6d86 100644 --- a/src/nvim/indent.c +++ b/src/nvim/indent.c @@ -7,6 +7,7 @@ #include "nvim/ascii_defs.h" #include "nvim/assert_defs.h" #include "nvim/buffer.h" +#include "nvim/buffer_defs.h" #include "nvim/change.h" #include "nvim/charset.h" #include "nvim/cursor.h" @@ -17,24 +18,27 @@ #include "nvim/ex_cmds_defs.h" #include "nvim/ex_docmd.h" #include "nvim/extmark.h" -#include "nvim/func_attr.h" -#include "nvim/gettext.h" +#include "nvim/extmark_defs.h" +#include "nvim/gettext_defs.h" #include "nvim/globals.h" #include "nvim/indent.h" #include "nvim/indent_c.h" -#include "nvim/mark.h" +#include "nvim/mark_defs.h" #include "nvim/mbyte.h" +#include "nvim/mbyte_defs.h" #include "nvim/memline.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/move.h" #include "nvim/option.h" +#include "nvim/option_defs.h" #include "nvim/option_vars.h" #include "nvim/optionstr.h" #include "nvim/os/input.h" #include "nvim/plines.h" #include "nvim/pos_defs.h" #include "nvim/regexp.h" +#include "nvim/regexp_defs.h" #include "nvim/search.h" #include "nvim/state_defs.h" #include "nvim/strings.h" @@ -54,15 +58,13 @@ bool tabstop_set(char *var, colnr_T **array) { int valcount = 1; - int t; - char *cp; if (var[0] == NUL || (var[0] == '0' && var[1] == NUL)) { *array = NULL; return true; } - for (cp = var; *cp != NUL; cp++) { + for (char *cp = var; *cp != NUL; cp++) { if (cp == var || cp[-1] == ',') { char *end; @@ -90,8 +92,8 @@ bool tabstop_set(char *var, colnr_T **array) *array = (colnr_T *)xmalloc((unsigned)(valcount + 1) * sizeof(int)); (*array)[0] = (colnr_T)valcount; - t = 1; - for (cp = var; *cp != NUL;) { + int t = 1; + for (char *cp = var; *cp != NUL;) { int n = atoi(cp); // Catch negative values, overflow and ridiculous big values. @@ -116,6 +118,7 @@ bool tabstop_set(char *var, colnr_T **array) /// If "vts" is set then the tab widths are taken from that array, /// otherwise the value of ts is used. int tabstop_padding(colnr_T col, OptInt ts_arg, const colnr_T *vts) + FUNC_ATTR_PURE { OptInt ts = ts_arg == 0 ? 8 : ts_arg; colnr_T tabcol = 0; @@ -172,14 +175,13 @@ int tabstop_at(colnr_T col, OptInt ts, const colnr_T *vts) colnr_T tabstop_start(colnr_T col, int ts, colnr_T *vts) { colnr_T tabcol = 0; - int t; if (vts == NULL || vts[0] == 0) { return ((col / ts) * ts); } const int tabcount = vts[0]; - for (t = 1; t <= tabcount; t++) { + for (int t = 1; t <= tabcount; t++) { tabcol += vts[t]; if (tabcol > col) { return (tabcol - vts[t]); @@ -259,8 +261,6 @@ void tabstop_fromto(colnr_T start_col, colnr_T end_col, int ts_arg, const colnr_ /// See if two tabstop arrays contain the same values. bool tabstop_eq(const colnr_T *ts1, const colnr_T *ts2) { - int t; - if ((ts1 == 0 && ts2) || (ts1 && ts2 == 0)) { return false; } @@ -271,7 +271,7 @@ bool tabstop_eq(const colnr_T *ts1, const colnr_T *ts2) return false; } - for (t = 1; t <= ts1[0]; t++) { + for (int t = 1; t <= ts1[0]; t++) { if (ts1[t] != ts2[t]) { return false; } @@ -283,15 +283,12 @@ bool tabstop_eq(const colnr_T *ts1, const colnr_T *ts2) /// Copy a tabstop array, allocating space for the new array. int *tabstop_copy(const int *oldts) { - int *newts; - int t; - if (oldts == 0) { return 0; } - newts = xmalloc((unsigned)(oldts[0] + 1) * sizeof(int)); - for (t = 0; t <= oldts[0]; t++) { + int *newts = xmalloc((unsigned)(oldts[0] + 1) * sizeof(int)); + for (int t = 0; t <= oldts[0]; t++) { newts[t] = oldts[t]; } @@ -353,117 +350,127 @@ int get_sts_value(void) return result; } -// Count the size (in window cells) of the indent in the current line. +/// Count the size (in window cells) of the indent in the current line. int get_indent(void) { - return get_indent_str_vtab(get_cursor_line_ptr(), - curbuf->b_p_ts, - curbuf->b_p_vts_array, - false); + return indent_size_ts(get_cursor_line_ptr(), curbuf->b_p_ts, curbuf->b_p_vts_array); } -// Count the size (in window cells) of the indent in line "lnum". +/// Count the size (in window cells) of the indent in line "lnum". int get_indent_lnum(linenr_T lnum) { - return get_indent_str_vtab(ml_get(lnum), - curbuf->b_p_ts, - curbuf->b_p_vts_array, - false); + return indent_size_ts(ml_get(lnum), curbuf->b_p_ts, curbuf->b_p_vts_array); } -// Count the size (in window cells) of the indent in line "lnum" of buffer -// "buf". +/// Count the size (in window cells) of the indent in line "lnum" of buffer "buf". int get_indent_buf(buf_T *buf, linenr_T lnum) { - return get_indent_str_vtab(ml_get_buf(buf, lnum), buf->b_p_ts, buf->b_p_vts_array, false); + return indent_size_ts(ml_get_buf(buf, lnum), buf->b_p_ts, buf->b_p_vts_array); } -/// Count the size (in window cells) of the indent in line "ptr", with -/// 'tabstop' at "ts". -/// If @param list is true, count only screen size for tabs. -int get_indent_str(const char *ptr, int ts, bool list) - FUNC_ATTR_NONNULL_ALL +/// Compute the size of the indent (in window cells) in line "ptr", +/// without tabstops (count tab as ^I or <09>). +int indent_size_no_ts(char const *ptr) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE { - int count = 0; - - for (; *ptr; ptr++) { - // Count a tab for what it is worth. - if (*ptr == TAB) { - if (!list || curwin->w_p_lcs_chars.tab1) { - // count a tab for what it is worth - count += ts - (count % ts); - } else { - // In list mode, when tab is not set, count screen char width - // for Tab, displays: ^I - count += ptr2cells(ptr); - } - } else if (*ptr == ' ') { - // Count a space for one. - count++; + int tab_size = byte2cells(TAB); + + int vcol = 0; + while (true) { + char const c = *ptr++; + if (c == ' ') { + vcol++; + } else if (c == TAB) { + vcol += tab_size; } else { - break; + return vcol; } } - return count; } -/// Count the size (in window cells) of the indent in line "ptr", using -/// variable tabstops. -/// if "list" is true, count only screen size for tabs. -int get_indent_str_vtab(const char *ptr, OptInt ts, colnr_T *vts, bool list) +/// Compute the size of the indent (in window cells) in line "ptr", +/// using tabstops +int indent_size_ts(char const *ptr, OptInt ts, colnr_T *vts) + FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_PURE { - int count = 0; + assert(char2cells(' ') == 1); + + int vcol = 0; + int tabstop_width, next_tab_vcol; + + if (vts == NULL || vts[0] < 1) { // tab has fixed width + // can ts be 0 ? This is from tabstop_padding(). + tabstop_width = (int)(ts == 0 ? 8 : ts); + next_tab_vcol = tabstop_width; + } else { // tab has variable width + colnr_T *cur_tabstop = vts + 1; + colnr_T *const last_tabstop = vts + vts[0]; + + while (cur_tabstop != last_tabstop) { + int cur_vcol = vcol; + vcol += *cur_tabstop++; + assert(cur_vcol < vcol); + + do { + char const c = *ptr++; + if (c == ' ') { + cur_vcol++; + } else if (c == TAB) { + break; + } else { + return cur_vcol; + } + } while (cur_vcol != vcol); + } - for (; *ptr; ptr++) { - if (*ptr == TAB) { // count a tab for what it is worth - if (!list || curwin->w_p_lcs_chars.tab1) { - count += tabstop_padding(count, ts, vts); - } else { - // In list mode, when tab is not set, count screen char width - // for Tab, displays: ^I - count += ptr2cells(ptr); - } - } else if (*ptr == ' ') { - count++; // count a space for one + tabstop_width = *last_tabstop; + next_tab_vcol = vcol + tabstop_width; + } + + assert(tabstop_width != 0); + while (true) { + char const c = *ptr++; + if (c == ' ') { + vcol++; + next_tab_vcol += (vcol == next_tab_vcol) ? tabstop_width : 0; + } else if (c == TAB) { + vcol = next_tab_vcol; + next_tab_vcol += tabstop_width; } else { - break; + return vcol; } } - return count; } -// Set the indent of the current line. -// Leaves the cursor on the first non-blank in the line. -// Caller must take care of undo. -// "flags": -// SIN_CHANGED: call changed_bytes() if the line was changed. -// SIN_INSERT: insert the indent in front of the line. -// SIN_UNDO: save line for undo before changing it. -// SIN_NOMARK: don't move extmarks (because just after ml_append or something) -// @param size measured in spaces -// Returns true if the line was changed. -int set_indent(int size, int flags) +/// Set the indent of the current line. +/// Leaves the cursor on the first non-blank in the line. +/// Caller must take care of undo. +/// "flags": +/// SIN_CHANGED: call changed_bytes() if the line was changed. +/// SIN_INSERT: insert the indent in front of the line. +/// SIN_UNDO: save line for undo before changing it. +/// SIN_NOMARK: don't move extmarks (because just after ml_append or something) +/// @param size measured in spaces +/// +/// @return true if the line was changed. +bool set_indent(int size, int flags) { - char *p; char *newline; char *oldline; char *s; - int todo; - int ind_len; // Measured in characters. - int line_len; int doit = false; int ind_done = 0; // Measured in spaces. int tab_pad; - int retval = false; + bool retval = false; // Number of initial whitespace chars when 'et' and 'pi' are both set. int orig_char_len = -1; // First check if there is anything to do and compute the number of // characters needed for the indent. - todo = size; - ind_len = 0; - p = oldline = get_cursor_line_ptr(); + int todo = size; + int ind_len = 0; // Measured in characters. + char *p = oldline = get_cursor_line_ptr(); // Calculate the buffer size for the new indent, and check to see if it // isn't already set. @@ -561,7 +568,7 @@ int set_indent(int size, int flags) } else { p = skipwhite(p); } - line_len = (int)strlen(p) + 1; + int line_len = (int)strlen(p) + 1; // If 'preserveindent' and 'expandtab' are both set keep the original // characters and allocate accordingly. We will fill the rest with spaces @@ -799,49 +806,60 @@ int get_breakindent_win(win_T *wp, char *line) { static int prev_indent = 0; // cached indent value static OptInt prev_ts = 0; // cached tabstop value + static colnr_T *prev_vts = NULL; // cached vartabs values static int prev_fnum = 0; // cached buffer number static char *prev_line = NULL; // cached copy of "line" static varnumber_T prev_tick = 0; // changedtick of cached value - static colnr_T *prev_vts = NULL; // cached vartabs values - static int prev_list = 0; // cached list value + static int prev_list = 0; // cached list indent static int prev_listopt = 0; // cached w_p_briopt_list value + static bool prev_no_ts = false; // cached no_ts value + static unsigned prev_dy_uhex = 0; // cached 'display' "uhex" value static char *prev_flp = NULL; // cached formatlistpat value int bri = 0; // window width minus window margin space, i.e. what rests for text - const int eff_wwidth = wp->w_width_inner - - ((wp->w_p_nu || wp->w_p_rnu) - && (vim_strchr(p_cpo, CPO_NUMCOL) == NULL) ? number_width(wp) + 1 : 0); - - // used cached indent, unless - // - buffer changed - // - 'tabstop' changed - // - buffer was changed - // - 'briopt_list changed' changed or - // - 'formatlistpattern' changed - // - line changed - // - 'vartabs' changed + const int eff_wwidth = wp->w_width_inner - win_col_off(wp) + win_col_off2(wp); + + // In list mode, if 'listchars' "tab" isn't set, a TAB is displayed as ^I. + const bool no_ts = wp->w_p_list && wp->w_p_lcs_chars.tab1 == NUL; + + // Used cached indent, unless + // - buffer changed, or + // - 'tabstop' changed, or + // - 'vartabstop' changed, or + // - buffer was changed, or + // - 'breakindentopt' "list" changed, or + // - 'list' or 'listchars' "tab" changed, or + // - 'display' "uhex" flag changed, or + // - 'formatlistpat' changed, or + // - line changed. if (prev_fnum != wp->w_buffer->b_fnum || prev_ts != wp->w_buffer->b_p_ts + || prev_vts != wp->w_buffer->b_p_vts_array || prev_tick != buf_get_changedtick(wp->w_buffer) || prev_listopt != wp->w_briopt_list + || prev_no_ts != no_ts + || prev_dy_uhex != (dy_flags & DY_UHEX) || prev_flp == NULL || strcmp(prev_flp, get_flp_value(wp->w_buffer)) != 0 - || prev_line == NULL || strcmp(prev_line, line) != 0 - || prev_vts != wp->w_buffer->b_p_vts_array) { + || prev_line == NULL || strcmp(prev_line, line) != 0) { prev_fnum = wp->w_buffer->b_fnum; xfree(prev_line); prev_line = xstrdup(line); prev_ts = wp->w_buffer->b_p_ts; - prev_tick = buf_get_changedtick(wp->w_buffer); prev_vts = wp->w_buffer->b_p_vts_array; if (wp->w_briopt_vcol == 0) { - prev_indent = get_indent_str_vtab(line, - wp->w_buffer->b_p_ts, - wp->w_buffer->b_p_vts_array, - wp->w_p_list); + if (no_ts) { + prev_indent = indent_size_no_ts(line); + } else { + prev_indent = indent_size_ts(line, wp->w_buffer->b_p_ts, + wp->w_buffer->b_p_vts_array); + } } + prev_tick = buf_get_changedtick(wp->w_buffer); prev_listopt = wp->w_briopt_list; prev_list = 0; + prev_no_ts = no_ts; + prev_dy_uhex = (dy_flags & DY_UHEX); xfree(prev_flp); prev_flp = xstrdup(get_flp_value(wp->w_buffer)); // add additional indent for numbered lists @@ -900,7 +918,7 @@ int get_breakindent_win(win_T *wp, char *line) // non-blank in the line. // When extra == 1: Return true if the cursor is before the first non-blank in // the line. -int inindent(int extra) +bool inindent(int extra) { char *ptr; colnr_T col; @@ -934,23 +952,18 @@ static void emsg_text_too_long(void) /// ":retab". void ex_retab(exarg_T *eap) { - linenr_T lnum; bool got_tab = false; int num_spaces = 0; - int num_tabs; - int len; int start_col = 0; // For start of white-space string int64_t start_vcol = 0; // For start of white-space string - int old_len; char *new_line = (char *)1; // init to non-NULL colnr_T *new_vts_array = NULL; char *new_ts_str; // string value of tab argument - int save_list; linenr_T first_line = 0; // first changed line linenr_T last_line = 0; // last changed line - save_list = curwin->w_p_list; + int save_list = curwin->w_p_list; curwin->w_p_list = 0; // don't want list mode here new_ts_str = eap->arg; @@ -970,7 +983,7 @@ void ex_retab(exarg_T *eap) } else { new_ts_str = xmemdupz(new_ts_str, (size_t)(eap->arg - new_ts_str)); } - for (lnum = eap->line1; !got_int && lnum <= eap->line2; lnum++) { + for (linenr_T lnum = eap->line1; !got_int && lnum <= eap->line2; lnum++) { char *ptr = ml_get(lnum); int col = 0; int64_t vcol = 0; @@ -992,8 +1005,8 @@ void ex_retab(exarg_T *eap) // Retabulate this string of white-space // len is virtual length of white string - len = num_spaces = (int)(vcol - start_vcol); - num_tabs = 0; + int len = num_spaces = (int)(vcol - start_vcol); + int num_tabs = 0; if (!curbuf->b_p_et) { int t, s; @@ -1015,7 +1028,7 @@ void ex_retab(exarg_T *eap) // len is actual number of white characters used len = num_spaces + num_tabs; - old_len = (int)strlen(ptr); + int old_len = (int)strlen(ptr); const int new_len = old_len - col + start_col + len + 1; if (new_len <= 0 || new_len >= MAXCOL) { emsg_text_too_long(); @@ -1092,7 +1105,7 @@ void ex_retab(exarg_T *eap) colnr_T *old_vts_ary = curbuf->b_p_vts_array; if (tabstop_count(old_vts_ary) > 0 || tabstop_count(new_vts_array) > 1) { - set_string_option_direct("vts", -1, new_ts_str, OPT_FREE | OPT_LOCAL, 0); + set_string_option_direct(kOptVartabstop, new_ts_str, OPT_LOCAL, 0); curbuf->b_p_vts_array = new_vts_array; xfree(old_vts_ary); } else { @@ -1111,19 +1124,14 @@ void ex_retab(exarg_T *eap) /// Get indent level from 'indentexpr'. int get_expr_indent(void) { - int indent = -1; - pos_T save_pos; - colnr_T save_curswant; - int save_set_curswant; - int save_State; - int use_sandbox = was_set_insecurely(curwin, "indentexpr", OPT_LOCAL); + bool use_sandbox = was_set_insecurely(curwin, kOptIndentexpr, OPT_LOCAL); const sctx_T save_sctx = current_sctx; // Save and restore cursor position and curswant, in case it was changed // * via :normal commands. - save_pos = curwin->w_cursor; - save_curswant = curwin->w_curswant; - save_set_curswant = curwin->w_set_curswant; + pos_T save_pos = curwin->w_cursor; + colnr_T save_curswant = curwin->w_curswant; + bool save_set_curswant = curwin->w_set_curswant; set_vim_var_nr(VV_LNUM, (varnumber_T)curwin->w_cursor.lnum); if (use_sandbox) { @@ -1135,7 +1143,7 @@ int get_expr_indent(void) // Need to make a copy, the 'indentexpr' option could be changed while // evaluating it. char *inde_copy = xstrdup(curbuf->b_p_inde); - indent = (int)eval_to_number(inde_copy); + int indent = (int)eval_to_number(inde_copy); xfree(inde_copy); if (use_sandbox) { @@ -1147,7 +1155,7 @@ int get_expr_indent(void) // Restore the cursor position so that 'indentexpr' doesn't need to. // Pretend to be in Insert mode, allow cursor past end of line for "o" // command. - save_State = State; + int save_State = State; State = MODE_INSERT; curwin->w_cursor = save_pos; curwin->w_curswant = save_curswant; @@ -1188,10 +1196,6 @@ int get_lisp_indent(void) pos_T *pos; pos_T paren; int amount; - char *that; - - // Set vi_lisp to use the vi-compatible method. - int vi_lisp = (vim_strchr(p_cpo, CPO_LISP) != NULL); pos_T realpos = curwin->w_cursor; curwin->w_cursor.col = 0; @@ -1218,7 +1222,7 @@ int get_lisp_indent(void) continue; } - for (that = get_cursor_line_ptr(); *that != NUL; that++) { + for (char *that = get_cursor_line_ptr(); *that != NUL; that++) { if (*that == ';') { while (*(that + 1) != NUL) { that++; @@ -1268,94 +1272,83 @@ int get_lisp_indent(void) curwin->w_cursor.col = pos->col; colnr_T col = pos->col; - that = get_cursor_line_ptr(); + char *line = get_cursor_line_ptr(); + + CharsizeArg csarg; + CSType cstype = init_charsize_arg(&csarg, curwin, pos->lnum, line); - if (vi_lisp && (get_indent() == 0)) { - amount = 2; + StrCharInfo sci = utf_ptr2StrCharInfo(line); + amount = 0; + while (*sci.ptr != NUL && col > 0) { + amount += win_charsize(cstype, amount, sci.ptr, sci.chr.value, &csarg).width; + sci = utfc_next(sci); + col--; + } + char *that = sci.ptr; + + // Some keywords require "body" indenting rules (the + // non-standard-lisp ones are Scheme special forms): + // (let ((a 1)) instead (let ((a 1)) + // (...)) of (...)) + if (((*that == '(') || (*that == '[')) && lisp_match(that + 1)) { + amount += 2; } else { - char *line = that; - chartabsize_T cts; - init_chartabsize_arg(&cts, curwin, pos->lnum, 0, line, line); - while (*cts.cts_ptr != NUL && col > 0) { - cts.cts_vcol += lbr_chartabsize_adv(&cts); - col--; + if (*that != NUL) { + that++; + amount++; + } + colnr_T firsttry = amount; + + while (ascii_iswhite(*that)) { + amount += win_charsize(cstype, amount, that, (uint8_t)(*that), &csarg).width; + that++; } - amount = cts.cts_vcol; - that = cts.cts_ptr; - clear_chartabsize_arg(&cts); - - // Some keywords require "body" indenting rules (the - // non-standard-lisp ones are Scheme special forms): - // (let ((a 1)) instead (let ((a 1)) - // (...)) of (...)) - if (!vi_lisp && ((*that == '(') || (*that == '[')) - && lisp_match(that + 1)) { - amount += 2; - } else { - if (*that != NUL) { - that++; - amount++; - } - colnr_T firsttry = amount; - init_chartabsize_arg(&cts, curwin, (colnr_T)(that - line), - amount, line, that); - while (ascii_iswhite(*cts.cts_ptr)) { - cts.cts_vcol += lbr_chartabsize(&cts); - cts.cts_ptr++; + if (*that && (*that != ';')) { + // Not a comment line. + // Test *that != '(' to accommodate first let/do + // argument if it is more than one line. + if ((*that != '(') && (*that != '[')) { + firsttry++; } - that = cts.cts_ptr; - amount = cts.cts_vcol; - clear_chartabsize_arg(&cts); - - if (*that && (*that != ';')) { - // Not a comment line. - // Test *that != '(' to accommodate first let/do - // argument if it is more than one line. - if (!vi_lisp && (*that != '(') && (*that != '[')) { - firsttry++; - } - parencount = 0; - - init_chartabsize_arg(&cts, curwin, - (colnr_T)(that - line), amount, line, that); - if (vi_lisp || ((*that != '"') && (*that != '\'') - && (*that != '#') - && (((uint8_t)(*that) < '0') || ((uint8_t)(*that) > '9')))) { - int quotecount = 0; - while (*cts.cts_ptr - && (!ascii_iswhite(*cts.cts_ptr) || quotecount || parencount) - && (!((*cts.cts_ptr == '(' || *cts.cts_ptr == '[') - && !quotecount && !parencount && vi_lisp))) { - if (*cts.cts_ptr == '"') { - quotecount = !quotecount; - } - if (((*cts.cts_ptr == '(') || (*cts.cts_ptr == '[')) && !quotecount) { - parencount++; - } - if (((*cts.cts_ptr == ')') || (*cts.cts_ptr == ']')) && !quotecount) { - parencount--; - } - if ((*cts.cts_ptr == '\\') && (*(cts.cts_ptr + 1) != NUL)) { - cts.cts_vcol += lbr_chartabsize_adv(&cts); - } - - cts.cts_vcol += lbr_chartabsize_adv(&cts); + parencount = 0; + + CharInfo ci = utf_ptr2CharInfo(that); + if (((ci.value != '"') && (ci.value != '\'') && (ci.value != '#') + && ((ci.value < '0') || (ci.value > '9')))) { + int quotecount = 0; + while (*that && (!ascii_iswhite(ci.value) || quotecount || parencount)) { + if (ci.value == '"') { + quotecount = !quotecount; + } + if (((ci.value == '(') || (ci.value == '[')) && !quotecount) { + parencount++; + } + if (((ci.value == ')') || (ci.value == ']')) && !quotecount) { + parencount--; + } + if ((ci.value == '\\') && (*(that + 1) != NUL)) { + amount += win_charsize(cstype, amount, that, ci.value, &csarg).width; + StrCharInfo next_sci = utfc_next((StrCharInfo){ that, ci }); + that = next_sci.ptr; + ci = next_sci.chr; } - } - while (ascii_iswhite(*cts.cts_ptr)) { - cts.cts_vcol += lbr_chartabsize(&cts); - cts.cts_ptr++; + amount += win_charsize(cstype, amount, that, ci.value, &csarg).width; + StrCharInfo next_sci = utfc_next((StrCharInfo){ that, ci }); + that = next_sci.ptr; + ci = next_sci.chr; } - that = cts.cts_ptr; - amount = cts.cts_vcol; - clear_chartabsize_arg(&cts); + } - if (!*that || (*that == ';')) { - amount = firsttry; - } + while (ascii_iswhite(*that)) { + amount += win_charsize(cstype, amount, that, (uint8_t)(*that), &csarg).width; + that++; + } + + if (!*that || (*that == ';')) { + amount = firsttry; } } } @@ -1374,7 +1367,7 @@ static int lisp_match(char *p) char *word = *curbuf->b_p_lw != NUL ? curbuf->b_p_lw : p_lispwords; while (*word != NUL) { - (void)copy_option_part(&word, buf, sizeof(buf), ","); + copy_option_part(&word, buf, sizeof(buf), ","); int len = (int)strlen(buf); if ((strncmp(buf, p, (size_t)len) == 0) && ascii_iswhite_or_nul(p[len])) { |