aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/api')
-rw-r--r--src/nvim/api/autocmd.c8
-rw-r--r--src/nvim/api/command.c117
-rw-r--r--src/nvim/api/extmark.c8
-rw-r--r--src/nvim/api/options.c4
-rw-r--r--src/nvim/api/private/helpers.c18
-rw-r--r--src/nvim/api/ui.c4
-rw-r--r--src/nvim/api/vim.c14
-rw-r--r--src/nvim/api/win_config.c2
-rw-r--r--src/nvim/api/window.c4
9 files changed, 111 insertions, 68 deletions
diff --git a/src/nvim/api/autocmd.c b/src/nvim/api/autocmd.c
index ac4cb953b8..b5c695b9ce 100644
--- a/src/nvim/api/autocmd.c
+++ b/src/nvim/api/autocmd.c
@@ -599,7 +599,7 @@ void nvim_del_autocmd(Integer id, Error *err)
}
/// Clear all autocommands that match the corresponding {opts}. To delete
-/// a particular autocmd, see |nvim_del_autocmd|.
+/// a particular autocmd, see |nvim_del_autocmd()|.
/// @param opts Parameters
/// - event: (string|table)
/// Examples:
@@ -728,7 +728,7 @@ Integer nvim_create_augroup(uint64_t channel_id, String name, Dict(create_augrou
///
/// To get a group id one can use |nvim_get_autocmds()|.
///
-/// NOTE: behavior differs from |augroup-delete|. When deleting a group, autocommands contained in
+/// NOTE: behavior differs from |:augroup-delete|. When deleting a group, autocommands contained in
/// this group will also be deleted and cleared. This group will no longer exist.
/// @param id Integer The id of the group.
/// @see |nvim_del_augroup_by_name()|
@@ -746,10 +746,10 @@ void nvim_del_augroup_by_id(Integer id, Error *err)
/// Delete an autocommand group by name.
///
-/// NOTE: behavior differs from |augroup-delete|. When deleting a group, autocommands contained in
+/// NOTE: behavior differs from |:augroup-delete|. When deleting a group, autocommands contained in
/// this group will also be deleted and cleared. This group will no longer exist.
/// @param name String The name of the group.
-/// @see |autocommand-groups|
+/// @see |autocmd-groups|
void nvim_del_augroup_by_name(String name, Error *err)
FUNC_API_SINCE(9)
{
diff --git a/src/nvim/api/command.c b/src/nvim/api/command.c
index ed0907e8f8..8cd2c0f8b8 100644
--- a/src/nvim/api/command.c
+++ b/src/nvim/api/command.c
@@ -31,14 +31,15 @@
/// @param[out] err Error details, if any.
/// @return Dictionary containing command information, with these keys:
/// - cmd: (string) Command name.
-/// - range: (array) Command <range>. Can have 0-2 elements depending on how many items the
-/// range contains. Has no elements if command doesn't accept a range or if
-/// no range was specified, one element if only a single range item was
-/// specified and two elements if both range items were specified.
-/// - count: (number) Any |<count>| that was supplied to the command. -1 if command cannot
-/// take a count.
-/// - reg: (number) The optional command |<register>|, if specified. Empty string if not
-/// specified or if command cannot take a register.
+/// - range: (array) (optional) Command range (|<line1>| |<line2>|).
+/// Omitted if command doesn't accept a range.
+/// Otherwise, has no elements if no range was specified, one element if
+/// only a single range item was specified, or two elements if both range
+/// items were specified.
+/// - count: (number) (optional) Command |<count>|.
+/// Omitted if command cannot take a count.
+/// - reg: (string) (optional) Command |<register>|.
+/// Omitted if command cannot take a register.
/// - bang: (boolean) Whether command contains a |<bang>| (!) modifier.
/// - args: (array) Command arguments.
/// - addr: (string) Value of |:command-addr|. Uses short name.
@@ -142,15 +143,15 @@ Dictionary nvim_parse_cmd(String str, Dictionary opts, Error *err)
PUT(result, "cmd", CSTR_TO_OBJ((char *)get_command_name(NULL, ea.cmdidx)));
}
- if ((ea.argt & EX_RANGE) && ea.addr_count > 0) {
+ if (ea.argt & EX_RANGE) {
Array range = ARRAY_DICT_INIT;
- if (ea.addr_count > 1) {
- ADD(range, INTEGER_OBJ(ea.line1));
+ if (ea.addr_count > 0) {
+ if (ea.addr_count > 1) {
+ ADD(range, INTEGER_OBJ(ea.line1));
+ }
+ ADD(range, INTEGER_OBJ(ea.line2));
}
- ADD(range, INTEGER_OBJ(ea.line2));
PUT(result, "range", ARRAY_OBJ(range));
- } else {
- PUT(result, "range", ARRAY_OBJ(ARRAY_DICT_INIT));
}
if (ea.argt & EX_COUNT) {
@@ -161,14 +162,12 @@ Dictionary nvim_parse_cmd(String str, Dictionary opts, Error *err)
} else {
PUT(result, "count", INTEGER_OBJ(0));
}
- } else {
- PUT(result, "count", INTEGER_OBJ(-1));
}
- char reg[2];
- reg[0] = (char)ea.regname;
- reg[1] = '\0';
- PUT(result, "reg", CSTR_TO_OBJ(reg));
+ if (ea.argt & EX_REGSTR) {
+ char reg[2] = { (char)ea.regname, NUL };
+ PUT(result, "reg", CSTR_TO_OBJ(reg));
+ }
PUT(result, "bang", BOOLEAN_OBJ(ea.forceit));
PUT(result, "args", ARRAY_OBJ(args));
@@ -285,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.
///
@@ -310,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;
@@ -383,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)) {
@@ -628,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;
@@ -684,6 +708,7 @@ clear_ga:
ga_clear(&capture_local);
}
end:
+ api_free_array(args);
xfree(cmdline);
xfree(cmdname);
xfree(ea.args);
@@ -713,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
@@ -800,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;
@@ -815,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
@@ -832,13 +858,12 @@ static void build_cmdline_str(char **cmdlinep, exarg_T *eap, CmdParseInfo *cmdin
// Replace, :make and :grep with 'makeprg' and 'grepprg'.
char *p = replace_makeprg(eap, eap->arg, cmdlinep);
if (p != eap->arg) {
- // If replace_makeprg modified the cmdline string, correct the argument pointers.
+ // If replace_makeprg() modified the cmdline string, correct the eap->arg pointer.
eap->arg = p;
- // We can only know the position of the first argument because the argument list can be used
- // multiple times in makeprg / grepprg.
- if (argc >= 1) {
- eap->args[0] = p;
- }
+ // This cannot be a user command, so eap->args will not be used.
+ XFREE_CLEAR(eap->args);
+ XFREE_CLEAR(eap->arglens);
+ eap->argc = 0;
}
}
diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c
index edcea52838..3b1b470629 100644
--- a/src/nvim/api/extmark.c
+++ b/src/nvim/api/extmark.c
@@ -389,11 +389,11 @@ 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
-/// can be obtained using |nvim_get_hl_id_by_name|.
+/// can be obtained using |nvim_get_hl_id_by_name()|.
/// - virt_text_pos : position of virtual text. Possible values:
/// - "eol": right after eol character (default)
/// - "overlay": display over the specified column, without
@@ -430,7 +430,7 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e
/// column of the window, bypassing
/// sign and number columns.
///
-/// - ephemeral : for use with |nvim_set_decoration_provider|
+/// - ephemeral : for use with |nvim_set_decoration_provider()|
/// callbacks. The mark will only be used for the current
/// redraw cycle, and not be permantently stored in the
/// buffer.
@@ -958,7 +958,7 @@ void nvim_buf_clear_namespace(Buffer buffer, Integer ns_id, Integer line_start,
/// being triggered during the redraw code.
///
/// The expected usage is to set extmarks for the currently
-/// redrawn buffer. |nvim_buf_set_extmark| can be called to add marks
+/// redrawn buffer. |nvim_buf_set_extmark()| can be called to add marks
/// on a per-window or per-lines basis. Use the `ephemeral` key to only
/// use the mark for the current screen redraw (the callback will be called
/// again for the next redraw ).
diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c
index 867584dd71..ec1f19cf6a 100644
--- a/src/nvim/api/options.c
+++ b/src/nvim/api/options.c
@@ -147,7 +147,7 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err)
/// @param name Option name
/// @param value New option value
/// @param opts Optional parameters
-/// - scope: One of 'global' or 'local'. Analogous to
+/// - 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.
@@ -202,7 +202,7 @@ void nvim_set_option_value(String name, Object value, Dict(option) *opts, Error
/// Gets the option information for all options.
///
/// The dictionary has the full option names as keys and option metadata
-/// dictionaries as detailed at |nvim_get_option_info|.
+/// dictionaries as detailed at |nvim_get_option_info()|.
///
/// @return dictionary of all options
Dictionary nvim_get_all_options_info(Error *err)
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index b888d09343..73b5489d5c 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -218,6 +218,8 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, bool retva
return rv;
}
+ bool watched = tv_dict_is_watched(dict);
+
if (del) {
// Delete the key
if (di == NULL) {
@@ -225,6 +227,10 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, bool retva
api_set_error(err, kErrorTypeValidation, "Key not found: %s",
key.data);
} else {
+ // Notify watchers
+ if (watched) {
+ tv_dict_watcher_notify(dict, key.data, NULL, &di->di_tv);
+ }
// Return the old value
if (retval) {
rv = vim_to_object(&di->di_tv);
@@ -241,11 +247,16 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, bool retva
return rv;
}
+ typval_T oldtv = TV_INITIAL_VALUE;
+
if (di == NULL) {
// Need to create an entry
di = tv_dict_item_alloc_len(key.data, key.size);
tv_dict_add(dict, di);
} else {
+ if (watched) {
+ tv_copy(&di->di_tv, &oldtv);
+ }
// Return the old value
if (retval) {
rv = vim_to_object(&di->di_tv);
@@ -255,6 +266,13 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, bool retva
// Update the value
tv_copy(&tv, &di->di_tv);
+
+ // Notify watchers
+ if (watched) {
+ tv_dict_watcher_notify(dict, key.data, &tv, &oldtv);
+ tv_clear(&oldtv);
+ }
+
// Clear the temporary variable
tv_clear(&tv);
}
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c
index 45c20d07e1..e6d8cb2fdb 100644
--- a/src/nvim/api/ui.c
+++ b/src/nvim/api/ui.c
@@ -453,7 +453,7 @@ void nvim_ui_try_resize_grid(uint64_t channel_id, Integer grid, Integer width, I
}
}
-/// Tells Nvim the number of elements displaying in the popumenu, to decide
+/// Tells Nvim the number of elements displaying in the popupmenu, to decide
/// <PageUp> and <PageDown> movement.
///
/// @param channel_id
@@ -483,7 +483,7 @@ void nvim_ui_pum_set_height(uint64_t channel_id, Integer height, Error *err)
ui->pum_nlines = (int)height;
}
-/// Tells Nvim the geometry of the popumenu, to align floating windows with an
+/// Tells Nvim the geometry of the popupmenu, to align floating windows with an
/// external popup menu.
///
/// Note that this method is not to be confused with |nvim_ui_pum_set_height()|,
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index ad9ed72f43..d65127e406 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -160,8 +160,8 @@ Dictionary nvim__get_hl_defs(Integer ns_id, Arena *arena, Error *err)
/// - nocombine: boolean
/// - link: name of another highlight group to link to, see |:hi-link|.
/// - default: Don't override existing definition |:hi-default|
-/// - ctermfg: Sets foreground of cterm color |highlight-ctermfg|
-/// - ctermbg: Sets background of cterm color |highlight-ctermbg|
+/// - ctermfg: Sets foreground of cterm color |ctermfg|
+/// - ctermbg: Sets background of cterm color |ctermbg|
/// - cterm: cterm attribute map, like |highlight-args|. If not set,
/// cterm attributes will match those from the attribute map
/// documented above.
@@ -185,7 +185,7 @@ void nvim_set_hl(Integer ns_id, String name, Dict(highlight) *val, Error *err)
}
/// Set active namespace for highlights. This can be set for a single window,
-/// see |nvim_win_set_hl_ns|.
+/// see |nvim_win_set_hl_ns()|.
///
/// @param ns_id the namespace to use
/// @param[out] err Error details, if any
@@ -205,7 +205,7 @@ void nvim_set_hl_ns(Integer ns_id, Error *err)
/// Set active namespace for highlights while redrawing.
///
/// This function meant to be called while redrawing, primarily from
-/// |nvim_set_decoration_provider| on_win and on_line callbacks, which
+/// |nvim_set_decoration_provider()| on_win and on_line callbacks, which
/// are allowed to change the namespace during a redraw cycle.
///
/// @param ns_id the namespace to activate
@@ -523,7 +523,7 @@ Array nvim__runtime_inspect(void)
/// Find files in runtime directories
///
-/// 'name' can contain wildcards. For example
+/// "name" can contain wildcards. For example
/// nvim_get_runtime_file("colors/*.vim", true) will return all color
/// scheme files. Always use forward slashes (/) in the search pattern for
/// subdirectories regardless of platform.
@@ -964,7 +964,7 @@ fail:
/// mode. Note: keypresses are sent raw as they would be to the pty
/// master end. For instance, a carriage return is sent
/// as a "\r", not as a "\n". |textlock| applies. It is possible
-/// to call |nvim_chan_send| directly in the callback however.
+/// to call |nvim_chan_send()| directly in the callback however.
/// ["input", term, bufnr, data]
/// @param[out] err Error details, if any
/// @return Channel id, or 0 on error
@@ -1452,7 +1452,7 @@ ArrayOf(Dictionary) nvim_get_keymap(String mode)
/// @param rhs Right-hand-side |{rhs}| of the mapping.
/// @param opts Optional parameters map: keys are |:map-arguments|, values are booleans (default
/// false). Accepts all |:map-arguments| as keys excluding |<buffer>| but including
-/// |noremap| and "desc". Unknown key is an error.
+/// |:noremap| and "desc". Unknown key is an error.
/// "desc" can be used to give a description to the mapping.
/// When called from Lua, also accepts a "callback" key that takes a Lua function to
/// call when the mapping is executed.
diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c
index 96c560efa1..636b9566ce 100644
--- a/src/nvim/api/win_config.c
+++ b/src/nvim/api/win_config.c
@@ -109,7 +109,7 @@
/// is changed to `auto` and 'colorcolumn' is cleared. The
/// end-of-buffer region is hidden by setting `eob` flag of
/// 'fillchars' to a space char, and clearing the
-/// |EndOfBuffer| region in 'winhighlight'.
+/// |hl-EndOfBuffer| region in 'winhighlight'.
/// - border: Style of (optional) window border. This can either be a string
/// or an array. The string values are
/// - "none": No border (default).
diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c
index 5203003369..aaff00d640 100644
--- a/src/nvim/api/window.c
+++ b/src/nvim/api/window.c
@@ -340,7 +340,7 @@ Boolean nvim_win_is_valid(Window window)
///
/// Like |:hide| the buffer becomes hidden unless another window is editing it,
/// or 'bufhidden' is `unload`, `delete` or `wipe` as opposed to |:close| or
-/// |nvim_win_close|, which will close the buffer.
+/// |nvim_win_close()|, which will close the buffer.
///
/// @param window Window handle, or 0 for current window
/// @param[out] err Error details, if any
@@ -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