aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZyX <kp-pav@yandex.ru>2017-06-28 22:09:10 +0300
committerZyX <kp-pav@yandex.ru>2017-06-28 22:09:10 +0300
commit3da49cd68e7d5c968cc99a926819038ff57f488f (patch)
tree1c41cb3f55e184278cbfc465abee90242bc7f3fc
parent9ccb3abbb55ec8ed7f3b4d2d2516fd451eca9a68 (diff)
downloadrneovim-3da49cd68e7d5c968cc99a926819038ff57f488f.tar.gz
rneovim-3da49cd68e7d5c968cc99a926819038ff57f488f.tar.bz2
rneovim-3da49cd68e7d5c968cc99a926819038ff57f488f.zip
ex_getln: Fix “echoerr msg not shown” problem
This also attempted to fix problem with cancelling input() on error by avoiding standard error printing facilities (assumed thrown error message is the problem), but with no luck so far.
-rw-r--r--src/nvim/ex_getln.c52
-rw-r--r--src/nvim/message.c21
-rw-r--r--test/functional/ui/cmdline_highlight_spec.lua11
3 files changed, 61 insertions, 23 deletions
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 9c494a2640..444a3e5b11 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -64,6 +64,7 @@
#include "nvim/os/time.h"
#include "nvim/lib/kvec.h"
#include "nvim/api/private/helpers.h"
+#include "nvim/highlight_defs.h"
/*
* Variables shared between getcmdline(), redrawcmdline() and others.
@@ -2202,6 +2203,13 @@ enum { MAX_CB_ERRORS = 1 };
/// to do.
static bool color_cmdline(void)
{
+ bool printed_errmsg = false;
+#define PRINT_ERRMSG(...) \
+ do { \
+ msg_putchar('\n'); \
+ msg_printf_attr(hl_attr(HLF_E)|MSG_HIST, __VA_ARGS__); \
+ printed_errmsg = true; \
+ } while (0)
bool ret = true;
kv_size(ccline_colors) = 0;
@@ -2274,7 +2282,7 @@ static bool color_cmdline(void)
goto color_cmdline_error;
}
if (tv.v_type != VAR_LIST) {
- emsgf(_("E5400: Callback should return list"));
+ PRINT_ERRMSG(_("E5400: Callback should return list"));
goto color_cmdline_error;
}
if (tv.vval.v_list == NULL) {
@@ -2285,13 +2293,13 @@ static bool color_cmdline(void)
for (const listitem_T *li = tv.vval.v_list->lv_first;
li != NULL; li = li->li_next, i++) {
if (li->li_tv.v_type != VAR_LIST) {
- emsgf(_("E5401: List item %i is not a List"), i);
+ PRINT_ERRMSG(_("E5401: List item %i is not a List"), i);
goto color_cmdline_error;
}
const list_T *const l = li->li_tv.vval.v_list;
if (tv_list_len(l) != 3) {
- emsgf(_("E5402: List item %i has incorrect length: %li /= 3"),
- i, tv_list_len(l));
+ PRINT_ERRMSG(_("E5402: List item %i has incorrect length: %li /= 3"),
+ i, tv_list_len(l));
goto color_cmdline_error;
}
bool error = false;
@@ -2299,13 +2307,13 @@ static bool color_cmdline(void)
if (error) {
goto color_cmdline_error;
} else if (!(prev_end <= start && start < ccline.cmdlen)) {
- emsgf(_("E5403: Chunk %i start %" PRIdVARNUMBER " not in range "
- "[%" PRIdVARNUMBER ", %i)"),
- i, start, prev_end, ccline.cmdlen);
+ PRINT_ERRMSG(_("E5403: Chunk %i start %" PRIdVARNUMBER " not in range "
+ "[%" PRIdVARNUMBER ", %i)"),
+ i, start, prev_end, ccline.cmdlen);
goto color_cmdline_error;
} else if (utf8len_tab_zero[(uint8_t)ccline.cmdbuff[start]] == 0) {
- emsgf(_("E5405: Chunk %i start %" PRIdVARNUMBER " splits multibyte "
- "character"), i, start);
+ PRINT_ERRMSG(_("E5405: Chunk %i start %" PRIdVARNUMBER " splits "
+ "multibyte character"), i, start);
goto color_cmdline_error;
}
if (start != prev_end) {
@@ -2320,14 +2328,14 @@ static bool color_cmdline(void)
if (error) {
goto color_cmdline_error;
} else if (!(start < end && end <= ccline.cmdlen)) {
- emsgf(_("E5404: Chunk %i end %" PRIdVARNUMBER " not in range "
- "(%" PRIdVARNUMBER ", %i]"),
- i, end, start, ccline.cmdlen);
+ PRINT_ERRMSG(_("E5404: Chunk %i end %" PRIdVARNUMBER " not in range "
+ "(%" PRIdVARNUMBER ", %i]"),
+ i, end, start, ccline.cmdlen);
goto color_cmdline_error;
} else if (end < ccline.cmdlen
&& utf8len_tab_zero[(uint8_t)ccline.cmdbuff[end]] == 0) {
- emsgf(_("E5406: Chunk %i end %" PRIdVARNUMBER " splits multibyte "
- "character"), i, end);
+ PRINT_ERRMSG(_("E5406: Chunk %i end %" PRIdVARNUMBER " splits multibyte "
+ "character"), i, end);
goto color_cmdline_error;
}
prev_end = end;
@@ -2364,19 +2372,19 @@ color_cmdline_end:
return ret;
color_cmdline_error:
if (ERROR_SET(&err)) {
- emsgf(_("E5407: Callback has thrown an exception: %s"), err.msg);
+ PRINT_ERRMSG(_("E5407: Callback has thrown an exception: %s"), err.msg);
api_clear_error(&err);
}
+ assert(printed_errmsg);
+
prev_prompt_errors++;
kv_size(ccline_colors) = 0;
- if (did_emsg) {
- did_emsg = false;
- prev_prompt_errors += MAX_CB_ERRORS;
- redrawcmdline();
- prev_prompt_errors -= MAX_CB_ERRORS;
- ret = false;
- }
+ prev_prompt_errors += MAX_CB_ERRORS;
+ redrawcmdline();
+ prev_prompt_errors -= MAX_CB_ERRORS;
+ ret = false;
goto color_cmdline_end;
+#undef PRINT_ERRMSG
}
/*
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 057ce75f79..ab918712e5 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -1611,6 +1611,27 @@ void msg_puts_attr_len(const char *const str, const ptrdiff_t len, int attr)
}
}
+/// Print a formatted message
+///
+/// Message printed is limited by #IOSIZE. Must not be used from inside
+/// msg_puts_attr().
+///
+/// @param[in] attr Highlight attributes.
+/// @param[in] fmt Format string.
+void msg_printf_attr(const int attr, const char *const fmt, ...)
+ FUNC_ATTR_NONNULL_ALL
+{
+ static char msgbuf[IOSIZE];
+
+ va_list ap;
+ va_start(ap, fmt);
+ const size_t len = vim_vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap, NULL);
+ va_end(ap);
+
+ msg_scroll = true;
+ msg_puts_attr_len(msgbuf, (ptrdiff_t)len, attr);
+}
+
/*
* The display part of msg_puts_attr_len().
* May be called recursively to display scroll-back text.
diff --git a/test/functional/ui/cmdline_highlight_spec.lua b/test/functional/ui/cmdline_highlight_spec.lua
index a3dc9af360..dbabf65b68 100644
--- a/test/functional/ui/cmdline_highlight_spec.lua
+++ b/test/functional/ui/cmdline_highlight_spec.lua
@@ -289,7 +289,16 @@ describe('Command-line coloring', function()
it('does the right thing when errorring', function()
set_color_cb('Echoerring')
start_prompt('e')
- -- FIXME Does not work well with :echoerr: error message not shown.
+ screen:expect([[
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ : |
+ {ERR:E5407: Callback has thrown an exception:}|
+ {ERR: Vim(echoerr):HERE} |
+ :e^ |
+ ]])
end)
it('does the right thing when throwing', function()
set_color_cb('Throwing')