ex_getln: Call highlight callback inside :try

This commit is contained in:
ZyX 2017-06-28 14:26:23 +03:00
parent 493d250446
commit 0ed95423de
2 changed files with 26 additions and 20 deletions

View File

@ -63,6 +63,7 @@
#include "nvim/event/loop.h" #include "nvim/event/loop.h"
#include "nvim/os/time.h" #include "nvim/os/time.h"
#include "nvim/lib/kvec.h" #include "nvim/lib/kvec.h"
#include "nvim/api/private/helpers.h"
/* /*
* Variables shared between getcmdline(), redrawcmdline() and others. * Variables shared between getcmdline(), redrawcmdline() and others.
@ -2217,6 +2218,7 @@ static bool color_cmdline(void)
static int prev_prompt_errors = 0; static int prev_prompt_errors = 0;
Callback color_cb = { .type = kCallbackNone }; Callback color_cb = { .type = kCallbackNone };
bool can_free_cb = false; bool can_free_cb = false;
Error err = ERROR_INIT;
if (ccline.input_fn) { if (ccline.input_fn) {
color_cb = getln_input_callback; color_cb = getln_input_callback;
@ -2259,16 +2261,16 @@ static bool color_cmdline(void)
// appears shifted one character to the right and cursor position is no longer // appears shifted one character to the right and cursor position is no longer
// correct, with msg_col it just misses leading `:`. Since `redraw!` in // correct, with msg_col it just misses leading `:`. Since `redraw!` in
// callback lags this is least of the user problems. // callback lags this is least of the user problems.
//
// Also using try_start() because error messages may overwrite typed
// command-line which is not expected.
try_start();
const int saved_msg_col = msg_col; const int saved_msg_col = msg_col;
msg_silent++; msg_silent++;
if (!callback_call(&color_cb, 1, &arg, &tv)) { const bool cbcall_ret = callback_call(&color_cb, 1, &arg, &tv);
msg_silent--;
msg_col = saved_msg_col;
goto color_cmdline_error;
}
msg_silent--; msg_silent--;
msg_col = saved_msg_col; msg_col = saved_msg_col;
if (got_int || did_emsg) { if (try_end(&err) || !cbcall_ret) {
goto color_cmdline_error; goto color_cmdline_error;
} }
if (tv.v_type != VAR_LIST) { if (tv.v_type != VAR_LIST) {
@ -2350,6 +2352,7 @@ static bool color_cmdline(void)
} }
prev_prompt_errors = 0; prev_prompt_errors = 0;
color_cmdline_end: color_cmdline_end:
assert(!ERROR_SET(&err));
if (can_free_cb) { if (can_free_cb) {
callback_free(&color_cb); callback_free(&color_cb);
} }
@ -2360,18 +2363,14 @@ color_cmdline_end:
tv_clear(&tv); tv_clear(&tv);
return ret; return ret;
color_cmdline_error: color_cmdline_error:
if (ERROR_SET(&err)) {
emsgf(_("E5407: Callback has thrown an exception: %s"), err.msg);
api_clear_error(&err);
}
prev_prompt_errors++; prev_prompt_errors++;
const bool do_redraw = (did_emsg || got_int);
got_int = false;
did_emsg = false;
if (did_throw) {
discard_current_exception();
}
if (msg_list != NULL && *msg_list != NULL) {
free_global_msglist();
}
kv_size(ccline_colors) = 0; kv_size(ccline_colors) = 0;
if (do_redraw) { if (did_emsg) {
did_emsg = false;
prev_prompt_errors += MAX_CB_ERRORS; prev_prompt_errors += MAX_CB_ERRORS;
redrawcmdline(); redrawcmdline();
prev_prompt_errors -= MAX_CB_ERRORS; prev_prompt_errors -= MAX_CB_ERRORS;

View File

@ -285,16 +285,23 @@ describe('Command-line coloring', function()
]]) ]])
end) end)
it('does the right thing when errorring', function() it('does the right thing when errorring', function()
if true then return pending('echoerr does not work well now') end
set_color_cb('Echoerring') set_color_cb('Echoerring')
start_prompt('e') start_prompt('e')
-- FIXME Does not work well with :echoerr: error message overwrites cmdline. -- FIXME Does not work well with :echoerr: error message not shown.
end) end)
it('does the right thing when throwing', function() it('does the right thing when throwing', function()
if true then return pending('Throwing does not work well now') end
set_color_cb('Throwing') set_color_cb('Throwing')
start_prompt('e') start_prompt('e')
-- FIXME Does not work well with :throw: error message overwrites cmdline. screen:expect([[
{EOB:~ }|
{EOB:~ }|
{EOB:~ }|
{EOB:~ }|
: |
{ERR:E5407: Callback has thrown an exception:}|
{ERR: ABC} |
:e^ |
]])
end) end)
it('stops executing callback after a number of errors', function() it('stops executing callback after a number of errors', function()
set_color_cb('SplittedMultibyteStart') set_color_cb('SplittedMultibyteStart')