diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/api/private/helpers.c | 2 | ||||
-rw-r--r-- | src/nvim/decoration.c | 6 | ||||
-rw-r--r-- | src/nvim/ex_cmds.lua | 2 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 47 | ||||
-rw-r--r-- | src/nvim/lua/executor.c | 37 | ||||
-rw-r--r-- | src/nvim/runtime.c | 9 | ||||
-rw-r--r-- | src/nvim/terminal.c | 3 | ||||
-rw-r--r-- | src/nvim/window.c | 2 |
8 files changed, 75 insertions, 33 deletions
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 8f30ac7c8f..9ce1786fa0 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -151,7 +151,7 @@ bool try_end(Error *err) if (should_free) { xfree(msg); } - } else if (did_throw) { + } else if (did_throw || need_rethrow) { if (*current_exception->throw_name != NUL) { if (current_exception->throw_lnum != 0) { api_set_error(err, kErrorTypeException, "%s, line %" PRIdLINENR ": %s", diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c index 8d9b234bbc..755655856d 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -629,9 +629,9 @@ next_mark: } else if (item.data.sh.flags & kSHSpellOff) { spell = kFalse; } - } - if (active && item.data.sh.url != NULL) { - attr = hl_add_url(attr, item.data.sh.url); + if (item.data.sh.url != NULL) { + attr = hl_add_url(attr, item.data.sh.url); + } } if (item.start_row == state->row && item.start_col <= col && decor_virt_pos(&item) && item.draw_col == -10) { diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua index 551d228862..1318eda5eb 100644 --- a/src/nvim/ex_cmds.lua +++ b/src/nvim/ex_cmds.lua @@ -1612,7 +1612,7 @@ module.cmds = { }, { command = 'lua', - flags = bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), + flags = bit.bor(RANGE, EXTRA, CMDWIN, LOCK_OK), addr_type = 'ADDR_LINES', func = 'ex_lua', }, diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 7c3eb47247..12e746d49e 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -309,6 +309,33 @@ static void msg_verbose_cmd(linenr_T lnum, char *cmd) no_wait_return--; } +static int cmdline_call_depth = 0; ///< recursiveness + +/// Start executing an Ex command line. +/// +/// @return FAIL if too recursive, OK otherwise. +static int do_cmdline_start(void) +{ + assert(cmdline_call_depth >= 0); + // It's possible to create an endless loop with ":execute", catch that + // here. The value of 200 allows nested function calls, ":source", etc. + // Allow 200 or 'maxfuncdepth', whatever is larger. + if (cmdline_call_depth >= 200 && cmdline_call_depth >= p_mfd) { + return FAIL; + } + cmdline_call_depth++; + start_batch_changes(); + return OK; +} + +/// End executing an Ex command line. +static void do_cmdline_end(void) +{ + cmdline_call_depth--; + assert(cmdline_call_depth >= 0); + end_batch_changes(); +} + /// Execute a simple command line. Used for translated commands like "*". int do_cmdline_cmd(const char *cmd) { @@ -359,7 +386,6 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) char *(*cmd_getline)(int, void *, int, bool); void *cmd_cookie; struct loop_cookie cmd_loop_cookie; - static int call_depth = 0; // recursiveness // For every pair of do_cmdline()/do_one_cmd() calls, use an extra memory // location for storing error messages to be converted to an exception. @@ -371,10 +397,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) msg_list = &private_msg_list; private_msg_list = NULL; - // It's possible to create an endless loop with ":execute", catch that - // here. The value of 200 allows nested function calls, ":source", etc. - // Allow 200 or 'maxfuncdepth', whatever is larger. - if (call_depth >= 200 && call_depth >= p_mfd) { + if (do_cmdline_start() == FAIL) { emsg(_(e_command_too_recursive)); // When converting to an exception, we do not include the command name // since this is not an error of the specific command. @@ -382,8 +405,6 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) msg_list = saved_msg_list; return FAIL; } - call_depth++; - start_batch_changes(); ga_init(&lines_ga, (int)sizeof(wcmd_T), 10); @@ -884,8 +905,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) did_endif = false; // in case do_cmdline used recursively - call_depth--; - end_batch_changes(); + do_cmdline_end(); return retval; } @@ -1669,9 +1689,13 @@ static int execute_cmd0(int *retv, exarg_T *eap, const char **errormsg, bool pre /// @param preview Execute command preview callback instead of actual command int execute_cmd(exarg_T *eap, CmdParseInfo *cmdinfo, bool preview) { - const char *errormsg = NULL; int retv = 0; + if (do_cmdline_start() == FAIL) { + emsg(_(e_command_too_recursive)); + return retv; + } + const char *errormsg = NULL; #undef ERROR #define ERROR(msg) \ do { \ @@ -1738,9 +1762,12 @@ end: if (errormsg != NULL && *errormsg != NUL) { emsg(errormsg); } + // Undo command modifiers undo_cmdmod(&cmdmod); cmdmod = save_cmdmod; + + do_cmdline_end(); return retv; #undef ERROR } diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index f48cab6739..62e82175c3 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -1641,27 +1641,38 @@ bool nlua_is_deferred_safe(void) return in_fast_callback == 0; } -/// Run lua string +/// Executes Lua code. /// -/// Used for :lua. +/// Implements `:lua` and `:lua ={expr}`. /// -/// @param eap Vimscript command being run. +/// @param eap Vimscript `:lua {code}`, `:{range}lua`, or `:lua ={expr}` command. void ex_lua(exarg_T *const eap) FUNC_ATTR_NONNULL_ALL { + // ":{range}lua" + if (eap->addr_count > 0 || *eap->arg == NUL) { + if (eap->addr_count > 0 && *eap->arg == NUL) { + cmd_source_buffer(eap, true); + } else { + semsg(_(e_invarg2), "exactly one of {chunk} or {range} required"); + } + return; + } + size_t len; char *code = script_get(eap, &len); if (eap->skip || code == NULL) { xfree(code); return; } - // When =expr is used transform it to vim.print(expr) + + // ":lua {code}", ":={expr}" or ":lua ={expr}" + // + // When "=expr" is used transform it to "vim.print(expr)". if (eap->cmdidx == CMD_equal || code[0] == '=') { size_t off = (eap->cmdidx == CMD_equal) ? 0 : 1; len += sizeof("vim.print()") - 1 - off; - // code_buf needs to be 1 char larger then len for null byte in the end. - // lua nlua_typval_exec doesn't expect null terminated string so len - // needs to end before null byte. + // `nlua_typval_exec` doesn't expect NUL-terminated string so `len` must end before NUL byte. char *code_buf = xmallocz(len); vim_snprintf(code_buf, len + 1, "vim.print(%s)", code + off); xfree(code); @@ -1673,11 +1684,11 @@ void ex_lua(exarg_T *const eap) xfree(code); } -/// Run lua string for each line in range +/// Executes Lua code for-each line in a buffer range. /// -/// Used for :luado. +/// Implements `:luado`. /// -/// @param eap Vimscript command being run. +/// @param eap Vimscript `:luado {code}` command. void ex_luado(exarg_T *const eap) FUNC_ATTR_NONNULL_ALL { @@ -1754,11 +1765,11 @@ void ex_luado(exarg_T *const eap) redraw_curbuf_later(UPD_NOT_VALID); } -/// Run lua file +/// Executes Lua code from a file location. /// -/// Used for :luafile. +/// Implements `:luafile`. /// -/// @param eap Vimscript command being run. +/// @param eap Vimscript `:luafile {file}` command. void ex_luafile(exarg_T *const eap) FUNC_ATTR_NONNULL_ALL { diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 3f8e467118..98e9d6c9e6 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -1779,7 +1779,7 @@ freeall: static void cmd_source(char *fname, exarg_T *eap) { if (eap != NULL && *fname == NUL) { - cmd_source_buffer(eap); + cmd_source_buffer(eap, false); } else if (eap != NULL && eap->forceit) { // ":source!": read Normal mode commands // Need to execute the commands directly. This is required at least @@ -1989,7 +1989,7 @@ static int source_using_linegetter(void *cookie, LineGetter fgetline, const char return retval; } -static void cmd_source_buffer(const exarg_T *const eap) +void cmd_source_buffer(const exarg_T *const eap, bool ex_lua) FUNC_ATTR_NONNULL_ALL { if (curbuf == NULL) { @@ -2012,9 +2012,10 @@ static void cmd_source_buffer(const exarg_T *const eap) .buf = ga.ga_data, .offset = 0, }; - if (strequal(curbuf->b_p_ft, "lua") + if (ex_lua || strequal(curbuf->b_p_ft, "lua") || (curbuf->b_fname && path_with_extension(curbuf->b_fname, "lua"))) { - nlua_source_using_linegetter(get_str_line, (void *)&cookie, ":source (no file)"); + char *name = ex_lua ? ":{range}lua" : ":source (no file)"; + nlua_source_using_linegetter(get_str_line, (void *)&cookie, name); } else { source_using_linegetter((void *)&cookie, get_str_line, ":source (no file)"); } diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 00acbfb602..499f31454e 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -93,6 +93,7 @@ #include "nvim/types_defs.h" #include "nvim/ui.h" #include "nvim/vim_defs.h" +#include "nvim/window.h" typedef struct { VimState state; @@ -615,6 +616,8 @@ static int terminal_check(VimState *state) curbuf->b_locked--; } + may_trigger_win_scrolled_resized(); + if (need_maketitle) { // Update title in terminal-mode. #7248 maketitle(); } diff --git a/src/nvim/window.c b/src/nvim/window.c index 66d090b0c8..23779d1e7b 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5367,7 +5367,7 @@ static int check_window_scroll_resize(int *size_count, win_T **first_scroll_win, FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { // Skip floating windows that do not have a snapshot (usually because they are newly-created), - // as unlike split windows, creating floating windows do not cause other windows to resize. + // as unlike split windows, creating floating windows doesn't cause other windows to resize. if (wp->w_floating && wp->w_last_topline == 0) { wp->w_last_topline = wp->w_topline; wp->w_last_topfill = wp->w_topfill; |