aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/clint.py2
-rw-r--r--src/nvim/api/command.c67
-rw-r--r--src/nvim/api/extmark.c2
-rw-r--r--src/nvim/api/window.c2
-rw-r--r--src/nvim/change.c2
-rw-r--r--src/nvim/charset.c2
-rw-r--r--src/nvim/ex_docmd.c53
-rw-r--r--src/nvim/getchar.c2
-rw-r--r--src/nvim/hashtab.c2
-rw-r--r--src/nvim/highlight_group.c2
-rw-r--r--src/nvim/lua/treesitter.c2
-rw-r--r--src/nvim/os/shell.c2
-rw-r--r--src/nvim/path.c2
-rw-r--r--src/nvim/textobject.c2
-rw-r--r--src/nvim/window.c2
15 files changed, 104 insertions, 42 deletions
diff --git a/src/clint.py b/src/clint.py
index c4ddbf706e..1a355e0218 100755
--- a/src/clint.py
+++ b/src/clint.py
@@ -202,7 +202,7 @@ _ERROR_CATEGORIES = [
'whitespace/cast',
]
-# The default state of the category filter. This is overrided by the --filter=
+# The default state of the category filter. This is overridden by the --filter=
# flag. By default all errors are on, so only add here categories that should be
# off by default (i.e., categories that must be enabled by the --filter= flags).
# All entries here should start with a '-' or '+', as in the --filter= flag.
diff --git a/src/nvim/api/command.c b/src/nvim/api/command.c
index 53701a8c7c..8cd2c0f8b8 100644
--- a/src/nvim/api/command.c
+++ b/src/nvim/api/command.c
@@ -284,7 +284,11 @@ end:
/// Unlike |nvim_command()| this command takes a structured Dictionary instead of a String. This
/// allows for easier construction and manipulation of an Ex command. This also allows for things
/// such as having spaces inside a command argument, expanding filenames in a command that otherwise
-/// doesn't expand filenames, etc.
+/// doesn't expand filenames, etc. Command arguments may also be Number, Boolean or String.
+///
+/// The first argument may also be used instead of count for commands that support it in order to
+/// make their usage simpler with |vim.cmd()|. For example, instead of
+/// `vim.cmd.bdelete{ count = 2 }`, you may do `vim.cmd.bdelete(2)`.
///
/// On execution error: fails with VimL error, updates v:errmsg.
///
@@ -309,8 +313,7 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error
char *cmdline = NULL;
char *cmdname = NULL;
- ArrayOf(String) args;
- size_t argc = 0;
+ ArrayOf(String) args = ARRAY_DICT_INIT;
String retv = (String)STRING_INIT;
@@ -382,48 +385,70 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error
if (cmd->args.type != kObjectTypeArray) {
VALIDATION_ERROR("'args' must be an Array");
}
- // Check if every argument is valid
+
+ // Process all arguments. Convert non-String arguments to String and check if String arguments
+ // have non-whitespace characters.
for (size_t i = 0; i < cmd->args.data.array.size; i++) {
Object elem = cmd->args.data.array.items[i];
- if (elem.type != kObjectTypeString) {
- VALIDATION_ERROR("Command argument must be a String");
- } else if (string_iswhite(elem.data.string)) {
- VALIDATION_ERROR("Command argument must have non-whitespace characters");
+ char *data_str;
+
+ switch (elem.type) {
+ case kObjectTypeBoolean:
+ data_str = xcalloc(2, sizeof(char));
+ data_str[0] = elem.data.boolean ? '1' : '0';
+ data_str[1] = '\0';
+ break;
+ case kObjectTypeBuffer:
+ case kObjectTypeWindow:
+ case kObjectTypeTabpage:
+ case kObjectTypeInteger:
+ data_str = xcalloc(NUMBUFLEN, sizeof(char));
+ snprintf(data_str, NUMBUFLEN, "%" PRId64, elem.data.integer);
+ break;
+ case kObjectTypeString:
+ if (string_iswhite(elem.data.string)) {
+ VALIDATION_ERROR("String command argument must have at least one non-whitespace "
+ "character");
+ }
+ data_str = xstrndup(elem.data.string.data, elem.data.string.size);
+ break;
+ default:
+ VALIDATION_ERROR("Invalid type for command argument");
+ break;
}
+
+ ADD(args, STRING_OBJ(cstr_as_string(data_str)));
}
- argc = cmd->args.data.array.size;
bool argc_valid;
// Check if correct number of arguments is used.
switch (ea.argt & (EX_EXTRA | EX_NOSPC | EX_NEEDARG)) {
case EX_EXTRA | EX_NOSPC | EX_NEEDARG:
- argc_valid = argc == 1;
+ argc_valid = args.size == 1;
break;
case EX_EXTRA | EX_NOSPC:
- argc_valid = argc <= 1;
+ argc_valid = args.size <= 1;
break;
case EX_EXTRA | EX_NEEDARG:
- argc_valid = argc >= 1;
+ argc_valid = args.size >= 1;
break;
case EX_EXTRA:
argc_valid = true;
break;
default:
- argc_valid = argc == 0;
+ argc_valid = args.size == 0;
break;
}
if (!argc_valid) {
VALIDATION_ERROR("Incorrect number of arguments supplied");
}
-
- args = cmd->args.data.array;
}
// Simply pass the first argument (if it exists) as the arg pointer to `set_cmd_addr_type()`
// since it only ever checks the first argument.
- set_cmd_addr_type(&ea, argc > 0 ? args.items[0].data.string.data : NULL);
+ set_cmd_addr_type(&ea, args.size > 0 ? args.items[0].data.string.data : NULL);
if (HAS_KEY(cmd->range)) {
if (!(ea.argt & EX_RANGE)) {
@@ -627,7 +652,7 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error
// Finally, build the command line string that will be stored inside ea.cmdlinep.
// This also sets the values of ea.cmd, ea.arg, ea.args and ea.arglens.
- build_cmdline_str(&cmdline, &ea, &cmdinfo, args, argc);
+ build_cmdline_str(&cmdline, &ea, &cmdinfo, args);
ea.cmdlinep = &cmdline;
garray_T capture_local;
@@ -683,6 +708,7 @@ clear_ga:
ga_clear(&capture_local);
}
end:
+ api_free_array(args);
xfree(cmdline);
xfree(cmdname);
xfree(ea.args);
@@ -712,8 +738,9 @@ static bool string_iswhite(String str)
/// Build cmdline string for command, used by `nvim_cmd()`.
static void build_cmdline_str(char **cmdlinep, exarg_T *eap, CmdParseInfo *cmdinfo,
- ArrayOf(String) args, size_t argc)
+ ArrayOf(String) args)
{
+ size_t argc = args.size;
StringBuilder cmdline = KV_INITIAL_VALUE;
kv_resize(cmdline, 32); // Make it big enough to handle most typical commands
@@ -799,7 +826,7 @@ static void build_cmdline_str(char **cmdlinep, exarg_T *eap, CmdParseInfo *cmdin
}
eap->argc = argc;
- eap->arglens = xcalloc(argc, sizeof(size_t));
+ eap->arglens = eap->argc > 0 ? xcalloc(argc, sizeof(size_t)) : NULL;
size_t argstart_idx = cmdline.size;
for (size_t i = 0; i < argc; i++) {
String s = args.items[i].data.string;
@@ -814,7 +841,7 @@ static void build_cmdline_str(char **cmdlinep, exarg_T *eap, CmdParseInfo *cmdin
// Now that all the arguments are appended, use the command index and argument indices to set the
// values of eap->cmd, eap->arg and eap->args.
eap->cmd = cmdline.items + cmdname_idx;
- eap->args = xcalloc(argc, sizeof(char *));
+ eap->args = eap->argc > 0 ? xcalloc(argc, sizeof(char *)) : NULL;
size_t offset = argstart_idx;
for (size_t i = 0; i < argc; i++) {
offset++; // Account for space
diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c
index c92a97519d..3b1b470629 100644
--- a/src/nvim/api/extmark.c
+++ b/src/nvim/api/extmark.c
@@ -389,7 +389,7 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e
/// - virt_text : virtual text to link to this mark.
/// A list of [text, highlight] tuples, each representing a
/// text chunk with specified highlight. `highlight` element
-/// can either be a a single highlight group, or an array of
+/// can either be a single highlight group, or an array of
/// multiple highlight groups that will be stacked
/// (highest priority last). A highlight group can be supplied
/// either as a string or as an integer, the latter which
diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c
index 59e806adb1..aaff00d640 100644
--- a/src/nvim/api/window.c
+++ b/src/nvim/api/window.c
@@ -430,7 +430,7 @@ Object nvim_win_call(Window window, LuaRef fun, Error *err)
/// Set highlight namespace for a window. This will use highlights defined in
/// this namespace, but fall back to global highlights (ns=0) when missing.
///
-/// This takes predecence over the 'winhighlight' option.
+/// This takes precedence over the 'winhighlight' option.
///
/// @param ns_id the namespace to use
/// @param[out] err Error details, if any
diff --git a/src/nvim/change.c b/src/nvim/change.c
index ab550259c8..c9e57ab88f 100644
--- a/src/nvim/change.c
+++ b/src/nvim/change.c
@@ -999,7 +999,7 @@ int copy_indent(int size, char *src)
/// "second_line_indent": indent for after ^^D in Insert mode or if flag
/// OPENLINE_COM_LIST
/// "did_do_comment" is set to true when intentionally putting the comment
-/// leader in fromt of the new line.
+/// leader in front of the new line.
///
/// @param dir FORWARD or BACKWARD
///
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index 0cc2189948..f5db03b0b4 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -650,7 +650,7 @@ static inline unsigned nr2hex(unsigned n)
///
/// @param b
///
-/// @reeturn Number of display cells.
+/// @return Number of display cells.
int byte2cells(int b)
FUNC_ATTR_PURE
{
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 386f708f79..987fb439d7 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -1339,6 +1339,20 @@ static int parse_count(exarg_T *eap, char **errormsg, bool validate)
|| ascii_iswhite(*p))) {
long n = getdigits_long(&eap->arg, false, -1);
eap->arg = skipwhite(eap->arg);
+
+ if (eap->args != NULL) {
+ assert(eap->argc > 0 && eap->arg >= eap->args[0]);
+ // If eap->arg is still pointing to the first argument, just make eap->args[0] point to the
+ // same location. This is needed for usecases like vim.cmd.sleep('10m'). If eap->arg is
+ // pointing outside the first argument, shift arguments by 1.
+ if (eap->arg < eap->args[0] + eap->arglens[0]) {
+ eap->arglens[0] -= (size_t)(eap->arg - eap->args[0]);
+ eap->args[0] = eap->arg;
+ } else {
+ shift_cmd_args(eap);
+ }
+ }
+
if (n <= 0 && (eap->argt & EX_ZEROR) == 0) {
if (errormsg != NULL) {
*errormsg = _(e_zerocount);
@@ -1512,6 +1526,30 @@ end:
return retval;
}
+// Shift Ex-command arguments to the right.
+static void shift_cmd_args(exarg_T *eap)
+{
+ assert(eap->args != NULL && eap->argc > 0);
+
+ char **oldargs = eap->args;
+ size_t *oldarglens = eap->arglens;
+
+ eap->argc--;
+ eap->args = eap->argc > 0 ? xcalloc(eap->argc, sizeof(char *)) : NULL;
+ eap->arglens = eap->argc > 0 ? xcalloc(eap->argc, sizeof(size_t)) : NULL;
+
+ for (size_t i = 0; i < eap->argc; i++) {
+ eap->args[i] = oldargs[i + 1];
+ eap->arglens[i] = oldarglens[i + 1];
+ }
+
+ // If there are no arguments, make eap->arg point to the end of string.
+ eap->arg = (eap->argc > 0 ? eap->args[0] : (oldargs[0] + oldarglens[0]));
+
+ xfree(oldargs);
+ xfree(oldarglens);
+}
+
static int execute_cmd0(int *retv, exarg_T *eap, char **errormsg, bool preview)
{
// If filename expansion is enabled, expand filenames
@@ -1551,15 +1589,7 @@ static int execute_cmd0(int *retv, exarg_T *eap, char **errormsg, bool preview)
eap->args[0] + eap->arglens[0],
(eap->argt & EX_BUFUNL) != 0, false, false);
eap->addr_count = 1;
- // Shift each argument by 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];
+ shift_cmd_args(eap);
}
if (eap->line2 < 0) { // failed
return FAIL;
@@ -1658,6 +1688,11 @@ int execute_cmd(exarg_T *eap, CmdParseInfo *cmdinfo, bool preview)
(void)hasFolding(eap->line2, NULL, &eap->line2);
}
+ // Use first argument as count when possible
+ if (parse_count(eap, &errormsg, true) == FAIL) {
+ goto end;
+ }
+
// Execute the command
execute_cmd0(&retv, eap, &errormsg, preview);
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index fd0acce25f..ef66e2d355 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -2104,7 +2104,7 @@ static int handle_mapping(int *keylenp, bool *timedout, int *mapdepth)
} else {
keylen = 0;
}
- if (keylen == 0) { // no simplication has been done
+ if (keylen == 0) { // no simplification has been done
// If there was no mapping at all use the character from the
// typeahead buffer right here.
if (mp == NULL) {
diff --git a/src/nvim/hashtab.c b/src/nvim/hashtab.c
index 3d0ab192b9..32d67621db 100644
--- a/src/nvim/hashtab.c
+++ b/src/nvim/hashtab.c
@@ -265,7 +265,7 @@ void hash_unlock(hashtab_T *ht)
hash_may_resize(ht, 0);
}
-/// Resize hastable (new size can be given or automatically computed).
+/// Resize hashtable (new size can be given or automatically computed).
///
/// @param minitems Minimum number of items the new table should hold.
/// If zero, new size will depend on currently used items:
diff --git a/src/nvim/highlight_group.c b/src/nvim/highlight_group.c
index fed39c6ed7..3508560e20 100644
--- a/src/nvim/highlight_group.c
+++ b/src/nvim/highlight_group.c
@@ -2034,7 +2034,7 @@ void highlight_changed(void)
}
}
- // sentinel value. used when no hightlight namespace is active
+ // sentinel value. used when no highlight namespace is active
highlight_attr[HLF_COUNT] = 0;
//
diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c
index 64cace9ab4..79b11eca4a 100644
--- a/src/nvim/lua/treesitter.c
+++ b/src/nvim/lua/treesitter.c
@@ -1369,7 +1369,7 @@ static int query_inspect(lua_State *L)
lua_rawseti(L, -2, nextitem++); // [retval, patterns, pat, pred]
}
// last predicate should have ended with TypeDone
- lua_pop(L, 1); // [retval, patters, pat]
+ lua_pop(L, 1); // [retval, patterns, pat]
lua_rawseti(L, -2, (int)i + 1); // [retval, patterns]
}
lua_setfield(L, -2, "patterns"); // [retval]
diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c
index 9766c8f3d9..750d2f342f 100644
--- a/src/nvim/os/shell.c
+++ b/src/nvim/os/shell.c
@@ -805,7 +805,7 @@ done:
/// char *output = NULL;
/// size_t nread = 0;
/// char *argv[] = {"ls", "-la", NULL};
-/// int exitcode = os_sytem(argv, NULL, 0, &output, &nread);
+/// int exitcode = os_system(argv, NULL, 0, &output, &nread);
///
/// @param argv The commandline arguments to be passed to the shell. `argv`
/// will be consumed.
diff --git a/src/nvim/path.c b/src/nvim/path.c
index d1a7e14c9f..9295905415 100644
--- a/src/nvim/path.c
+++ b/src/nvim/path.c
@@ -575,7 +575,7 @@ bool path_has_exp_wildcard(const char_u *p)
/// @param path The path to search.
/// @param flags Flags for regexp expansion.
/// - EW_ICASE: Ignore case.
-/// - EW_NOERROR: Silence error messeges.
+/// - EW_NOERROR: Silence error messages.
/// - EW_NOTWILD: Add matches literally.
/// @returns the number of matches found.
static size_t path_expand(garray_T *gap, const char_u *path, int flags)
diff --git a/src/nvim/textobject.c b/src/nvim/textobject.c
index 621efa44cf..e6b330cbf1 100644
--- a/src/nvim/textobject.c
+++ b/src/nvim/textobject.c
@@ -1503,7 +1503,7 @@ bool current_quote(oparg_T *oap, long count, bool include, int quotechar)
bool inside_quotes = false; // Looks like "i'" done before
bool selected_quote = false; // Has quote inside selection
int i;
- bool restore_vis_bef = false; // resotre VIsual on abort
+ bool restore_vis_bef = false; // restore VIsual on abort
// When 'selection' is "exclusive" move the cursor to where it would be
// with 'selection' "inclusive", so that the logic is the same for both.
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 5523c3df8b..adcf9cdd56 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -737,7 +737,7 @@ void win_set_minimal_style(win_T *wp)
}
// TODO(bfredl): this could use a highlight namespace directly,
- // and avoid pecularities around window options
+ // and avoid peculiarities around window options
char_u *old = (char_u *)wp->w_p_winhl;
wp->w_p_winhl = ((*old == NUL)
? xstrdup("EndOfBuffer:")