diff options
-rw-r--r-- | runtime/doc/api.txt | 79 | ||||
-rwxr-xr-x | scripts/gen_vimdoc.py | 1 | ||||
-rw-r--r-- | src/nvim/api/buffer.c | 2 | ||||
-rw-r--r-- | src/nvim/api/vim.c | 8 | ||||
-rw-r--r-- | src/nvim/api/window.c | 2 | ||||
-rw-r--r-- | src/nvim/func_attr.h | 2 | ||||
-rw-r--r-- | src/nvim/generators/c_grammar.lua | 1 | ||||
-rw-r--r-- | src/nvim/generators/gen_api_dispatch.lua | 17 | ||||
-rw-r--r-- | test/functional/eval/api_functions_spec.lua | 4 |
9 files changed, 94 insertions, 22 deletions
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index 755e7becb3..7a3af78ab4 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -646,6 +646,9 @@ nvim_create_namespace({name}) *nvim_create_namespace()* nvim_del_current_line() *nvim_del_current_line()* Deletes the current line. + Attributes: ~ + not allowed when |textlock| is active + nvim_del_keymap({mode}, {lhs}) *nvim_del_keymap()* Unmaps a global |mapping| for the given mode. @@ -755,6 +758,15 @@ nvim_feedkeys({keys}, {mode}, {escape_csi}) *nvim_feedkeys()* feedkeys() vim_strsave_escape_csi +nvim_get_all_options_info() *nvim_get_all_options_info()* + 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|. + + Return: ~ + dictionary of all options + nvim_get_api_info() *nvim_get_api_info()* Returns a 2-tuple (Array), where item 0 is the current channel id and item 1 is the |api-metadata| map (Dictionary). @@ -937,22 +949,18 @@ nvim_get_option_info({name}) *nvim_get_option_info()* Gets the option information for one option Resulting dictionary has keys: - • name (string): Name of the option - • shortname (shortname): Shortened name of the option - • type (string): Name of the type of option - • default (Any): The default value for the option - - Script-Related Keys: - • was_set (bool): Whether the option was set. - • last_set_sid (int): Last set script id - • last_set_linenr (int): Last set script id, -1 if invalid. - • last_set_lchan (int): Last set script id, -1 if invalid. - - Flag-Related Keys: - • win (bool): Window-local option - • buf (bool): Buffer-local option - • global_local (bool): Global or Buffer local option - • flaglist (bool): List of single char flags + • name: Name of the option (like 'filetype') + • shortname: Shortened name of the option (like 'ft') + • type: type of option ("string", "integer" or "boolean") + • default: The default value for the option + • was_set: Whether the option was set. + • last_set_sid: Last set script id (if any) + • last_set_linenr: line number where option was set + • last_set_chan: Channel where option was set (0 for local) + • scope: one of "global", "win", or "buf" + • global_local: whether win or buf option has a global value + • commalist: List of comma separated values + • flaglist: List of single char flags Parameters: ~ {name} Option name @@ -960,12 +968,6 @@ nvim_get_option_info({name}) *nvim_get_option_info()* Return: ~ Option Information -nvim_get_options_info() *nvim_get_options_info()* - Gets the option information for all options. - - Return: ~ - Map<option_name, option_info> - nvim_get_proc({pid}) *nvim_get_proc()* Gets info describing process `pid` . @@ -1174,6 +1176,9 @@ nvim_open_win({buffer}, {enter}, {config}) *nvim_open_win()* {relative='win', width=12, height=3, bufpos={100,10}}) < + Attributes: ~ + not allowed when |textlock| is active + Parameters: ~ {buffer} Buffer to display, or 0 for current buffer {enter} Enter the window (make it the current window) @@ -1352,6 +1357,9 @@ nvim_paste({data}, {crlf}, {phase}) *nvim_paste()* calls are ignored ("drained") until the next paste is initiated (phase 1 or -1). + Attributes: ~ + not allowed when |textlock| is active + Parameters: ~ {data} Multiline input. May be binary (containing NUL bytes). @@ -1372,6 +1380,9 @@ nvim_put({lines}, {type}, {after}, {follow}) *nvim_put()* Compare |:put| and |p| which are always linewise. + Attributes: ~ + not allowed when |textlock| is active + Parameters: ~ {lines} |readfile()|-style list of lines. |channel-lines| @@ -1489,6 +1500,9 @@ nvim_set_client_info({name}, {version}, {type}, {methods}, {attributes}) nvim_set_current_buf({buffer}) *nvim_set_current_buf()* Sets the current buffer. + Attributes: ~ + not allowed when |textlock| is active + Parameters: ~ {buffer} Buffer handle @@ -1501,18 +1515,27 @@ nvim_set_current_dir({dir}) *nvim_set_current_dir()* nvim_set_current_line({line}) *nvim_set_current_line()* Sets the current line. + Attributes: ~ + not allowed when |textlock| is active + Parameters: ~ {line} Line contents nvim_set_current_tabpage({tabpage}) *nvim_set_current_tabpage()* Sets the current tabpage. + Attributes: ~ + not allowed when |textlock| is active + Parameters: ~ {tabpage} Tabpage handle nvim_set_current_win({window}) *nvim_set_current_win()* Sets the current window. + Attributes: ~ + not allowed when |textlock| is active + Parameters: ~ {window} Window handle @@ -1859,6 +1882,9 @@ nvim_buf_del_var({buffer}, {name}) *nvim_buf_del_var()* nvim_buf_delete({buffer}, {opts}) *nvim_buf_delete()* Deletes the buffer. See |:bwipeout| + Attributes: ~ + not allowed when |textlock| is active + Parameters: ~ {buffer} Buffer handle, or 0 for current buffer {opts} Optional parameters. Keys: @@ -2155,6 +2181,9 @@ nvim_buf_set_lines({buffer}, {start}, {end}, {strict_indexing}, {replacement}) Out-of-bounds indices are clamped to the nearest valid value, unless `strict_indexing` is set. + Attributes: ~ + not allowed when |textlock| is active + Parameters: ~ {buffer} Buffer handle, or 0 for current buffer {start} First line index @@ -2232,6 +2261,9 @@ Window Functions *api-window* nvim_win_close({window}, {force}) *nvim_win_close()* Closes the window (like |:close| with a |window-ID|). + Attributes: ~ + not allowed when |textlock| is active + Parameters: ~ {window} Window handle, or 0 for current window {force} Behave like `:close!` The last window of a @@ -2357,6 +2389,9 @@ nvim_win_is_valid({window}) *nvim_win_is_valid()* nvim_win_set_buf({window}, {buffer}) *nvim_win_set_buf()* Sets the current buffer in a window, without side-effects + Attributes: ~ + not allowed when |textlock| is active + Parameters: ~ {window} Window handle, or 0 for current window {buffer} Buffer handle diff --git a/scripts/gen_vimdoc.py b/scripts/gen_vimdoc.py index b1a7f92854..0507e4b7b6 100755 --- a/scripts/gen_vimdoc.py +++ b/scripts/gen_vimdoc.py @@ -186,6 +186,7 @@ param_exclude = ( # Annotations are displayed as line items after API function descriptions. annotation_map = { 'FUNC_API_FAST': '{fast}', + 'FUNC_API_CHECK_TEXTLOCK': 'not allowed when |textlock| is active', } diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 45545d24d9..f1151d196a 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -337,6 +337,7 @@ void nvim_buf_set_lines(uint64_t channel_id, ArrayOf(String) replacement, Error *err) FUNC_API_SINCE(1) + FUNC_API_CHECK_TEXTLOCK { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -787,6 +788,7 @@ Boolean nvim_buf_is_loaded(Buffer buffer) /// - unload: Unloaded only, do not delete. See |:bunload| void nvim_buf_delete(Buffer buffer, Dictionary opts, Error *err) FUNC_API_SINCE(7) + FUNC_API_CHECK_TEXTLOCK { buf_T *buf = find_buffer_by_handle(buffer, err); diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 8b80d4aad9..1e972e01be 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -857,6 +857,7 @@ String nvim_get_current_line(Error *err) /// @param[out] err Error details, if any void nvim_set_current_line(String line, Error *err) FUNC_API_SINCE(1) + FUNC_API_CHECK_TEXTLOCK { buffer_set_line(curbuf->handle, curwin->w_cursor.lnum - 1, line, err); } @@ -866,6 +867,7 @@ void nvim_set_current_line(String line, Error *err) /// @param[out] err Error details, if any void nvim_del_current_line(Error *err) FUNC_API_SINCE(1) + FUNC_API_CHECK_TEXTLOCK { buffer_del_line(curbuf->handle, curwin->w_cursor.lnum - 1, err); } @@ -1060,6 +1062,7 @@ Buffer nvim_get_current_buf(void) /// @param[out] err Error details, if any void nvim_set_current_buf(Buffer buffer, Error *err) FUNC_API_SINCE(1) + FUNC_API_CHECK_TEXTLOCK { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -1114,6 +1117,7 @@ Window nvim_get_current_win(void) /// @param[out] err Error details, if any void nvim_set_current_win(Window window, Error *err) FUNC_API_SINCE(1) + FUNC_API_CHECK_TEXTLOCK { win_T *win = find_window_by_handle(window, err); @@ -1263,6 +1267,7 @@ fail: Window nvim_open_win(Buffer buffer, Boolean enter, Dictionary config, Error *err) FUNC_API_SINCE(6) + FUNC_API_CHECK_TEXTLOCK { FloatConfig fconfig = FLOAT_CONFIG_INIT; if (!parse_float_config(config, &fconfig, false, err)) { @@ -1327,6 +1332,7 @@ Tabpage nvim_get_current_tabpage(void) /// @param[out] err Error details, if any void nvim_set_current_tabpage(Tabpage tabpage, Error *err) FUNC_API_SINCE(1) + FUNC_API_CHECK_TEXTLOCK { tabpage_T *tp = find_tab_by_handle(tabpage, err); @@ -1411,6 +1417,7 @@ Dictionary nvim_get_namespaces(void) /// - false: Client must cancel the paste. Boolean nvim_paste(String data, Boolean crlf, Integer phase, Error *err) FUNC_API_SINCE(6) + FUNC_API_CHECK_TEXTLOCK { static bool draining = false; bool cancel = false; @@ -1483,6 +1490,7 @@ theend: 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); if (!prepare_yankreg_from_object(reg, type, lines.size)) { diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c index a3ec1c8e53..f4af1632ec 100644 --- a/src/nvim/api/window.c +++ b/src/nvim/api/window.c @@ -44,6 +44,7 @@ Buffer nvim_win_get_buf(Window window, Error *err) /// @param[out] err Error details, if any void nvim_win_set_buf(Window window, Buffer buffer, Error *err) FUNC_API_SINCE(5) + FUNC_API_CHECK_TEXTLOCK { win_T *win = find_window_by_handle(window, err), *save_curwin = curwin; buf_T *buf = find_buffer_by_handle(buffer, err); @@ -500,6 +501,7 @@ Dictionary nvim_win_get_config(Window window, Error *err) /// @param[out] err Error details, if any void nvim_win_close(Window window, Boolean force, Error *err) FUNC_API_SINCE(6) + FUNC_API_CHECK_TEXTLOCK { win_T *win = find_window_by_handle(window, err); if (!win) { diff --git a/src/nvim/func_attr.h b/src/nvim/func_attr.h index 38b51b5564..e0b0610646 100644 --- a/src/nvim/func_attr.h +++ b/src/nvim/func_attr.h @@ -213,6 +213,8 @@ # define FUNC_API_REMOTE_ONLY /// API function not exposed in VimL/remote. # define FUNC_API_LUA_ONLY +/// API function checked textlock. +# define FUNC_API_CHECK_TEXTLOCK /// API function introduced at the given API level. # define FUNC_API_SINCE(X) /// API function deprecated since the given API level. diff --git a/src/nvim/generators/c_grammar.lua b/src/nvim/generators/c_grammar.lua index de098b7a7b..c9ab0cf709 100644 --- a/src/nvim/generators/c_grammar.lua +++ b/src/nvim/generators/c_grammar.lua @@ -43,6 +43,7 @@ local c_proto = Ct( (fill * Cg((P('FUNC_API_NOEXPORT') * Cc(true)), 'noexport') ^ -1) * (fill * Cg((P('FUNC_API_REMOTE_ONLY') * Cc(true)), 'remote_only') ^ -1) * (fill * Cg((P('FUNC_API_LUA_ONLY') * Cc(true)), 'lua_only') ^ -1) * + (fill * Cg((P('FUNC_API_CHECK_TEXTLOCK') * Cc(true)), 'check_textlock') ^ -1) * (fill * Cg((P('FUNC_API_REMOTE_IMPL') * Cc(true)), 'remote_impl') ^ -1) * (fill * Cg((P('FUNC_API_BRIDGE_IMPL') * Cc(true)), 'bridge_impl') ^ -1) * (fill * Cg((P('FUNC_API_COMPOSITOR_IMPL') * Cc(true)), 'compositor_impl') ^ -1) * diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index b31209e8ff..7e78b9e9d6 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -260,6 +260,13 @@ for i = 1, #functions do args[#args + 1] = converted end + if fn.check_textlock then + output:write('\n if (textlock != 0) {') + output:write('\n api_set_error(error, kErrorTypeException, "%s", e_secure);') + output:write('\n goto cleanup;') + output:write('\n }\n') + end + -- function call local call_args = table.concat(args, ', ') output:write('\n ') @@ -393,6 +400,16 @@ local function process_function(fn) } ]], fn.name)) end + + if fn.check_textlock then + write_shifted_output(output, [[ + if (textlock != 0) { + api_set_error(&err, kErrorTypeException, "%s", e_secure); + goto exit_0; + } + ]]) + end + local cparams = '' local free_code = {} for j = #fn.parameters,1,-1 do diff --git a/test/functional/eval/api_functions_spec.lua b/test/functional/eval/api_functions_spec.lua index ed110efeb4..7d09a652ba 100644 --- a/test/functional/eval/api_functions_spec.lua +++ b/test/functional/eval/api_functions_spec.lua @@ -47,6 +47,10 @@ describe('eval-API', function() eq('Vim(call):E5555: API call: Invalid buffer id: 17', err) end) + it('cannot change texts if textlocked', function() + command("autocmd TextYankPost <buffer> ++once call nvim_buf_set_lines(0, 0, -1, v:false, [])") + eq('Vim(call):E5555: API call: E523: Not allowed here', pcall_err(command, "normal! yy")) + end) it("use buffer numbers and windows ids as handles", function() local screen = Screen.new(40, 8) |