aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/api/vim.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/api/vim.c')
-rw-r--r--src/nvim/api/vim.c727
1 files changed, 331 insertions, 396 deletions
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 349cc0e7da..3be45d0cf7 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -3,54 +3,54 @@
#include <assert.h>
#include <inttypes.h>
+#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
-#include <limits.h>
-#include "nvim/api/vim.h"
-#include "nvim/ascii.h"
-#include "nvim/api/private/helpers.h"
+#include "nvim/api/buffer.h"
+#include "nvim/api/deprecated.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/dispatch.h"
-#include "nvim/api/buffer.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/api/vim.h"
#include "nvim/api/window.h"
-#include "nvim/api/deprecated.h"
-#include "nvim/msgpack_rpc/channel.h"
-#include "nvim/msgpack_rpc/helpers.h"
-#include "nvim/lua/executor.h"
-#include "nvim/vim.h"
+#include "nvim/ascii.h"
#include "nvim/buffer.h"
#include "nvim/context.h"
-#include "nvim/file_search.h"
-#include "nvim/highlight.h"
-#include "nvim/window.h"
-#include "nvim/types.h"
-#include "nvim/ex_cmds2.h"
-#include "nvim/ex_docmd.h"
-#include "nvim/screen.h"
-#include "nvim/memline.h"
-#include "nvim/mark.h"
-#include "nvim/memory.h"
-#include "nvim/message.h"
-#include "nvim/popupmnu.h"
+#include "nvim/decoration.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
#include "nvim/eval/userfunc.h"
+#include "nvim/ex_cmds2.h"
+#include "nvim/ex_docmd.h"
+#include "nvim/file_search.h"
#include "nvim/fileio.h"
+#include "nvim/getchar.h"
+#include "nvim/highlight.h"
+#include "nvim/lua/executor.h"
+#include "nvim/mark.h"
+#include "nvim/memline.h"
+#include "nvim/memory.h"
+#include "nvim/message.h"
#include "nvim/move.h"
+#include "nvim/msgpack_rpc/channel.h"
+#include "nvim/msgpack_rpc/helpers.h"
#include "nvim/ops.h"
#include "nvim/option.h"
-#include "nvim/state.h"
-#include "nvim/decoration.h"
-#include "nvim/syntax.h"
-#include "nvim/getchar.h"
#include "nvim/os/input.h"
#include "nvim/os/process.h"
+#include "nvim/popupmnu.h"
+#include "nvim/screen.h"
+#include "nvim/state.h"
+#include "nvim/syntax.h"
+#include "nvim/types.h"
+#include "nvim/ui.h"
+#include "nvim/vim.h"
#include "nvim/viml/parser/expressions.h"
#include "nvim/viml/parser/parser.h"
-#include "nvim/ui.h"
+#include "nvim/window.h"
#define LINE_BUFFER_SIZE 4096
@@ -58,22 +58,16 @@
# include "api/vim.c.generated.h"
#endif
-void api_vim_init(void)
- FUNC_API_NOEXPORT
-{
- namespace_ids = map_new(String, handle_T)();
-}
-
void api_vim_free_all_mem(void)
FUNC_API_NOEXPORT
{
String name;
handle_T id;
- map_foreach(namespace_ids, name, id, {
+ map_foreach(&namespace_ids, name, id, {
(void)id;
xfree(name.data);
})
- map_free(String, handle_T)(namespace_ids);
+ map_destroy(String, handle_T)(&namespace_ids);
}
/// Executes Vimscript (multiline block of Ex-commands), like anonymous
@@ -217,7 +211,7 @@ Dictionary nvim__get_hl_defs(Integer ns_id, Error *err)
///
/// @param ns_id number of namespace for this highlight
/// @param name highlight group name, like ErrorMsg
-/// @param val highlight definiton map, like |nvim_get_hl_by_name|.
+/// @param val highlight definition map, like |nvim_get_hl_by_name|.
/// in addition the following keys are also recognized:
/// `default`: don't override existing definition,
/// like `hi default`
@@ -281,9 +275,9 @@ static void on_redraw_event(void **argv)
///
/// On execution error: does not fail, but updates v:errmsg.
///
-/// If you need to input sequences like <C-o> use |nvim_replace_termcodes| to
-/// replace the termcodes and then pass the resulting string to nvim_feedkeys.
-/// You'll also want to enable escape_csi.
+/// To input sequences like <C-o> use |nvim_replace_termcodes()| (typically
+/// with escape_csi=true) to replace |keycodes|, then pass the result to
+/// nvim_feedkeys().
///
/// Example:
/// <pre>
@@ -307,12 +301,18 @@ void nvim_feedkeys(String keys, String mode, Boolean escape_csi)
for (size_t i = 0; i < mode.size; ++i) {
switch (mode.data[i]) {
- case 'n': remap = false; break;
- case 'm': remap = true; break;
- case 't': typed = true; break;
- case 'i': insert = true; break;
- case 'x': execute = true; break;
- case '!': dangerous = true; break;
+ case 'n':
+ remap = false; break;
+ case 'm':
+ remap = true; break;
+ case 't':
+ typed = true; break;
+ case 'i':
+ insert = true; break;
+ case 'x':
+ execute = true; break;
+ case '!':
+ dangerous = true; break;
}
}
@@ -322,11 +322,11 @@ void nvim_feedkeys(String keys, String mode, Boolean escape_csi)
char *keys_esc;
if (escape_csi) {
- // Need to escape K_SPECIAL and CSI before putting the string in the
- // typeahead buffer.
- keys_esc = (char *)vim_strsave_escape_csi((char_u *)keys.data);
+ // Need to escape K_SPECIAL and CSI before putting the string in the
+ // typeahead buffer.
+ keys_esc = (char *)vim_strsave_escape_csi((char_u *)keys.data);
} else {
- keys_esc = keys.data;
+ keys_esc = keys.data;
}
ins_typebuf((char_u *)keys_esc, (remap ? REMAP_YES : REMAP_NONE),
insert ? 0 : typebuf.tb_len, !typed, false);
@@ -335,7 +335,7 @@ void nvim_feedkeys(String keys, String mode, Boolean escape_csi)
}
if (escape_csi) {
- xfree(keys_esc);
+ xfree(keys_esc);
}
if (execute) {
@@ -384,7 +384,7 @@ Integer nvim_input(String keys)
/// by calling it multiple times in a loop: the intermediate mouse
/// positions will be ignored. It should be used to implement real-time
/// mouse input in a GUI. The deprecated pseudokey form
-/// ("<LeftMouse><col,row>") of |nvim_input()| has the same limitiation.
+/// ("<LeftMouse><col,row>") of |nvim_input()| has the same limitation.
///
/// @param button Mouse button: one of "left", "right", "middle", "wheel".
/// @param action For ordinary buttons, one of "press", "drag", "release".
@@ -397,8 +397,8 @@ Integer nvim_input(String keys)
/// @param row Mouse row-position (zero-based, like redraw events)
/// @param col Mouse column-position (zero-based, like redraw events)
/// @param[out] err Error details, if any
-void nvim_input_mouse(String button, String action, String modifier,
- Integer grid, Integer row, Integer col, Error *err)
+void nvim_input_mouse(String button, String action, String modifier, Integer grid, Integer row,
+ Integer col, Error *err)
FUNC_API_SINCE(6) FUNC_API_FAST
{
if (button.data == NULL || action.data == NULL) {
@@ -475,8 +475,7 @@ error:
/// @param special Replace |keycodes|, e.g. <CR> becomes a "\n" char.
/// @see replace_termcodes
/// @see cpoptions
-String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt,
- Boolean special)
+String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt, Boolean special)
FUNC_API_SINCE(1)
{
if (str.size == 0) {
@@ -505,32 +504,32 @@ Object nvim_eval(String expr, Error *err)
Object rv = OBJECT_INIT;
TRY_WRAP({
- // Initialize `force_abort` and `suppress_errthrow` at the top level.
- if (!recursive) {
- force_abort = false;
- suppress_errthrow = false;
- current_exception = NULL;
- // `did_emsg` is set by emsg(), which cancels execution.
- did_emsg = false;
- }
- recursive++;
- try_start();
+ // Initialize `force_abort` and `suppress_errthrow` at the top level.
+ if (!recursive) {
+ force_abort = false;
+ suppress_errthrow = false;
+ current_exception = NULL;
+ // `did_emsg` is set by emsg(), which cancels execution.
+ did_emsg = false;
+ }
+ recursive++;
+ try_start();
- typval_T rettv;
- int ok = eval0((char_u *)expr.data, &rettv, NULL, true);
+ typval_T rettv;
+ int ok = eval0((char_u *)expr.data, &rettv, NULL, true);
- if (!try_end(err)) {
- if (ok == FAIL) {
- // Should never happen, try_end() should get the error. #8371
- api_set_error(err, kErrorTypeException,
- "Failed to evaluate expression: '%.*s'", 256, expr.data);
- } else {
- rv = vim_to_object(&rettv);
+ if (!try_end(err)) {
+ if (ok == FAIL) {
+ // Should never happen, try_end() should get the error. #8371
+ api_set_error(err, kErrorTypeException,
+ "Failed to evaluate expression: '%.*s'", 256, expr.data);
+ } else {
+ rv = vim_to_object(&rettv);
+ }
}
- }
- tv_clear(&rettv);
- recursive--;
+ tv_clear(&rettv);
+ recursive--;
});
return rv;
@@ -558,7 +557,7 @@ Object nvim_exec_lua(String code, Array args, Error *err)
/// Notify the user with a message
///
/// Relays the call to vim.notify . By default forwards your message in the
-/// echo area but can be overriden to trigger desktop notifications.
+/// echo area but can be overridden to trigger desktop notifications.
///
/// @param msg Message to display to the user
/// @param log_level The log level
@@ -603,28 +602,31 @@ static Object _call_function(String fn, Array args, dict_T *self, Error *err)
}
TRY_WRAP({
- // Initialize `force_abort` and `suppress_errthrow` at the top level.
- if (!recursive) {
- force_abort = false;
- suppress_errthrow = false;
- current_exception = NULL;
- // `did_emsg` is set by emsg(), which cancels execution.
- did_emsg = false;
- }
- recursive++;
- try_start();
- typval_T rettv;
- int dummy;
- // call_func() retval is deceptive, ignore it. Instead we set `msg_list`
- // (see above) to capture abort-causing non-exception errors.
- (void)call_func((char_u *)fn.data, (int)fn.size, &rettv, (int)args.size,
- vim_args, NULL, curwin->w_cursor.lnum, curwin->w_cursor.lnum,
- &dummy, true, NULL, self);
- if (!try_end(err)) {
- rv = vim_to_object(&rettv);
- }
- tv_clear(&rettv);
- recursive--;
+ // Initialize `force_abort` and `suppress_errthrow` at the top level.
+ if (!recursive) {
+ force_abort = false;
+ suppress_errthrow = false;
+ current_exception = NULL;
+ // `did_emsg` is set by emsg(), which cancels execution.
+ did_emsg = false;
+ }
+ recursive++;
+ try_start();
+ typval_T rettv;
+ funcexe_T funcexe = FUNCEXE_INIT;
+ funcexe.firstline = curwin->w_cursor.lnum;
+ funcexe.lastline = curwin->w_cursor.lnum;
+ funcexe.evaluate = true;
+ funcexe.selfdict = self;
+ // call_func() retval is deceptive, ignore it. Instead we set `msg_list`
+ // (see above) to capture abort-causing non-exception errors.
+ (void)call_func((char_u *)fn.data, (int)fn.size, &rettv, (int)args.size,
+ vim_args, &funcexe);
+ if (!try_end(err)) {
+ rv = vim_to_object(&rettv);
+ }
+ tv_clear(&rettv);
+ recursive--;
});
free_vim_args:
@@ -666,31 +668,28 @@ Object nvim_call_dict_function(Object dict, String fn, Array args, Error *err)
typval_T rettv;
bool mustfree = false;
switch (dict.type) {
- case kObjectTypeString: {
- try_start();
- if (eval0((char_u *)dict.data.string.data, &rettv, NULL, true) == FAIL) {
- api_set_error(err, kErrorTypeException,
- "Failed to evaluate dict expression");
- }
- if (try_end(err)) {
- return rv;
- }
- // Evaluation of the string arg created a new dict or increased the
- // refcount of a dict. Not necessary for a RPC dict.
- mustfree = true;
- break;
- }
- case kObjectTypeDictionary: {
- if (!object_to_vim(dict, &rettv, err)) {
- goto end;
- }
- break;
+ case kObjectTypeString:
+ try_start();
+ if (eval0((char_u *)dict.data.string.data, &rettv, NULL, true) == FAIL) {
+ api_set_error(err, kErrorTypeException,
+ "Failed to evaluate dict expression");
}
- default: {
- api_set_error(err, kErrorTypeValidation,
- "dict argument type must be String or Dictionary");
+ if (try_end(err)) {
return rv;
}
+ // Evaluation of the string arg created a new dict or increased the
+ // refcount of a dict. Not necessary for a RPC dict.
+ mustfree = true;
+ break;
+ case kObjectTypeDictionary:
+ if (!object_to_vim(dict, &rettv, err)) {
+ goto end;
+ }
+ break;
+ default:
+ api_set_error(err, kErrorTypeValidation,
+ "dict argument type must be String or Dictionary");
+ return rv;
}
dict_T *self_dict = rettv.vval.v_dict;
if (rettv.v_type != VAR_DICT || !self_dict) {
@@ -753,47 +752,10 @@ Integer nvim_strwidth(String text, Error *err)
/// Gets the paths contained in 'runtimepath'.
///
/// @return List of paths
-ArrayOf(String) nvim_list_runtime_paths(void)
+ArrayOf(String) nvim_list_runtime_paths(Error *err)
FUNC_API_SINCE(1)
{
- // TODO(bfredl): this should just work:
- // return nvim_get_runtime_file(NULL_STRING, true);
-
- Array rv = ARRAY_DICT_INIT;
-
- char_u *rtp = p_rtp;
-
- if (*rtp == NUL) {
- // No paths
- return rv;
- }
-
- // Count the number of paths in rtp
- while (*rtp != NUL) {
- if (*rtp == ',') {
- rv.size++;
- }
- rtp++;
- }
- rv.size++;
-
- // Allocate memory for the copies
- rv.items = xmalloc(sizeof(*rv.items) * rv.size);
- // Reset the position
- rtp = p_rtp;
- // Start copying
- for (size_t i = 0; i < rv.size; i++) {
- rv.items[i].type = kObjectTypeString;
- rv.items[i].data.string.data = xmalloc(MAXPATHL);
- // Copy the path from 'runtimepath' to rv.items[i]
- size_t length = copy_option_part(&rtp,
- (char_u *)rv.items[i].data.string.data,
- MAXPATHL,
- ",");
- rv.items[i].data.string.size = length;
- }
-
- return rv;
+ return nvim_get_runtime_file(NULL_STRING, true, err);
}
/// Find files in runtime directories
@@ -805,10 +767,6 @@ ArrayOf(String) nvim_list_runtime_paths(void)
///
/// It is not an error to not find any files. An empty array is returned then.
///
-/// To find a directory, `name` must end with a forward slash, like
-/// "rplugin/python/". Without the slash it would instead look for an ordinary
-/// file called "rplugin/python".
-///
/// @param name pattern of files to search for
/// @param all whether to return all matches or only the first
/// @return list of absolute paths to the found files
@@ -818,11 +776,7 @@ ArrayOf(String) nvim_get_runtime_file(String name, Boolean all, Error *err)
{
Array rv = ARRAY_DICT_INIT;
- int flags = DIP_START | (all ? DIP_ALL : 0);
-
- if (name.size == 0 || name.data[name.size-1] == '/') {
- flags |= DIP_DIR;
- }
+ int flags = DIP_DIRFILE | (all ? DIP_ALL : 0);
do_in_runtimepath((char_u *)(name.size ? name.data : ""),
flags, find_runtime_cb, &rv);
@@ -1260,7 +1214,7 @@ fail:
///
/// By default (and currently the only option) the terminal will not be
/// connected to an external process. Instead, input send on the channel
-/// will be echoed directly by the terminal. This is useful to disply
+/// will be echoed directly by the terminal. This is useful to display
/// ANSI terminal sequences returned as part of a rpc message, or similar.
///
/// Note: to directly initiate the terminal using the right size, display the
@@ -1290,7 +1244,7 @@ Integer nvim_open_term(Buffer buffer, Dictionary opts, Error *err)
TerminalOptions topts;
Channel *chan = channel_alloc(kChannelStreamInternal);
topts.data = chan;
- // NB: overriden in terminal_check_size if a window is already
+ // NB: overridden in terminal_check_size if a window is already
// displaying the buffer
topts.width = (uint16_t)MAX(curwin->w_width_inner - win_col_off(curwin), 0);
topts.height = (uint16_t)curwin->w_height_inner;
@@ -1468,8 +1422,7 @@ void nvim_chan_send(Integer chan, String data, Error *err)
/// @param[out] err Error details, if any
///
/// @return Window handle, or 0 on error
-Window nvim_open_win(Buffer buffer, Boolean enter, Dictionary config,
- Error *err)
+Window nvim_open_win(Buffer buffer, Boolean enter, Dictionary config, Error *err)
FUNC_API_SINCE(6)
FUNC_API_CHECK_TEXTLOCK
{
@@ -1554,10 +1507,10 @@ void nvim_set_current_tabpage(Tabpage tabpage, Error *err)
}
}
-/// Creates a new namespace, or gets an existing one.
+/// Creates a new *namespace*, or gets an existing one.
///
/// Namespaces are used for buffer highlights and virtual text, see
-/// |nvim_buf_add_highlight()| and |nvim_buf_set_virtual_text()|.
+/// |nvim_buf_add_highlight()| and |nvim_buf_set_extmark()|.
///
/// Namespaces can be named or anonymous. If `name` matches an existing
/// namespace, the associated id is returned. If `name` is an empty string
@@ -1568,14 +1521,14 @@ void nvim_set_current_tabpage(Tabpage tabpage, Error *err)
Integer nvim_create_namespace(String name)
FUNC_API_SINCE(5)
{
- handle_T id = map_get(String, handle_T)(namespace_ids, name);
+ handle_T id = map_get(String, handle_T)(&namespace_ids, name);
if (id > 0) {
return id;
}
id = next_namespace_id++;
if (name.size > 0) {
String name_alloc = copy_string(name);
- map_put(String, handle_T)(namespace_ids, name_alloc, id);
+ map_put(String, handle_T)(&namespace_ids, name_alloc, id);
}
return (Integer)id;
}
@@ -1590,7 +1543,7 @@ Dictionary nvim_get_namespaces(void)
String name;
handle_T id;
- map_foreach(namespace_ids, name, id, {
+ map_foreach(&namespace_ids, name, id, {
PUT(retval, name.data, INTEGER_OBJ(id));
})
@@ -1627,7 +1580,7 @@ Boolean nvim_paste(String data, Boolean crlf, Integer phase, Error *err)
bool cancel = false;
if (phase < -1 || phase > 3) {
- api_set_error(err, kErrorTypeValidation, "Invalid phase: %"PRId64, phase);
+ api_set_error(err, kErrorTypeValidation, "Invalid phase: %" PRId64, phase);
return false;
}
Array args = ARRAY_DICT_INIT;
@@ -1691,12 +1644,11 @@ theend:
/// @param after If true insert after cursor (like |p|), or before (like |P|).
/// @param follow If true place cursor at end of inserted text.
/// @param[out] err Error details, if any
-void nvim_put(ArrayOf(String) lines, String type, Boolean after,
- Boolean follow, Error *err)
+void nvim_put(ArrayOf(String) lines, String type, Boolean after, Boolean follow, Error *err)
FUNC_API_SINCE(6)
FUNC_API_CHECK_TEXTLOCK
{
- yankreg_T *reg = xcalloc(sizeof(yankreg_T), 1);
+ yankreg_T *reg = xcalloc(1, sizeof(yankreg_T));
if (!prepare_yankreg_from_object(reg, type, lines.size)) {
api_set_error(err, kErrorTypeValidation, "Invalid type: '%s'", type.data);
goto cleanup;
@@ -1933,8 +1885,7 @@ ArrayOf(Dictionary) nvim_get_keymap(String mode)
/// as keys excluding |<buffer>| but including |noremap|.
/// Values are Booleans. Unknown key is an error.
/// @param[out] err Error details, if any.
-void nvim_set_keymap(String mode, String lhs, String rhs,
- Dictionary opts, Error *err)
+void nvim_set_keymap(String mode, String lhs, String rhs, Dictionary opts, Error *err)
FUNC_API_SINCE(6)
{
modify_keymap(-1, false, mode, lhs, rhs, opts, err);
@@ -2031,10 +1982,8 @@ Array nvim_get_api_info(uint64_t channel_id)
/// .png or .svg format is preferred.
///
/// @param[out] err Error details, if any
-void nvim_set_client_info(uint64_t channel_id, String name,
- Dictionary version, String type,
- Dictionary methods, Dictionary attributes,
- Error *err)
+void nvim_set_client_info(uint64_t channel_id, String name, Dictionary version, String type,
+ Dictionary methods, Dictionary attributes, Error *err)
FUNC_API_SINCE(4) FUNC_API_REMOTE_ONLY
{
Dictionary info = ARRAY_DICT_INIT;
@@ -2060,27 +2009,28 @@ void nvim_set_client_info(uint64_t channel_id, String name,
rpc_set_client_info(channel_id, info);
}
-/// Get information about a channel.
+/// Gets information about a channel.
///
/// @returns Dictionary describing a channel, with these keys:
-/// - "stream" the stream underlying the channel
+/// - "id" Channel id.
+/// - "argv" (optional) Job arguments list.
+/// - "stream" Stream underlying the channel.
/// - "stdio" stdin and stdout of this Nvim instance
/// - "stderr" stderr of this Nvim instance
/// - "socket" TCP/IP socket or named pipe
-/// - "job" job with communication over its stdio
-/// - "mode" how data received on the channel is interpreted
-/// - "bytes" send and receive raw bytes
-/// - "terminal" a |terminal| instance interprets ASCII sequences
-/// - "rpc" |RPC| communication on the channel is active
-/// - "pty" Name of pseudoterminal, if one is used (optional).
-/// On a POSIX system, this will be a device path like
-/// /dev/pts/1. Even if the name is unknown, the key will
-/// still be present to indicate a pty is used. This is
-/// currently the case when using winpty on windows.
-/// - "buffer" buffer with connected |terminal| instance (optional)
-/// - "client" information about the client on the other end of the
-/// RPC channel, if it has added it using
-/// |nvim_set_client_info()|. (optional)
+/// - "job" Job with communication over its stdio.
+/// - "mode" How data received on the channel is interpreted.
+/// - "bytes" Send and receive raw bytes.
+/// - "terminal" |terminal| instance interprets ASCII sequences.
+/// - "rpc" |RPC| communication on the channel is active.
+/// - "pty" (optional) Name of pseudoterminal. On a POSIX system this
+/// is a device path like "/dev/pts/1". If the name is unknown,
+/// the key will still be present if a pty is used (e.g. for
+/// winpty on Windows).
+/// - "buffer" (optional) Buffer with connected |terminal| instance.
+/// - "client" (optional) Info about the peer (client on the other end of
+/// the RPC channel), if provided by it via
+/// |nvim_set_client_info()|.
///
Dictionary nvim_get_chan_info(Integer chan, Error *err)
FUNC_API_SINCE(4)
@@ -2161,9 +2111,9 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err)
Array args = call.items[1].data.array;
MsgpackRpcRequestHandler handler =
- msgpack_rpc_get_handler_for(name.data,
- name.size,
- &nested_error);
+ msgpack_rpc_get_handler_for(name.data,
+ name.size,
+ &nested_error);
if (ERROR_SET(&nested_error)) {
break;
@@ -2237,7 +2187,7 @@ typedef kvec_withinit_t(ExprASTConvStackItem, 16) ExprASTConvStack;
/// - "arg": String, error message argument.
/// - "len": Amount of bytes successfully parsed. With flags equal to ""
/// that should be equal to the length of expr string.
-/// (“Sucessfully parsed” here means “participated in AST
+/// (“Successfully parsed” here means “participated in AST
/// creation”, not “till the first error”.)
/// - "ast": AST, either nil or a dictionary with these keys:
/// - "type": node type, one of the value names from ExprASTNodeType
@@ -2279,29 +2229,29 @@ typedef kvec_withinit_t(ExprASTConvStackItem, 16) ExprASTConvStack;
/// - "svalue": String, value for "SingleQuotedString" and
/// "DoubleQuotedString" nodes.
/// @param[out] err Error details, if any
-Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
- Error *err)
+Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight, Error *err)
FUNC_API_SINCE(4) FUNC_API_FAST
{
int pflags = 0;
for (size_t i = 0 ; i < flags.size ; i++) {
switch (flags.data[i]) {
- case 'm': { pflags |= kExprFlagsMulti; break; }
- case 'E': { pflags |= kExprFlagsDisallowEOC; break; }
- case 'l': { pflags |= kExprFlagsParseLet; break; }
- case NUL: {
- api_set_error(err, kErrorTypeValidation, "Invalid flag: '\\0' (%u)",
- (unsigned)flags.data[i]);
- return (Dictionary)ARRAY_DICT_INIT;
- }
- default: {
- api_set_error(err, kErrorTypeValidation, "Invalid flag: '%c' (%u)",
- flags.data[i], (unsigned)flags.data[i]);
- return (Dictionary)ARRAY_DICT_INIT;
- }
+ case 'm':
+ pflags |= kExprFlagsMulti; break;
+ case 'E':
+ pflags |= kExprFlagsDisallowEOC; break;
+ case 'l':
+ pflags |= kExprFlagsParseLet; break;
+ case NUL:
+ api_set_error(err, kErrorTypeValidation, "Invalid flag: '\\0' (%u)",
+ (unsigned)flags.data[i]);
+ return (Dictionary)ARRAY_DICT_INIT;
+ default:
+ api_set_error(err, kErrorTypeValidation, "Invalid flag: '%c' (%u)",
+ flags.data[i], (unsigned)flags.data[i]);
+ return (Dictionary)ARRAY_DICT_INIT;
}
}
- ParserLine plines[] = {
+ ParserLine parser_lines[] = {
{
.data = expr.data,
.size = expr.size,
@@ -2309,20 +2259,19 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
},
{ NULL, 0, false },
};
- ParserLine *plines_p = plines;
+ ParserLine *plines_p = parser_lines;
ParserHighlight colors;
kvi_init(colors);
ParserHighlight *const colors_p = (highlight ? &colors : NULL);
ParserState pstate;
- viml_parser_init(
- &pstate, parser_simple_get_line, &plines_p, colors_p);
+ viml_parser_init(&pstate, parser_simple_get_line, &plines_p, colors_p);
ExprAST east = viml_pexpr_parse(&pstate, pflags);
const size_t ret_size = (
- 2 // "ast", "len"
- + (size_t)(east.err.msg != NULL) // "error"
- + (size_t)highlight // "highlight"
- + 0);
+ 2 // "ast", "len"
+ + (size_t)(east.err.msg != NULL) // "error"
+ + (size_t)highlight // "highlight"
+ + 0);
Dictionary ret = {
.items = xmalloc(ret_size * sizeof(ret.items[0])),
.size = 0,
@@ -2335,7 +2284,7 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
ret.items[ret.size++] = (KeyValuePair) {
.key = STATIC_CSTR_TO_STRING("len"),
.value = INTEGER_OBJ((Integer)(pstate.pos.line == 1
- ? plines[0].size
+ ? parser_lines[0].size
: pstate.pos.col)),
};
if (east.err.msg != NULL) {
@@ -2409,23 +2358,23 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
} else {
if (cur_item.ret_node_p->type == kObjectTypeNil) {
const size_t ret_node_items_size = (size_t)(
- 3 // "type", "start" and "len"
- + (node->children != NULL) // "children"
- + (node->type == kExprNodeOption
- || node->type == kExprNodePlainIdentifier) // "scope"
- + (node->type == kExprNodeOption
- || node->type == kExprNodePlainIdentifier
- || node->type == kExprNodePlainKey
- || node->type == kExprNodeEnvironment) // "ident"
- + (node->type == kExprNodeRegister) // "name"
- + (3 // "cmp_type", "ccs_strategy", "invert"
- * (node->type == kExprNodeComparison))
- + (node->type == kExprNodeInteger) // "ivalue"
- + (node->type == kExprNodeFloat) // "fvalue"
- + (node->type == kExprNodeDoubleQuotedString
- || node->type == kExprNodeSingleQuotedString) // "svalue"
- + (node->type == kExprNodeAssignment) // "augmentation"
- + 0);
+ 3 // "type", "start" and "len"
+ + (node->children != NULL) // "children"
+ + (node->type == kExprNodeOption
+ || node->type == kExprNodePlainIdentifier) // "scope"
+ + (node->type == kExprNodeOption
+ || node->type == kExprNodePlainIdentifier
+ || node->type == kExprNodePlainKey
+ || node->type == kExprNodeEnvironment) // "ident"
+ + (node->type == kExprNodeRegister) // "name"
+ + (3 // "cmp_type", "ccs_strategy", "invert"
+ * (node->type == kExprNodeComparison))
+ + (node->type == kExprNodeInteger) // "ivalue"
+ + (node->type == kExprNodeFloat) // "fvalue"
+ + (node->type == kExprNodeDoubleQuotedString
+ || node->type == kExprNodeSingleQuotedString) // "svalue"
+ + (node->type == kExprNodeAssignment) // "augmentation"
+ + 0);
Dictionary ret_node = {
.items = xmalloc(ret_node_items_size * sizeof(ret_node.items[0])),
.capacity = ret_node_items_size,
@@ -2479,151 +2428,138 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
.value = INTEGER_OBJ((Integer)node->len),
};
switch (node->type) {
- case kExprNodeDoubleQuotedString:
- case kExprNodeSingleQuotedString: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("svalue"),
- .value = STRING_OBJ(((String) {
- .data = node->data.str.value,
- .size = node->data.str.size,
- })),
- };
- break;
- }
- case kExprNodeOption: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("scope"),
- .value = INTEGER_OBJ(node->data.opt.scope),
- };
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ident"),
- .value = STRING_OBJ(((String) {
- .data = xmemdupz(node->data.opt.ident,
- node->data.opt.ident_len),
- .size = node->data.opt.ident_len,
- })),
- };
- break;
- }
- case kExprNodePlainIdentifier: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("scope"),
- .value = INTEGER_OBJ(node->data.var.scope),
- };
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ident"),
- .value = STRING_OBJ(((String) {
- .data = xmemdupz(node->data.var.ident,
- node->data.var.ident_len),
- .size = node->data.var.ident_len,
- })),
- };
- break;
- }
- case kExprNodePlainKey: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ident"),
- .value = STRING_OBJ(((String) {
- .data = xmemdupz(node->data.var.ident,
- node->data.var.ident_len),
- .size = node->data.var.ident_len,
- })),
- };
- break;
- }
- case kExprNodeEnvironment: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ident"),
- .value = STRING_OBJ(((String) {
- .data = xmemdupz(node->data.env.ident,
- node->data.env.ident_len),
- .size = node->data.env.ident_len,
- })),
- };
- break;
- }
- case kExprNodeRegister: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("name"),
- .value = INTEGER_OBJ(node->data.reg.name),
- };
- break;
- }
- case kExprNodeComparison: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("cmp_type"),
- .value = STRING_OBJ(cstr_to_string(
- eltkn_cmp_type_tab[node->data.cmp.type])),
- };
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ccs_strategy"),
- .value = STRING_OBJ(cstr_to_string(
- ccs_tab[node->data.cmp.ccs])),
- };
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("invert"),
- .value = BOOLEAN_OBJ(node->data.cmp.inv),
- };
- break;
- }
- case kExprNodeFloat: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("fvalue"),
- .value = FLOAT_OBJ(node->data.flt.value),
- };
- break;
- }
- case kExprNodeInteger: {
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("ivalue"),
- .value = INTEGER_OBJ((Integer)(
- node->data.num.value > API_INTEGER_MAX
+ case kExprNodeDoubleQuotedString:
+ case kExprNodeSingleQuotedString:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("svalue"),
+ .value = STRING_OBJ(((String) {
+ .data = node->data.str.value,
+ .size = node->data.str.size,
+ })),
+ };
+ break;
+ case kExprNodeOption:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("scope"),
+ .value = INTEGER_OBJ(node->data.opt.scope),
+ };
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ident"),
+ .value = STRING_OBJ(((String) {
+ .data = xmemdupz(node->data.opt.ident,
+ node->data.opt.ident_len),
+ .size = node->data.opt.ident_len,
+ })),
+ };
+ break;
+ case kExprNodePlainIdentifier:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("scope"),
+ .value = INTEGER_OBJ(node->data.var.scope),
+ };
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ident"),
+ .value = STRING_OBJ(((String) {
+ .data = xmemdupz(node->data.var.ident,
+ node->data.var.ident_len),
+ .size = node->data.var.ident_len,
+ })),
+ };
+ break;
+ case kExprNodePlainKey:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ident"),
+ .value = STRING_OBJ(((String) {
+ .data = xmemdupz(node->data.var.ident,
+ node->data.var.ident_len),
+ .size = node->data.var.ident_len,
+ })),
+ };
+ break;
+ case kExprNodeEnvironment:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ident"),
+ .value = STRING_OBJ(((String) {
+ .data = xmemdupz(node->data.env.ident,
+ node->data.env.ident_len),
+ .size = node->data.env.ident_len,
+ })),
+ };
+ break;
+ case kExprNodeRegister:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("name"),
+ .value = INTEGER_OBJ(node->data.reg.name),
+ };
+ break;
+ case kExprNodeComparison:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("cmp_type"),
+ .value = STRING_OBJ(cstr_to_string(eltkn_cmp_type_tab[node->data.cmp.type])),
+ };
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ccs_strategy"),
+ .value = STRING_OBJ(cstr_to_string(ccs_tab[node->data.cmp.ccs])),
+ };
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("invert"),
+ .value = BOOLEAN_OBJ(node->data.cmp.inv),
+ };
+ break;
+ case kExprNodeFloat:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("fvalue"),
+ .value = FLOAT_OBJ(node->data.flt.value),
+ };
+ break;
+ case kExprNodeInteger:
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ivalue"),
+ .value = INTEGER_OBJ((Integer)(
+ node->data.num.value > API_INTEGER_MAX
? API_INTEGER_MAX
: (Integer)node->data.num.value)),
- };
- break;
- }
- case kExprNodeAssignment: {
- const ExprAssignmentType asgn_type = node->data.ass.type;
- ret_node->items[ret_node->size++] = (KeyValuePair) {
- .key = STATIC_CSTR_TO_STRING("augmentation"),
- .value = STRING_OBJ(
- asgn_type == kExprAsgnPlain
+ };
+ break;
+ case kExprNodeAssignment: {
+ const ExprAssignmentType asgn_type = node->data.ass.type;
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("augmentation"),
+ .value = STRING_OBJ(asgn_type == kExprAsgnPlain
? (String)STRING_INIT
: cstr_to_string(expr_asgn_type_tab[asgn_type])),
- };
- break;
- }
- case kExprNodeMissing:
- case kExprNodeOpMissing:
- case kExprNodeTernary:
- case kExprNodeTernaryValue:
- case kExprNodeSubscript:
- case kExprNodeListLiteral:
- case kExprNodeUnaryPlus:
- case kExprNodeBinaryPlus:
- case kExprNodeNested:
- case kExprNodeCall:
- case kExprNodeComplexIdentifier:
- case kExprNodeUnknownFigure:
- case kExprNodeLambda:
- case kExprNodeDictLiteral:
- case kExprNodeCurlyBracesIdentifier:
- case kExprNodeComma:
- case kExprNodeColon:
- case kExprNodeArrow:
- case kExprNodeConcat:
- case kExprNodeConcatOrSubscript:
- case kExprNodeOr:
- case kExprNodeAnd:
- case kExprNodeUnaryMinus:
- case kExprNodeBinaryMinus:
- case kExprNodeNot:
- case kExprNodeMultiplication:
- case kExprNodeDivision:
- case kExprNodeMod: {
- break;
- }
+ };
+ break;
+ }
+ case kExprNodeMissing:
+ case kExprNodeOpMissing:
+ case kExprNodeTernary:
+ case kExprNodeTernaryValue:
+ case kExprNodeSubscript:
+ case kExprNodeListLiteral:
+ case kExprNodeUnaryPlus:
+ case kExprNodeBinaryPlus:
+ case kExprNodeNested:
+ case kExprNodeCall:
+ case kExprNodeComplexIdentifier:
+ case kExprNodeUnknownFigure:
+ case kExprNodeLambda:
+ case kExprNodeDictLiteral:
+ case kExprNodeCurlyBracesIdentifier:
+ case kExprNodeComma:
+ case kExprNodeColon:
+ case kExprNodeArrow:
+ case kExprNodeConcat:
+ case kExprNodeConcatOrSubscript:
+ case kExprNodeOr:
+ case kExprNodeAnd:
+ case kExprNodeUnaryMinus:
+ case kExprNodeBinaryMinus:
+ case kExprNodeNot:
+ case kExprNodeMultiplication:
+ case kExprNodeDivision:
+ case kExprNodeMod:
+ break;
}
assert(cur_item.ret_node_p->data.dictionary.size
== cur_item.ret_node_p->data.dictionary.capacity);
@@ -2853,8 +2789,8 @@ Object nvim_get_proc(Integer pid, Error *err)
/// `insert`.
/// @param opts Optional parameters. Reserved for future use.
/// @param[out] err Error details, if any
-void nvim_select_popupmenu_item(Integer item, Boolean insert, Boolean finish,
- Dictionary opts, Error *err)
+void nvim_select_popupmenu_item(Integer item, Boolean insert, Boolean finish, Dictionary opts,
+ Error *err)
FUNC_API_SINCE(6)
{
if (opts.size > 0) {
@@ -2925,7 +2861,7 @@ void nvim__screenshot(String path)
/// Note: this function should not be called often. Rather, the callbacks
/// themselves can be used to throttle unneeded callbacks. the `on_start`
/// callback can return `false` to disable the provider until the next redraw.
-/// Similarily, return `false` in `on_win` will skip the `on_lines` calls
+/// Similarly, return `false` in `on_win` will skip the `on_lines` calls
/// for that window (but any extmarks set in `on_win` will still be used).
/// A plugin managing multiple sources of decoration should ideally only set
/// one provider, and merge the sources internally. You can use multiple `ns_id`
@@ -2951,8 +2887,7 @@ void nvim__screenshot(String path)
/// ["win", winid, bufnr, row]
/// - on_end: called at the end of a redraw cycle
/// ["end", tick]
-void nvim_set_decoration_provider(Integer ns_id, DictionaryOf(LuaRef) opts,
- Error *err)
+void nvim_set_decoration_provider(Integer ns_id, DictionaryOf(LuaRef) opts, Error *err)
FUNC_API_SINCE(7) FUNC_API_LUA_ONLY
{
DecorProvider *p = get_decor_provider((NS)ns_id, true);