diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/api/deprecated.c | 86 | ||||
-rw-r--r-- | src/nvim/api/extmark.c | 91 | ||||
-rw-r--r-- | src/nvim/drawscreen.c | 4 | ||||
-rw-r--r-- | src/nvim/ex_getln.c | 4 | ||||
-rw-r--r-- | src/nvim/fileio.c | 6 | ||||
-rw-r--r-- | src/nvim/lua/executor.c | 3 | ||||
-rw-r--r-- | src/nvim/message.c | 26 | ||||
-rw-r--r-- | src/nvim/option.c | 6 | ||||
-rw-r--r-- | src/nvim/optionstr.c | 112 | ||||
-rw-r--r-- | src/nvim/statusline.c | 9 | ||||
-rw-r--r-- | src/nvim/window.c | 11 |
11 files changed, 179 insertions, 179 deletions
diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c index b9e7d7143a..1d81b21be6 100644 --- a/src/nvim/api/deprecated.c +++ b/src/nvim/api/deprecated.c @@ -21,6 +21,7 @@ #include "nvim/highlight.h" #include "nvim/highlight_group.h" #include "nvim/lua/executor.h" +#include "nvim/marktree.h" #include "nvim/memory.h" #include "nvim/memory_defs.h" #include "nvim/message.h" @@ -84,6 +85,17 @@ Integer nvim_buf_get_number(Buffer buffer, Error *err) return buf->b_fnum; } +static uint32_t src2ns(Integer *src_id) +{ + if (*src_id == 0) { + *src_id = nvim_create_namespace((String)STRING_INIT); + } + if (*src_id < 0) { + return (((uint32_t)1) << 31) - 1; + } + return (uint32_t)(*src_id); +} + /// Clears highlights and virtual text from namespace and range of lines /// /// @deprecated use |nvim_buf_clear_namespace()|. @@ -102,6 +114,80 @@ void nvim_buf_clear_highlight(Buffer buffer, Integer ns_id, Integer line_start, nvim_buf_clear_namespace(buffer, ns_id, line_start, line_end, err); } +/// Adds a highlight to buffer. +/// +/// @deprecated use |nvim_buf_set_extmark()| or |vim.hl.range()| +/// +/// Namespaces are used for batch deletion/updating of a set of highlights. To +/// create a namespace, use |nvim_create_namespace()| which returns a namespace +/// id. Pass it in to this function as `ns_id` to add highlights to the +/// namespace. All highlights in the same namespace can then be cleared with +/// single call to |nvim_buf_clear_namespace()|. If the highlight never will be +/// deleted by an API call, pass `ns_id = -1`. +/// +/// As a shorthand, `ns_id = 0` can be used to create a new namespace for the +/// highlight, the allocated id is then returned. If `hl_group` is the empty +/// string no highlight is added, but a new `ns_id` is still returned. This is +/// supported for backwards compatibility, new code should use +/// |nvim_create_namespace()| to create a new empty namespace. +/// +/// @param buffer Buffer handle, or 0 for current buffer +/// @param ns_id namespace to use or -1 for ungrouped highlight +/// @param hl_group Name of the highlight group to use +/// @param line Line to highlight (zero-indexed) +/// @param col_start Start of (byte-indexed) column range to highlight +/// @param col_end End of (byte-indexed) column range to highlight, +/// or -1 to highlight to end of line +/// @param[out] err Error details, if any +/// @return The ns_id that was used +Integer nvim_buf_add_highlight(Buffer buffer, Integer ns_id, String hl_group, Integer line, + Integer col_start, Integer col_end, Error *err) + FUNC_API_SINCE(1) + FUNC_API_DEPRECATED_SINCE(13) +{ + buf_T *buf = find_buffer_by_handle(buffer, err); + if (!buf) { + return 0; + } + + VALIDATE_RANGE((line >= 0 && line < MAXLNUM), "line number", { + return 0; + }); + VALIDATE_RANGE((col_start >= 0 && col_start <= MAXCOL), "column", { + return 0; + }); + + if (col_end < 0 || col_end > MAXCOL) { + col_end = MAXCOL; + } + + uint32_t ns = src2ns(&ns_id); + + if (!(line < buf->b_ml.ml_line_count)) { + // safety check, we can't add marks outside the range + return ns_id; + } + + int hl_id = 0; + if (hl_group.size > 0) { + hl_id = syn_check_group(hl_group.data, hl_group.size); + } else { + return ns_id; + } + + int end_line = (int)line; + if (col_end == MAXCOL) { + col_end = 0; + end_line++; + } + + DecorInline decor = DECOR_INLINE_INIT; + decor.data.hl.hl_id = hl_id; + + extmark_set(buf, ns, NULL, (int)line, (colnr_T)col_start, end_line, (colnr_T)col_end, + decor, MT_FLAG_DECOR_HL, true, false, false, false, NULL); + return ns_id; +} /// Set the virtual text (annotation) for a buffer line. /// /// @deprecated use nvim_buf_set_extmark to use full virtual text functionality. diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c index 18e37012ee..e66140da5a 100644 --- a/src/nvim/api/extmark.c +++ b/src/nvim/api/extmark.c @@ -49,7 +49,7 @@ void api_extmark_free_all_mem(void) /// Creates a new namespace or gets an existing one. [namespace]() /// /// Namespaces are used for buffer highlights and virtual text, see -/// |nvim_buf_add_highlight()| and |nvim_buf_set_extmark()|. +/// |nvim_buf_set_extmark()|. /// /// Namespaces can be named or anonymous. If `name` matches an existing /// namespace, the associated id is returned. If `name` is an empty string @@ -901,95 +901,6 @@ Boolean nvim_buf_del_extmark(Buffer buffer, Integer ns_id, Integer id, Error *er return extmark_del_id(buf, (uint32_t)ns_id, (uint32_t)id); } -uint32_t src2ns(Integer *src_id) -{ - if (*src_id == 0) { - *src_id = nvim_create_namespace((String)STRING_INIT); - } - if (*src_id < 0) { - return (((uint32_t)1) << 31) - 1; - } - return (uint32_t)(*src_id); -} - -/// Adds a highlight to buffer. -/// -/// Useful for plugins that dynamically generate highlights to a buffer -/// (like a semantic highlighter or linter). The function adds a single -/// highlight to a buffer. Unlike |matchaddpos()| highlights follow changes to -/// line numbering (as lines are inserted/removed above the highlighted line), -/// like signs and marks do. -/// -/// Namespaces are used for batch deletion/updating of a set of highlights. To -/// create a namespace, use |nvim_create_namespace()| which returns a namespace -/// id. Pass it in to this function as `ns_id` to add highlights to the -/// namespace. All highlights in the same namespace can then be cleared with -/// single call to |nvim_buf_clear_namespace()|. If the highlight never will be -/// deleted by an API call, pass `ns_id = -1`. -/// -/// As a shorthand, `ns_id = 0` can be used to create a new namespace for the -/// highlight, the allocated id is then returned. If `hl_group` is the empty -/// string no highlight is added, but a new `ns_id` is still returned. This is -/// supported for backwards compatibility, new code should use -/// |nvim_create_namespace()| to create a new empty namespace. -/// -/// @param buffer Buffer handle, or 0 for current buffer -/// @param ns_id namespace to use or -1 for ungrouped highlight -/// @param hl_group Name of the highlight group to use -/// @param line Line to highlight (zero-indexed) -/// @param col_start Start of (byte-indexed) column range to highlight -/// @param col_end End of (byte-indexed) column range to highlight, -/// or -1 to highlight to end of line -/// @param[out] err Error details, if any -/// @return The ns_id that was used -Integer nvim_buf_add_highlight(Buffer buffer, Integer ns_id, String hl_group, Integer line, - Integer col_start, Integer col_end, Error *err) - FUNC_API_SINCE(1) -{ - buf_T *buf = find_buffer_by_handle(buffer, err); - if (!buf) { - return 0; - } - - VALIDATE_RANGE((line >= 0 && line < MAXLNUM), "line number", { - return 0; - }); - VALIDATE_RANGE((col_start >= 0 && col_start <= MAXCOL), "column", { - return 0; - }); - - if (col_end < 0 || col_end > MAXCOL) { - col_end = MAXCOL; - } - - uint32_t ns = src2ns(&ns_id); - - if (!(line < buf->b_ml.ml_line_count)) { - // safety check, we can't add marks outside the range - return ns_id; - } - - int hl_id = 0; - if (hl_group.size > 0) { - hl_id = syn_check_group(hl_group.data, hl_group.size); - } else { - return ns_id; - } - - int end_line = (int)line; - if (col_end == MAXCOL) { - col_end = 0; - end_line++; - } - - DecorInline decor = DECOR_INLINE_INIT; - decor.data.hl.hl_id = hl_id; - - extmark_set(buf, ns, NULL, (int)line, (colnr_T)col_start, end_line, (colnr_T)col_end, - decor, MT_FLAG_DECOR_HL, true, false, false, false, NULL); - return ns_id; -} - /// Clears |namespace|d objects (highlights, |extmarks|, virtual text) from /// a region. /// diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index 7f4de9eab8..b1ea38e280 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -2580,9 +2580,9 @@ int compute_foldcolumn(win_T *wp, int col) { int fdc = win_fdccol_count(wp); int wmw = wp == curwin && p_wmw == 0 ? 1 : (int)p_wmw; - int wwidth = wp->w_grid.cols; + int n = wp->w_grid.cols - (col + wmw); - return MIN(fdc, wwidth - (col + wmw)); + return MIN(fdc, n); } /// Return the width of the 'number' and 'relativenumber' column. diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 423b50cd32..1eecee2a38 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -163,6 +163,7 @@ typedef struct { typedef struct { buf_T *buf; OptInt save_b_p_ul; + int save_b_p_ma; int save_b_changed; pos_T save_b_op_start; pos_T save_b_op_end; @@ -2419,6 +2420,7 @@ static void cmdpreview_prepare(CpInfo *cpinfo) if (!set_has(ptr_t, &saved_bufs, buf)) { CpBufInfo cp_bufinfo; cp_bufinfo.buf = buf; + cp_bufinfo.save_b_p_ma = buf->b_p_ma; cp_bufinfo.save_b_p_ul = buf->b_p_ul; cp_bufinfo.save_b_changed = buf->b_changed; cp_bufinfo.save_b_op_start = buf->b_op_start; @@ -2509,6 +2511,7 @@ static void cmdpreview_restore_state(CpInfo *cpinfo) } buf->b_p_ul = cp_bufinfo.save_b_p_ul; // Restore 'undolevels' + buf->b_p_ma = cp_bufinfo.save_b_p_ma; // Restore 'modifiable' } for (size_t i = 0; i < cpinfo->win_info.size; i++) { @@ -2704,7 +2707,6 @@ static int command_line_changed(CommandLineState *s) && current_sctx.sc_sid == 0 // only if interactive && *p_icm != NUL // 'inccommand' is set && !exmode_active // not in ex mode - && curbuf->b_p_ma // buffer is modifiable && cmdline_star == 0 // not typing a password && !vpeekc_any() && cmdpreview_may_show(s)) { diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 031ae30d41..1c9903695e 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -3276,7 +3276,11 @@ static void vim_mktempdir(void) expand_env((char *)temp_dirs[i], tmp, TEMP_FILE_PATH_MAXLEN - 64); if (!os_isdir(tmp)) { if (strequal("$TMPDIR", temp_dirs[i])) { - WLOG("$TMPDIR tempdir not a directory (or does not exist): %s", tmp); + if (!os_getenv("TMPDIR")) { + WLOG("$TMPDIR is unset"); + } else { + WLOG("$TMPDIR tempdir not a directory (or does not exist): \"%s\"", tmp); + } } continue; } diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 68d3af6074..a5b48a5d5e 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -276,10 +276,9 @@ static int nlua_luv_thread_common_cfpcall(lua_State *lstate, int nargs, int nres #endif } const char *error = lua_tostring(lstate, -1); - loop_schedule_deferred(&main_loop, event_create(nlua_luv_error_event, - xstrdup(error), + error != NULL ? xstrdup(error) : NULL, (void *)(intptr_t)(is_callback ? kThreadCallback : kThread))); diff --git a/src/nvim/message.c b/src/nvim/message.c index 5423446ef9..4c20edb7eb 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -153,7 +153,6 @@ static Array *msg_ext_chunks = NULL; static garray_T msg_ext_last_chunk = GA_INIT(sizeof(char), 40); static sattr_T msg_ext_last_attr = -1; static int msg_ext_last_hl_id; -static size_t msg_ext_cur_len = 0; static bool msg_ext_history = false; ///< message was added to history static bool msg_ext_overwrite = false; ///< will overwrite last message @@ -2246,14 +2245,13 @@ static void msg_puts_display(const char *str, int maxlen, int hl_id, int recurse // Concat pieces with the same highlight size_t len = maxlen < 0 ? strlen(str) : strnlen(str, (size_t)maxlen); ga_concat_len(&msg_ext_last_chunk, str, len); - msg_ext_cur_len += len; - msg_col += (int)mb_string2cells(str); - // When message ends in newline, reset variables used to format message: msg_advance(). - assert(len > 0); - if (str[len - 1] == '\n') { - msg_ext_cur_len = 0; - msg_col = 0; - } + + // Find last newline in the message and calculate the current message column + const char *lastline = strrchr(str, '\n'); + maxlen -= (int)(lastline ? (lastline - str) : 0); + const char *p = lastline ? lastline + 1 : str; + int col = (int)(maxlen < 0 ? mb_string2cells(p) : mb_string2cells_len(p, (size_t)(maxlen))); + msg_col = (lastline ? 0 : msg_col) + col; return; } @@ -3155,7 +3153,7 @@ static Array *msg_ext_init_chunks(void) { Array *tofree = msg_ext_chunks; msg_ext_chunks = xcalloc(1, sizeof(*msg_ext_chunks)); - msg_ext_cur_len = 0; + msg_col = 0; return tofree; } @@ -3472,14 +3470,6 @@ void msg_advance(int col) msg_col = col; // for redirection, may fill it up later return; } - if (ui_has(kUIMessages)) { - // TODO(bfredl): use byte count as a basic proxy. - // later on we might add proper support for formatted messages. - while (msg_ext_cur_len < (size_t)col) { - msg_putchar(' '); - } - return; - } col = MIN(col, Columns - 1); // not enough room while (msg_col < col) { msg_putchar(' '); diff --git a/src/nvim/option.c b/src/nvim/option.c index 073a816d0c..f9eb67ff83 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -980,12 +980,12 @@ static int validate_opt_idx(win_T *win, OptIndex opt_idx, int opt_flags, uint32_ // Skip all options that are not window-local (used when showing // an already loaded buffer in a window). - if ((opt_flags & OPT_WINONLY) && (opt_idx == kOptInvalid || !option_is_window_local(opt_idx))) { + if ((opt_flags & OPT_WINONLY) && !option_is_window_local(opt_idx)) { return FAIL; } // Skip all options that are window-local (used for :vimgrep). - if ((opt_flags & OPT_NOWIN) && opt_idx != kOptInvalid && option_is_window_local(opt_idx)) { + if ((opt_flags & OPT_NOWIN) && option_is_window_local(opt_idx)) { return FAIL; } @@ -3267,7 +3267,7 @@ bool is_option_hidden(OptIndex opt_idx) /// Check if option supports a specific type. bool option_has_type(OptIndex opt_idx, OptValType type) { - return options[opt_idx].type == type; + return opt_idx != kOptInvalid && options[opt_idx].type == type; } /// Check if option supports a specific scope. diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c index be5047f814..645bb23638 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -3,6 +3,7 @@ #include <stdint.h> #include <string.h> +#include "nvim/api/private/defs.h" #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer_defs.h" @@ -2086,49 +2087,54 @@ static schar_T get_encoded_char_adv(const char **p) } struct chars_tab { - schar_T *cp; ///< char value - const char *name; ///< char id - const char *def; ///< default value - const char *fallback; ///< default value when "def" isn't single-width + schar_T *cp; ///< char value + String name; ///< char id + const char *def; ///< default value + const char *fallback; ///< default value when "def" isn't single-width }; +#define CHARSTAB_ENTRY(cp, name, def, fallback) \ + { (cp), { name, STRLEN_LITERAL(name) }, def, fallback } + static fcs_chars_T fcs_chars; static const struct chars_tab fcs_tab[] = { - { &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 }, + CHARSTAB_ENTRY(&fcs_chars.stl, "stl", " ", NULL), + CHARSTAB_ENTRY(&fcs_chars.stlnc, "stlnc", " ", NULL), + CHARSTAB_ENTRY(&fcs_chars.wbr, "wbr", " ", NULL), + CHARSTAB_ENTRY(&fcs_chars.horiz, "horiz", "─", "-"), + CHARSTAB_ENTRY(&fcs_chars.horizup, "horizup", "┴", "-"), + CHARSTAB_ENTRY(&fcs_chars.horizdown, "horizdown", "┬", "-"), + CHARSTAB_ENTRY(&fcs_chars.vert, "vert", "│", "|"), + CHARSTAB_ENTRY(&fcs_chars.vertleft, "vertleft", "┤", "|"), + CHARSTAB_ENTRY(&fcs_chars.vertright, "vertright", "├", "|"), + CHARSTAB_ENTRY(&fcs_chars.verthoriz, "verthoriz", "┼", "+"), + CHARSTAB_ENTRY(&fcs_chars.fold, "fold", "·", "-"), + CHARSTAB_ENTRY(&fcs_chars.foldopen, "foldopen", "-", NULL), + CHARSTAB_ENTRY(&fcs_chars.foldclosed, "foldclose", "+", NULL), + CHARSTAB_ENTRY(&fcs_chars.foldsep, "foldsep", "│", "|"), + CHARSTAB_ENTRY(&fcs_chars.diff, "diff", "-", NULL), + CHARSTAB_ENTRY(&fcs_chars.msgsep, "msgsep", " ", NULL), + CHARSTAB_ENTRY(&fcs_chars.eob, "eob", "~", NULL), + CHARSTAB_ENTRY(&fcs_chars.lastline, "lastline", "@", NULL), }; static lcs_chars_T lcs_chars; static const struct chars_tab lcs_tab[] = { - { &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 }, + CHARSTAB_ENTRY(&lcs_chars.eol, "eol", NULL, NULL), + CHARSTAB_ENTRY(&lcs_chars.ext, "extends", NULL, NULL), + CHARSTAB_ENTRY(&lcs_chars.nbsp, "nbsp", NULL, NULL), + CHARSTAB_ENTRY(&lcs_chars.prec, "precedes", NULL, NULL), + CHARSTAB_ENTRY(&lcs_chars.space, "space", NULL, NULL), + CHARSTAB_ENTRY(&lcs_chars.tab2, "tab", NULL, NULL), + CHARSTAB_ENTRY(&lcs_chars.lead, "lead", NULL, NULL), + CHARSTAB_ENTRY(&lcs_chars.trail, "trail", NULL, NULL), + CHARSTAB_ENTRY(&lcs_chars.conceal, "conceal", NULL, NULL), + CHARSTAB_ENTRY(NULL, "multispace", NULL, NULL), + CHARSTAB_ENTRY(NULL, "leadmultispace", NULL, NULL), }; +#undef CHARSTAB_ENTRY + static char *field_value_err(char *errbuf, size_t errbuflen, const char *fmt, const char *field) { if (errbuf == NULL) { @@ -2209,13 +2215,13 @@ const char *set_chars_option(win_T *wp, const char *value, CharsOption what, boo while (*p) { int i; for (i = 0; i < entries; i++) { - const size_t len = strlen(tab[i].name); - if (!(strncmp(p, tab[i].name, len) == 0 && p[len] == ':')) { + if (!(strncmp(p, tab[i].name.data, + tab[i].name.size) == 0 && p[tab[i].name.size] == ':')) { continue; } - if (what == kListchars && strcmp(tab[i].name, "multispace") == 0) { - const char *s = p + len + 1; + const char *s = p + tab[i].name.size + 1; + if (what == kListchars && strcmp(tab[i].name.data, "multispace") == 0) { if (round == 0) { // Get length of lcs-multispace string in the first round last_multispace = p; @@ -2225,7 +2231,7 @@ const char *set_chars_option(win_T *wp, const char *value, CharsOption what, boo if (c1 == 0) { return field_value_err(errbuf, errbuflen, e_wrong_character_width_for_field_str, - tab[i].name); + tab[i].name.data); } multispace_len++; } @@ -2233,7 +2239,7 @@ const char *set_chars_option(win_T *wp, const char *value, CharsOption what, boo // lcs-multispace cannot be an empty string return field_value_err(errbuf, errbuflen, e_wrong_number_of_characters_for_field_str, - tab[i].name); + tab[i].name.data); } p = s; } else { @@ -2249,8 +2255,7 @@ const char *set_chars_option(win_T *wp, const char *value, CharsOption what, boo break; } - if (what == kListchars && strcmp(tab[i].name, "leadmultispace") == 0) { - const char *s = p + len + 1; + if (what == kListchars && strcmp(tab[i].name.data, "leadmultispace") == 0) { if (round == 0) { // get length of lcs-leadmultispace string in first round last_lmultispace = p; @@ -2260,7 +2265,7 @@ const char *set_chars_option(win_T *wp, const char *value, CharsOption what, boo if (c1 == 0) { return field_value_err(errbuf, errbuflen, e_wrong_character_width_for_field_str, - tab[i].name); + tab[i].name.data); } lead_multispace_len++; } @@ -2268,7 +2273,7 @@ const char *set_chars_option(win_T *wp, const char *value, CharsOption what, boo // lcs-leadmultispace cannot be an empty string return field_value_err(errbuf, errbuflen, e_wrong_number_of_characters_for_field_str, - tab[i].name); + tab[i].name.data); } p = s; } else { @@ -2284,17 +2289,16 @@ const char *set_chars_option(win_T *wp, const char *value, CharsOption what, boo break; } - const char *s = p + len + 1; if (*s == NUL) { return field_value_err(errbuf, errbuflen, e_wrong_number_of_characters_for_field_str, - tab[i].name); + tab[i].name.data); } schar_T c1 = get_encoded_char_adv(&s); if (c1 == 0) { return field_value_err(errbuf, errbuflen, e_wrong_character_width_for_field_str, - tab[i].name); + tab[i].name.data); } schar_T c2 = 0; schar_T c3 = 0; @@ -2302,20 +2306,20 @@ const char *set_chars_option(win_T *wp, const char *value, CharsOption what, boo if (*s == NUL) { return field_value_err(errbuf, errbuflen, e_wrong_number_of_characters_for_field_str, - tab[i].name); + tab[i].name.data); } c2 = get_encoded_char_adv(&s); if (c2 == 0) { return field_value_err(errbuf, errbuflen, e_wrong_character_width_for_field_str, - tab[i].name); + tab[i].name.data); } if (!(*s == ',' || *s == NUL)) { c3 = get_encoded_char_adv(&s); if (c3 == 0) { return field_value_err(errbuf, errbuflen, e_wrong_character_width_for_field_str, - tab[i].name); + tab[i].name.data); } } } @@ -2335,7 +2339,7 @@ const char *set_chars_option(win_T *wp, const char *value, CharsOption what, boo } else { return field_value_err(errbuf, errbuflen, e_wrong_number_of_characters_for_field_str, - tab[i].name); + tab[i].name.data); } } @@ -2366,22 +2370,22 @@ const char *set_chars_option(win_T *wp, const char *value, CharsOption what, boo /// 'fillchars' option. char *get_fillchars_name(expand_T *xp FUNC_ATTR_UNUSED, int idx) { - if (idx >= (int)ARRAY_SIZE(fcs_tab)) { + if (idx < 0 || idx >= (int)ARRAY_SIZE(fcs_tab)) { return NULL; } - return (char *)fcs_tab[idx].name; + return fcs_tab[idx].name.data; } /// Function given to ExpandGeneric() to obtain possible arguments of the /// 'listchars' option. char *get_listchars_name(expand_T *xp FUNC_ATTR_UNUSED, int idx) { - if (idx >= (int)ARRAY_SIZE(lcs_tab)) { + if (idx < 0 || idx >= (int)ARRAY_SIZE(lcs_tab)) { return NULL; } - return (char *)lcs_tab[idx].name; + return lcs_tab[idx].name.data; } /// Check all global and local values of 'listchars' and 'fillchars'. diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index 434d4c8a6f..b8515fa3e2 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -772,8 +772,7 @@ void draw_tabline(void) if (modified || wincount > 1) { if (wincount > 1) { - vim_snprintf(NameBuff, MAXPATHL, "%d", wincount); - int len = (int)strlen(NameBuff); + int len = vim_snprintf(NameBuff, MAXPATHL, "%d", wincount); if (col + len >= Columns - 3) { break; } @@ -798,7 +797,8 @@ void draw_tabline(void) len -= ptr2cells(p); MB_PTR_ADV(p); } - len = MIN(len, Columns - col - 1); + int n = Columns - col - 1; + len = MIN(len, n); grid_line_puts(col, p, -1, attr); col += len; @@ -832,7 +832,8 @@ void draw_tabline(void) // Draw the 'showcmd' information if 'showcmdloc' == "tabline". if (p_sc && *p_sloc == 't') { - const int sc_width = MIN(10, (int)Columns - col - (tabcount > 1) * 3); + int n = Columns - col - (tabcount > 1) * 3; + const int sc_width = MIN(10, n); if (sc_width > 0) { grid_line_puts(Columns - sc_width - (tabcount > 1) * 2, diff --git a/src/nvim/window.c b/src/nvim/window.c index 1c0d8c1027..fa2bfec138 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5243,11 +5243,13 @@ void win_free(win_T *wp, tabpage_T *tp) // freed memory is re-used for another window. FOR_ALL_BUFFERS(buf) { WinInfo *wip_wp = NULL; + size_t pos_wip = kv_size(buf->b_wininfo); size_t pos_null = kv_size(buf->b_wininfo); for (size_t i = 0; i < kv_size(buf->b_wininfo); i++) { WinInfo *wip = kv_A(buf->b_wininfo, i); if (wip->wi_win == wp) { wip_wp = wip; + pos_wip = i; } else if (wip->wi_win == NULL) { pos_null = i; } @@ -5255,11 +5257,12 @@ void win_free(win_T *wp, tabpage_T *tp) if (wip_wp) { wip_wp->wi_win = NULL; - // If there already is an entry with "wi_win" set to NULL it - // must be removed, it would never be used. + // If there already is an entry with "wi_win" set to NULL, only + // the first entry with NULL will ever be used, delete the other one. if (pos_null < kv_size(buf->b_wininfo)) { - free_wininfo(kv_A(buf->b_wininfo, pos_null), buf); - kv_shift(buf->b_wininfo, pos_null, 1); + size_t pos_delete = MAX(pos_null, pos_wip); + free_wininfo(kv_A(buf->b_wininfo, pos_delete), buf); + kv_shift(buf->b_wininfo, pos_delete, 1); } } } |