diff options
Diffstat (limited to 'src/nvim')
174 files changed, 1651 insertions, 1757 deletions
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 38be5bfb1d..da74b4dc9d 100755 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -13,8 +13,10 @@ if(USE_GCOV) endif() if(WIN32) - # tell MinGW compiler to enable wmain - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -municode") + if(MINGW) + # Enable wmain + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -municode") + endif() elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework CoreServices") set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -framework CoreServices") diff --git a/src/nvim/api/autocmd.c b/src/nvim/api/autocmd.c index 76e531e7aa..19b4119344 100644 --- a/src/nvim/api/autocmd.c +++ b/src/nvim/api/autocmd.c @@ -31,7 +31,6 @@ goto goto_name; \ } - // ID for associating autocmds created via nvim_create_autocmd // Used to delete autocmds from nvim_del_autocmd static int64_t next_autocmd_id = 1; @@ -283,7 +282,7 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Error *err) PUT(autocmd_info, "command", - STRING_OBJ(cstr_to_string(aucmd_exec_to_string(ac, ac->exec)))); + STRING_OBJ(cstr_as_string(aucmd_exec_to_string(ac, ac->exec)))); PUT(autocmd_info, "pattern", @@ -405,6 +404,7 @@ cleanup: /// - match: (string) the expanded value of |<amatch>| /// - buf: (number) the expanded value of |<abuf>| /// - file: (string) the expanded value of |<afile>| +/// - data: (any) arbitrary data passed to |nvim_exec_autocmds()| /// - command (string) optional: Vim command to execute on event. Cannot be used with /// {callback} /// - once (boolean) optional: defaults to false. Run the autocommand @@ -428,7 +428,6 @@ Integer nvim_create_autocmd(uint64_t channel_id, Object event, Dict(create_autoc AucmdExecutable aucmd = AUCMD_EXECUTABLE_INIT; Callback cb = CALLBACK_NONE; - if (!unpack_string_or_array(&event_array, &event, "event", true, err)) { goto cleanup; } @@ -549,7 +548,6 @@ Integer nvim_create_autocmd(uint64_t channel_id, Object event, Dict(create_autoc } }); - cleanup: aucmd_exec_free(&aucmd); api_free_array(event_array); @@ -749,6 +747,8 @@ void nvim_del_augroup_by_name(String name, Error *err) /// {pattern}. /// - modeline (bool) optional: defaults to true. Process the /// modeline after the autocommands |<nomodeline>|. +/// - data (any): arbitrary data to send to the autocommand callback. See +/// |nvim_create_autocmd()| for details. /// @see |:doautocmd| void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err) FUNC_API_SINCE(9) @@ -760,6 +760,7 @@ void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err) bool set_buf = false; char *pattern = NULL; + Object *data = NULL; bool set_pattern = false; Array event_array = ARRAY_DICT_INIT; @@ -818,6 +819,10 @@ void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err) set_pattern = true; } + if (opts->data.type != kObjectTypeNil) { + data = &opts->data; + } + modeline = api_object_to_bool(opts->modeline, "modeline", true, err); if (set_pattern && set_buf) { @@ -829,7 +834,7 @@ void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err) FOREACH_ITEM(event_array, event_str, { GET_ONE_EVENT(event_nr, event_str, cleanup) - did_aucmd |= apply_autocmds_group(event_nr, pattern, NULL, true, au_group, buf, NULL); + did_aucmd |= apply_autocmds_group(event_nr, pattern, NULL, true, au_group, buf, NULL, data); }) if (did_aucmd && modeline) { diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 9842975d62..4fa8b13c54 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -35,7 +35,6 @@ # include "api/buffer.c.generated.h" #endif - /// \defgroup api-buffer /// /// \brief For more information on buffers, see |buffers| @@ -51,7 +50,6 @@ /// You can use |nvim_buf_is_loaded()| or |nvim_buf_line_count()| to check /// whether a buffer is loaded. - /// Returns the number of lines in the given buffer. /// /// @param buffer Buffer handle, or 0 for current buffer @@ -737,7 +735,6 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In (int)new_len - 1, (colnr_T)last_item.size, new_byte, kExtmarkUndo); - changed_lines((linenr_T)start_row, 0, (linenr_T)end_row + 1, (long)extra, true); @@ -1039,7 +1036,6 @@ void nvim_buf_del_var(Buffer buffer, String name, Error *err) dict_set_var(buf->b_vars, name, NIL, true, false, err); } - /// Gets a buffer option value /// /// @param buffer Buffer handle, or 0 for current buffer @@ -1336,7 +1332,6 @@ ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err) return rv; } - /// call a function with buffer as temporary current buffer /// /// This temporarily switches current buffer to "buffer". diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c index f968593e47..abaac07755 100644 --- a/src/nvim/api/deprecated.c +++ b/src/nvim/api/deprecated.c @@ -78,7 +78,6 @@ 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); } - /// Set the virtual text (annotation) for a buffer line. /// /// @deprecated use nvim_buf_set_extmark to use full virtual text @@ -137,7 +136,6 @@ Integer nvim_buf_set_virtual_text(Buffer buffer, Integer src_id, Integer line, A return 0; } - Decoration *existing = decor_find_virttext(buf, (int)line, ns_id); if (existing) { @@ -292,7 +290,6 @@ void buffer_set_line_slice(Buffer buffer, Integer start, Integer end, Boolean in nvim_buf_set_lines(0, buffer, start, end, false, replacement, err); } - /// Sets a buffer-scoped (b:) variable /// /// @deprecated diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c index e05d80812d..9d80a5be5f 100644 --- a/src/nvim/api/extmark.c +++ b/src/nvim/api/extmark.c @@ -94,28 +94,27 @@ static bool ns_initialized(uint32_t ns) return ns < (uint32_t)next_namespace_id; } - -static Array extmark_to_array(ExtmarkInfo extmark, bool id, bool add_dict) +static Array extmark_to_array(const ExtmarkInfo *extmark, bool id, bool add_dict) { Array rv = ARRAY_DICT_INIT; if (id) { - ADD(rv, INTEGER_OBJ((Integer)extmark.mark_id)); + ADD(rv, INTEGER_OBJ((Integer)extmark->mark_id)); } - ADD(rv, INTEGER_OBJ(extmark.row)); - ADD(rv, INTEGER_OBJ(extmark.col)); + ADD(rv, INTEGER_OBJ(extmark->row)); + ADD(rv, INTEGER_OBJ(extmark->col)); if (add_dict) { Dictionary dict = ARRAY_DICT_INIT; - PUT(dict, "right_gravity", BOOLEAN_OBJ(extmark.right_gravity)); + PUT(dict, "right_gravity", BOOLEAN_OBJ(extmark->right_gravity)); - if (extmark.end_row >= 0) { - PUT(dict, "end_row", INTEGER_OBJ(extmark.end_row)); - PUT(dict, "end_col", INTEGER_OBJ(extmark.end_col)); - PUT(dict, "end_right_gravity", BOOLEAN_OBJ(extmark.end_right_gravity)); + if (extmark->end_row >= 0) { + PUT(dict, "end_row", INTEGER_OBJ(extmark->end_row)); + PUT(dict, "end_col", INTEGER_OBJ(extmark->end_col)); + PUT(dict, "end_right_gravity", BOOLEAN_OBJ(extmark->end_right_gravity)); } - Decoration *decor = &extmark.decor; + const Decoration *decor = &extmark->decor; if (decor->hl_id) { String name = cstr_to_string((const char *)syn_id2name(decor->hl_id)); PUT(dict, "hl_group", STRING_OBJ(name)); @@ -233,12 +232,11 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id, } } - ExtmarkInfo extmark = extmark_from_id(buf, (uint32_t)ns_id, (uint32_t)id); if (extmark.row < 0) { return rv; } - return extmark_to_array(extmark, false, details); + return extmark_to_array(&extmark, false, details); } /// Gets extmarks in "traversal order" from a |charwise| region defined by @@ -333,7 +331,6 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e limit = INT64_MAX; } - bool reverse = false; int l_row; @@ -352,12 +349,11 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e reverse = true; } - ExtmarkInfoArray marks = extmark_get(buf, (uint32_t)ns_id, l_row, l_col, u_row, u_col, (int64_t)limit, reverse); for (size_t i = 0; i < kv_size(marks); i++) { - ADD(rv, ARRAY_OBJ(extmark_to_array(kv_A(marks, i), true, (bool)details))); + ADD(rv, ARRAY_OBJ(extmark_to_array(&kv_A(marks, i), true, (bool)details))); } kv_destroy(marks); @@ -366,12 +362,11 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e /// Creates or updates an extmark. /// -/// To create a new extmark, pass id=0. The extmark id will be returned. -/// To move an existing mark, pass its id. -/// -/// It is also allowed to create a new mark by passing in a previously unused -/// id, but the caller must then keep track of existing and unused ids itself. -/// (Useful over RPC, to avoid waiting for the return value.) +/// By default a new extmark is created when no id is passed in, but it is also +/// possible to create a new mark by passing in a previously unused id or move +/// an existing mark by passing in its id. The caller must then keep track of +/// existing and unused ids itself. (Useful over RPC, to avoid waiting for the +/// return value.) /// /// Using the optional arguments, it is possible to use this to highlight /// a range of text, and also to associate virtual text to the mark. @@ -676,7 +671,6 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer goto error; } - OPTION_TO_BOOL(decor.virt_lines_above, virt_lines_above, false); if (opts->priority.type == kObjectTypeInteger) { @@ -778,7 +772,6 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer col2 = 0; } - // TODO(bfredl): synergize these two branches even more if (ephemeral && decor_state.buf == buf) { decor_add_ephemeral((int)line, (int)col, line2, col2, &decor, (uint64_t)ns_id, id); diff --git a/src/nvim/api/keysets.lua b/src/nvim/api/keysets.lua index 78f8ed3cca..d4882abffe 100644 --- a/src/nvim/api/keysets.lua +++ b/src/nvim/api/keysets.lua @@ -80,10 +80,13 @@ return { "maxwidth"; "fillchar"; "highlights"; + "use_winbar"; "use_tabline"; }; option = { "scope"; + "win"; + "buf"; }; highlight = { "bold"; @@ -145,6 +148,7 @@ return { "group"; "modeline"; "pattern"; + "data"; }; get_autocmds = { "event"; diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index dcede27bcb..3cccbc3cdf 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -407,7 +407,6 @@ void set_option_to(uint64_t channel_id, void *to, int type, String name, Object }); } - buf_T *find_buffer_by_handle(Buffer buffer, Error *err) { if (buffer == 0) { @@ -1040,8 +1039,8 @@ Object copy_object(Object obj) } } -static void set_option_value_for(char *key, int numval, char *stringval, int opt_flags, - int opt_type, void *from, Error *err) +void set_option_value_for(char *key, long numval, char *stringval, int opt_flags, int opt_type, + void *from, Error *err) { switchwin_T switchwin; aco_save_T aco; @@ -1080,8 +1079,7 @@ static void set_option_value_for(char *key, int numval, char *stringval, int opt try_end(err); } - -static void set_option_value_err(char *key, int numval, char *stringval, int opt_flags, Error *err) +static void set_option_value_err(char *key, long numval, char *stringval, int opt_flags, Error *err) { char *errmsg; @@ -1418,14 +1416,14 @@ bool set_mark(buf_T *buf, String name, Integer line, Integer col, Error *err) } /// Get default statusline highlight for window -const char *get_default_stl_hl(win_T *wp) +const char *get_default_stl_hl(win_T *wp, bool use_winbar) { if (wp == NULL) { return "TabLineFill"; - } else if (wp == curwin) { - return "StatusLine"; + } else if (use_winbar) { + return (wp == curwin) ? "WinBar" : "WinBarNC"; } else { - return "StatusLineNC"; + return (wp == curwin) ? "StatusLine" : "StatusLineNC"; } } @@ -1562,7 +1560,6 @@ void create_user_command(String name, Object command, Dict(user_command) *opts, goto err; } - if (api_object_to_bool(opts->register_, "register", false, err)) { argt |= EX_REGSTR; } else if (ERROR_SET(err)) { @@ -1616,7 +1613,7 @@ void create_user_command(String name, Object command, Dict(user_command) *opts, if (uc_add_command(name.data, name.size, rep, argt, def, flags, compl, compl_arg, compl_luaref, addr_type_arg, luaref, force) != OK) { api_set_error(err, kErrorTypeException, "Failed to create user command"); - goto err; + // Do not goto err, since uc_add_command now owns luaref, compl_luaref, and compl_arg } return; @@ -1624,6 +1621,7 @@ void create_user_command(String name, Object command, Dict(user_command) *opts, err: NLUA_CLEAR_REF(luaref); NLUA_CLEAR_REF(compl_luaref); + xfree(compl_arg); } int find_sid(uint64_t channel_id) diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h index bbbc3de7d5..8423db4970 100644 --- a/src/nvim/api/private/helpers.h +++ b/src/nvim/api/private/helpers.h @@ -146,7 +146,6 @@ typedef struct { code; \ } - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "api/private/helpers.h.generated.h" # include "keysets.h.generated.h" @@ -163,5 +162,4 @@ typedef struct { current_sctx = save_current_sctx; \ } while (0); - #endif // NVIM_API_PRIVATE_HELPERS_H diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index b4d20ed975..dc04eedebc 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -196,7 +196,6 @@ void nvim_ui_detach(uint64_t channel_id, Error *err) remote_ui_disconnect(channel_id); } - void nvim_ui_try_resize(uint64_t channel_id, Integer width, Integer height, Error *err) FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY { @@ -349,7 +348,11 @@ void nvim_ui_try_resize_grid(uint64_t channel_id, Integer grid, Integer width, I return; } - ui_grid_resize((handle_T)grid, (int)width, (int)height, err); + if (grid == DEFAULT_GRID_HANDLE) { + nvim_ui_try_resize(channel_id, width, height, err); + } else { + ui_grid_resize((handle_T)grid, (int)width, (int)height, err); + } } /// Tells Nvim the number of elements displaying in the popumenu, to decide @@ -567,7 +570,6 @@ static void remote_ui_highlight_set(UI *ui, int id) Array args = ARRAY_DICT_INIT; UIData *data = ui->data; - if (data->hl_id == id) { return; } @@ -790,7 +792,6 @@ static void remote_ui_event(UI *ui, char *name, Array args, bool *args_consumed) } } - Array my_args = ARRAY_DICT_INIT; // Objects are currently single-reference // make a copy, but only if necessary diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h index 63aaaae38a..0030f9edf7 100644 --- a/src/nvim/api/ui_events.in.h +++ b/src/nvim/api/ui_events.in.h @@ -174,4 +174,6 @@ void msg_ruler(Array content) FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY; void msg_history_show(Array entries) FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY; +void msg_history_clear(void) + FUNC_API_SINCE(10) FUNC_API_REMOTE_ONLY; #endif // NVIM_API_UI_EVENTS_IN_H diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index a257dd6478..dd0b75bbfb 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -209,7 +209,6 @@ static void on_redraw_event(void **argv) redraw_all_later(NOT_VALID); } - /// Sends input-keys to Nvim, subject to various quirks controlled by `mode` /// flags. This is a blocking call, unlike |nvim_input()|. /// @@ -441,7 +440,6 @@ String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt, Bool return cstr_as_string(ptr); } - /// Execute Lua code. Parameters (if any) are available as `...` inside the /// chunk. The chunk can return a value. /// @@ -570,7 +568,6 @@ ArrayOf(String) nvim__get_runtime(Array pat, Boolean all, Dict(runtime) *opts, E return runtime_get_named(is_lua, pat, all); } - /// Changes the global working directory. /// /// @param dir Directory path @@ -775,11 +772,15 @@ end: /// |:set|: for global-local options, both the global and local value are set /// unless otherwise specified with {scope}. /// +/// Note the options {win} and {buf} cannot be used together. +/// /// @param name Option name /// @param value New option value /// @param opts Optional parameters /// - scope: One of 'global' or 'local'. Analogous to /// |:setglobal| and |:setlocal|, respectively. +/// - win: |window-ID|. Used for setting window local option. +/// - buf: Buffer number. Used for setting buffer local option. /// @param[out] err Error details, if any void nvim_set_option_value(String name, Object value, Dict(option) *opts, Error *err) FUNC_API_SINCE(9) @@ -799,6 +800,36 @@ void nvim_set_option_value(String name, Object value, Dict(option) *opts, Error return; } + int opt_type = SREQ_GLOBAL; + void *to = NULL; + + if (opts->win.type == kObjectTypeInteger) { + opt_type = SREQ_WIN; + to = find_window_by_handle((int)opts->win.data.integer, err); + } else if (HAS_KEY(opts->win)) { + api_set_error(err, kErrorTypeValidation, "invalid value for key: win"); + return; + } + + if (opts->buf.type == kObjectTypeInteger) { + scope = OPT_LOCAL; + opt_type = SREQ_BUF; + to = find_buffer_by_handle((int)opts->buf.data.integer, err); + } else if (HAS_KEY(opts->buf)) { + api_set_error(err, kErrorTypeValidation, "invalid value for key: buf"); + return; + } + + if (HAS_KEY(opts->scope) && HAS_KEY(opts->buf)) { + api_set_error(err, kErrorTypeValidation, "scope and buf cannot be used together"); + return; + } + + if (HAS_KEY(opts->win) && HAS_KEY(opts->buf)) { + api_set_error(err, kErrorTypeValidation, "buf and win cannot be used together"); + return; + } + long numval = 0; char *stringval = NULL; @@ -820,10 +851,7 @@ void nvim_set_option_value(String name, Object value, Dict(option) *opts, Error return; } - char *e = set_option_value(name.data, numval, stringval, scope); - if (e) { - api_set_error(err, kErrorTypeException, "%s", e); - } + set_option_value_for(name.data, numval, stringval, scope, opt_type, to, err); } /// Gets the option information for all options. @@ -1214,7 +1242,6 @@ static void term_close(void *data) channel_decref(chan); } - /// Send data to channel `id`. For a job, it writes it to the /// stdin of the process. For the stdio channel |channel-stdio|, /// it writes to Nvim's stdout. For an internal terminal instance @@ -1904,13 +1931,13 @@ static void write_msg(String message, bool to_err) static char out_line_buf[LINE_BUFFER_SIZE], err_line_buf[LINE_BUFFER_SIZE]; #define PUSH_CHAR(i, pos, line_buf, msg) \ - if (message.data[i] == NL || pos == LINE_BUFFER_SIZE - 1) { \ - line_buf[pos] = NUL; \ + if (message.data[i] == NL || (pos) == LINE_BUFFER_SIZE - 1) { \ + (line_buf)[pos] = NUL; \ msg(line_buf); \ - pos = 0; \ + (pos) = 0; \ continue; \ } \ - line_buf[pos++] = message.data[i]; + (line_buf)[(pos)++] = message.data[i]; no_wait_return++; for (uint32_t i = 0; i < message.size; i++) { @@ -2140,8 +2167,8 @@ Array nvim__inspect_cell(Integer grid, Integer row, Integer col, Error *err) } } - if (row < 0 || row >= g->Rows - || col < 0 || col >= g->Columns) { + if (row < 0 || row >= g->rows + || col < 0 || col >= g->cols) { return ret; } size_t off = g->line_offset[(size_t)row] + (size_t)col; @@ -2161,7 +2188,6 @@ void nvim__screenshot(String path) ui_call_screenshot(path); } - /// Deletes an uppercase/file named mark. See |mark-motions|. /// /// @note fails with error if a lowercase or buffer local named mark is used. @@ -2274,8 +2300,9 @@ Array nvim_get_mark(String name, Dictionary opts, Error *err) /// - fillchar: (string) Character to fill blank spaces in the statusline (see /// 'fillchars'). Treated as single-width even if it isn't. /// - highlights: (boolean) Return highlight information. +/// - use_winbar: (boolean) Evaluate winbar instead of statusline. /// - use_tabline: (boolean) Evaluate tabline instead of statusline. When |TRUE|, {winid} -/// is ignored. +/// is ignored. Mutually exclusive with {use_winbar}. /// /// @param[out] err Error details, if any. /// @return Dictionary containing statusline information, with these keys: @@ -2294,6 +2321,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * int maxwidth; int fillchar = 0; Window window = 0; + bool use_winbar = false; bool use_tabline = false; bool highlights = false; @@ -2313,7 +2341,6 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * window = (Window)opts->winid.data.integer; } - if (HAS_KEY(opts->fillchar)) { if (opts->fillchar.type != kObjectTypeString || opts->fillchar.data.string.size == 0 || ((size_t)utf_ptr2len(opts->fillchar.data.string.data) @@ -2323,7 +2350,6 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * } fillchar = utf_ptr2char(opts->fillchar.data.string.data); } - if (HAS_KEY(opts->highlights)) { highlights = api_object_to_bool(opts->highlights, "highlights", false, err); @@ -2331,7 +2357,13 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * return result; } } + if (HAS_KEY(opts->use_winbar)) { + use_winbar = api_object_to_bool(opts->use_winbar, "use_winbar", false, err); + if (ERROR_SET(err)) { + return result; + } + } if (HAS_KEY(opts->use_tabline)) { use_tabline = api_object_to_bool(opts->use_tabline, "use_tabline", false, err); @@ -2339,6 +2371,10 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * return result; } } + if (use_winbar && use_tabline) { + api_set_error(err, kErrorTypeValidation, "use_winbar and use_tabline are mutually exclusive"); + return result; + } win_T *wp, *ewp; @@ -2348,7 +2384,6 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * fillchar = ' '; } else { wp = find_window_by_handle(window, err); - if (wp == NULL) { api_set_error(err, kErrorTypeException, "unknown winid %d", window); return result; @@ -2356,8 +2391,12 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * ewp = wp; if (fillchar == 0) { - int attr; - fillchar = fillchar_status(&attr, wp); + if (use_winbar) { + fillchar = wp->w_p_fcs_chars.wbr; + } else { + int attr; + fillchar = fillchar_status(&attr, wp); + } } } @@ -2369,7 +2408,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * maxwidth = (int)opts->maxwidth.data.integer; } else { - maxwidth = (use_tabline || global_stl_height() > 0) ? Columns : wp->w_width; + maxwidth = (use_tabline || (!use_winbar && global_stl_height() > 0)) ? Columns : wp->w_width; } char buf[MAXPATHL]; @@ -2404,7 +2443,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * // add the default highlight at the beginning of the highlight list if (hltab->start == NULL || ((char *)hltab->start - buf) != 0) { Dictionary hl_info = ARRAY_DICT_INIT; - grpname = get_default_stl_hl(wp); + grpname = get_default_stl_hl(wp, use_winbar); PUT(hl_info, "start", INTEGER_OBJ(0)); PUT(hl_info, "group", CSTR_TO_OBJ(grpname)); @@ -2418,22 +2457,18 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * PUT(hl_info, "start", INTEGER_OBJ((char *)sp->start - buf)); if (sp->userhl == 0) { - grpname = get_default_stl_hl(wp); + grpname = get_default_stl_hl(wp, use_winbar); } else if (sp->userhl < 0) { grpname = (char *)syn_id2name(-sp->userhl); } else { snprintf(user_group, sizeof(user_group), "User%d", sp->userhl); grpname = user_group; } - PUT(hl_info, "group", CSTR_TO_OBJ(grpname)); - ADD(hl_values, DICTIONARY_OBJ(hl_info)); } - PUT(result, "highlights", ARRAY_OBJ(hl_values)); } - PUT(result, "str", CSTR_TO_OBJ((char *)buf)); return result; diff --git a/src/nvim/api/vimscript.c b/src/nvim/api/vimscript.c index 42101af7f0..e71f1a11ec 100644 --- a/src/nvim/api/vimscript.c +++ b/src/nvim/api/vimscript.c @@ -34,7 +34,7 @@ /// Unlike |nvim_command()| this function supports heredocs, script-scope (s:), /// etc. /// -/// On execution error: fails with VimL error, does not update v:errmsg. +/// On execution error: fails with VimL error, updates v:errmsg. /// /// @see |execute()| /// @see |nvim_command()| @@ -98,7 +98,7 @@ theend: /// Executes an Ex command. /// -/// On execution error: fails with VimL error, does not update v:errmsg. +/// On execution error: fails with VimL error, updates v:errmsg. /// /// Prefer using |nvim_cmd()| or |nvim_exec()| over this. To evaluate multiple lines of Vim script /// or an Ex command directly, use |nvim_exec()|. To construct an Ex command using a structured @@ -118,7 +118,7 @@ void nvim_command(String command, Error *err) /// Evaluates a VimL |expression|. /// Dictionaries and Lists are recursively expanded. /// -/// On execution error: fails with VimL error, does not update v:errmsg. +/// On execution error: fails with VimL error, updates v:errmsg. /// /// @param expr VimL expression string /// @param[out] err Error details, if any @@ -226,7 +226,7 @@ free_vim_args: /// Calls a VimL function with the given arguments. /// -/// On execution error: fails with VimL error, does not update v:errmsg. +/// On execution error: fails with VimL error, updates v:errmsg. /// /// @param fn Function to call /// @param args Function arguments packed in an Array @@ -240,7 +240,7 @@ Object nvim_call_function(String fn, Array args, Error *err) /// Calls a VimL |Dictionary-function| with the given arguments. /// -/// On execution error: fails with VimL error, does not update v:errmsg. +/// On execution error: fails with VimL error, updates v:errmsg. /// /// @param dict Dictionary, or String evaluating to a VimL |self| dict /// @param fn Name of the function defined on the VimL dict @@ -996,6 +996,8 @@ end: /// such as having spaces inside a command argument, expanding filenames in a command that otherwise /// doesn't expand filenames, etc. /// +/// On execution error: fails with VimL error, updates v:errmsg. +/// /// @see |nvim_exec()| /// @see |nvim_command()| /// @@ -1302,20 +1304,23 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error capture_ga = &capture_local; } - try_start(); - if (output) { - msg_silent++; - } + TRY_WRAP({ + try_start(); + if (output) { + msg_silent++; + } - WITH_SCRIPT_CONTEXT(channel_id, { - execute_cmd(&ea, &cmdinfo); - }); + WITH_SCRIPT_CONTEXT(channel_id, { + execute_cmd(&ea, &cmdinfo); + }); - if (output) { - capture_ga = save_capture_ga; - msg_silent = save_msg_silent; - } - try_end(err); + if (output) { + capture_ga = save_capture_ga; + msg_silent = save_msg_silent; + } + + try_end(err); + }); if (ERROR_SET(err)) { goto clear_ga; diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c index 0d8bdbec61..898d95f49a 100644 --- a/src/nvim/api/win_config.c +++ b/src/nvim/api/win_config.c @@ -22,7 +22,6 @@ # include "api/win_config.c.generated.h" #endif - /// Open a new window. /// /// Currently this is used to open floating and external windows. @@ -590,7 +589,6 @@ static bool parse_float_config(Dict(float_config) *config, FloatConfig *fconfig, return false; } - if (HAS_KEY(config->focusable)) { fconfig->focusable = api_object_to_bool(config->focusable, "'focusable' key", false, err); if (ERROR_SET(err)) { diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c index 3a3a65f812..9f2afc67a6 100644 --- a/src/nvim/api/window.c +++ b/src/nvim/api/window.c @@ -373,7 +373,6 @@ Boolean nvim_win_is_valid(Window window) return ret; } - /// Closes the window and hide the buffer it contains (like |:hide| with a /// |window-ID|). /// diff --git a/src/nvim/arabic.c b/src/nvim/arabic.c index e76a75d37a..130ce65b86 100644 --- a/src/nvim/arabic.c +++ b/src/nvim/arabic.c @@ -244,7 +244,6 @@ #define a_BYTE_ORDER_MARK 0xfeff - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "arabic.c.generated.h" #endif diff --git a/src/nvim/ascii.h b/src/nvim/ascii.h index 692db40c0d..b1241166bf 100644 --- a/src/nvim/ascii.h +++ b/src/nvim/ascii.h @@ -75,7 +75,6 @@ #define Ctrl_HAT 30 // ^ #define Ctrl__ 31 - // Character that separates dir names in a path. #ifdef BACKSLASH_IN_FILENAME # define PATHSEP psepc diff --git a/src/nvim/assert.h b/src/nvim/assert.h index bc5260b914..ad92d9a2af 100644 --- a/src/nvim/assert.h +++ b/src/nvim/assert.h @@ -108,8 +108,6 @@ # define STATIC_ASSERT_STATEMENT STATIC_ASSERT_EXPR #endif -// uncrustify:off - #define ASSERT_CONCAT_(a, b) a##b #define ASSERT_CONCAT(a, b) ASSERT_CONCAT_(a, b) // These can't be used after statements in c89. @@ -125,8 +123,6 @@ ((enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(e)), }) 0) #endif -// uncrustify:on - /// @def STRICT_ADD /// @brief Adds (a + b) and stores result in `c`. Aborts on overflow. /// diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua index 9e3eb06752..93a870fe04 100644 --- a/src/nvim/auevents.lua +++ b/src/nvim/auevents.lua @@ -70,6 +70,8 @@ return { 'InsertEnter', -- when entering Insert mode 'InsertLeave', -- just after leaving Insert mode 'InsertLeavePre', -- just before leaving Insert mode + 'LspAttach', -- after an LSP client attaches to a buffer + 'LspDetach', -- after an LSP client detaches from a buffer 'MenuPopup', -- just before popup menu is displayed 'ModeChanged', -- after changing the mode 'OptionSet', -- after setting any option @@ -133,6 +135,8 @@ return { nvim_specific = { BufModifiedSet=true, DiagnosticChanged=true, + LspAttach=true, + LspDetach=true, RecordingEnter=true, RecordingLeave=true, Signal=true, diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c index 6c7950fdd1..31efce13f6 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -126,7 +126,6 @@ static void augroup_map_del(int id, char *name) } } - static inline const char *get_deleted_augroup(void) FUNC_ATTR_ALWAYS_INLINE { if (deleted_augroup == NULL) { @@ -190,7 +189,18 @@ static void aupat_show(AutoPat *ap, event_T event, int previous_group) if (got_int) { return; } - msg_outtrans((char_u *)aucmd_exec_to_string(ac, ac->exec)); + + char *exec_to_string = aucmd_exec_to_string(ac, ac->exec); + if (ac->desc != NULL) { + size_t msglen = 100; + char *msg = (char *)xmallocz(msglen); + snprintf(msg, msglen, "%s [%s]", exec_to_string, ac->desc); + msg_outtrans((char_u *)msg); + XFREE_CLEAR(msg); + } else { + msg_outtrans((char_u *)exec_to_string); + } + XFREE_CLEAR(exec_to_string); if (p_verbose > 0) { last_set_msg(ac->script_ctx); } @@ -377,7 +387,6 @@ static void au_cleanup(void) au_need_clean = false; } - // Get the first AutoPat for a particular event. AutoPat *au_get_autopat_for_event(event_T event) FUNC_ATTR_PURE @@ -657,7 +666,6 @@ const char *event_nr2name(event_T event) return "Unknown"; } - /// Return true if "event" is included in 'eventignore'. /// /// @param event event to check @@ -1006,7 +1014,6 @@ int autocmd_register(int64_t id, event_T event, char *pat, int patlen, int group findgroup = group; } - // detect special <buffer[=X]> buffer-local patterns int is_buflocal = aupat_is_buflocal(pat, patlen); int buflocal_nr = 0; @@ -1136,8 +1143,6 @@ int autocmd_register(int64_t id, event_T event, char *pat, int patlen, int group // perhaps: <lua>DESCRIPTION or similar if (desc != NULL) { ac->desc = xstrdup(desc); - } else { - ac->desc = aucmd_exec_default_desc(aucmd); } return OK; @@ -1220,7 +1225,7 @@ int do_doautocmd(char *arg_start, bool do_msg, bool *did_something) // Loop over the events. while (*arg && !ends_excmd(*arg) && !ascii_iswhite(*arg)) { if (apply_autocmds_group(event_name2nr(arg, &arg), fname, NULL, true, group, - curbuf, NULL)) { + curbuf, NULL, NULL)) { nothing_done = false; } } @@ -1505,7 +1510,7 @@ win_found: /// @return true if some commands were executed. bool apply_autocmds(event_T event, char *fname, char *fname_io, bool force, buf_T *buf) { - return apply_autocmds_group(event, fname, fname_io, force, AUGROUP_ALL, buf, NULL); + return apply_autocmds_group(event, fname, fname_io, force, AUGROUP_ALL, buf, NULL, NULL); } /// Like apply_autocmds(), but with extra "eap" argument. This takes care of @@ -1522,7 +1527,7 @@ bool apply_autocmds(event_T event, char *fname, char *fname_io, bool force, buf_ bool apply_autocmds_exarg(event_T event, char *fname, char *fname_io, bool force, buf_T *buf, exarg_T *eap) { - return apply_autocmds_group(event, fname, fname_io, force, AUGROUP_ALL, buf, eap); + return apply_autocmds_group(event, fname, fname_io, force, AUGROUP_ALL, buf, eap, NULL); } /// Like apply_autocmds(), but handles the caller's retval. If the script @@ -1546,7 +1551,7 @@ bool apply_autocmds_retval(event_T event, char *fname, char *fname_io, bool forc } bool did_cmd = apply_autocmds_group(event, fname, fname_io, force, - AUGROUP_ALL, buf, NULL); + AUGROUP_ALL, buf, NULL, NULL); if (did_cmd && aborting()) { *retval = FAIL; } @@ -1595,7 +1600,7 @@ bool trigger_cursorhold(void) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT /// /// @return true if some commands were executed. bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force, int group, - buf_T *buf, exarg_T *eap) + buf_T *buf, exarg_T *eap, Object *data) { char *sfname = NULL; // short file name bool retval = false; @@ -1811,6 +1816,9 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force patcmd.next = active_apc_list; active_apc_list = &patcmd; + // Attach data to command + patcmd.data = data; + // set v:cmdarg (only when there is a matching pattern) save_cmdbang = (long)get_vim_var_nr(VV_CMDBANG); if (eap != NULL) { @@ -1841,7 +1849,6 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force reset_lnums(); } - if (eap != NULL) { (void)set_cmdarg(NULL, save_cmdarg); set_vim_var_nr(VV_CMDBANG, save_cmdbang); @@ -2026,6 +2033,10 @@ static bool call_autocmd_callback(const AutoCmd *ac, const AutoPatCmd *apc) PUT(data, "file", CSTR_TO_OBJ((char *)autocmd_fname)); PUT(data, "buf", INTEGER_OBJ(autocmd_bufnr)); + if (apc->data) { + PUT(data, "data", copy_object(*apc->data)); + } + int group = apc->curpat->group; switch (group) { case AUGROUP_ERROR: @@ -2111,8 +2122,10 @@ char *getnextac(int c, void *cookie, int indent, bool do_concat) if (p_verbose >= 9) { verbose_enter_scroll(); - smsg(_("autocommand %s"), aucmd_exec_to_string(ac, ac->exec)); + char *exec_to_string = aucmd_exec_to_string(ac, ac->exec); + smsg(_("autocommand %s"), exec_to_string); msg_puts("\n"); // don't overwrite this either + XFREE_CLEAR(exec_to_string); verbose_leave_scroll(); } @@ -2463,45 +2476,42 @@ bool autocmd_delete_id(int64_t id) // =========================================================================== // AucmdExecutable Functions // =========================================================================== -char *aucmd_exec_default_desc(AucmdExecutable acc) + +/// Generate a string description of a callback +static char *aucmd_callback_to_string(Callback cb) { + // NOTE: this function probably belongs in a helper + size_t msglen = 100; + char *msg = (char *)xmallocz(msglen); - switch (acc.type) { - case CALLABLE_CB: - switch (acc.callable.cb.type) { - case kCallbackLua: { - char *msg = (char *)xmallocz(msglen); - snprintf(msg, msglen, "<Lua function %d>", acc.callable.cb.data.luaref); - return msg; - } - case kCallbackFuncref: { - // TODO(tjdevries): Is this enough space for this? - char *msg = (char *)xmallocz(msglen); - snprintf(msg, msglen, "<vim function: %s>", acc.callable.cb.data.funcref); - return msg; - } - case kCallbackPartial: { - char *msg = (char *)xmallocz(msglen); - snprintf(msg, msglen, "<vim partial: %s>", acc.callable.cb.data.partial->pt_name); - return msg; - } - default: - return NULL; - } + switch (cb.type) { + case kCallbackLua: + snprintf(msg, msglen, "<lua: %d>", cb.data.luaref); + break; + case kCallbackFuncref: + // TODO(tjdevries): Is this enough space for this? + snprintf(msg, msglen, "<vim function: %s>", cb.data.funcref); + break; + case kCallbackPartial: + snprintf(msg, msglen, "<vim partial: %s>", cb.data.partial->pt_name); + break; default: - return NULL; + snprintf(msg, msglen, "%s", ""); + break; } + return msg; } +/// Generate a string description for the command/callback of an autocmd char *aucmd_exec_to_string(AutoCmd *ac, AucmdExecutable acc) FUNC_ATTR_PURE { switch (acc.type) { case CALLABLE_EX: - return acc.callable.cmd; + return xstrdup(acc.callable.cmd); case CALLABLE_CB: - return ac->desc; + return aucmd_callback_to_string(acc.callable.cb); case CALLABLE_NONE: return "This is not possible"; } @@ -2636,7 +2646,6 @@ static bool arg_autocmd_flag_get(bool *flag, char **cmd_ptr, char *pattern, int return false; } - // UI Enter void do_autocmd_uienter(uint64_t chanid, bool attached) { diff --git a/src/nvim/autocmd.h b/src/nvim/autocmd.h index d3503672fd..a085a03455 100644 --- a/src/nvim/autocmd.h +++ b/src/nvim/autocmd.h @@ -57,10 +57,10 @@ typedef struct AutoPatCmd { char *tail; // tail of fname event_T event; // current event int arg_bufnr; // initially equal to <abuf>, set to zero when buf is deleted + Object *data; // arbitrary data struct AutoPatCmd *next; // chain of active apc-s for auto-invalidation } AutoPatCmd; - // Set by the apply_autocmds_group function if the given event is equal to // EVENT_FILETYPE. Used by the readfile function in order to determine if // EVENT_BUFREADPOST triggered the EVENT_FILETYPE. @@ -69,7 +69,6 @@ typedef struct AutoPatCmd { // apply_autocmds_group. EXTERN bool au_did_filetype INIT(= false); - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "autocmd.h.generated.h" #endif diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 4b1aea5720..4c3f1308b3 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1025,11 +1025,9 @@ char *do_bufdel(int command, char_u *arg, int addr_count, int start_bnr, int end } } - return errormsg; } - /// Make the current buffer empty. /// Used when it is wiped out and it's the last buffer. static int empty_curbuf(int close_others, int forceit, int action) @@ -1180,7 +1178,6 @@ int do_buffer(int action, int start, int dir, int count, int forceit) return FAIL; } - // delete buffer "buf" from memory and/or the list if (unload) { int forward; @@ -1425,7 +1422,6 @@ int do_buffer(int action, int start, int dir, int count, int forceit) return OK; } - /// Set current buffer to "buf". Executes autocommands and closes current /// buffer. /// @@ -1585,7 +1581,6 @@ void enter_buffer(buf_T *buf) scroll_cursor_halfway(false); // redisplay at correct position } - // Change directories when the 'acd' option is set. do_autochdir(); @@ -1932,7 +1927,6 @@ void free_buf_options(buf_T *buf, int free_p_ff) clear_string_option(&buf->b_p_menc); } - /// Get alternate file "n". /// Set linenr to "lnum" or altfpos.lnum if "lnum" == 0. /// Also set cursor column to altfpos.col if 'startofline' is not set. @@ -2357,7 +2351,6 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) return count == 0 ? FAIL : OK; } - /// Check for a match on the file name for buffer "buf" with regprog "prog". /// /// @param ignore_case When true, ignore case. Use 'fic' otherwise. @@ -2491,7 +2484,6 @@ void buflist_setfpos(buf_T *const buf, win_T *const win, linenr_T lnum, colnr_T } } - /// Check that "wip" has 'diff' set and the diff is only for another tab page. /// That's because a diff is local to a tab page. static bool wininfo_other_tab_diff(wininfo_T *wip) @@ -3113,7 +3105,6 @@ void col_print(char_u *buf, size_t buflen, int col, int vcol) static char_u *lasttitle = NULL; static char_u *lasticon = NULL; - /// Put the title name in the title bar and icon of the window. void maketitle(void) { @@ -3331,7 +3322,6 @@ static bool value_change(char_u *str, char_u **last) return false; } - /// Set current window title void resettitle(void) { @@ -3356,7 +3346,6 @@ typedef enum { kNumBaseHexadecimal = 16, } NumberBase; - /// Build a string from the status line items in "fmt". /// Return length of string in screen cells. /// @@ -3473,7 +3462,6 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san // so any user-visible characters must occur before here. char *out_end_p = (out + outlen) - 1; - // Proceed character by character through the statusline format string // fmt_p is the current position in the input buffer for (char *fmt_p = usefmt; *fmt_p;) { @@ -3915,7 +3903,6 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int use_san } } - // If the output of the expression needs to be evaluated // replace the %{} block with the result of evaluation if (reevaluate && str != NULL && *str != 0 @@ -4698,7 +4685,6 @@ void do_arg_all(int count, int forceit, int keep_tabs) old_curwin = curwin; old_curtab = curtab; - // Try closing all windows that are not in the argument list. // Also close windows that are not full width; // When 'hidden' or "forceit" set the buffer becomes hidden. @@ -4947,7 +4933,6 @@ void ex_buffer_all(exarg_T *eap) setpcmark(); - // Close superfluous windows (two windows for the same buffer). // Also close windows that are not full-width. if (had_tab > 0) { @@ -5098,7 +5083,6 @@ void ex_buffer_all(exarg_T *eap) } } - /// do_modelines() - process mode lines for the current file /// /// @param flags diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 2adeeadbca..b5980612f8 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -6,6 +6,8 @@ // for FILE #include <stdio.h> +#include "grid_defs.h" + typedef struct file_buffer buf_T; // Forward declaration // Reference to a buffer that stores the value of buf_free_count. @@ -233,6 +235,8 @@ typedef struct { #define w_p_sbr w_onebuf_opt.wo_sbr // 'showbreak' char_u *wo_stl; #define w_p_stl w_onebuf_opt.wo_stl // 'statusline' + char *wo_wbr; +#define w_p_wbr w_onebuf_opt.wo_wbr // 'winbar' int wo_scb; #define w_p_scb w_onebuf_opt.wo_scb // 'scrollbind' int wo_diff_saved; // options were saved for starting diff mode @@ -1235,6 +1239,7 @@ struct window_S { struct { int stl; int stlnc; + int wbr; int horiz; int horizup; int horizdown; @@ -1282,14 +1287,20 @@ struct window_S { // int w_winrow; // first row of window in screen int w_height; // number of rows in window, excluding - // status/command/winbar line(s) + // status/command line(s) int w_status_height; // number of status lines (0 or 1) + int w_winbar_height; // number of window bars (0 or 1) int w_wincol; // Leftmost column of window in screen. int w_width; // Width of window, excluding separation. int w_hsep_height; // Number of horizontal separator rows (0 or 1) int w_vsep_width; // Number of vertical separator columns (0 or 1). pos_save_T w_save_cursor; // backup of cursor pos and topline + int w_winrow_off; ///< offset from winrow to the inner window area + int w_wincol_off; ///< offset from wincol to the inner window area + ///< this includes float border but excludes special columns + ///< implemented in win_line() (i.e. signs, folds, numbers) + // inner size of window, which can be overridden by external UI int w_height_inner; int w_width_inner; @@ -1378,7 +1389,7 @@ struct window_S { // w_redr_type is REDRAW_TOP linenr_T w_redraw_top; // when != 0: first line needing redraw linenr_T w_redraw_bot; // when != 0: last line needing redraw - bool w_redr_status; // if true status line must be redrawn + bool w_redr_status; // if true statusline/winbar must be redrawn bool w_redr_border; // if true border must be redrawn // remember what is shown in the ruler for this window (if 'ruler' set) @@ -1408,6 +1419,7 @@ struct window_S { // A few options have local flags for P_INSECURE. uint32_t w_p_stl_flags; // flags for 'statusline' + uint32_t w_p_wbr_flags; // flags for 'winbar' uint32_t w_p_fde_flags; // flags for 'foldexpr' uint32_t w_p_fdt_flags; // flags for 'foldtext' int *w_p_cc_cols; // array of columns to highlight or NULL @@ -1481,6 +1493,16 @@ struct window_S { // Location list reference used in the location list window. // In a non-location list window, w_llist_ref is NULL. qf_info_T *w_llist_ref; + + // Status line click definitions + StlClickDefinition *w_status_click_defs; + // Size of the w_status_click_defs array + size_t w_status_click_defs_size; + + // Window bar click definitions + StlClickDefinition *w_winbar_click_defs; + // Size of the w_winbar_click_defs array + size_t w_winbar_click_defs_size; }; static inline int win_hl_attr(win_T *wp, int hlf) diff --git a/src/nvim/buffer_updates.c b/src/nvim/buffer_updates.c index 57f052ced0..cb08ba0cfb 100644 --- a/src/nvim/buffer_updates.c +++ b/src/nvim/buffer_updates.c @@ -186,7 +186,6 @@ void buf_updates_unload(buf_T *buf, bool can_reload) } } - void buf_updates_send_changes(buf_T *buf, linenr_T firstline, int64_t num_added, int64_t num_removed, bool send_tick) { diff --git a/src/nvim/change.c b/src/nvim/change.c index 94e5a19edc..9fd5083fd3 100644 --- a/src/nvim/change.c +++ b/src/nvim/change.c @@ -615,7 +615,6 @@ void ins_char_bytes(char_u *buf, size_t charlen) oldlen = (size_t)utfc_ptr2len((char *)oldp + col); } - // Push the replaced bytes onto the replace stack, so that they can be // put back when BS is used. The bytes of a multi-byte character are // done the other way around, so that the first byte is popped off @@ -1033,8 +1032,7 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment) // If 'autoindent' and/or 'smartindent' is set, try to figure out what // indent to use for the new line. - if (curbuf->b_p_ai - || do_si) { + if (curbuf->b_p_ai || do_si) { // count white space on current line newindent = get_indent_str_vtab(saved_line, curbuf->b_p_ts, @@ -1189,7 +1187,7 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment) if (flags & OPENLINE_DO_COM) { lead_len = get_leader_len(saved_line, &lead_flags, dir == BACKWARD, true); if (lead_len == 0 && curbuf->b_p_cin && do_cindent && dir == FORWARD - && !has_format_option(FO_NO_OPEN_COMS)) { + && (!has_format_option(FO_NO_OPEN_COMS) || (flags & OPENLINE_FORMAT))) { // Check for a line comment after code. comment_start = check_linecomment(saved_line); if (comment_start != MAXCOL) { @@ -1482,8 +1480,7 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment) } // Recompute the indent, it may have changed. - if (curbuf->b_p_ai - || do_si) { + if (curbuf->b_p_ai || do_si) { newindent = get_indent_str_vtab(leader, curbuf->b_p_ts, curbuf->b_p_vts_array, false); @@ -1526,15 +1523,13 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment) // if a new indent will be set below, remove the indent that // is in the comment leader - if (newindent - || did_si) { + if (newindent || did_si) { while (lead_len && ascii_iswhite(*leader)) { lead_len--; newcol--; leader++; } } - did_si = can_si = false; } else if (comment_end != NULL) { // We have finished a comment, so we don't use the leader. @@ -1646,8 +1641,7 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment) } inhibit_delete_count++; - if (newindent - || did_si) { + if (newindent || did_si) { curwin->w_cursor.lnum++; if (did_si) { int sw = get_sw_value(curbuf); @@ -1764,6 +1758,7 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment) } else { vreplace_mode = 0; } + // May do lisp indenting. if (!p_paste && leader == NULL @@ -1772,11 +1767,13 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment) fixthisline(get_lisp_indent); ai_col = (colnr_T)getwhitecols_curline(); } + // May do indenting after opening a new line. if (do_cindent) { do_c_expr_indent(); ai_col = (colnr_T)getwhitecols_curline(); } + if (vreplace_mode != 0) { State = vreplace_mode; } diff --git a/src/nvim/change.h b/src/nvim/change.h index e7c8a2b031..fdfa8a29ec 100644 --- a/src/nvim/change.h +++ b/src/nvim/change.h @@ -5,11 +5,12 @@ #include "nvim/pos.h" // for linenr_T // flags for open_line() -#define OPENLINE_DELSPACES 1 // delete spaces after cursor -#define OPENLINE_DO_COM 2 // format comments -#define OPENLINE_KEEPTRAIL 4 // keep trailing spaces -#define OPENLINE_MARKFIX 8 // fix mark positions -#define OPENLINE_COM_LIST 16 // format comments with list/2nd line indent +#define OPENLINE_DELSPACES 0x01 // delete spaces after cursor +#define OPENLINE_DO_COM 0x02 // format comments +#define OPENLINE_KEEPTRAIL 0x04 // keep trailing spaces +#define OPENLINE_MARKFIX 0x08 // fix mark positions +#define OPENLINE_COM_LIST 0x10 // format comments with list/2nd line indent +#define OPENLINE_FORMAT 0x20 // formatting long comment #ifdef INCLUDE_GENERATED_DECLARATIONS # include "change.h.generated.h" diff --git a/src/nvim/channel.c b/src/nvim/channel.c index 6278f84190..7a71be58c1 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -279,13 +279,11 @@ static void channel_destroy_early(Channel *chan) multiqueue_put(main_loop.events, free_channel_event, 1, chan); } - static void close_cb(Stream *stream, void *data) { channel_decref(data); } - /// Starts a job and returns the associated channel /// /// @param[in] argv Arguments vector specifying the command to run, @@ -416,7 +414,6 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout, CallbackReader return chan; } - uint64_t channel_connect(bool tcp, const char *address, bool rpc, CallbackReader on_output, int timeout, const char **error) { @@ -555,7 +552,6 @@ size_t channel_send(uint64_t id, char *data, size_t len, bool data_owned, const goto retfree; } - Stream *in = channel_instream(chan); if (in->closed) { *error = _("Can't send data to closed stream"); @@ -756,7 +752,6 @@ static void channel_callback_call(Channel *chan, CallbackReader *reader) tv_clear(&rettv); } - /// Open terminal for channel /// /// Channel `chan` is assumed to be an open pty channel, diff --git a/src/nvim/channel.h b/src/nvim/channel.h index 5cec5731eb..0f1b481792 100644 --- a/src/nvim/channel.h +++ b/src/nvim/channel.h @@ -149,5 +149,4 @@ static inline Stream *channel_outstream(Channel *chan) abort(); } - #endif // NVIM_CHANNEL_H diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 082791ffd1..e20c0e3f3f 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -34,7 +34,6 @@ # include "charset.c.generated.h" #endif - static bool chartab_initialized = false; // b_chartab[] is an array with 256 bits, each bit representing one of the @@ -495,7 +494,6 @@ char_u *str_foldcase(char_u *str, int orglen, char_u *buf, int buflen) i += utfc_ptr2len((char *)STR_PTR(i)); } - if (buf == NULL) { return (char_u *)ga.ga_data; } @@ -1558,10 +1556,10 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len, cons } \ const uvarnumber_T digit = (uvarnumber_T)(conv); \ /* avoid ubsan error for overflow */ \ - if (un < UVARNUMBER_MAX / base \ - || (un == UVARNUMBER_MAX / base \ - && (base != 10 || digit <= UVARNUMBER_MAX % 10))) { \ - un = base * un + digit; \ + if (un < UVARNUMBER_MAX / (base) \ + || (un == UVARNUMBER_MAX / (base) \ + && ((base) != 10 || digit <= UVARNUMBER_MAX % 10))) { \ + un = (base) * un + digit; \ } else { \ un = UVARNUMBER_MAX; \ } \ diff --git a/src/nvim/cursor_shape.c b/src/nvim/cursor_shape.c index b69505d7c9..0248c25dfa 100644 --- a/src/nvim/cursor_shape.c +++ b/src/nvim/cursor_shape.c @@ -315,7 +315,6 @@ bool cursor_mode_uses_syn_id(int syn_id) return false; } - /// Return the index into shape_table[] for the current mode. int cursor_get_mode_idx(void) FUNC_ATTR_PURE diff --git a/src/nvim/debugger.c b/src/nvim/debugger.c index b2ac28629c..30d6ea2505 100644 --- a/src/nvim/debugger.c +++ b/src/nvim/debugger.c @@ -74,7 +74,6 @@ void do_debug(char_u *cmd) #define CMD_UP 9 #define CMD_DOWN 10 - RedrawingDisabled++; // don't redisplay the window no_wait_return++; // don't wait for return did_emsg = false; // don't use error from debugged stuff @@ -445,7 +444,7 @@ bool dbg_check_skipped(exarg_T *eap) static garray_T dbg_breakp = { 0, 0, sizeof(struct debuggy), 4, NULL }; #define BREAKP(idx) (((struct debuggy *)dbg_breakp.ga_data)[idx]) -#define DEBUGGY(gap, idx) (((struct debuggy *)gap->ga_data)[idx]) +#define DEBUGGY(gap, idx) (((struct debuggy *)(gap)->ga_data)[idx]) static int last_breakp = 0; // nr of last defined breakpoint // Profiling uses file and func names similar to breakpoints. diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c index 28257dd7b5..b1a22b3294 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -180,7 +180,6 @@ static bool decor_virt_pos(Decoration decor) return kv_size(decor.virt_text) || decor.ui_watched; } - bool decor_redraw_start(buf_T *buf, int top_row, DecorState *state) { state->top_row = top_row; @@ -530,7 +529,6 @@ void decor_add_ephemeral(int start_row, int start_col, int end_row, int end_col, decor_add(&decor_state, start_row, start_col, end_row, end_col, decor, true, ns_id, mark_id); } - int decor_virt_lines(win_T *wp, linenr_T lnum, VirtLines *lines) { buf_T *buf = wp->w_buffer; diff --git a/src/nvim/decoration.h b/src/nvim/decoration.h index 9a82af8661..8f28442d41 100644 --- a/src/nvim/decoration.h +++ b/src/nvim/decoration.h @@ -31,10 +31,8 @@ EXTERN const char *const hl_mode_str[] INIT(= { "", "replace", "combine", "blend typedef kvec_t(VirtTextChunk) VirtText; #define VIRTTEXT_EMPTY ((VirtText)KV_INITIAL_VALUE) - typedef kvec_t(struct virt_line { VirtText line; bool left_col; }) VirtLines; - struct Decoration { VirtText virt_text; VirtLines virt_lines; diff --git a/src/nvim/decoration_provider.c b/src/nvim/decoration_provider.c index ef27b2af1c..0f6a260247 100644 --- a/src/nvim/decoration_provider.c +++ b/src/nvim/decoration_provider.c @@ -140,7 +140,6 @@ void providers_invoke_line(win_T *wp, DecorProviders *providers, int row, bool * } } - /// For each provider invoke the 'buf' callback for a given buffer. /// /// @param buf Buffer @@ -158,7 +157,6 @@ void decor_providers_invoke_buf(buf_T *buf, DecorProviders *providers, char **er } } - /// For each provider invoke the 'end' callback /// /// @param providers Decoration providers diff --git a/src/nvim/diff.c b/src/nvim/diff.c index e8d54d7030..8c98c1ef23 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1371,7 +1371,6 @@ static void set_diff_option(win_T *wp, int value) curbuf = curwin->w_buffer; } - /// Set options in window "wp" for diff mode. /// /// @param addbuf Add buffer to diff. @@ -2036,7 +2035,6 @@ void diff_set_topline(win_T *fromwin, win_T *towin) } towin->w_topfill = 0; - // search for a change that includes "lnum" in the list of diffblocks. for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next) { if (lnum <= dp->df_lnum[fromidx] + dp->df_count[fromidx]) { diff --git a/src/nvim/digraph.c b/src/nvim/digraph.c index 1b536bdde6..b461082be0 100644 --- a/src/nvim/digraph.c +++ b/src/nvim/digraph.c @@ -1832,7 +1832,6 @@ static void printdigraph(const digr_T *dp, result_T *previous) msg_putchar('\n'); } - // Make msg_col a multiple of list_width by using spaces. if (msg_col % list_width != 0) { int spaces = (msg_col / list_width + 1) * list_width - msg_col; @@ -2016,7 +2015,6 @@ typedef struct { #define KMAP_MAXLEN 20 // maximum length of "from" or "to" - /// Set up key mapping tables for the 'keymap' option. /// /// @return NULL if OK, an error message for failure. This only needs to be diff --git a/src/nvim/edit.c b/src/nvim/edit.c index aa77c03b48..41fa34c31e 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -245,7 +245,6 @@ typedef struct insert_state { char_u *ptr; } InsertState; - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "edit.c.generated.h" #endif @@ -459,9 +458,8 @@ static void insert_enter(InsertState *s) where_paste_started.lnum = 0; can_cindent = true; - // The cursor line is not in a closed fold, unless 'insertmode' is set or - // restarting. - if (!p_im && did_restart_edit == 0) { + // The cursor line is not in a closed fold, unless restarting. + if (did_restart_edit == 0) { foldOpenCursor(); } @@ -473,7 +471,7 @@ static void insert_enter(InsertState *s) s->i = showmode(); } - if (!p_im && did_restart_edit == 0) { + if (did_restart_edit == 0) { change_warning(curbuf, s->i == 0 ? 0 : s->i + 1); } @@ -554,7 +552,7 @@ static int insert_check(VimState *state) } if (stop_insert_mode && !compl_started) { - // ":stopinsert" used or 'insertmode' reset + // ":stopinsert" used s->count = 0; return 0; // exit insert mode } @@ -576,7 +574,6 @@ static int insert_check(VimState *state) // When emsg() was called msg_scroll will have been set. msg_scroll = false; - // Open fold at the cursor line, according to 'foldopen'. if (fdo_flags & FDO_INSERT) { foldOpenCursor(); @@ -756,7 +753,6 @@ static int insert_execute(VimState *state, int key) } // CTRL-\ CTRL-N goes to Normal mode, - // CTRL-\ CTRL-G goes to mode selected with 'insertmode', // CTRL-\ CTRL-O is like CTRL-O but without moving the cursor if (s->c == Ctrl_BSL) { // may need to redraw when no more chars available now @@ -770,8 +766,6 @@ static int insert_execute(VimState *state, int key) // it's something else vungetc(s->c); s->c = Ctrl_BSL; - } else if (s->c == Ctrl_G && p_im) { - return 1; // continue } else { if (s->c == Ctrl_O) { ins_ctrl_o(); @@ -842,17 +836,6 @@ static int insert_execute(VimState *state, int key) return insert_handle_key(s); } - -/// Return true when need to go to Insert mode because of 'insertmode'. -/// -/// Don't do this when still processing a command or a mapping. -/// Don't do this when inside a ":normal" command. -bool goto_im(void) - FUNC_ATTR_PURE -{ - return p_im && stuff_empty() && typebuf_typed(); -} - static int insert_handle_key(InsertState *s) { // The big switch to handle a character in insert mode. @@ -884,26 +867,10 @@ static int insert_handle_key(InsertState *s) } } - // when 'insertmode' set, and not halfway through a mapping, don't leave - // Insert mode - if (goto_im()) { - if (got_int) { - (void)vgetc(); // flush all buffers - got_int = false; - } else { - vim_beep(BO_IM); - } - break; - } return 0; // exit insert mode - case Ctrl_Z: // suspend when 'insertmode' set - if (!p_im) { - goto normalchar; // insert CTRL-Z as normal char - } - do_cmdline_cmd("stop"); - ui_cursor_shape(); // may need to update cursor shape - break; + case Ctrl_Z: + goto normalchar; // insert CTRL-Z as normal char case Ctrl_O: // execute one command if (ctrl_x_mode == CTRL_X_OMNI) { @@ -934,17 +901,12 @@ static int insert_handle_key(InsertState *s) case K_SELECT: // end of Select mode mapping - ignore break; - case K_HELP: // Help key works like <ESC> <Help> case K_F1: case K_XF1: stuffcharReadbuff(K_HELP); - if (p_im) { - need_start_insertmode = true; - } return 0; // exit insert mode - case ' ': if (mod_mask != MOD_MASK_CTRL) { goto normalchar; @@ -956,7 +918,7 @@ static int insert_handle_key(InsertState *s) // For ^@ the trailing ESC will end the insert, unless there is an // error. if (stuff_inserted(NUL, 1L, (s->c == Ctrl_A)) == FAIL - && s->c != Ctrl_A && !p_im) { + && s->c != Ctrl_A) { return 0; // exit insert mode } s->inserted_space = false; @@ -1190,7 +1152,6 @@ check_pum: } break; - case K_S_TAB: // When not mapped, use like a normal TAB s->c = TAB; FALLTHROUGH; @@ -1236,7 +1197,7 @@ check_pum: } break; } - if (!ins_eol(s->c) && !p_im) { + if (!ins_eol(s->c)) { return 0; // out of memory } auto_format(false, false); @@ -1288,13 +1249,6 @@ check_pum: case Ctrl_L: // Whole line completion after ^X if (ctrl_x_mode != CTRL_X_WHOLE_LINE) { - // CTRL-L with 'insertmode' set: Leave Insert mode - if (p_im) { - if (echeck_abbr(Ctrl_L + ABBR_OFF)) { - break; - } - return 0; // exit insert mode - } goto normalchar; } FALLTHROUGH; @@ -1632,7 +1586,7 @@ void edit_putchar(int c, bool highlight) pc_col = 0; pc_status = PC_STATUS_UNSET; if (curwin->w_p_rl) { - pc_col += curwin->w_grid.Columns - 1 - curwin->w_wcol; + pc_col += curwin->w_grid.cols - 1 - curwin->w_wcol; const int fix_col = grid_fix_col(&curwin->w_grid, pc_col, pc_row); if (fix_col != pc_col) { @@ -1759,7 +1713,7 @@ void display_dollar(colnr_T col) char_u *p = get_cursor_line_ptr(); curwin->w_cursor.col -= utf_head_off(p, p + col); curs_columns(curwin, false); // Recompute w_wrow and w_wcol - if (curwin->w_wcol < curwin->w_grid.Columns) { + if (curwin->w_wcol < curwin->w_grid.cols) { edit_putchar('$', false); dollar_vcol = curwin->w_virtcol; } @@ -2111,7 +2065,6 @@ bool ctrl_x_mode_not_defined_yet(void) return ctrl_x_mode == CTRL_X_NOT_DEFINED_YET; } - /// Check that the "dict" or "tsr" option can be used. /// /// @param dict_opt check "dict" when true, "tsr" when false. @@ -2398,9 +2351,9 @@ static int ins_compl_add(char_u *const str, int len, char_u *const fname, } #define FREE_CPTEXT(cptext, cptext_allocated) \ do { \ - if (cptext != NULL && cptext_allocated) { \ + if ((cptext) != NULL && (cptext_allocated)) { \ for (size_t i = 0; i < CPT_COUNT; i++) { \ - xfree(cptext[i]); \ + xfree((cptext)[i]); \ } \ } \ } while (0) @@ -2648,7 +2601,6 @@ void completeopt_was_set(void) } } - /* * Start completion for the complete() function. * "startcol" is where the matched text starts (1 is first column). @@ -2712,13 +2664,11 @@ void set_completion(colnr_T startcol, list_T *list) ui_flush(); } - /* "compl_match_array" points the currently displayed list of entries in the * popup menu. It is NULL when there is no popup menu. */ static pumitem_T *compl_match_array = NULL; static int compl_match_arraysize; - /* * Remove any popup menu. */ @@ -3383,7 +3333,6 @@ static char_u *ins_compl_mode(void) return (char_u *)""; } - /* * Delete one character before the cursor and show the subset of the matches * that match the word that is now before the cursor. @@ -3799,6 +3748,7 @@ static bool ins_compl_prep(int c) } bool want_cindent = (can_cindent && cindent_on()); + // When completing whole lines: fix indent for 'cindent'. // Otherwise, break line if it's too long. if (compl_cont_mode == CTRL_X_WHOLE_LINE) { @@ -3968,7 +3918,6 @@ static buf_T *ins_compl_next_buf(buf_T *buf, int flag) return buf; } - /// Get the user-defined completion function name for completion 'type' static char_u *get_complete_funcname(int type) { @@ -5432,7 +5381,6 @@ static int ins_complete(int c, bool enable_pum) save_w_leftcol = curwin->w_leftcol; n = ins_compl_next(true, ins_compl_key2count(c), insert_match, false); - if (n > 1) { // all matches have been found compl_matches = n; } @@ -6285,6 +6233,7 @@ static void internal_format(int textwidth, int second_indent, int flags, int for open_line(FORWARD, OPENLINE_DELSPACES + OPENLINE_MARKFIX + (fo_white_par ? OPENLINE_KEEPTRAIL : 0) + (do_comments ? OPENLINE_DO_COM : 0) + + OPENLINE_FORMAT + ((flags & INSCHAR_COM_LIST) ? OPENLINE_COM_LIST : 0), ((flags & INSCHAR_COM_LIST) ? second_indent : old_indent), &did_do_comment); @@ -7792,7 +7741,6 @@ static void ins_reg(void) add_to_showcmd_c(Ctrl_R); } - // Don't map the register name. This also prevents the mode message to be // deleted when ESC is hit. no_mapping++; @@ -7963,10 +7911,8 @@ static bool ins_esc(long *count, int cmdchar, bool nomove) } if (!arrow_used) { // Don't append the ESC for "r<CR>" and "grx". - // When 'insertmode' is set only CTRL-L stops Insert mode. Needed for - // when "count" is non-zero. if (cmdchar != 'r' && cmdchar != 'v') { - AppendToRedobuff(p_im ? "\014" : ESC_STR); + AppendToRedobuff(ESC_STR); } /* @@ -8039,7 +7985,6 @@ static bool ins_esc(long *count, int cmdchar, bool nomove) } } - State = MODE_NORMAL; may_trigger_modechanged(); // need to position cursor again when on a TAB @@ -8242,7 +8187,6 @@ static void ins_del(void) AppendCharToRedobuff(K_DEL); } - /* * Delete one character for ins_bs(). */ @@ -8412,9 +8356,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) mincol = 0; // keep indent if (mode == BACKSPACE_LINE - && (curbuf->b_p_ai - || cindent_on() - ) + && (curbuf->b_p_ai || cindent_on()) && !revins_on) { save_col = curwin->w_cursor.col; beginline(BL_WHITE); @@ -8670,7 +8612,6 @@ static void ins_mousescroll(int dir) } } - static void ins_left(void) { pos_T tpos; @@ -9196,7 +9137,6 @@ static int ins_digraph(void) add_to_showcmd_c(Ctrl_K); } - // don't map the digraph chars. This also prevents the // mode message to be deleted when ESC is hit no_mapping++; diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 9c2069663d..02dc5ec954 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -53,12 +53,10 @@ #include "nvim/version.h" #include "nvim/window.h" - // TODO(ZyX-I): Remove DICT_MAXNEST, make users be non-recursive instead #define DICT_MAXNEST 100 // maximum nesting of lists and dicts - static char *e_letunexp = N_("E18: Unexpected characters in :let"); static char *e_missbrac = N_("E111: Missing ']'"); static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary"); @@ -126,13 +124,13 @@ typedef struct { #define VV(idx, name, type, flags) \ [idx] = { \ - .vv_name = name, \ + .vv_name = (name), \ .vv_di = { \ - .di_tv = { .v_type = type }, \ + .di_tv = { .v_type = (type) }, \ .di_flags = 0, \ .di_key = { 0 }, \ }, \ - .vv_flags = flags, \ + .vv_flags = (flags), \ } #define VIMVAR_KEY_LEN 16 // Maximum length of the key of v:variables @@ -1067,7 +1065,6 @@ int get_spellword(list_T *const list, const char **ret_word) return tv_list_find_nr(list, -1, NULL); } - // Call some vim script function and return the result in "*rettv". // Uses argv[0] to argv[argc-1] for the function arguments. argv[argc] // should have type VAR_UNKNOWN. @@ -1209,7 +1206,6 @@ void prof_child_exit(proftime_T *tm) script_prof_restore(tm); } - /// Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding /// it in "*cp". Doesn't give error messages. int eval_foldexpr(char *arg, int *cp) @@ -2701,7 +2697,6 @@ void free_for_info(void *fi_void) xfree(fi); } - void set_context_for_expression(expand_T *xp, char *arg, cmdidx_T cmdidx) FUNC_ATTR_NONNULL_ALL { @@ -3146,7 +3141,6 @@ void del_menutrans_vars(void) * get_user_var_name(). */ - static char *varnamebuf = NULL; static size_t varnamebuflen = 0; @@ -5636,7 +5630,6 @@ bool set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack, list_stack return abort; } - /// Mark all lists and dicts referenced in given mark /// /// @return true if setting references failed somehow. @@ -5683,7 +5676,6 @@ static inline bool set_ref_dict(dict_T *dict, int copyID) return false; } - /// Get the key for *{key: val} into "tv" and advance "arg". /// /// @return FAIL when there is no valid key. @@ -6405,7 +6397,7 @@ dict_T *get_win_info(win_T *wp, int16_t tpnr, int16_t winnr) tv_dict_add_nr(dict, S_LEN("winrow"), wp->w_winrow + 1); tv_dict_add_nr(dict, S_LEN("topline"), wp->w_topline); tv_dict_add_nr(dict, S_LEN("botline"), wp->w_botline - 1); - tv_dict_add_nr(dict, S_LEN("winbar"), 0); + tv_dict_add_nr(dict, S_LEN("winbar"), wp->w_winbar_height); tv_dict_add_nr(dict, S_LEN("width"), wp->w_width); tv_dict_add_nr(dict, S_LEN("bufnr"), wp->w_buffer->b_fnum); tv_dict_add_nr(dict, S_LEN("wincol"), wp->w_wincol + 1); @@ -6865,8 +6857,8 @@ void screenchar_adjust_grid(ScreenGrid **grid, int *row, int *col) // have its own buffer, this should just read from it instead. msg_scroll_flush(); if (msg_grid.chars && msg_grid.comp_index > 0 && *row >= msg_grid.comp_row - && *row < (msg_grid.Rows + msg_grid.comp_row) - && *col < msg_grid.Columns) { + && *row < (msg_grid.rows + msg_grid.comp_row) + && *col < msg_grid.cols) { *grid = &msg_grid; *row -= msg_grid.comp_row; } @@ -6886,6 +6878,7 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T buf_T *curbuf_save = NULL; win_T *curwin_save = NULL; const bool is_curbuf = buf == curbuf; + const bool save_VIsual_active = VIsual_active; // When using the current buffer ml_mfp will be set if needed. Useful when // setline() is used on startup. For other buffers the buffer must be @@ -6896,6 +6889,7 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T } if (!is_curbuf) { + VIsual_active = false; curbuf_save = curbuf; curwin_save = curwin; curbuf = buf; @@ -6986,6 +6980,7 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T if (!is_curbuf) { curbuf = curbuf_save; curwin = curwin_save; + VIsual_active = save_VIsual_active; } } @@ -7284,7 +7279,6 @@ static bool set_ref_in_callback(Callback *callback, int copyID, ht_stack_T **ht_ return set_ref_in_item(&tv, copyID, ht_stack, list_stack); break; - default: abort(); } @@ -10245,7 +10239,6 @@ repeat: *usedlen += 2; } - // ":t" - tail, just the basename if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') { *usedlen += 2; @@ -10486,7 +10479,6 @@ bool common_job_callbacks(dict_T *vopts, CallbackReader *on_stdout, CallbackRead return false; } - Channel *find_job(uint64_t id, bool show_error) { Channel *data = find_channel(id); @@ -10504,7 +10496,6 @@ Channel *find_job(uint64_t id, bool show_error) return data; } - void script_host_eval(char *name, typval_T *argvars, typval_T *rettv) { if (check_secure()) { diff --git a/src/nvim/eval.h b/src/nvim/eval.h index 101f6d9176..fa02b1ea0f 100644 --- a/src/nvim/eval.h +++ b/src/nvim/eval.h @@ -199,7 +199,6 @@ typedef struct { hashtab_T sve_hashtab; } save_v_event_T; - /// trans_function_name() flags typedef enum { TFN_INT = 1, ///< May use internal function name diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c index 2dd18c0942..7b975ce775 100644 --- a/src/nvim/eval/decode.c +++ b/src/nvim/eval/decode.c @@ -414,9 +414,9 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len, bool hasnul = false; #define PUT_FST_IN_PAIR(fst_in_pair, str_end) \ do { \ - if (fst_in_pair != 0) { \ - str_end += utf_char2bytes(fst_in_pair, str_end); \ - fst_in_pair = 0; \ + if ((fst_in_pair) != 0) { \ + (str_end) += utf_char2bytes(fst_in_pair, (str_end)); \ + (fst_in_pair) = 0; \ } \ } while (0) for (const char *t = s; t < p; t++) { diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c index de93ddc70d..090939666d 100644 --- a/src/nvim/eval/encode.c +++ b/src/nvim/eval/encode.c @@ -293,8 +293,8 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s #define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \ do { \ - const char *const buf_ = (const char *)buf; \ - if (buf == NULL) { \ + const char *const buf_ = (const char *)(buf); \ + if ((buf) == NULL) { \ ga_concat(gap, "''"); \ } else { \ const size_t len_ = (len); \ @@ -383,14 +383,14 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s #define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len) \ do { \ - if (len != 0) { \ + if ((len) != 0) { \ ga_concat(gap, ", "); \ } \ } while (0) #define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len) \ do { \ - if ((ptrdiff_t)len != -1) { \ + if ((ptrdiff_t)(len) != -1) { \ ga_concat(gap, ", "); \ } \ } while (0) @@ -452,12 +452,12 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s size_t backref = 0; \ for (; backref < kv_size(*mpstack); backref++) { \ const MPConvStackVal mpval = kv_A(*mpstack, backref); \ - if (mpval.type == conv_type) { \ - if (conv_type == kMPConvDict) { \ + if (mpval.type == (conv_type)) { \ + if ((conv_type) == kMPConvDict) { \ if ((void *)mpval.data.d.dict == (void *)(val)) { \ break; \ } \ - } else if (conv_type == kMPConvList) { \ + } else if ((conv_type) == kMPConvList) { \ if ((void *)mpval.data.l.list == (void *)(val)) { \ break; \ } \ @@ -487,19 +487,19 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s size_t backref = 0; \ for (; backref < kv_size(*mpstack); backref++) { \ const MPConvStackVal mpval = kv_A(*mpstack, backref); \ - if (mpval.type == conv_type) { \ - if (conv_type == kMPConvDict) { \ - if ((void *)mpval.data.d.dict == (void *)val) { \ + if (mpval.type == (conv_type)) { \ + if ((conv_type) == kMPConvDict) { \ + if ((void *)mpval.data.d.dict == (void *)(val)) { \ break; \ } \ - } else if (conv_type == kMPConvList) { \ - if ((void *)mpval.data.l.list == (void *)val) { \ + } else if ((conv_type) == kMPConvList) { \ + if ((void *)mpval.data.l.list == (void *)(val)) { \ break; \ } \ } \ } \ } \ - if (conv_type == kMPConvDict) { \ + if ((conv_type) == kMPConvDict) { \ vim_snprintf(ebuf, ARRAY_SIZE(ebuf), "{...@%zu}", backref); \ } else { \ vim_snprintf(ebuf, ARRAY_SIZE(ebuf), "[...@%zu]", backref); \ @@ -609,7 +609,7 @@ static inline int convert_to_json_string(garray_T *const gap, const char *const // This is done to make resulting values displayable on screen also not from // Neovim. #define ENCODE_RAW(ch) \ - (ch >= 0x20 && utf_printable(ch)) + ((ch) >= 0x20 && utf_printable(ch)) for (size_t i = 0; i < utf_len;) { const int ch = utf_ptr2char(utf_buf + i); const size_t shift = (ch == 0 ? 1 : ((size_t)utf_ptr2len(utf_buf + i))); @@ -788,7 +788,7 @@ bool encode_check_json_key(const typval_T *const tv) #undef TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK #define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(label, key) \ do { \ - if (!encode_check_json_key(&key)) { \ + if (!encode_check_json_key(&(key))) { \ emsg(_("E474: Invalid key in special dictionary")); \ goto label; \ } \ @@ -911,7 +911,7 @@ char *encode_tv2json(typval_T *tv, size_t *len) #define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \ do { \ - if (buf == NULL) { \ + if ((buf) == NULL) { \ msgpack_pack_bin(packer, 0); \ } else { \ const size_t len_ = (len); \ @@ -922,7 +922,7 @@ char *encode_tv2json(typval_T *tv, size_t *len) #define TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len) \ do { \ - if (buf == NULL) { \ + if ((buf) == NULL) { \ msgpack_pack_str(packer, 0); \ } else { \ const size_t len_ = (len); \ @@ -933,11 +933,11 @@ char *encode_tv2json(typval_T *tv, size_t *len) #define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type) \ do { \ - if (buf == NULL) { \ - msgpack_pack_ext(packer, 0, (int8_t)type); \ + if ((buf) == NULL) { \ + msgpack_pack_ext(packer, 0, (int8_t)(type)); \ } else { \ const size_t len_ = (len); \ - msgpack_pack_ext(packer, len_, (int8_t)type); \ + msgpack_pack_ext(packer, len_, (int8_t)(type)); \ msgpack_pack_ext_body(packer, buf, len_); \ } \ } while (0) diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 68c2e37f22..fc8c9ef445 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -90,14 +90,15 @@ typedef enum { # pragma function(floor) # endif +// uncrustify:off PRAGMA_DIAG_PUSH_IGNORE_MISSING_PROTOTYPES PRAGMA_DIAG_PUSH_IGNORE_IMPLICIT_FALLTHROUGH # include "funcs.generated.h" PRAGMA_DIAG_POP PRAGMA_DIAG_POP +// uncrustify:on #endif - static char *e_listblobarg = N_("E899: Argument of %s must be a List or Blob"); static char *e_invalwindow = N_("E957: Invalid window number"); static char *e_reduceempty = N_("E998: Reduce of an empty %s with no initial value"); @@ -110,7 +111,6 @@ static char *e_reduceempty = N_("E998: Reduce of an empty %s with no initial val /// - using va_start() to initialize it gives "function with fixed args" error static va_list dummy_ap; - /// Function given to ExpandGeneric() to obtain the list of internal /// or user defined function names. char *get_function_name(expand_T *xp, int idx) @@ -343,7 +343,6 @@ static void f_and(typval_T *argvars, typval_T *rettv, FunPtr fptr) & tv_get_number_chk(&argvars[1], NULL); } - /// "api_info()" function static void f_api_info(typval_T *argvars, typval_T *rettv, FunPtr fptr) { @@ -470,7 +469,6 @@ static void f_browsedir(typval_T *argvars, typval_T *rettv, FunPtr fptr) f_browse(argvars, rettv, NULL); } - /// Find a buffer by number or exact name. static buf_T *find_buffer(typval_T *avar) { @@ -1634,6 +1632,7 @@ static void f_deletebufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } const bool is_curbuf = buf == curbuf; + const bool save_VIsual_active = VIsual_active; const linenr_T first = tv_get_lnum_buf(&argvars[1], buf); if (argvars[2].v_type != VAR_UNKNOWN) { @@ -1649,6 +1648,7 @@ static void f_deletebufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) } if (!is_curbuf) { + VIsual_active = false; curbuf_save = curbuf; curwin_save = curwin; curbuf = buf; @@ -1692,6 +1692,7 @@ static void f_deletebufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (!is_curbuf) { curbuf = curbuf_save; curwin = curwin_save; + VIsual_active = save_VIsual_active; } } @@ -2164,7 +2165,6 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr) #endif } - /// "menu_get(path [, modes])" function static void f_menu_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) { @@ -2202,7 +2202,6 @@ static void f_expandcmd(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->vval.v_string = (char *)cmdstr; } - /// "flatten(list[, {maxdepth}])" function static void f_flatten(typval_T *argvars, typval_T *rettv, FunPtr fptr) { @@ -2354,7 +2353,6 @@ static void f_filewritable(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->vval.v_number = os_file_is_writable(filename); } - static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what) { char_u *fresult = NULL; @@ -2413,7 +2411,6 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what) } } - /// "filter()" function static void f_filter(typval_T *argvars, typval_T *rettv, FunPtr fptr) { @@ -2497,7 +2494,6 @@ static void f_fnamemodify(typval_T *argvars, typval_T *rettv, FunPtr fptr) xfree(fbuf); } - /// "foldclosed()" function static void foldclosed_both(typval_T *argvars, typval_T *rettv, int end) { @@ -3565,7 +3561,6 @@ static void f_getloclist(typval_T *argvars, typval_T *rettv, FunPtr fptr) get_qf_loc_list(false, wp, &argvars[1], rettv); } - /// "getmarklist()" function static void f_getmarklist(typval_T *argvars, typval_T *rettv, FunPtr fptr) { @@ -3611,8 +3606,8 @@ static void f_getmousepos(typval_T *argvars, typval_T *rettv, FunPtr fptr) // necessary for a top border since `row` starts at -1 in that case. if (row < height + wp->w_border_adj[2]) { winid = wp->handle; - winrow = row + 1 + wp->w_border_adj[0]; // Adjust by 1 for top border - wincol = col + 1 + wp->w_border_adj[3]; // Adjust by 1 for left border + winrow = row + 1 + wp->w_winrow_off; // Adjust by 1 for top border + wincol = col + 1 + wp->w_wincol_off; // Adjust by 1 for left border if (row >= 0 && row < wp->w_height && col >= 0 && col < wp->w_width) { (void)mouse_comp_pos(wp, &row, &col, &lnum); col = vcol2col(wp, lnum, col); @@ -4758,7 +4753,6 @@ static void f_inputlist(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->vval.v_number = selected; } - static garray_T ga_userinput = { 0, 0, sizeof(tasave_T), 4, NULL }; /// "inputrestore()" function @@ -5000,7 +4994,6 @@ static void f_jobresize(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - Channel *data = find_job(argvars[0].vval.v_number, true); if (!data) { return; @@ -5165,7 +5158,6 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - dict_T *job_opts = NULL; bool detach = false; bool rpc = false; @@ -5655,7 +5647,6 @@ static void f_localtime(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->vval.v_number = (varnumber_T)time(NULL); } - static void get_maparg(typval_T *argvars, typval_T *rettv, int exact) { char *keys_buf = NULL; @@ -5769,7 +5760,6 @@ static void f_mapcheck(typval_T *argvars, typval_T *rettv, FunPtr fptr) get_maparg(argvars, rettv, FALSE); } - static void find_some_match(typval_T *const argvars, typval_T *const rettv, const SomeMatchType type) { @@ -7898,7 +7888,6 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr) set_current_funccal((funccall_T *)(provider_caller_scope.funccalp)); } - Error err = ERROR_INIT; uint64_t chan_id = (uint64_t)argvars[0].vval.v_number; @@ -8047,8 +8036,8 @@ static void f_screenattr(typval_T *argvars, typval_T *rettv, FunPtr fptr) int row = (int)tv_get_number_chk(&argvars[0], NULL) - 1; int col = (int)tv_get_number_chk(&argvars[1], NULL) - 1; - if (row < 0 || row >= default_grid.Rows - || col < 0 || col >= default_grid.Columns) { + if (row < 0 || row >= default_grid.rows + || col < 0 || col >= default_grid.cols) { c = -1; } else { ScreenGrid *grid = &default_grid; @@ -8065,8 +8054,8 @@ static void f_screenchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) int row = tv_get_number_chk(&argvars[0], NULL) - 1; int col = tv_get_number_chk(&argvars[1], NULL) - 1; - if (row < 0 || row >= default_grid.Rows - || col < 0 || col >= default_grid.Columns) { + if (row < 0 || row >= default_grid.rows + || col < 0 || col >= default_grid.cols) { c = -1; } else { ScreenGrid *grid = &default_grid; @@ -8081,8 +8070,8 @@ static void f_screenchars(typval_T *argvars, typval_T *rettv, FunPtr fptr) { int row = tv_get_number_chk(&argvars[0], NULL) - 1; int col = tv_get_number_chk(&argvars[1], NULL) - 1; - if (row < 0 || row >= default_grid.Rows - || col < 0 || col >= default_grid.Columns) { + if (row < 0 || row >= default_grid.rows + || col < 0 || col >= default_grid.cols) { tv_list_alloc_ret(rettv, 0); return; } @@ -8148,8 +8137,8 @@ static void f_screenstring(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->v_type = VAR_STRING; int row = tv_get_number_chk(&argvars[0], NULL) - 1; int col = tv_get_number_chk(&argvars[1], NULL) - 1; - if (row < 0 || row >= default_grid.Rows - || col < 0 || col >= default_grid.Columns) { + if (row < 0 || row >= default_grid.rows + || col < 0 || col >= default_grid.cols) { return; } ScreenGrid *grid = &default_grid; @@ -9573,7 +9562,6 @@ static void f_stdioopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - bool rpc = false; CallbackReader on_stdin = CALLBACK_READER_INIT; dict_T *opts = argvars[0].vval.v_dict; @@ -9597,7 +9585,6 @@ static void f_stdioopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) semsg(e_stdiochan2, error); } - rettv->vval.v_number = (varnumber_T)id; rettv->v_type = VAR_NUMBER; } @@ -10385,7 +10372,6 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr) modec = 'c'; } - const char *p = NULL; switch (TOLOWER_ASC(what[0])) { case 'b': @@ -10533,7 +10519,6 @@ static void f_systemlist(typval_T *argvars, typval_T *rettv, FunPtr fptr) get_system_output_as_rettv(argvars, rettv, true); } - /// "tabpagebuflist()" function static void f_tabpagebuflist(typval_T *argvars, typval_T *rettv, FunPtr fptr) { @@ -10579,7 +10564,6 @@ static void f_tabpagenr(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->vval.v_number = nr; } - /// Common code for tabpagewinnr() and winnr(). static int get_winnr(tabpage_T *tp, typval_T *argvar) { @@ -10790,10 +10774,16 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) // "/home/foo/…" => "~/…" size_t len = home_replace(NULL, NameBuff, IObuff, sizeof(IObuff), true); // Trim slash. - if (IObuff[len - 1] == '\\' || IObuff[len - 1] == '/') { + if (len != 1 && (IObuff[len - 1] == '\\' || IObuff[len - 1] == '/')) { IObuff[len - 1] = '\0'; } + if (len == 1 && IObuff[0] == '/') { + // Avoid ambiguity in the URI when CWD is root directory. + IObuff[1] = '.'; + IObuff[2] = '\0'; + } + // Terminal URI: "term://$CWD//$PID:$CMD" snprintf((char *)NameBuff, sizeof(NameBuff), "term://%s//%d:%s", (char *)IObuff, pid, cmd); @@ -10887,7 +10877,6 @@ static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr) timer_start(tv_get_number(&argvars[0]), repeat, &callback); } - /// "timer_stop(timerid)" function static void f_timer_stop(typval_T *argvars, typval_T *rettv, FunPtr fptr) { diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 035bf6318a..2c76741891 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -879,9 +879,9 @@ void tv_list_reverse(list_T *const l) list_log(l, NULL, NULL, "reverse"); #define SWAP(a, b) \ do { \ - tmp = a; \ - a = b; \ - b = tmp; \ + tmp = (a); \ + (a) = (b); \ + (b) = tmp; \ } while (0) listitem_T *tmp; @@ -1515,7 +1515,6 @@ void tv_dict_free(dict_T *const d) } } - /// Unreference a dictionary /// /// Decrements the reference count and frees dictionary when it becomes zero. @@ -2263,36 +2262,36 @@ void tv_blob_copy(typval_T *const from, typval_T *const to) #define TYPVAL_ENCODE_CONV_NIL(tv) \ do { \ - tv->vval.v_special = kSpecialVarNull; \ - tv->v_lock = VAR_UNLOCKED; \ + (tv)->vval.v_special = kSpecialVarNull; \ + (tv)->v_lock = VAR_UNLOCKED; \ } while (0) #define TYPVAL_ENCODE_CONV_BOOL(tv, num) \ do { \ - tv->vval.v_bool = kBoolVarFalse; \ - tv->v_lock = VAR_UNLOCKED; \ + (tv)->vval.v_bool = kBoolVarFalse; \ + (tv)->v_lock = VAR_UNLOCKED; \ } while (0) #define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \ do { \ - (void)num; \ - tv->vval.v_number = 0; \ - tv->v_lock = VAR_UNLOCKED; \ + (void)(num); \ + (tv)->vval.v_number = 0; \ + (tv)->v_lock = VAR_UNLOCKED; \ } while (0) #define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, num) #define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \ do { \ - tv->vval.v_float = 0; \ - tv->v_lock = VAR_UNLOCKED; \ + (tv)->vval.v_float = 0; \ + (tv)->v_lock = VAR_UNLOCKED; \ } while (0) #define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \ do { \ xfree(buf); \ - tv->vval.v_string = NULL; \ - tv->v_lock = VAR_UNLOCKED; \ + (tv)->vval.v_string = NULL; \ + (tv)->v_lock = VAR_UNLOCKED; \ } while (0) #define TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len) @@ -2301,9 +2300,9 @@ void tv_blob_copy(typval_T *const from, typval_T *const to) #define TYPVAL_ENCODE_CONV_BLOB(tv, blob, len) \ do { \ - tv_blob_unref(tv->vval.v_blob); \ - tv->vval.v_blob = NULL; \ - tv->v_lock = VAR_UNLOCKED; \ + tv_blob_unref((tv)->vval.v_blob); \ + (tv)->vval.v_blob = NULL; \ + (tv)->v_lock = VAR_UNLOCKED; \ } while (0) static inline int _nothing_conv_func_start(typval_T *const tv, char_u *const fun) @@ -2360,9 +2359,9 @@ static inline void _nothing_conv_func_end(typval_T *const tv, const int copyID) #define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \ do { \ - tv_list_unref(tv->vval.v_list); \ - tv->vval.v_list = NULL; \ - tv->v_lock = VAR_UNLOCKED; \ + tv_list_unref((tv)->vval.v_list); \ + (tv)->vval.v_list = NULL; \ + (tv)->v_lock = VAR_UNLOCKED; \ } while (0) static inline void _nothing_conv_empty_dict(typval_T *const tv, dict_T **const dictp) @@ -2376,8 +2375,8 @@ static inline void _nothing_conv_empty_dict(typval_T *const tv, dict_T **const d } #define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \ do { \ - assert((void *)&dict != (void *)&TYPVAL_ENCODE_NODICT_VAR); \ - _nothing_conv_empty_dict(tv, ((dict_T **)&dict)); \ + assert((void *)&(dict) != (void *)&TYPVAL_ENCODE_NODICT_VAR); \ + _nothing_conv_empty_dict(tv, ((dict_T **)&(dict))); \ } while (0) static inline int _nothing_conv_real_list_after_start(typval_T *const tv, @@ -2398,7 +2397,7 @@ static inline int _nothing_conv_real_list_after_start(typval_T *const tv, #define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv) \ do { \ - if (_nothing_conv_real_list_after_start(tv, &mpsv) != NOTDONE) { \ + if (_nothing_conv_real_list_after_start(tv, &(mpsv)) != NOTDONE) { \ goto typval_encode_stop_converting_one_item; \ } \ } while (0) @@ -2438,8 +2437,9 @@ static inline int _nothing_conv_real_dict_after_start(typval_T *const tv, dict_T #define TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, dict, mpsv) \ do { \ - if (_nothing_conv_real_dict_after_start(tv, (dict_T **)&dict, (void *)&TYPVAL_ENCODE_NODICT_VAR, \ - &mpsv) != NOTDONE) { \ + if (_nothing_conv_real_dict_after_start(tv, (dict_T **)&(dict), \ + (void *)&TYPVAL_ENCODE_NODICT_VAR, &(mpsv)) \ + != NOTDONE) { \ goto typval_encode_stop_converting_one_item; \ } \ } while (0) @@ -2458,7 +2458,7 @@ static inline void _nothing_conv_dict_end(typval_T *const tv, dict_T **const dic } } #define TYPVAL_ENCODE_CONV_DICT_END(tv, dict) \ - _nothing_conv_dict_end(tv, (dict_T **)&dict, \ + _nothing_conv_dict_end(tv, (dict_T **)&(dict), \ (void *)&TYPVAL_ENCODE_NODICT_VAR) #define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) @@ -2640,9 +2640,9 @@ void tv_item_lock(typval_T *const tv, const int deep, const bool lock, const boo // lock/unlock the item itself #define CHANGE_LOCK(lock, var) \ do { \ - var = ((VarLockStatus[]) { \ - [VAR_UNLOCKED] = (lock ? VAR_LOCKED : VAR_UNLOCKED), \ - [VAR_LOCKED] = (lock ? VAR_LOCKED : VAR_UNLOCKED), \ + (var) = ((VarLockStatus[]) { \ + [VAR_UNLOCKED] = ((lock) ? VAR_LOCKED : VAR_UNLOCKED), \ + [VAR_LOCKED] = ((lock) ? VAR_LOCKED : VAR_UNLOCKED), \ [VAR_FIXED] = VAR_FIXED, \ })[var]; \ } while (0) diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index e5f48501f7..9938dc5012 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -200,7 +200,6 @@ static void register_closure(ufunc_T *fp) [current_funccal->fc_funcs.ga_len++] = fp; } - /// @return a name for a lambda. Returned in static memory. char_u *get_lambda_name(void) { @@ -3598,5 +3597,6 @@ char_u *register_cfunc(cfunc_T cb, cfunc_free_T cb_free, void *state) STRCPY(fp->uf_name, name); hash_add(&func_hashtab, UF2HIKEY(fp)); + // coverity[leaked_storage] return fp->uf_name; } diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c index 89fced59c5..f40573a0bc 100644 --- a/src/nvim/event/loop.c +++ b/src/nvim/event/loop.c @@ -13,7 +13,6 @@ # include "event/loop.c.generated.h" #endif - void loop_init(Loop *loop, void *data) { uv_loop_init(&loop->uv); @@ -143,7 +142,7 @@ bool loop_close(Loop *loop, bool wait) while (true) { // Run the loop to tickle close-callbacks (which should then free memory). // Use UV_RUN_NOWAIT to avoid a hang. #11820 - uv_run(&loop->uv, didstop ? UV_RUN_DEFAULT : UV_RUN_NOWAIT); + uv_run(&loop->uv, didstop ? UV_RUN_DEFAULT : UV_RUN_NOWAIT); // -V547 if ((uv_loop_close(&loop->uv) != UV_EBUSY) || !wait) { break; } diff --git a/src/nvim/event/loop.h b/src/nvim/event/loop.h index b3cd60f53d..c0c5bc527f 100644 --- a/src/nvim/event/loop.h +++ b/src/nvim/event/loop.h @@ -82,7 +82,6 @@ typedef struct loop { } \ } while (0) - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/loop.h.generated.h" #endif diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c index a90cbc4e80..40d20033e0 100644 --- a/src/nvim/event/multiqueue.c +++ b/src/nvim/event/multiqueue.c @@ -82,7 +82,6 @@ typedef struct { int refcount; } MulticastEvent; ///< Event present on multiple queues. - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/multiqueue.c.generated.h" #endif diff --git a/src/nvim/event/multiqueue.h b/src/nvim/event/multiqueue.h index dc60fbb4c7..2c5ba9d436 100644 --- a/src/nvim/event/multiqueue.h +++ b/src/nvim/event/multiqueue.h @@ -12,7 +12,6 @@ typedef void (*PutCallback)(MultiQueue *multiq, void *data); #define multiqueue_put(q, h, ...) \ multiqueue_put_event(q, event_create(h, __VA_ARGS__)); - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/multiqueue.h.generated.h" #endif diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h index c20feb2c7a..30254bfe07 100644 --- a/src/nvim/event/process.h +++ b/src/nvim/event/process.h @@ -33,7 +33,6 @@ struct process { MultiQueue *events; }; - static inline Process process_init(Loop *loop, ProcessType type, void *data) { return (Process) { diff --git a/src/nvim/event/rstream.c b/src/nvim/event/rstream.c index 26b5ce3b75..2847788ef8 100644 --- a/src/nvim/event/rstream.c +++ b/src/nvim/event/rstream.c @@ -42,7 +42,6 @@ void rstream_init(Stream *stream, size_t bufsize) stream->buffer->nonfull_cb = on_rbuffer_nonfull; } - /// Starts watching for events from a `Stream` instance. /// /// @param stream The `Stream` instance diff --git a/src/nvim/event/rstream.h b/src/nvim/event/rstream.h index 77418c59a2..23ed00bfea 100644 --- a/src/nvim/event/rstream.h +++ b/src/nvim/event/rstream.h @@ -8,7 +8,6 @@ #include "nvim/event/loop.h" #include "nvim/event/stream.h" - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/rstream.h.generated.h" #endif diff --git a/src/nvim/event/signal.c b/src/nvim/event/signal.c index fec46da4ff..4a45a2ec2f 100644 --- a/src/nvim/event/signal.c +++ b/src/nvim/event/signal.c @@ -10,7 +10,6 @@ # include "event/signal.c.generated.h" #endif - void signal_watcher_init(Loop *loop, SignalWatcher *watcher, void *data) FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_NONNULL_ARG(2) { diff --git a/src/nvim/event/time.c b/src/nvim/event/time.c index aa7b9cf2a1..c997e3c558 100644 --- a/src/nvim/event/time.c +++ b/src/nvim/event/time.c @@ -11,7 +11,6 @@ # include "event/time.c.generated.h" #endif - void time_watcher_init(Loop *loop, TimeWatcher *watcher, void *data) FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_NONNULL_ARG(2) { diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 8369db7de1..f6bdfc6175 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -73,7 +73,6 @@ #include "nvim/vim.h" #include "nvim/window.h" - /// Case matching style to use for :substitute typedef enum { kSubHonorOptions = 0, ///< Honor the user's 'ignorecase'/'smartcase' options @@ -971,7 +970,11 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest) */ last_line = curbuf->b_ml.ml_line_count; mark_adjust_nofold(line1, line2, last_line - line2, 0L, kExtmarkNOOP); + + disable_fold_update++; changed_lines(last_line - num_lines + 1, 0, last_line + 1, num_lines, false); + disable_fold_update--; + int line_off = 0; bcount_t byte_off = 0; if (dest >= line2) { @@ -1005,7 +1008,9 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest) mark_adjust_nofold(last_line - num_lines + 1, last_line, -(last_line - dest - extra), 0L, kExtmarkNOOP); + disable_fold_update++; changed_lines(last_line - num_lines + 1, 0, last_line + 1, -extra, false); + disable_fold_update--; // send update regarding the new lines that were added buf_updates_send_changes(curbuf, dest + 1, num_lines, 0, true); @@ -1501,7 +1506,6 @@ void do_shell(char *cmd, int flags) return; } - /* * For autocommands we want to get the output on the current screen, to * avoid having to type return below. @@ -2874,14 +2878,9 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum redraw_curbuf_later(NOT_VALID); // redraw this buffer later } - if (p_im && (State & MODE_INSERT) == 0) { - need_start_insertmode = true; - } - // Change directories when the 'acd' option is set. do_autochdir(); - theend: if (bufref_valid(&old_curbuf) && old_curbuf.br_buf->terminal != NULL) { terminal_check_size(old_curbuf.br_buf->terminal); @@ -4063,7 +4062,6 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle goto skip; } - // 3. Substitute the string. During 'inccommand' preview only do this if // there is a replace pattern. if (!preview || has_second_delim) { @@ -4141,7 +4139,6 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle } replaced_bytes += end.col - start.col; - // Now the trick is to replace CTRL-M chars with a real line // break. This would make it impossible to insert a CTRL-M in // the text. The line break can be avoided by preceding the @@ -4197,7 +4194,6 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle lnum - lnum_start, subcols, sublen - 1, kExtmarkUndo); } - // 4. If subflags.do_all is set, find next match. // Prevent endless loop with patterns that match empty // strings, e.g. :s/$/pat/g or :s/[a-z]* /(&)/g. @@ -4749,7 +4745,6 @@ bool prepare_tagpreview(bool undo_sync) return false; } - /// ":help": open a read-only window on a help file void ex_help(exarg_T *eap) { @@ -4903,9 +4898,8 @@ void ex_help(exarg_T *eap) } } - if (!p_im) { - restart_edit = 0; // don't want insert mode in help file - } + restart_edit = 0; // don't want insert mode in help file + // Restore KeyTyped, setting 'filetype=help' may reset it. // It is needed for do_tag top open folds under the cursor. KeyTyped = old_KeyTyped; @@ -4931,7 +4925,6 @@ erret: xfree(tag); } - /// In an argument search for a language specifiers in the form "@xx". /// Changes the "@" to NUL if found, and returns a pointer to "xx". /// @@ -5519,7 +5512,6 @@ void ex_viusage(exarg_T *eap) do_cmdline_cmd("help normal-index"); } - /// Generate tags in one help directory /// /// @param dir Path to the doc directory diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index a6cafb2628..0a91072036 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -537,7 +537,6 @@ bool check_changed(buf_T *buf, int flags) return false; } - /// Ask the user what to do when abandoning a changed buffer. /// Must check 'write' option first! /// @@ -625,7 +624,6 @@ bool can_abandon(buf_T *buf, int forceit) || forceit; } - /// Add a buffer number to "bufnrs", unless it's already there. static void add_bufnum(int *bufnrs, int *bufnump, int nr) { @@ -878,7 +876,6 @@ int get_arglist_exp(char_u *str, int *fcountp, char_u ***fnamesp, bool wig) return i; } - /// @param str /// @param what /// AL_SET: Redefine the argument list to 'str'. @@ -1637,7 +1634,6 @@ void ex_compiler(exarg_T *eap) } } - /// ":options" void ex_options(exarg_T *eap) { @@ -2146,7 +2142,6 @@ theend: return retval; } - /// Check if fname was sourced before to finds its SID. /// If it's new, generate a new SID. /// @@ -2192,7 +2187,6 @@ scriptitem_T *get_current_script_id(char_u *fname, sctx_T *ret_sctx) return si; } - /// ":scriptnames" void ex_scriptnames(exarg_T *eap) { @@ -2291,7 +2285,6 @@ linenr_T get_sourced_lnum(LineGetter fgetline, void *cookie) : sourcing_lnum; } - /// Get one full line from a sourced file. /// Called by do_cmdline() when it's called from do_source(). /// @@ -2619,7 +2612,6 @@ void do_finish(exarg_T *eap, int reanimate) } } - /// @return true when a sourced file had the ":finish" command: Don't give error /// message for missing ":endif". /// false when not sourcing a file. @@ -2721,7 +2713,6 @@ static char *get_mess_env(void) #endif - /// Set the "v:lang" variable according to the current locale setting. /// Also do "v:lc_time"and "v:ctype". void set_lang_var(void) @@ -2869,7 +2860,6 @@ void ex_language(exarg_T *eap) } } - static char **locales = NULL; // Array of all available locales # ifndef WIN32 @@ -2971,7 +2961,6 @@ char *get_locales(expand_T *xp, int idx) #endif - static void script_host_execute(char *name, exarg_T *eap) { size_t len; diff --git a/src/nvim/ex_cmds2.h b/src/nvim/ex_cmds2.h index d426ff28f8..74e52dfb4b 100644 --- a/src/nvim/ex_cmds2.h +++ b/src/nvim/ex_cmds2.h @@ -6,7 +6,6 @@ #include "nvim/ex_docmd.h" #include "nvim/runtime.h" - // // flags for check_changed() // diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index e845073c12..4b7958efa5 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -115,7 +115,6 @@ struct loop_cookie { void *cookie; }; - // Struct to save a few things while debugging. Used in do_cmdline() only. struct dbg_stuff { int trylevel; @@ -345,7 +344,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) // here. The value of 200 allows nested function calls, ":source", etc. // Allow 200 or 'maxfuncdepth', whatever is larger. if (call_depth >= 200 && call_depth >= p_mfd) { - emsg(_("E169: Command too recursive")); + emsg(_(e_command_too_recursive)); // When converting to an exception, we do not include the command name // since this is not an error of the specific command. do_errthrow((cstack_T *)NULL, NULL); @@ -624,7 +623,6 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) next_cmdline = cmdline_copy; } - // reset did_emsg for a function that is not aborted by an error if (did_emsg && !force_abort && getline_equal(fgetline, cookie, get_func_line) @@ -1109,7 +1107,6 @@ static int current_tab_nr(tabpage_T *tab) #define CURRENT_TAB_NR current_tab_nr(curtab) #define LAST_TAB_NR current_tab_nr(NULL) - /// Figure out the address type for ":wincmd". static void get_wincmd_addr_type(char *arg, exarg_T *eap) { @@ -1583,13 +1580,14 @@ bool parse_cmdline(char *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo, char **er /// @param cmdinfo Command parse information void execute_cmd(exarg_T *eap, CmdParseInfo *cmdinfo) { + char *errormsg = NULL; + #define ERROR(msg) \ do { \ - emsg(msg); \ + errormsg = msg; \ goto end; \ } while (0) - char *errormsg = NULL; cmdmod_T save_cmdmod = cmdmod; cmdmod = cmdinfo->cmdmod; @@ -1648,7 +1646,7 @@ void execute_cmd(exarg_T *eap, CmdParseInfo *cmdinfo) // If filename expansion is enabled, expand filenames if (cmdinfo->magic.file) { if (expand_filename(eap, (char_u **)eap->cmdlinep, &errormsg) == FAIL) { - ERROR(errormsg); + goto end; } } @@ -1683,14 +1681,13 @@ void execute_cmd(exarg_T *eap, CmdParseInfo *cmdinfo) (eap->argt & EX_BUFUNL) != 0, false, false); eap->addr_count = 1; // Shift each argument by 1 - if (eap->args != NULL) { - for (size_t i = 0; i < eap->argc - 1; i++) { - eap->args[i] = eap->args[i + 1]; - } - // Make the last argument point to the NUL terminator at the end of string - eap->args[eap->argc - 1] = eap->args[eap->argc - 1] + eap->arglens[eap->argc - 1]; - eap->argc -= 1; + for (size_t i = 0; i < eap->argc - 1; i++) { + eap->args[i] = eap->args[i + 1]; } + // Make the last argument point to the NUL terminator at the end of string + eap->args[eap->argc - 1] = eap->args[eap->argc - 1] + eap->arglens[eap->argc - 1]; + eap->argc -= 1; + eap->arg = eap->args[0]; } if (eap->line2 < 0) { // failed @@ -1707,14 +1704,20 @@ void execute_cmd(exarg_T *eap, CmdParseInfo *cmdinfo) eap->errmsg = NULL; (cmdnames[eap->cmdidx].cmd_func)(eap); if (eap->errmsg != NULL) { - ERROR(_(eap->errmsg)); + errormsg = _(eap->errmsg); } } + end: + if (errormsg != NULL && *errormsg != NUL) { + emsg(errormsg); + } // Undo command modifiers undo_cmdmod(eap, msg_scroll); cmdmod = save_cmdmod; - + if (eap->did_sandbox) { + sandbox--; + } #undef ERROR } @@ -4669,7 +4672,6 @@ static void correct_range(exarg_T *eap) } } - /// For a ":vimgrep" or ":vimgrepadd" command return a pointer past the /// pattern. Otherwise return eap->arg. static char *skip_grep_pat(exarg_T *eap) @@ -5522,6 +5524,11 @@ char *uc_validate_name(char *name) return name; } +/// Create a new user command {name}, if one doesn't already exist. +/// +/// This function takes ownership of compl_arg, compl_luaref, and luaref. +/// +/// @return OK if the command is created, FAIL otherwise. int uc_add_command(char *name, size_t name_len, char *rep, uint32_t argt, long def, int flags, int compl, char *compl_arg, LuaRef compl_luaref, cmd_addr_T addr_type, LuaRef luaref, bool force) @@ -5624,7 +5631,6 @@ fail: return FAIL; } - static struct { cmd_addr_T expand; char *name; @@ -6947,7 +6953,6 @@ static void ex_highlight(exarg_T *eap) do_highlight((const char *)eap->arg, eap->forceit, false); } - /// Call this function if we thought we were going to exit, but we won't /// (because of an error). May need to restore the terminal mode. void not_exiting(void) @@ -7154,7 +7159,6 @@ void ex_win_close(int forceit, win_T *win, tabpage_T *tp) } } - // free buffer when not hiding it or when it's a scratch buffer if (tp == NULL) { win_close(win, !need_hide && !buf_hide(buf), forceit); @@ -7421,7 +7425,7 @@ static void ex_goto(exarg_T *eap) /// Clear an argument list: free all file names and reset it to zero entries. void alist_clear(alist_T *al) { -#define FREE_AENTRY_FNAME(arg) xfree(arg->ae_fname) +#define FREE_AENTRY_FNAME(arg) xfree((arg)->ae_fname) GA_DEEP_CLEAR(&al->al_ga, aentry_T, FREE_AENTRY_FNAME); } @@ -7431,7 +7435,6 @@ void alist_init(alist_T *al) ga_init(&al->al_ga, (int)sizeof(aentry_T), 5); } - /// Remove a reference from an argument list. /// Ignored when the argument list is the global one. /// If the argument list is no longer used by any window, free it. @@ -7672,7 +7675,6 @@ void ex_splitview(exarg_T *eap) do_exedit(eap, old_curwin); } - theend: xfree(fname); } @@ -7790,7 +7792,6 @@ static void ex_tabs(exarg_T *eap) } } - /// ":mode": /// If no argument given, get the screen size and redraw. static void ex_mode(exarg_T *eap) @@ -8000,7 +8001,6 @@ static void ex_nogui(exarg_T *eap) eap->errmsg = N_("E25: Nvim does not have a built-in GUI"); } - static void ex_swapname(exarg_T *eap) { if (curbuf->b_ml.ml_mfp == NULL || curbuf->b_ml.ml_mfp->mf_fname == NULL) { @@ -8043,7 +8043,6 @@ static void ex_syncbind(exarg_T *eap) topline = 1; } - /* * Set all scrollbind windows to the same topline. */ @@ -8078,7 +8077,6 @@ static void ex_syncbind(exarg_T *eap) } } - static void ex_read(exarg_T *eap) { int i; @@ -8831,7 +8829,7 @@ static void ex_redraw(exarg_T *eap) ui_flush(); } -/// ":redrawstatus": force redraw of status line(s) +/// ":redrawstatus": force redraw of status line(s) and window bar(s) static void ex_redrawstatus(exarg_T *eap) { if (State & MODE_CMDPREVIEW) { @@ -8847,8 +8845,7 @@ static void ex_redrawstatus(exarg_T *eap) } else { status_redraw_curbuf(); } - update_screen(VIsual_active ? INVERTED : - 0); + update_screen(VIsual_active ? INVERTED : 0); RedrawingDisabled = r; p_lz = p; ui_flush(); @@ -8969,7 +8966,6 @@ bool save_current_state(save_state_T *sst) sst->save_restart_edit = restart_edit; sst->save_msg_didout = msg_didout; sst->save_State = State; - sst->save_insertmode = p_im; sst->save_finish_op = finish_op; sst->save_opcount = opcount; sst->save_reg_executing = reg_executing; @@ -8977,7 +8973,6 @@ bool save_current_state(save_state_T *sst) msg_scroll = false; // no msg scrolling in Normal mode restart_edit = 0; // don't go to Insert mode - p_im = false; // don't use 'insertmode // Save the current typeahead. This is required to allow using ":normal" // from an event handler and makes sure we don't hang when the argument @@ -9000,7 +8995,6 @@ void restore_current_state(save_state_T *sst) // override the value of restart_edit anyway. restart_edit = sst->save_restart_edit; } - p_im = sst->save_insertmode; finish_op = sst->save_finish_op; opcount = sst->save_opcount; reg_executing = sst->save_reg_executing; @@ -9237,7 +9231,6 @@ static void ex_findpat(exarg_T *eap) } } - /// ":ptag", ":ptselect", ":ptjump", ":ptnext", etc. static void ex_ptag(exarg_T *eap) { diff --git a/src/nvim/ex_docmd.h b/src/nvim/ex_docmd.h index 874e0e599e..24656f3851 100644 --- a/src/nvim/ex_docmd.h +++ b/src/nvim/ex_docmd.h @@ -25,7 +25,6 @@ typedef struct { int save_restart_edit; bool save_msg_didout; int save_State; - int save_insertmode; bool save_finish_op; long save_opcount; int save_reg_executing; diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c index fa70f762a2..46b9528546 100644 --- a/src/nvim/ex_eval.c +++ b/src/nvim/ex_eval.c @@ -439,7 +439,6 @@ char *get_exception_string(void *value, except_type_T type, char *cmdname, int * return ret; } - /// Throw a new exception. "value" is the exception string for a /// user or interrupt exception, or points to a message list in case of an /// error exception. @@ -1140,7 +1139,6 @@ void ex_endwhile(exarg_T *eap) } } - /// Handle ":throw expr" void ex_throw(exarg_T *eap) { @@ -1868,7 +1866,6 @@ void leave_cleanup(cleanup_T *csp) } } - /// Make conditionals inactive and discard what's pending in finally clauses /// until the conditional type searched for or a try conditional not in its /// finally clause is reached. If this is in an active catch clause, finish @@ -2009,7 +2006,6 @@ static char *get_end_emsg(cstack_T *cstack) return e_endif; } - /// Rewind conditionals until index "idx" is reached. "cond_type" and /// "cond_level" specify a conditional type and the address of a level variable /// which is to be decremented with each skipped conditional of the specified diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 114f1e2ae5..13cfd76adf 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -804,6 +804,12 @@ static uint8_t *command_line_enter(int firstc, long count, int indent, bool init ccline.cmdlen = s->indent; } + if (cmdline_level == 50) { + // Somehow got into a loop recursively calling getcmdline(), bail out. + emsg(_(e_command_too_recursive)); + goto theend; + } + ExpandInit(&s->xpc); ccline.xpc = &s->xpc; @@ -910,7 +916,6 @@ static uint8_t *command_line_enter(int firstc, long count, int indent, bool init apply_autocmds(EVENT_CMDLINEENTER, firstcbuf, firstcbuf, false, curbuf); restore_v_event(dict, &save_v_event); - tl_ret = try_leave(&tstate, &err); if (!tl_ret && ERROR_SET(&err)) { msg_putchar('\n'); @@ -995,12 +1000,13 @@ static uint8_t *command_line_enter(int firstc, long count, int indent, bool init State = s->save_State; setmouse(); ui_cursor_shape(); // may show different cursor shape + sb_text_end_cmdline(); + +theend: xfree(s->save_p_icm); xfree(ccline.last_colors.cmdbuff); kv_destroy(ccline.last_colors.colors); - sb_text_end_cmdline(); - char_u *p = ccline.cmdbuff; if (ui_has(kUICmdline)) { @@ -1329,8 +1335,7 @@ static int command_line_execute(VimState *state, int key) } } - // CTRL-\ CTRL-N goes to Normal mode, CTRL-\ CTRL-G goes to Insert - // mode when 'insertmode' is set, CTRL-\ e prompts for an expression. + // CTRL-\ CTRL-N goes to Normal mode, CTRL-\ e prompts for an expression. if (s->c == Ctrl_BSL) { no_mapping++; allow_keys++; @@ -1392,9 +1397,6 @@ static int command_line_execute(VimState *state, int key) redrawcmd(); return command_line_not_changed(s); } else { - if (s->c == Ctrl_G && p_im && restart_edit == 0) { - restart_edit = 'a'; - } s->gotesc = true; // will free ccline.cmdbuff after putting it // in history return 0; // back to Normal mode @@ -1603,7 +1605,6 @@ static int may_do_command_line_next_incsearch(int firstc, long count, incsearch_ int search_flags = SEARCH_NOOF; char_u save; - if (search_delim == ccline.cmdbuff[skiplen]) { pat = last_search_pattern(); if (pat == NULL) { @@ -1997,7 +1998,6 @@ static int command_line_handle_key(CommandLineState *s) // Ignore mouse event or open_cmdwin() result. return command_line_not_changed(s); - case K_MIDDLEDRAG: case K_MIDDLERELEASE: return command_line_not_changed(s); // Ignore mouse @@ -2007,7 +2007,6 @@ static int command_line_handle_key(CommandLineState *s) redrawcmd(); return command_line_changed(s); - case K_LEFTDRAG: case K_LEFTRELEASE: case K_RIGHTDRAG: @@ -2057,7 +2056,6 @@ static int command_line_handle_key(CommandLineState *s) case K_MOUSEMOVE: return command_line_not_changed(s); - case K_SELECT: // end of Select mode mapping - ignore return command_line_not_changed(s); @@ -2281,7 +2279,6 @@ static int command_line_handle_key(CommandLineState *s) return command_line_changed(s); } - static int command_line_not_changed(CommandLineState *s) { // Incremental searches for "/" and "?": @@ -2551,7 +2548,6 @@ static int cmd_startcol(void) return ccline.cmdindent + ((ccline.cmdfirstc != NUL) ? 1 : 0); } - /// Compute the column position for a byte position on the command line. static int cmd_screencol(int bytepos) { @@ -2614,7 +2610,6 @@ bool cmdline_overstrike(void) return ccline.overstrike; } - /// Return true if the cursor is at the end of the cmdline. bool cmdline_at_end(void) FUNC_ATTR_PURE @@ -3438,7 +3433,6 @@ static bool cmdline_paste(int regname, bool literally, bool remcr) return FAIL; } - // Need to set "textlock" to avoid nasty things like going to another // buffer when evaluating an expression. textlock++; @@ -5584,7 +5578,6 @@ static int ExpandPackAddDir(char_u *pat, int *num_file, char_u ***file) return OK; } - /// Expand `file` for all comma-separated directories in `path`. /// Adds matches to `ga`. void globpath(char_u *path, char_u *file, garray_T *ga, int expand_options) @@ -5625,7 +5618,6 @@ void globpath(char_u *path, char_u *file, garray_T *ga, int expand_options) xfree(buf); } - /********************************* * Command line history stuff * *********************************/ @@ -5915,7 +5907,6 @@ void add_to_history(int histype, char_u *new_entry, int in_map, int sep) } } - /* * Get identifier of newest history entry. * "histype" may be one of the HIST_ values. @@ -5930,7 +5921,6 @@ int get_history_idx(int histype) return history[histype][hisidx[histype]].hisnum; } - /// Get pointer to the command line info to use. save_cmdline() may clear /// ccline and put the previous value in ccline.prev_ccline. static struct cmdline_info *get_ccline_ptr(void) diff --git a/src/nvim/ex_session.c b/src/nvim/ex_session.c index 7eef6707dd..3b6f7b90bf 100644 --- a/src/nvim/ex_session.c +++ b/src/nvim/ex_session.c @@ -181,6 +181,10 @@ static bool ses_do_frame(const frame_T *fr) /// @return non-zero if window "wp" is to be stored in the Session. static int ses_do_win(win_T *wp) { + // Skip floating windows to avoid issues when restoring the Session. #18432 + if (wp->w_floating) { + return false; + } if (wp->w_buffer->b_fname == NULL // When 'buftype' is "nofile" can't restore the window contents. || (!wp->w_buffer->terminal && bt_nofile(wp->w_buffer))) { @@ -598,9 +602,14 @@ static int makeopens(FILE *fd, char_u *dirnow) PUTLINE_FAIL("let s:shortmess_save = &shortmess"); } - // Now save the current files, current buffer first. - PUTLINE_FAIL("set shortmess=aoO"); + // set 'shortmess' for the following. Add the 'A' flag if it was there + PUTLINE_FAIL("if &shortmess =~ 'A'"); + PUTLINE_FAIL(" set shortmess=aoOA"); + PUTLINE_FAIL("else"); + PUTLINE_FAIL(" set shortmess=aoO"); + PUTLINE_FAIL("endif"); + // Now save the current files, current buffer first. // Put all buffers into the buffer list. // Do it very early to preserve buffer order after loading session (which // can be disrupted by prior `edit` or `tabedit` calls). diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c index f367bc66e0..72c7640d3d 100644 --- a/src/nvim/extmark.c +++ b/src/nvim/extmark.c @@ -53,7 +53,6 @@ static uint32_t *buf_ns_ref(buf_T *buf, uint32_t ns_id, bool put) return map_ref(uint32_t, uint32_t)(buf->b_extmark_ns, ns_id, put); } - /// Create or update an extmark /// /// must not be used during iteration! @@ -361,7 +360,6 @@ ExtmarkInfo extmark_from_id(buf_T *buf, uint32_t ns_id, uint32_t id) return ret; } - /// free extmarks from the buffer void extmark_free_all(buf_T *buf) { @@ -391,7 +389,6 @@ void extmark_free_all(buf_T *buf) map_init(uint32_t, uint32_t, buf->b_extmark_ns); } - /// Save info for undo/redo of set marks static void u_extmark_set(buf_T *buf, uint64_t mark, int row, colnr_T col) { @@ -501,7 +498,6 @@ void extmark_apply_undo(ExtmarkUndoObject undo_info, bool undo) } } - /// Adjust extmark row for inserted/deleted rows (columns stay fixed). void extmark_adjust(buf_T *buf, linenr_T line1, linenr_T line2, long amount, long amount_after, ExtmarkOp undo) @@ -593,7 +589,6 @@ void extmark_splice_impl(buf_T *buf, int start_row, colnr_T start_col, bcount_t u_extmark_copy(buf, start_row, start_col, end_row, end_col); } - marktree_splice(buf->b_marktree, (int32_t)start_row, start_col, old_row, old_col, new_row, new_col); @@ -684,7 +679,6 @@ void extmark_move_region(buf_T *buf, int start_row, colnr_T start_col, bcount_t 0, 0, 0, extent_row, extent_col, extent_byte); - if (undo == kExtmarkUndo) { u_header_T *uhp = u_force_get_undo_header(buf); if (!uhp) { diff --git a/src/nvim/extmark.h b/src/nvim/extmark.h index b856a1148f..c144504076 100644 --- a/src/nvim/extmark.h +++ b/src/nvim/extmark.h @@ -26,7 +26,6 @@ typedef kvec_t(ExtmarkInfo) ExtmarkInfoArray; // TODO(bfredl): good enough name for now. typedef ptrdiff_t bcount_t; - // delete the columns between mincol and endcol typedef struct { int start_row; @@ -80,7 +79,6 @@ struct undo_object { } data; }; - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "extmark.h.generated.h" #endif diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index 47e20d58a3..e327b97fbe 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -146,7 +146,6 @@ typedef struct ff_visited_list_hdr { ff_visited_T *ffvl_visited_list; } ff_visited_list_hdr_T; - /* * '**' can be expanded to several directory levels. * Set the default maximum depth. diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 06d72f3395..8d8c10f823 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -147,7 +147,6 @@ void filemess(buf_T *buf, char_u *name, char_u *s, int attr) msg_scrolled_ign = false; } - /// Read lines from file "fname" into the buffer after line "from". /// /// 1. We allocate blocks with try_malloc, as big as possible. @@ -839,7 +838,6 @@ retry: fio_flags = get_fio_flags((char_u *)fenc); } - #ifdef HAVE_ICONV // Try using iconv() if we can't convert internally. if (fio_flags == 0 @@ -1293,7 +1291,6 @@ retry: size -= conv_restlen; } - while (p > (uint8_t *)ptr) { if (fio_flags & FIO_LATIN1) { u8c = *--p; @@ -1995,7 +1992,6 @@ bool is_dev_fd_file(char_u *fname) } #endif - /// From the current line count and characters read after that, estimate the /// line number where we are now. /// Used for error messages that include a line number. @@ -2146,7 +2142,6 @@ static char_u *readfile_charconvert(char_u *fname, char_u *fenc, int *fdp) return tmpname; } - /// Read marks for the current buffer from the ShaDa file, when we support /// buffer marks and the buffer has a name. static void check_marks_read(void) @@ -2200,11 +2195,11 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en linenr_T lnum; long nchars; #define SET_ERRMSG_NUM(num, msg) \ - errnum = num, errmsg = msg, errmsgarg = 0 + errnum = (num), errmsg = (msg), errmsgarg = 0 #define SET_ERRMSG_ARG(msg, error) \ - errnum = NULL, errmsg = msg, errmsgarg = error + errnum = NULL, errmsg = (msg), errmsgarg = error #define SET_ERRMSG(msg) \ - errnum = NULL, errmsg = msg, errmsgarg = 0 + errnum = NULL, errmsg = (msg), errmsgarg = 0 const char *errnum = NULL; char *errmsg = NULL; int errmsgarg = 0; @@ -3053,7 +3048,6 @@ nobackup: } } - // Default: write the file directly. May write to a temp file for // multi-byte conversion. wfname = fname; @@ -3089,7 +3083,6 @@ nobackup: } } - if (converted && wb_flags == 0) { #ifdef HAVE_ICONV // Use iconv() conversion when conversion is needed and it's not done @@ -4109,7 +4102,6 @@ static bool ucs2bytes(unsigned c, char_u **pp, int flags) FUNC_ATTR_NONNULL_ALL bool error = false; int cc; - if (flags & FIO_UCS4) { if (flags & FIO_ENDIAN_L) { *p++ = c; @@ -4238,7 +4230,6 @@ static int get_fio_flags(const char_u *name) return 0; } - /// Check for a Unicode BOM (Byte Order Mark) at the start of p[size]. /// "size" must be at least 2. /// @@ -5493,7 +5484,6 @@ char_u *vim_tempname(void) return vim_strsave(template); } - /// Tries matching a filename with a "pattern" ("prog" is NULL), or use the /// precompiled regprog "prog" ("pattern" is NULL). That avoids calling /// vim_regcomp() often. diff --git a/src/nvim/fold.c b/src/nvim/fold.c index 090f754e93..234c11227d 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -660,7 +660,6 @@ void foldCreate(win_T *wp, pos_T start, pos_T end) } } - // deleteFold() {{{2 /// @param start delete all folds from start to end when not 0 /// @param end delete all folds from start to end when not 0 @@ -775,7 +774,7 @@ void clearFolding(win_T *win) /// The changes in lines from top to bot (inclusive). void foldUpdate(win_T *wp, linenr_T top, linenr_T bot) { - if (compl_busy || State & MODE_INSERT) { + if (disable_fold_update || compl_busy || State & MODE_INSERT) { return; } @@ -785,11 +784,18 @@ void foldUpdate(win_T *wp, linenr_T top, linenr_T bot) } if (wp->w_folds.ga_len > 0) { - // Mark all folds from top to bot as maybe-small. + linenr_T maybe_small_start = top; + linenr_T maybe_small_end = bot; + + // Mark all folds from top to bot (or bot to top) as maybe-small. + if (top > bot) { + maybe_small_start = bot; + maybe_small_end = top; + } fold_T *fp; - (void)foldFind(&wp->w_folds, top, &fp); + (void)foldFind(&wp->w_folds, maybe_small_start, &fp); while (fp < (fold_T *)wp->w_folds.ga_data + wp->w_folds.ga_len - && fp->fd_top < bot) { + && fp->fd_top <= maybe_small_end) { fp->fd_small = kNone; fp++; } @@ -1929,7 +1935,7 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot) bot = wp->w_buffer->b_ml.ml_line_count; wp->w_foldinvalid = false; - // Mark all folds a maybe-small. + // Mark all folds as maybe-small. setSmallMaybe(&wp->w_folds); } @@ -1996,7 +2002,7 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot) // start one line back, because a "<1" may indicate the end of a // fold in the topline if (top > 1) { - --fline.lnum; + fline.lnum--; } } else if (foldmethodIsSyntax(wp)) { getlevel = foldlevelSyntax; @@ -2004,6 +2010,12 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot) getlevel = foldlevelDiff; } else { getlevel = foldlevelIndent; + // Start one line back, because if the line above "top" has an + // undefined fold level, folding it relies on the line under it, + // which is "top". + if (top > 1) { + fline.lnum--; + } } // Backup to a line for which the fold level is defined. Since it's @@ -2310,6 +2322,7 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level, } fp->fd_len += fp->fd_top - firstlnum; fp->fd_top = firstlnum; + fp->fd_small = kNone; fold_changed = true; } else if ((flp->start != 0 && lvl == level) || (firstlnum != startlnum)) { diff --git a/src/nvim/fold.h b/src/nvim/fold.h index 6b29214760..60ea4b322e 100644 --- a/src/nvim/fold.h +++ b/src/nvim/fold.h @@ -23,6 +23,7 @@ typedef struct foldinfo { #define FOLDINFO_INIT { 0, 0, 0, 0 } +EXTERN int disable_fold_update INIT(= 0); #ifdef INCLUDE_GENERATED_DECLARATIONS # include "fold.h.generated.h" diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 2cc068b30d..788e1113e2 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -54,7 +54,6 @@ #include "nvim/undo.h" #include "nvim/vim.h" - /// Index in scriptin static int curscript = 0; FileDescriptor *scriptin[NSCRIPT] = { NULL }; @@ -1352,14 +1351,12 @@ void openscript(char_u *name, bool directly) int oldcurscript; int save_State = State; int save_restart_edit = restart_edit; - int save_insertmode = p_im; int save_finish_op = finish_op; int save_msg_scroll = msg_scroll; State = MODE_NORMAL; msg_scroll = false; // no msg scrolling in Normal mode restart_edit = 0; // don't go to Insert mode - p_im = false; // don't use 'insertmode' clear_oparg(&oa); finish_op = false; @@ -1373,7 +1370,6 @@ void openscript(char_u *name, bool directly) State = save_State; msg_scroll = save_msg_scroll; restart_edit = save_restart_edit; - p_im = save_insertmode; finish_op = save_finish_op; } } @@ -1881,8 +1877,7 @@ static int handle_mapping(int *keylenp, bool *timedout, int *mapdepth) if (no_mapping == 0 && maphash_valid && (no_zero_mapping == 0 || tb_c1 != '0') && (typebuf.tb_maplen == 0 || is_plug_map - || (p_remap - && !(typebuf.tb_noremap[typebuf.tb_off] & (RM_NONE|RM_ABBR)))) + || (!(typebuf.tb_noremap[typebuf.tb_off] & (RM_NONE|RM_ABBR)))) && !(p_paste && (State & (MODE_INSERT | MODE_CMDLINE))) && !(State == MODE_HITRETURN && (tb_c1 == CAR || tb_c1 == ' ')) && State != MODE_ASKMORE @@ -2514,16 +2509,12 @@ static int vgetorpeek(bool advance) timedout = true; continue; } - // When 'insertmode' is set, ESC just beeps in Insert - // mode. Use CTRL-L to make edit() return. // In Ex-mode \n is compatible with original Vim behaviour. // For the command line only CTRL-C always breaks it. // For the cmdline window: Alternate between ESC and // CTRL-C: ESC for most situations and CTRL-C to close the // cmdline window. - if (p_im && (State & MODE_INSERT)) { - c = Ctrl_L; - } else if ((State & MODE_CMDLINE) || (cmdwin_type > 0 && tc == ESC)) { + if ((State & MODE_CMDLINE) || (cmdwin_type > 0 && tc == ESC)) { c = Ctrl_C; } else { c = ESC; @@ -3441,7 +3432,6 @@ theend: return retval; } - /// Set or remove a mapping or an abbreviation in the current buffer, OR /// display (matching) mappings/abbreviations. /// @@ -3809,7 +3799,7 @@ bool map_to_exists(const char *const str, const char *const modechars, const boo #define MAPMODE(mode, modechars, chr, modeflags) \ do { \ if (strchr(modechars, chr) != NULL) { \ - mode |= modeflags; \ + (mode) |= (modeflags); \ } \ } while (0) MAPMODE(mode, modechars, 'n', MODE_NORMAL); @@ -4724,7 +4714,6 @@ char_u *check_map(char_u *keys, int mode, int exact, int ign_mod, int abbr, mapb return NULL; } - /// Add a mapping. Unlike @ref do_map this copies the {map} argument, so /// static or read-only strings can be used. /// @@ -4866,7 +4855,6 @@ char *getcmdkeycmd(int promptc, void *cookie, int indent, bool do_concat) c1 = TO_SPECIAL(c1, c2); } - if (got_int) { aborted = true; } else if (c1 == '\r' || c1 == '\n') { diff --git a/src/nvim/globals.h b/src/nvim/globals.h index e34e3983db..b0006ebaca 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -84,7 +84,7 @@ EXTERN struct nvim_stats_s { // 0 not starting anymore // Number of Rows and Columns in the screen. -// Note: Use default_grid.Rows and default_grid.Columns to access items in +// Note: Use default_grid.rows and default_grid.cols to access items in // default_grid.chars[]. They may have different values when the screen // wasn't (re)allocated yet after setting Rows or Columns (e.g., when starting // up). @@ -96,7 +96,6 @@ EXTERN int Columns INIT(= DFLT_COLS); // nr of columns in the screen EXTERN NS ns_hl_active INIT(= 0); // current ns that defines highlights EXTERN bool ns_hl_changed INIT(= false); // highlight need update - // We use 64-bit file functions here, if available. E.g. ftello() returns // off_t instead of long, which helps if long is 32 bit and off_t is 64 bit. // We assume that when fseeko() is available then ftello() is too. @@ -202,7 +201,6 @@ EXTERN bool msg_scrolled_ign INIT(= false); // is reset before the screen is redrawn, so we need to keep track of this. EXTERN bool msg_did_scroll INIT(= false); - EXTERN char_u *keep_msg INIT(= NULL); // msg to be shown after redraw EXTERN int keep_msg_attr INIT(= 0); // highlight attr for keep_msg EXTERN bool need_fileinfo INIT(= false); // do fileinfo() after redraw @@ -315,7 +313,6 @@ EXTERN bool suppress_errthrow INIT(= false); /// cstacks; the pending exceptions, however, are not on the caught stack. EXTERN except_T *caught_stack INIT(= NULL); - /// /// Garbage collection can only take place when we are sure there are no Lists /// or Dictionaries being used internally. This is flagged with @@ -361,7 +358,6 @@ EXTERN struct caller_scope { } provider_caller_scope; EXTERN int provider_call_nesting INIT(= 0); - EXTERN int t_colors INIT(= 256); // int value of T_CCO // Flags to indicate an additional string for highlight name completion. @@ -421,10 +417,6 @@ EXTERN vimmenu_T *root_menu INIT(= NULL); // overruling of menus that the user already defined. EXTERN int sys_menu INIT(= false); -// While redrawing the screen this flag is set. It means the screen size -// ('lines' and 'rows') must not be changed. -EXTERN int updating_screen INIT(= 0); - // All windows are linked in a list. firstwin points to the first entry, // lastwin to the last entry (can be the same as firstwin) and curwin to the // currently active window. @@ -482,7 +474,6 @@ EXTERN buf_T *curbuf INIT(= NULL); // currently active buffer #define FOR_ALL_SIGNS_IN_BUF(buf, sign) \ for ((sign) = (buf)->b_signlist; (sign) != NULL; (sign) = (sign)->se_next) // NOLINT - // List of files being edited (global argument list). curwin->w_alist points // to this when the window is using the global argument list. EXTERN alist_T global_alist; // global argument list @@ -797,7 +788,6 @@ enum { WM_LIST = 3, ///< cmdline CTRL-D }; - // Some file names are stored in pathdef.c, which is generated from the // Makefile to make their value depend on the Makefile. #ifdef HAVE_PATHDEF @@ -846,7 +836,6 @@ EXTERN bool no_hlsearch INIT(= false); // Page number used for %N in 'pageheader' and 'guitablabel'. EXTERN linenr_T printer_page_num; - EXTERN bool typebuf_was_filled INIT(= false); // received text from client // or from feedkeys() @@ -877,7 +866,8 @@ EXTERN char e_api_spawn_failed[] INIT(= N_("E903: Could not spawn API job")); EXTERN char e_argreq[] INIT(= N_("E471: Argument required")); EXTERN char e_backslash[] INIT(= N_("E10: \\ should be followed by /, ? or &")); EXTERN char e_cmdwin[] INIT(= N_("E11: Invalid in command-line window; <CR> executes, CTRL-C quits")); -EXTERN char e_curdir[] INIT(= N_( "E12: Command not allowed from exrc/vimrc in current dir or tag search")); +EXTERN char e_curdir[] INIT(= N_("E12: Command not allowed from exrc/vimrc in current dir or tag search")); +EXTERN char e_command_too_recursive[] INIT(= N_("E169: Command too recursive")); EXTERN char e_endif[] INIT(= N_("E171: Missing :endif")); EXTERN char e_endtry[] INIT(= N_("E600: Missing :endtry")); EXTERN char e_endwhile[] INIT(= N_("E170: Missing :endwhile")); diff --git a/src/nvim/grid.c b/src/nvim/grid.c index 8a5d8081c0..7d407bd3d1 100644 --- a/src/nvim/grid.c +++ b/src/nvim/grid.c @@ -4,6 +4,7 @@ #include "nvim/arabic.h" #include "nvim/grid.h" #include "nvim/highlight.h" +#include "nvim/screen.h" #include "nvim/ui.h" #include "nvim/vim.h" @@ -16,7 +17,6 @@ // Per-cell attributes static size_t linebuf_size = 0; - /// Determine if dedicated window grid should be used or the default_grid /// /// If UI did not request multigrid support, draw all windows on the @@ -63,7 +63,7 @@ void grid_clear_line(ScreenGrid *grid, size_t off, int width, bool valid) void grid_invalidate(ScreenGrid *grid) { - (void)memset(grid->attrs, -1, sizeof(sattr_T) * (size_t)(grid->Rows * grid->Columns)); + (void)memset(grid->attrs, -1, sizeof(sattr_T) * (size_t)grid->rows * (size_t)grid->cols); } bool grid_invalid_row(ScreenGrid *grid, int row) @@ -92,7 +92,7 @@ bool grid_lefthalve(ScreenGrid *grid, int row, int col) grid_adjust(&grid, &row, &col); return grid_off2cells(grid, grid->line_offset[row] + (size_t)col, - grid->line_offset[row] + (size_t)grid->Columns) > 1; + grid->line_offset[row] + (size_t)grid->cols) > 1; } /// Correct a position on the screen, if it's the right half of a double-wide @@ -128,14 +128,13 @@ void grid_getbytes(ScreenGrid *grid, int row, int col, char_u *bytes, int *attrp grid_adjust(&grid, &row, &col); // safety check - if (grid->chars != NULL && row < grid->Rows && col < grid->Columns) { + if (grid->chars != NULL && row < grid->rows && col < grid->cols) { off = grid->line_offset[row] + (size_t)col; *attrp = grid->attrs[off]; schar_copy(bytes, grid->chars[off]); } } - /// put string '*text' on the window grid at position 'row' and 'col', with /// attributes 'attr', and update chars[] and attrs[]. /// Note: only outputs within one row, message is truncated at grid boundary! @@ -202,8 +201,8 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row, int col // Safety check. The check for negative row and column is to fix issue // vim/vim#4102. TODO(neovim): find out why row/col could be negative. if (grid->chars == NULL - || row >= grid->Rows || row < 0 - || col >= grid->Columns || col < 0) { + || row >= grid->rows || row < 0 + || col >= grid->cols || col < 0) { return; } @@ -225,8 +224,8 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row, int col put_dirty_last = MAX(put_dirty_last, 1); } - max_off = grid->line_offset[row] + (size_t)grid->Columns; - while (col < grid->Columns + max_off = grid->line_offset[row] + (size_t)grid->cols; + while (col < grid->cols && (len < 0 || (int)(ptr - text) < len) && *ptr != NUL) { c = *ptr; @@ -259,7 +258,7 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row, int col } else { prev_c = u8c; } - if (col + mbyte_cells > grid->Columns) { + if (col + mbyte_cells > grid->cols) { // Only 1 cell left, but character requires 2 cells: // display a '>' in the last column to avoid wrapping. */ c = '>'; @@ -271,7 +270,6 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row, int col schar_T buf; schar_from_cc(buf, u8c, u8cc); - need_redraw = schar_cmp(grid->chars[off], buf) || (mbyte_cells == 2 && grid->chars[off + 1][0] != 0) || grid->attrs[off] != attr @@ -338,7 +336,7 @@ void grid_puts_line_flush(bool set_cursor) if (put_dirty_first < put_dirty_last) { if (set_cursor) { ui_grid_cursor_goto(put_dirty_grid->handle, put_dirty_row, - MIN(put_dirty_last, put_dirty_grid->Columns - 1)); + MIN(put_dirty_last, put_dirty_grid->cols - 1)); } if (!put_dirty_grid->throttled) { ui_line(put_dirty_grid, put_dirty_row, put_dirty_first, put_dirty_last, @@ -371,11 +369,11 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int end_col += col_off; // safety check - if (end_row > grid->Rows) { - end_row = grid->Rows; + if (end_row > grid->rows) { + end_row = grid->rows; } - if (end_col > grid->Columns) { - end_col = grid->Columns; + if (end_col > grid->cols) { + end_col = grid->cols; } // nothing to do @@ -391,7 +389,7 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int if (start_col > 0 && grid_fix_col(grid, start_col, row) != start_col) { grid_puts_len(grid, (char_u *)" ", 1, row, start_col - 1, 0); } - if (end_col < grid->Columns + if (end_col < grid->cols && grid_fix_col(grid, end_col, row) != end_col) { grid_puts_len(grid, (char_u *)" ", 1, row, end_col, 0); } @@ -443,7 +441,7 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int } } - if (end_col == grid->Columns) { + if (end_col == grid->cols) { grid->line_wraps[row] = false; } } @@ -491,17 +489,17 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int cle // TODO(bfredl): check all callsites and eliminate // Check for illegal row and col, just in case - if (row >= grid->Rows) { - row = grid->Rows - 1; + if (row >= grid->rows) { + row = grid->rows - 1; } - if (endcol > grid->Columns) { - endcol = grid->Columns; + if (endcol > grid->cols) { + endcol = grid->cols; } grid_adjust(&grid, &row, &coloff); // Safety check. Avoids clang warnings down the call stack. - if (grid->chars == NULL || row >= grid->Rows || coloff >= grid->Columns) { + if (grid->chars == NULL || row >= grid->rows || coloff >= grid->cols) { DLOG("invalid state, skipped"); return; } @@ -509,7 +507,7 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int cle size_t off_from = 0; size_t off_to = grid->line_offset[row] + (size_t)coloff; max_off_from = linebuf_size; - max_off_to = grid->line_offset[row] + (size_t)grid->Columns; + max_off_to = grid->line_offset[row] + (size_t)grid->cols; if (rlflag) { // Clear rest first, because it's left of the text. @@ -617,7 +615,7 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int cle } } - if (clear_width > 0 || wp->w_width != grid->Columns) { + if (clear_width > 0 || wp->w_width != grid->cols) { // If we cleared after the end of the line, it did not wrap. // For vsplit, line wrapping is not possible. grid->line_wraps[row] = false; @@ -646,11 +644,11 @@ void grid_alloc(ScreenGrid *grid, int rows, int columns, bool copy, bool valid) new.line_offset = xmalloc((size_t)rows * sizeof(*new.line_offset)); new.line_wraps = xmalloc((size_t)rows * sizeof(*new.line_wraps)); - new.Rows = rows; - new.Columns = columns; + new.rows = rows; + new.cols = columns; - for (new_row = 0; new_row < new.Rows; new_row++) { - new.line_offset[new_row] = (size_t)new_row * (size_t)new.Columns; + for (new_row = 0; new_row < new.rows; new_row++) { + new.line_offset[new_row] = (size_t)new_row * (size_t)new.cols; new.line_wraps[new_row] = false; grid_clear_line(&new, new.line_offset[new_row], columns, valid); @@ -660,8 +658,8 @@ void grid_alloc(ScreenGrid *grid, int rows, int columns, bool copy, bool valid) // possible from the old screen to the new one and clear the rest // (used when resizing the window at the "--more--" prompt or when // executing an external command, for the GUI). - if (new_row < grid->Rows && grid->chars != NULL) { - int len = MIN(grid->Columns, new.Columns); + if (new_row < grid->rows && grid->chars != NULL) { + int len = MIN(grid->cols, new.cols); memmove(new.chars + new.line_offset[new_row], grid->chars + grid->line_offset[new_row], (size_t)len * sizeof(schar_T)); @@ -705,3 +703,83 @@ void grid_free_all_mem(void) xfree(linebuf_char); xfree(linebuf_attr); } + +/// (Re)allocates a window grid if size changed while in ext_multigrid mode. +/// Updates size, offsets and handle for the grid regardless. +/// +/// If "doclear" is true, don't try to copy from the old grid rather clear the +/// resized grid. +void win_grid_alloc(win_T *wp) +{ + ScreenGrid *grid = &wp->w_grid; + ScreenGrid *grid_allocated = &wp->w_grid_alloc; + + int rows = wp->w_height_inner; + int cols = wp->w_width_inner; + int total_rows = wp->w_height_outer; + int total_cols = wp->w_width_outer; + + bool want_allocation = ui_has(kUIMultigrid) || wp->w_floating; + bool has_allocation = (grid_allocated->chars != NULL); + + if (grid->rows != rows) { + wp->w_lines_valid = 0; + xfree(wp->w_lines); + wp->w_lines = xcalloc((size_t)rows + 1, sizeof(wline_T)); + } + + int was_resized = false; + if (want_allocation && (!has_allocation + || grid_allocated->rows != total_rows + || grid_allocated->cols != total_cols)) { + grid_alloc(grid_allocated, total_rows, total_cols, + wp->w_grid_alloc.valid, false); + grid_allocated->valid = true; + if (wp->w_floating && wp->w_float_config.border) { + wp->w_redr_border = true; + } + was_resized = true; + } else if (!want_allocation && has_allocation) { + // Single grid mode, all rendering will be redirected to default_grid. + // Only keep track of the size and offset of the window. + grid_free(grid_allocated); + grid_allocated->valid = false; + was_resized = true; + } else if (want_allocation && has_allocation && !wp->w_grid_alloc.valid) { + grid_invalidate(grid_allocated); + grid_allocated->valid = true; + } + + grid->rows = rows; + grid->cols = cols; + + if (want_allocation) { + grid->target = grid_allocated; + grid->row_offset = wp->w_winrow_off; + grid->col_offset = wp->w_wincol_off; + } else { + grid->target = &default_grid; + grid->row_offset = wp->w_winrow + wp->w_winrow_off; + grid->col_offset = wp->w_wincol + wp->w_wincol_off; + } + + // send grid resize event if: + // - a grid was just resized + // - screen_resize was called and all grid sizes must be sent + // - the UI wants multigrid event (necessary) + if ((resizing_screen || was_resized) && want_allocation) { + ui_call_grid_resize(grid_allocated->handle, + grid_allocated->cols, grid_allocated->rows); + } +} + +/// assign a handle to the grid. The grid need not be allocated. +void grid_assign_handle(ScreenGrid *grid) +{ + static int last_grid_handle = DEFAULT_GRID_HANDLE; + + // only assign a grid handle if not already + if (grid->handle == 0) { + grid->handle = ++last_grid_handle; + } +} diff --git a/src/nvim/grid_defs.h b/src/nvim/grid_defs.h index 2516ea52a7..1571340849 100644 --- a/src/nvim/grid_defs.h +++ b/src/nvim/grid_defs.h @@ -21,7 +21,6 @@ enum { kZIndexCmdlinePopupMenu = 250, }; - /// ScreenGrid represents a resizable rectuangular grid displayed by UI clients. /// /// chars[] contains the UTF-8 text that is currently displayed on the grid. @@ -58,8 +57,8 @@ struct ScreenGrid { int *dirty_col; // the size of the allocated grid. - int Rows; - int Columns; + int rows; + int cols; // The state of the grid is valid. Otherwise it needs to be redrawn. bool valid; @@ -111,4 +110,22 @@ struct ScreenGrid { false, 0, 0, NULL, false, true, 0, \ 0, 0, 0, 0, 0, false } +/// Status line click definition +typedef struct { + enum { + kStlClickDisabled = 0, ///< Clicks to this area are ignored. + kStlClickTabSwitch, ///< Switch to the given tab. + kStlClickTabClose, ///< Close given tab. + kStlClickFuncRun, ///< Run user function. + } type; ///< Type of the click. + int tabnr; ///< Tab page number. + char *func; ///< Function to run. +} StlClickDefinition; + +/// Used for tabline clicks +typedef struct { + StlClickDefinition def; ///< Click definition. + const char *start; ///< Location where region starts. +} StlClickRecord; + #endif // NVIM_GRID_DEFS_H diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c index fb174baef8..00a3c3cdab 100644 --- a/src/nvim/hardcopy.c +++ b/src/nvim/hardcopy.c @@ -116,7 +116,6 @@ static option_table_T printer_opts[OPT_PRINT_NUM_OPTIONS] } ; - static const uint32_t cterm_color_8[8] = { 0x000000, 0xff0000, 0x00ff00, 0xffff00, 0x0000ff, 0xff00ff, 0x00ffff, 0xffffff @@ -366,7 +365,6 @@ static char *parse_list_options(char_u *option_str, option_table_T *table, size_ return ret; } - /* * If using a dark background, the colors will probably be too bright to show * up well on white paper, so reduce their brightness. @@ -970,7 +968,6 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T return col; } - /* * PS printer stuff. * @@ -1242,7 +1239,6 @@ static struct prt_ps_mbfont_S prt_ps_mbfonts[] = #define PRT_RESOURCE_ENCODING "Encoding" #define PRT_RESOURCE_CMAP "CMap" - /* Data for table based DSC comment recognition, easy to extend if VIM needs to * read more comments. */ #define PRT_DSC_MISC_TYPE (-1) @@ -1254,7 +1250,6 @@ static struct prt_ps_mbfont_S prt_ps_mbfonts[] = #define PRT_DSC_VERSION "%%Version:" #define PRT_DSC_ENDCOMMENTS "%%EndComments:" - #define SIZEOF_CSTR(s) (sizeof(s) - 1) static struct prt_dsc_comment_S prt_dsc_table[] = { @@ -1265,7 +1260,6 @@ static struct prt_dsc_comment_S prt_dsc_table[] = PRT_DSC_ENDCOMMENTS_TYPE } }; - /* * Variables for the output PostScript file. */ @@ -2053,7 +2047,6 @@ static void prt_font_metrics(int font_scale) prt_char_width = PRT_PS_FONT_TO_USER(font_scale, prt_ps_font->wx); } - static int prt_get_cpl(void) { if (prt_use_number()) { @@ -2168,7 +2161,6 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit) struct prt_ps_encoding_S *p_mbenc_first; struct prt_ps_charset_S *p_mbchar = NULL; - /* * Set up font and encoding. */ diff --git a/src/nvim/hardcopy.h b/src/nvim/hardcopy.h index 16119c5d2d..7b28169a5b 100644 --- a/src/nvim/hardcopy.h +++ b/src/nvim/hardcopy.h @@ -80,7 +80,6 @@ typedef struct { #define PRINT_NUMBER_WIDTH 8 - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "hardcopy.h.generated.h" #endif diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c index 90ca0047bd..3bcd72fc39 100644 --- a/src/nvim/highlight.c +++ b/src/nvim/highlight.c @@ -229,7 +229,6 @@ int ns_get_hl(NS ns_id, int hl_id, bool link, bool nodefault) } } - bool win_check_ns_hl(win_T *wp) { if (ns_hl_changed) { @@ -760,7 +759,6 @@ Dictionary hlattrs2dict(HlAttrs ae, bool use_rgb) PUT(hl, "underdash", BOOLEAN_OBJ(true)); } - if (mask & HL_ITALIC) { PUT(hl, "italic", BOOLEAN_OBJ(true)); } diff --git a/src/nvim/highlight_defs.h b/src/nvim/highlight_defs.h index 0515842b61..caf345386d 100644 --- a/src/nvim/highlight_defs.h +++ b/src/nvim/highlight_defs.h @@ -111,7 +111,9 @@ typedef enum { HLF_NFLOAT, // Floating window HLF_MSG, // Message area HLF_BORDER, // Floating window border - HLF_COUNT, // MUST be the last one + HLF_WBR, // Window bars + HLF_WBRNC, // Window bars of not-current windows + HLF_COUNT, // MUST be the last one } hlf_T; EXTERN const char *hlf_names[] INIT(= { @@ -172,9 +174,10 @@ EXTERN const char *hlf_names[] INIT(= { [HLF_NFLOAT] = "NormalFloat", [HLF_MSG] = "MsgArea", [HLF_BORDER] = "FloatBorder", + [HLF_WBR] = "WinBar", + [HLF_WBRNC] = "WinBarNC", }); - EXTERN int highlight_attr[HLF_COUNT]; // Highl. attr for each context. EXTERN int highlight_attr_last[HLF_COUNT]; // copy for detecting changed groups EXTERN int highlight_user[9]; // User[1-9] attributes @@ -218,5 +221,4 @@ typedef struct { #define COLOR_ITEM_INITIALIZER { .attr_id = -1, .link_id = -1, \ .version = -1, .is_default = false } - #endif // NVIM_HIGHLIGHT_DEFS_H diff --git a/src/nvim/highlight_group.c b/src/nvim/highlight_group.c index 240a96cb4b..05781dd7e2 100644 --- a/src/nvim/highlight_group.c +++ b/src/nvim/highlight_group.c @@ -103,9 +103,11 @@ static const char *highlight_init_both[] = { "TabLineFill cterm=reverse gui=reverse", "TabLineSel cterm=bold gui=bold", "TermCursor cterm=reverse gui=reverse", + "WinBar cterm=bold gui=bold", "WildMenu ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black", "default link VertSplit Normal", "default link WinSeparator VertSplit", + "default link WinBarNC WinBar", "default link EndOfBuffer NonText", "default link LineNrAbove LineNr", "default link LineNrBelow LineNr", @@ -1833,7 +1835,6 @@ int syn_get_final_id(int hl_id) continue; } - if (sgp->sg_link == 0 || sgp->sg_link > highlight_ga.ga_len) { break; } diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c index 7174e58986..af0d32ad9c 100644 --- a/src/nvim/if_cscope.c +++ b/src/nvim/if_cscope.c @@ -68,7 +68,6 @@ static void cs_usage_msg(csid_e x) (void)semsg(_("E560: Usage: cs[cope] %s"), cs_cmds[(int)x].usage); } - static enum { EXP_CSCOPE_SUBCMD, // expand ":cscope" sub-commands EXP_SCSCOPE_SUBCMD, // expand ":scscope" sub-commands @@ -169,7 +168,6 @@ void set_context_in_cscope_cmd(expand_T *xp, const char *arg, cmdidx_T cmdidx) } } - /// Find the command, print help if invalid, and then call the corresponding /// command function. /// @@ -274,7 +272,6 @@ void ex_cstag(exarg_T *eap) } } - /// This simulates a vim_fgets(), but for cscope, returns the next line /// from the cscope output. should only be called from find_tags() /// @@ -292,7 +289,6 @@ bool cs_fgets(char_u *buf, int size) return false; } - /// Called only from do_tag(), when popping the tag stack. void cs_free_tags(void) { @@ -380,7 +376,6 @@ bool cs_connection(int num, char_u *dbpath, char_u *ppath) return false; } // cs_connection - /* * PRIVATE functions ****************************************************************************/ @@ -408,7 +403,6 @@ static void cs_stat_emsg(char *fname) (void)semsg(_("E563: stat(%s) error: %d"), fname, err); } - /// The common routine to add a new cscope connection. Called by /// cs_add() and cs_reset(). I really don't like to do this, but this /// routine uses a number of goto statements. @@ -520,7 +514,6 @@ add_err: return CSCOPE_FAILURE; } - static bool cs_check_for_connections(void) { return cs_cnt_connections() > 0; @@ -613,7 +606,6 @@ static int cs_cnt_matches(size_t idx) return nlines; } - /// Creates the actual cscope command query from what the user entered. static char *cs_create_cmd(char *csoption, char *pattern) { @@ -680,7 +672,6 @@ static char *cs_create_cmd(char *csoption, char *pattern) return cmd; } - /// This piece of code was taken/adapted from nvi. do we need to add /// the BSD license notice? static int cs_create_connection(size_t i) @@ -879,7 +870,6 @@ err_closing: return CSCOPE_SUCCESS; } - /// Query cscope using command line interface. Parse the output and use tselect /// to allow choices. Like Nvi, creates a pipe to send to/from query/cscope. /// @@ -918,7 +908,6 @@ static int cs_find(exarg_T *eap) eap->cmdidx == CMD_lcscope, (char_u *)(*eap->cmdlinep)); } - /// Common code for cscope find, shared by cs_find() and ex_cstag(). static bool cs_find_common(char *opt, char *pat, int forceit, int verbose, bool use_ll, char_u *cmdline) @@ -1119,7 +1108,6 @@ static int cs_help(exarg_T *eap) return CSCOPE_SUCCESS; } - static void clear_csinfo(size_t i) { csinfo[i].fname = NULL; @@ -1193,7 +1181,6 @@ static int cs_insert_filelist(char *fname, char *ppath, char *flags, FileInfo *f return (int)i; } - /// Find cscope command in command table. static cscmd_T *cs_lookup_cmd(exarg_T *eap) { @@ -1221,7 +1208,6 @@ static cscmd_T *cs_lookup_cmd(exarg_T *eap) return NULL; } - /// Nuke em. static int cs_kill(exarg_T *eap) { @@ -1281,7 +1267,6 @@ static int cs_kill(exarg_T *eap) return CSCOPE_SUCCESS; } - /// Actually kills a specific cscope connection. /// /// @param i cscope table index @@ -1296,7 +1281,6 @@ static void cs_kill_execute(size_t i, char *cname) cs_release_csp(i, TRUE); } - /// Convert the cscope output into a ctags style entry (as might be found /// in a ctags tags file). there's one catch though: cscope doesn't tell you /// the type of the tag you are looking for. for example, in Darren Hiebert's @@ -1343,7 +1327,6 @@ static char *cs_make_vim_style_matches(char *fname, char *slno, char *search, ch return buf; } - /// This is kind of hokey, but i don't see an easy way round this. /// /// Store: keep a ptr to the (malloc'd) memory of matches originally @@ -1415,7 +1398,6 @@ static char *cs_manage_matches(char **matches, char **contexts, size_t totmatche return p; } - /// Parse cscope output. static char *cs_parse_results(size_t cnumber, char *buf, int bufsize, char **context, char **linenumber, char **search) @@ -1581,7 +1563,6 @@ static void cs_fill_results(char *tagstr, size_t totmatches, int *nummatches_a, xfree(buf); } - // get the requested path components static char *cs_pathcomponents(char *path) { @@ -1929,7 +1910,6 @@ static void cs_release_csp(size_t i, bool freefnpp) clear_csinfo(i); } - /// Calls cs_kill on all cscope connections then reinits. static int cs_reset(exarg_T *eap) { @@ -1980,7 +1960,6 @@ static int cs_reset(exarg_T *eap) return CSCOPE_SUCCESS; } - /// Construct the full pathname to a file found in the cscope database. /// (Prepends ppath, if there is one and if it's not already prepended, /// otherwise just uses the name found.) @@ -2031,7 +2010,6 @@ static char *cs_resolve_file(size_t i, char *name) return fullname; } - /// Show all cscope connections. static int cs_show(exarg_T *eap) { @@ -2059,7 +2037,6 @@ static int cs_show(exarg_T *eap) return CSCOPE_SUCCESS; } - /// Only called when VIM exits to quit any cscope sessions. void cs_end(void) { diff --git a/src/nvim/indent.c b/src/nvim/indent.c index 882a10e1e8..010d2fe869 100644 --- a/src/nvim/indent.c +++ b/src/nvim/indent.c @@ -26,7 +26,6 @@ #include "nvim/strings.h" #include "nvim/undo.h" - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "indent.c.generated.h" #endif @@ -40,7 +39,6 @@ int get_indent(void) false); } - // Count the size (in window cells) of the indent in line "lnum". int get_indent_lnum(linenr_T lnum) { @@ -50,7 +48,6 @@ int get_indent_lnum(linenr_T lnum) false); } - // 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) @@ -61,7 +58,6 @@ int get_indent_buf(buf_T *buf, linenr_T lnum) false); } - /// 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. @@ -387,7 +383,6 @@ int set_indent(int size, int flags) return retval; } - // Return the indent of the current line after a number. Return -1 if no // number was found. Used for 'n' in 'formatoptions': numbered list. // Since a pattern is used it can actually handle more than numbers. @@ -580,7 +575,6 @@ int get_expr_indent(void) return indent; } - // When 'p' is present in 'cpoptions, a Vi compatible method is used. // The incompatible newer method is quite a bit better at indenting // code in lisp-like languages than the traditional one; it's still @@ -766,7 +760,6 @@ int get_lisp_indent(void) return amount; } - static int lisp_match(char_u *p) { char_u buf[LSIZE]; diff --git a/src/nvim/indent_c.c b/src/nvim/indent_c.c index e6dc985726..29d3c5f95b 100644 --- a/src/nvim/indent_c.c +++ b/src/nvim/indent_c.c @@ -212,7 +212,6 @@ int is_pos_in_string(const char_u *line, colnr_T col) * Below "XXX" means that this function may unlock the current line. */ - /* * Return true if the string "line" starts with a word from 'cinwords'. */ @@ -238,7 +237,6 @@ bool cin_is_cinword(const char_u *line) return retval; } - /* * Skip over white space and C comments within the line. * Also skip over Perl/shell comments if desired. @@ -1422,7 +1420,6 @@ static int cin_is_cpp_extern_c(const char_u *s) return false; } - /* * Skip strings, chars and comments until at or past "trypos". * Return the column found. @@ -1553,7 +1550,6 @@ static pos_T *find_match_paren_after_brace(int ind_maxparen) return trypos; } - /* * Return ind_maxparen corrected for the difference in line number between the * cursor position and "startpos". This makes sure that searching for a @@ -3746,7 +3742,6 @@ term_again: amount += curbuf->b_ind_comment; } - // add extra indent if the previous line ended in a backslash: // "asdfasdf{backslash} // here"; diff --git a/src/nvim/lib/kbtree.h b/src/nvim/lib/kbtree.h index 2edec527ff..99f79952d7 100644 --- a/src/nvim/lib/kbtree.h +++ b/src/nvim/lib/kbtree.h @@ -224,7 +224,6 @@ kb_putp_##name(b, &k); \ } - #define __KB_DEL(name, key_t, kbnode_t, T) \ static inline key_t __kb_delp_aux_##name(kbtree_##name##_t *b, kbnode_t *x, key_t * __restrict k, \ int s) \ diff --git a/src/nvim/lib/khash.h b/src/nvim/lib/khash.h index e81db43038..57a41f9c13 100644 --- a/src/nvim/lib/khash.h +++ b/src/nvim/lib/khash.h @@ -113,7 +113,6 @@ * Added destructor */ - #ifndef NVIM_LIB_KHASH_H #define NVIM_LIB_KHASH_H diff --git a/src/nvim/lib/klist.h b/src/nvim/lib/klist.h index c8489e298b..a9abbc6dc2 100644 --- a/src/nvim/lib/klist.h +++ b/src/nvim/lib/klist.h @@ -32,7 +32,6 @@ #include "nvim/func_attr.h" #include "nvim/memory.h" - #define KMEMPOOL_INIT(name, kmptype_t, kmpfree_f) \ typedef struct { \ size_t cnt, n, max; \ diff --git a/src/nvim/lib/kvec.h b/src/nvim/lib/kvec.h index 68841e0af8..4238088b1c 100644 --- a/src/nvim/lib/kvec.h +++ b/src/nvim/lib/kvec.h @@ -121,7 +121,6 @@ #define kv_push(v, x) \ (*kv_pushp(v) = (x)) - #define kv_a(v, i) \ (*(((v).capacity <= (size_t)(i) \ ? ((v).capacity = (v).size = (i) + 1, \ diff --git a/src/nvim/lib/queue.h b/src/nvim/lib/queue.h index e5574094bc..c6d3f74ec1 100644 --- a/src/nvim/lib/queue.h +++ b/src/nvim/lib/queue.h @@ -44,7 +44,6 @@ typedef struct _queue { (q) = next; \ } - // ffi.cdef is unable to swallow `bool` in place of `int` here. static inline int QUEUE_EMPTY(const QUEUE *const q) FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT diff --git a/src/nvim/log.h b/src/nvim/log.h index 81e39d1cdd..724d073d02 100644 --- a/src/nvim/log.h +++ b/src/nvim/log.h @@ -16,7 +16,6 @@ # define NVIM_PROBE(name, n, ...) #endif - #define TRACE_LOG_LEVEL 0 #define DEBUG_LOG_LEVEL 1 #define INFO_LOG_LEVEL 2 diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c index 782fc425fc..4d6e6090b8 100644 --- a/src/nvim/lua/converter.c +++ b/src/nvim/lua/converter.c @@ -49,7 +49,6 @@ typedef struct { #define LUA_PUSH_STATIC_STRING(lstate, s) \ lua_pushlstring(lstate, s, sizeof(s) - 1) - static LuaTableProps nlua_traverse_table(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { @@ -674,7 +673,6 @@ static inline void nlua_create_typed_table(lua_State *lstate, const size_t narr, lua_rawset(lstate, -3); } - /// Convert given String to lua string /// /// Leaves converted string on top of the stack. @@ -808,7 +806,6 @@ void nlua_push_Object(lua_State *lstate, const Object obj, bool special) } } - /// Convert lua value to string /// /// Always pops one value from the stack. @@ -1297,7 +1294,6 @@ void nlua_init_types(lua_State *const lstate) lua_rawset(lstate, -3); } - void nlua_pop_keydict(lua_State *L, void *retval, field_hash hashy, Error *err) { if (!lua_istable(L, -1)) { diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index c2d76e3ce8..0009420281 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -135,7 +135,6 @@ static int nlua_pcall(lua_State *lstate, int nargs, int nresults) return status; } - /// Gets the version of the current Nvim build. /// /// @param lstate Lua interpreter state. @@ -147,7 +146,6 @@ static int nlua_nvim_version(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL return 1; } - static void nlua_luv_error_event(void **argv) { char *error = (char *)argv[0]; @@ -1051,7 +1049,6 @@ static int nlua_empty_dict_tostring(lua_State *lstate) return 1; } - #ifdef WIN32 /// os.getenv: override os.getenv to maintain coherency. #9681 /// @@ -1065,7 +1062,6 @@ static int nlua_getenv(lua_State *lstate) } #endif - /// add the value to the registry /// The current implementation does not support calls from threads. LuaRef nlua_ref(lua_State *lstate, nlua_ref_state_t *ref_state, int index) @@ -1084,7 +1080,6 @@ LuaRef nlua_ref(lua_State *lstate, nlua_ref_state_t *ref_state, int index) return ref; } - LuaRef nlua_ref_global(lua_State *lstate, int index) { return nlua_ref(lstate, nlua_global_refs, index); @@ -1110,7 +1105,6 @@ void nlua_unref_global(lua_State *lstate, LuaRef ref) nlua_unref(lstate, nlua_global_refs, ref); } - void api_free_luaref(LuaRef ref) { nlua_unref_global(global_lstate, ref); @@ -1122,7 +1116,6 @@ void nlua_pushref(lua_State *lstate, LuaRef ref) lua_rawgeti(lstate, LUA_REGISTRYINDEX, ref); } - /// Gets a new reference to an object stored at original_ref /// /// NOTE: It does not copy the value, it creates a new ref to the lua object. @@ -1140,7 +1133,6 @@ LuaRef api_new_luaref(LuaRef original_ref) return new_ref; } - /// Evaluate lua string /// /// Used for luaeval(). @@ -1754,7 +1746,6 @@ char_u *nlua_register_table_as_callable(typval_T *const arg) char_u *name = register_cfunc(&nlua_CFunction_func_call, &nlua_CFunction_func_free, state); - lua_pop(lstate, 1); // [] assert(top == lua_gettop(lstate)); diff --git a/src/nvim/lua/stdlib.c b/src/nvim/lua/stdlib.c index 79e21e518c..432cb25adc 100644 --- a/src/nvim/lua/stdlib.c +++ b/src/nvim/lua/stdlib.c @@ -349,7 +349,6 @@ static dict_T *nlua_get_var_scope(lua_State *lstate) return dict; } - int nlua_setvar(lua_State *lstate) { // non-local return if not found @@ -470,7 +469,6 @@ static int nlua_stricmp(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL return 1; } - void nlua_state_add_stdlib(lua_State *const lstate, bool is_thread) { if (!is_thread) { diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index d3693207ec..6ec9cfd21d 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -529,7 +529,6 @@ static int parser_set_ranges(lua_State *L) size_t tbl_len = lua_objlen(L, 2); TSRange *ranges = xmalloc(sizeof(TSRange) * tbl_len); - // [ parser, ranges ] for (size_t index = 0; index < tbl_len; index++) { lua_rawgeti(L, 2, index + 1); // [ parser, ranges, range ] @@ -558,7 +557,6 @@ static int parser_get_ranges(lua_State *L) return 1; } - // Tree methods /// push tree interface on lua stack. @@ -656,7 +654,6 @@ static bool node_check(lua_State *L, int index, TSNode *res) return false; } - static int node_tostring(lua_State *L) { TSNode node; @@ -1059,7 +1056,6 @@ static int query_next_match(lua_State *L) return 0; } - static int query_next_capture(lua_State *L) { // Upvalues are: @@ -1205,7 +1201,6 @@ int tslua_parse_query(lua_State *L) return 1; } - static const char *query_err_string(TSQueryError err) { switch (err) { diff --git a/src/nvim/macros.h b/src/nvim/macros.h index c9c424568d..a896a406d1 100644 --- a/src/nvim/macros.h +++ b/src/nvim/macros.h @@ -94,7 +94,6 @@ #define REPLACE_NORMAL(s) (((s) & REPLACE_FLAG) && !((s) & VREPLACE_FLAG)) - // MB_PTR_ADV(): advance a pointer to the next character, taking care of // multi-byte characters if needed. Skip over composing chars. #define MB_PTR_ADV(p) (p += utfc_ptr2len((char *)p)) diff --git a/src/nvim/main.c b/src/nvim/main.c index 80a856e91a..936b42be23 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -530,11 +530,6 @@ int main(int argc, char **argv) // 'autochdir' has been postponed. do_autochdir(); - // start in insert mode - if (p_im) { - need_start_insertmode = true; - } - set_vim_var_nr(VV_VIM_DID_ENTER, 1L); apply_autocmds(EVENT_VIMENTER, NULL, NULL, false, curbuf); TIME_MSG("VimEnter autocommands"); @@ -815,7 +810,6 @@ static void init_locale(void) } #endif - static uint64_t server_connect(char *server_addr, const char **errmsg) { if (server_addr == NULL) { @@ -922,7 +916,6 @@ static void remote_request(mparm_T *params, int remote_args, char *server_addr, } } - /// Decides whether text (as opposed to commands) will be read from stdin. /// @see EDIT_STDIN static bool edit_stdin(bool explicit, mparm_T *parmp) @@ -1498,7 +1491,6 @@ static void set_window_layout(mparm_T *paramp) } } - /* * "-q errorfile": Load the error file now. * If the error file can't be read, exit before doing anything else. @@ -2180,7 +2172,6 @@ static void usage(void) mch_msg(_("\nSee \":help startup-options\" for all options.\n")); } - /* * Check the result of the ATTENTION dialog: * When "Quit" selected, exit Vim. diff --git a/src/nvim/map.c b/src/nvim/map.c index b3f48ad5d6..05ad113008 100644 --- a/src/nvim/map.c +++ b/src/nvim/map.c @@ -32,13 +32,12 @@ #define handle_T_hash kh_int_hash_func #define handle_T_eq kh_int_hash_equal - #if defined(ARCH_64) -# define ptr_t_hash(key) uint64_t_hash((uint64_t)key) -# define ptr_t_eq(a, b) uint64_t_eq((uint64_t)a, (uint64_t)b) +# define ptr_t_hash(key) uint64_t_hash((uint64_t)(key)) +# define ptr_t_eq(a, b) uint64_t_eq((uint64_t)(a), (uint64_t)(b)) #elif defined(ARCH_32) -# define ptr_t_hash(key) uint32_t_hash((uint32_t)key) -# define ptr_t_eq(a, b) uint32_t_eq((uint32_t)a, (uint32_t)b) +# define ptr_t_hash(key) uint32_t_hash((uint32_t)(key)) +# define ptr_t_eq(a, b) uint32_t_eq((uint32_t)(a), (uint32_t)(b)) #endif #define INITIALIZER(T, U) T##_##U##_initializer @@ -163,7 +162,6 @@ static inline bool ColorKey_eq(ColorKey ae1, ColorKey ae2) return memcmp(&ae1, &ae2, sizeof(ae1)) == 0; } - MAP_IMPL(int, int, DEFAULT_INITIALIZER) MAP_IMPL(cstr_t, ptr_t, DEFAULT_INITIALIZER) MAP_IMPL(cstr_t, int, DEFAULT_INITIALIZER) diff --git a/src/nvim/mark.c b/src/nvim/mark.c index 6de8d5dfd5..35000ce39a 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -1016,7 +1016,6 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, long amount, lo ONE_ADJUST(&(curbuf->b_last_cursor.mark.lnum)); } - // list of change positions for (i = 0; i < curbuf->b_changelistlen; i++) { ONE_ADJUST_NODEL(&(curbuf->b_changelist[i].mark.lnum)); @@ -1586,7 +1585,6 @@ void mark_mb_adjustpos(buf_T *buf, pos_T *lp) } } - // Add information about mark 'mname' to list 'l' static int add_mark(list_T *l, const char *mname, const pos_T *pos, int bufnr, const char *fname) FUNC_ATTR_NONNULL_ARG(1, 2, 3) @@ -1614,7 +1612,6 @@ static int add_mark(list_T *l, const char *mname, const pos_T *pos, int bufnr, c return OK; } - /// Get information about marks local to a buffer. /// /// @param[in] buf Buffer to get the marks from diff --git a/src/nvim/marktree.c b/src/nvim/marktree.c index fb2fa6bc7d..03340a99d6 100644 --- a/src/nvim/marktree.c +++ b/src/nvim/marktree.c @@ -58,7 +58,7 @@ #define ID_INCR (((uint64_t)1) << 2) -#define rawkey(itr) (itr->node->key[itr->i]) +#define rawkey(itr) ((itr)->node->key[(itr)->i]) static bool pos_leq(mtpos_t a, mtpos_t b) { @@ -575,7 +575,6 @@ void marktree_move(MarkTree *b, MarkTreeIter *itr, int row, int col) marktree_del_itr(b, itr, false); key.pos = (mtpos_t){ row, col }; - marktree_put_key(b, key); itr->node = NULL; // itr might become invalid by put } @@ -799,7 +798,6 @@ bool marktree_itr_node_done(MarkTreeIter *itr) return !itr->node || itr->i == itr->node->n - 1; } - mtpos_t marktree_itr_pos(MarkTreeIter *itr) { mtpos_t pos = rawkey(itr).pos; @@ -961,7 +959,6 @@ past_continue_same_node: } } - while (itr->node) { unrelative(oldbase[itr->lvl], &rawkey(itr).pos); int realrow = rawkey(itr).pos.row; diff --git a/src/nvim/marktree.h b/src/nvim/marktree.h index 5b3171d9aa..e2e05eebd5 100644 --- a/src/nvim/marktree.h +++ b/src/nvim/marktree.h @@ -32,7 +32,6 @@ typedef struct { iterstate_t s[MT_MAX_DEPTH]; } MarkTreeIter; - // Internal storage // // NB: actual marks have flags > 0, so we can use (row,col,0) pseudo-key for @@ -109,7 +108,6 @@ static inline uint16_t mt_flags(bool right_gravity, uint8_t decor_level) | (decor_level << MT_FLAG_DECOR_OFFSET)); } - struct mtnode_s { int32_t n; int32_t level; @@ -130,7 +128,6 @@ typedef struct { PMap(uint64_t) id2node[1]; } MarkTree; - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "marktree.h.generated.h" #endif diff --git a/src/nvim/math.c b/src/nvim/math.c index 63a29509bd..b427688083 100644 --- a/src/nvim/math.c +++ b/src/nvim/math.c @@ -1,7 +1,9 @@ // This is an open source non-commercial project. Dear PVS-Studio, please check // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +// uncrustify:off #include <math.h> +// uncrustify:on #include <stdint.h> #include <string.h> @@ -29,10 +31,12 @@ int xfpclassify(double d) return m ? FP_NAN : FP_INFINITE; } } + int xisinf(double d) { return FP_INFINITE == xfpclassify(d); } + int xisnan(double d) { return FP_NAN == xfpclassify(d); diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index 3868d65ab9..24d079ea2c 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -344,7 +344,6 @@ static int enc_canon_search(const char_u *name) return -1; } - /* * Find canonical encoding "name" in the list and return its properties. * Returns 0 if not found. @@ -473,27 +472,12 @@ static bool intable(const struct interval *table, size_t n_items, int c) int utf_char2cells(int c) { if (c >= 0x100) { -#ifdef USE_WCHAR_FUNCTIONS - // - // Assume the library function wcwidth() works better than our own - // stuff. It should return 1 for ambiguous width chars! - // - int n = wcwidth(c); - - if (n < 0) { - return 6; // unprintable, displays <xxxx> - } - if (n > 1) { - return n; - } -#else if (!utf_printable(c)) { return 6; // unprintable, displays <xxxx> } if (intable(doublewidth, ARRAY_SIZE(doublewidth), c)) { return 2; } -#endif if (p_emoji && intable(emoji_width, ARRAY_SIZE(emoji_width), c)) { return 2; } @@ -1061,12 +1045,6 @@ bool utf_iscomposing(int c) */ bool utf_printable(int c) { -#ifdef USE_WCHAR_FUNCTIONS - /* - * Assume the iswprint() library function works better than our own stuff. - */ - return iswprint(c); -#else // Sorted list of non-overlapping intervals. // 0xd800-0xdfff is reserved for UTF-16, actually illegal. static struct interval nonprint[] = @@ -1077,7 +1055,6 @@ bool utf_printable(int c) }; return !intable(nonprint, ARRAY_SIZE(nonprint), c); -#endif } /* @@ -1547,7 +1524,6 @@ ssize_t mb_utf_index_to_bytes(const char_u *s, size_t len, size_t index, bool us return -1; } - /* * Version of strnicmp() that handles multi-byte characters. * Needed for Big5, Shift-JIS and UTF-8 encoding. Other DBCS encodings can @@ -1889,7 +1865,6 @@ int mb_tail_off(const char_u *base, const char_u *p) return i; } - /// Return the offset from "p" to the first byte of the character it points /// into. Can start anywhere in a stream of bytes. /// Unlike utf_head_off() this doesn't include composing characters and returns a negative value. @@ -2151,7 +2126,6 @@ const char *mb_unescape(const char **const pp) return NULL; } - /* * Skip the Vim specific head of a 'encoding' name. */ @@ -2247,7 +2221,6 @@ static int enc_alias_search(const char_u *name) return -1; } - #ifdef HAVE_LANGINFO_H # include <langinfo.h> #endif @@ -2321,7 +2294,6 @@ enc_locale_copy_enc: #if defined(HAVE_ICONV) - /* * Call iconv_open() with a check if iconv() works properly (there are broken * versions). @@ -2451,7 +2423,6 @@ static char_u *iconv_string(const vimconv_T *const vcp, char_u *str, size_t slen #endif // HAVE_ICONV - /* * Setup "vcp" for conversion from "from" to "to". * The names must have been made canonical with enc_canonize(). diff --git a/src/nvim/memfile.c b/src/nvim/memfile.c index 28337803ac..c828334eaf 100644 --- a/src/nvim/memfile.c +++ b/src/nvim/memfile.c @@ -60,7 +60,6 @@ #define MEMFILE_PAGE_SIZE 4096 /// default page size - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "memfile.c.generated.h" #endif diff --git a/src/nvim/memline.c b/src/nvim/memline.c index ac6bdfa1a4..81d89ef3df 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -288,7 +288,6 @@ int ml_open(buf_T *buf) buf->b_ml.ml_line_count = 1; curwin->w_nrwidth_line_count = 0; - /* * fill block0 struct and write page 0 */ @@ -732,7 +731,6 @@ static void add_b0_fenc(ZERO_BL *b0p, buf_T *buf) } } - /// Try to recover curbuf from the .swp file. /// /// @param checkext if true, check the extension and detect whether it is a @@ -2445,7 +2443,6 @@ void ml_add_deleted_len_buf(buf_T *buf, char_u *ptr, ssize_t len) } } - int ml_replace(linenr_T lnum, char *line, bool copy) { return ml_replace_buf(curbuf, lnum, (char_u *)line, copy); @@ -3304,7 +3301,6 @@ char_u *get_file_in_dir(char_u *fname, char_u *dname) return retval; } - /// Print the ATTENTION message: info about an existing swap file. /// /// @param buf buffer being edited @@ -3351,7 +3347,6 @@ static void attention_message(buf_T *buf, char_u *fname) --no_wait_return; } - /// Trigger the SwapExists autocommands. /// /// @return a value for equivalent to do_dialog() (see below): diff --git a/src/nvim/memory.c b/src/nvim/memory.c index 8a65188f22..19a520636e 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -661,7 +661,6 @@ void free_all_mem(void) ResetRedobuff(); ResetRedobuff(); - // highlight info free_highlight(); diff --git a/src/nvim/menu.c b/src/nvim/menu.c index c1ce2eefe3..01a44224e8 100644 --- a/src/nvim/menu.c +++ b/src/nvim/menu.c @@ -31,12 +31,10 @@ #define MENUDEPTH 10 // maximum depth of menus - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "menu.c.generated.h" #endif - /// The character for each menu mode static char menu_mode_chars[] = { 'n', 'v', 's', 'o', 'i', 'c', 't' }; @@ -98,7 +96,6 @@ void ex_menu(exarg_T *eap) break; } - // Locate an optional "icon=filename" argument // TODO(nvim): Currently this is only parsed. Should expose it to UIs. if (STRNCMP(arg, "icon=", 5) == 0) { @@ -162,7 +159,6 @@ void ex_menu(exarg_T *eap) return; } - menu_path = arg; if (*menu_path == '.') { semsg(_(e_invarg2), menu_path); @@ -268,7 +264,6 @@ theend: ; } - /// Add the menu with the given name to the menu hierarchy /// /// @param[out] menuarg menu entry @@ -398,7 +393,6 @@ static int add_menu_path(const char *const menu_path, vimmenu_T *menuarg, const } } - menup = &menu->children; parent = menu; name = next_name; @@ -543,7 +537,6 @@ static int menu_enable_recurse(vimmenu_T *menu, char *name, int modes, int enabl return FAIL; } - return OK; } @@ -615,7 +608,6 @@ static int remove_menu(vimmenu_T **menup, char *name, int modes, bool silent) return FAIL; } - // Recalculate modes for menu based on the new updated children menu->modes &= ~modes; child = menu->children; @@ -645,7 +637,6 @@ static void free_menu(vimmenu_T **menup) menu = *menup; - // Don't change *menup until after calling gui_mch_destroy_menu(). The // MacOS code needs the original structure to properly delete the menu. *menup = menu->next; @@ -749,7 +740,6 @@ static dict_T *menu_get_recursive(const vimmenu_T *menu, int modes) return dict; } - /// Export menus matching path \p path_name /// /// @param path_name @@ -776,7 +766,6 @@ bool menu_get(char *const path_name, int modes, list_T *list) return true; } - /// Find menu matching `name` and `modes`. /// /// @param menu top menu to start looking from @@ -913,7 +902,6 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth) } } - /* * Used when expanding menu names. */ @@ -937,7 +925,6 @@ char *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char *arg, bool for xp->xp_context = EXPAND_UNSUCCESSFUL; - // Check for priority numbers, enable and disable for (p = arg; *p; ++p) { if (!ascii_isdigit(*p) && *p != '.') { @@ -1146,7 +1133,6 @@ char *get_menu_names(expand_T *xp, int idx) return str; } - /// Skip over this element of the menu path and return the start of the next /// element. Any \ and ^Vs are removed from the current element. /// @@ -1197,7 +1183,6 @@ static bool menu_namecmp(const char *const name, const char *const mname) && (mname[i] == NUL || mname[i] == TAB); } - /// Returns the \ref MENU_MODES specified by menu command `cmd`. /// (eg :menu! returns MENU_CMDLINE_MODE | MENU_INSERT_MODE) /// @@ -1281,7 +1266,6 @@ static char *popup_mode_name(char *name, int idx) return p; } - /// Duplicate the menu item text and then process to see if a mnemonic key /// and/or accelerator text has been identified. /// @@ -1346,7 +1330,6 @@ bool menu_is_popup(const char *const name) return STRNCMP(name, "PopUp", 5) == 0; } - // Return true if "name" is a toolbar menu name. bool menu_is_toolbar(const char *const name) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL @@ -1363,7 +1346,6 @@ int menu_is_separator(char *name) return name[0] == '-' && name[STRLEN(name) - 1] == '-'; } - /// True if a popup menu or starts with \ref MNU_HIDDEN_CHAR /// /// @return true if the menu is hidden diff --git a/src/nvim/message.c b/src/nvim/message.c index 9ab086f1ea..2e57d11fb6 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -114,7 +114,6 @@ bool keep_msg_more = false; // keep_msg was set by msgmore() * This is an allocated string or NULL when not used. */ - // Extended msg state, currently used for external UIs with ext_messages static const char *msg_ext_kind = NULL; static Array msg_ext_chunks = ARRAY_DICT_INIT; @@ -125,6 +124,8 @@ static size_t msg_ext_cur_len = 0; static bool msg_ext_overwrite = false; ///< will overwrite last message static int msg_ext_visible = 0; ///< number of messages currently visible +static bool msg_ext_history_visible = false; + /// Shouldn't clear message after leaving cmdline static bool msg_ext_keep_after_cmdline = false; @@ -162,7 +163,7 @@ void msg_grid_validate(void) { grid_assign_handle(&msg_grid); bool should_alloc = msg_use_grid(); - if (should_alloc && (msg_grid.Rows != Rows || msg_grid.Columns != Columns + if (should_alloc && (msg_grid.rows != Rows || msg_grid.cols != Columns || !msg_grid.chars)) { // TODO(bfredl): eventually should be set to "invalid". I e all callers // will use the grid including clear to EOS if necessary. @@ -174,9 +175,9 @@ void msg_grid_validate(void) // Tricky: allow resize while pager is active int pos = msg_scrolled ? msg_grid_pos : Rows - p_ch; - ui_comp_put_grid(&msg_grid, pos, 0, msg_grid.Rows, msg_grid.Columns, + ui_comp_put_grid(&msg_grid, pos, 0, msg_grid.rows, msg_grid.cols, false, true); - ui_call_grid_resize(msg_grid.handle, msg_grid.Columns, msg_grid.Rows); + ui_call_grid_resize(msg_grid.handle, msg_grid.cols, msg_grid.rows); msg_grid.throttled = false; // don't throttle in 'cmdheight' area msg_scrolled_at_flush = msg_scrolled; @@ -263,7 +264,6 @@ void msg_multiline_attr(const char *s, int attr, bool check_int, bool *need_clea } } - /// @param keep set keep_msg if it doesn't scroll bool msg_attr_keep(const char *s, int attr, bool keep, bool multiline) FUNC_ATTR_NONNULL_ALL @@ -758,7 +758,6 @@ bool semsg_multiline(const char *const fmt, ...) bool ret; va_list ap; - static char errbuf[MULTILINE_BUFSIZE]; if (emsg_not_now()) { return true; @@ -1008,7 +1007,6 @@ void ex_messages(void *const eap_p) return; } - p = first_msg_hist; if (eap->addr_count != 0) { @@ -1025,6 +1023,9 @@ void ex_messages(void *const eap_p) // Display what was not skipped. if (ui_has(kUIMessages)) { + if (msg_silent) { + return; + } Array entries = ARRAY_DICT_INIT; for (; p != NULL; p = p->next) { if (p->msg != NULL && p->msg[0] != NUL) { @@ -1040,6 +1041,8 @@ void ex_messages(void *const eap_p) } } ui_call_msg_history_show(entries); + msg_ext_history_visible = true; + wait_return(false); } else { msg_hist_off = true; for (; p != NULL && !got_int; p = p->next) { @@ -1161,7 +1164,6 @@ void wait_return(int redraw) reg_recording = save_reg_recording; scriptout = save_scriptout; - /* * Allow scrolling back in the messages. * Also accept scroll-down commands when messages fill the screen, @@ -1336,7 +1338,6 @@ void msgmore(long n) } } - void msg_ext_set_kind(const char *msg_kind) { // Don't change the label of an existing batch: @@ -2320,10 +2321,10 @@ void msg_scroll_up(bool may_throttle) if (msg_grid_pos > 0) { msg_grid_set_pos(msg_grid_pos - 1, true); } else { - grid_del_lines(&msg_grid, 0, 1, msg_grid.Rows, 0, msg_grid.Columns); + grid_del_lines(&msg_grid, 0, 1, msg_grid.rows, 0, msg_grid.cols); memmove(msg_grid.dirty_col, msg_grid.dirty_col + 1, - (msg_grid.Rows - 1) * sizeof(*msg_grid.dirty_col)); - msg_grid.dirty_col[msg_grid.Rows - 1] = 0; + (msg_grid.rows - 1) * sizeof(*msg_grid.dirty_col)); + msg_grid.dirty_col[msg_grid.rows - 1] = 0; } } else { grid_del_lines(&msg_grid_adj, 0, 1, Rows, 0, Columns); @@ -2356,7 +2357,7 @@ void msg_scroll_flush(void) msg_grid.throttled = false; int pos_delta = msg_grid_pos_at_flush - msg_grid_pos; assert(pos_delta >= 0); - int delta = MIN(msg_scrolled - msg_scrolled_at_flush, msg_grid.Rows); + int delta = MIN(msg_scrolled - msg_scrolled_at_flush, msg_grid.rows); if (pos_delta > 0) { ui_ext_msg_set_pos(msg_grid_pos, true); @@ -2374,7 +2375,7 @@ void msg_scroll_flush(void) for (int i = MAX(Rows - MAX(delta, 1), 0); i < Rows; i++) { int row = i - msg_grid_pos; assert(row >= 0); - ui_line(&msg_grid, row, 0, msg_grid.dirty_col[row], msg_grid.Columns, + ui_line(&msg_grid, row, 0, msg_grid.dirty_col[row], msg_grid.cols, HL_ATTR(HLF_MSG), false); msg_grid.dirty_col[row] = 0; } @@ -2400,9 +2401,9 @@ void msg_reset_scroll(void) clear_cmdline = true; if (msg_grid.chars) { // non-displayed part of msg_grid is considered invalid. - for (int i = 0; i < MIN(msg_scrollsize(), msg_grid.Rows); i++) { + for (int i = 0; i < MIN(msg_scrollsize(), msg_grid.rows); i++) { grid_clear_line(&msg_grid, msg_grid.line_offset[i], - msg_grid.Columns, false); + msg_grid.cols, false); } } } else { @@ -2735,7 +2736,6 @@ static int do_more_prompt(int typed_char) c = get_keystroke(resize_events); } - toscroll = 0; switch (c) { case BS: // scroll one line back @@ -3126,6 +3126,10 @@ void msg_ext_clear(bool force) msg_ext_visible = 0; msg_ext_overwrite = false; // nothing to overwrite } + if (msg_ext_history_visible) { + ui_call_msg_history_clear(); + msg_ext_history_visible = false; + } // Only keep once. msg_ext_keep_after_cmdline = false; @@ -3429,7 +3433,6 @@ int do_dialog(int type, char_u *title, char_u *message, char_u *buttons, int dfl return dfltbutton; // return default option } - int save_msg_silent = msg_silent; int oldState = State; @@ -3496,7 +3499,6 @@ int do_dialog(int type, char_u *title, char_u *message, char_u *buttons, int dfl return retval; } - /// Copy one character from "*from" to "*to", taking care of multi-byte /// characters. Return the length of the character in bytes. /// @@ -3567,7 +3569,6 @@ static char_u *console_dialog_alloc(const char_u *message, char_u *buttons, bool len += 2; // "x" -> "[x]" } - // Now allocate space for the strings xfree(confirm_msg); confirm_msg = xmalloc(len); diff --git a/src/nvim/message.h b/src/nvim/message.h index 316b2df7a4..b402ee8b60 100644 --- a/src/nvim/message.h +++ b/src/nvim/message.h @@ -69,7 +69,6 @@ EXTERN ScreenGrid msg_grid_adj INIT(= SCREEN_GRID_INIT); // value of msg_scrolled at latest msg_scroll_flush. EXTERN int msg_scrolled_at_flush INIT(= 0); - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "message.h.generated.h" #endif diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 8038ba2cad..fc5ecbc6a0 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -68,12 +68,12 @@ bool is_mouse_key(int c) /// mouse was previously on a status line, then the status line may be dragged. /// /// If flags has MOUSE_MAY_VIS, then VIsual mode will be started before the -/// cursor is moved unless the cursor was on a status line. +/// cursor is moved unless the cursor was on a status line or window bar. /// This function returns one of IN_UNKNOWN, IN_BUFFER, IN_STATUS_LINE or /// IN_SEP_LINE depending on where the cursor was clicked. /// /// If flags has MOUSE_MAY_STOP_VIS, then Visual mode will be stopped, unless -/// the mouse is on the status line of the same window. +/// the mouse is on the status line or window bar of the same window. /// /// If flags has MOUSE_DID_MOVE, nothing is done if the mouse didn't move since /// the last call. @@ -87,6 +87,7 @@ int jump_to_mouse(int flags, bool *inclusive, int which_button) { static int on_status_line = 0; // #lines below bottom of window static int on_sep_line = 0; // on separator right of window + static bool on_winbar = false; static int prev_row = -1; static int prev_col = -1; static win_T *dragwin = NULL; // window being dragged @@ -126,6 +127,9 @@ retnomove: if (on_sep_line) { return IN_SEP_LINE; } + if (on_winbar) { + return IN_OTHER_WIN | MOUSE_WINBAR; + } if (flags & MOUSE_MAY_STOP_VIS) { end_visual_mode(); redraw_curbuf_later(INVERTED); // delete the inversion @@ -156,13 +160,15 @@ retnomove: dragwin = NULL; if (row == -1) { - return IN_OTHER_WIN; + on_winbar = wp->w_winbar_height != 0; + return IN_OTHER_WIN | (on_winbar ? MOUSE_WINBAR : 0); } + on_winbar = false; // winpos and height may change in win_enter()! - if (grid == DEFAULT_GRID_HANDLE && row >= wp->w_height) { + if (grid == DEFAULT_GRID_HANDLE && row + wp->w_winbar_height >= wp->w_height) { // In (or below) status line - on_status_line = row - wp->w_height + 1; + on_status_line = row + wp->w_winbar_height - wp->w_height + 1; dragwin = wp; } else { on_status_line = 0; @@ -235,8 +241,8 @@ retnomove: } curwin->w_cursor.lnum = curwin->w_topline; - } else if (on_status_line && which_button == MOUSE_LEFT) { - if (dragwin != NULL) { + } else if (on_status_line) { + if (which_button == MOUSE_LEFT && dragwin != NULL) { // Drag the status line count = row - dragwin->w_winrow - dragwin->w_height + 1 - on_status_line; @@ -253,6 +259,9 @@ retnomove: did_drag |= count; } return IN_SEP_LINE; // Cursor didn't move + } else if (on_winbar) { + // After a click on the window bar don't start Visual mode. + return IN_OTHER_WIN | MOUSE_WINBAR; } else { // keep_window_focus must be true // before moving the cursor for a left click, stop Visual mode @@ -264,6 +273,9 @@ retnomove: if (grid == 0) { row -= curwin->w_grid_alloc.comp_row + curwin->w_grid.row_offset; col -= curwin->w_grid_alloc.comp_col + curwin->w_grid.col_offset; + } else if (grid != DEFAULT_GRID_HANDLE) { + row -= curwin->w_grid.row_offset; + col -= curwin->w_grid.col_offset; } // When clicking beyond the end of the window, scroll the screen. @@ -468,7 +480,6 @@ win_T *mouse_find_win(int *gridp, int *rowp, int *colp) return NULL; } - frame_T *fp; fp = topframe; @@ -497,6 +508,7 @@ win_T *mouse_find_win(int *gridp, int *rowp, int *colp) // exist. FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { if (wp == fp->fr_win) { + *rowp -= wp->w_winbar_height; return wp; } } @@ -512,8 +524,8 @@ static win_T *mouse_find_grid_win(int *gridp, int *rowp, int *colp) win_T *wp = get_win_by_grid_handle(*gridp); if (wp && wp->w_grid_alloc.chars && !(wp->w_floating && !wp->w_float_config.focusable)) { - *rowp = MIN(*rowp - wp->w_grid.row_offset, wp->w_grid.Rows - 1); - *colp = MIN(*colp - wp->w_grid.col_offset, wp->w_grid.Columns - 1); + *rowp = MIN(*rowp - wp->w_grid.row_offset, wp->w_grid.rows - 1); + *colp = MIN(*colp - wp->w_grid.col_offset, wp->w_grid.cols - 1); return wp; } } else if (*gridp == 0) { @@ -560,7 +572,6 @@ void setmouse(void) ui_check_mouse(); } - // Set orig_topline. Used when jumping to another window, so that a double // click still works. void set_mouse_topline(win_T *wp) @@ -784,8 +795,8 @@ int mouse_check_fold(void) wp = mouse_find_win(&click_grid, &click_row, &click_col); if (wp && multigrid) { - max_row = wp->w_grid_alloc.Rows; - max_col = wp->w_grid_alloc.Columns; + max_row = wp->w_grid_alloc.rows; + max_col = wp->w_grid_alloc.cols; } if (wp && mouse_row >= 0 && mouse_row < max_row diff --git a/src/nvim/mouse.h b/src/nvim/mouse.h index 04acb88bb3..08261e4a30 100644 --- a/src/nvim/mouse.h +++ b/src/nvim/mouse.h @@ -41,7 +41,6 @@ #define MSCR_LEFT (-1) #define MSCR_RIGHT (-2) - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "mouse.h.generated.h" #endif diff --git a/src/nvim/move.c b/src/nvim/move.c index 11feb497ea..9f72b36638 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -45,7 +45,6 @@ typedef struct { # include "move.c.generated.h" #endif - /* * Compute wp->w_botline for the current wp->w_topline. Can be called after * wp->w_topline changed. @@ -1016,7 +1015,7 @@ void textpos2screenpos(win_T *wp, pos_T *pos, int *rowp, int *scolp, int *ccolp, col -= wp->w_leftcol; if (col >= 0 && col < wp->w_width) { - coloff = col - scol + (local ? 0 : wp->w_wincol + wp->w_border_adj[3]) + 1; + coloff = col - scol + (local ? 0 : wp->w_wincol + wp->w_wincol_off) + 1; } else { scol = ccol = ecol = 0; // character is left or right of the window @@ -1027,7 +1026,7 @@ void textpos2screenpos(win_T *wp, pos_T *pos, int *rowp, int *scolp, int *ccolp, } } } - *rowp = (local ? 0 : wp->w_winrow + wp->w_border_adj[0]) + row + rowoff; + *rowp = (local ? 0 : wp->w_winrow + wp->w_winrow_off) + row + rowoff; *scolp = scol + coloff; *ccolp = ccol + coloff; *ecolp = ecol + coloff; @@ -1863,7 +1862,6 @@ void cursor_correct(void) curwin->w_viewport_invalid = true; } - /* * move screen 'count' pages up or down and update screen * diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 48ecd5d0ea..79ecd9f827 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -49,7 +49,6 @@ void rpc_init(void) msgpack_sbuffer_init(&out_buffer); } - void rpc_start(Channel *channel) { channel_incref(channel); @@ -73,7 +72,6 @@ void rpc_start(Channel *channel) } } - static Channel *find_rpc_channel(uint64_t id) { Channel *chan = find_channel(id); @@ -359,7 +357,6 @@ static void handle_request(Channel *channel, msgpack_object *request) } } - /// Handles a message, depending on the type: /// - Request: invokes method and writes the response (or error). /// - Notification: invokes method (emits `nvim_error_event` on error). @@ -413,7 +410,6 @@ static bool channel_write(Channel *channel, WBuffer *buffer) success = wstream_write(in, buffer); } - if (!success) { // If the write failed for any reason, close the channel char buf[256]; @@ -535,7 +531,6 @@ static void unsubscribe(Channel *channel, char *event) xfree(event_string); } - /// Mark rpc state as closed, and release its reference to the channel. /// Don't call this directly, call channel_close(id, kChannelPartRpc, &error) void rpc_close(Channel *channel) diff --git a/src/nvim/msgpack_rpc/channel.h b/src/nvim/msgpack_rpc/channel.h index eb0de47437..ac7911bb2c 100644 --- a/src/nvim/msgpack_rpc/channel.h +++ b/src/nvim/msgpack_rpc/channel.h @@ -17,7 +17,6 @@ /// of os_inchar(), so they are processed "just-in-time". EXTERN MultiQueue *ch_before_blocking_events INIT(= NULL); - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "msgpack_rpc/channel.h.generated.h" #endif diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c index 32014fcf2b..488321be42 100644 --- a/src/nvim/msgpack_rpc/helpers.c +++ b/src/nvim/msgpack_rpc/helpers.c @@ -22,7 +22,6 @@ static msgpack_zone zone; static msgpack_sbuffer sbuffer; - void msgpack_rpc_helpers_init(void) { msgpack_zone_init(&zone, 0xfff); @@ -252,7 +251,6 @@ bool msgpack_rpc_to_dictionary(const msgpack_object *const obj, Dictionary *cons arg->size = obj->via.array.size; arg->items = xcalloc(obj->via.map.size, sizeof(KeyValuePair)); - for (uint32_t i = 0; i < obj->via.map.size; i++) { if (!msgpack_rpc_to_string(&obj->via.map.ptr[i].key, &arg->items[i].key)) { diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 2826b7dad1..d806741175 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -32,6 +32,7 @@ #include "nvim/fold.h" #include "nvim/getchar.h" #include "nvim/globals.h" +#include "nvim/grid_defs.h" #include "nvim/indent.h" #include "nvim/keycodes.h" #include "nvim/log.h" @@ -85,7 +86,6 @@ typedef struct normal_state { static int VIsual_mode_orig = NUL; // saved Visual mode - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "normal.c.generated.h" #endif @@ -431,15 +431,15 @@ static int find_command(int cmdchar) return idx; } -// Normal state entry point. This is called on: -// -// - Startup, In this case the function never returns. -// - The command-line window is opened(`q:`). Returns when `cmdwin_result` != 0. -// - The :visual command is called from :global in ex mode, `:global/PAT/visual` -// for example. Returns when re-entering ex mode(because ex mode recursion is -// not allowed) -// -// This used to be called main_loop on main.c +/// Normal state entry point. This is called on: +/// +/// - Startup, In this case the function never returns. +/// - The command-line window is opened(`q:`). Returns when `cmdwin_result` != 0. +/// - The :visual command is called from :global in ex mode, `:global/PAT/visual` +/// for example. Returns when re-entering ex mode(because ex mode recursion is +/// not allowed) +/// +/// This used to be called main_loop on main.c void normal_enter(bool cmdwin, bool noexmode) { NormalState state; @@ -1126,9 +1126,6 @@ static int normal_execute(VimState *state, int key) if (s->ca.nchar == ESC) { clearop(&s->oa); - if (restart_edit == 0 && goto_im()) { - restart_edit = 'a'; - } s->command_finished = true; goto finish; } @@ -1178,14 +1175,6 @@ static void normal_check_stuff_buffer(NormalState *s) // if wait_return still needed call it now wait_return(false); } - - if (need_start_insertmode && goto_im() && !VIsual_active) { - need_start_insertmode = false; - stuffReadbuff("i"); // start insert mode next - // skip the fileinfo message now, because it would be shown - // after insert mode finishes! - need_fileinfo = false; - } } } @@ -1280,7 +1269,8 @@ static void normal_redraw(NormalState *s) validate_cursor(); if (VIsual_active) { - update_curbuf(INVERTED); // update inverted part + redraw_curbuf_later(INVERTED); // update inverted part + update_screen(INVERTED); } else if (must_redraw) { update_screen(0); } else if (redraw_cmdline || clear_cmdline) { @@ -1325,11 +1315,12 @@ static void normal_redraw(NormalState *s) setcursor(); } -// Function executed before each iteration of normal mode. -// Return: -// 1 if the iteration should continue normally -// -1 if the iteration should be skipped -// 0 if the main loop must exit +/// Function executed before each iteration of normal mode. +/// +/// @return: +/// 1 if the iteration should continue normally +/// -1 if the iteration should be skipped +/// 0 if the main loop must exit static int normal_check(VimState *state) { NormalState *s = (NormalState *)state; @@ -1428,8 +1419,8 @@ static void set_vcount_ca(cmdarg_T *cap, bool *set_prevcount) *set_prevcount = false; // only set v:prevcount once } -// Move the current tab to tab in same column as mouse or to end of the -// tabline if there is no tab there. +/// Move the current tab to tab in same column as mouse or to end of the +/// tabline if there is no tab there. static void move_tab_to_mouse(void) { int tabnr = tab_page_click_defs[mouse_col].tabnr; @@ -1442,6 +1433,63 @@ static void move_tab_to_mouse(void) } } +/// Call click definition function for column "col" in the "click_defs" array for button +/// "which_button". +static void call_click_def_func(StlClickDefinition *click_defs, int col, int which_button) +{ + typval_T argv[] = { + { + .v_lock = VAR_FIXED, + .v_type = VAR_NUMBER, + .vval = { + .v_number = (varnumber_T)click_defs[col].tabnr + }, + }, + { + .v_lock = VAR_FIXED, + .v_type = VAR_NUMBER, + .vval = { + .v_number = ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_4CLICK + ? 4 + : ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_3CLICK + ? 3 + : ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK + ? 2 + : 1))) + }, + }, + { + .v_lock = VAR_FIXED, + .v_type = VAR_STRING, + .vval = { + .v_string = (which_button == MOUSE_LEFT + ? "l" + : (which_button == MOUSE_RIGHT + ? "r" + : (which_button == MOUSE_MIDDLE + ? "m" + : "?"))) + }, + }, + { + .v_lock = VAR_FIXED, + .v_type = VAR_STRING, + .vval = { + .v_string = (char[]) { + (char)(mod_mask & MOD_MASK_SHIFT ? 's' : ' '), + (char)(mod_mask & MOD_MASK_CTRL ? 'c' : ' '), + (char)(mod_mask & MOD_MASK_ALT ? 'a' : ' '), + (char)(mod_mask & MOD_MASK_META ? 'm' : ' '), + NUL + } + }, + } + }; + typval_T rettv; + (void)call_vim_function(click_defs[col].func, ARRAY_SIZE(argv), argv, &rettv); + tv_clear(&rettv); +} + /// Do the appropriate action for the current mouse click in the current mode. /// Not used for Command-line mode. /// @@ -1491,6 +1539,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) int jump_flags = 0; // flags for jump_to_mouse() pos_T start_visual; bool moved; // Has cursor moved? + bool in_winbar; // mouse in window bar bool in_status_line; // mouse in status line static bool in_tab_line = false; // mouse clicked in tab line bool in_sep_line; // mouse in vertical separator line @@ -1556,7 +1605,6 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) } } - // CTRL right mouse button does CTRL-T if (is_click && (mod_mask & MOD_MASK_CTRL) && which_button == MOUSE_RIGHT) { if (State & MODE_INSERT) { @@ -1721,66 +1769,10 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) } } break; - case kStlClickFuncRun: { - typval_T argv[] = { - { - .v_lock = VAR_FIXED, - .v_type = VAR_NUMBER, - .vval = { - .v_number = (varnumber_T)tab_page_click_defs[mouse_col].tabnr - }, - }, - { - .v_lock = VAR_FIXED, - .v_type = VAR_NUMBER, - .vval = { - .v_number = ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_4CLICK - ? 4 - : ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_3CLICK - ? 3 - : ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK - ? 2 - : 1))) - }, - }, - { - .v_lock = VAR_FIXED, - .v_type = VAR_STRING, - .vval = { - .v_string = (which_button == MOUSE_LEFT - ? "l" - : (which_button == MOUSE_RIGHT - ? "r" - : (which_button == MOUSE_MIDDLE - ? "m" - : "?"))) - }, - }, - { - .v_lock = VAR_FIXED, - .v_type = VAR_STRING, - .vval = { - .v_string = (char[]) { - (char)(mod_mask & MOD_MASK_SHIFT ? 's' : ' '), - (char)(mod_mask & MOD_MASK_CTRL ? 'c' : ' '), - (char)(mod_mask & MOD_MASK_ALT ? 'a' : ' '), - (char)(mod_mask & MOD_MASK_META ? 'm' : ' '), - NUL - } - }, - } - }; - typval_T rettv; - funcexe_T funcexe = FUNCEXE_INIT; - funcexe.firstline = curwin->w_cursor.lnum; - funcexe.lastline = curwin->w_cursor.lnum; - funcexe.evaluate = true; - (void)call_func(tab_page_click_defs[mouse_col].func, -1, - &rettv, ARRAY_SIZE(argv), argv, &funcexe); - tv_clear(&rettv); + case kStlClickFuncRun: + call_click_def_func(tab_page_click_defs, mouse_col, which_button); break; } - } } return true; } else if (is_drag && in_tab_line) { @@ -1788,7 +1780,6 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) return false; } - // When 'mousemodel' is "popup" or "popup_setpos", translate mouse events: // right button up -> pop-up menu // shift-left button -> right button @@ -1851,9 +1842,41 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) which_button); moved = (jump_flags & CURSOR_MOVED); + in_winbar = (jump_flags & MOUSE_WINBAR); in_status_line = (jump_flags & IN_STATUS_LINE); in_sep_line = (jump_flags & IN_SEP_LINE); + if ((in_winbar || in_status_line) && is_click) { + // Handle click event on window bar or status lin + int click_grid = mouse_grid; + int click_row = mouse_row; + int click_col = mouse_col; + win_T *wp = mouse_find_win(&click_grid, &click_row, &click_col); + if (wp == NULL) { + return false; + } + + StlClickDefinition *click_defs = in_status_line ? wp->w_status_click_defs + : wp->w_winbar_click_defs; + + if (click_defs != NULL) { + switch (click_defs[click_col].type) { + case kStlClickDisabled: + break; + case kStlClickFuncRun: + call_click_def_func(click_defs, click_col, which_button); + break; + default: + assert(false && "winbar and statusline only support %@ for clicks"); + break; + } + } + + return false; + } else if (in_winbar) { + // A drag or release event in the window bar has no side effects. + return false; + } // When jumping to another window, clear a pending operator. That's a bit // friendlier than beeping and not jumping to that window. @@ -1877,7 +1900,6 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) } } - // Set global flag that we are extending the Visual area with mouse dragging; // temporarily minimize 'scrolloff'. if (VIsual_active && is_drag && get_scrolloff_value(curwin)) { @@ -2250,12 +2272,14 @@ void restore_visual_mode(void) } } -// Check for a balloon-eval special item to include when searching for an -// identifier. When "dir" is BACKWARD "ptr[-1]" must be valid! -// Returns true if the character at "*ptr" should be included. -// "dir" is FORWARD or BACKWARD, the direction of searching. -// "*colp" is in/decremented if "ptr[-dir]" should also be included. -// "bnp" points to a counter for square brackets. +/// Check for a balloon-eval special item to include when searching for an +/// identifier. When "dir" is BACKWARD "ptr[-1]" must be valid! +/// +/// @return true if the character at "*ptr" should be included. +/// +/// @param dir the direction of searching, is either FORWARD or BACKWARD +/// @param *colp is in/decremented if "ptr[-dir]" should also be included. +/// @param bnp points to a counter for square brackets. static bool find_is_eval_item(const char_u *const ptr, int *const colp, int *const bnp, const int dir) { @@ -2284,25 +2308,26 @@ static bool find_is_eval_item(const char_u *const ptr, int *const colp, int *con return false; } -// Find the identifier under or to the right of the cursor. -// "find_type" can have one of three values: -// FIND_IDENT: find an identifier (keyword) -// FIND_STRING: find any non-white text -// FIND_IDENT + FIND_STRING: find any non-white text, identifier preferred. -// FIND_EVAL: find text useful for C program debugging -// -// There are three steps: -// 1. Search forward for the start of an identifier/text. Doesn't move if -// already on one. -// 2. Search backward for the start of this identifier/text. -// This doesn't match the real Vi but I like it a little better and it -// shouldn't bother anyone. -// 3. Search forward to the end of this identifier/text. -// When FIND_IDENT isn't defined, we backup until a blank. -// -// Returns the length of the text, or zero if no text is found. -// If text is found, a pointer to the text is put in "*text". This -// points into the current buffer line and is not always NUL terminated. +/// Find the identifier under or to the right of the cursor. +/// "find_type" can have one of three values: +/// FIND_IDENT: find an identifier (keyword) +/// FIND_STRING: find any non-white text +/// FIND_IDENT + FIND_STRING: find any non-white text, identifier preferred. +/// FIND_EVAL: find text useful for C program debugging +/// +/// There are three steps: +/// 1. Search forward for the start of an identifier/text. Doesn't move if +/// already on one. +/// 2. Search backward for the start of this identifier/text. +/// This doesn't match the real Vi but I like it a little better and it +/// shouldn't bother anyone. +/// 3. Search forward to the end of this identifier/text. +/// When FIND_IDENT isn't defined, we backup until a blank. +/// +/// @return the length of the text, or zero if no text is found. +/// +/// If text is found, a pointer to the text is put in "*text". This +/// points into the current buffer line and is not always NUL terminated. size_t find_ident_under_cursor(char_u **text, int find_type) FUNC_ATTR_NONNULL_ARG(1) { @@ -2531,7 +2556,6 @@ static char_u old_showcmd_buf[SHOWCMD_BUFLEN]; // For push_showcmd() static bool showcmd_is_clear = true; static bool showcmd_visual = false; - void clear_showcmd(void) { if (!p_sc) { @@ -3791,7 +3815,6 @@ dozet: } break; - case 'u': // "zug" and "zuw": undo "zg" and "zw" no_mapping++; allow_keys++; // no mapping for nchar, but allow key codes @@ -3878,7 +3901,6 @@ dozet: } } - /// "Q" command. static void nv_regreplay(cmdarg_T *cap) { @@ -3898,7 +3920,6 @@ static void nv_regreplay(cmdarg_T *cap) /// Handle a ":" command and <Cmd> or Lua keymaps. static void nv_colon(cmdarg_T *cap) { - int old_p_im; bool cmd_result; bool is_cmdkey = cap->cmdchar == K_COMMAND; bool is_lua = cap->cmdchar == K_LUA; @@ -3924,8 +3945,6 @@ static void nv_colon(cmdarg_T *cap) compute_cmdrow(); } - old_p_im = p_im; - if (is_lua) { cmd_result = map_execute_lua(); } else { @@ -3934,15 +3953,6 @@ static void nv_colon(cmdarg_T *cap) cap->oap->op_type != OP_NOP ? DOCMD_KEEPLINE : 0); } - // If 'insertmode' changed, enter or exit Insert mode - if (p_im != old_p_im) { - if (p_im) { - restart_edit = 'i'; - } else { - restart_edit = 0; - } - } - if (cmd_result == false) { // The Ex command failed, do not execute the operator. clearop(cap->oap); @@ -4009,8 +4019,8 @@ static void nv_ctrlo(cmdarg_T *cap) } } -// CTRL-^ command, short for ":e #". Works even when the alternate buffer is -// not named. +/// CTRL-^ command, short for ":e #". Works even when the alternate buffer is +/// not named. static void nv_hat(cmdarg_T *cap) { if (!checkclearopq(cap->oap)) { @@ -5435,7 +5445,6 @@ static void n_swapchar(cmdarg_T *cap) } } - check_cursor(); curwin->w_set_curswant = true; if (did_change) { @@ -5792,7 +5801,6 @@ static void n_start_visual_mode(int c) } } - /// CTRL-W: Window commands static void nv_window(cmdarg_T *cap) { @@ -6365,7 +6373,7 @@ static void nv_dot(cmdarg_T *cap) } } -// CTRL-R: undo undo or specify register in select mode +/// CTRL-R: undo undo or specify register in select mode static void nv_redo_or_register(cmdarg_T *cap) { if (VIsual_select && VIsual_active) { @@ -6682,7 +6690,6 @@ static void nv_select(cmdarg_T *cap) } } - /// "G", "gg", CTRL-END, CTRL-HOME. /// cap->arg is true for "G". static void nv_goto(cmdarg_T *cap) @@ -6729,10 +6736,6 @@ static void nv_normal(cmdarg_T *cap) end_visual_mode(); // stop Visual redraw_curbuf_later(INVERTED); } - // CTRL-\ CTRL-G restarts Insert mode when 'insertmode' is set. - if (cap->nchar == Ctrl_G && p_im) { - restart_edit = 'a'; - } } else { clearopbeep(cap->oap); } @@ -6747,8 +6750,7 @@ static void nv_esc(cmdarg_T *cap) no_reason = (cap->oap->op_type == OP_NOP && cap->opcount == 0 && cap->count0 == 0 - && cap->oap->regname == 0 - && !p_im); + && cap->oap->regname == 0); if (cap->arg) { // true for CTRL-C if (restart_edit == 0 @@ -6765,9 +6767,8 @@ static void nv_esc(cmdarg_T *cap) // Don't reset "restart_edit" when 'insertmode' is set, it won't be // set again below when halfway through a mapping. - if (!p_im) { - restart_edit = 0; - } + restart_edit = 0; + if (cmdwin_type != 0) { cmdwin_result = K_IGNORE; got_int = false; // don't stop executing autocommands et al. @@ -6790,16 +6791,9 @@ static void nv_esc(cmdarg_T *cap) vim_beep(BO_ESC); } clearop(cap->oap); - - // A CTRL-C is often used at the start of a menu. When 'insertmode' is - // set return to Insert mode afterwards. - if (restart_edit == 0 && goto_im() - && ex_normal_busy == 0) { - restart_edit = 'a'; - } } -// Move the cursor for the "A" command. +/// Move the cursor for the "A" command. void set_cursor_for_append_to_line(void) { curwin->w_set_curswant = true; @@ -6831,8 +6825,7 @@ static void nv_edit(cmdarg_T *cap) } else if ((cap->cmdchar == 'a' || cap->cmdchar == 'i') && (cap->oap->op_type != OP_NOP || VIsual_active)) { nv_object(cap); - } else if (!curbuf->b_p_ma && !p_im && !curbuf->terminal) { - // Only give this error when 'insertmode' is off. + } else if (!curbuf->b_p_ma && !curbuf->terminal) { emsg(_(e_modifiable)); clearop(cap->oap); } else if (!checkclearopq(cap->oap)) { @@ -7063,8 +7056,9 @@ static void nv_put(cmdarg_T *cap) nv_put_opt(cap, false); } -// "P", "gP", "p" and "gp" commands. -// "fix_indent" is true for "[p", "[P", "]p" and "]P". +/// "P", "gP", "p" and "gp" commands. +/// +/// @param fix_indent true for "[p", "[P", "]p" and "]P". static void nv_put_opt(cmdarg_T *cap, bool fix_indent) { int regname = 0; @@ -7214,7 +7208,7 @@ static void nv_open(cmdarg_T *cap) } } -// Handle an arbitrary event in normal mode +/// Handle an arbitrary event in normal mode static void nv_event(cmdarg_T *cap) { // Garbage collection should have been executed before blocking for events in @@ -7237,7 +7231,7 @@ static void nv_event(cmdarg_T *cap) } } -/// @return true when 'mousemodel' is set to "popup" or "popup_setpos". +/// @return true when 'mousemodel' is set to "popup" or "popup_setpos". static bool mouse_model_popup(void) { return p_mousem[0] == 'p'; diff --git a/src/nvim/normal.h b/src/nvim/normal.h index 0c2b8b4d8a..9bda70eacd 100644 --- a/src/nvim/normal.h +++ b/src/nvim/normal.h @@ -76,7 +76,6 @@ typedef struct cmdarg_S { #define CA_COMMAND_BUSY 1 // skip restarting edit() once #define CA_NO_ADJ_OP_END 2 // don't adjust operator end - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "normal.h.generated.h" #endif diff --git a/src/nvim/ops.c b/src/nvim/ops.c index c3d7742307..6e6f478166 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -453,7 +453,6 @@ static void shift_block(oparg_T *oap, int amount) non_white_col += incr; } - const colnr_T block_space_width = non_white_col - oap->start_vcol; // We will shift by "total" or "block_space_width", whichever is less. const colnr_T shift_amount = block_space_width < total @@ -2105,7 +2104,6 @@ static int op_replace(oparg_T *oap, int c) return OK; } - /* * Handle the (non-standard vi) tilde operator. Also for "gu", "gU" and "g?". */ @@ -2629,7 +2627,6 @@ void clear_registers(void) #endif - /// Free contents of yankreg `reg`. /// Called for normal freeing and in case of error. /// `reg` must not be NULL (but `reg->y_array` might be) @@ -3699,8 +3696,11 @@ error: len = STRLEN(y_array[y_size - 1]); col = (colnr_T)len - lendiff; if (col > 1) { - curbuf->b_op_end.col = col - 1 - utf_head_off(y_array[y_size - 1], - y_array[y_size - 1] + len - 1); + curbuf->b_op_end.col = col - 1; + if (len > 0) { + curbuf->b_op_end.col -= utf_head_off(y_array[y_size - 1], + y_array[y_size - 1] + len - 1); + } } else { curbuf->b_op_end.col = 0; } @@ -3853,7 +3853,6 @@ void ex_display(exarg_T *eap) continue; // did not ask for this register } - if (i == -1) { if (y_previous != NULL) { yb = y_previous; @@ -4911,12 +4910,19 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd) ssize_t change_cnt = 0; linenr_T amount = Prenum1; + // do_addsub() might trigger re-evaluation of 'foldexpr' halfway, when the + // buffer is not completly updated yet. Postpone updating folds until before + // the call to changed_lines(). + disable_fold_update++; + if (!VIsual_active) { pos = curwin->w_cursor; if (u_save_cursor() == FAIL) { + disable_fold_update--; return; } change_cnt = do_addsub(oap->op_type, &pos, 0, amount); + disable_fold_update--; if (change_cnt) { changed_lines(pos.lnum, 0, pos.lnum + 1, 0L, true); } @@ -4927,6 +4933,7 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd) if (u_save((linenr_T)(oap->start.lnum - 1), (linenr_T)(oap->end.lnum + 1)) == FAIL) { + disable_fold_update--; return; } @@ -4973,6 +4980,8 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd) amount += Prenum1; } } + + disable_fold_update--; if (change_cnt) { changed_lines(oap->start.lnum, 0, oap->end.lnum + 1, 0L, true); } @@ -5426,7 +5435,6 @@ void format_reg_type(MotionType reg_type, colnr_T reg_width, char *buf, size_t b } } - /// When `flags` has `kGRegList` return a list with text `s`. /// Otherwise just return `s`. /// @@ -5807,7 +5815,6 @@ void clear_oparg(oparg_T *oap) memset(oap, 0, sizeof(oparg_T)); } - /* * Count the number of bytes, characters and "words" in a line. * @@ -6276,7 +6283,6 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) int restart_edit_save; int lbr_saved = curwin->w_p_lbr; - // The visual area is remembered for redo static int redo_VIsual_mode = NUL; // 'v', 'V', or Ctrl-V static linenr_T redo_VIsual_line_count; // number of lines @@ -6709,7 +6715,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) // remember it to make 'insertmode' work with mappings for // Visual mode. But do this only once and not when typed and // 'insertmode' isn't set. - if (p_im || !KeyTyped) { + if (!KeyTyped) { restart_edit_save = restart_edit; } else { restart_edit_save = 0; @@ -7266,7 +7272,6 @@ void restore_batch_count(int save_count) } } - /// Check whether register is empty static inline bool reg_empty(const yankreg_T *const reg) FUNC_ATTR_PURE diff --git a/src/nvim/option.c b/src/nvim/option.c index 8267bcf9da..5565e6f167 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -101,7 +101,6 @@ #define OPT_BUF(x) (idopt_T)(PV_BUF + (int)(x)) #define OPT_BOTH(x) (idopt_T)(PV_BOTH + (int)(x)) - // WV_ and BV_ values get typecasted to this for the "indir" field typedef enum { PV_NONE = 0, @@ -211,7 +210,6 @@ typedef struct vimoption { LastSet last_set; // script in which the option was last set } vimoption_T; - /* * Flags */ @@ -519,7 +517,6 @@ void set_init_1(bool clean_arg) */ set_options_default(0); - curbuf->b_p_initialized = true; curbuf->b_p_ar = -1; // no local 'autoread' value curbuf->b_p_ul = NO_LOCAL_UNDOLEVEL; @@ -778,7 +775,6 @@ void free_all_options(void) } #endif - /// Initialize the options, part two: After getting Rows and Columns. void set_init_2(bool headless) { @@ -909,7 +905,6 @@ void set_helplang_default(const char *lang) } } - /// 'title' and 'icon' only default to true if they have not been set or reset /// in .vimrc and we can read the old value. /// When 'title' and 'icon' have been reset in .vimrc, we won't even check if @@ -2149,6 +2144,8 @@ static uint32_t *insecure_flag(win_T *const wp, int opt_idx, int opt_flags) switch ((int)options[opt_idx].indir) { case PV_STL: return &wp->w_p_stl_flags; + case PV_WBR: + return &wp->w_p_wbr_flags; case PV_FDE: return &wp->w_p_fde_flags; case PV_FDT: @@ -2166,7 +2163,6 @@ static uint32_t *insecure_flag(win_T *const wp, int opt_idx, int opt_flags) return &options[opt_idx].flags; } - /// Redraw the window title and/or tab page text later. static void redraw_titles(void) { @@ -2930,8 +2926,8 @@ ambw_end: curbuf->b_help = (curbuf->b_p_bt[0] == 'h'); redraw_titles(); } - } else if (gvarp == &p_stl || varp == &p_tal || varp == &p_ruf) { - // 'statusline', 'tabline' or 'rulerformat' + } else if (gvarp == &p_stl || gvarp == (char_u **)&p_wbr || varp == &p_tal || varp == &p_ruf) { + // 'statusline', 'winbar', 'tabline' or 'rulerformat' int wid; if (varp == &p_ruf) { // reset ru_wid first @@ -2950,12 +2946,16 @@ ambw_end: errmsg = check_stl_option(p_ruf); } } else if (varp == &p_ruf || s[0] != '%' || s[1] != '!') { - // check 'statusline' or 'tabline' only if it doesn't start with "%!" + // check 'statusline', 'winbar' or 'tabline' only if it doesn't start with "%!" errmsg = check_stl_option(s); } if (varp == &p_ruf && errmsg == NULL) { comp_col(); } + // add / remove window bars for 'winbar' + if (gvarp == (char_u **)&p_wbr) { + set_winbar(); + } } else if (gvarp == &p_cpt) { // check if it is a valid value for 'complete' -- Acevedo for (s = *varp; *s;) { @@ -3570,6 +3570,7 @@ static char *set_chars_option(win_T *wp, char_u **varp, bool set) struct chars_tab fcs_tab[] = { { &wp->w_p_fcs_chars.stl, "stl", ' ' }, { &wp->w_p_fcs_chars.stlnc, "stlnc", ' ' }, + { &wp->w_p_fcs_chars.wbr, "wbr", ' ' }, { &wp->w_p_fcs_chars.horiz, "horiz", 9472 }, // ─ { &wp->w_p_fcs_chars.horizup, "horizup", 9524 }, // ┴ { &wp->w_p_fcs_chars.horizdown, "horizdown", 9516 }, // ┬ @@ -3612,15 +3613,15 @@ static char *set_chars_option(win_T *wp, char_u **varp, bool set) if (*p_ambw == 'd') { // XXX: If ambiwidth=double then some characters take 2 columns, // which is forbidden (TUI limitation?). Set old defaults. - fcs_tab[2].def = '-'; fcs_tab[3].def = '-'; fcs_tab[4].def = '-'; - fcs_tab[5].def = '|'; + fcs_tab[5].def = '-'; fcs_tab[6].def = '|'; fcs_tab[7].def = '|'; - fcs_tab[8].def = '+'; - fcs_tab[9].def = '-'; - fcs_tab[12].def = '|'; + fcs_tab[8].def = '|'; + fcs_tab[9].def = '+'; + fcs_tab[10].def = '-'; + fcs_tab[13].def = '|'; } } @@ -3960,7 +3961,6 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, const int va // Remember where the option was set. set_option_sctx_idx(opt_idx, opt_flags, current_sctx); - // May set global value for local option. if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) { *(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = value; @@ -4042,36 +4042,9 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, const int va // buf->b_p_swf mf_close_file(curbuf, true); // remove the swap file } - } else if ((int *)varp == &p_terse) { - // when 'terse' is set change 'shortmess' - char *p = vim_strchr((char *)p_shm, SHM_SEARCH); - - // insert 's' in p_shm - if (p_terse && p == NULL) { - STRCPY(IObuff, p_shm); - STRCAT(IObuff, "s"); - set_string_option_direct("shm", -1, IObuff, OPT_FREE, 0); - } else if (!p_terse && p != NULL) { // remove 's' from p_shm - STRMOVE(p, p + 1); - } } else if ((int *)varp == &p_paste) { // when 'paste' is set or reset also change other options paste_option_changed(); - } else if ((int *)varp == &p_im) { - // when 'insertmode' is set from an autocommand need to do work here - if (p_im) { - if ((State & MODE_INSERT) == 0) { - need_start_insertmode = true; - } - stop_insert_mode = false; - } else if (old_value) { // only reset if it was set previously - need_start_insertmode = false; - stop_insert_mode = true; - if (restart_edit != 0 && mode_displayed) { - clear_cmdline = true; // remove "(insert)" - } - restart_edit = 0; - } } else if ((int *)varp == &p_ic && p_hls) { // when 'ignorecase' is set or reset and 'hlsearch' is set, redraw redraw_all_later(SOME_VALID); @@ -4215,7 +4188,6 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, const int va } } - /* * End of handling side effects for bool options. */ @@ -4585,7 +4557,6 @@ static char *set_num_option(int opt_idx, char_u *varp, long value, char *errbuf, check_blending(curwin); } - // Check the (new) bounds for Rows and Columns here. if (p_lines < min_rows() && full_screen) { if (errbuf != NULL) { @@ -4766,7 +4737,7 @@ static void check_redraw(uint32_t flags) bool doclear = (flags & P_RCLR) == P_RCLR; bool all = ((flags & P_RALL) == P_RALL || doclear); - if ((flags & P_RSTAT) || all) { // mark all status lines dirty + if ((flags & P_RSTAT) || all) { // mark all status lines and window bars dirty status_redraw_all(); } @@ -5814,6 +5785,9 @@ void unset_global_local_option(char *name, void *from) case PV_STL: clear_string_option(&((win_T *)from)->w_p_stl); break; + case PV_WBR: + clear_string_option((char_u **)&((win_T *)from)->w_p_wbr); + break; case PV_UL: buf->b_p_ul = NO_LOCAL_UNDOLEVEL; break; @@ -5891,6 +5865,8 @@ static char_u *get_varp_scope(vimoption_T *p, int opt_flags) return (char_u *)&(curwin->w_p_sbr); case PV_STL: return (char_u *)&(curwin->w_p_stl); + case PV_WBR: + return (char_u *)&(curwin->w_p_wbr); case PV_UL: return (char_u *)&(curbuf->b_p_ul); case PV_LW: @@ -5984,6 +5960,9 @@ static char_u *get_varp(vimoption_T *p) case PV_STL: return *curwin->w_p_stl != NUL ? (char_u *)&(curwin->w_p_stl) : p->var; + case PV_WBR: + return *curwin->w_p_wbr != NUL + ? (char_u *)&(curwin->w_p_wbr) : p->var; case PV_UL: return curbuf->b_p_ul != NO_LOCAL_UNDOLEVEL ? (char_u *)&(curbuf->b_p_ul) : p->var; @@ -6252,6 +6231,7 @@ void copy_winopt(winopt_T *from, winopt_T *to) to->wo_rlc = vim_strsave(from->wo_rlc); to->wo_sbr = vim_strsave(from->wo_sbr); to->wo_stl = vim_strsave(from->wo_stl); + to->wo_wbr = xstrdup(from->wo_wbr); to->wo_wrap = from->wo_wrap; to->wo_wrap_save = from->wo_wrap_save; to->wo_lbr = from->wo_lbr; @@ -6327,6 +6307,7 @@ static void check_winopt(winopt_T *wop) check_string_option(&wop->wo_fcs); check_string_option(&wop->wo_lcs); check_string_option(&wop->wo_ve); + check_string_option((char_u **)&wop->wo_wbr); } /// Free the allocated memory inside a winopt_T. @@ -6352,6 +6333,7 @@ void clear_winopt(winopt_T *wop) clear_string_option(&wop->wo_fcs); clear_string_option(&wop->wo_lcs); clear_string_option(&wop->wo_ve); + clear_string_option((char_u **)&wop->wo_wbr); } void didset_window_options(win_T *wp) @@ -6538,6 +6520,7 @@ void buf_copy_options(buf_T *buf, int flags) COPY_OPT_SCTX(buf, BV_SI); buf->b_p_channel = 0; buf->b_p_ci = p_ci; + COPY_OPT_SCTX(buf, BV_CI); buf->b_p_cin = p_cin; COPY_OPT_SCTX(buf, BV_CIN); @@ -6547,6 +6530,7 @@ void buf_copy_options(buf_T *buf, int flags) COPY_OPT_SCTX(buf, BV_CINO); buf->b_p_cinsd = vim_strsave(p_cinsd); COPY_OPT_SCTX(buf, BV_CINSD); + // Don't copy 'filetype', it must be detected buf->b_p_ft = empty_option; buf->b_p_pi = p_pi; diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index e358a29622..9268b1eff6 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -49,7 +49,6 @@ # define DFLT_FFS_VI "" #endif - // Possible values for 'encoding' #define ENC_UCSBOM "ucs-bom" // check for BOM at start of file @@ -334,9 +333,9 @@ EXTERN unsigned bo_flags; #ifdef IN_OPTION_C static char *(p_bo_values[]) = { "all", "backspace", "cursor", "complete", "copy", "ctrlg", "error", "esc", "ex", - "hangul", "insertmode", "lang", "mess", - "showmatch", "operator", "register", "shell", - "spell", "wildmode", NULL }; + "hangul", "lang", "mess", "showmatch", + "operator", "register", "shell", "spell", + "wildmode", NULL }; #endif // values for the 'belloff' option @@ -485,7 +484,6 @@ EXTERN char_u *p_iconstring; // 'iconstring' EXTERN int p_ic; // 'ignorecase' EXTERN int p_is; // 'incsearch' EXTERN char_u *p_icm; // 'inccommand' -EXTERN int p_im; // 'insertmode' EXTERN char_u *p_isf; // 'isfname' EXTERN char_u *p_isi; // 'isident' EXTERN char_u *p_isp; // 'isprint' @@ -557,7 +555,6 @@ static char *(p_rdb_values[]) = { #define RDB_NODELTA 0x008 EXTERN long p_rdt; // 'redrawtime' -EXTERN int p_remap; // 'remap' EXTERN long p_re; // 'regexpengine' EXTERN long p_report; // 'report' EXTERN long p_pvh; // 'previewheight' @@ -618,6 +615,7 @@ EXTERN int p_stmp; // 'shelltemp' EXTERN int p_ssl; // 'shellslash' #endif EXTERN char_u *p_stl; // 'statusline' +EXTERN char *p_wbr; // 'winbar' EXTERN int p_sr; // 'shiftround' EXTERN char_u *p_shm; // 'shortmess' EXTERN char_u *p_sbr; // 'showbreak' @@ -678,7 +676,6 @@ EXTERN int p_tr; ///< 'tagrelative' EXTERN char_u *p_tags; ///< 'tags' EXTERN int p_tgst; ///< 'tagstack' EXTERN int p_tbidi; ///< 'termbidi' -EXTERN int p_terse; ///< 'terse' EXTERN int p_to; ///< 'tildeop' EXTERN int p_timeout; ///< 'timeout' EXTERN long p_tm; ///< 'timeoutlen' @@ -897,6 +894,7 @@ enum { WV_FCS, WV_LCS, WV_WINBL, + WV_WBR, WV_COUNT, // must be the last one }; diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 313cace4b2..a0fbf8d9f0 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -1250,9 +1250,9 @@ return { }, { full_name='insertmode', abbreviation='im', - short_desc=N_("start the edit of a file in Insert mode"), + short_desc=N_("No description"), type='bool', scope={'global'}, - varname='p_im', + varname='p_force_off', defaults={if_true=false} }, { @@ -1911,9 +1911,9 @@ return { }, { full_name='remap', - short_desc=N_("mappings to work recursively"), + short_desc=N_("No description"), type='bool', scope={'global'}, - varname='p_remap', + varname='p_force_on', defaults={if_true=true} }, { @@ -2529,9 +2529,9 @@ return { }, { full_name='terse', - short_desc=N_("hides notification of search wrap"), + short_desc=N_("No description"), type='bool', scope={'global'}, - varname='p_terse', + varname='p_force_off', defaults={if_true=false} }, { @@ -2832,6 +2832,16 @@ return { defaults={if_true="menu"} }, { + full_name='winbar', abbreviation='wbr', + short_desc=N_("custom format for the window bar"), + type='string', scope={'global', 'window'}, + alloced=true, + modelineexpr=true, + redraw={'statuslines'}, + varname='p_wbr', + defaults={if_true=""} + }, + { full_name='winblend', abbreviation='winbl', short_desc=N_("Controls transparency level for floating windows"), type='number', scope={'window'}, diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index c03fd60f03..4bc003bc7f 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -878,7 +878,6 @@ const void *vim_env_iter_rev(const char delim, const char *const val, const void } } - /// @param[out] exe_name should be at least MAXPATHL in size void vim_get_prefix_from_exepath(char *exe_name) { @@ -1155,7 +1154,6 @@ char_u *home_replace_save(buf_T *buf, char_u *src) FUNC_ATTR_NONNULL_RET return dst; } - /// Function given to ExpandGeneric() to obtain an environment variable name. char *get_env_name(expand_T *xp, int idx) { diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 5fcae79a67..68da53c476 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -56,7 +56,6 @@ static const int kLibuvSuccess = 0; static uv_loop_t fs_loop; static uv_mutex_t fs_loop_mutex; - // Initialize the fs module void fs_init(void) { @@ -77,7 +76,6 @@ void fs_loop_unlock(void) uv_mutex_unlock(&fs_loop_mutex); } - /// Changes the current directory to `path`. /// /// @return 0 on success, or negative error code. diff --git a/src/nvim/os/fs.h b/src/nvim/os/fs.h new file mode 100644 index 0000000000..c68081da02 --- /dev/null +++ b/src/nvim/os/fs.h @@ -0,0 +1,10 @@ +#ifndef NVIM_OS_FS_H +#define NVIM_OS_FS_H + +#include "nvim/os/fs_defs.h" // for uv_* +#include "nvim/types.h" // for char_u + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "os/fs.h.generated.h" +#endif +#endif // NVIM_OS_FS_H diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index c99d2869da..c47a891c18 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -19,6 +19,7 @@ #include "nvim/memory.h" #include "nvim/msgpack_rpc/channel.h" #include "nvim/os/input.h" +#include "nvim/screen.h" #include "nvim/state.h" #include "nvim/ui.h" #include "nvim/vim.h" @@ -178,15 +179,7 @@ void os_breakcheck(void) return; } - int save_us = updating_screen; - // We do not want screen_resize() to redraw here. - // TODO(bfredl): we are already special casing redraw events, is this - // hack still needed? - updating_screen++; - loop_poll_events(&main_loop, 0); - - updating_screen = save_us; } #define BREAKCHECK_SKIP 1000 @@ -223,7 +216,6 @@ void veryfast_breakcheck(void) } } - /// Test whether a file descriptor refers to a terminal. /// /// @param fd File descriptor. @@ -337,7 +329,6 @@ static uint8_t check_multiclick(int code, int grid, int row, int col) return modifiers; } - // Mouse event handling code(Extract row/col if available and detect multiple // clicks) static unsigned int handle_mouse_event(char **ptr, uint8_t *buf, unsigned int bufsize) diff --git a/src/nvim/os/os_win_console.c b/src/nvim/os/os_win_console.c index 18e2e02b81..20b7f869f1 100644 --- a/src/nvim/os/os_win_console.c +++ b/src/nvim/os/os_win_console.c @@ -9,7 +9,6 @@ # include "os/os_win_console.c.generated.h" #endif - int os_get_conin_fd(void) { const HANDLE conin_handle = CreateFile("CONIN$", diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c index d9f4fe9e37..396bf6986a 100644 --- a/src/nvim/os/time.c +++ b/src/nvim/os/time.c @@ -15,7 +15,6 @@ static uv_mutex_t delay_mutex; static uv_cond_t delay_cond; - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os/time.c.generated.h" #endif diff --git a/src/nvim/os/users.c b/src/nvim/os/users.c index 4803be20c3..9fe97dd5e4 100644 --- a/src/nvim/os/users.c +++ b/src/nvim/os/users.c @@ -30,7 +30,7 @@ static void add_user(garray_T *users, char *user, bool need_copy) if (user_copy == NULL || *user_copy == NUL) { if (need_copy) { - xfree(user); + xfree(user_copy); } return; } @@ -160,7 +160,6 @@ char *os_get_user_directory(const char *name) return NULL; } - #if defined(EXITFREE) void free_users(void) diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c index 1398dba0e4..473bf5072c 100644 --- a/src/nvim/os_unix.c +++ b/src/nvim/os_unix.c @@ -48,7 +48,6 @@ # include <sys/access.h> # endif - // Return a pointer to the ACL of file "fname" in allocated memory. // Return NULL if the ACL is not available for whatever reason. vim_acl_T mch_get_acl(const char_u *fname) diff --git a/src/nvim/path.c b/src/nvim/path.c index fcb91a2783..7f47ce083d 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -1107,7 +1107,6 @@ const char *gettail_dir(const char *const fname) return dir_end; } - /// Calls globpath() with 'path' values for the given pattern and stores the /// result in "gap". /// Returns the total number of matches. @@ -1143,7 +1142,6 @@ static int expand_in_path(garray_T *const gap, char_u *const pattern, const int return gap->ga_len; } - /* * Return TRUE if "p" contains what looks like an environment variable. * Allowing for escaping. diff --git a/src/nvim/plines.c b/src/nvim/plines.c index f940598bf8..35f2512ee3 100644 --- a/src/nvim/plines.c +++ b/src/nvim/plines.c @@ -45,7 +45,6 @@ int plines_win(win_T *wp, linenr_T lnum, bool winheight) return plines_win_nofill(wp, lnum, winheight) + win_get_fill(wp, lnum); } - /// Return the number of filler lines above "lnum". /// /// @param wp diff --git a/src/nvim/po/check.vim b/src/nvim/po/check.vim index aca878f9d5..7705ba8577 100644 --- a/src/nvim/po/check.vim +++ b/src/nvim/po/check.vim @@ -41,7 +41,7 @@ set nowrapscan " Start at the first "msgid" line. let wsv = winsaveview() 1 -/^msgid\> +keeppatterns /^msgid\> " When an error is detected this is set to the line number. " Note: this is used in the Makefile. @@ -104,7 +104,7 @@ while 1 " Find next msgid. Quit when there is no more. let lnum = line('.') - silent! /^msgid\> + silent! keeppatterns /^msgid\> if line('.') == lnum break endif @@ -137,7 +137,7 @@ endfunc " Check that the \n at the end of the msgid line is also present in the msgstr " line. Skip over the header. 1 -/^"MIME-Version: +keeppatterns /^"MIME-Version: while 1 let lnum = search('^msgid\>') if lnum <= 0 diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index c5c1d87919..a77463c9ca 100644 --- a/src/nvim/popupmnu.c +++ b/src/nvim/popupmnu.c @@ -429,9 +429,9 @@ void pum_redraw(void) must_redraw_pum = false; if (!pum_grid.chars - || pum_grid.Rows != pum_height || pum_grid.Columns != grid_width) { + || pum_grid.rows != pum_height || pum_grid.cols != grid_width) { grid_alloc(&pum_grid, pum_height, grid_width, !invalid_grid, false); - ui_call_grid_resize(pum_grid.handle, pum_grid.Columns, pum_grid.Rows); + ui_call_grid_resize(pum_grid.handle, pum_grid.cols, pum_grid.rows); } else if (invalid_grid) { grid_invalidate(&pum_grid); } @@ -443,7 +443,6 @@ void pum_redraw(void) false, pum_grid.zindex); } - // Never display more than we have if (pum_first > pum_size - pum_height) { pum_first = pum_size - pum_height; diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 883de85aee..f8d0d117e2 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -44,7 +44,6 @@ #include "nvim/vim.h" #include "nvim/window.h" - struct dir_stack_T { struct dir_stack_T *next; char *dirname; @@ -251,7 +250,6 @@ static char *e_no_more_items = N_("E553: No more items"); !got_int && (i) <= (qfl)->qf_count && (qfp) != NULL; \ (i)++, (qfp) = (qfp)->qf_next) - // Looking up a buffer can be slow if there are many. Remember the last one // to make this a lot faster if there are multiple matches in the same file. static char *qf_last_bufname = NULL; @@ -466,7 +464,6 @@ static const char *efm_analyze_prefix(const char *efmp, efm_T *efminfo) return efmp; } - // Converts a 'errorformat' string to regular expression pattern static int efm_to_regpat(const char *efm, int len, efm_T *fmt_ptr, char *regpat) FUNC_ATTR_NONNULL_ALL @@ -1107,7 +1104,6 @@ static int qf_init_ext(qf_info_T *qi, int qf_idx, const char *restrict efile, bu } } - // Use the local value of 'errorformat' if it's set. if (errorformat == p_efm && tv == NULL && buf && *buf->b_p_efm != NUL) { efm = (char *)buf->b_p_efm; @@ -2213,7 +2209,6 @@ static char *qf_push_dir(char *dirbuf, struct dir_stack_T **stackptr, bool is_fi } } - // pop dirbuf from the directory stack and return previous directory or NULL if // stack is empty static char *qf_pop_dir(struct dir_stack_T **stackptr) @@ -2540,9 +2535,7 @@ static int jump_to_help_window(qf_info_T *qi, bool newwin, int *opened_window) } } - if (!p_im) { - restart_edit = 0; // don't want insert mode in help file - } + restart_edit = 0; // don't want insert mode in help file return OK; } @@ -3081,7 +3074,6 @@ theend: decr_quickfix_busy(); } - // Highlight attributes used for displaying entries from the quickfix list. static int qfFileAttr; static int qfSepAttr; @@ -3286,7 +3278,6 @@ static void qf_range_text(const qfline_T *qfp, char *buf, int bufsize) buf[len] = NUL; } - /// Display information (list number, list size and the title) about a /// quickfix/location list. static void qf_msg(qf_info_T *qi, int which, char *lead) @@ -5071,7 +5062,6 @@ void ex_cbelow(exarg_T *eap) } } - /// Return the autocmd name for the :cfile Ex commands static char *cfile_get_auname(cmdidx_T cmdidx) { @@ -5093,7 +5083,6 @@ static char *cfile_get_auname(cmdidx_T cmdidx) } } - // ":cfile"/":cgetfile"/":caddfile" commands. // ":lfile"/":lgetfile"/":laddfile" commands. void ex_cfile(exarg_T *eap) @@ -5203,7 +5192,6 @@ static void vgr_init_regmatch(regmmatch_T *regmatch, char *s) regmatch->rmm_maxcol = 0; } - /// Display a file name when vimgrep is running. static void vgr_display_fname(char *fname) { @@ -5266,7 +5254,6 @@ static bool vgr_qflist_valid(win_T *wp, qf_info_T *qi, unsigned qfid, char *titl return true; } - /// Search for a pattern in all the lines in a buffer and add the matching lines /// to a quickfix list. static bool vgr_match_buflines(qf_list_T *qfl, char *fname, buf_T *buf, char *spat, diff --git a/src/nvim/rbuffer.h b/src/nvim/rbuffer.h index 09d6ba3d34..3ebbc9d82c 100644 --- a/src/nvim/rbuffer.h +++ b/src/nvim/rbuffer.h @@ -50,7 +50,6 @@ rbuffer_space(buf); \ wptr = rbuffer_write_ptr(buf, &wcnt)) - // Iteration #define RBUFFER_EACH(buf, c, i) \ for (size_t i = 0; /* NOLINT(readability/braces) */ \ diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index f0ccd19478..6b8c75e430 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -157,7 +157,6 @@ static char_u *reg_prev_sub = NULL; static char REGEXP_INRANGE[] = "]^-n\\"; static char REGEXP_ABBR[] = "nrtebdoxuU"; - /* * Translate '\x' to its control character, except "\n", which is Magic. */ @@ -376,7 +375,6 @@ typedef struct { int regnpar; } parse_state_T; - static regengine_T bt_regengine; static regengine_T nfa_regengine; @@ -384,7 +382,6 @@ static regengine_T nfa_regengine; # include "regexp.c.generated.h" #endif - // Return true if compiled regular expression "prog" can match a line break. int re_multiline(const regprog_T *prog) FUNC_ATTR_NONNULL_ALL @@ -414,7 +411,6 @@ static int get_equi_class(char_u **pp) return 0; } - /* * Check for a collating element "[.a.]". "pp" points to the '['. * Returns a character. Zero means that no item was recognized. Otherwise @@ -540,7 +536,6 @@ char_u *skip_regexp(char_u *startp, int dirc, int magic, char_u **newp) return p; } - // variables used for parsing static int prevchr_len; // byte length of previous char static int at_start; // True when on the first character @@ -591,7 +586,6 @@ static void restore_parse_state(parse_state_T *ps) regnpar = ps->regnpar; } - /* * Get the next character without advancing. */ @@ -898,7 +892,6 @@ static int64_t getoctchrs(void) return nr; } - /* * read_limits - Read two integers to be taken as a minimum and maximum. * If the first character is '-', then the range is reversed. @@ -1000,7 +993,6 @@ typedef struct { int need_clear_zsubexpr; ///< extmatch subexpressions still need to be ///< cleared - // Internal copy of 'ignorecase'. It is set at each call to vim_regexec(). // Normally it gets the value of "rm_ic" or "rmm_ic", but when the pattern // contains '\c' or '\C' the value is overruled. @@ -1112,7 +1104,6 @@ static int reg_prev_class(void) return -1; } - // Return true if the current rex.input position matches the Visual area. static bool reg_match_visual(void) { @@ -1245,7 +1236,6 @@ static void cleanup_zsubexpr(void) } } - // Advance rex.lnum, rex.line and rex.input to the next line. static void reg_nextline(void) { @@ -1254,7 +1244,6 @@ static void reg_nextline(void) fast_breakcheck(); } - /* * Check whether a backreference matches. * Returns RA_FAIL, RA_NOMATCH or RA_MATCH. @@ -1511,7 +1500,6 @@ static inline char_u *cstrchr(const char_u *const s, const int c) // This stuff below really confuses cc on an SGI -- webb - static fptr_T do_upper(int *d, int c) { *d = mb_toupper(c); @@ -2081,7 +2069,6 @@ exit: return (int)((dst - dest) + 1 - num_escaped); } - /* * Call reg_getline() with the line numbers from the submatch. If a * substitute() was used the reg_maxline and other values have been @@ -2378,7 +2365,6 @@ void vim_regfree(regprog_T *prog) } } - #if defined(EXITFREE) void free_regexp_stuff(void) { diff --git a/src/nvim/regexp_bt.c b/src/nvim/regexp_bt.c index c13c2c6832..03e4d74f14 100644 --- a/src/nvim/regexp_bt.c +++ b/src/nvim/regexp_bt.c @@ -43,7 +43,6 @@ * Named character class support added by Walter Briscoe (1998 Jul 01) */ - /* * The "internal use only" fields in regexp_defs.h are present to pass info from * compile to execute that permits the execute phase to run lots faster on @@ -173,7 +172,6 @@ #define NEWL 18 // Match line-break #define BHPOS 19 // End position for BEHIND or NOBEHIND - // character classes: 20-48 normal, 50-78 include a line-break #define ADD_NL 30 #define FIRST_NL ANY + ADD_NL @@ -252,7 +250,6 @@ #define HASLOOKBH 0x10 // Contains "\@<=" or "\@<!". #define WORST 0 // Worst case. - static int prevchr_len; ///< byte length of previous char static int num_complex_braces; ///< Complex \{...} count static char_u *regcode; ///< Code-emit pointer, or JUST_CALC_SIZE @@ -346,7 +343,6 @@ typedef struct regitem_S { } rs_un; // room for saving rex.input } regitem_T; - // used for STAR, PLUS and BRACE_SIMPLE matching typedef struct regstar_S { int nextb; // next byte @@ -443,7 +439,6 @@ static char_u *reg(int paren, int *flagp); static void regdump(char_u *, bt_regprog_T *); #endif - #ifdef REGEXP_DEBUG static char_u *regprop(char_u *); @@ -454,7 +449,6 @@ static int regnarrate = 0; # include "regexp_bt.c.generated.h" #endif - /* * Setup to parse the regexp. Used once to get the length and once to do it. */ @@ -490,7 +484,6 @@ static bool use_multibytecode(int c) || utf_iscomposing(c)); } - /* * Emit (if appropriate) a byte of code */ @@ -515,7 +508,6 @@ static void regmbc(int c) } } - /* * Produce the bytes for equivalence class "c". * Currently only handles latin1, latin9 and utf-8. @@ -1489,7 +1481,6 @@ static void reg_equi_class(int c) regmbc(c); } - /* * Emit a node. * Return pointer to generated code. @@ -1596,7 +1587,6 @@ static void regoptail(char_u *p, char_u *val) regtail(OPERAND(p), val); } - /* * Insert an operator in front of already-emitted operand * @@ -2877,7 +2867,6 @@ static char_u *reg(int paren, int *flagp) return ret; } - /* * bt_regcomp() - compile a regular expression into internal code for the * traditional back track matcher. @@ -5223,7 +5212,6 @@ static int bt_regexec_nl(regmatch_T *rmp, char_u *line, colnr_T col, bool line_l return (int)r; } - /// Matches a regexp against multiple lines. /// "rmp->regprog" is a compiled regexp as returned by vim_regcomp(). /// Uses curbuf for line count and 'iskeyword'. diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index cad5e9df29..d867b5db95 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -2747,7 +2747,6 @@ static int nfa_regpiece(void) break; - default: break; } // end switch @@ -3485,7 +3484,6 @@ static nfa_state_T *alloc_state(int c, nfa_state_T *out, nfa_state_T *out1) * next state for this fragment. */ - /* * Initialize a Frag_T struct and return it. */ @@ -3523,7 +3521,6 @@ static void patch(Ptrlist *l, nfa_state_T *s) } } - /* * Join the two lists l1 and l2, returning the combination. */ @@ -4403,7 +4400,6 @@ static void nfa_postprocess(nfa_regprog_T *prog) #define NFA_PIM_MATCH 2 // pim executed, matches #define NFA_PIM_NOMATCH 3 // pim executed, no match - #ifdef REGEXP_DEBUG static void log_subsexpr(regsubs_T *subs) { @@ -4790,7 +4786,6 @@ static bool match_follows(const nfa_state_T *startstate, int depth) return false; } - /// @param l runtime state list /// @param state state to update /// @param subs pointers to subexpressions @@ -5460,7 +5455,6 @@ retempty: return false; } - /// Check for a match with \z subexpression "subidx". /// /// @param bytelen out: length of match in bytes @@ -5530,7 +5524,6 @@ static bool nfa_re_num_cmp(uintmax_t val, int op, uintmax_t pos) return val == pos; } - /* * Recursively call nfa_regmatch() * "pim" is NULL or contains info about a Postponed Invisible Match (start @@ -5684,7 +5677,6 @@ static int recursive_regmatch(nfa_state_T *state, nfa_pim_T *pim, nfa_regprog_T return result; } - /* * Estimate the chance of a match with "state" failing. * empty match: 0 @@ -6035,7 +6027,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm #define ADD_STATE_IF_MATCH(state) \ if (result) { \ - add_state = state->out; \ + add_state = (state)->out; \ add_off = clen; \ } diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 8f81b79aff..9f6d129392 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -57,7 +57,6 @@ void ex_runtime(exarg_T *eap) source_runtime(arg, flags); } - static void source_callback(char *fname, void *cookie) { (void)do_source(fname, false, DOSO_NONE); @@ -160,7 +159,6 @@ int do_in_path(char_u *path, char *name, int flags, DoInRuntimepathCB callback, } } - return did_one ? OK : FAIL; } @@ -202,7 +200,6 @@ void runtime_search_path_unref(RuntimeSearchPath path, int *ref) } } - /// Find the file "name" in all directories in "path" and invoke /// "callback(fname, cookie)". /// "name" can contain wildcards. @@ -524,7 +521,6 @@ RuntimeSearchPath runtime_search_path_build(void) map_put(String, handle_T)(&pack_used, the_entry, 0); } - char *rtp_entry; for (rtp_entry = (char *)p_rtp; *rtp_entry != NUL;) { char *cur_entry = rtp_entry; @@ -612,7 +608,6 @@ void runtime_search_path_validate(void) } } - /// Just like do_in_path_and_pp(), using 'runtimepath' for "path". int do_in_runtimepath(char *name, int flags, DoInRuntimepathCB callback, void *cookie) { @@ -884,7 +879,6 @@ static void add_opt_pack_plugin(char *fname, void *cookie) add_pack_plugin(true, (char_u *)fname, cookie); } - /// Add all packages in the "start" directory to 'runtimepath'. void add_pack_start_dirs(void) { @@ -918,7 +912,6 @@ static void add_pack_start_dir(char *fname, void *cookie) } } - /// Load plugins from all packages in the "start" directory. void load_start_packages(void) { @@ -1049,7 +1042,6 @@ static inline size_t compute_double_env_sep_len(const char *const val, const siz return ret; } - #define NVIM_SIZE (sizeof("nvim") - 1) /// Add directories to a ENV_SEPCHAR-separated array from a colon-separated one /// diff --git a/src/nvim/runtime.h b/src/nvim/runtime.h index 0550a082e9..d83ec00185 100644 --- a/src/nvim/runtime.h +++ b/src/nvim/runtime.h @@ -32,7 +32,6 @@ typedef kvec_t(char *) CharVec; #define DIP_LUA 0x100 // also use ".lua" files #define DIP_DIRFILE 0x200 // find both files and directories - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "runtime.h.generated.h" #endif diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 686516f17b..b0edad7740 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -88,6 +88,7 @@ #include "nvim/fold.h" #include "nvim/garray.h" #include "nvim/getchar.h" +#include "nvim/grid_defs.h" #include "nvim/highlight.h" #include "nvim/highlight_group.h" #include "nvim/indent.h" @@ -132,10 +133,6 @@ static match_T search_hl; // used for 'hlsearch' highlight matching -StlClickDefinition *tab_page_click_defs = NULL; - -long tab_page_click_defs_size = 0; - // for line_putchar. Contains the state that needs to be remembered from // putting one character to the next. typedef struct { @@ -163,7 +160,6 @@ typedef struct { } WinExtmark; static kvec_t(WinExtmark) win_extmark_arr INIT(= KV_INITIAL_VALUE); - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "screen.c.generated.h" #endif @@ -276,21 +272,12 @@ void redrawWinline(win_T *wp, linenr_T lnum) } } -/* - * update all windows that are editing the current buffer - */ -void update_curbuf(int type) -{ - redraw_curbuf_later(type); - update_screen(type); -} - /// called when the status bars for the buffer 'buf' need to be updated void redraw_buf_status_later(buf_T *buf) { FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - if (wp->w_buffer == buf - && (wp->w_status_height || (wp == curwin && global_stl_height()))) { + if (wp->w_buffer == buf && (wp->w_status_height || (wp == curwin && global_stl_height()) + || wp->w_winbar_height)) { wp->w_redr_status = true; if (must_redraw < VALID) { must_redraw = VALID; @@ -382,9 +369,9 @@ int update_screen(int type) int valid = MAX(Rows - msg_scrollsize(), 0); if (msg_grid.chars) { // non-displayed part of msg_grid is considered invalid. - for (int i = 0; i < MIN(msg_scrollsize(), msg_grid.Rows); i++) { + for (int i = 0; i < MIN(msg_scrollsize(), msg_grid.rows); i++) { grid_clear_line(&msg_grid, msg_grid.line_offset[i], - msg_grid.Columns, false); + msg_grid.cols, false); } } if (msg_use_msgsep()) { @@ -431,7 +418,7 @@ int update_screen(int type) wp->w_redr_type = REDRAW_TOP; } else { wp->w_redr_type = NOT_VALID; - if (!is_stl_global && W_ENDROW(wp) + wp->w_status_height <= msg_scrolled) { + if (wp->w_winrow + wp->w_winbar_height <= msg_scrolled) { wp->w_redr_status = true; } } @@ -563,7 +550,6 @@ int update_screen(int type) bool did_one = false; search_hl.rm.regprog = NULL; - FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { if (wp->w_redr_type == CLEAR && wp->w_floating && wp->w_grid_alloc.chars) { grid_invalidate(&wp->w_grid_alloc); @@ -585,8 +571,9 @@ int update_screen(int type) win_update(wp, &providers); } - // redraw status line after the window to minimize cursor movement + // redraw status line and window bar after the window to minimize cursor movement if (wp->w_redr_status) { + win_redr_winbar(wp); win_redr_status(wp); } } @@ -598,8 +585,6 @@ int update_screen(int type) pum_redraw(); } - send_grid_resize = false; - /* Reset b_mod_set flags. Going through all windows is probably faster * than going through all buffers (there could be many buffers). */ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { @@ -623,7 +608,6 @@ int update_screen(int type) decor_providers_invoke_end(&providers, &provider_err); kvi_destroy(providers); - // either cmdline is cleared, not drawn or mode is last drawn cmdline_was_last_drawn = false; return OK; @@ -747,7 +731,7 @@ static void win_update(win_T *wp, DecorProviders *providers) } // Window is zero-height: Only need to draw the separator - if (wp->w_grid.Rows == 0) { + if (wp->w_grid.rows == 0) { // draw the horizontal separator below this window draw_hsep_win(wp); draw_sep_connectors_win(wp); @@ -756,7 +740,7 @@ static void win_update(win_T *wp, DecorProviders *providers) } // Window is zero-width: Only need to draw the separator. - if (wp->w_grid.Columns == 0) { + if (wp->w_grid.cols == 0) { // draw the vertical separator right of this window draw_vsep_win(wp); draw_sep_connectors_win(wp); @@ -955,7 +939,7 @@ static void win_update(win_T *wp, DecorProviders *providers) j = 0; for (ln = wp->w_topline; ln < wp->w_lines[0].wl_lnum; ln++) { j++; - if (j >= wp->w_grid.Rows - 2) { + if (j >= wp->w_grid.rows - 2) { break; } (void)hasFoldingWin(wp, ln, NULL, &ln, true, NULL); @@ -963,13 +947,13 @@ static void win_update(win_T *wp, DecorProviders *providers) } else { j = wp->w_lines[0].wl_lnum - wp->w_topline; } - if (j < wp->w_grid.Rows - 2) { // not too far off + if (j < wp->w_grid.rows - 2) { // not too far off i = plines_m_win(wp, wp->w_topline, wp->w_lines[0].wl_lnum - 1); // insert extra lines for previously invisible filler lines if (wp->w_lines[0].wl_lnum != wp->w_topline) { i += win_get_fill(wp, wp->w_lines[0].wl_lnum) - wp->w_old_topfill; } - if (i != 0 && i < wp->w_grid.Rows - 2) { // less than a screen off + if (i != 0 && i < wp->w_grid.rows - 2) { // less than a screen off // Try to insert the correct number of lines. // If not the last window, delete the lines at the bottom. // win_ins_lines may fail when the terminal can't do it. @@ -982,8 +966,8 @@ static void win_update(win_T *wp, DecorProviders *providers) // Move the entries that were scrolled, disable // the entries for the lines to be redrawn. - if ((wp->w_lines_valid += j) > wp->w_grid.Rows) { - wp->w_lines_valid = wp->w_grid.Rows; + if ((wp->w_lines_valid += j) > wp->w_grid.rows) { + wp->w_lines_valid = wp->w_grid.rows; } for (idx = wp->w_lines_valid; idx - j >= 0; idx--) { wp->w_lines[idx] = wp->w_lines[idx - j]; @@ -1036,7 +1020,7 @@ static void win_update(win_T *wp, DecorProviders *providers) row -= wp->w_topfill; if (row > 0) { win_scroll_lines(wp, 0, -row); - bot_start = wp->w_grid.Rows - row; + bot_start = wp->w_grid.rows - row; } if ((row == 0 || bot_start < 999) && wp->w_lines_valid != 0) { /* @@ -1052,7 +1036,7 @@ static void win_update(win_T *wp, DecorProviders *providers) /* stop at line that didn't fit, unless it is still * valid (no lines deleted) */ if (row > 0 && bot_start + row - + (int)wp->w_lines[j].wl_size > wp->w_grid.Rows) { + + (int)wp->w_lines[j].wl_size > wp->w_grid.rows) { wp->w_lines_valid = idx + 1; break; } @@ -1077,18 +1061,18 @@ static void win_update(win_T *wp, DecorProviders *providers) // When starting redraw in the first line, redraw all lines. if (mid_start == 0) { - mid_end = wp->w_grid.Rows; + mid_end = wp->w_grid.rows; } } else { // Not VALID or INVERTED: redraw all lines. mid_start = 0; - mid_end = wp->w_grid.Rows; + mid_end = wp->w_grid.rows; } if (type == SOME_VALID) { // SOME_VALID: redraw all lines. mid_start = 0; - mid_end = wp->w_grid.Rows; + mid_end = wp->w_grid.rows; type = NOT_VALID; } @@ -1275,7 +1259,7 @@ static void win_update(win_T *wp, DecorProviders *providers) } } srow += mid_start; - mid_end = wp->w_grid.Rows; + mid_end = wp->w_grid.rows; for (; idx < wp->w_lines_valid; idx++) { // find end if (wp->w_lines[idx].wl_valid && wp->w_lines[idx].wl_lnum >= to + 1) { @@ -1328,7 +1312,7 @@ static void win_update(win_T *wp, DecorProviders *providers) for (;;) { /* stop updating when reached the end of the window (check for _past_ * the end of the window is at the end of the loop) */ - if (row == wp->w_grid.Rows) { + if (row == wp->w_grid.rows) { didline = true; break; } @@ -1433,7 +1417,7 @@ static void win_update(win_T *wp, DecorProviders *providers) new_rows += plines_win(wp, l, true); } j++; - if (new_rows > wp->w_grid.Rows - row - 2) { + if (new_rows > wp->w_grid.rows - row - 2) { // it's getting too much, must redraw the rest new_rows = 9999; break; @@ -1445,17 +1429,17 @@ static void win_update(win_T *wp, DecorProviders *providers) * remaining text or scrolling fails, must redraw the * rest. If scrolling works, must redraw the text * below the scrolled text. */ - if (row - xtra_rows >= wp->w_grid.Rows - 2) { + if (row - xtra_rows >= wp->w_grid.rows - 2) { mod_bot = MAXLNUM; } else { win_scroll_lines(wp, row, xtra_rows); - bot_start = wp->w_grid.Rows + xtra_rows; + bot_start = wp->w_grid.rows + xtra_rows; } } else if (xtra_rows > 0) { /* May scroll text down. If there is not enough * remaining text of scrolling fails, must redraw the * rest. */ - if (row + xtra_rows >= wp->w_grid.Rows - 2) { + if (row + xtra_rows >= wp->w_grid.rows - 2) { mod_bot = MAXLNUM; } else { win_scroll_lines(wp, row + old_rows, xtra_rows); @@ -1483,7 +1467,7 @@ static void win_update(win_T *wp, DecorProviders *providers) wp->w_lines[j] = wp->w_lines[i]; // stop at a line that won't fit if (x + (int)wp->w_lines[j].wl_size - > wp->w_grid.Rows) { + > wp->w_grid.rows) { wp->w_lines_valid = j + 1; break; } @@ -1497,8 +1481,8 @@ static void win_update(win_T *wp, DecorProviders *providers) // move entries in w_lines[] downwards j -= i; wp->w_lines_valid += j; - if (wp->w_lines_valid > wp->w_grid.Rows) { - wp->w_lines_valid = wp->w_grid.Rows; + if (wp->w_lines_valid > wp->w_grid.rows) { + wp->w_lines_valid = wp->w_grid.rows; } for (i = wp->w_lines_valid; i - j >= idx; i--) { wp->w_lines[i] = wp->w_lines[i - j]; @@ -1529,11 +1513,11 @@ static void win_update(win_T *wp, DecorProviders *providers) && wp->w_lines[idx].wl_lnum == lnum && lnum > wp->w_topline && !(dy_flags & (DY_LASTLINE | DY_TRUNCATE)) - && srow + wp->w_lines[idx].wl_size > wp->w_grid.Rows + && srow + wp->w_lines[idx].wl_size > wp->w_grid.rows && win_get_fill(wp, lnum) == 0) { // This line is not going to fit. Don't draw anything here, // will draw "@ " lines below. - row = wp->w_grid.Rows + 1; + row = wp->w_grid.rows + 1; } else { prepare_search_hl(wp, &search_hl, lnum); // Let the syntax stuff know we skipped a few lines. @@ -1544,7 +1528,7 @@ static void win_update(win_T *wp, DecorProviders *providers) // Display one line row = win_line(wp, lnum, srow, - foldinfo.fi_lines ? srow : wp->w_grid.Rows, + foldinfo.fi_lines ? srow : wp->w_grid.rows, mod_top == 0, false, foldinfo, &line_providers); if (foldinfo.fi_lines == 0) { @@ -1563,7 +1547,7 @@ static void win_update(win_T *wp, DecorProviders *providers) wp->w_lines[idx].wl_lnum = lnum; wp->w_lines[idx].wl_valid = true; - if (row > wp->w_grid.Rows) { // past end of grid + if (row > wp->w_grid.rows) { // past end of grid // we may need the size of that too long line later on if (dollar_vcol == -1) { wp->w_lines[idx].wl_size = plines_win(wp, lnum, true); @@ -1581,13 +1565,13 @@ static void win_update(win_T *wp, DecorProviders *providers) // 'relativenumber' set and cursor moved vertically: The // text doesn't need to be drawn, but the number column does. foldinfo_T info = fold_info(wp, lnum); - (void)win_line(wp, lnum, srow, wp->w_grid.Rows, true, true, + (void)win_line(wp, lnum, srow, wp->w_grid.rows, true, true, info, &line_providers); } // This line does not need to be drawn, advance to the next one. row += wp->w_lines[idx++].wl_size; - if (row > wp->w_grid.Rows) { // past end of screen + if (row > wp->w_grid.rows) { // past end of screen break; } lnum = wp->w_lines[idx - 1].wl_lastlnum + 1; @@ -1635,41 +1619,41 @@ static void win_update(win_T *wp, DecorProviders *providers) * Don't overwrite it, it can be edited. */ wp->w_botline = lnum + 1; - } else if (win_get_fill(wp, lnum) >= wp->w_grid.Rows - srow) { + } else if (win_get_fill(wp, lnum) >= wp->w_grid.rows - srow) { // Window ends in filler lines. wp->w_botline = lnum; - wp->w_filler_rows = wp->w_grid.Rows - srow; + wp->w_filler_rows = wp->w_grid.rows - srow; } else if (dy_flags & DY_TRUNCATE) { // 'display' has "truncate" - int scr_row = wp->w_grid.Rows - 1; + int scr_row = wp->w_grid.rows - 1; // Last line isn't finished: Display "@@@" in the last screen line. - grid_puts_len(&wp->w_grid, (char_u *)"@@", MIN(wp->w_grid.Columns, 2), scr_row, 0, at_attr); + grid_puts_len(&wp->w_grid, (char_u *)"@@", MIN(wp->w_grid.cols, 2), scr_row, 0, at_attr); - grid_fill(&wp->w_grid, scr_row, scr_row + 1, 2, wp->w_grid.Columns, + grid_fill(&wp->w_grid, scr_row, scr_row + 1, 2, wp->w_grid.cols, '@', ' ', at_attr); set_empty_rows(wp, srow); wp->w_botline = lnum; } else if (dy_flags & DY_LASTLINE) { // 'display' has "lastline" - int start_col = wp->w_grid.Columns - 3; + int start_col = wp->w_grid.cols - 3; // Last line isn't finished: Display "@@@" at the end. - grid_fill(&wp->w_grid, wp->w_grid.Rows - 1, wp->w_grid.Rows, - MAX(start_col, 0), wp->w_grid.Columns, '@', '@', at_attr); + grid_fill(&wp->w_grid, wp->w_grid.rows - 1, wp->w_grid.rows, + MAX(start_col, 0), wp->w_grid.cols, '@', '@', at_attr); set_empty_rows(wp, srow); wp->w_botline = lnum; } else { - win_draw_end(wp, '@', ' ', true, srow, wp->w_grid.Rows, HLF_AT); + win_draw_end(wp, '@', ' ', true, srow, wp->w_grid.rows, HLF_AT); wp->w_botline = lnum; } } else { if (eof) { // we hit the end of the file wp->w_botline = buf->b_ml.ml_line_count + 1; j = win_get_fill(wp, wp->w_botline); - if (j > 0 && !wp->w_botfill && row < wp->w_grid.Rows) { + if (j > 0 && !wp->w_botfill && row < wp->w_grid.rows) { // Display filler text below last line. win_line() will check // for ml_line_count+1 and only draw filler lines foldinfo_T info = FOLDINFO_INIT; - row = win_line(wp, wp->w_botline, row, wp->w_grid.Rows, + row = win_line(wp, wp->w_botline, row, wp->w_grid.rows, false, false, info, &line_providers); } } else if (dollar_vcol == -1) { @@ -1678,7 +1662,7 @@ static void win_update(win_T *wp, DecorProviders *providers) // make sure the rest of the screen is blank // write the 'eob' character to rows that aren't part of the file. - win_draw_end(wp, wp->w_p_fcs_chars.eob, ' ', false, row, wp->w_grid.Rows, + win_draw_end(wp, wp->w_p_fcs_chars.eob, ' ', false, row, wp->w_grid.rows, HLF_EOB); } @@ -1734,7 +1718,6 @@ static void win_update(win_T *wp, DecorProviders *providers) } } - // restore got_int, unless CTRL-C was hit while redrawing if (!got_int) { got_int = save_got_int; @@ -1763,8 +1746,8 @@ static int win_fill_end(win_T *wp, int c1, int c2, int off, int width, int row, { int nn = off + width; - if (nn > wp->w_grid.Columns) { - nn = wp->w_grid.Columns; + if (nn > wp->w_grid.cols) { + nn = wp->w_grid.cols; } if (wp->w_p_rl) { @@ -1813,13 +1796,12 @@ static void win_draw_end(win_T *wp, int c1, int c2, bool draw_margin, int row, i grid_fill(&wp->w_grid, row, endrow, W_ENDCOL(wp) - 1 - n, W_ENDCOL(wp) - n, c1, c2, attr); } else { - grid_fill(&wp->w_grid, row, endrow, n, wp->w_grid.Columns, c1, c2, attr); + grid_fill(&wp->w_grid, row, endrow, n, wp->w_grid.cols, c1, c2, attr); } set_empty_rows(wp, row); } - /// Advance **color_cols /// /// @return true when there are columns to draw. @@ -1837,7 +1819,7 @@ static int compute_foldcolumn(win_T *wp, int col) { int fdc = win_fdccol_count(wp); int wmw = wp == curwin && p_wmw == 0 ? 1 : p_wmw; - int wwidth = wp->w_grid.Columns; + int wwidth = wp->w_grid.cols; if (fdc > wwidth - (col + wmw)) { fdc = wwidth - (col + wmw); @@ -1902,7 +1884,6 @@ done: return cells; } - /// Fills the foldcolumn at "p" for window "wp". /// Only to be called when 'foldcolumn' > 0. /// @@ -2621,7 +2602,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc // Rightleft window: process the text in the normal direction, but put // it in linebuf_char[off] from right to left. Start at the // rightmost column of the window. - col = grid->Columns - 1; + col = grid->cols - 1; off += col; } @@ -2803,7 +2784,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc if (wp->w_p_rl) { n_extra = col + 1; } else { - n_extra = grid->Columns - col; + n_extra = grid->cols - col; } char_attr = 0; } else if (filler_todo > 0) { @@ -2818,7 +2799,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc if (wp->w_p_rl) { n_extra = col + 1; } else { - n_extra = grid->Columns - col; + n_extra = grid->cols - col; } char_attr = win_hl_attr(wp, HLF_DED); } @@ -2892,15 +2873,15 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc && vcol >= (long)wp->w_virtcol) || (number_only && draw_state > WL_NR)) && filler_todo <= 0) { - draw_virt_text(wp, buf, win_col_offset, &col, grid->Columns, row); - grid_put_linebuf(grid, row, 0, col, -grid->Columns, wp->w_p_rl, wp, + draw_virt_text(wp, buf, win_col_offset, &col, grid->cols, row); + grid_put_linebuf(grid, row, 0, col, -grid->cols, wp->w_p_rl, wp, wp->w_hl_attr_normal, false); // Pretend we have finished updating the window. Except when // 'cursorcolumn' is set. if (wp->w_p_cuc) { row = wp->w_cline_row + wp->w_cline_height; } else { - row = grid->Rows; + row = grid->rows; } break; } @@ -2928,19 +2909,19 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc if (draw_state == WL_LINE && has_fold - && col < grid->Columns + && col < grid->cols && n_extra == 0 && row == startrow) { // fill rest of line with 'fold' c_extra = wp->w_p_fcs_chars.fold; c_final = NUL; - n_extra = wp->w_p_rl ? (col + 1) : (grid->Columns - col); + n_extra = wp->w_p_rl ? (col + 1) : (grid->cols - col); } if (draw_state == WL_LINE && has_fold - && col >= grid->Columns + && col >= grid->cols && n_extra != 0 && row == startrow) { // Truncate the folding. @@ -3069,7 +3050,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc } // If a double-width char doesn't fit display a '>' in the last column. - if ((wp->w_p_rl ? (col <= 0) : (col >= grid->Columns - 1)) + if ((wp->w_p_rl ? (col <= 0) : (col >= grid->cols - 1)) && utf_char2cells(mb_c) == 2) { c = '>'; mb_c = c; @@ -3183,7 +3164,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc // last column; the character is displayed at the start of the // next line. if ((wp->w_p_rl ? (col <= 0) : - (col >= grid->Columns - 1)) + (col >= grid->cols - 1)) && utf_char2cells(mb_c) == 2) { c = '>'; mb_c = c; @@ -3388,7 +3369,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc } } - if (c == TAB && n_extra + col > grid->Columns) { + if (c == TAB && n_extra + col > grid->cols) { n_extra = tabstop_padding(vcol, wp->w_buffer->b_p_ts, wp->w_buffer->b_p_vts_array) - 1; } @@ -3591,7 +3572,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc || ((fromcol >= 0 || fromcol_prev >= 0) && tocol > vcol && VIsual_mode != Ctrl_V - && (wp->w_p_rl ? (col >= 0) : (col < grid->Columns)) + && (wp->w_p_rl ? (col >= 0) : (col < grid->cols)) && !(noinvcur && lnum == wp->w_cursor.lnum && (colnr_T)vcol == wp->w_virtcol))) @@ -3663,7 +3644,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc && virtual_active() && tocol != MAXCOL && vcol < tocol - && (wp->w_p_rl ? (col >= 0) : (col < grid->Columns))) { + && (wp->w_p_rl ? (col >= 0) : (col < grid->cols))) { c = ' '; ptr--; // put it back at the NUL } @@ -3745,7 +3726,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc && conceal_cursor_line(wp) && (int)wp->w_virtcol <= vcol + n_skip) { if (wp->w_p_rl) { - wp->w_wcol = grid->Columns - col + boguscols - 1; + wp->w_wcol = grid->cols - col + boguscols - 1; } else { wp->w_wcol = col - boguscols; } @@ -3817,7 +3798,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc n = 1; } } else { - if (col >= grid->Columns) { + if (col >= grid->cols) { n = -1; } } @@ -3885,7 +3866,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc if (((wp->w_p_cuc && (int)wp->w_virtcol >= VCOL_HLC - eol_hl_off && (int)wp->w_virtcol < - (long)grid->Columns * (row - startrow + 1) + v + (long)grid->cols * (row - startrow + 1) + v && lnum != wp->w_cursor.lnum) || draw_color_col || line_attr_lowprio || line_attr || diff_hlf != (hlf_T)0 || has_virttext)) { @@ -3923,7 +3904,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc int col_stride = wp->w_p_rl ? -1 : 1; - while (wp->w_p_rl ? col >= 0 : col < grid->Columns) { + while (wp->w_p_rl ? col >= 0 : col < grid->cols) { schar_from_ascii(linebuf_char[off], ' '); col += col_stride; if (draw_color_col) { @@ -3956,7 +3937,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc // terminal buffers may need to highlight beyond the end of the // logical line int n = wp->w_p_rl ? -1 : 1; - while (col >= 0 && col < grid->Columns) { + while (col >= 0 && col < grid->cols) { schar_from_ascii(linebuf_char[off], ' '); linebuf_attr[off] = vcol >= TERM_ATTRS_MAX ? 0 : term_attrs[vcol]; off += n; @@ -3965,8 +3946,8 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc } } - draw_virt_text(wp, buf, win_col_offset, &col, grid->Columns, row); - grid_put_linebuf(grid, row, 0, col, grid->Columns, wp->w_p_rl, wp, + draw_virt_text(wp, buf, win_col_offset, &col, grid->cols, row); + grid_put_linebuf(grid, row, 0, col, grid->cols, wp->w_p_rl, wp, wp->w_hl_attr_normal, false); row++; @@ -3991,7 +3972,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc && wp->w_p_list && !wp->w_p_wrap && filler_todo <= 0 - && (wp->w_p_rl ? col == 0 : col == grid->Columns - 1) + && (wp->w_p_rl ? col == 0 : col == grid->cols - 1) && !has_fold && (*ptr != NUL || lcs_eol_one > 0 @@ -4126,7 +4107,6 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc n_attr = 0; } - if (utf_char2cells(mb_c) > 1) { // Need to fill two screen columns. if (wp->w_p_rl) { @@ -4181,7 +4161,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc * At end of screen line and there is more to come: Display the line * so far. If there is no more to display it is caught above. */ - if ((wp->w_p_rl ? (col < 0) : (col >= grid->Columns)) + if ((wp->w_p_rl ? (col < 0) : (col >= grid->cols)) && foldinfo.fi_lines == 0 && (draw_state != WL_LINE || *ptr != NUL @@ -4194,7 +4174,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc && filler_todo <= 0 // Not drawing diff filler lines. && lcs_eol_one != -1 // Haven't printed the lcs_eol character. && row != endrow - 1 // Not the last line being displayed. - && (grid->Columns == Columns // Window spans the width of the screen, + && (grid->cols == Columns // Window spans the width of the screen, || ui_has(kUIMultigrid)) // or has dedicated grid. && !wp->w_p_rl; // Not right-to-left. @@ -4206,13 +4186,13 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc assert(i >= 0); int offset = kv_A(virt_lines, i).left_col ? 0 : win_col_offset; draw_virt_text_item(buf, offset, kv_A(virt_lines, i).line, - kHlModeReplace, grid->Columns, offset); + kHlModeReplace, grid->cols, offset); } } else { - draw_virt_text(wp, buf, win_col_offset, &draw_col, grid->Columns, row); + draw_virt_text(wp, buf, win_col_offset, &draw_col, grid->cols, row); } - grid_put_linebuf(grid, row, 0, draw_col, grid->Columns, wp->w_p_rl, + grid_put_linebuf(grid, row, 0, draw_col, grid->cols, wp->w_p_rl, wp, wp->w_hl_attr_normal, wrap); if (wrap) { ScreenGrid *current_grid = grid; @@ -4239,7 +4219,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc // When the window is too narrow draw all "@" lines. if (draw_state != WL_LINE && filler_todo <= 0) { - win_draw_end(wp, '@', ' ', true, row, wp->w_grid.Rows, HLF_AT); + win_draw_end(wp, '@', ' ', true, row, wp->w_grid.rows, HLF_AT); row = endrow; } @@ -4252,7 +4232,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc col = 0; off = 0; if (wp->w_p_rl) { - col = grid->Columns - 1; // col is not used if breaking! + col = grid->cols - 1; // col is not used if breaking! off += col; } @@ -4511,7 +4491,6 @@ static void get_sign_display_info(bool nrcol, win_T *wp, linenr_T lnum, sign_att } } - /* * Mirror text "str" for right-left displaying. * Only works for single-byte characters (e.g., numbers). @@ -4528,42 +4507,36 @@ void rl_mirror(char_u *str) } } -/* - * mark all status lines for redraw; used after first :cd - */ +/// Mark all status lines and window bars for redraw; used after first :cd void status_redraw_all(void) { - if (global_stl_height()) { - curwin->w_redr_status = true; - redraw_later(curwin, VALID); - } else { - FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - if (wp->w_status_height) { - wp->w_redr_status = true; - redraw_later(wp, VALID); - } + bool is_stl_global = global_stl_height() != 0; + + FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { + if ((!is_stl_global && wp->w_status_height) || (is_stl_global && wp == curwin) + || wp->w_winbar_height) { + wp->w_redr_status = true; + redraw_later(wp, VALID); } } } -/// Marks all status lines of the current buffer for redraw. +/// Marks all status lines and window bars of the current buffer for redraw. void status_redraw_curbuf(void) { status_redraw_buf(curbuf); } -/// Marks all status lines of the specified buffer for redraw. +/// Marks all status lines and window bars of the given buffer for redraw. void status_redraw_buf(buf_T *buf) { - if (global_stl_height() != 0 && curwin->w_buffer == buf) { - curwin->w_redr_status = true; - redraw_later(curwin, VALID); - } else { - FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - if (wp->w_status_height != 0 && wp->w_buffer == buf) { - wp->w_redr_status = true; - redraw_later(wp, VALID); - } + bool is_stl_global = global_stl_height() != 0; + + FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { + if (wp->w_buffer == buf && ((!is_stl_global && wp->w_status_height) + || (is_stl_global && wp == curwin) || wp->w_winbar_height)) { + wp->w_redr_status = true; + redraw_later(wp, VALID); } } } @@ -4575,6 +4548,7 @@ void redraw_statuslines(void) { FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { if (wp->w_redr_status) { + win_redr_winbar(wp); win_redr_status(wp); } } @@ -5075,7 +5049,7 @@ static void redraw_custom_statusline(win_T *wp) entered = true; did_emsg = false; - win_redr_custom(wp, false); + win_redr_custom(wp, false, false); if (did_emsg) { // When there is an error disable the statusline, otherwise the // display is messed up with errors and a redraw triggers the problem @@ -5088,6 +5062,37 @@ static void redraw_custom_statusline(win_T *wp) entered = false; } +static void win_redr_winbar(win_T *wp) +{ + static bool entered = false; + + // Return when called recursively. This can happen when the winbar contains an expression + // that triggers a redraw. + if (entered) { + return; + } + entered = true; + + if (wp->w_winbar_height == 0 || !redrawing()) { + // Do nothing. + } else if (*p_wbr != NUL || *wp->w_p_wbr != NUL) { + int saved_did_emsg = did_emsg; + + did_emsg = false; + win_redr_custom(wp, true, false); + if (did_emsg) { + // When there is an error disable the winbar, otherwise the + // display is messed up with errors and a redraw triggers the problem + // again and again. + set_string_option_direct("winbar", -1, (char_u *)"", + OPT_FREE | (*wp->w_p_stl != NUL + ? OPT_LOCAL : OPT_GLOBAL), SID_ERROR); + } + did_emsg |= saved_did_emsg; + } + entered = false; +} + /// Only call if (wp->w_vsep_width != 0). /// /// @return true if the status line of window "wp" is connected to the status @@ -5224,11 +5229,9 @@ bool get_keymap_str(win_T *wp, char_u *fmt, char_u *buf, int len) return buf[0] != NUL; } -/* - * Redraw the status line or ruler of window "wp". - * When "wp" is NULL redraw the tab pages line from 'tabline'. - */ -static void win_redr_custom(win_T *wp, bool draw_ruler) +/// Redraw the status line, window bar or ruler of window "wp". +/// When "wp" is NULL redraw the tab pages line from 'tabline'. +static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) { static bool entered = false; int attr; @@ -5269,11 +5272,42 @@ static void win_redr_custom(win_T *wp, bool draw_ruler) attr = HL_ATTR(HLF_TPF); maxwidth = Columns; use_sandbox = was_set_insecurely(wp, "tabline", 0); + } else if (draw_winbar) { + stl = (char_u *)((*wp->w_p_wbr != NUL) ? wp->w_p_wbr : p_wbr); + row = -1; // row zero is first row of text + col = 0; + grid = &wp->w_grid; + grid_adjust(&grid, &row, &col); + + if (row < 0) { + return; + } + + fillchar = wp->w_p_fcs_chars.wbr; + attr = (wp == curwin) ? HL_ATTR(HLF_WBR) : HL_ATTR(HLF_WBRNC); + maxwidth = wp->w_width_inner; + use_sandbox = was_set_insecurely(wp, "winbar", 0); + + stl_clear_click_defs(wp->w_winbar_click_defs, wp->w_winbar_click_defs_size); + // Allocate / resize the click definitions array for winbar if needed. + if (wp->w_winbar_height && wp->w_winbar_click_defs_size < (size_t)maxwidth) { + xfree(wp->w_winbar_click_defs); + wp->w_winbar_click_defs_size = (size_t)maxwidth; + wp->w_winbar_click_defs = xcalloc(wp->w_winbar_click_defs_size, sizeof(StlClickRecord)); + } } else { row = is_stl_global ? (Rows - p_ch - 1) : W_ENDROW(wp); fillchar = fillchar_status(&attr, wp); maxwidth = is_stl_global ? Columns : wp->w_width; + stl_clear_click_defs(wp->w_status_click_defs, wp->w_status_click_defs_size); + // Allocate / resize the click definitions array for statusline if needed. + if (wp->w_status_click_defs_size < (size_t)maxwidth) { + xfree(wp->w_status_click_defs); + wp->w_status_click_defs_size = maxwidth; + wp->w_status_click_defs = xcalloc(wp->w_status_click_defs_size, sizeof(StlClickRecord)); + } + if (draw_ruler) { stl = p_ruf; // advance past any leading group spec - implicit in ru_col @@ -5377,26 +5411,38 @@ static void win_redr_custom(win_T *wp, bool draw_ruler) grid_puts_line_flush(false); - if (wp == NULL) { - // Fill the tab_page_click_defs array for clicking in the tab pages line. - col = 0; - len = 0; - p = buf; - StlClickDefinition cur_click_def = { - .type = kStlClickDisabled, - }; - for (n = 0; tabtab[n].start != NULL; n++) { - len += vim_strnsize(p, (int)(tabtab[n].start - (char *)p)); - while (col < len) { - tab_page_click_defs[col++] = cur_click_def; - } - p = (char_u *)tabtab[n].start; - cur_click_def = tabtab[n].def; + // Fill the tab_page_click_defs, w_status_click_defs or w_winbar_click_defs array for clicking + // in the tab page line, status line or window bar + StlClickDefinition *click_defs = (wp == NULL) ? tab_page_click_defs + : draw_winbar ? wp->w_winbar_click_defs + : wp->w_status_click_defs; + + if (click_defs == NULL) { + goto theend; + } + + col = 0; + len = 0; + p = buf; + StlClickDefinition cur_click_def = { + .type = kStlClickDisabled, + }; + for (n = 0; tabtab[n].start != NULL; n++) { + len += vim_strnsize(p, (int)(tabtab[n].start - (char *)p)); + while (col < len) { + click_defs[col++] = cur_click_def; } - while (col < Columns) { - tab_page_click_defs[col++] = cur_click_def; + p = (char_u *)tabtab[n].start; + cur_click_def = tabtab[n].def; + if ((wp != NULL) && !(cur_click_def.type == kStlClickDisabled + || cur_click_def.type == kStlClickFuncRun)) { + // window bar and status line only support click functions + cur_click_def.type = kStlClickDisabled; } } + while (col < maxwidth) { + click_defs[col++] = cur_click_def; + } theend: entered = false; @@ -5414,7 +5460,6 @@ static void win_redr_border(win_T *wp) schar_T *chars = wp->w_float_config.border_chars; int *attrs = wp->w_float_config.border_attr; - int *adj = wp->w_border_adj; int irow = wp->w_height_inner, icol = wp->w_width_inner; @@ -5462,7 +5507,6 @@ static void win_redr_border(win_T *wp) } } - /* * Prepare for 'hlsearch' highlighting. */ @@ -5487,7 +5531,6 @@ static void end_search_hl(void) } } - /// Check if there should be a delay. Used before clearing or redrawing the /// screen or the command line. void check_for_delay(bool check_msg_scroll) @@ -5504,93 +5547,13 @@ void check_for_delay(bool check_msg_scroll) } } -/// (Re)allocates a window grid if size changed while in ext_multigrid mode. -/// Updates size, offsets and handle for the grid regardless. -/// -/// If "doclear" is true, don't try to copy from the old grid rather clear the -/// resized grid. -void win_grid_alloc(win_T *wp) -{ - ScreenGrid *grid = &wp->w_grid; - ScreenGrid *grid_allocated = &wp->w_grid_alloc; - - int rows = wp->w_height_inner; - int cols = wp->w_width_inner; - int total_rows = wp->w_height_outer; - int total_cols = wp->w_width_outer; - - bool want_allocation = ui_has(kUIMultigrid) || wp->w_floating; - bool has_allocation = (grid_allocated->chars != NULL); - - if (grid->Rows != rows) { - wp->w_lines_valid = 0; - xfree(wp->w_lines); - wp->w_lines = xcalloc(rows + 1, sizeof(wline_T)); - } - - int was_resized = false; - if (want_allocation && (!has_allocation - || grid_allocated->Rows != total_rows - || grid_allocated->Columns != total_cols)) { - grid_alloc(grid_allocated, total_rows, total_cols, - wp->w_grid_alloc.valid, false); - grid_allocated->valid = true; - if (wp->w_floating && wp->w_float_config.border) { - wp->w_redr_border = true; - } - was_resized = true; - } else if (!want_allocation && has_allocation) { - // Single grid mode, all rendering will be redirected to default_grid. - // Only keep track of the size and offset of the window. - grid_free(grid_allocated); - grid_allocated->valid = false; - was_resized = true; - } else if (want_allocation && has_allocation && !wp->w_grid_alloc.valid) { - grid_invalidate(grid_allocated); - grid_allocated->valid = true; - } - - grid->Rows = rows; - grid->Columns = cols; - - if (want_allocation) { - grid->target = grid_allocated; - grid->row_offset = wp->w_border_adj[0]; - grid->col_offset = wp->w_border_adj[3]; - } else { - grid->target = &default_grid; - grid->row_offset = wp->w_winrow; - grid->col_offset = wp->w_wincol; - } - - // send grid resize event if: - // - a grid was just resized - // - screen_resize was called and all grid sizes must be sent - // - the UI wants multigrid event (necessary) - if ((send_grid_resize || was_resized) && want_allocation) { - ui_call_grid_resize(grid_allocated->handle, - grid_allocated->Columns, grid_allocated->Rows); - } -} - -/// assign a handle to the grid. The grid need not be allocated. -void grid_assign_handle(ScreenGrid *grid) -{ - static int last_grid_handle = DEFAULT_GRID_HANDLE; - - // only assign a grid handle if not already - if (grid->handle == 0) { - grid->handle = ++last_grid_handle; - } -} - /// Resize the screen to Rows and Columns. /// /// Allocate default_grid.chars[] and other grid arrays. /// /// There may be some time between setting Rows and Columns and (re)allocating /// default_grid arrays. This happens when starting up and when -/// (manually) changing the shell size. Always use default_grid.Rows and +/// (manually) changing the shell size. Always use default_grid.rows and /// default_grid.Columns to access items in default_grid.chars[]. Use Rows /// and Columns for positioning text etc. where the final size of the shell is /// needed. @@ -5611,8 +5574,8 @@ retry: // when Rows and Columns have been set and we have started doing full // screen stuff. if ((default_grid.chars != NULL - && Rows == default_grid.Rows - && Columns == default_grid.Columns + && Rows == default_grid.rows + && Columns == default_grid.cols ) || Rows == 0 || Columns == 0 @@ -5652,7 +5615,7 @@ retry: StlClickDefinition *new_tab_page_click_defs = xcalloc((size_t)Columns, sizeof(*new_tab_page_click_defs)); - clear_tab_page_click_defs(tab_page_click_defs, tab_page_click_defs_size); + stl_clear_click_defs(tab_page_click_defs, tab_page_click_defs_size); xfree(tab_page_click_defs); tab_page_click_defs = new_tab_page_click_defs; @@ -5683,19 +5646,19 @@ retry: resizing = false; } -/// Clear tab_page_click_defs table +/// Clear status line, window bar or tab page line click definition table /// /// @param[out] tpcd Table to clear. /// @param[in] tpcd_size Size of the table. -void clear_tab_page_click_defs(StlClickDefinition *const tpcd, const long tpcd_size) +void stl_clear_click_defs(StlClickDefinition *const click_defs, const long click_defs_size) { - if (tpcd != NULL) { - for (long i = 0; i < tpcd_size; i++) { - if (i == 0 || tpcd[i].func != tpcd[i - 1].func) { - xfree(tpcd[i].func); + if (click_defs != NULL) { + for (long i = 0; i < click_defs_size; i++) { + if (i == 0 || click_defs[i].func != click_defs[i - 1].func) { + xfree(click_defs[i].func); } } - memset(tpcd, 0, (size_t)tpcd_size * sizeof(tpcd[0])); + memset(click_defs, 0, (size_t)click_defs_size * sizeof(click_defs[0])); } } @@ -5711,9 +5674,9 @@ void screenclear(void) } // blank out the default grid - for (i = 0; i < default_grid.Rows; i++) { + for (i = 0; i < default_grid.rows; i++) { grid_clear_line(&default_grid, default_grid.line_offset[i], - default_grid.Columns, true); + default_grid.cols, true); default_grid.line_wraps[i] = false; } @@ -5797,16 +5760,16 @@ void win_scroll_lines(win_T *wp, int row, int line_count) } // No lines are being moved, just draw over the entire area - if (row + abs(line_count) >= wp->w_grid.Rows) { + if (row + abs(line_count) >= wp->w_grid.rows) { return; } if (line_count < 0) { grid_del_lines(&wp->w_grid, row, -line_count, - wp->w_grid.Rows, 0, wp->w_grid.Columns); + wp->w_grid.rows, 0, wp->w_grid.cols); } else { grid_ins_lines(&wp->w_grid, row, line_count, - wp->w_grid.Rows, 0, wp->w_grid.Columns); + wp->w_grid.rows, 0, wp->w_grid.cols); } } @@ -5820,7 +5783,6 @@ void win_scroll_lines(win_T *wp, int row, int line_count) * screen changes, and in the meantime, everything still works. */ - /// insert lines on the screen and move the existing lines down /// 'line_count' is the number of lines to be inserted. /// 'end' is the line after the scrolled part. Normally it is Rows. @@ -5845,7 +5807,7 @@ void grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col, // Shift line_offset[] line_count down to reflect the inserted lines. // Clear the inserted lines. for (i = 0; i < line_count; i++) { - if (width != grid->Columns) { + if (width != grid->cols) { // need to copy part of a line j = end - 1 - i; while ((j -= line_count) >= row) { @@ -5863,7 +5825,7 @@ void grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col, } grid->line_offset[j + line_count] = temp; grid->line_wraps[j + line_count] = false; - grid_clear_line(grid, temp, grid->Columns, false); + grid_clear_line(grid, temp, grid->cols, false); } } @@ -5894,7 +5856,7 @@ void grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col, // Now shift line_offset[] line_count up to reflect the deleted lines. // Clear the inserted lines. for (i = 0; i < line_count; i++) { - if (width != grid->Columns) { + if (width != grid->cols) { // need to copy part of a line j = row + i; while ((j += line_count) <= end - 1) { @@ -5913,7 +5875,7 @@ void grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col, } grid->line_offset[j - line_count] = temp; grid->line_wraps[j - line_count] = false; - grid_clear_line(grid, temp, grid->Columns, false); + grid_clear_line(grid, temp, grid->cols, false); } } @@ -5922,7 +5884,6 @@ void grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col, } } - // Show the current mode and ruler. // // If clear_cmdline is true, clear the rest of the cmdline. @@ -6208,10 +6169,9 @@ void draw_tabline(void) return; } - // Init TabPageIdxs[] to zero: Clicking outside of tabs has no effect. assert(Columns == tab_page_click_defs_size); - clear_tab_page_click_defs(tab_page_click_defs, tab_page_click_defs_size); + stl_clear_click_defs(tab_page_click_defs, tab_page_click_defs_size); // Use the 'tabline' option if it's set. if (*p_tal != NUL) { @@ -6220,7 +6180,7 @@ void draw_tabline(void) // Check for an error. If there is one we would loop in redrawing the // screen. Avoid that by making 'tabline' empty. did_emsg = false; - win_redr_custom(NULL, false); + win_redr_custom(NULL, false, false); if (did_emsg) { set_string_option_direct("tabline", -1, (char_u *)"", OPT_FREE, SID_ERROR); @@ -6257,7 +6217,6 @@ void draw_tabline(void) wp = tp->tp_firstwin; } - if (tp->tp_topframe == topframe) { attr = win_hl_attr(cwp, HLF_TPS); } @@ -6279,7 +6238,6 @@ void draw_tabline(void) } } - if (modified || wincount > 1) { if (wincount > 1) { vim_snprintf((char *)NameBuff, MAXPATHL, "%d", wincount); @@ -6474,6 +6432,9 @@ void showruler(bool always) } else { win_redr_ruler(curwin, always); } + if (*p_wbr != NUL || *curwin->w_p_wbr != NUL) { + win_redr_winbar(curwin); + } if (need_maketitle || (p_icon && (stl_syntax & STL_IN_ICON)) @@ -6516,7 +6477,7 @@ static void win_redr_ruler(win_T *wp, bool always) int save_called_emsg = called_emsg; called_emsg = false; - win_redr_custom(wp, true); + win_redr_custom(wp, false, true); if (called_emsg) { set_string_option_direct("rulerformat", -1, (char_u *)"", OPT_FREE, SID_ERROR); @@ -6754,11 +6715,9 @@ static void margin_columns_win(win_T *wp, int *left_col, int *right_col) /// Set dimensions of the Nvim application "shell". void screen_resize(int width, int height) { - static bool recursive = false; - // Avoid recursiveness, can happen when setting the window size causes // another window-changed signal. - if (updating_screen || recursive) { + if (updating_screen || resizing_screen) { return; } @@ -6780,7 +6739,7 @@ void screen_resize(int width, int height) return; } - recursive = true; + resizing_screen = true; Rows = height; Columns = width; @@ -6797,9 +6756,9 @@ void screen_resize(int width, int height) send_grid_resize = true; - /* The window layout used to be adjusted here, but it now happens in - * screenalloc() (also invoked from screenclear()). That is because the - * "recursive" check above may skip this, but not screenalloc(). */ + /// The window layout used to be adjusted here, but it now happens in + /// screenalloc() (also invoked from screenclear()). That is because the + /// recursize "resizing_screen" check above may skip this, but not screenalloc(). if (State != MODE_ASKMORE && State != MODE_EXTERNCMD && State != MODE_CONFIRM) { screenclear(); @@ -6858,7 +6817,7 @@ void screen_resize(int width, int height) } ui_flush(); } - recursive = false; + resizing_screen = false; } /// Check if the new Nvim application "shell" dimensions are valid. diff --git a/src/nvim/screen.h b/src/nvim/screen.h index 3afbaa5eb6..9eda5223f1 100644 --- a/src/nvim/screen.h +++ b/src/nvim/screen.h @@ -30,33 +30,22 @@ typedef enum { // Maximum columns for terminal highlight attributes #define TERM_ATTRS_MAX 1024 -/// Status line click definition -typedef struct { - enum { - kStlClickDisabled = 0, ///< Clicks to this area are ignored. - kStlClickTabSwitch, ///< Switch to the given tab. - kStlClickTabClose, ///< Close given tab. - kStlClickFuncRun, ///< Run user function. - } type; ///< Type of the click. - int tabnr; ///< Tab page number. - char *func; ///< Function to run. -} StlClickDefinition; - -/// Used for tabline clicks -typedef struct { - StlClickDefinition def; ///< Click definition. - const char *start; ///< Location where region starts. -} StlClickRecord; - /// Array defining what should be done when tabline is clicked -extern StlClickDefinition *tab_page_click_defs; +EXTERN StlClickDefinition *tab_page_click_defs INIT(= NULL); /// Size of the tab_page_click_defs array -extern long tab_page_click_defs_size; +EXTERN long tab_page_click_defs_size INIT(= 0); #define W_ENDCOL(wp) ((wp)->w_wincol + (wp)->w_width) #define W_ENDROW(wp) ((wp)->w_winrow + (wp)->w_height) +// While redrawing the screen this flag is set. It means the screen size +// ('lines' and 'rows') must not be changed. +EXTERN bool updating_screen INIT(= 0); + +// While resizing the screen this flag is set. +EXTERN bool resizing_screen INIT(= 0); + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "screen.h.generated.h" #endif diff --git a/src/nvim/search.c b/src/nvim/search.c index 11d40c058c..3eb8d20ffc 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -204,31 +204,6 @@ char_u *get_search_pat(void) return mr_pattern; } -/* - * Reverse text into allocated memory. - * Returns the allocated string. - * - * TODO(philix): move reverse_text() to strings.c - */ -char_u *reverse_text(char_u *s) FUNC_ATTR_NONNULL_RET -{ - /* - * Reverse the pattern. - */ - size_t len = STRLEN(s); - char_u *rev = xmalloc(len + 1); - size_t rev_i = len; - for (size_t s_i = 0; s_i < len; s_i++) { - const int mb_len = utfc_ptr2len((char *)s + s_i); - rev_i -= mb_len; - memmove(rev + rev_i, s + s_i, mb_len); - s_i += mb_len - 1; - } - rev[len] = NUL; - - return rev; -} - void save_re_pat(int idx, char_u *pat, int magic) { if (spats[idx].pat != pat) { @@ -1990,13 +1965,13 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) clearpos(&match_pos); // backward search: Check if this line contains a single-line comment - if ((backwards && comment_dir) - || lisp) { + if ((backwards && comment_dir) || lisp) { comment_col = check_linecomment(linep); } if (lisp && comment_col != MAXCOL && pos.col > (colnr_T)comment_col) { lispcomm = true; // find match inside this comment } + while (!got_int) { /* * Go to the next position, forward or backward. We could use @@ -2023,8 +1998,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) line_breakcheck(); // Check if this line contains a single-line comment - if (comment_dir - || lisp) { + if (comment_dir || lisp) { comment_col = check_linecomment(linep); } // skip comment @@ -2038,7 +2012,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) } else { // forward search if (linep[pos.col] == NUL // at end of line, go to next one - // don't search for match in comment + // For lisp don't search for match in comment || (lisp && comment_col != MAXCOL && pos.col == (colnr_T)comment_col)) { if (pos.lnum == curbuf->b_ml.ml_line_count // end of file @@ -2348,8 +2322,8 @@ int check_linecomment(const char_u *line) } else { while ((p = (char_u *)vim_strchr((char *)p, '/')) != NULL) { // Accept a double /, unless it's preceded with * and followed by *, - // because * / / * is an end and start of a C comment. - // Only accept the position if it is not inside a string. + // because * / / * is an end and start of a C comment. Only + // accept the position if it is not inside a string. if (p[1] == '/' && (p == line || p[-1] != '*' || p[2] != '*') && !is_pos_in_string(line, (colnr_T)(p - line))) { break; @@ -3479,11 +3453,11 @@ int current_block(oparg_T *oap, long count, int include, int what, int other) } } - /* - * In Visual mode, when the resulting area is not bigger than what we - * started with, extend it to the next block, and then exclude again. - */ + // In Visual mode, when the resulting area is not bigger than what we + // started with, extend it to the next block, and then exclude again. + // Don't try to expand the area if the area is empty. if (!lt(start_pos, old_start) && !lt(old_end, curwin->w_cursor) + && !equalpos(start_pos, curwin->w_cursor) && VIsual_active) { curwin->w_cursor = old_start; decl(&curwin->w_cursor); @@ -3533,7 +3507,6 @@ int current_block(oparg_T *oap, long count, int include, int what, int other) return OK; } - /// @param end_tag when true, return true if the cursor is on "</aaa>". /// /// @return true if the cursor is on a "<aaa>" tag. Ignore "<aaa/>". @@ -3951,7 +3924,6 @@ extend: return OK; } - /// Search quote char from string line[col]. /// Quote character escaped by one of the characters in "escape" is not counted /// as a quote. @@ -4270,7 +4242,6 @@ abort_search: return false; } - /// Find next search match under cursor, cursor at end. /// Used while an operator is pending, and in Visual mode. /// diff --git a/src/nvim/shada.c b/src/nvim/shada.c index abb6c68474..2693cb0273 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -512,8 +512,8 @@ static inline void hmll_init(HMLList *const hmll, const size_t size) /// /// @return `for` cycle header (use `HMLL_FORALL(hmll, cur_entry) {body}`). #define HMLL_FORALL(hmll, cur_entry, code) \ - for (HMLListEntry *cur_entry = (hmll)->first; cur_entry != NULL; \ - cur_entry = cur_entry->next) { \ + for (HMLListEntry *(cur_entry) = (hmll)->first; (cur_entry) != NULL; \ + (cur_entry) = (cur_entry)->next) { \ code \ } \ @@ -550,7 +550,6 @@ static inline void hmll_remove(HMLList *const hmll, HMLListEntry *const hmll_ent } } - /// Insert entry to the linked list /// /// @param[out] hmll List to insert to. @@ -1073,13 +1072,13 @@ static inline bool marks_equal(const pos_T a, const pos_T b) entry, fname_cond, free_func, fin_func, \ idxadj_func, afterfree_func) \ do { \ - const int jl_len = (int)jumps_size; \ + const int jl_len = (int)(jumps_size); \ int i; \ for (i = jl_len; i > 0; i--) { \ - const jumps_type jl_entry = jumps[i - 1]; \ - if (jl_entry.timestamp_attr <= entry.timestamp) { \ - if (marks_equal(jl_entry.mark_attr, entry.data.filemark.mark) \ - && fname_cond) { \ + const jumps_type jl_entry = (jumps)[i - 1]; \ + if (jl_entry.timestamp_attr <= (entry).timestamp) { \ + if (marks_equal(jl_entry.mark_attr, (entry).data.filemark.mark) \ + && (fname_cond)) { \ i = -1; \ } \ break; \ @@ -1087,30 +1086,30 @@ static inline bool marks_equal(const pos_T a, const pos_T b) } \ if (i > 0) { \ if (jl_len == JUMPLISTSIZE) { \ - free_func(jumps[0]); \ + free_func((jumps)[0]); \ i--; \ if (i > 0) { \ - memmove(&jumps[0], &jumps[1], sizeof(jumps[1]) * (size_t)i); \ + memmove(&(jumps)[0], &(jumps)[1], sizeof((jumps)[1]) * (size_t)i); \ } \ } else if (i != jl_len) { \ - memmove(&jumps[i + 1], &jumps[i], \ - sizeof(jumps[0]) * (size_t)(jl_len - i)); \ + memmove(&(jumps)[i + 1], &(jumps)[i], \ + sizeof((jumps)[0]) * (size_t)(jl_len - i)); \ } \ } else if (i == 0) { \ if (jl_len == JUMPLISTSIZE) { \ i = -1; \ } else if (jl_len > 0) { \ - memmove(&jumps[1], &jumps[0], sizeof(jumps[0]) * (size_t)jl_len); \ + memmove(&(jumps)[1], &(jumps)[0], sizeof((jumps)[0]) * (size_t)jl_len); \ } \ } \ if (i != -1) { \ - jumps[i] = fin_func(entry); \ + (jumps)[i] = fin_func(entry); \ if (jl_len < JUMPLISTSIZE) { \ - jumps_size++; \ + (jumps_size)++; \ } \ idxadj_func(i); \ } else { \ - shada_free_shada_entry(&entry); \ + shada_free_shada_entry(&(entry)); \ afterfree_func(entry); \ } \ } while (0) @@ -1305,7 +1304,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags) } else { #define SDE_TO_XFMARK(entry) fm #define ADJUST_IDX(i) \ - if (curwin->w_jumplistidx >= i \ + if (curwin->w_jumplistidx >= (i) \ && curwin->w_jumplistidx + 1 <= curwin->w_jumplistlen) { \ curwin->w_jumplistidx++; \ } @@ -1548,7 +1547,7 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer, ShadaEntr } \ } while (0) #define CHECK_DEFAULT(entry, attr) \ - (sd_default_values[entry.type].data.attr == entry.data.attr) + (sd_default_values[(entry).type].data.attr == (entry).data.attr) #define ONE_IF_NOT_DEFAULT(entry, attr) \ ((size_t)(!CHECK_DEFAULT(entry, attr))) switch (entry.type) { @@ -1638,7 +1637,7 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer, ShadaEntr do { \ if (!CHECK_DEFAULT(entry, search_pattern.attr)) { \ PACK_STATIC_STR(name); \ - if (sd_default_values[entry.type].data.search_pattern.attr) { \ + if (sd_default_values[(entry).type].data.search_pattern.attr) { \ msgpack_pack_false(spacker); \ } else { \ msgpack_pack_true(spacker); \ @@ -2222,12 +2221,12 @@ static inline ShaDaWriteResult shada_read_when_writing(ShaDaReadDef *const sd_re } else { #define FREE_POSSIBLY_FREED_SHADA_ENTRY(entry) \ do { \ - if (entry.can_free_entry) { \ - shada_free_shada_entry(&entry.data); \ + if ((entry).can_free_entry) { \ + shada_free_shada_entry(&(entry).data); \ } \ } while (0) #define SDE_TO_PFSDE(entry) \ - ((PossiblyFreedShadaEntry) { .can_free_entry = true, .data = entry }) + ((PossiblyFreedShadaEntry) { .can_free_entry = true, .data = (entry) }) #define AFTERFREE_DUMMY(entry) #define DUMMY_IDX_ADJ(i) MERGE_JUMPS(filemarks->changes_size, filemarks->changes, @@ -2815,8 +2814,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, ShaDaReadDef #define PACK_WMS_ARRAY(wms_array) \ do { \ for (size_t i_ = 0; i_ < ARRAY_SIZE(wms_array); i_++) { \ - if (wms_array[i_].data.type != kSDItemMissing) { \ - if (shada_pack_pfreed_entry(packer, wms_array[i_], max_kbyte) \ + if ((wms_array)[i_].data.type != kSDItemMissing) { \ + if (shada_pack_pfreed_entry(packer, (wms_array)[i_], max_kbyte) \ == kSDWriteFailed) { \ ret = kSDWriteFailed; \ goto shada_write_exit; \ @@ -2836,7 +2835,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, ShaDaReadDef } #define PACK_WMS_ENTRY(wms_entry) \ do { \ - if (wms_entry.data.type != kSDItemMissing) { \ + if ((wms_entry).data.type != kSDItemMissing) { \ if (shada_pack_pfreed_entry(packer, wms_entry, max_kbyte) \ == kSDWriteFailed) { \ ret = kSDWriteFailed; \ @@ -3313,16 +3312,16 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader, const RERR "Error while reading ShaDa file: " \ entry_name " entry at position %" PRIu64 " " \ error_desc -#define CHECK_KEY(key, expected) ( \ - key.via.str.size == sizeof(expected) - 1 \ - && STRNCMP(key.via.str.ptr, expected, sizeof(expected) - 1) == 0) +#define CHECK_KEY(key, \ + expected) ((key).via.str.size == (sizeof(expected) - 1) \ + && STRNCMP((key).via.str.ptr, expected, (sizeof(expected) - 1)) == 0) #define CLEAR_GA_AND_ERROR_OUT(ga) \ do { \ - ga_clear(&ga); \ + ga_clear(&(ga)); \ goto shada_read_next_item_error; \ } while (0) #define ID(s) s -#define BINDUP(b) xmemdupz(b.ptr, b.size) +#define BINDUP(b) xmemdupz((b).ptr, (b).size) #define TOINT(s) ((int)(s)) #define TOLONG(s) ((long)(s)) #define TOCHAR(s) ((char)(s)) @@ -3335,28 +3334,31 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader, const semsg(_(READERR(entry_name, error_desc)), initial_fpos); \ CLEAR_GA_AND_ERROR_OUT(ad_ga); \ } \ - tgt = proc(obj.via.attr); \ + (tgt) = proc((obj).via.attr); \ } while (0) #define CHECK_KEY_IS_STR(un, entry_name) \ - if (un.data.via.map.ptr[i].key.type != MSGPACK_OBJECT_STR) { \ + if ((un).data.via.map.ptr[i].key.type != MSGPACK_OBJECT_STR) { \ semsg(_(READERR(entry_name, "has key which is not a string")), \ initial_fpos); \ CLEAR_GA_AND_ERROR_OUT(ad_ga); \ - } else if (un.data.via.map.ptr[i].key.via.str.size == 0) { \ + } else if ((un).data.via.map.ptr[i].key.via.str.size == 0) { \ semsg(_(READERR(entry_name, "has empty key")), initial_fpos); \ CLEAR_GA_AND_ERROR_OUT(ad_ga); \ } -#define CHECKED_KEY(un, entry_name, name, error_desc, tgt, condition, attr, \ - proc) \ - else if (CHECK_KEY( /* NOLINT(readability/braces) */ \ - un.data.via.map.ptr[i].key, name)) { \ - CHECKED_ENTRY(condition, "has " name " key value " error_desc, \ - entry_name, un.data.via.map.ptr[i].val, \ - tgt, attr, proc); \ +#define CHECKED_KEY(un, entry_name, name, error_desc, tgt, condition, attr, proc) \ + else if (CHECK_KEY((un).data.via.map.ptr[i].key, name)) /* NOLINT(readability/braces) */ \ + { \ + CHECKED_ENTRY(condition, \ + "has " name " key value " error_desc, \ + entry_name, \ + (un).data.via.map.ptr[i].val, \ + tgt, \ + attr, \ + proc); \ } #define TYPED_KEY(un, entry_name, name, type_name, tgt, objtype, attr, proc) \ CHECKED_KEY(un, entry_name, name, "which is not " type_name, tgt, \ - un.data.via.map.ptr[i].val.type == MSGPACK_OBJECT_##objtype, \ + (un).data.via.map.ptr[i].val.type == MSGPACK_OBJECT_##objtype, \ attr, proc) #define BOOLEAN_KEY(un, entry_name, name, tgt) \ TYPED_KEY(un, entry_name, name, "a boolean", tgt, BOOLEAN, boolean, ID) @@ -3367,9 +3369,9 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader, const BIN_CONVERTED) #define INT_KEY(un, entry_name, name, tgt, proc) \ CHECKED_KEY(un, entry_name, name, "which is not an integer", tgt, \ - ((un.data.via.map.ptr[i].val.type \ + (((un).data.via.map.ptr[i].val.type \ == MSGPACK_OBJECT_POSITIVE_INTEGER) \ - || (un.data.via.map.ptr[i].val.type \ + || ((un).data.via.map.ptr[i].val.type \ == MSGPACK_OBJECT_NEGATIVE_INTEGER)), \ i64, proc) #define INTEGER_KEY(un, entry_name, name, tgt) \ @@ -3380,12 +3382,12 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader, const else { /* NOLINT(readability/braces) */ \ ga_grow(&ad_ga, 1); \ memcpy(((char *)ad_ga.ga_data) + ((size_t)ad_ga.ga_len \ - * sizeof(*un.data.via.map.ptr)), \ - un.data.via.map.ptr + i, \ - sizeof(*un.data.via.map.ptr)); \ + * sizeof(*(un).data.via.map.ptr)), \ + (un).data.via.map.ptr + i, \ + sizeof(*(un).data.via.map.ptr)); \ ad_ga.ga_len++; \ } -#define BIN_CONVERTED(b) (xmemdupz((b.ptr), (b.size))) +#define BIN_CONVERTED(b) (xmemdupz(((b).ptr), ((b).size))) #define SET_ADDITIONAL_DATA(tgt, name) \ do { \ if (ad_ga.ga_len) { \ @@ -3408,7 +3410,7 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader, const tv_clear(&adtv); \ goto shada_read_next_item_error; \ } \ - tgt = adtv.vval.v_dict; \ + (tgt) = adtv.vval.v_dict; \ } \ ga_clear(&ad_ga); \ } while (0) diff --git a/src/nvim/sign.c b/src/nvim/sign.c index dd6fdf3cd5..f61dd53c2a 100644 --- a/src/nvim/sign.c +++ b/src/nvim/sign.c @@ -59,7 +59,6 @@ static char *cmds[] = { #define SIGNCMD_LAST 6 }; - static hashtab_T sg_table; // sign group (signgroup_T) hashtable static int next_sign_id = 1; // next sign id in the global group @@ -361,7 +360,6 @@ static void sign_sort_by_prio_on_line(buf_T *buf, sign_entry_T *sign) } } - /// Add the sign into the signlist. Find the right spot to do it though. /// /// @param buf buffer to store sign in @@ -586,7 +584,6 @@ static linenr_T buf_delsign(buf_T *buf, linenr_T atlnum, int id, char_u *group) return lnum; } - /// Find the line number of the sign with the requested id in group 'group'. If /// the sign does not exist, return 0 as the line number. This will still let /// the correct file get loaded. diff --git a/src/nvim/sign.h b/src/nvim/sign.h index 6e75a4e62b..c61e5d20ef 100644 --- a/src/nvim/sign.h +++ b/src/nvim/sign.h @@ -8,7 +8,6 @@ #include "nvim/ex_cmds_defs.h" #include "nvim/sign_defs.h" - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "sign.h.generated.h" #endif diff --git a/src/nvim/sign_defs.h b/src/nvim/sign_defs.h index 6d28c1849a..e4ece71846 100644 --- a/src/nvim/sign_defs.h +++ b/src/nvim/sign_defs.h @@ -55,5 +55,4 @@ typedef enum { SIGN_TEXT, } SignType; - #endif // NVIM_SIGN_DEFS_H diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 1ba29e3fc1..8f84204481 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -301,7 +301,6 @@ typedef struct { int score; } limitscore_T; - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "spell.c.generated.h" #endif @@ -443,7 +442,7 @@ size_t spell_check(win_T *wp, char_u *ptr, hlf_T *attrp, int *capcol, bool docou MAXWLEN + 1); mi.mi_fwordlen = (int)STRLEN(mi.mi_fword); - if (camel_case) { + if (camel_case && mi.mi_fwordlen > 0) { // introduce a fake word end space into the folded word. mi.mi_fword[mi.mi_fwordlen - 1] = ' '; } @@ -1303,7 +1302,6 @@ static void find_prefix(matchinf_T *mip, int mode) mip->mi_word); find_word(mip, FIND_PREFIX); - if (len == 0) { break; // no children, word must end here } @@ -2550,7 +2548,6 @@ void spell_reload(void) } } - // Opposite of offset2bytes(). // "pp" points to the bytes and is advanced over it. // Returns the offset. @@ -3138,7 +3135,6 @@ static bool check_need_cap(linenr_T lnum, colnr_T col) return need_cap; } - // ":spellrepall" void ex_spellrepall(exarg_T *eap) { @@ -3523,7 +3519,7 @@ static void spell_suggest_intern(suginfo_T *su, bool interactive) // Free the info put in "*su" by spell_find_suggest(). static void spell_find_cleanup(suginfo_T *su) { -#define FREE_SUG_WORD(sug) xfree(sug->st_word) +#define FREE_SUG_WORD(sug) xfree((sug)->st_word) // Free the suggestions. GA_DEEP_CLEAR(&su->su_ga, suggest_T, FREE_SUG_WORD); GA_DEEP_CLEAR(&su->su_sga, suggest_T, FREE_SUG_WORD); @@ -4937,7 +4933,6 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so } } - // Go one level deeper in the tree. static void go_deeper(trystate_T *stack, int depth, int score_add) { @@ -5834,7 +5829,6 @@ static void check_suggestions(suginfo_T *su, garray_T *gap) } } - // Add a word to be banned. static void add_banned(suginfo_T *su, char_u *word) { @@ -5888,7 +5882,6 @@ static void rescore_one(suginfo_T *su, suggest_T *stp) } } - // Function given to qsort() to sort the suggestions on st_score. // First on "st_score", then "st_altscore" then alphabetically. static int sug_compare(const void *s1, const void *s2) @@ -6069,7 +6062,6 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res) bool did_white = false; int wordlen; - // Convert the multi-byte string to a wide-character string. // Remove accents, if wanted. We actually remove all non-word characters. // But keep white space. diff --git a/src/nvim/spell_defs.h b/src/nvim/spell_defs.h index 12e44cb7ff..7e85b5bf03 100644 --- a/src/nvim/spell_defs.h +++ b/src/nvim/spell_defs.h @@ -60,7 +60,6 @@ typedef int idx_T; #define WF_PFX_COMPFORBID (WFP_COMPFORBID << 24) // postponed prefix with // COMPOUNDFORBIDFLAG - // flags for <compoptions> #define COMP_CHECKDUP 1 // CHECKCOMPOUNDDUP #define COMP_CHECKREP 2 // CHECKCOMPOUNDREP diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index f8c01bc27f..2b6bb098d1 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -638,7 +638,6 @@ slang_T *spell_load_file(char_u *fname, char_u *lang, slang_T *old_lp, bool sile goto endFAIL; } - // <SECTIONS>: <section> ... <sectionend> // <section>: <sectionID> <sectionflags> <sectionlen> (section contents) for (;;) { @@ -992,7 +991,6 @@ nextone: } } - // Read a length field from "fd" in "cnt_bytes" bytes. // Allocate memory, read the string into it and add a NUL at the end. // Returns NULL when the count is zero. @@ -3886,7 +3884,6 @@ static char_u *getroom_save(spellinfo_T *spin, char_u *s) return memcpy(getroom(spin, s_size, false), s, s_size); } - // Free the list of allocated sblock_T. static void free_blocks(sblock_T *bl) { @@ -4338,7 +4335,6 @@ static bool node_equal(wordnode_T *n1, wordnode_T *n2) return p1 == NULL && p2 == NULL; } - // Function given to qsort() to sort the REP items on "from" string. static int rep_compare(const void *s1, const void *s2) { @@ -4685,7 +4681,6 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) // end of <SECTIONS> putc(SN_END, fd); // <sectionend> - // <LWORDTREE> <KWORDTREE> <PREFIXTREE> spin->si_memtot = 0; for (unsigned int round = 1; round <= 3; ++round) { @@ -4753,7 +4748,6 @@ static void clear_node(wordnode_T *node) } } - /// Dump a word tree at node "node". /// /// This first writes the list of possible bytes (siblings). Then for each @@ -4872,7 +4866,6 @@ static int put_node(FILE *fd, wordnode_T *node, int idx, int regionmask, bool pr return newindex; } - // ":mkspell [-ascii] outfile infile ..." // ":mkspell [-ascii] addfile" void ex_mkspell(exarg_T *eap) @@ -5260,7 +5253,6 @@ theend: fclose(fd); } - /// Create a Vim spell file from one or more word lists. /// "fnames[0]" is the output file name. /// "fnames[fcount - 1]" is the last input file name. diff --git a/src/nvim/state.c b/src/nvim/state.c index 36789016a9..f6d9b535fc 100644 --- a/src/nvim/state.c +++ b/src/nvim/state.c @@ -24,7 +24,6 @@ # include "state.c.generated.h" #endif - void state_enter(VimState *s) { for (;;) { @@ -122,7 +121,6 @@ void state_handle_k_event(void) } } - /// Return true if in the current mode we need to use virtual. bool virtual_active(void) { diff --git a/src/nvim/strings.c b/src/nvim/strings.c index c0c942ffd2..5c2721536d 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -146,7 +146,7 @@ char *vim_strnsave_unquoted(const char *const string, const size_t length) FUNC_ATTR_NONNULL_RET { #define ESCAPE_COND(p, inquote, string_end) \ - (*p == '\\' && inquote && p + 1 < string_end && (p[1] == '\\' || p[1] == '"')) + (*(p) == '\\' && (inquote) && (p) + 1 < (string_end) && ((p)[1] == '\\' || (p)[1] == '"')) size_t ret_length = 0; bool inquote = false; const char *const string_end = string + length; @@ -553,7 +553,6 @@ char_u *concat_str(const char_u *restrict str1, const char_u *restrict str2) return dest; } - static const char *const e_printf = N_("E766: Insufficient arguments for printf()"); @@ -634,12 +633,12 @@ static const void *tv_ptr(const typval_T *const tvs, int *const idxp) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { #define OFF(attr) offsetof(union typval_vval_union, attr) - STATIC_ASSERT(OFF(v_string) == OFF(v_list) + STATIC_ASSERT(OFF(v_string) == OFF(v_list) // -V568 && OFF(v_string) == OFF(v_dict) && OFF(v_string) == OFF(v_partial) - && sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_list) // -V568 - && sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_dict) // -V568 - && sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_partial), // -V568 + && sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_list) + && sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_dict) + && sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_partial), "Strings, dictionaries, lists and partials are expected to be pointers, " "so that all three of them can be accessed via v_string"); #undef OFF @@ -1496,6 +1495,7 @@ int kv_do_printf(StringBuilder *str, const char *fmt, ...) // printed string didn't fit, resize and try again if ((size_t)printed >= remaining) { kv_ensure_space(*str, (size_t)printed + 1); // include space for NUL terminator at the end + assert(str->items != NULL); va_start(ap, fmt); printed = vsnprintf(str->items + str->size, str->capacity - str->size, fmt, ap); va_end(ap); @@ -1507,3 +1507,24 @@ int kv_do_printf(StringBuilder *str, const char *fmt, ...) str->size += (size_t)printed; return printed; } + +/// Reverse text into allocated memory. +/// +/// @return the allocated string. +char_u *reverse_text(char_u *s) + FUNC_ATTR_NONNULL_RET +{ + // Reverse the pattern. + size_t len = STRLEN(s); + char_u *rev = xmalloc(len + 1); + size_t rev_i = len; + for (size_t s_i = 0; s_i < len; s_i++) { + const int mb_len = utfc_ptr2len((char *)s + s_i); + rev_i -= (size_t)mb_len; + memmove(rev + rev_i, s + s_i, (size_t)mb_len); + s_i += (size_t)mb_len - 1; + } + rev[len] = NUL; + + return rev; +} diff --git a/src/nvim/strings.h b/src/nvim/strings.h index 0503cecc8a..9ef1eb5816 100644 --- a/src/nvim/strings.h +++ b/src/nvim/strings.h @@ -6,8 +6,8 @@ #include <string.h> #include "nvim/eval/typval.h" -#include "nvim/types.h" #include "nvim/lib/kvec.h" +#include "nvim/types.h" /// Append string to string and return pointer to the next byte /// diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 6744e4445c..47305b6709 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -95,7 +95,6 @@ typedef struct syn_pattern { syn_time_T sp_time; } synpat_T; - typedef struct syn_cluster_S { char_u *scl_name; // syntax cluster name char_u *scl_name_u; // uppercase of scl_name @@ -178,7 +177,6 @@ static char *(spo_name_tab[SPO_COUNT]) = #define SPTYPE_END 3 // match a regexp, end of item #define SPTYPE_SKIP 4 // match a regexp, skip within item - #define SYN_ITEMS(buf) ((synpat_T *)((buf)->b_syn_patterns.ga_data)) #define NONE_IDX (-2) // value of sp_sync_idx for "NONE" @@ -2094,7 +2092,6 @@ static int syn_current_attr(const bool syncing, const bool displaying, bool *con } } - /* * Check for end of current state (and the states before it) at the * next column. Don't do this for syncing, because we would miss a @@ -2140,7 +2137,6 @@ static int syn_current_attr(const bool syncing, const bool displaying, bool *con return current_attr; } - /// @return true if we already matched pattern "idx" at the current column. static bool did_match_already(int idx, garray_T *gap) { @@ -3607,7 +3603,6 @@ static void syn_match_msg(void) static int last_matchgroup; - /// List one syntax item, for ":syntax" or "syntax list syntax_name". /// /// @param syncing when true: list syncing items @@ -5694,7 +5689,6 @@ bool syntax_present(win_T *win) || win->w_s->b_keywtab_ic.ht_used > 0; } - static enum { EXP_SUBCMD, // expand ":syn" sub-commands EXP_CASE, // expand ":syn case" arguments @@ -5788,7 +5782,6 @@ char *get_syntax_name(expand_T *xp, int idx) return NULL; } - /// Function called for expression evaluation: get syntax ID at file position. /// /// @param trans remove transparency @@ -5823,7 +5816,6 @@ int get_syntax_info(int *seqnrp) return current_flags; } - /// Get the sequence number of the concealed file position. /// /// @return seqnr if the file position is concealed, 0 otherwise. diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 8a21ec3e5d..73b5bb4058 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -99,7 +99,6 @@ static char *mt_names[MT_COUNT/2] = #define NOTAGFILE 99 // return value for jumpto_tag static char_u *nofile_fname = NULL; // fname for NOTAGFILE error - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "tag.c.generated.h" #endif @@ -603,7 +602,6 @@ bool do_tag(char_u *tag, int type, int count, int forceit, int verbose) smsg(_("File \"%s\" does not exist"), nofile_fname); } - ic = (matches[cur_match][0] & MT_IC_OFF); if (type != DT_TAG && type != DT_SELECT && type != DT_JUMP && type != DT_CSCOPE @@ -1064,7 +1062,6 @@ void do_tags(exarg_T *eap) } } - /* * Compare two strings, for length "len", ignoring case the ASCII way. * return 0 for match, < 0 for smaller, > 0 for bigger @@ -1089,7 +1086,6 @@ static int tag_strnicmp(char_u *s1, char_u *s2, size_t len) return 0; // strings match } - /* * Extract info from the tag search pattern "pats->pat". */ @@ -1410,7 +1406,6 @@ int find_tags(char_u *pat, int *num_matches, char_u ***matchesp, int flags, int int matchoff = 0; int save_emsg_off; - char_u *mfp; garray_T ga_match[MT_COUNT]; // stores matches in sequence hashtab_T ht_match[MT_COUNT]; // stores matches by key @@ -1752,7 +1747,6 @@ line_read_in: } } - /* * When still at the start of the file, check for Emacs tags file * format, and for "not sorted" flag. @@ -2723,7 +2717,6 @@ static int jumpto_tag(const char_u *lbuf_arg, int forceit, int keep_help) ++RedrawingDisabled; - if (l_g_do_tagpreview != 0) { postponed_split = 0; // don't split again below curwin_save = curwin; // Save current window @@ -3148,7 +3141,6 @@ int expand_tags(int tagnames, char_u *pat, int *num_file, char_u ***file) return ret; } - /// Add a tag field to the dictionary "dict". /// Return OK or FAIL. /// diff --git a/src/nvim/tag.h b/src/nvim/tag.h index 902fe0c7ba..c8051e1dcc 100644 --- a/src/nvim/tag.h +++ b/src/nvim/tag.h @@ -41,7 +41,6 @@ typedef struct { void *tn_search_ctx; } tagname_T; - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "tag.h.generated.h" #endif diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 2d3102707c..e4262c2ca9 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -359,7 +359,6 @@ void terminal_check_size(Terminal *term) vterm_get_size(term->vt, &curheight, &curwidth); uint16_t width = 0, height = 0; - FOR_ALL_TAB_WINDOWS(tp, wp) { if (wp->w_buffer && wp->w_buffer->terminal == term) { const uint16_t win_width = @@ -722,7 +721,6 @@ static int get_rgb(VTermState *state, VTermColor color) return RGB_(color.rgb.red, color.rgb.green, color.rgb.blue); } - void terminal_get_line_attributes(Terminal *term, win_T *wp, int linenr, int *term_attrs) { int height, width; @@ -1364,7 +1362,6 @@ end: // }}} // terminal buffer refresh & misc {{{ - static void fetch_row(Terminal *term, int row, int end_col) { int col = 0; @@ -1374,26 +1371,21 @@ static void fetch_row(Terminal *term, int row, int end_col) while (col < end_col) { VTermScreenCell cell; fetch_cell(term, row, col, &cell); - int cell_len = 0; if (cell.chars[0]) { + int cell_len = 0; for (int i = 0; cell.chars[i]; i++) { cell_len += utf_char2bytes((int)cell.chars[i], ptr + cell_len); } - } else { - *ptr = ' '; - cell_len = 1; - } - char c = *ptr; - ptr += cell_len; - if (c != ' ') { - // only increase the line length if the last character is not whitespace + ptr += cell_len; line_len = (size_t)(ptr - term->textbuf); + } else { + *ptr++ = ' '; } col += cell.width; } - // trim trailing whitespace - term->textbuf[line_len] = 0; + // end of line + term->textbuf[line_len] = NUL; } static bool fetch_cell(Terminal *term, int row, int col, VTermScreenCell *cell) diff --git a/src/nvim/testdir/test_bufline.vim b/src/nvim/testdir/test_bufline.vim index 765ae17736..ffb8e3facd 100644 --- a/src/nvim/testdir/test_bufline.vim +++ b/src/nvim/testdir/test_bufline.vim @@ -153,3 +153,38 @@ func Test_appendbufline_redraw() call StopVimInTerminal(buf) call delete('XscriptMatchCommon') endfunc + +func Test_setbufline_select_mode() + new + call setline(1, ['foo', 'bar']) + call feedkeys("j^v2l\<C-G>", 'nx') + + let bufnr = bufadd('Xdummy') + call bufload(bufnr) + call setbufline(bufnr, 1, ['abc']) + + call feedkeys("x", 'nx') + call assert_equal(['foo', 'x'], getline(1, 2)) + + exe "bwipe! " .. bufnr + bwipe! +endfunc + +func Test_deletebufline_select_mode() + new + call setline(1, ['foo', 'bar']) + call feedkeys("j^v2l\<C-G>", 'nx') + + let bufnr = bufadd('Xdummy') + call bufload(bufnr) + call setbufline(bufnr, 1, ['abc', 'def']) + call deletebufline(bufnr, 1) + + call feedkeys("x", 'nx') + call assert_equal(['foo', 'x'], getline(1, 2)) + + exe "bwipe! " .. bufnr + bwipe! +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim index 759caac878..b2c752376f 100644 --- a/src/nvim/testdir/test_cmdline.vim +++ b/src/nvim/testdir/test_cmdline.vim @@ -1224,4 +1224,16 @@ func Test_screenpos_and_completion() call feedkeys(":let a\<C-R>=Check_completion()\<CR>\<Esc>", "xt") endfunc +func Test_recursive_register() + let @= = '' + silent! ?e/ + let caught = 'no' + try + normal // + catch /E169:/ + let caught = 'yes' + endtry + call assert_equal('yes', caught) +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_cursor_func.vim b/src/nvim/testdir/test_cursor_func.vim index 9ba82e3b70..6c6a6290cb 100644 --- a/src/nvim/testdir/test_cursor_func.vim +++ b/src/nvim/testdir/test_cursor_func.vim @@ -102,10 +102,11 @@ func Test_screenpos() bwipe! call assert_equal({'col': 1, 'row': 1, 'endcol': 1, 'curscol': 1}, screenpos(win_getid(), 1, 1)) - " Needs WinBar " nmenu WinBar.TEST : - " call assert_equal({'col': 1, 'row': 2, 'endcol': 1, 'curscol': 1}, screenpos(win_getid(), 1, 1)) + setlocal winbar=TEST + call assert_equal({'col': 1, 'row': 2, 'endcol': 1, 'curscol': 1}, screenpos(win_getid(), 1, 1)) " nunmenu WinBar.TEST + setlocal winbar& endfunc func Test_screenpos_number() diff --git a/src/nvim/testdir/test_edit.vim b/src/nvim/testdir/test_edit.vim index 848666727f..275c8f7a15 100644 --- a/src/nvim/testdir/test_edit.vim +++ b/src/nvim/testdir/test_edit.vim @@ -16,8 +16,9 @@ func Test_edit_00b() call setline(1, ['abc ']) inoreabbr <buffer> h here some more call cursor(1, 4) - " <c-l> expands the abbreviation and ends insertmode - call feedkeys(":set im\<cr> h\<c-l>:set noim\<cr>", 'tix') + " <esc> expands the abbreviation and ends insert mode + " call feedkeys(":set im\<cr> h\<c-l>:set noim\<cr>", 'tix') + call feedkeys("i h\<esc>", 'tix') call assert_equal(['abc here some more '], getline(1,'$')) iunabbr <buffer> h bw! @@ -234,15 +235,18 @@ func Test_edit_09() call setline(1, ['abc', 'def', 'ghi']) call cursor(1, 1) " 1) CTRL-\ CTLR-N - call feedkeys(":set im\<cr>\<c-\>\<c-n>ccABC\<c-l>", 'txin') + " call feedkeys(":set im\<cr>\<c-\>\<c-n>ccABC\<c-l>", 'txin') + call feedkeys("i\<c-\>\<c-n>ccABC\<esc>", 'txin') call assert_equal(['ABC', 'def', 'ghi'], getline(1,'$')) call setline(1, ['ABC', 'def', 'ghi']) " 2) CTRL-\ CTLR-G - call feedkeys("j0\<c-\>\<c-g>ZZZ\<cr>\<c-l>", 'txin') - call assert_equal(['ABC', 'ZZZ', 'def', 'ghi'], getline(1,'$')) - call feedkeys("I\<c-\>\<c-g>YYY\<c-l>", 'txin') - call assert_equal(['ABC', 'ZZZ', 'YYYdef', 'ghi'], getline(1,'$')) - set noinsertmode + " CTRL-\ CTRL-G goes to Insert mode when 'insertmode' is set, but + " 'insertmode' is now removed so skip this test + " call feedkeys("j0\<c-\>\<c-g>ZZZ\<cr>\<esc>", 'txin') + " call assert_equal(['ABC', 'ZZZ', 'def', 'ghi'], getline(1,'$')) + " call feedkeys("I\<c-\>\<c-g>YYY\<c-l>", 'txin') + " call assert_equal(['ABC', 'ZZZ', 'YYYdef', 'ghi'], getline(1,'$')) + " set noinsertmode " 3) CTRL-\ CTRL-O call setline(1, ['ABC', 'ZZZ', 'def', 'ghi']) call cursor(1, 1) @@ -395,15 +399,13 @@ endfunc func Test_edit_13() " Test smartindenting - if exists("+smartindent") - new - set smartindent autoindent - call setline(1, ["\tabc"]) - call feedkeys("A {\<cr>more\<cr>}\<esc>", 'tnix') - call assert_equal(["\tabc {", "\t\tmore", "\t}"], getline(1, '$')) - set smartindent& autoindent& - bwipe! - endif + new + set smartindent autoindent + call setline(1, ["\tabc"]) + call feedkeys("A {\<cr>more\<cr>}\<esc>", 'tnix') + call assert_equal(["\tabc {", "\t\tmore", "\t}"], getline(1, '$')) + set smartindent& autoindent& + bwipe! " Test autoindent removing indent of blank line. new @@ -1045,7 +1047,8 @@ endfunc func Test_edit_F1() " Pressing <f1> new - call feedkeys(":set im\<cr>\<f1>\<c-l>", 'tnix') + " call feedkeys(":set im\<cr>\<f1>\<c-l>", 'tnix') + call feedkeys("i\<f1>\<esc>", 'tnix') set noinsertmode call assert_equal('help', &buftype) bw diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim index c0c35b89cb..4819c4877c 100644 --- a/src/nvim/testdir/test_filetype.vim +++ b/src/nvim/testdir/test_filetype.vim @@ -77,16 +77,16 @@ let s:filename_checks = { \ 'awk': ['file.awk', 'file.gawk'], \ 'b': ['file.mch', 'file.ref', 'file.imp'], \ 'basic': ['file.bas', 'file.bi', 'file.bm'], - \ 'bzl': ['file.bazel', 'file.bzl', 'WORKSPACE'], \ 'bc': ['file.bc'], \ 'bdf': ['file.bdf'], + \ 'beancount': ['file.beancount'], \ 'bib': ['file.bib'], \ 'bicep': ['file.bicep'], - \ 'beancount': ['file.beancount'], \ 'bindzone': ['named.root', '/bind/db.file', '/named/db.file', 'any/bind/db.file', 'any/named/db.file'], \ 'blank': ['file.bl'], \ 'bsdl': ['file.bsd', 'file.bsdl', 'bsd', 'some-bsd'], \ 'bst': ['file.bst'], + \ 'bzl': ['file.bazel', 'file.bzl', 'WORKSPACE'], \ 'bzr': ['bzr_log.any', 'bzr_log.file'], \ 'c': ['enlightenment/file.cfg', 'file.qc', 'file.c', 'some-enlightenment/file.cfg'], \ 'cabal': ['file.cabal'], @@ -109,6 +109,7 @@ let s:filename_checks = { \ 'clean': ['file.dcl', 'file.icl'], \ 'clojure': ['file.clj', 'file.cljs', 'file.cljx', 'file.cljc'], \ 'cmake': ['CMakeLists.txt', 'file.cmake', 'file.cmake.in'], + \ 'cmod': ['file.cmod'], \ 'cmusrc': ['any/.cmus/autosave', 'any/.cmus/rc', 'any/.cmus/command-history', 'any/.cmus/file.theme', 'any/cmus/rc', 'any/cmus/file.theme', '/.cmus/autosave', '/.cmus/command-history', '/.cmus/file.theme', '/.cmus/rc', '/cmus/file.theme', '/cmus/rc'], \ 'cobol': ['file.cbl', 'file.cob', 'file.lib'], \ 'coco': ['file.atg'], @@ -150,7 +151,7 @@ let s:filename_checks = { \ 'diff': ['file.diff', 'file.rej'], \ 'dircolors': ['.dir_colors', '.dircolors', '/etc/DIR_COLORS', 'any/etc/DIR_COLORS'], \ 'dnsmasq': ['/etc/dnsmasq.conf', '/etc/dnsmasq.d/file', 'any/etc/dnsmasq.conf', 'any/etc/dnsmasq.d/file'], - \ 'dockerfile': ['Containerfile', 'Dockerfile', 'file.Dockerfile', 'Dockerfile.debian', 'Containerfile.something'], + \ 'dockerfile': ['Containerfile', 'Dockerfile', 'dockerfile', 'file.Dockerfile', 'file.dockerfile', 'Dockerfile.debian', 'Containerfile.something'], \ 'dosbatch': ['file.bat'], \ 'dosini': ['.editorconfig', '/etc/yum.conf', 'file.ini', 'npmrc', '.npmrc', 'php.ini', 'php.ini-5', 'php.ini-file', '/etc/yum.repos.d/file', 'any/etc/yum.conf', 'any/etc/yum.repos.d/file', 'file.wrap'], \ 'dot': ['file.dot', 'file.gv'], @@ -164,9 +165,9 @@ let s:filename_checks = { \ 'dylanlid': ['file.lid'], \ 'ecd': ['file.ecd'], \ 'edif': ['file.edf', 'file.edif', 'file.edo'], + \ 'eelixir': ['file.eex', 'file.leex'], \ 'elinks': ['elinks.conf'], \ 'elixir': ['file.ex', 'file.exs', 'mix.lock'], - \ 'eelixir': ['file.eex', 'file.leex'], \ 'elm': ['file.elm'], \ 'elmfilt': ['filter-rules'], \ 'elvish': ['file.elv'], @@ -199,9 +200,9 @@ let s:filename_checks = { \ 'fusion': ['file.fusion'], \ 'fvwm': ['/.fvwm/file', 'any/.fvwm/file'], \ 'gdb': ['.gdbinit', 'gdbinit', 'file.gdb', '.config/gdbearlyinit', '.gdbearlyinit'], + \ 'gdmo': ['file.mo', 'file.gdmo'], \ 'gdresource': ['file.tscn', 'file.tres'], \ 'gdscript': ['file.gd'], - \ 'gdmo': ['file.mo', 'file.gdmo'], \ 'gedcom': ['file.ged', 'lltxxxxx.txt', '/tmp/lltmp', '/tmp/lltmp-file', 'any/tmp/lltmp', 'any/tmp/lltmp-file'], \ 'gemtext': ['file.gmi', 'file.gemini'], \ 'gift': ['file.gift'], @@ -237,31 +238,20 @@ let s:filename_checks = { \ 'hastepreproc': ['file.htpp'], \ 'hb': ['file.hb'], \ 'hcl': ['file.hcl'], - \ 'hercules': ['file.vc', 'file.ev', 'file.sum', 'file.errsum'], \ 'heex': ['file.heex'], + \ 'hercules': ['file.vc', 'file.ev', 'file.sum', 'file.errsum'], \ 'hex': ['file.hex', 'file.h32'], \ 'hgcommit': ['hg-editor-file.txt'], \ 'hjson': ['file.hjson'], \ 'hog': ['file.hog', 'snort.conf', 'vision.conf'], \ 'hollywood': ['file.hws'], + \ 'hoon': ['file.hoon'], \ 'hostconf': ['/etc/host.conf', 'any/etc/host.conf'], \ 'hostsaccess': ['/etc/hosts.allow', '/etc/hosts.deny', 'any/etc/hosts.allow', 'any/etc/hosts.deny'], - \ 'i3config': ['/home/user/.i3/config', '/home/user/.config/i3/config', '/etc/i3/config', '/etc/xdg/i3/config'], - \ 'logcheck': ['/etc/logcheck/file.d-some/file', '/etc/logcheck/file.d/file', 'any/etc/logcheck/file.d-some/file', 'any/etc/logcheck/file.d/file'], - \ 'modula3': ['file.m3', 'file.mg', 'file.i3', 'file.ig'], - \ 'natural': ['file.NSA', 'file.NSC', 'file.NSG', 'file.NSL', 'file.NSM', 'file.NSN', 'file.NSP', 'file.NSS'], - \ 'neomuttrc': ['Neomuttrc', '.neomuttrc', '.neomuttrc-file', '/.neomutt/neomuttrc', '/.neomutt/neomuttrc-file', 'Neomuttrc', 'Neomuttrc-file', 'any/.neomutt/neomuttrc', 'any/.neomutt/neomuttrc-file', 'neomuttrc', 'neomuttrc-file'], - \ 'opl': ['file.OPL', 'file.OPl', 'file.OpL', 'file.Opl', 'file.oPL', 'file.oPl', 'file.opL', 'file.opl'], - \ 'pcmk': ['file.pcmk'], - \ 'r': ['file.r'], - \ 'rhelp': ['file.rd'], - \ 'rmd': ['file.rmd', 'file.smd'], - \ 'rnoweb': ['file.rnw', 'file.snw'], - \ 'rrst': ['file.rrst', 'file.srst'], - \ 'template': ['file.tmpl'], \ 'html': ['file.html', 'file.htm', 'file.cshtml'], \ 'htmlm4': ['file.html.m4'], \ 'httest': ['file.htt', 'file.htb'], + \ 'i3config': ['/home/user/.i3/config', '/home/user/.config/i3/config', '/etc/i3/config', '/etc/xdg/i3/config'], \ 'ibasic': ['file.iba', 'file.ibi'], \ 'icemenu': ['/.icewm/menu', 'any/.icewm/menu'], \ 'icon': ['file.icn'], @@ -314,17 +304,18 @@ let s:filename_checks = { \ 'lisp': ['file.lsp', 'file.lisp', 'file.asd', 'file.el', 'file.cl', '.emacs', '.sawfishrc', 'sbclrc', '.sbclrc'], \ 'lite': ['file.lite', 'file.lt'], \ 'litestep': ['/LiteStep/any/file.rc', 'any/LiteStep/any/file.rc'], + \ 'logcheck': ['/etc/logcheck/file.d-some/file', '/etc/logcheck/file.d/file', 'any/etc/logcheck/file.d-some/file', 'any/etc/logcheck/file.d/file'], \ 'loginaccess': ['/etc/login.access', 'any/etc/login.access'], \ 'logindefs': ['/etc/login.defs', 'any/etc/login.defs'], \ 'logtalk': ['file.lgt'], \ 'lotos': ['file.lot', 'file.lotos'], \ 'lout': ['file.lou', 'file.lout'], + \ 'lpc': ['file.lpc', 'file.ulpc'], \ 'lprolog': ['file.sig'], \ 'lsl': ['file.lsl'], \ 'lss': ['file.lss'], \ 'lua': ['file.lua', 'file.rockspec', 'file.nse'], \ 'lynx': ['lynx.cfg'], - \ 'matlab': ['file.m'], \ 'm3build': ['m3makefile', 'm3overrides'], \ 'm3quake': ['file.quake', 'cm3.cfg'], \ 'm4': ['file.at'], @@ -339,6 +330,7 @@ let s:filename_checks = { \ 'markdown': ['file.markdown', 'file.mdown', 'file.mkd', 'file.mkdn', 'file.mdwn', 'file.md'], \ 'mason': ['file.mason', 'file.mhtml', 'file.comp'], \ 'master': ['file.mas', 'file.master'], + \ 'matlab': ['file.m'], \ 'maxima': ['file.demo', 'file.dmt', 'file.dm1', 'file.dm2', 'file.dm3', \ 'file.wxm', 'maxima-init.mac'], \ 'mel': ['file.mel'], @@ -359,8 +351,10 @@ let s:filename_checks = { \ 'mmp': ['file.mmp'], \ 'modconf': ['/etc/modules.conf', '/etc/modules', '/etc/conf.modules', '/etc/modprobe.file', 'any/etc/conf.modules', 'any/etc/modprobe.file', 'any/etc/modules', 'any/etc/modules.conf'], \ 'modula2': ['file.m2', 'file.mi'], + \ 'modula3': ['file.m3', 'file.mg', 'file.i3', 'file.ig'], \ 'monk': ['file.isc', 'file.monk', 'file.ssc', 'file.tsc'], \ 'moo': ['file.moo'], + \ 'moonscript': ['file.moon'], \ 'mp': ['file.mp'], \ 'mplayerconf': ['mplayer.conf', '/.mplayer/config', 'any/.mplayer/config'], \ 'mrxvtrc': ['mrxvtrc', '.mrxvtrc'], @@ -373,7 +367,9 @@ let s:filename_checks = { \ 'n1ql': ['file.n1ql', 'file.nql'], \ 'named': ['namedfile.conf', 'rndcfile.conf', 'named-file.conf', 'named.conf', 'rndc-file.conf', 'rndc-file.key', 'rndc.conf', 'rndc.key'], \ 'nanorc': ['/etc/nanorc', 'file.nanorc', 'any/etc/nanorc'], + \ 'natural': ['file.NSA', 'file.NSC', 'file.NSG', 'file.NSL', 'file.NSM', 'file.NSN', 'file.NSP', 'file.NSS'], \ 'ncf': ['file.ncf'], + \ 'neomuttrc': ['Neomuttrc', '.neomuttrc', '.neomuttrc-file', '/.neomutt/neomuttrc', '/.neomutt/neomuttrc-file', 'Neomuttrc', 'Neomuttrc-file', 'any/.neomutt/neomuttrc', 'any/.neomutt/neomuttrc-file', 'neomuttrc', 'neomuttrc-file'], \ 'netrc': ['.netrc'], \ 'nginx': ['file.nginx', 'nginxfile.conf', 'filenginx.conf', 'any/etc/nginx/file', 'any/usr/local/nginx/conf/file', 'any/nginx/file.conf'], \ 'ninja': ['file.ninja'], @@ -389,6 +385,7 @@ let s:filename_checks = { \ 'opam': ['opam', 'file.opam', 'file.opam.template'], \ 'openroad': ['file.or'], \ 'openscad': ['file.scad'], + \ 'opl': ['file.OPL', 'file.OPl', 'file.OpL', 'file.Opl', 'file.oPL', 'file.oPl', 'file.opL', 'file.opl'], \ 'ora': ['file.ora'], \ 'org': ['file.org', 'file.org_archive'], \ 'pamconf': ['/etc/pam.conf', '/etc/pam.d/file', 'any/etc/pam.conf', 'any/etc/pam.d/file'], @@ -398,14 +395,13 @@ let s:filename_checks = { \ 'passwd': ['any/etc/passwd', 'any/etc/passwd-', 'any/etc/passwd.edit', 'any/etc/shadow', 'any/etc/shadow-', 'any/etc/shadow.edit', 'any/var/backups/passwd.bak', 'any/var/backups/shadow.bak', '/etc/passwd', '/etc/passwd-', '/etc/passwd.edit', '/etc/shadow', '/etc/shadow-', '/etc/shadow.edit', '/var/backups/passwd.bak', '/var/backups/shadow.bak'], \ 'pbtxt': ['file.pbtxt'], \ 'pccts': ['file.g'], + \ 'pcmk': ['file.pcmk'], \ 'pdf': ['file.pdf'], \ 'perl': ['file.plx', 'file.al', 'file.psgi', 'gitolite.rc', '.gitolite.rc', 'example.gitolite.rc'], \ 'pf': ['pf.conf'], \ 'pfmain': ['main.cf'], \ 'php': ['file.php', 'file.php9', 'file.phtml', 'file.ctp', 'file.phpt'], - \ 'lpc': ['file.lpc', 'file.ulpc'], \ 'pike': ['file.pike', 'file.pmod'], - \ 'cmod': ['file.cmod'], \ 'pilrc': ['file.rcp'], \ 'pine': ['.pinerc', 'pinerc', '.pinercex', 'pinercex'], \ 'pinfo': ['/etc/pinforc', '/.pinforc', 'any/.pinforc', 'any/etc/pinforc'], @@ -421,8 +417,8 @@ let s:filename_checks = { \ 'povini': ['.povrayrc'], \ 'ppd': ['file.ppd'], \ 'ppwiz': ['file.it', 'file.ih'], - \ 'privoxy': ['file.action'], \ 'prisma': ['file.prisma'], + \ 'privoxy': ['file.action'], \ 'proc': ['file.pc'], \ 'procmail': ['.procmail', '.procmailrc'], \ 'prolog': ['file.pdb'], @@ -440,27 +436,33 @@ let s:filename_checks = { \ 'python': ['file.py', 'file.pyw', '.pythonstartup', '.pythonrc', 'file.ptl', 'file.pyi', 'SConstruct'], \ 'ql': ['file.ql', 'file.qll'], \ 'quake': ['anybaseq2/file.cfg', 'anyid1/file.cfg', 'quake3/file.cfg', 'baseq2/file.cfg', 'id1/file.cfg', 'quake1/file.cfg', 'some-baseq2/file.cfg', 'some-id1/file.cfg', 'some-quake1/file.cfg'], + \ 'r': ['file.r'], \ 'radiance': ['file.rad', 'file.mat'], \ 'raku': ['file.pm6', 'file.p6', 'file.t6', 'file.pod6', 'file.raku', 'file.rakumod', 'file.rakudoc', 'file.rakutest'], + \ 'raml': ['file.raml'], \ 'ratpoison': ['.ratpoisonrc', 'ratpoisonrc'], \ 'rbs': ['file.rbs'], \ 'rc': ['file.rc', 'file.rch'], \ 'rcs': ['file,v'], \ 'readline': ['.inputrc', 'inputrc'], - \ 'remind': ['.reminders', 'file.remind', 'file.rem', '.reminders-file'], \ 'rego': ['file.rego'], + \ 'remind': ['.reminders', 'file.remind', 'file.rem', '.reminders-file'], \ 'rescript': ['file.res', 'file.resi'], \ 'resolv': ['resolv.conf'], \ 'reva': ['file.frt'], \ 'rexx': ['file.rex', 'file.orx', 'file.rxo', 'file.rxj', 'file.jrexx', 'file.rexxj', 'file.rexx', 'file.testGroup', 'file.testUnit'], + \ 'rhelp': ['file.rd'], \ 'rib': ['file.rib'], + \ 'rmd': ['file.rmd', 'file.smd'], \ 'rnc': ['file.rnc'], \ 'rng': ['file.rng'], + \ 'rnoweb': ['file.rnw', 'file.snw'], \ 'robot': ['file.robot', 'file.resource'], \ 'robots': ['robots.txt'], \ 'routeros': ['file.rsc'], \ 'rpcgen': ['file.x'], \ 'rpl': ['file.rpl'], + \ 'rrst': ['file.rrst', 'file.srst'], \ 'rst': ['file.rst'], \ 'rtf': ['file.rtf'], \ 'ruby': ['.irbrc', 'irbrc', 'file.rb', 'file.rbw', 'file.gemspec', 'file.ru', 'Gemfile', 'file.builder', 'file.rxml', 'file.rjs', 'file.rant', 'file.rake', 'rakefile', 'Rakefile', 'rantfile', 'Rantfile', 'rakefile-file', 'Rakefile-file', 'Puppetfile', 'Vagrantfile'], @@ -474,7 +476,6 @@ let s:filename_checks = { \ 'scheme': ['file.scm', 'file.ss', 'file.sld', 'file.rkt', 'file.rktd', 'file.rktl'], \ 'scilab': ['file.sci', 'file.sce'], \ 'screen': ['.screenrc', 'screenrc'], - \ 'sexplib': ['file.sexp'], \ 'scss': ['file.scss'], \ 'sd': ['file.sd'], \ 'sdc': ['file.sdc'], @@ -483,28 +484,29 @@ let s:filename_checks = { \ 'sensors': ['/etc/sensors.conf', '/etc/sensors3.conf', '/etc/sensors.d/file', 'any/etc/sensors.conf', 'any/etc/sensors3.conf', 'any/etc/sensors.d/file'], \ 'services': ['/etc/services', 'any/etc/services'], \ 'setserial': ['/etc/serial.conf', 'any/etc/serial.conf'], + \ 'sexplib': ['file.sexp'], \ 'sh': ['.bashrc', 'file.bash', '/usr/share/doc/bash-completion/filter.sh','/etc/udev/cdsymlinks.conf', 'any/etc/udev/cdsymlinks.conf'], \ 'sieve': ['file.siv', 'file.sieve'], + \ 'sil': ['file.sil'], \ 'simula': ['file.sim'], \ 'sinda': ['file.sin', 'file.s85'], \ 'sisu': ['file.sst', 'file.ssm', 'file.ssi', 'file.-sst', 'file._sst', 'file.sst.meta', 'file.-sst.meta', 'file._sst.meta'], \ 'skill': ['file.il', 'file.ils', 'file.cdf'], \ 'slang': ['file.sl'], \ 'slice': ['file.ice'], - \ 'solidity': ['file.sol'], - \ 'solution': ['file.sln'], \ 'slpconf': ['/etc/slp.conf', 'any/etc/slp.conf'], \ 'slpreg': ['/etc/slp.reg', 'any/etc/slp.reg'], \ 'slpspi': ['/etc/slp.spi', 'any/etc/slp.spi'], \ 'slrnrc': ['.slrnrc'], \ 'slrnsc': ['file.score'], \ 'sm': ['sendmail.cf'], - \ 'svelte': ['file.svelte'], \ 'smarty': ['file.tpl'], \ 'smcl': ['file.hlp', 'file.ihlp', 'file.smcl'], \ 'smith': ['file.smt', 'file.smith'], \ 'sml': ['file.sml'], \ 'snobol4': ['file.sno', 'file.spt'], + \ 'solidity': ['file.sol'], + \ 'solution': ['file.sln'], \ 'sparql': ['file.rq', 'file.sparql'], \ 'spec': ['file.spec'], \ 'spice': ['file.sp', 'file.spice'], @@ -524,11 +526,11 @@ let s:filename_checks = { \ 'sudoers': ['any/etc/sudoers', 'sudoers.tmp', '/etc/sudoers', 'any/etc/sudoers.d/file'], \ 'supercollider': ['file.quark'], \ 'surface': ['file.sface'], + \ 'svelte': ['file.svelte'], \ 'svg': ['file.svg'], \ 'svn': ['svn-commitfile.tmp', 'svn-commit-file.tmp', 'svn-commit.tmp'], \ 'swift': ['file.swift'], \ 'swiftgyb': ['file.swift.gyb'], - \ 'sil': ['file.sil'], \ 'sysctl': ['/etc/sysctl.conf', '/etc/sysctl.d/file.conf', 'any/etc/sysctl.conf', 'any/etc/sysctl.d/file.conf'], \ 'systemd': ['any/systemd/file.automount', 'any/systemd/file.dnssd', 'any/systemd/file.link', 'any/systemd/file.mount', 'any/systemd/file.netdev', 'any/systemd/file.network', 'any/systemd/file.nspawn', 'any/systemd/file.path', 'any/systemd/file.service', 'any/systemd/file.slice', 'any/systemd/file.socket', 'any/systemd/file.swap', 'any/systemd/file.target', 'any/systemd/file.timer', '/etc/systemd/some.conf.d/file.conf', '/etc/systemd/system/some.d/file.conf', '/etc/systemd/system/some.d/.#file', '/etc/systemd/system/.#otherfile', '/home/user/.config/systemd/user/some.d/mine.conf', '/home/user/.config/systemd/user/some.d/.#file', '/home/user/.config/systemd/user/.#otherfile', '/.config/systemd/user/.#', '/.config/systemd/user/.#-file', '/.config/systemd/user/file.d/.#', '/.config/systemd/user/file.d/.#-file', '/.config/systemd/user/file.d/file.conf', '/etc/systemd/file.conf.d/file.conf', '/etc/systemd/system/.#', '/etc/systemd/system/.#-file', '/etc/systemd/system/file.d/.#', '/etc/systemd/system/file.d/.#-file', '/etc/systemd/system/file.d/file.conf', '/systemd/file.automount', '/systemd/file.dnssd', '/systemd/file.link', '/systemd/file.mount', '/systemd/file.netdev', '/systemd/file.network', '/systemd/file.nspawn', '/systemd/file.path', '/systemd/file.service', '/systemd/file.slice', '/systemd/file.socket', '/systemd/file.swap', '/systemd/file.target', '/systemd/file.timer', 'any/.config/systemd/user/.#', 'any/.config/systemd/user/.#-file', 'any/.config/systemd/user/file.d/.#', 'any/.config/systemd/user/file.d/.#-file', 'any/.config/systemd/user/file.d/file.conf', 'any/etc/systemd/file.conf.d/file.conf', 'any/etc/systemd/system/.#', 'any/etc/systemd/system/.#-file', 'any/etc/systemd/system/file.d/.#', 'any/etc/systemd/system/file.d/.#-file', 'any/etc/systemd/system/file.d/file.conf'], \ 'systemverilog': ['file.sv', 'file.svh'], @@ -538,6 +540,7 @@ let s:filename_checks = { \ 'taskedit': ['file.task'], \ 'tcl': ['file.tcl', 'file.tm', 'file.tk', 'file.itcl', 'file.itk', 'file.jacl', '.tclshrc', 'tclsh.rc', '.wishrc'], \ 'teal': ['file.tl'], + \ 'template': ['file.tmpl'], \ 'teraterm': ['file.ttl'], \ 'terminfo': ['file.ti'], \ 'terraform': ['file.tfvars'], @@ -574,8 +577,8 @@ let s:filename_checks = { \ 'upstreamlog': ['fdrupstream.log', 'upstream.log', 'UPSTREAM.LOG', 'upstream.file.log', 'UPSTREAM.FILE.LOG', 'file.upstream.log', 'FILE.UPSTREAM.LOG', 'UPSTREAM-file.log', 'UPSTREAM-FILE.LOG'], \ 'usserverlog': ['usserver.log', 'USSERVER.LOG', 'usserver.file.log', 'USSERVER.FILE.LOG', 'file.usserver.log', 'FILE.USSERVER.LOG'], \ 'usw2kagtlog': ['usw2kagt.log', 'USW2KAGT.LOG', 'usw2kagt.file.log', 'USW2KAGT.FILE.LOG', 'file.usw2kagt.log', 'FILE.USW2KAGT.LOG'], - \ 'vb': ['file.sba', 'file.vb', 'file.vbs', 'file.dsm', 'file.ctl'], \ 'vala': ['file.vala'], + \ 'vb': ['file.sba', 'file.vb', 'file.vbs', 'file.dsm', 'file.ctl'], \ 'vera': ['file.vr', 'file.vri', 'file.vrh'], \ 'verilog': ['file.v'], \ 'verilogams': ['file.va', 'file.vams'], @@ -598,12 +601,12 @@ let s:filename_checks = { \ 'wsml': ['file.wsml'], \ 'wvdial': ['wvdial.conf', '.wvdialrc'], \ 'xdefaults': ['.Xdefaults', '.Xpdefaults', '.Xresources', 'xdm-config', 'file.ad', '/Xresources/file', '/app-defaults/file', 'Xresources', 'Xresources-file', 'any/Xresources/file', 'any/app-defaults/file'], + \ 'xf86conf': ['xorg.conf', 'xorg.conf-4'], \ 'xhtml': ['file.xhtml', 'file.xht'], \ 'xinetd': ['/etc/xinetd.conf', '/etc/xinetd.d/file', 'any/etc/xinetd.conf', 'any/etc/xinetd.d/file'], \ 'xmath': ['file.msc', 'file.msf'], \ 'xml': ['/etc/blkid.tab', '/etc/blkid.tab.old', 'file.xmi', 'file.csproj', 'file.csproj.user', 'file.fsproj', 'file.fsproj.user', 'file.vbproj', 'file.vbproj.user', 'file.ui', 'file.tpm', '/etc/xdg/menus/file.menu', 'fglrxrc', 'file.xlf', 'file.xliff', 'file.xul', 'file.wsdl', 'file.wpl', 'any/etc/blkid.tab', 'any/etc/blkid.tab.old', 'any/etc/xdg/menus/file.menu', 'file.atom', 'file.rss', 'file.cdxml', 'file.psc1', 'file.mpd'], \ 'xmodmap': ['anyXmodmap', 'Xmodmap', 'some-Xmodmap', 'some-xmodmap', 'some-xmodmap-file', 'xmodmap', 'xmodmap-file'], - \ 'xf86conf': ['xorg.conf', 'xorg.conf-4'], \ 'xpm': ['file.xpm'], \ 'xpm2': ['file.xpm2'], \ 'xquery': ['file.xq', 'file.xql', 'file.xqm', 'file.xquery', 'file.xqy'], @@ -613,7 +616,6 @@ let s:filename_checks = { \ 'yacc': ['file.yy', 'file.yxx', 'file.y++'], \ 'yaml': ['file.yaml', 'file.yml'], \ 'yang': ['file.yang'], - \ 'raml': ['file.raml'], \ 'z8a': ['file.z8a'], \ 'zig': ['file.zig'], \ 'zimbu': ['file.zu'], @@ -843,6 +845,7 @@ func Test_cfg_file() let ext = substitute(ext, '\(\l\)', '\u\1', '') endfor + " clean up filetype off endfunc diff --git a/src/nvim/testdir/test_fold.vim b/src/nvim/testdir/test_fold.vim index 9f5ad53adb..327f0f73f2 100644 --- a/src/nvim/testdir/test_fold.vim +++ b/src/nvim/testdir/test_fold.vim @@ -217,6 +217,26 @@ func Test_update_folds_expr_read() set foldmethod& foldexpr& endfunc +" Test for what patch 8.1.0535 fixes. +func Test_foldexpr_no_interrupt_addsub() + new + func! FoldFunc() + call setpos('.', getcurpos()) + return '=' + endfunc + + set foldmethod=expr + set foldexpr=FoldFunc() + call setline(1, '1.2') + + exe "norm! $\<C-A>" + call assert_equal('1.3', getline(1)) + + bwipe! + delfunc FoldFunc + set foldmethod& foldexpr& +endfunc + func Check_foldlevels(expected) call assert_equal(a:expected, map(range(1, line('$')), 'foldlevel(v:val)')) endfunc @@ -901,4 +921,72 @@ func Test_fold_split() bw! endfunc +" Make sure that when you append under a blank line that is under a fold with +" the same indent level as your appended line, the fold expands across the +" blank line +func Test_indent_append_under_blank_line() + new + let lines =<< trim END + line 1 + line 2 + line 3 + END + call setline(1, lines) + setlocal sw=2 + setlocal foldmethod=indent foldenable + call assert_equal([0, 1, 1], range(1, 3)->map('foldlevel(v:val)')) + call append(3, '') + call append(4, ' line 5') + call assert_equal([0, 1, 1, 1, 1], range(1, 5)->map('foldlevel(v:val)')) + bw! +endfunc + +" Make sure that when you delete 1 line of a fold whose length is 2 lines, the +" fold can't be closed since its length (1) is now less than foldminlines. +func Test_indent_one_line_fold_close() + let lines =<< trim END + line 1 + line 2 + line 3 + END + + new + setlocal sw=2 foldmethod=indent + call setline(1, lines) + " open all folds, delete line, then close all folds + normal zR + 3delete + normal zM + call assert_equal(-1, foldclosed(2)) " the fold should not be closed + + " Now do the same, but delete line 2 this time; this covers different code. + " (Combining this code with the above code doesn't expose both bugs.) + 1,$delete + call setline(1, lines) + normal zR + 2delete + normal zM + call assert_equal(-1, foldclosed(2)) + bw! +endfunc + +" Make sure that when appending [an indented line then a blank line] right +" before a single indented line, the resulting extended fold can be closed +func Test_indent_append_blank_small_fold_close() + new + setlocal sw=2 foldmethod=indent + " at first, the fold at the second line can't be closed since it's smaller + " than foldminlines + let lines =<< trim END + line 1 + line 4 + END + call setline(1, lines) + call append(1, [' line 2', '']) + " close all folds + normal zM + call assert_notequal(-1, foldclosed(2)) " the fold should be closed now + bw! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_mksession.vim b/src/nvim/testdir/test_mksession.vim index 5dbe2cd366..c55ba391a5 100644 --- a/src/nvim/testdir/test_mksession.vim +++ b/src/nvim/testdir/test_mksession.vim @@ -838,6 +838,30 @@ func Test_mksession_shortmess() set sessionoptions& endfunc +" Test that when Vim loading session has 'A' in 'shortmess' it does not +" complain about an existing swapfile. +func Test_mksession_shortmess_with_A() + edit Xtestfile + write + let fname = swapname('%') + " readblob() needs patch 8.2.2343 + " let cont = readblob(fname) + let cont = readfile(fname, 'B') + set sessionoptions-=options + mksession Xtestsession + bwipe! + + " Recreate the swap file to pretend the file is being edited + call writefile(cont, fname) + set shortmess+=A + source Xtestsession + + set shortmess& + set sessionoptions& + call delete('Xtestsession') + call delete(fname) +endfunc + " Test for mksession with 'compatible' option func Test_mksession_compatible() throw 'skipped: Nvim does not support "compatible" option' diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim index 1feffe1f8c..d1cb89bbd4 100644 --- a/src/nvim/testdir/test_normal.vim +++ b/src/nvim/testdir/test_normal.vim @@ -133,7 +133,8 @@ func Test_normal02_selectmode2() " some basic select mode tests call Setup_NewWindow() 50 - call feedkeys(":set im\n\<c-o>gHc\<c-o>:set noim\n", 'tx') + " call feedkeys(":set im\n\<c-o>gHc\<c-o>:set noim\n", 'tx') + call feedkeys("i\<c-o>gHc\<esc>", 'tx') call assert_equal('c51', getline('.')) " clean up bw! @@ -2113,11 +2114,11 @@ fun! Test_normal40_ctrl_bsl() call assert_equal('n', mode()) call assert_equal(1, col('.')) "imap <buffer> , <c-\><c-n> - set im + " set im exe ":norm! \<c-\>\<c-n>dw" - set noim + " set noim call assert_equal('are some words', getline(1)) - call assert_false(&insertmode) + " call assert_false(&insertmode) " clean up bw! diff --git a/src/nvim/testdir/test_put.vim b/src/nvim/testdir/test_put.vim index 65232175c6..ffdaa81e0b 100644 --- a/src/nvim/testdir/test_put.vim +++ b/src/nvim/testdir/test_put.vim @@ -203,3 +203,15 @@ func Test_multibyte_op_end_mark() call assert_equal([0, 2, 7, 0], getpos("']")) bwipe! endfunc + +" this was putting a mark before the start of a line +func Test_put_empty_register() + new + norm yy + norm [Pi00ggv)s0 + sil! norm [P + bwipe! +endfunc + + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_tagjump.vim b/src/nvim/testdir/test_tagjump.vim index e0b05edf15..2fe3c448d6 100644 --- a/src/nvim/testdir/test_tagjump.vim +++ b/src/nvim/testdir/test_tagjump.vim @@ -1077,6 +1077,15 @@ Type number and <Enter> (q or empty cancels): %bwipe endfunc +func Test_define_search() + " this was accessing freed memory + new + call setline(1, ['first line', '', '#define something 0']) + sil norm o0 + sil! norm + bwipe! +endfunc + " Test for the 'taglength' option func Test_tag_length() set tags=Xtags diff --git a/src/nvim/testdir/test_textformat.vim b/src/nvim/testdir/test_textformat.vim index 92705cb69f..748af199b2 100644 --- a/src/nvim/testdir/test_textformat.vim +++ b/src/nvim/testdir/test_textformat.vim @@ -289,11 +289,28 @@ func Test_format_c_comment() x END call assert_equal(expected, getline(1, '$')) + + " Comment is formatted when it wraps + normal 2GA with some more text added + let expected =<< trim END + nop; + val = val; // This is a comment + // with some more text + // added + x + END + call assert_equal(expected, getline(1, '$')) + set fo-=/ " using 'indentexpr' instead of 'cindent' does not repeat a comment setl nocindent indentexpr=2 - 3delete + %del + let text =<< trim END + nop; + val = val; // This is a comment + END + call setline(1, text) normal 2Gox let expected =<< trim END nop; diff --git a/src/nvim/testdir/test_textobjects.vim b/src/nvim/testdir/test_textobjects.vim index 8f8dfdc46d..81f2fea026 100644 --- a/src/nvim/testdir/test_textobjects.vim +++ b/src/nvim/testdir/test_textobjects.vim @@ -42,6 +42,24 @@ func Test_inner_block_with_cpo_M_right_backslash() call CpoM('(red (blue\) green)', 1, ['red (blue\) green', 'blue\', 'red (blue\) green']) endfunc +func Test_inner_block_single_char() + new + call setline(1, "(a)") + + set selection=inclusive + let @" = '' + call assert_nobeep('norm! 0faviby') + call assert_equal('a', @") + + set selection=exclusive + let @" = '' + call assert_nobeep('norm! 0faviby') + call assert_equal('a', @") + + set selection& + bwipe! +endfunc + func Test_quote_selection_selection_exclusive() new call setline(1, "a 'bcde' f") @@ -50,11 +68,11 @@ func Test_quote_selection_selection_exclusive() exe "norm! fdvhi'y" call assert_equal('bcde', @") - let @"='dummy' + let @" = 'dummy' exe "norm! $gevi'y" call assert_equal('bcde', @") - let @"='dummy' + let @" = 'dummy' exe "norm! 0fbhvi'y" call assert_equal('bcde', @") diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index fbbd6f1bc2..c8083cddb1 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -1,7 +1,6 @@ // This is an open source non-commercial project. Dear PVS-Studio, please check // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com - #include "nvim/api/private/helpers.h" #include "nvim/api/vim.h" #include "nvim/ascii.h" @@ -331,7 +330,6 @@ static TermKeyResult tk_getkey(TermKey *tk, TermKeyKey *key, bool force) return force ? termkey_getkey_force(tk, key) : termkey_getkey(tk, key); } - static void tk_getkeys(TermInput *input, bool force) { TermKeyKey key; diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 720abb1cec..6c1c1ade00 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -145,7 +145,6 @@ static bool cursor_style_enabled = false; # include "tui/tui.c.generated.h" #endif - UI *tui_start(void) { UI *ui = xcalloc(1, sizeof(UI)); // Freed by ui_bridge_stop(). @@ -713,7 +712,6 @@ static void update_attrs(UI *ui, int attr_id) } } - data->default_attr = fg == -1 && bg == -1 && !bold && !italic && !has_any_underline && !reverse && !standout && !strikethrough; diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 9e2d1f8e68..b40033296e 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -182,7 +182,6 @@ void ui_event(char *name, Array args) } } - void ui_refresh(void) { if (!ui_active()) { @@ -436,7 +435,7 @@ void ui_set_ext_option(UI *ui, UIExtension ext, bool active) void ui_line(ScreenGrid *grid, int row, int startcol, int endcol, int clearcol, int clearattr, bool wrap) { - assert(0 <= row && row < grid->Rows); + assert(0 <= row && row < grid->rows); LineFlags flags = wrap ? kLineFlagWrap : 0; if (startcol == -1) { startcol = 0; @@ -453,7 +452,7 @@ void ui_line(ScreenGrid *grid, int row, int startcol, int endcol, int clearcol, if (p_wd && !(rdb_flags & RDB_COMPOSITOR)) { // If 'writedelay' is active, set the cursor to indicate what was drawn. ui_call_grid_cursor_goto(grid->handle, row, - MIN(clearcol, (int)grid->Columns - 1)); + MIN(clearcol, (int)grid->cols - 1)); ui_call_flush(); uint64_t wd = (uint64_t)labs(p_wd); os_microdelay(wd * 1000u, true); @@ -533,7 +532,6 @@ void ui_flush(void) ui_call_flush(); } - /// Check if 'mouse' is active for the current mode /// /// TODO(bfredl): precompute the State -> active mapping when 'mouse' changes, diff --git a/src/nvim/ui.h b/src/nvim/ui.h index 7cc0bd9eff..1d278010e8 100644 --- a/src/nvim/ui.h +++ b/src/nvim/ui.h @@ -74,6 +74,5 @@ struct ui_t { # include "ui_events_call.h.generated.h" #endif - EXTERN MultiQueue *resize_events; #endif // NVIM_UI_H diff --git a/src/nvim/ui_bridge.h b/src/nvim/ui_bridge.h index a62ed15621..c18600a857 100644 --- a/src/nvim/ui_bridge.h +++ b/src/nvim/ui_bridge.h @@ -38,7 +38,6 @@ struct ui_bridge_data { uv_mutex_unlock(&d->mutex); \ } while (0) - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ui_bridge.h.generated.h" #endif diff --git a/src/nvim/ui_compositor.c b/src/nvim/ui_compositor.c index f76158ff12..3ce2b80ea9 100644 --- a/src/nvim/ui_compositor.c +++ b/src/nvim/ui_compositor.c @@ -138,19 +138,19 @@ bool ui_comp_put_grid(ScreenGrid *grid, int row, int col, int height, int width, // use it. grid->comp_disabled = true; compose_area(grid->comp_row, row, - grid->comp_col, grid->comp_col + grid->Columns); + grid->comp_col, grid->comp_col + grid->cols); if (grid->comp_col < col) { compose_area(MAX(row, grid->comp_row), - MIN(row + height, grid->comp_row + grid->Rows), + MIN(row + height, grid->comp_row + grid->rows), grid->comp_col, col); } - if (col + width < grid->comp_col + grid->Columns) { + if (col + width < grid->comp_col + grid->cols) { compose_area(MAX(row, grid->comp_row), - MIN(row + height, grid->comp_row + grid->Rows), - col + width, grid->comp_col + grid->Columns); + MIN(row + height, grid->comp_row + grid->rows), + col + width, grid->comp_col + grid->cols); } - compose_area(row + height, grid->comp_row + grid->Rows, - grid->comp_col, grid->comp_col + grid->Columns); + compose_area(row + height, grid->comp_row + grid->rows, + grid->comp_col, grid->comp_col + grid->cols); grid->comp_disabled = false; } grid->comp_row = row; @@ -188,8 +188,8 @@ bool ui_comp_put_grid(ScreenGrid *grid, int row, int col, int height, int width, grid->comp_index = insert_at; } if (moved && valid && ui_comp_should_draw()) { - compose_area(grid->comp_row, grid->comp_row + grid->Rows, - grid->comp_col, grid->comp_col + grid->Columns); + compose_area(grid->comp_row, grid->comp_row + grid->rows, + grid->comp_col, grid->comp_col + grid->cols); } return moved; } @@ -249,10 +249,10 @@ static void ui_comp_raise_grid(ScreenGrid *grid, size_t new_index) for (size_t i = old_index; i < new_index; i++) { ScreenGrid *grid2 = kv_A(layers, i); int startcol = MAX(grid->comp_col, grid2->comp_col); - int endcol = MIN(grid->comp_col + grid->Columns, - grid2->comp_col + grid2->Columns); + int endcol = MIN(grid->comp_col + grid->cols, + grid2->comp_col + grid2->cols); compose_area(MAX(grid->comp_row, grid2->comp_row), - MIN(grid->comp_row + grid->Rows, grid2->comp_row + grid2->Rows), + MIN(grid->comp_row + grid->rows, grid2->comp_row + grid2->rows), startcol, endcol); } } @@ -279,7 +279,7 @@ static void ui_comp_grid_cursor_goto(UI *ui, Integer grid_handle, Integer r, Int } } - if (cursor_col >= default_grid.Columns || cursor_row >= default_grid.Rows) { + if (cursor_col >= default_grid.cols || cursor_row >= default_grid.rows) { // TODO(bfredl): this happens with 'writedelay', refactor? // abort(); return; @@ -292,8 +292,8 @@ ScreenGrid *ui_comp_mouse_focus(int row, int col) for (ssize_t i = (ssize_t)kv_size(layers) - 1; i > 0; i--) { ScreenGrid *grid = kv_A(layers, i); if (grid->focusable - && row >= grid->comp_row && row < grid->comp_row + grid->Rows - && col >= grid->comp_col && col < grid->comp_col + grid->Columns) { + && row >= grid->comp_row && row < grid->comp_row + grid->rows + && col >= grid->comp_col && col < grid->comp_col + grid->cols) { return grid; } } @@ -315,7 +315,7 @@ static void compose_line(Integer row, Integer startcol, Integer endcol, LineFlag startcol--; skipstart = 1; } - if (endcol < default_grid.Columns && (flags & kLineFlagInvalid)) { + if (endcol < default_grid.cols && (flags & kLineFlagInvalid)) { endcol++; skipend = 1; } @@ -337,8 +337,8 @@ static void compose_line(Integer row, Integer startcol, Integer endcol, LineFlag // first check to see if any grids have pending updates to width/height, // to ensure that we don't accidentally put any characters into `linebuf` // that have been invalidated. - grid_width = MIN(g->Columns, g->comp_width); - grid_height = MIN(g->Rows, g->comp_height); + grid_width = MIN(g->cols, g->comp_width); + grid_height = MIN(g->rows, g->comp_height); if (g->comp_row > row || row >= g->comp_row + grid_height || g->comp_disabled) { continue; @@ -354,7 +354,7 @@ static void compose_line(Integer row, Integer startcol, Integer endcol, LineFlag assert(grid != NULL); assert(until > col); - assert(until <= default_grid.Columns); + assert(until <= default_grid.cols); size_t n = (size_t)(until - col); if (row == msg_sep_row && grid->comp_index <= msg_grid.comp_index) { @@ -371,7 +371,7 @@ static void compose_line(Integer row, Integer startcol, Integer endcol, LineFlag + (size_t)(col - grid->comp_col); memcpy(linebuf + (col - startcol), grid->chars + off, n * sizeof(*linebuf)); memcpy(attrbuf + (col - startcol), grid->attrs + off, n * sizeof(*attrbuf)); - if (grid->comp_col + grid->Columns > until + if (grid->comp_col + grid->cols > until && grid->chars[off + n][0] == NUL) { linebuf[until - 1 - startcol][0] = ' '; linebuf[until - 1 - startcol][1] = '\0'; @@ -452,8 +452,8 @@ static void compose_debug(Integer startrow, Integer endrow, Integer startcol, In return; } - endrow = MIN(endrow, default_grid.Rows); - endcol = MIN(endcol, default_grid.Columns); + endrow = MIN(endrow, default_grid.rows); + endcol = MIN(endcol, default_grid.cols); int attr = syn_id2attr(syn_id); for (int row = (int)startrow; row < endrow; row++) { @@ -462,7 +462,6 @@ static void compose_debug(Integer startrow, Integer endrow, Integer startcol, In (const sattr_T *)attrbuf); } - if (delay) { debug_delay(endrow - startrow); } @@ -476,12 +475,11 @@ static void debug_delay(Integer lines) os_microdelay(factor * wd * 1000u, true); } - static void compose_area(Integer startrow, Integer endrow, Integer startcol, Integer endcol) { compose_debug(startrow, endrow, startcol, endcol, dbghl_recompose, true); - endrow = MIN(endrow, default_grid.Rows); - endcol = MIN(endcol, default_grid.Columns); + endrow = MIN(endrow, default_grid.rows); + endcol = MIN(endcol, default_grid.cols); if (endcol <= startcol) { return; } @@ -497,8 +495,8 @@ static void compose_area(Integer startrow, Integer endrow, Integer startcol, Int void ui_comp_compose_grid(ScreenGrid *grid) { if (ui_comp_should_draw()) { - compose_area(grid->comp_row, grid->comp_row + grid->Rows, - grid->comp_col, grid->comp_col + grid->Columns); + compose_area(grid->comp_row, grid->comp_row + grid->rows, + grid->comp_col, grid->comp_col + grid->cols); } } @@ -523,17 +521,17 @@ static void ui_comp_raw_line(UI *ui, Integer grid, Integer row, Integer startcol // TODO(bfredl): this should not really be necessary. But on some condition // when resizing nvim, a window will be attempted to be drawn on the older // and possibly larger global screen size. - if (row >= default_grid.Rows) { + if (row >= default_grid.rows) { DLOG("compositor: invalid row %" PRId64 " on grid %" PRId64, row, grid); return; } - if (clearcol > default_grid.Columns) { + if (clearcol > default_grid.cols) { DLOG("compositor: invalid last column %" PRId64 " on grid %" PRId64, clearcol, grid); - if (startcol >= default_grid.Columns) { + if (startcol >= default_grid.cols) { return; } - clearcol = default_grid.Columns; + clearcol = default_grid.cols; endcol = MIN(endcol, clearcol); } @@ -581,7 +579,7 @@ static void ui_comp_msg_set_pos(UI *ui, Integer grid, Integer row, Boolean scrol } if (row > msg_current_row && ui_comp_should_draw()) { - compose_area(MAX(msg_current_row - 1, 0), row, 0, default_grid.Columns); + compose_area(MAX(msg_current_row - 1, 0), row, 0, default_grid.cols); } else if (row < msg_current_row && ui_comp_should_draw() && msg_current_row < Rows) { int delta = msg_current_row - (int)row; diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 529eef19a3..f496c4199a 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -611,7 +611,6 @@ int u_savecommon(buf_T *buf, linenr_T top, linenr_T bot, linenr_T newbot, int re return OK; } - // magic at start of undofile #define UF_START_MAGIC "Vim\237UnDo\345" #define UF_START_MAGIC_LEN 9 @@ -2472,7 +2471,6 @@ static void u_undoredo(int undo, bool do_buf_event) } // finish Adjusting extmarks - curhead->uh_entry = newlist; curhead->uh_flags = new_flags; if ((old_flags & UH_EMPTYBUF) && buf_is_empty(curbuf)) { diff --git a/src/nvim/version.c b/src/nvim/version.c index 1b520780d1..1c8fdce1eb 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -35,7 +35,6 @@ #endif #define NVIM_VERSION_LONG "NVIM " NVIM_VERSION_MEDIUM - char *Version = VIM_VERSION_SHORT; char *longVersion = NVIM_VERSION_LONG; char *version_buildtype = "Build type: " NVIM_VERSION_BUILD_TYPE; @@ -2194,7 +2193,6 @@ void list_version(void) version_msg("\nRun :checkhealth for more info"); } - /// Show the intro message when not editing a file. void maybe_intro_message(void) { diff --git a/src/nvim/vim.h b/src/nvim/vim.h index 1c05387da3..7e82af2d93 100644 --- a/src/nvim/vim.h +++ b/src/nvim/vim.h @@ -10,7 +10,6 @@ #define SYS_OPTWIN_FILE "$VIMRUNTIME/optwin.vim" #define RUNTIME_DIRNAME "runtime" - #include "auto/config.h" #define HAVE_PATHDEF @@ -37,7 +36,6 @@ enum { NUMBUFLEN = 65, }; // special attribute addition: Put message in history #define MSG_HIST 0x1000 - // Values for State // // The lower bits up to 0x80 are used to distinguish normal/visual/op_pending @@ -74,7 +72,6 @@ enum { NUMBUFLEN = 65, }; #define MODE_CONFIRM 0x7000 // ":confirm" prompt #define MODE_CMDPREVIEW 0x8000 // Showing 'inccommand' command "live" preview. - /// Directions. typedef enum { kDirectionNotSet = 0, @@ -103,7 +100,6 @@ typedef enum { #define VAR_TYPE_SPECIAL 7 #define VAR_TYPE_BLOB 10 - // values for xp_context when doing command line completion enum { @@ -164,7 +160,6 @@ enum { EXPAND_LUA, }; - // Minimal size for block 0 of a swap file. // NOTE: This depends on size of struct block0! It's not done with a sizeof(), // because struct block0 is defined in memline.c (Sorry). @@ -173,7 +168,6 @@ enum { #define MIN_SWAP_PAGE_SIZE 1048 #define MAX_SWAP_PAGE_SIZE 50000 - // Boolean constants #ifndef TRUE @@ -186,7 +180,6 @@ enum { #define STATUS_HEIGHT 1 // height of a status line under a window #define QF_WINHEIGHT 10 // default height for quickfix window - // Buffer sizes #ifndef CMDBUFFSIZE @@ -199,7 +192,6 @@ enum { enum { FOLD_TEXT_LEN = 51, }; //!< buffer size for get_foldtext() - // Maximum length of key sequence to be mapped. // Must be able to hold an Amiga resize report. @@ -283,7 +275,6 @@ enum { FOLD_TEXT_LEN = 51, }; //!< buffer size for get_foldtext() (const char *)(y), \ (size_t)(n)) - // Enums need a typecast to be used as array index (for Ultrix). #define HL_ATTR(n) highlight_attr[(int)(n)] diff --git a/src/nvim/viml/parser/expressions.c b/src/nvim/viml/parser/expressions.c index 41b4a7edd6..fd7dc17ee3 100644 --- a/src/nvim/viml/parser/expressions.c +++ b/src/nvim/viml/parser/expressions.c @@ -2646,6 +2646,7 @@ viml_pexpr_parse_figure_brace_closing_error: kvi_push(pt_stack, kEPTLambdaArguments); lambda_node = cur_node; } else { + // uncrustify:off ADD_IDENT(do { NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeCurlyBracesIdentifier); @@ -2660,6 +2661,7 @@ viml_pexpr_parse_figure_brace_closing_error: want_node = kENodeValue; } while (0), Curly); + // uncrustify:on } if (pt_is_assignment(cur_pt) && !pt_is_assignment(kv_last(pt_stack))) { @@ -2737,6 +2739,7 @@ viml_pexpr_parse_figure_brace_closing_error: : HL(IdentifierName))); } else { if (scope == kExprVarScopeMissing) { + // uncrustify:off ADD_IDENT(do { NEW_NODE_WITH_CUR_POS(cur_node, kExprNodePlainIdentifier); cur_node->data.var.scope = scope; @@ -2745,6 +2748,7 @@ viml_pexpr_parse_figure_brace_closing_error: want_node = kENodeOperator; } while (0), IdentifierName); + // uncrustify:on } else { OP_MISSING; } diff --git a/src/nvim/viml/parser/parser.c b/src/nvim/viml/parser/parser.c index 8d26d08ea7..a41b750e76 100644 --- a/src/nvim/viml/parser/parser.c +++ b/src/nvim/viml/parser/parser.c @@ -7,7 +7,6 @@ # include "viml/parser/parser.c.generated.h" #endif - void parser_simple_get_line(void *cookie, ParserLine *ret_pline) { ParserLine **plines_p = (ParserLine **)cookie; diff --git a/src/nvim/window.c b/src/nvim/window.c index 2c27a5d6a5..f42ef874ef 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -53,12 +53,10 @@ #include "nvim/vim.h" #include "nvim/window.h" - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "window.c.generated.h" #endif - #define NOWIN ((win_T *)-1) // non-existing window #define ROWS_AVAIL (Rows - p_ch - tabline_height() - global_stl_height()) @@ -515,9 +513,14 @@ wingotofile: if ((len = find_ident_under_cursor(&ptr, FIND_IDENT)) == 0) { break; } + + // Make a copy, if the line was changed it will be freed. + ptr = vim_strnsave(ptr, len); + find_pattern_in_path(ptr, 0, len, true, Prenum == 0, type, Prenum1, ACTION_SPLIT, 1, MAXLNUM); - curwin->w_set_curswant = TRUE; + xfree(ptr); + curwin->w_set_curswant = true; break; // Quickfix window only: view the result under the cursor in a new split. @@ -528,7 +531,6 @@ wingotofile: } break; - // CTRL-W g extended commands case 'g': case Ctrl_G: @@ -695,6 +697,7 @@ win_T *win_new_float(win_T *wp, bool last, FloatConfig fconfig, Error *err) } wp->w_floating = 1; wp->w_status_height = 0; + wp->w_winbar_height = 0; wp->w_hsep_height = 0; wp->w_vsep_width = 0; @@ -767,7 +770,6 @@ void win_config_float(win_T *wp, FloatConfig fconfig) wp->w_float_config.border_hl_ids, sizeof fconfig.border_hl_ids)); - wp->w_float_config = fconfig; bool has_border = wp->w_floating && wp->w_float_config.border; @@ -780,10 +782,8 @@ void win_config_float(win_T *wp, FloatConfig fconfig) } if (!ui_has(kUIMultigrid)) { - wp->w_height = MIN(wp->w_height, - Rows - 1 - (wp->w_border_adj[0] + wp->w_border_adj[2])); - wp->w_width = MIN(wp->w_width, - Columns - (wp->w_border_adj[1] + wp->w_border_adj[3])); + wp->w_height = MIN(wp->w_height, Rows - 1 - win_extra_height(wp)); + wp->w_width = MIN(wp->w_width, Columns - win_extra_width(wp)); } win_set_inner_size(wp); @@ -1051,7 +1051,6 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) need_status = STATUS_HEIGHT; } - if (flags & WSP_VERT) { int wmw1; int minwidth; @@ -1138,15 +1137,12 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) } else { layout = FR_COL; - /* - * Check if we are able to split the current window and compute its - * height. - */ - // Current window requires at least 1 space. - wmh1 = p_wmh == 0 ? 1 : p_wmh; + // Check if we are able to split the current window and compute its height. + // Current window requires at least 1 space plus space for the window bar. + wmh1 = MAX(p_wmh, 1) + oldwin->w_winbar_height; needed = wmh1 + STATUS_HEIGHT; if (flags & WSP_ROOM) { - needed += p_wh - wmh1; + needed += p_wh - wmh1 + oldwin->w_winbar_height; } if (flags & (WSP_BOT | WSP_TOP)) { minheight = frame_minheight(topframe, NOWIN) + need_status; @@ -1155,8 +1151,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) } else if (p_ea) { minheight = frame_minheight(oldwin->w_frame, NOWIN) + need_status; prevfrp = oldwin->w_frame; - for (frp = oldwin->w_frame->fr_parent; frp != NULL; - frp = frp->fr_parent) { + for (frp = oldwin->w_frame->fr_parent; frp != NULL; frp = frp->fr_parent) { if (frp->fr_layout == FR_COL) { FOR_ALL_FRAMES(frp2, frp->fr_child) { if (frp2 != prevfrp) { @@ -1339,6 +1334,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) set_fraction(oldwin); } wp->w_fraction = oldwin->w_fraction; + wp->w_winbar_height = oldwin->w_winbar_height; if (flags & WSP_VERT) { wp->w_p_scr = curwin->w_p_scr; @@ -1416,9 +1412,9 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) if (flags & (WSP_TOP | WSP_BOT)) { int new_fr_height = curfrp->fr_height - new_size; - if (!((flags & WSP_BOT) && p_ls == 0) && global_stl_height() == 0) { + if (!((flags & WSP_BOT) && p_ls == 0) && !is_stl_global) { new_fr_height -= STATUS_HEIGHT; - } else if (global_stl_height() > 0) { + } else if (is_stl_global) { if (flags & WSP_BOT) { frame_add_hsep(curfrp); } else { @@ -1452,7 +1448,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) } } } - if ((flags & WSP_BOT) && global_stl_height() == 0) { + if ((flags & WSP_BOT) && !is_stl_global) { frame_add_statusline(curfrp); } frame_fix_height(wp); @@ -1482,10 +1478,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) * equalize the window sizes. */ if (do_equal || dir != 0) { - win_equal(wp, true, - (flags & WSP_VERT) ? (dir == 'v' ? 'b' : 'h') - : dir == 'h' ? 'b' : - 'v'); + win_equal(wp, true, (flags & WSP_VERT) ? (dir == 'v' ? 'b' : 'h') : (dir == 'h' ? 'b' : 'v')); } // Don't change the window height/width to 'winheight' / 'winwidth' if a @@ -1522,7 +1515,6 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) return OK; } - /* * Initialize window "newp" from window "oldp". * Used when splitting a window and when creating a new tab page. @@ -1675,10 +1667,10 @@ int win_count(void) } /// Make "count" windows on the screen. -/// Must be called when there is just one window, filling the whole screen +/// Must be called when there is just one window, filling the whole screen. /// (excluding the command line). /// -/// @param vertical split windows vertically if true +/// @param vertical split windows vertically if true. /// /// @return actual number of windows on the screen. int make_windows(int count, bool vertical) @@ -1687,15 +1679,15 @@ int make_windows(int count, bool vertical) int todo; if (vertical) { - // Each window needs at least 'winminwidth' lines and a separator - // column. + // Each window needs at least 'winminwidth' lines and a separator column. maxcount = (curwin->w_width + curwin->w_vsep_width - (p_wiw - p_wmw)) / (p_wmw + 1); } else { - // Each window needs at least 'winminheight' lines - // If statusline isn't global, each window also needs a statusline + // Each window needs at least 'winminheight' lines. + // If statusline isn't global, each window also needs a statusline. + // If 'winbar' is set, each window also needs a winbar. maxcount = (curwin->w_height + curwin->w_hsep_height + curwin->w_status_height - - (p_wh - p_wmh)) / (p_wmh + STATUS_HEIGHT); + - (p_wh - p_wmh)) / (p_wmh + STATUS_HEIGHT + global_winbar_height()); } if (maxcount < 2) { @@ -1705,17 +1697,13 @@ int make_windows(int count, bool vertical) count = maxcount; } - /* - * add status line now, otherwise first window will be too big - */ + // add status line now, otherwise first window will be too big if (count > 1) { last_status(true); } - /* - * Don't execute autocommands while creating the windows. Must do that - * when putting the buffers in the windows. - */ + // Don't execute autocommands while creating the windows. Must do that + // when putting the buffers in the windows. block_autocmds(); // todo is number of windows left to create @@ -1762,7 +1750,6 @@ static void win_exchange(long Prenum) return; } - /* * find window to exchange with */ @@ -1790,7 +1777,7 @@ static void win_exchange(long Prenum) * if wp != wp2 * 3. remove wp from the list * 4. insert wp after wp2 - * 5. exchange the status line height, hsep height and vsep width. + * 5. exchange the status line height, winbar height, hsep height and vsep width. */ wp2 = curwin->w_prev; frp2 = curwin->w_frame->fr_prev; @@ -1897,7 +1884,7 @@ static void win_rotate(bool upwards, int count) frame_insert(frp->fr_parent->fr_child, frp); } - // exchange status height, hsep height and vsep width of old and new last window + // exchange status height, winbar height, hsep height and vsep width of old and new last window n = wp2->w_status_height; wp2->w_status_height = wp1->w_status_height; wp1->w_status_height = n; @@ -1988,7 +1975,8 @@ void win_move_after(win_T *win1, win_T *win2) return; } - // may need move the status line, horizontal or vertical separator of the last window + // may need move the status line, window bar, horizontal or vertical separator of the last + // window if (win1 == lastwin) { height = win1->w_prev->w_status_height; win1->w_prev->w_status_height = win1->w_status_height; @@ -2038,6 +2026,37 @@ void win_move_after(win_T *win1, win_T *win2) win2->w_pos_changed = true; } +/// Compute maximum number of windows that can fit within "height" in frame "fr". +static int get_maximum_wincount(frame_T *fr, int height) +{ + if (fr->fr_layout != FR_COL) { + return (height / (p_wmh + STATUS_HEIGHT + frame2win(fr)->w_winbar_height)); + } else if (global_winbar_height()) { + // If winbar is globally enabled, no need to check each window for it. + return (height / (p_wmh + STATUS_HEIGHT + 1)); + } + + frame_T *frp; + int total_wincount = 0; + + // First, try to fit all child frames of "fr" into "height" + FOR_ALL_FRAMES(frp, fr->fr_child) { + win_T *wp = frame2win(frp); + + if (height < (p_wmh + STATUS_HEIGHT + wp->w_winbar_height)) { + break; + } + height -= p_wmh + STATUS_HEIGHT + wp->w_winbar_height; + total_wincount += 1; + } + + // If we still have enough room for more windows, just use the default winbar height (which is 0) + // in order to get the amount of windows that'd fit in the remaining space + total_wincount += height / (p_wmh + STATUS_HEIGHT); + + return total_wincount; +} + /// Make all windows the same height. ///'next_curwin' will soon be the current window, make sure it has enough rows. /// @@ -2237,7 +2256,7 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int } else { extra_sep = 0; } - totwincount = (n + extra_sep) / (p_wmh + STATUS_HEIGHT); + totwincount = get_maximum_wincount(topfr, n + extra_sep); has_next_curwin = frame_has_win(topfr, next_curwin); /* @@ -2271,8 +2290,7 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int } } else { // These windows don't use up room. - totwincount -= (n + (fr->fr_next == NULL - ? extra_sep : 0)) / (p_wmh + STATUS_HEIGHT); + totwincount -= get_maximum_wincount(fr, (n + (fr->fr_next == NULL ? extra_sep : 0))); } room -= new_size - n; if (room < 0) { @@ -2317,8 +2335,7 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int } else { // Compute the maximum number of windows vert. in "fr". n = frame_minheight(fr, NOWIN); - wincount = (n + (fr->fr_next == NULL ? extra_sep : 0)) - / (p_wmh + STATUS_HEIGHT); + wincount = get_maximum_wincount(fr, (n + (fr->fr_next == NULL ? extra_sep : 0))); m = frame_minheight(fr, next_curwin); if (has_next_curwin) { hnc = frame_has_win(fr, next_curwin); @@ -3732,13 +3749,9 @@ static void frame_fix_height(win_T *wp) wp->w_frame->fr_height = wp->w_height + wp->w_hsep_height + wp->w_status_height; } -/* - * Compute the minimal height for frame "topfrp". - * Uses the 'winminheight' option. - * When "next_curwin" isn't NULL, use p_wh for this window. - * When "next_curwin" is NOWIN, don't use at least one line for the current - * window. - */ +/// Compute the minimal height for frame "topfrp". Uses the 'winminheight' option. +/// When "next_curwin" isn't NULL, use p_wh for this window. +/// When "next_curwin" is NOWIN, don't use at least one line for the current window. static int frame_minheight(frame_T *topfrp, win_T *next_curwin) { frame_T *frp; @@ -3746,12 +3759,14 @@ static int frame_minheight(frame_T *topfrp, win_T *next_curwin) int n; if (topfrp->fr_win != NULL) { + // Combined height of window bar and separator column or status line. + int extra_height = topfrp->fr_win->w_winbar_height + topfrp->fr_win->w_hsep_height + + topfrp->fr_win->w_status_height; + if (topfrp->fr_win == next_curwin) { - m = p_wh + topfrp->fr_win->w_hsep_height + topfrp->fr_win->w_status_height; + m = p_wh + extra_height; } else { - // window: minimal height of the window plus separator column or status line - // depending on whether global statusline is enabled - m = p_wmh + topfrp->fr_win->w_hsep_height + topfrp->fr_win->w_status_height; + m = p_wmh + extra_height; if (topfrp->fr_win == curwin && next_curwin == NULL) { // Current window is minimal one line high. if (p_wmh == 0) { @@ -3821,7 +3836,6 @@ static int frame_minwidth(frame_T *topfrp, win_T *next_curwin) return m; } - /// Try to close all windows except current one. /// Buffers in the other windows become hidden if 'hidden' is set, or '!' is /// used and the buffer was modified. @@ -3976,7 +3990,7 @@ static void new_frame(win_T *wp) void win_init_size(void) { firstwin->w_height = ROWS_AVAIL; - firstwin->w_height_inner = firstwin->w_height; + firstwin->w_height_inner = firstwin->w_height - firstwin->w_winbar_height; firstwin->w_height_outer = firstwin->w_height; topframe->fr_height = ROWS_AVAIL; firstwin->w_width = Columns; @@ -4087,6 +4101,7 @@ int win_new_tabpage(int after, char_u *filename) newtp->tp_topframe = topframe; last_status(false); + set_winbar(); redraw_all_later(NOT_VALID); @@ -4537,7 +4552,6 @@ void tabpage_move(int nr) redraw_tabline = true; } - /* * Go to another window. * When jumping to another buffer, stop Visual mode. Do this before @@ -4575,7 +4589,6 @@ void win_goto(win_T *wp) } } - /* * Find the tabpage for window "win". */ @@ -5038,7 +5051,6 @@ static win_T *win_alloc(win_T *after, bool hidden) return new_wp; } - // Free one wininfo_T. void free_wininfo(wininfo_T *wip, buf_T *bp) { @@ -5049,7 +5061,6 @@ void free_wininfo(wininfo_T *wip, buf_T *bp) xfree(wip); } - /// Remove window 'wp' from the window list and free the structure. /// /// @param tp tab page "win" is in, NULL for current @@ -5096,6 +5107,12 @@ static void win_free(win_T *wp, tabpage_T *tp) xfree(wp->w_localdir); xfree(wp->w_prevdir); + stl_clear_click_defs(wp->w_status_click_defs, wp->w_status_click_defs_size); + xfree(wp->w_status_click_defs); + + stl_clear_click_defs(wp->w_winbar_click_defs, wp->w_winbar_click_defs_size); + xfree(wp->w_winbar_click_defs); + // Remove the window from the b_wininfo lists, it may happen that the // freed memory is re-used for another window. FOR_ALL_BUFFERS(buf) { @@ -5254,7 +5271,6 @@ static void frame_remove(frame_T *frp) } } - /* * Called from win_new_shellsize() after Rows changed. * This only does the current tab page, others must be done when made active. @@ -5444,7 +5460,6 @@ static void frame_comp_pos(frame_T *topfrp, int *row, int *col) } } - /* * Set current window height and take care of repositioning other windows to * fit around it. @@ -5460,16 +5475,9 @@ void win_setheight(int height) */ void win_setheight_win(int height, win_T *win) { - if (win == curwin) { - // Always keep current window at least one line high, even when - // 'winminheight' is zero. - if (height < p_wmh) { - height = p_wmh; - } - if (height == 0) { - height = 1; - } - } + // Always keep current window at least one line high, even when 'winminheight' is zero. + // Keep window at least two lines high if 'winbar' is enabled. + height = MAX(height, (win == curwin ? MAX(p_wmh, 1) : p_wmh) + win->w_winbar_height); if (win->w_floating) { win->w_float_config.height = height; @@ -5499,7 +5507,6 @@ void win_setheight_win(int height, win_T *win) } } - /* * Set the height of a frame to "height" and take care that all frames and * windows inside it are resized. Also resize frames on the left and right if @@ -6110,7 +6117,6 @@ void win_drag_vsep_line(win_T *dragwin, int offset) redraw_all_later(NOT_VALID); } - #define FRACTION_MULT 16384L // Set wp->w_fraction for the current w_wrow and w_height. @@ -6262,7 +6268,7 @@ void win_set_inner_size(win_T *wp) int prev_height = wp->w_height_inner; int height = wp->w_height_request; if (height == 0) { - height = wp->w_height; + height = wp->w_height - wp->w_winbar_height; } if (height != prev_height) { @@ -6279,8 +6285,8 @@ void win_set_inner_size(win_T *wp) set_fraction(wp); } } - wp->w_height_inner = height; wp->w_skipcol = 0; + wp->w_height_inner = height; // There is no point in adjusting the scroll position when exiting. Some // values might be invalid. @@ -6306,10 +6312,20 @@ void win_set_inner_size(win_T *wp) terminal_check_size(wp->w_buffer->terminal); } - wp->w_height_outer = (wp->w_height_inner - + wp->w_border_adj[0] + wp->w_border_adj[2]); - wp->w_width_outer = (wp->w_width_inner - + wp->w_border_adj[1] + wp->w_border_adj[3]); + wp->w_height_outer = (wp->w_height_inner + win_extra_height(wp)); + wp->w_width_outer = (wp->w_width_inner + win_extra_width(wp)); + wp->w_winrow_off = wp->w_border_adj[0] + wp->w_winbar_height; + wp->w_wincol_off = wp->w_border_adj[3]; +} + +static int win_extra_height(win_T *wp) +{ + return wp->w_border_adj[0] + wp->w_border_adj[2] + wp->w_winbar_height; +} + +static int win_extra_width(win_T *wp) +{ + return wp->w_border_adj[1] + wp->w_border_adj[3]; } /// Set the width of a window. @@ -6586,6 +6602,23 @@ void last_status(bool morewin) global_stl_height() > 0); } +// Remove status line from window, replacing it with a horizontal separator if needed. +static void win_remove_status_line(win_T *wp, bool add_hsep) +{ + wp->w_status_height = 0; + if (add_hsep) { + wp->w_hsep_height = 1; + } else { + win_new_height(wp, wp->w_height + STATUS_HEIGHT); + } + comp_col(); + + stl_clear_click_defs(wp->w_status_click_defs, wp->w_status_click_defs_size); + xfree(wp->w_status_click_defs); + wp->w_status_click_defs_size = 0; + wp->w_status_click_defs = NULL; +} + // Look for resizable frames and take lines from them to make room for the statusline static void resize_frame_for_status(frame_T *fr) { @@ -6626,10 +6659,7 @@ static void last_status_rec(frame_T *fr, bool statusline, bool is_stl_global) if (is_last) { if (wp->w_status_height != 0 && (!statusline || is_stl_global)) { - // Remove status line - wp->w_status_height = 0; - win_new_height(wp, wp->w_height + STATUS_HEIGHT); - comp_col(); + win_remove_status_line(wp, false); } else if (wp->w_status_height == 0 && !is_stl_global && statusline) { // Add statusline to window if needed wp->w_status_height = STATUS_HEIGHT; @@ -6639,9 +6669,7 @@ static void last_status_rec(frame_T *fr, bool statusline, bool is_stl_global) } else if (wp->w_status_height != 0 && is_stl_global) { // If statusline is global and the window has a statusline, replace it with a horizontal // separator - wp->w_status_height = 0; - wp->w_hsep_height = 1; - comp_col(); + win_remove_status_line(wp, true); } else if (wp->w_status_height == 0 && !is_stl_global) { // If statusline isn't global and the window doesn't have a statusline, re-add it wp->w_status_height = STATUS_HEIGHT; @@ -6649,19 +6677,35 @@ static void last_status_rec(frame_T *fr, bool statusline, bool is_stl_global) comp_col(); } redraw_all_later(SOME_VALID); - } else if (fr->fr_layout == FR_COL) { - // For a column frame, recursively call this function for all child frames - FOR_ALL_FRAMES(fp, fr->fr_child) { - last_status_rec(fp, statusline, is_stl_global); - } } else { - // For a row frame, recursively call this function for all child frames + // For a column or row frame, recursively call this function for all child frames FOR_ALL_FRAMES(fp, fr->fr_child) { last_status_rec(fp, statusline, is_stl_global); } } } +// Add or remove window bars from windows depending on the value of 'winbar'. +void set_winbar(void) +{ + FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { + int winbar_height = (*p_wbr != NUL || *wp->w_p_wbr != NUL) ? 1 : 0; + if (wp->w_winbar_height != winbar_height) { + wp->w_winbar_height = winbar_height; + win_set_inner_size(wp); + wp->w_redr_status = wp->w_redr_status || winbar_height; + + if (winbar_height == 0) { + // When removing winbar, deallocate the w_winbar_click_defs array + stl_clear_click_defs(wp->w_winbar_click_defs, wp->w_winbar_click_defs_size); + xfree(wp->w_winbar_click_defs); + wp->w_winbar_click_defs_size = 0; + wp->w_winbar_click_defs = NULL; + } + } + } +} + /// Return the number of lines used by the tab page line. int tabline_height(void) { @@ -6678,6 +6722,12 @@ int tabline_height(void) return 1; } +/// Return the number of lines used by default by the window bar. +int global_winbar_height(void) +{ + return *p_wbr != NUL ? 1 : 0; +} + /// Return the number of lines used by the global statusline int global_stl_height(void) { |