diff options
Diffstat (limited to 'src/nvim/api')
-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 | 143 |
3 files changed, 183 insertions, 127 deletions
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 10f7dd1a7b..19601b6539 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -25,6 +25,7 @@ #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" @@ -72,10 +73,70 @@ void api_vim_free_all_mem(void) map_free(String, handle_T)(namespace_ids); } +/// Executes Vimscript (multiline block of Ex-commands), like anonymous +/// |:source|. +/// +/// Unlike |nvim_command()| this function supports heredocs, script-scope (s:), +/// etc. +/// +/// On execution error: fails with VimL error, does not update v:errmsg. +/// +/// @see |execute()| +/// @see |nvim_command()| +/// +/// @param src Vimscript code +/// @param output Capture and return all (non-error, non-shell |:!|) output +/// @param[out] err Error details (Vim error), if any +/// @return Output (non-error, non-shell |:!|) if `output` is true, +/// else empty string. +String nvim_exec(String src, Boolean output, Error *err) + FUNC_API_SINCE(7) +{ + const int save_msg_silent = msg_silent; + garray_T *const save_capture_ga = capture_ga; + garray_T capture_local; + if (output) { + ga_init(&capture_local, 1, 80); + capture_ga = &capture_local; + } + + try_start(); + msg_silent++; + do_source_str(src.data, "nvim_exec()"); + capture_ga = save_capture_ga; + msg_silent = save_msg_silent; + try_end(err); + + if (ERROR_SET(err)) { + goto theend; + } + + if (output && capture_local.ga_len > 1) { + String s = (String){ + .data = capture_local.ga_data, + .size = (size_t)capture_local.ga_len, + }; + // redir usually (except :echon) prepends a newline. + if (s.data[0] == '\n') { + memmove(s.data, s.data + 1, s.size - 1); + s.data[s.size - 1] = '\0'; + s.size = s.size - 1; + } + return s; // Caller will free the memory. + } +theend: + if (output) { + ga_clear(&capture_local); + } + return (String)STRING_INIT; +} + /// Executes an ex-command. /// /// On execution error: fails with VimL error, does not update v:errmsg. /// +/// @see |nvim_exec()| +/// /// @param command Ex-command string /// @param[out] err Error details (Vim error), if any void nvim_command(String command, Error *err) @@ -332,53 +393,16 @@ String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt, return cstr_as_string(ptr); } -/// Executes an ex-command and returns its (non-error) output. -/// Shell |:!| output is not captured. -/// -/// On execution error: fails with VimL error, does not update v:errmsg. -/// -/// @param command Ex-command string -/// @param[out] err Error details (Vim error), if any +/// @deprecated +/// @see nvim_exec String nvim_command_output(String command, Error *err) FUNC_API_SINCE(1) + FUNC_API_DEPRECATED_SINCE(7) { - const int save_msg_silent = msg_silent; - garray_T *const save_capture_ga = capture_ga; - garray_T capture_local; - ga_init(&capture_local, 1, 80); - - try_start(); - msg_silent++; - capture_ga = &capture_local; - do_cmdline_cmd(command.data); - capture_ga = save_capture_ga; - msg_silent = save_msg_silent; - try_end(err); - - if (ERROR_SET(err)) { - goto theend; - } - - if (capture_local.ga_len > 1) { - String s = (String){ - .data = capture_local.ga_data, - .size = (size_t)capture_local.ga_len, - }; - // redir usually (except :echon) prepends a newline. - if (s.data[0] == '\n') { - memmove(s.data, s.data + 1, s.size - 1); - s.data[s.size - 1] = '\0'; - s.size = s.size - 1; - } - return s; // Caller will free the memory. - } - -theend: - ga_clear(&capture_local); - return (String)STRING_INIT; + return nvim_exec(command, true, err); } -/// Evaluates a VimL expression (:help expression). +/// Evaluates a VimL |expression|. /// Dictionaries and Lists are recursively expanded. /// /// On execution error: fails with VimL error, does not update v:errmsg. @@ -423,6 +447,15 @@ Object nvim_eval(String expr, Error *err) return rv; } +/// @deprecated Use nvim_exec_lua() instead. +Object nvim_execute_lua(String code, Array args, Error *err) + FUNC_API_SINCE(3) + FUNC_API_DEPRECATED_SINCE(7) + FUNC_API_REMOTE_ONLY +{ + return executor_exec_lua_api(code, args, err); +} + /// Execute Lua code. Parameters (if any) are available as `...` inside the /// chunk. The chunk can return a value. /// @@ -435,8 +468,9 @@ Object nvim_eval(String expr, Error *err) /// or executing the Lua code. /// /// @return Return value of Lua code if present or NIL. -Object nvim_execute_lua(String code, Array args, Error *err) - FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY +Object nvim_exec_lua(String code, Array args, Error *err) + FUNC_API_SINCE(7) + FUNC_API_REMOTE_ONLY { return executor_exec_lua_api(code, args, err); } @@ -1074,9 +1108,10 @@ fail: /// float where the text should not be edited. Disables /// 'number', 'relativenumber', 'cursorline', 'cursorcolumn', /// 'foldcolumn', 'spell' and 'list' options. 'signcolumn' -/// is changed to `auto`. The end-of-buffer region is hidden -/// by setting `eob` flag of 'fillchars' to a space char, -/// and clearing the |EndOfBuffer| region in 'winhighlight'. +/// 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'. /// @param[out] err Error details, if any /// /// @return Window handle, or 0 on error @@ -1095,6 +1130,10 @@ Window nvim_open_win(Buffer buffer, Boolean enter, Dictionary config, if (enter) { win_enter(wp, false); } + if (!win_valid(wp)) { + api_set_error(err, kErrorTypeException, "Window was closed immediately"); + return 0; + } if (buffer > 0) { nvim_win_set_buf(wp->handle, buffer, err); } @@ -1246,8 +1285,8 @@ Boolean nvim_paste(String data, Boolean crlf, Integer phase, Error *err) Array lines = string_to_array(data, crlf); ADD(args, ARRAY_OBJ(lines)); ADD(args, INTEGER_OBJ(phase)); - rv = nvim_execute_lua(STATIC_CSTR_AS_STRING("return vim.paste(...)"), args, - err); + rv = nvim_exec_lua(STATIC_CSTR_AS_STRING("return vim.paste(...)"), args, + err); if (ERROR_SET(err)) { draining = true; goto theend; @@ -1290,7 +1329,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|). @@ -2381,7 +2420,7 @@ Array nvim_get_proc_children(Integer pid, Error *err) Array a = ARRAY_DICT_INIT; ADD(a, INTEGER_OBJ(pid)); String s = cstr_to_string("return vim._os_proc_children(select(1, ...))"); - Object o = nvim_execute_lua(s, a, err); + Object o = nvim_exec_lua(s, a, err); api_free_string(s); api_free_array(a); if (o.type == kObjectTypeArray) { @@ -2427,7 +2466,7 @@ Object nvim_get_proc(Integer pid, Error *err) Array a = ARRAY_DICT_INIT; ADD(a, INTEGER_OBJ(pid)); String s = cstr_to_string("return vim._os_proc_info(select(1, ...))"); - Object o = nvim_execute_lua(s, a, err); + Object o = nvim_exec_lua(s, a, err); api_free_string(s); api_free_array(a); if (o.type == kObjectTypeArray && o.data.array.size == 0) { |