diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/CMakeLists.txt | 12 | ||||
-rw-r--r-- | src/nvim/api/buffer.c | 141 | ||||
-rw-r--r-- | src/nvim/api/private/helpers.c | 26 | ||||
-rw-r--r-- | src/nvim/api/vim.c | 2 | ||||
-rw-r--r-- | src/nvim/buffer.c | 8 | ||||
-rw-r--r-- | src/nvim/ex_cmds.c | 2 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 24 | ||||
-rw-r--r-- | src/nvim/ex_getln.c | 17 | ||||
-rw-r--r-- | src/nvim/fileio.c | 3 | ||||
-rw-r--r-- | src/nvim/generators/gen_char_blob.lua | 70 | ||||
-rw-r--r-- | src/nvim/lua/executor.c | 25 | ||||
-rw-r--r-- | src/nvim/lua/vim.lua | 229 | ||||
-rw-r--r-- | src/nvim/main.c | 2 | ||||
-rw-r--r-- | src/nvim/memline.c | 5 | ||||
-rw-r--r-- | src/nvim/mouse.c | 29 | ||||
-rw-r--r-- | src/nvim/normal.c | 26 | ||||
-rw-r--r-- | src/nvim/ops.c | 3 | ||||
-rw-r--r-- | src/nvim/option.c | 7 | ||||
-rw-r--r-- | src/nvim/po/af.po | 2 | ||||
-rw-r--r-- | src/nvim/po/fi.po | 2 | ||||
-rw-r--r-- | src/nvim/po/uk.po | 4 | ||||
-rw-r--r-- | src/nvim/quickfix.c | 467 | ||||
-rw-r--r-- | src/nvim/state.c | 2 | ||||
-rw-r--r-- | src/nvim/testdir/test_cmdline.vim | 28 | ||||
-rw-r--r-- | src/nvim/testdir/test_ins_complete.vim | 18 |
25 files changed, 638 insertions, 516 deletions
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index b00ac866b7..bc8e64dd41 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -52,7 +52,8 @@ set(UNICODE_TABLES_GENERATOR ${GENERATOR_DIR}/gen_unicode_tables.lua) set(UNICODE_DIR ${PROJECT_SOURCE_DIR}/unicode) set(GENERATED_UNICODE_TABLES ${GENERATED_DIR}/unicode_tables.generated.h) set(VIM_MODULE_FILE ${GENERATED_DIR}/lua/vim_module.generated.h) -set(VIM_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/src/nvim/lua/vim.lua) +set(LUA_VIM_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/src/nvim/lua/vim.lua) +set(LUA_SHARED_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/shared.lua) set(CHAR_BLOB_GENERATOR ${GENERATOR_DIR}/gen_char_blob.lua) set(LINT_SUPPRESS_FILE ${PROJECT_BINARY_DIR}/errors.json) set(LINT_SUPPRESS_URL_BASE "https://raw.githubusercontent.com/neovim/doc/gh-pages/reports/clint") @@ -317,11 +318,13 @@ add_custom_command( add_custom_command( OUTPUT ${VIM_MODULE_FILE} - COMMAND ${LUA_PRG} ${CHAR_BLOB_GENERATOR} ${VIM_MODULE_SOURCE} - ${VIM_MODULE_FILE} vim_module + COMMAND ${LUA_PRG} ${CHAR_BLOB_GENERATOR} ${VIM_MODULE_FILE} + ${LUA_VIM_MODULE_SOURCE} vim_module + ${LUA_SHARED_MODULE_SOURCE} shared_module DEPENDS ${CHAR_BLOB_GENERATOR} - ${VIM_MODULE_SOURCE} + ${LUA_VIM_MODULE_SOURCE} + ${LUA_SHARED_MODULE_SOURCE} ) list(APPEND NVIM_GENERATED_SOURCES @@ -462,6 +465,7 @@ install_helper(TARGETS nvim) set_property(TARGET nvim APPEND PROPERTY INCLUDE_DIRECTORIES ${LUA_PREFERRED_INCLUDE_DIRS}) +set_property(TARGET nvim PROPERTY ENABLE_EXPORTS TRUE) if(ENABLE_LTO AND (POLICY CMP0069)) include(CheckIPOSupported) diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index a5f8b0974e..8f5718d97e 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -1013,10 +1013,10 @@ ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err) /// Returns position for a given extmark id /// -/// @param buffer The buffer handle -/// @param namespace a identifier returned previously with nvim_create_namespace -/// @param id the extmark id -/// @param[out] err Details of an error that may have occurred +/// @param buffer Buffer handle, or 0 for current buffer +/// @param ns_id Namespace id from |nvim_create_namespace()| +/// @param id Extmark id +/// @param[out] err Error details, if any /// @return (row, col) tuple or empty list () if extmark id was absent ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id, Integer id, Error *err) @@ -1044,30 +1044,50 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id, return rv; } -/// List extmarks in a range (inclusive) -/// -/// range ends can be specified as (row, col) tuples, as well as extmark -/// ids in the same namespace. In addition, 0 and -1 works as shorthands -/// for (0,0) and (-1,-1) respectively, so that all marks in the buffer can be -/// queried as: -/// -/// all_marks = nvim_buf_get_extmarks(0, my_ns, 0, -1, {}) -/// -/// If end is a lower position than start, then the range will be traversed -/// backwards. This is mostly useful with limited amount, to be able to get the -/// first marks prior to a given position. -/// -/// @param buffer The buffer handle -/// @param ns_id An id returned previously from nvim_create_namespace -/// @param start One of: extmark id, (row, col) or 0, -1 for buffer ends -/// @param end One of: extmark id, (row, col) or 0, -1 for buffer ends -/// @param opts additional options. Supports the keys: -/// - amount: Maximum number of marks to return -/// @param[out] err Details of an error that may have occurred -/// @return [[extmark_id, row, col], ...] -Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, - Object start, Object end, Dictionary opts, - Error *err) +/// Gets extmarks in "traversal order" from a |charwise| region defined by +/// buffer positions (inclusive, 0-indexed |api-indexing|). +/// +/// Region can be given as (row,col) tuples, or valid extmark ids (whose +/// positions define the bounds). 0 and -1 are understood as (0,0) and (-1,-1) +/// respectively, thus the following are equivalent: +/// +/// <pre> +/// nvim_buf_get_extmarks(0, my_ns, 0, -1, {}) +/// nvim_buf_get_extmarks(0, my_ns, [0,0], [-1,-1], {}) +/// </pre> +/// +/// If `end` is less than `start`, traversal works backwards. (Useful +/// with `limit`, to get the first marks prior to a given position.) +/// +/// Example: +/// +/// <pre> +/// local a = vim.api +/// local pos = a.nvim_win_get_cursor(0) +/// local ns = a.nvim_create_namespace('my-plugin') +/// -- Create new extmark at line 1, column 1. +/// local m1 = a.nvim_buf_set_extmark(0, ns, 0, 0, 0, {}) +/// -- Create new extmark at line 3, column 1. +/// local m2 = a.nvim_buf_set_extmark(0, ns, 0, 2, 0, {}) +/// -- Get extmarks only from line 3. +/// local ms = a.nvim_buf_get_extmarks(0, ns, {2,0}, {2,0}, {}) +/// -- Get all marks in this buffer + namespace. +/// local all = a.nvim_buf_get_extmarks(0, ns, 0, -1, {}) +/// print(vim.inspect(ms)) +/// </pre> +/// +/// @param buffer Buffer handle, or 0 for current buffer +/// @param ns_id Namespace id from |nvim_create_namespace()| +/// @param start Start of range, given as (row, col) or valid extmark id +/// (whose position defines the bound) +/// @param end End of range, given as (row, col) or valid extmark id +/// (whose position defines the bound) +/// @param opts Optional parameters. Keys: +/// - limit: Maximum number of marks to return +/// @param[out] err Error details, if any +/// @return List of [extmark_id, row, col] tuples in "traversal order". +Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, + Object end, Dictionary opts, Error *err) FUNC_API_SINCE(7) { Array rv = ARRAY_DICT_INIT; @@ -1081,17 +1101,17 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, api_set_error(err, kErrorTypeValidation, _("Invalid ns_id")); return rv; } - Integer amount = -1; + Integer limit = -1; for (size_t i = 0; i < opts.size; i++) { String k = opts.items[i].key; Object *v = &opts.items[i].value; - if (strequal("amount", k.data)) { + if (strequal("limit", k.data)) { if (v->type != kObjectTypeInteger) { - api_set_error(err, kErrorTypeValidation, "amount is not an integer"); + api_set_error(err, kErrorTypeValidation, "limit is not an integer"); return rv; } - amount = v->data.integer; + limit = v->data.integer; v->data.integer = LUA_NOREF; } else { api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data); @@ -1099,7 +1119,7 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, } } - if (amount == 0) { + if (limit == 0) { return rv; } @@ -1108,13 +1128,13 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, linenr_T l_lnum; colnr_T l_col; - if (!set_extmark_index_from_obj(buf, ns_id, start, &l_lnum, &l_col, err)) { + if (!extmark_get_index_from_obj(buf, ns_id, start, &l_lnum, &l_col, err)) { return rv; } linenr_T u_lnum; colnr_T u_col; - if (!set_extmark_index_from_obj(buf, ns_id, end, &u_lnum, &u_col, err)) { + if (!extmark_get_index_from_obj(buf, ns_id, end, &u_lnum, &u_col, err)) { return rv; } @@ -1129,9 +1149,8 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, } - ExtmarkArray marks = extmark_get(buf, (uint64_t)ns_id, l_lnum, l_col, - u_lnum, u_col, (int64_t)amount, - reverse); + ExtmarkArray marks = extmark_get(buf, (uint64_t)ns_id, l_lnum, l_col, u_lnum, + u_col, (int64_t)limit, reverse); for (size_t i = 0; i < kv_size(marks); i++) { Array mark = ARRAY_DICT_INIT; @@ -1146,26 +1165,23 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, return rv; } -/// Create or update an extmark at a position +/// Creates or updates an extmark. /// -/// If an invalid namespace is given, an error will be raised. -/// -/// To create a new extmark, pass in id=0. The new extmark id will be -/// returned. To move an existing mark, pass in its id. +/// 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. -/// This is mainly useful over RPC, to avoid needing to wait for the return -/// value. -/// -/// @param buffer The buffer handle -/// @param ns_id a identifier returned previously with nvim_create_namespace -/// @param id The extmark's id or 0 to create a new mark. -/// @param line The row to set the extmark to. -/// @param col The column to set the extmark to. -/// @param opts Optional parameters. Currently not used. -/// @param[out] err Details of an error that may have occurred -/// @return the id of the extmark. +/// (Useful over RPC, to avoid waiting for the return value.) +/// +/// @param buffer Buffer handle, or 0 for current buffer +/// @param ns_id Namespace id from |nvim_create_namespace()| +/// @param id Extmark id, or 0 to create new +/// @param line Line number where to place the mark +/// @param col Column where to place the mark +/// @param opts Optional parameters. Currently not used. +/// @param[out] err Error details, if any +/// @return Id of the created/updated extmark Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer id, Integer line, Integer col, Dictionary opts, Error *err) @@ -1191,7 +1207,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer id, api_set_error(err, kErrorTypeValidation, "line value outside range"); return 0; } else if (line < buf->b_ml.ml_line_count) { - len = STRLEN(ml_get_buf(curbuf, (linenr_T)line+1, false)); + len = STRLEN(ml_get_buf(buf, (linenr_T)line+1, false)); } if (col == -1) { @@ -1217,13 +1233,13 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer id, return (Integer)id_num; } -/// Remove an extmark +/// Removes an extmark. /// -/// @param buffer The buffer handle -/// @param ns_id a identifier returned previously with nvim_create_namespace -/// @param id The extmarks's id -/// @param[out] err Details of an error that may have occurred -/// @return true on success, false if the extmark was not found. +/// @param buffer Buffer handle, or 0 for current buffer +/// @param ns_id Namespace id from |nvim_create_namespace()| +/// @param id Extmark id +/// @param[out] err Error details, if any +/// @return true if the extmark was found, else false Boolean nvim_buf_del_extmark(Buffer buffer, Integer ns_id, Integer id, @@ -1309,7 +1325,8 @@ Integer nvim_buf_add_highlight(Buffer buffer, return ns_id; } -/// Clears namespaced objects, highlights and virtual text, from a line range +/// Clears namespaced objects (highlights, extmarks, virtual text) from +/// a region. /// /// Lines are 0-indexed. |api-indexing| To clear the namespace in the entire /// buffer, specify line_start=0 and line_end=-1. diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index fbfdb27827..b8d62e42a1 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -1512,7 +1512,7 @@ ArrayOf(Dictionary) keymap_array(String mode, buf_T *buf) // If throw == true then an error will be raised if nothing // was found // Returns NULL if something went wrong -Extmark *extmark_from_id_or_pos(Buffer buffer, Integer namespace, Object id, +Extmark *extmark_from_id_or_pos(Buffer buffer, Integer ns, Object id, Error *err, bool throw) { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -1536,7 +1536,7 @@ Extmark *extmark_from_id_or_pos(Buffer buffer, Integer namespace, Object id, } return NULL; } - extmark = extmark_from_pos(buf, (uint64_t)namespace, row, col); + extmark = extmark_from_pos(buf, (uint64_t)ns, row, col); } else if (id.type != kObjectTypeInteger) { if (throw) { api_set_error(err, kErrorTypeValidation, @@ -1550,7 +1550,7 @@ Extmark *extmark_from_id_or_pos(Buffer buffer, Integer namespace, Object id, return NULL; } else { extmark = extmark_from_id(buf, - (uint64_t)namespace, + (uint64_t)ns, (uint64_t)id.data.integer); } @@ -1572,17 +1572,17 @@ bool ns_initialized(uint64_t ns) return ns < (uint64_t)next_namespace_id; } -/// Get line and column from extmark object +/// Gets the line and column of an extmark. /// -/// Extmarks may be queried from position or name or even special names -/// in the future such as "cursor". This function sets the line and col -/// to make the extmark functions recognize what's required +/// Extmarks may be queried by position, name or even special names +/// in the future such as "cursor". /// -/// @param[out] lnum lnum to be set -/// @param[out] colnr col to be set -bool set_extmark_index_from_obj(buf_T *buf, Integer namespace, - Object obj, linenr_T *lnum, colnr_T *colnr, - Error *err) +/// @param[out] lnum extmark line +/// @param[out] colnr extmark column +/// +/// @return true if the extmark was found, else false +bool extmark_get_index_from_obj(buf_T *buf, Integer ns, Object obj, linenr_T + *lnum, colnr_T *colnr, Error *err) { // Check if it is mark id if (obj.type == kObjectTypeInteger) { @@ -1600,7 +1600,7 @@ bool set_extmark_index_from_obj(buf_T *buf, Integer namespace, return false; } - Extmark *extmark = extmark_from_id(buf, (uint64_t)namespace, (uint64_t)id); + Extmark *extmark = extmark_from_id(buf, (uint64_t)ns, (uint64_t)id); if (extmark) { *lnum = extmark->line->lnum; *colnr = extmark->col; diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 3535bc3186..9adc61b843 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1291,7 +1291,7 @@ theend: /// @param lines |readfile()|-style list of lines. |channel-lines| /// @param type Edit behavior: any |getregtype()| result, or: /// - "b" |blockwise-visual| mode (may include width, e.g. "b3") -/// - "c" |characterwise| mode +/// - "c" |charwise| mode /// - "l" |linewise| mode /// - "" guess by contents, see |setreg()| /// @param after Insert after cursor (like |p|), or before (like |P|). diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 0cd02ce36b..e3b8e9cc6d 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -411,11 +411,11 @@ bool buf_valid(buf_T *buf) /// caller should get a new buffer very soon! /// The 'bufhidden' option can force freeing and deleting. /// @param abort_if_last -/// If TRUE, do not close the buffer if autocommands cause +/// If true, do not close the buffer if autocommands cause /// there to be only one window with this buffer. e.g. when /// ":quit" is supposed to close the window but autocommands /// close all other windows. -void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last) +void close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last) { bool unload_buf = (action != 0); bool del_buf = (action == DOBUF_DEL || action == DOBUF_WIPE); @@ -1238,7 +1238,7 @@ do_buffer( return FAIL; } } else { - EMSG2(_("E89: %s will be killed(add ! to override)"), + EMSG2(_("E89: %s will be killed (add ! to override)"), (char *)buf->b_fname); return FAIL; } @@ -2694,7 +2694,7 @@ setfname( buf_T *buf, char_u *ffname, char_u *sfname, - int message // give message when buffer already exists + bool message // give message when buffer already exists ) { buf_T *obuf = NULL; diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 4725246764..0c3b467612 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -1587,7 +1587,7 @@ int rename_buffer(char_u *new_fname) xfname = curbuf->b_fname; curbuf->b_ffname = NULL; curbuf->b_sfname = NULL; - if (setfname(curbuf, new_fname, NULL, TRUE) == FAIL) { + if (setfname(curbuf, new_fname, NULL, true) == FAIL) { curbuf->b_ffname = fname; curbuf->b_sfname = sfname; return FAIL; diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 641edf4610..f18ebffa0a 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -5133,9 +5133,11 @@ static void uc_list(char_u *name, size_t name_len) ucmd_T *cmd; int len; uint32_t a; - garray_T *gap; - gap = &curbuf->b_ucmds; + // In cmdwin, the alternative buffer should be used. + garray_T *gap = (cmdwin_type != 0 && get_cmdline_type() == NUL) + ? &prevwin->w_buffer->b_ucmds + : &curbuf->b_ucmds; for (;; ) { for (i = 0; i < gap->ga_len; ++i) { cmd = USER_CMD_GA(gap, i); @@ -5984,13 +5986,21 @@ char_u *get_user_cmd_addr_type(expand_T *xp, int idx) /* * Function given to ExpandGeneric() to obtain the list of user command names. */ -char_u *get_user_commands(expand_T *xp, int idx) +char_u *get_user_commands(expand_T *xp FUNC_ATTR_UNUSED, int idx) + FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { - if (idx < curbuf->b_ucmds.ga_len) - return USER_CMD_GA(&curbuf->b_ucmds, idx)->uc_name; - idx -= curbuf->b_ucmds.ga_len; - if (idx < ucmds.ga_len) + // In cmdwin, the alternative buffer should be used. + const buf_T *const buf = (cmdwin_type != 0 && get_cmdline_type() == NUL) + ? prevwin->w_buffer + : curbuf; + + if (idx < buf->b_ucmds.ga_len) { + return USER_CMD_GA(&buf->b_ucmds, idx)->uc_name; + } + idx -= buf->b_ucmds.ga_len; + if (idx < ucmds.ga_len) { return USER_CMD(idx)->uc_name; + } return NULL; } diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 9e2671ca5e..7948da5e6b 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -5008,19 +5008,24 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file, hashtab_T found_ht; hash_init(&found_ht); for (s = path; ; s = e) { + e = vim_strchr(s, ENV_SEPCHAR); + if (e == NULL) { + e = s + STRLEN(s); + } + if (*s == NUL) { if (did_curdir) { break; } // Find directories in the current directory, path is empty. did_curdir = true; - } else if (*s == '.') { + flags |= EW_DIR; + } else if (STRNCMP(s, ".", e - s) == 0) { did_curdir = true; - } - - e = vim_strchr(s, ENV_SEPCHAR); - if (e == NULL) { - e = s + STRLEN(s); + flags |= EW_DIR; + } else { + // Do not match directories inside a $PATH item. + flags &= ~EW_DIR; } l = (size_t)(e - s); diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index fcf15638c7..f518e59acc 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -3731,8 +3731,9 @@ static int set_rw_fname(char_u *fname, char_u *sfname) return FAIL; } - if (setfname(curbuf, fname, sfname, FALSE) == OK) + if (setfname(curbuf, fname, sfname, false) == OK) { curbuf->b_flags |= BF_NOTEDITED; + } /* ....and a new named one is created */ apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, curbuf); diff --git a/src/nvim/generators/gen_char_blob.lua b/src/nvim/generators/gen_char_blob.lua index 1702add2e4..a7dad50d48 100644 --- a/src/nvim/generators/gen_char_blob.lua +++ b/src/nvim/generators/gen_char_blob.lua @@ -1,49 +1,59 @@ if arg[1] == '--help' then print('Usage:') - print(' gencharblob.lua source target varname') + print(' '..arg[0]..' target source varname [source varname]...') print('') print('Generates C file with big uint8_t blob.') print('Blob will be stored in a static const array named varname.') os.exit() end -assert(#arg == 3) +assert(#arg >= 3 and (#arg - 1) % 2 == 0) -local source_file = arg[1] -local target_file = arg[2] -local varname = arg[3] - -local source = io.open(source_file, 'r') +local target_file = arg[1] or error('Need a target file') local target = io.open(target_file, 'w') target:write('#include <stdint.h>\n\n') -target:write(('static const uint8_t %s[] = {\n'):format(varname)) - -local num_bytes = 0 -local MAX_NUM_BYTES = 15 -- 78 / 5: maximum number of bytes on one line -target:write(' ') - -local increase_num_bytes -increase_num_bytes = function() - num_bytes = num_bytes + 1 - if num_bytes == MAX_NUM_BYTES then - num_bytes = 0 - target:write('\n ') + +local varnames = {} +for argi = 2, #arg, 2 do + local source_file = arg[argi] + local varname = arg[argi + 1] + if varnames[varname] then + error(string.format("varname %q is already specified for file %q", varname, varnames[varname])) end -end + varnames[varname] = source_file + + local source = io.open(source_file, 'r') + or error(string.format("source_file %q doesn't exist", source_file)) + + target:write(('static const uint8_t %s[] = {\n'):format(varname)) -for line in source:lines() do - for i = 1,string.len(line) do - local byte = string.byte(line, i) - assert(byte ~= 0) - target:write(string.format(' %3u,', byte)) + local num_bytes = 0 + local MAX_NUM_BYTES = 15 -- 78 / 5: maximum number of bytes on one line + target:write(' ') + + local increase_num_bytes + increase_num_bytes = function() + num_bytes = num_bytes + 1 + if num_bytes == MAX_NUM_BYTES then + num_bytes = 0 + target:write('\n ') + end + end + + for line in source:lines() do + for i = 1, string.len(line) do + local byte = line:byte(i) + assert(byte ~= 0) + target:write(string.format(' %3u,', byte)) + increase_num_bytes() + end + target:write(string.format(' %3u,', string.byte('\n', 1))) increase_num_bytes() end - target:write(string.format(' %3u,', string.byte('\n', 1))) - increase_num_bytes() -end -target:write(' 0};\n') + target:write(' 0};\n') + source:close() +end -source:close() target:close() diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 093c130c5f..5450f62f54 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -268,12 +268,7 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL #endif // vim - const char *code = (char *)&vim_module[0]; - if (luaL_loadbuffer(lstate, code, strlen(code), "@vim.lua") - || lua_pcall(lstate, 0, LUA_MULTRET, 0)) { - nlua_error(lstate, _("E5106: Error while creating vim module: %.*s")); - return 1; - } + lua_newtable(lstate); // vim.api nlua_add_api_functions(lstate); // vim.types, vim.type_idx, vim.val_idx @@ -334,6 +329,24 @@ static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL lua_setglobal(lstate, "vim"); + { + const char *code = (char *)&shared_module[0]; + if (luaL_loadbuffer(lstate, code, strlen(code), "@shared.lua") + || lua_pcall(lstate, 0, 0, 0)) { + nlua_error(lstate, _("E5106: Error while creating shared module: %.*s")); + return 1; + } + } + + { + const char *code = (char *)&vim_module[0]; + if (luaL_loadbuffer(lstate, code, strlen(code), "@vim.lua") + || lua_pcall(lstate, 0, 0, 0)) { + nlua_error(lstate, _("E5106: Error while creating vim module: %.*s")); + return 1; + } + } + return 0; } diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua index 1665a55aff..e13b44a8ed 100644 --- a/src/nvim/lua/vim.lua +++ b/src/nvim/lua/vim.lua @@ -33,35 +33,35 @@ -- - https://github.com/bakpakin/Fennel (pretty print, repl) -- - https://github.com/howl-editor/howl/tree/master/lib/howl/util +local vim = vim +assert(vim) -- Internal-only until comments in #8107 are addressed. -- Returns: -- {errcode}, {output} -local function _system(cmd) - local out = vim.api.nvim_call_function('system', { cmd }) - local err = vim.api.nvim_get_vvar('shell_error') +function vim._system(cmd) + local out = vim.fn.system(cmd) + local err = vim.v.shell_error return err, out end -- Gets process info from the `ps` command. -- Used by nvim_get_proc() as a fallback. -local function _os_proc_info(pid) +function vim._os_proc_info(pid) if pid == nil or pid <= 0 or type(pid) ~= 'number' then error('invalid pid') end local cmd = { 'ps', '-p', pid, '-o', 'comm=', } - local err, name = _system(cmd) - if 1 == err and string.gsub(name, '%s*', '') == '' then + local err, name = vim._system(cmd) + if 1 == err and vim.trim(name) == '' then return {} -- Process not found. elseif 0 ~= err then - local args_str = vim.api.nvim_call_function('string', { cmd }) - error('command failed: '..args_str) + error('command failed: '..vim.fn.string(cmd)) end - local _, ppid = _system({ 'ps', '-p', pid, '-o', 'ppid=', }) + local _, ppid = vim._system({ 'ps', '-p', pid, '-o', 'ppid=', }) -- Remove trailing whitespace. - name = string.gsub(string.gsub(name, '%s+$', ''), '^.*/', '') - ppid = string.gsub(ppid, '%s+$', '') - ppid = tonumber(ppid) == nil and -1 or tonumber(ppid) + name = vim.trim(name):gsub('^.*/', '') + ppid = tonumber(ppid) or -1 return { name = name, pid = pid, @@ -71,20 +71,19 @@ end -- Gets process children from the `pgrep` command. -- Used by nvim_get_proc_children() as a fallback. -local function _os_proc_children(ppid) +function vim._os_proc_children(ppid) if ppid == nil or ppid <= 0 or type(ppid) ~= 'number' then error('invalid ppid') end local cmd = { 'pgrep', '-P', ppid, } - local err, rv = _system(cmd) - if 1 == err and string.gsub(rv, '%s*', '') == '' then + local err, rv = vim._system(cmd) + if 1 == err and vim.trim(rv) == '' then return {} -- Process not found. elseif 0 ~= err then - local args_str = vim.api.nvim_call_function('string', { cmd }) - error('command failed: '..args_str) + error('command failed: '..vim.fn.string(cmd)) end local children = {} - for s in string.gmatch(rv, '%S+') do + for s in rv:gmatch('%S+') do local i = tonumber(s) if i ~= nil then table.insert(children, i) @@ -98,7 +97,7 @@ end -- Last inserted paths. Used to clear out items from package.[c]path when they -- are no longer in &runtimepath. local last_nvim_paths = {} -local function _update_package_paths() +function vim._update_package_paths() local cur_nvim_paths = {} local rtps = vim.api.nvim_list_runtime_paths() local sep = package.config:sub(1, 1) @@ -162,35 +161,35 @@ local function inspect(object, options) -- luacheck: no unused error(object, options) -- Stub for gen_vimdoc.py end ---- Paste handler, invoked by |nvim_paste()| when a conforming UI ---- (such as the |TUI|) pastes text into the editor. ---- ---- Example: To remove ANSI color codes when pasting: ---- <pre> ---- vim.paste = (function(overridden) ---- return function(lines, phase) ---- for i,line in ipairs(lines) do ---- -- Scrub ANSI color codes from paste input. ---- lines[i] = line:gsub('\27%[[0-9;mK]+', '') ---- end ---- overridden(lines, phase) ---- end ---- end)(vim.paste) ---- </pre> ---- ---@see |paste| ---- ---@param lines |readfile()|-style list of lines to paste. |channel-lines| ---@param phase -1: "non-streaming" paste: the call contains all lines. ---- If paste is "streamed", `phase` indicates the stream state: ---- - 1: starts the paste (exactly once) ---- - 2: continues the paste (zero or more times) ---- - 3: ends the paste (exactly once) ---@returns false if client should cancel the paste. -local function paste(lines, phase) end -- luacheck: no unused -paste = (function() +do local tdots, tick, got_line1 = 0, 0, false - return function(lines, phase) + + --- Paste handler, invoked by |nvim_paste()| when a conforming UI + --- (such as the |TUI|) pastes text into the editor. + --- + --- Example: To remove ANSI color codes when pasting: + --- <pre> + --- vim.paste = (function(overridden) + --- return function(lines, phase) + --- for i,line in ipairs(lines) do + --- -- Scrub ANSI color codes from paste input. + --- lines[i] = line:gsub('\27%[[0-9;mK]+', '') + --- end + --- overridden(lines, phase) + --- end + --- end)(vim.paste) + --- </pre> + --- + --@see |paste| + --- + --@param lines |readfile()|-style list of lines to paste. |channel-lines| + --@param phase -1: "non-streaming" paste: the call contains all lines. + --- If paste is "streamed", `phase` indicates the stream state: + --- - 1: starts the paste (exactly once) + --- - 2: continues the paste (zero or more times) + --- - 3: ends the paste (exactly once) + --@returns false if client should cancel the paste. + function vim.paste(lines, phase) local call = vim.api.nvim_call_function local now = vim.loop.now() local mode = call('mode', {}):sub(1,1) @@ -230,20 +229,33 @@ paste = (function() end return true -- Paste will not continue if not returning `true`. end -end)() +end --- Defers callback `cb` until the Nvim API is safe to call. --- ---@see |lua-loop-callbacks| ---@see |vim.schedule()| ---@see |vim.in_fast_event()| -local function schedule_wrap(cb) +function vim.schedule_wrap(cb) return (function (...) local args = {...} vim.schedule(function() cb(unpack(args)) end) end) end +-- vim.fn.{func}(...) +vim.fn = setmetatable({}, { + __index = function(t, key) + local function _fn(...) + return vim.call(key, ...) + end + t[key] = _fn + return _fn + end +}) + +-- These are for loading runtime modules lazily since they aren't available in +-- the nvim binary as specified in executor.c local function __index(t, key) if key == 'inspect' then t.inspect = require('vim.inspect') @@ -251,10 +263,6 @@ local function __index(t, key) elseif key == 'treesitter' then t.treesitter = require('vim.treesitter') return t.treesitter - elseif require('vim.shared')[key] ~= nil then - -- Expose all `vim.shared` functions on the `vim` module. - t[key] = require('vim.shared')[key] - return t[key] elseif require('vim.uri')[key] ~= nil then -- Expose all `vim.uri` functions on the `vim` module. t[key] = require('vim.uri')[key] @@ -265,29 +273,102 @@ local function __index(t, key) end end +setmetatable(vim, { + __index = __index +}) --- vim.fn.{func}(...) -local function _fn_index(t, key) - local function _fn(...) - return vim.call(key, ...) +do + local a = vim.api + local validate = vim.validate + local function make_meta_accessor(get, set, del) + validate { + get = {get, 'f'}; + set = {set, 'f'}; + del = {del, 'f', true}; + } + local mt = {} + if del then + function mt:__newindex(k, v) + if v == nil then + return del(k) + end + return set(k, v) + end + else + function mt:__newindex(k, v) + return set(k, v) + end + end + function mt:__index(k) + return get(k) + end + return setmetatable({}, mt) + end + local function pcall_ret(status, ...) + if status then return ... end + end + local function nil_wrap(fn) + return function(...) + return pcall_ret(pcall(fn, ...)) + end + end + vim.g = make_meta_accessor(nil_wrap(a.nvim_get_var), a.nvim_set_var, a.nvim_del_var) + vim.v = make_meta_accessor(nil_wrap(a.nvim_get_vvar), a.nvim_set_vvar) + vim.o = make_meta_accessor(a.nvim_get_option, a.nvim_set_option) + vim.env = make_meta_accessor(vim.fn.getenv, vim.fn.setenv) + -- TODO(ashkan) if/when these are available from an API, generate them + -- instead of hardcoding. + local window_options = { + arab = true; arabic = true; breakindent = true; breakindentopt = true; + bri = true; briopt = true; cc = true; cocu = true; + cole = true; colorcolumn = true; concealcursor = true; conceallevel = true; + crb = true; cuc = true; cul = true; cursorbind = true; + cursorcolumn = true; cursorline = true; diff = true; fcs = true; + fdc = true; fde = true; fdi = true; fdl = true; + fdm = true; fdn = true; fdt = true; fen = true; + fillchars = true; fml = true; fmr = true; foldcolumn = true; + foldenable = true; foldexpr = true; foldignore = true; foldlevel = true; + foldmarker = true; foldmethod = true; foldminlines = true; foldnestmax = true; + foldtext = true; lbr = true; lcs = true; linebreak = true; + list = true; listchars = true; nu = true; number = true; + numberwidth = true; nuw = true; previewwindow = true; pvw = true; + relativenumber = true; rightleft = true; rightleftcmd = true; rl = true; + rlc = true; rnu = true; scb = true; scl = true; + scr = true; scroll = true; scrollbind = true; signcolumn = true; + spell = true; statusline = true; stl = true; wfh = true; + wfw = true; winbl = true; winblend = true; winfixheight = true; + winfixwidth = true; winhighlight = true; winhl = true; wrap = true; + } + local function new_buf_opt_accessor(bufnr) + local function get(k) + if window_options[k] then + return a.nvim_err_writeln(k.." is a window option, not a buffer option") + end + if bufnr == nil and type(k) == "number" then + return new_buf_opt_accessor(k) + end + return a.nvim_buf_get_option(bufnr or 0, k) + end + local function set(k, v) + if window_options[k] then + return a.nvim_err_writeln(k.." is a window option, not a buffer option") + end + return a.nvim_buf_set_option(bufnr or 0, k, v) + end + return make_meta_accessor(get, set) + end + vim.bo = new_buf_opt_accessor(nil) + local function new_win_opt_accessor(winnr) + local function get(k) + if winnr == nil and type(k) == "number" then + return new_win_opt_accessor(k) + end + return a.nvim_win_get_option(winnr or nil, k) + end + local function set(k, v) return a.nvim_win_set_option(winnr or nil, k, v) end + return make_meta_accessor(get, set) end - t[key] = _fn - return _fn + vim.wo = new_win_opt_accessor(nil) end -local fn = setmetatable({}, {__index=_fn_index}) - -local module = { - _update_package_paths = _update_package_paths, - _os_proc_children = _os_proc_children, - _os_proc_info = _os_proc_info, - _system = _system, - paste = paste, - schedule_wrap = schedule_wrap, - fn=fn, -} - -setmetatable(module, { - __index = __index -}) return module diff --git a/src/nvim/main.c b/src/nvim/main.c index e39eec4038..c8959d9ad1 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -1516,7 +1516,7 @@ static void create_windows(mparm_T *parmp) /* We can't close the window, it would disturb what * happens next. Clear the file name and set the arg * index to -1 to delete it later. */ - setfname(curbuf, NULL, NULL, FALSE); + setfname(curbuf, NULL, NULL, false); curwin->w_arg_idx = -1; swap_exists_action = SEA_NONE; } else diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 2824d57f49..e5ba17a0a7 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -540,7 +540,7 @@ void ml_open_file(buf_T *buf) /// file, or reading into an existing buffer, create a swap file now. /// /// @param newfile reading file into new buffer -void check_need_swap(int newfile) +void check_need_swap(bool newfile) { int old_msg_silent = msg_silent; // might be reset by an E325 message msg_silent = 0; // If swap dialog prompts for input, user needs to see it! @@ -937,8 +937,9 @@ void ml_recover(bool checkext) */ if (directly) { expand_env(b0p->b0_fname, NameBuff, MAXPATHL); - if (setfname(curbuf, NameBuff, NULL, TRUE) == FAIL) + if (setfname(curbuf, NameBuff, NULL, true) == FAIL) { goto theend; + } } home_replace(NULL, mfp->mf_fname, NameBuff, MAXPATHL, TRUE); diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index d0aa0653cb..deb7ee6342 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -508,31 +508,30 @@ static win_T *mouse_find_grid_win(int *gridp, int *rowp, int *colp) return NULL; } -/* - * setmouse() - switch mouse on/off depending on current mode and 'mouse' - */ +/// Set UI mouse depending on current mode and 'mouse'. +/// +/// Emits mouse_on/mouse_off UI event (unless 'mouse' is empty). void setmouse(void) { - int checkfor; - ui_cursor_shape(); - /* be quick when mouse is off */ - if (*p_mouse == NUL) + // Be quick when mouse is off. + if (*p_mouse == NUL) { return; + } - if (VIsual_active) + int checkfor = MOUSE_NORMAL; // assume normal mode + if (VIsual_active) { checkfor = MOUSE_VISUAL; - else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE) + } else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE) { checkfor = MOUSE_RETURN; - else if (State & INSERT) + } else if (State & INSERT) { checkfor = MOUSE_INSERT; - else if (State & CMDLINE) + } else if (State & CMDLINE) { checkfor = MOUSE_COMMAND; - else if (State == CONFIRM || State == EXTERNCMD) - checkfor = ' '; /* don't use mouse for ":confirm" or ":!cmd" */ - else - checkfor = MOUSE_NORMAL; /* assume normal mode */ + } else if (State == CONFIRM || State == EXTERNCMD) { + checkfor = ' '; // don't use mouse for ":confirm" or ":!cmd" + } if (mouse_has(checkfor)) { ui_call_mouse_on(); diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 2ef2c3101f..b9dbcc6805 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -1422,12 +1422,12 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) if (oap->motion_type == kMTLineWise) { oap->inclusive = false; } else if (oap->motion_type == kMTCharWise) { - // If the motion already was characterwise, toggle "inclusive" + // If the motion already was charwise, toggle "inclusive" oap->inclusive = !oap->inclusive; } oap->motion_type = kMTCharWise; } else if (oap->motion_force == Ctrl_V) { - // Change line- or characterwise motion into Visual block mode. + // Change line- or charwise motion into Visual block mode. if (!VIsual_active) { VIsual_active = true; VIsual = oap->start; @@ -1516,7 +1516,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) } // In Select mode, a linewise selection is operated upon like a - // characterwise selection. + // charwise selection. // Special case: gH<Del> deletes the last line. if (VIsual_select && VIsual_mode == 'V' && cap->oap->op_type != OP_DELETE) { @@ -4588,7 +4588,7 @@ static void nv_colon(cmdarg_T *cap) nv_operator(cap); } else { if (cap->oap->op_type != OP_NOP) { - // Using ":" as a movement is characterwise exclusive. + // Using ":" as a movement is charwise exclusive. cap->oap->motion_type = kMTCharWise; cap->oap->inclusive = false; } else if (cap->count0 && !is_cmdkey) { @@ -6372,8 +6372,8 @@ static void nv_visual(cmdarg_T *cap) if (cap->cmdchar == Ctrl_Q) cap->cmdchar = Ctrl_V; - /* 'v', 'V' and CTRL-V can be used while an operator is pending to make it - * characterwise, linewise, or blockwise. */ + // 'v', 'V' and CTRL-V can be used while an operator is pending to make it + // charwise, linewise, or blockwise. if (cap->oap->op_type != OP_NOP) { motion_force = cap->oap->motion_force = cap->cmdchar; finish_op = false; // operator doesn't finish now but later @@ -7887,15 +7887,17 @@ static void nv_put_opt(cmdarg_T *cap, bool fix_indent) cap->oap->regname = regname; } - /* When deleted a linewise Visual area, put the register as - * lines to avoid it joined with the next line. When deletion was - * characterwise, split a line when putting lines. */ - if (VIsual_mode == 'V') + // When deleted a linewise Visual area, put the register as + // lines to avoid it joined with the next line. When deletion was + // charwise, split a line when putting lines. + if (VIsual_mode == 'V') { flags |= PUT_LINE; - else if (VIsual_mode == 'v') + } else if (VIsual_mode == 'v') { flags |= PUT_LINE_SPLIT; - if (VIsual_mode == Ctrl_V && dir == FORWARD) + } + if (VIsual_mode == Ctrl_V && dir == FORWARD) { flags |= PUT_LINE_FORWARD; + } dir = BACKWARD; if ((VIsual_mode != 'V' && curwin->w_cursor.col < curbuf->b_op_start.col) diff --git a/src/nvim/ops.c b/src/nvim/ops.c index f2d35d5e43..294c65ca03 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -5204,8 +5204,7 @@ void write_reg_contents_lst(int name, char_u **strings, /// write_reg_contents_ex - store `str` in register `name` /// -/// If `str` ends in '\n' or '\r', use linewise, otherwise use -/// characterwise. +/// If `str` ends in '\n' or '\r', use linewise, otherwise use charwise. /// /// @warning when `name` is '/', `len` and `must_append` are ignored. This /// means that `str` MUST be NUL-terminated. diff --git a/src/nvim/option.c b/src/nvim/option.c index 25933d497e..68ab310329 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -5195,6 +5195,13 @@ void ui_refresh_options(void) } ui_call_option_set(name, value); } + if (p_mouse != NULL) { + if (*p_mouse == NUL) { + ui_call_mouse_off(); + } else { + setmouse(); + } + } } /* diff --git a/src/nvim/po/af.po b/src/nvim/po/af.po index 61ad72d7e0..79048eac39 100644 --- a/src/nvim/po/af.po +++ b/src/nvim/po/af.po @@ -100,7 +100,7 @@ msgid "E88: Cannot go before first buffer" msgstr "E88: Kan nie vóór eerste buffer gaan nie" #, fuzzy, c-format -#~ msgid "E89: %s will be killed(add ! to override)" +#~ msgid "E89: %s will be killed (add ! to override)" #~ msgstr "E189: \"%s\" bestaan (gebruik ! om te dwing)" #, c-format diff --git a/src/nvim/po/fi.po b/src/nvim/po/fi.po index 4612988c95..f568a34b3c 100644 --- a/src/nvim/po/fi.po +++ b/src/nvim/po/fi.po @@ -323,7 +323,7 @@ msgid "E88: Cannot go before first buffer" msgstr "E88: Ensimmäisen puskurin ohi ei voi edetä" #, fuzzy, c-format -#~ msgid "E89: %s will be killed(add ! to override)" +#~ msgid "E89: %s will be killed (add ! to override)" #~ msgstr "E189: %s on jo olemassa (lisää komentoon ! ohittaaksesi)" #, fuzzy, c-format diff --git a/src/nvim/po/uk.po b/src/nvim/po/uk.po index 211d38e53a..19ea8e897a 100644 --- a/src/nvim/po/uk.po +++ b/src/nvim/po/uk.po @@ -87,8 +87,8 @@ msgid "E88: Cannot go before first buffer" msgstr "E88: Це вже найперший буфер" #, c-format -msgid "E89: %s will be killed(add ! to override)" -msgstr "E89: «%s» буде вбито(! щоб не зважати)" +msgid "E89: %s will be killed (add ! to override)" +msgstr "E89: «%s» буде вбито (! щоб не зважати)" #, c-format msgid "" diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index ed57b28029..194cc5781b 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -1,9 +1,7 @@ // 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 -/* - * quickfix.c: functions for quickfix mode, using a file with error messages - */ +// quickfix.c: functions for quickfix mode, using a file with error messages #include <assert.h> #include <inttypes.h> @@ -53,9 +51,7 @@ struct dir_stack_T { char_u *dirname; }; -/* - * For each error the next struct is allocated and linked in a list. - */ +// For each error the next struct is allocated and linked in a list. typedef struct qfline_S qfline_T; struct qfline_S { qfline_T *qf_next; ///< pointer to next error in the list @@ -74,9 +70,7 @@ struct qfline_S { char_u qf_valid; ///< valid error message detected }; -/* - * There is a stack of error lists. - */ +// There is a stack of error lists. #define LISTCOUNT 10 #define INVALID_QFIDX (-1) @@ -120,15 +114,13 @@ typedef struct qf_list_S { /// Quickfix/Location list stack definition /// Contains a list of quickfix/location lists (qf_list_T) struct qf_info_S { - /* - * Count of references to this list. Used only for location lists. - * When a location list window reference this list, qf_refcount - * will be 2. Otherwise, qf_refcount will be 1. When qf_refcount - * reaches 0, the list is freed. - */ + // Count of references to this list. Used only for location lists. + // When a location list window reference this list, qf_refcount + // will be 2. Otherwise, qf_refcount will be 1. When qf_refcount + // reaches 0, the list is freed. int qf_refcount; - int qf_listcount; /* current number of lists */ - int qf_curlist; /* current error list */ + int qf_listcount; // current number of lists + int qf_curlist; // current error list qf_list_T qf_lists[LISTCOUNT]; qfltype_T qfl_type; // type of list }; @@ -138,31 +130,29 @@ static unsigned last_qf_id = 0; // Last Used quickfix list id #define FMT_PATTERNS 11 // maximum number of % recognized -/* - * Structure used to hold the info of one part of 'errorformat' - */ +// Structure used to hold the info of one part of 'errorformat' typedef struct efm_S efm_T; struct efm_S { - regprog_T *prog; /* pre-formatted part of 'errorformat' */ - efm_T *next; /* pointer to next (NULL if last) */ - char_u addr[FMT_PATTERNS]; /* indices of used % patterns */ - char_u prefix; /* prefix of this format line: */ - /* 'D' enter directory */ - /* 'X' leave directory */ - /* 'A' start of multi-line message */ - /* 'E' error message */ - /* 'W' warning message */ - /* 'I' informational message */ - /* 'C' continuation line */ - /* 'Z' end of multi-line message */ - /* 'G' general, unspecific message */ - /* 'P' push file (partial) message */ - /* 'Q' pop/quit file (partial) message */ - /* 'O' overread (partial) message */ - char_u flags; /* additional flags given in prefix */ - /* '-' do not include this line */ - /* '+' include whole line in message */ - int conthere; /* %> used */ + regprog_T *prog; // pre-formatted part of 'errorformat' + efm_T *next; // pointer to next (NULL if last) + char_u addr[FMT_PATTERNS]; // indices of used % patterns + char_u prefix; // prefix of this format line: + // 'D' enter directory + // 'X' leave directory + // 'A' start of multi-line message + // 'E' error message + // 'W' warning message + // 'I' informational message + // 'C' continuation line + // 'Z' end of multi-line message + // 'G' general, unspecific message + // 'P' push file (partial) message + // 'Q' pop/quit file (partial) message + // 'O' overread (partial) message + char_u flags; // additional flags given in prefix + // '-' do not include this line + // '+' include whole line in message + int conthere; // %> used }; /// List of location lists to be deleted. @@ -221,7 +211,7 @@ static char_u *e_no_more_items = (char_u *)N_("E553: No more items"); // Quickfix window check helper macro #define IS_QF_WINDOW(wp) (bt_quickfix(wp->w_buffer) && wp->w_llist_ref == NULL) -/* Location list window check helper macro */ +// Location list window check helper macro #define IS_LL_WINDOW(wp) (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL) // Quickfix and location list stack check helper macros @@ -1156,16 +1146,12 @@ qf_init_ext( goto error2; } - /* - * got_int is reset here, because it was probably set when killing the - * ":make" command, but we still want to read the errorfile then. - */ - got_int = FALSE; + // got_int is reset here, because it was probably set when killing the + // ":make" command, but we still want to read the errorfile then. + got_int = false; - /* - * Read the lines in the error file one by one. - * Try to recognize one of the error formats in each line. - */ + // Read the lines in the error file one by one. + // Try to recognize one of the error formats in each line. while (!got_int) { status = qf_init_process_nextline(qfl, fmt_first, &state, &fields); if (status == QF_END_OF_INPUT) { // end of input @@ -1263,10 +1249,8 @@ static void qf_new_list(qf_info_T *qi, const char_u *qf_title) qf_free(&qi->qf_lists[--qi->qf_listcount]); } - /* - * When the stack is full, remove to oldest entry - * Otherwise, add a new entry. - */ + // When the stack is full, remove to oldest entry + // Otherwise, add a new entry. if (qi->qf_listcount == LISTCOUNT) { qf_free(&qi->qf_lists[0]); for (i = 1; i < LISTCOUNT; i++) { @@ -1714,7 +1698,7 @@ static void ll_free_all(qf_info_T **pqi) qi = *pqi; if (qi == NULL) return; - *pqi = NULL; /* Remove reference to this list */ + *pqi = NULL; // Remove reference to this list qi->qf_refcount--; if (qi->qf_refcount < 1) { @@ -1739,7 +1723,7 @@ void qf_free_all(win_T *wp) qf_info_T *qi = &ql_info; if (wp != NULL) { - /* location list */ + // location list ll_free_all(&wp->w_llist); ll_free_all(&wp->w_llist_ref); } else { @@ -1892,14 +1876,13 @@ static qf_info_T *qf_alloc_stack(qfltype_T qfltype) static qf_info_T *ll_get_or_alloc_list(win_T *wp) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET { - if (IS_LL_WINDOW(wp)) - /* For a location list window, use the referenced location list */ + if (IS_LL_WINDOW(wp)) { + // For a location list window, use the referenced location list return wp->w_llist_ref; + } - /* - * For a non-location list window, w_llist_ref should not point to a - * location list. - */ + // For a non-location list window, w_llist_ref should not point to a + // location list. ll_free_all(&wp->w_llist_ref); if (wp->w_llist == NULL) { @@ -2133,22 +2116,21 @@ static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr, { struct dir_stack_T *ds_ptr; - /* allocate new stack element and hook it in */ + // allocate new stack element and hook it in struct dir_stack_T *ds_new = xmalloc(sizeof(struct dir_stack_T)); ds_new->next = *stackptr; *stackptr = ds_new; - /* store directory on the stack */ + // store directory on the stack if (vim_isAbsName(dirbuf) || (*stackptr)->next == NULL - || (*stackptr && is_file_stack)) + || (*stackptr && is_file_stack)) { (*stackptr)->dirname = vim_strsave(dirbuf); - else { - /* Okay we don't have an absolute path. - * dirbuf must be a subdir of one of the directories on the stack. - * Let's search... - */ + } else { + // Okay we don't have an absolute path. + // dirbuf must be a subdir of one of the directories on the stack. + // Let's search... ds_new = (*stackptr)->next; (*stackptr)->dirname = NULL; while (ds_new) { @@ -2161,7 +2143,7 @@ static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr, ds_new = ds_new->next; } - /* clean up all dirs we already left */ + // clean up all dirs we already left while ((*stackptr)->next != ds_new) { ds_ptr = (*stackptr)->next; (*stackptr)->next = (*stackptr)->next->next; @@ -2169,7 +2151,7 @@ static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr, xfree(ds_ptr); } - /* Nothing found -> it must be on top level */ + // Nothing found -> it must be on top level if (ds_new == NULL) { xfree((*stackptr)->dirname); (*stackptr)->dirname = vim_strsave(dirbuf); @@ -2187,18 +2169,16 @@ static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr, } -/* - * pop dirbuf from the directory stack and return previous directory or NULL if - * stack is empty - */ +// pop dirbuf from the directory stack and return previous directory or NULL if +// stack is empty static char_u *qf_pop_dir(struct dir_stack_T **stackptr) { struct dir_stack_T *ds_ptr; - /* TODO: Should we check if dirbuf is the directory on top of the stack? - * What to do if it isn't? */ + // TODO(vim): Should we check if dirbuf is the directory on top of the stack? + // What to do if it isn't? - /* pop top element and free it */ + // pop top element and free it if (*stackptr != NULL) { ds_ptr = *stackptr; *stackptr = (*stackptr)->next; @@ -2206,13 +2186,11 @@ static char_u *qf_pop_dir(struct dir_stack_T **stackptr) xfree(ds_ptr); } - /* return NEW top element as current dir or NULL if stack is empty*/ + // return NEW top element as current dir or NULL if stack is empty return *stackptr ? (*stackptr)->dirname : NULL; } -/* - * clean up directory stack - */ +// clean up directory stack static void qf_clean_dir_stack(struct dir_stack_T **stackptr) { struct dir_stack_T *ds_ptr; @@ -2887,10 +2865,8 @@ void qf_jump(qf_info_T *qi, int dir, int errornr, int forceit) } } - /* - * If there is a file name, - * read the wanted file if needed, and check autowrite etc. - */ + // If there is a file name, + // read the wanted file if needed, and check autowrite etc. old_curbuf = curbuf; old_lnum = curwin->w_cursor.lnum; @@ -2938,8 +2914,8 @@ theend: qfl->qf_index = qf_index; } if (p_swb != old_swb && opened_window) { - /* Restore old 'switchbuf' value, but not when an autocommand or - * modeline has changed the value. */ + // Restore old 'switchbuf' value, but not when an autocommand or + // modeline has changed the value. if (p_swb == empty_option) { p_swb = old_swb; swb_flags = old_swb_flags; @@ -3038,10 +3014,8 @@ static void qf_list_entry(qfline_T *qfp, int qf_idx, bool cursel) ui_flush(); // show one line at a time } -/* - * ":clist": list all errors - * ":llist": list all locations - */ +// ":clist": list all errors +// ":llist": list all locations void qf_list(exarg_T *eap) { qf_list_T *qfl; @@ -3116,10 +3090,8 @@ void qf_list(exarg_T *eap) } } -/* - * Remove newlines and leading whitespace from an error message. - * Put the result in "buf[bufsize]". - */ +// Remove newlines and leading whitespace from an error message. +// Put the result in "buf[bufsize]". static void qf_fmt_text(const char_u *restrict text, char_u *restrict buf, int bufsize) FUNC_ATTR_NONNULL_ALL @@ -3277,9 +3249,7 @@ static void qf_free(qf_list_T *qfl) qfl->qf_changedtick = 0L; } -/* - * qf_mark_adjust: adjust marks - */ +// qf_mark_adjust: adjust marks bool qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, long amount_after) { @@ -3321,21 +3291,19 @@ bool qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, return found_one; } -/* - * Make a nice message out of the error character and the error number: - * char number message - * e or E 0 " error" - * w or W 0 " warning" - * i or I 0 " info" - * 0 0 "" - * other 0 " c" - * e or E n " error n" - * w or W n " warning n" - * i or I n " info n" - * 0 n " error n" - * other n " c n" - * 1 x "" :helpgrep - */ +// Make a nice message out of the error character and the error number: +// char number message +// e or E 0 " error" +// w or W 0 " warning" +// i or I 0 " info" +// 0 0 "" +// other 0 " c" +// e or E n " error n" +// w or W n " warning n" +// i or I n " info n" +// 0 n " error n" +// other n " c n" +// 1 x "" :helpgrep static char_u *qf_types(int c, int nr) { static char_u buf[20]; @@ -3396,12 +3364,10 @@ void qf_view_result(bool split) do_cmdline_cmd((IS_LL_WINDOW(curwin) ? ".ll" : ".cc")); } -/* - * ":cwindow": open the quickfix window if we have errors to display, - * close it if not. - * ":lwindow": open the location list window if we have locations to display, - * close it if not. - */ +// ":cwindow": open the quickfix window if we have errors to display, +// close it if not. +// ":lwindow": open the location list window if we have locations to display, +// close it if not. void ex_cwindow(exarg_T *eap) { qf_info_T *qi; @@ -3414,14 +3380,12 @@ void ex_cwindow(exarg_T *eap) qfl = qf_get_curlist(qi); - /* Look for an existing quickfix window. */ + // Look for an existing quickfix window. win = qf_find_win(qi); - /* - * If a quickfix window is open but we have no errors to display, - * close the window. If a quickfix window is not open, then open - * it if we have errors; otherwise, leave it closed. - */ + // If a quickfix window is open but we have no errors to display, + // close the window. If a quickfix window is not open, then open + // it if we have errors; otherwise, leave it closed. if (qf_stack_empty(qi) || qfl->qf_nonevalid || qf_list_empty(qf_get_curlist(qi))) { @@ -3433,10 +3397,8 @@ void ex_cwindow(exarg_T *eap) } } -/* - * ":cclose": close the window showing the list of errors. - * ":lclose": close the window showing the location list - */ +// ":cclose": close the window showing the list of errors. +// ":lclose": close the window showing the location list void ex_cclose(exarg_T *eap) { win_T *win = NULL; @@ -3446,7 +3408,7 @@ void ex_cclose(exarg_T *eap) return; } - /* Find existing quickfix window and close it. */ + // Find existing quickfix window and close it. win = qf_find_win(qi); if (win != NULL) { win_close(win, false); @@ -3642,38 +3604,32 @@ void ex_cbottom(exarg_T *eap) } } -/* - * Return the number of the current entry (line number in the quickfix - * window). - */ +// Return the number of the current entry (line number in the quickfix +// window). linenr_T qf_current_entry(win_T *wp) { qf_info_T *qi = &ql_info; - if (IS_LL_WINDOW(wp)) - /* In the location list window, use the referenced location list */ + if (IS_LL_WINDOW(wp)) { + // In the location list window, use the referenced location list qi = wp->w_llist_ref; + } return qf_get_curlist(qi)->qf_index; } -/* - * Update the cursor position in the quickfix window to the current error. - * Return TRUE if there is a quickfix window. - */ -static int -qf_win_pos_update ( +// Update the cursor position in the quickfix window to the current error. +// Return TRUE if there is a quickfix window. +static int qf_win_pos_update( qf_info_T *qi, - int old_qf_index /* previous qf_index or zero */ + int old_qf_index // previous qf_index or zero ) { win_T *win; int qf_index = qf_get_curlist(qi)->qf_index; - /* - * Put the cursor on the current error in the quickfix window, so that - * it's viewable. - */ + // Put the cursor on the current error in the quickfix window, so that + // it's viewable. win = qf_find_win(qi); if (win != NULL && qf_index <= win->w_buffer->b_ml.ml_line_count @@ -3725,10 +3681,8 @@ static win_T *qf_find_win(const qf_info_T *qi) return NULL; } -/* - * Find a quickfix buffer. - * Searches in windows opened in all the tabs. - */ +// Find a quickfix buffer. +// Searches in windows opened in all the tabs. static buf_T *qf_find_buf(const qf_info_T *qi) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { @@ -3754,16 +3708,14 @@ static void qf_update_win_titlevar(qf_info_T *qi) } } -/* - * Find the quickfix buffer. If it exists, update the contents. - */ +// Find the quickfix buffer. If it exists, update the contents. static void qf_update_buffer(qf_info_T *qi, qfline_T *old_last) { buf_T *buf; win_T *win; aco_save_T aco; - /* Check if a buffer for the quickfix list exists. Update it. */ + // Check if a buffer for the quickfix list exists. Update it. buf = qf_find_buf(qi); if (buf != NULL) { linenr_T old_line_count = buf->b_ml.ml_line_count; @@ -3936,7 +3888,7 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last) redraw_curbuf_later(NOT_VALID); } - /* Restore KeyTyped, setting 'filetype' may reset it. */ + // Restore KeyTyped, setting 'filetype' may reset it. KeyTyped = old_KeyTyped; } @@ -3990,9 +3942,7 @@ static void qf_jump_first(qf_info_T *qi, unsigned save_qfid, int forceit) } } -/* - * Return TRUE when using ":vimgrep" for ":grep". - */ +// Return TRUE when using ":vimgrep" for ":grep". int grep_internal(cmdidx_T cmdidx) { return (cmdidx == CMD_grep @@ -4055,9 +4005,7 @@ static char *make_get_fullcmd(const char_u *makecmd, const char_u *fname) return cmd; } -/* - * Used for ":make", ":lmake", ":grep", ":lgrep", ":grepadd", and ":lgrepadd" - */ +// Used for ":make", ":lmake", ":grep", ":lgrep", ":grepadd", and ":lgrepadd" void ex_make(exarg_T *eap) { char_u *fname; @@ -4128,11 +4076,9 @@ cleanup: xfree(cmd); } -/* - * Return the name for the errorfile, in allocated memory. - * Find a new unique name when 'makeef' contains "##". - * Returns NULL for error. - */ +// Return the name for the errorfile, in allocated memory. +// Find a new unique name when 'makeef' contains "##". +// Returns NULL for error. static char_u *get_mef_name(void) { char_u *p; @@ -4154,7 +4100,7 @@ static char_u *get_mef_name(void) if (*p == NUL) return vim_strsave(p_mef); - /* Keep trying until the name doesn't exist yet. */ + // Keep trying until the name doesn't exist yet. for (;; ) { if (start == -1) { start = (int)os_get_pid(); @@ -4703,10 +4649,8 @@ static char_u * cfile_get_auname(cmdidx_T cmdidx) } -/* - * ":cfile"/":cgetfile"/":caddfile" commands. - * ":lfile"/":lgetfile"/":laddfile" commands. - */ +// ":cfile"/":cgetfile"/":caddfile" commands. +// ":lfile"/":lgetfile"/":laddfile" commands. void ex_cfile(exarg_T *eap) { win_T *wp = NULL; @@ -4947,12 +4891,10 @@ static void vgr_jump_to_match(qf_info_T *qi, int forceit, int *redraw_for_dummy, } } -/* - * ":vimgrep {pattern} file(s)" - * ":vimgrepadd {pattern} file(s)" - * ":lvimgrep {pattern} file(s)" - * ":lvimgrepadd {pattern} file(s)" - */ +// ":vimgrep {pattern} file(s)" +// ":vimgrepadd {pattern} file(s)" +// ":lvimgrep {pattern} file(s)" +// ":lvimgrepadd {pattern} file(s)" void ex_vimgrep(exarg_T *eap) { regmmatch_T regmatch; @@ -4994,7 +4936,7 @@ void ex_vimgrep(exarg_T *eap) else tomatch = MAXLNUM; - /* Get the search pattern: either white-separated or enclosed in // */ + // Get the search pattern: either white-separated or enclosed in // regmatch.regprog = NULL; char_u *title = vim_strsave(qf_cmdtitle(*eap->cmdlinep)); p = skip_vimgrep_pat(eap->arg, &s, &flags); @@ -5021,9 +4963,10 @@ void ex_vimgrep(exarg_T *eap) qf_new_list(qi, title); } - /* parse the list of arguments */ - if (get_arglist_exp(p, &fcount, &fnames, true) == FAIL) + // parse the list of arguments + if (get_arglist_exp(p, &fcount, &fnames, true) == FAIL) { goto theend; + } if (fcount == 0) { EMSG(_(e_nomatch)); goto theend; @@ -5032,8 +4975,8 @@ void ex_vimgrep(exarg_T *eap) dirname_start = xmalloc(MAXPATHL); dirname_now = xmalloc(MAXPATHL); - /* Remember the current directory, because a BufRead autocommand that does - * ":lcd %:p:h" changes the meaning of short path names. */ + // Remember the current directory, because a BufRead autocommand that does + // ":lcd %:p:h" changes the meaning of short path names. os_dirname(dirname_start, MAXPATHL); incr_quickfix_busy(); @@ -5046,15 +4989,15 @@ void ex_vimgrep(exarg_T *eap) for (fi = 0; fi < fcount && !got_int && tomatch > 0; fi++) { fname = path_try_shorten_fname(fnames[fi]); if (time(NULL) > seconds) { - /* Display the file name every second or so, show the user we are - * working on it. */ + // Display the file name every second or so, show the user we are + // working on it. seconds = time(NULL); vgr_display_fname(fname); } buf = buflist_findname_exp(fnames[fi]); if (buf == NULL || buf->b_ml.ml_mfp == NULL) { - /* Remember that a buffer with this name already exists. */ + // Remember that a buffer with this name already exists. duplicate_name = (buf != NULL); using_dummy = TRUE; redraw_for_dummy = TRUE; @@ -5087,20 +5030,20 @@ void ex_vimgrep(exarg_T *eap) if (found_match && first_match_buf == NULL) first_match_buf = buf; if (duplicate_name) { - /* Never keep a dummy buffer if there is another buffer - * with the same name. */ + // Never keep a dummy buffer if there is another buffer + // with the same name. wipe_dummy_buffer(buf, dirname_start); buf = NULL; } else if (!cmdmod.hide - || buf->b_p_bh[0] == 'u' /* "unload" */ - || buf->b_p_bh[0] == 'w' /* "wipe" */ - || buf->b_p_bh[0] == 'd') { /* "delete" */ - /* When no match was found we don't need to remember the - * buffer, wipe it out. If there was a match and it - * wasn't the first one or we won't jump there: only - * unload the buffer. - * Ignore 'hidden' here, because it may lead to having too - * many swap files. */ + || buf->b_p_bh[0] == 'u' // "unload" + || buf->b_p_bh[0] == 'w' // "wipe" + || buf->b_p_bh[0] == 'd') { // "delete" + // When no match was found we don't need to remember the + // buffer, wipe it out. If there was a match and it + // wasn't the first one or we won't jump there: only + // unload the buffer. + // Ignore 'hidden' here, because it may lead to having too + // many swap files. if (!found_match) { wipe_dummy_buffer(buf, dirname_start); buf = NULL; @@ -5124,10 +5067,10 @@ void ex_vimgrep(exarg_T *eap) target_dir = vim_strsave(dirname_now); } - /* The buffer is still loaded, the Filetype autocommands - * need to be done now, in that buffer. And the modelines - * need to be done (again). But not the window-local - * options! */ + // The buffer is still loaded, the Filetype autocommands + // need to be done now, in that buffer. And the modelines + // need to be done (again). But not the window-local + // options! aucmd_prepbuf(&aco, buf); apply_autocmds(EVENT_FILETYPE, buf->b_p_ft, buf->b_fname, TRUE, buf); @@ -5171,8 +5114,8 @@ void ex_vimgrep(exarg_T *eap) decr_quickfix_busy(); - /* If we loaded a dummy buffer into the current window, the autocommands - * may have messed up things, need to redraw and recompute folds. */ + // If we loaded a dummy buffer into the current window, the autocommands + // may have messed up things, need to redraw and recompute folds. if (redraw_for_dummy) { foldUpdateAll(curwin); } @@ -5185,18 +5128,16 @@ theend: vim_regfree(regmatch.regprog); } -/* - * Restore current working directory to "dirname_start" if they differ, taking - * into account whether it is set locally or globally. - */ +// Restore current working directory to "dirname_start" if they differ, taking +// into account whether it is set locally or globally. static void restore_start_dir(char_u *dirname_start) { char_u *dirname_now = xmalloc(MAXPATHL); os_dirname(dirname_now, MAXPATHL); if (STRCMP(dirname_start, dirname_now) != 0) { - /* If the directory has changed, change it back by building up an - * appropriate ex command and executing it. */ + // If the directory has changed, change it back by building up an + // appropriate ex command and executing it. exarg_T ea = { .arg = dirname_start, .cmdidx = (curwin->w_localdir == NULL) ? CMD_cd : CMD_lcd, @@ -5206,23 +5147,21 @@ static void restore_start_dir(char_u *dirname_start) xfree(dirname_now); } -/* - * Load file "fname" into a dummy buffer and return the buffer pointer, - * placing the directory resulting from the buffer load into the - * "resulting_dir" pointer. "resulting_dir" must be allocated by the caller - * prior to calling this function. Restores directory to "dirname_start" prior - * to returning, if autocmds or the 'autochdir' option have changed it. - * - * If creating the dummy buffer does not fail, must call unload_dummy_buffer() - * or wipe_dummy_buffer() later! - * - * Returns NULL if it fails. - */ +// Load file "fname" into a dummy buffer and return the buffer pointer, +// placing the directory resulting from the buffer load into the +// "resulting_dir" pointer. "resulting_dir" must be allocated by the caller +// prior to calling this function. Restores directory to "dirname_start" prior +// to returning, if autocmds or the 'autochdir' option have changed it. +// +// If creating the dummy buffer does not fail, must call unload_dummy_buffer() +// or wipe_dummy_buffer() later! +// +// Returns NULL if it fails. static buf_T * load_dummy_buffer ( char_u *fname, - char_u *dirname_start, /* in: old directory */ - char_u *resulting_dir /* out: new directory */ + char_u *dirname_start, // in: old directory + char_u *resulting_dir // out: new directory ) { buf_T *newbuf; @@ -5239,24 +5178,24 @@ load_dummy_buffer ( } set_bufref(&newbufref, newbuf); - /* Init the options. */ + // Init the options. buf_copy_options(newbuf, BCO_ENTER | BCO_NOHELP); - /* need to open the memfile before putting the buffer in a window */ + // need to open the memfile before putting the buffer in a window if (ml_open(newbuf) == OK) { // Make sure this buffer isn't wiped out by autocommands. newbuf->b_locked++; // set curwin/curbuf to buf and save a few things aucmd_prepbuf(&aco, newbuf); - /* Need to set the filename for autocommands. */ - (void)setfname(curbuf, fname, NULL, FALSE); + // Need to set the filename for autocommands. + (void)setfname(curbuf, fname, NULL, false); - /* Create swap file now to avoid the ATTENTION message. */ - check_need_swap(TRUE); + // Create swap file now to avoid the ATTENTION message. + check_need_swap(true); - /* Remove the "dummy" flag, otherwise autocommands may not - * work. */ + // Remove the "dummy" flag, otherwise autocommands may not + // work. curbuf->b_flags &= ~BF_DUMMY; newbuf_to_wipe.br_buf = NULL; @@ -5289,11 +5228,9 @@ load_dummy_buffer ( newbuf->b_flags |= BF_DUMMY; } - /* - * When autocommands/'autochdir' option changed directory: go back. - * Let the caller know what the resulting dir was first, in case it is - * important. - */ + // When autocommands/'autochdir' option changed directory: go back. + // Let the caller know what the resulting dir was first, in case it is + // important. os_dirname(resulting_dir, MAXPATHL); restore_start_dir(dirname_start); @@ -5307,42 +5244,38 @@ load_dummy_buffer ( return newbuf; } -/* - * Wipe out the dummy buffer that load_dummy_buffer() created. Restores - * directory to "dirname_start" prior to returning, if autocmds or the - * 'autochdir' option have changed it. - */ +// Wipe out the dummy buffer that load_dummy_buffer() created. Restores +// directory to "dirname_start" prior to returning, if autocmds or the +// 'autochdir' option have changed it. static void wipe_dummy_buffer(buf_T *buf, char_u *dirname_start) { - if (curbuf != buf) { /* safety check */ + if (curbuf != buf) { // safety check cleanup_T cs; - /* Reset the error/interrupt/exception state here so that aborting() - * returns FALSE when wiping out the buffer. Otherwise it doesn't - * work when got_int is set. */ + // Reset the error/interrupt/exception state here so that aborting() + // returns FALSE when wiping out the buffer. Otherwise it doesn't + // work when got_int is set. enter_cleanup(&cs); wipe_buffer(buf, FALSE); - /* Restore the error/interrupt/exception state if not discarded by a - * new aborting error, interrupt, or uncaught exception. */ + // Restore the error/interrupt/exception state if not discarded by a + // new aborting error, interrupt, or uncaught exception. leave_cleanup(&cs); - /* When autocommands/'autochdir' option changed directory: go back. */ + // When autocommands/'autochdir' option changed directory: go back. restore_start_dir(dirname_start); } } -/* - * Unload the dummy buffer that load_dummy_buffer() created. Restores - * directory to "dirname_start" prior to returning, if autocmds or the - * 'autochdir' option have changed it. - */ +// Unload the dummy buffer that load_dummy_buffer() created. Restores +// directory to "dirname_start" prior to returning, if autocmds or the +// 'autochdir' option have changed it. static void unload_dummy_buffer(buf_T *buf, char_u *dirname_start) { - if (curbuf != buf) { /* safety check */ - close_buffer(NULL, buf, DOBUF_UNLOAD, FALSE); + if (curbuf != buf) { // safety check + close_buffer(NULL, buf, DOBUF_UNLOAD, false); - /* When autocommands/'autochdir' option changed directory: go back. */ + // When autocommands/'autochdir' option changed directory: go back. restore_start_dir(dirname_start); } } @@ -6297,14 +6230,12 @@ static int cbuffer_process_args(exarg_T *eap, return OK; } -/* - * ":[range]cbuffer [bufnr]" command. - * ":[range]caddbuffer [bufnr]" command. - * ":[range]cgetbuffer [bufnr]" command. - * ":[range]lbuffer [bufnr]" command. - * ":[range]laddbuffer [bufnr]" command. - * ":[range]lgetbuffer [bufnr]" command. - */ +// ":[range]cbuffer [bufnr]" command. +// ":[range]caddbuffer [bufnr]" command. +// ":[range]cgetbuffer [bufnr]" command. +// ":[range]lbuffer [bufnr]" command. +// ":[range]laddbuffer [bufnr]" command. +// ":[range]lgetbuffer [bufnr]" command. void ex_cbuffer(exarg_T *eap) { buf_T *buf = NULL; @@ -6405,8 +6336,8 @@ void ex_cexpr(exarg_T *eap) qf_info_T *qi = qf_cmd_get_or_alloc_stack(eap, &wp); - /* Evaluate the expression. When the result is a string or a list we can - * use it to fill the errorlist. */ + // Evaluate the expression. When the result is a string or a list we can + // use it to fill the errorlist. typval_T tv; if (eval0(eap->arg, &tv, NULL, true) != FAIL) { if ((tv.v_type == VAR_STRING && tv.vval.v_string != NULL) diff --git a/src/nvim/state.c b/src/nvim/state.c index 81bc078a88..b195c1d96b 100644 --- a/src/nvim/state.c +++ b/src/nvim/state.c @@ -156,7 +156,7 @@ char *get_mode(void) buf[0] = 'n'; if (finish_op) { buf[1] = 'o'; - // to be able to detect force-linewise/blockwise/characterwise operations + // to be able to detect force-linewise/blockwise/charwise operations buf[2] = (char)motion_force; } else if (restart_edit == 'I' || restart_edit == 'R' || restart_edit == 'V') { diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim index 0a3e6ae625..635ee7984a 100644 --- a/src/nvim/testdir/test_cmdline.vim +++ b/src/nvim/testdir/test_cmdline.vim @@ -301,7 +301,7 @@ func Test_getcompletion() call assert_equal([], l) let l = getcompletion('.', 'shellcmd') - call assert_equal(['./', '../'], l[0:1]) + call assert_equal(['./', '../'], filter(l, 'v:val =~ "\\./"')) call assert_equal(-1, match(l[2:], '^\.\.\?/$')) let root = has('win32') ? 'C:\\' : '/' let l = getcompletion(root, 'shellcmd') @@ -375,6 +375,29 @@ func Test_getcompletion() call assert_fails('call getcompletion("", "burp")', 'E475:') endfunc +func Test_shellcmd_completion() + let save_path = $PATH + + call mkdir('Xpathdir/Xpathsubdir', 'p') + call writefile([''], 'Xpathdir/Xfile.exe') + call setfperm('Xpathdir/Xfile.exe', 'rwx------') + + " Set PATH to example directory without trailing slash. + let $PATH = getcwd() . '/Xpathdir' + + " Test for the ":!<TAB>" case. Previously, this would include subdirs of + " dirs in the PATH, even though they won't be executed. We check that only + " subdirs of the PWD and executables from the PATH are included in the + " suggestions. + let actual = getcompletion('X', 'shellcmd') + let expected = map(filter(glob('*', 0, 1), 'isdirectory(v:val) && v:val[0] == "X"'), 'v:val . "/"') + call insert(expected, 'Xfile.exe') + call assert_equal(expected, actual) + + call delete('Xpathdir', 'rf') + let $PATH = save_path +endfunc + func Test_expand_star_star() call mkdir('a/b', 'p') call writefile(['asdfasdf'], 'a/b/fileXname') @@ -492,8 +515,9 @@ func Test_cmdline_complete_user_names() let names = system('net user') if names =~ 'Administrator' " Trying completion of :e ~A should complete to Administrator. + " There could be other names starting with "A" before Administrator. call feedkeys(':e ~A' . "\<c-a>\<c-B>\"\<cr>", 'tx') - call assert_match('^"e \~Administrator', @:) + call assert_match('^"e \~.*Administrator', @:) endif endif endfunc diff --git a/src/nvim/testdir/test_ins_complete.vim b/src/nvim/testdir/test_ins_complete.vim index 7f52481ba8..52ec281d82 100644 --- a/src/nvim/testdir/test_ins_complete.vim +++ b/src/nvim/testdir/test_ins_complete.vim @@ -285,3 +285,21 @@ func Test_compl_feedkeys() bwipe! set completeopt& endfunc + +func Test_compl_in_cmdwin() + set wildmenu wildchar=<Tab> + com! -nargs=1 -complete=command GetInput let input = <q-args> + com! -buffer TestCommand echo 'TestCommand' + + let input = '' + call feedkeys("q:iGetInput T\<C-x>\<C-v>\<CR>", 'tx!') + call assert_equal('TestCommand', input) + + let input = '' + call feedkeys("q::GetInput T\<Tab>\<CR>:q\<CR>", 'tx!') + call assert_equal('T', input) + + delcom TestCommand + delcom GetInput + set wildmenu& wildchar& +endfunc |