diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/lua/executor.c | 2 | ||||
-rw-r--r-- | src/nvim/message.c | 156 |
2 files changed, 130 insertions, 28 deletions
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index a7bda9d037..bc81df4c0b 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -50,7 +50,7 @@ static void nlua_error(lua_State *const lstate, const char *const msg) size_t len; const char *const str = lua_tolstring(lstate, -1, &len); - emsgf(msg, (int)len, str); + emsgf_echo(msg, (int)len, str); lua_pop(lstate, 1); } diff --git a/src/nvim/message.c b/src/nvim/message.c index 37e40c3cc1..7544048434 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -54,6 +54,8 @@ struct msgchunk_S { char_u sb_text[1]; /* text to be displayed, actually longer */ }; +typedef int (*FuncMsgAttr)(const char *s, const int attr); + /* Magic chars used in confirm dialog strings */ #define DLG_BUTTON_SEP '\n' #define DLG_HOTKEY_CHAR '&' @@ -132,31 +134,29 @@ int verb_msg(char_u *s) return n; } -int msg_attr(const char *s, const int attr) FUNC_ATTR_NONNULL_ARG(1) +int msg_attr(const char *s, const int attr) + FUNC_ATTR_NONNULL_ARG(1) { return msg_attr_keep((char_u *)s, attr, false); } -int -msg_attr_keep ( - char_u *s, - int attr, - int keep /* TRUE: set keep_msg if it doesn't scroll */ -) - FUNC_ATTR_NONNULL_ARG(1) +int msg_echo_attr(const char *s, const int attr) + FUNC_ATTR_NONNULL_ALL { - static int entered = 0; - int retval; - char_u *buf = NULL; + return msg_echo_attr_keep(s, attr, false); +} +bool msg_attr_skip(const char *s, const int attr, int *const call) + FUNC_ATTR_NONNULL_ALL +{ // Skip messages not match ":filter pattern". // Don't filter when there is an error. - if (!emsg_on_display && message_filtered(s)) { + if (!emsg_on_display && message_filtered((char_u *)s)) { return true; } if (attr == 0) { - set_vim_var_string(VV_STATUSMSG, (char *) s, -1); + set_vim_var_string(VV_STATUSMSG, s, -1); } /* @@ -164,9 +164,86 @@ msg_attr_keep ( * when redrawing the window), which causes another message, etc.. To * break this loop, limit the recursiveness to 3 levels. */ - if (entered >= 3) - return TRUE; - ++entered; + if (*call >= 3) { + return true; + } + + (*call)++; + + return false; +} + + +bool msg_echo_attr_keep(const char *s, const int attr, const int keep) + FUNC_ATTR_NONNULL_ALL +{ + static int entered = 0; + + if (msg_attr_skip(s, attr, &entered)) { + return true; + } + + msg_start(); + + char *const buf = (char *)msg_strtrunc((char_u *)s, false); + if (buf != NULL) { + s = buf; + } + + const char *next_spec = s; + + while (next_spec != NULL) { + next_spec = strpbrk(s, "\t\n\r"); + + if (next_spec != NULL) { + // Printing all char that are before the char found by strpbrk + msg_outtrans_len_attr((char_u *)s, next_spec - s, attr); + + if (*next_spec != TAB) { + msg_clr_eos(); + } + msg_putchar_attr((uint8_t)(*next_spec), attr); + s = next_spec + 1; + } + } + + // Print the rest of the message. We know there is no special + // character because strpbrk returned NULL + if (*s != NUL) { + msg_outtrans_attr((char_u *)s, attr); + } + + msg_clr_eos(); + const bool retval = msg_end(); + + if (keep && retval && vim_strsize((char_u *)s) < (int)(Rows - cmdline_row -1) + * Columns + sc_col) { + set_keep_msg((char_u *)s, 0); + } + + xfree((void *)buf); + entered--; + return retval; +} + + +int +msg_attr_keep ( + char_u *s, + int attr, + int keep /* TRUE: set keep_msg if it doesn't scroll */ +) + FUNC_ATTR_NONNULL_ARG(1) +{ + static int entered = 0; + + if (msg_attr_skip((const char *)s, attr, &entered)) { + return true; + } + + int retval; + char_u *buf = NULL; + /* Add message to history (unless it's a repeated kept message or a * truncated message) */ @@ -468,17 +545,8 @@ int emsg_not_now(void) return FALSE; } -/* - * emsg() - display an error message - * - * Rings the bell, if appropriate, and calls message() to do the real work - * When terminal not initialized (yet) mch_errmsg(..) is used. - * - * return TRUE if wait_return not called - */ -int emsg(const char_u *s_) +static int _emsg(const char *s, FuncMsgAttr display_msg) { - const char *s = (const char *)s_; int attr; int ignore = false; int severe; @@ -573,7 +641,20 @@ int emsg(const char_u *s_) // Display the error message itself. msg_nowait = false; // Wait for this msg. - return msg_attr(s, attr); + return display_msg(s, attr); +} + +/* + * emsg() - display an error message + * + * Rings the bell, if appropriate, and calls message() to do the real work + * When terminal not initialized (yet) mch_errmsg(..) is used. + * + * return TRUE if wait_return not called + */ +int emsg(const char_u *s) +{ + return _emsg((const char *)s, &msg_attr); } void emsg_invreg(int name) @@ -595,6 +676,27 @@ bool emsgf(const char *const fmt, ...) return ret; } +bool emsgf_echo(const char *const fmt, ...) +{ + bool ret; + va_list ap; + + va_start(ap, fmt); + + static char errbuf[IOSIZE]; + if (emsg_not_now()) { + return true; + } + + vim_vsnprintf(errbuf, sizeof(errbuf), fmt, ap, NULL); + + FuncMsgAttr f = &msg_echo_attr; + ret = _emsg(errbuf, f); + va_end(ap); + + return ret; +} + /// Print an error message with unknown number of arguments static bool emsgfv(const char *fmt, va_list ap) { |