diff options
-rw-r--r-- | src/nvim/api/vim.c | 42 | ||||
-rw-r--r-- | src/nvim/eval.c | 4 | ||||
-rw-r--r-- | src/nvim/message.c | 4 | ||||
-rw-r--r-- | src/nvim/message.h | 4 |
4 files changed, 28 insertions, 26 deletions
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 2d1e2bbe94..7f8c10fcd1 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -260,7 +260,7 @@ theend: /// Evaluates a VimL expression (:help expression). /// Dictionaries and Lists are recursively expanded. /// -/// On execution error: fails with generic error; v:errmsg is not updated. +/// On execution error: fails with VimL error, does not update v:errmsg. /// /// @param expr VimL expression string /// @param[out] err Error details, if any @@ -269,7 +269,6 @@ Object nvim_eval(String expr, Error *err) FUNC_API_SINCE(1) { Object rv = OBJECT_INIT; - // Evaluate the expression try_start(); typval_T rettv; @@ -278,11 +277,9 @@ Object nvim_eval(String expr, Error *err) } if (!try_end(err)) { - // No errors, convert the result rv = vim_to_object(&rettv); } - // Free the Vim object tv_clear(&rettv); return rv; @@ -315,7 +312,9 @@ Object nvim_execute_lua(String code, Array args, Error *err) /// @return Result of the function call static Object _call_function(String fn, Array args, dict_T *self, Error *err) { + static int recursive = 0; // recursion depth Object rv = OBJECT_INIT; + if (args.size > MAX_FUNC_ARGS) { api_set_error(err, kErrorTypeValidation, "Function called with too many arguments"); @@ -331,25 +330,36 @@ static Object _call_function(String fn, Array args, dict_T *self, Error *err) } } + // `msg_list` controls the collection of abort-causing non-exception errors, + // which would otherwise be ignored. This pattern is from do_cmdline(). + struct msglist **saved_msg_list = msg_list; + struct msglist *private_msg_list; + msg_list = &private_msg_list; + private_msg_list = NULL; + + // 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(); - msg_first_ignored_err = NULL; - typval_T rettv; int dummy; - int r = 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); - // call_func() retval is deceptive; must also check did_emsg et al. - if (msg_first_ignored_err - && (r == FAIL || (did_emsg && force_abort && !current_exception))) { - api_set_error(err, kErrorTypeException, msg_first_ignored_err); - } + // 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); } - xfree(msg_first_ignored_err); - msg_first_ignored_err = NULL; tv_clear(&rettv); + msg_list = saved_msg_list; // Restore the exception context. + recursive--; free_vim_args: while (i > 0) { diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 3c408a4381..45a1776c86 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -6242,8 +6242,8 @@ bool set_ref_in_func(char_u *name, ufunc_T *fp_in, int copyID) /// new_argcount = argv_func(current_argcount, argv, called_func_argcount) /// /// @return FAIL if function cannot be called, else OK (even if an error -/// occurred while executing the function! Use `msg_first_ignored_err` -/// to get the error) +/// occurred while executing the function! Set `msg_list` to capture +/// the error, see do_cmdline()). int call_func( const char_u *funcname, // name of the function diff --git a/src/nvim/message.c b/src/nvim/message.c index bcfff90d7d..7ca82c2878 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -67,7 +67,6 @@ static char_u *confirm_msg_tail; /* tail of confirm_msg */ MessageHistoryEntry *first_msg_hist = NULL; MessageHistoryEntry *last_msg_hist = NULL; -char *msg_first_ignored_err = NULL; static int msg_hist_len = 0; static FILE *verbose_fd = NULL; @@ -505,9 +504,6 @@ int emsg(const char_u *s_) if (cause_errthrow((char_u *)s, severe, &ignore) == true) { if (!ignore) { did_emsg = true; - if (msg_first_ignored_err == NULL) { - msg_first_ignored_err = xstrdup(s); - } } return true; } diff --git a/src/nvim/message.h b/src/nvim/message.h index eede0ed9b1..82935a36a9 100644 --- a/src/nvim/message.h +++ b/src/nvim/message.h @@ -85,10 +85,6 @@ extern MessageHistoryEntry *first_msg_hist; /// Last message extern MessageHistoryEntry *last_msg_hist; -/// Abort-causing non-exception error ignored by emsg(), needed by callers -/// (RPC API) of call_func() to get error details when messages are disabled. -extern char *msg_first_ignored_err; - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "message.h.generated.h" #endif |