diff options
Diffstat (limited to 'src/nvim/message.c')
-rw-r--r-- | src/nvim/message.c | 652 |
1 files changed, 314 insertions, 338 deletions
diff --git a/src/nvim/message.c b/src/nvim/message.c index 80b5f53f4e..de4acd601f 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -1,57 +1,62 @@ // This is an open source non-commercial project. Dear PVS-Studio, please check // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com -/* - * message.c: functions for displaying messages on the command line - */ +// message.c: functions for displaying messages on the command line #include <assert.h> #include <inttypes.h> #include <stdarg.h> #include <stdbool.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> #include <string.h> #include "nvim/api/private/helpers.h" #include "nvim/ascii.h" -#include "nvim/assert.h" +#include "nvim/buffer_defs.h" +#include "nvim/channel.h" #include "nvim/charset.h" #include "nvim/drawscreen.h" #include "nvim/eval.h" -#include "nvim/ex_docmd.h" +#include "nvim/eval/typval.h" +#include "nvim/eval/typval_defs.h" +#include "nvim/event/defs.h" +#include "nvim/event/loop.h" +#include "nvim/event/multiqueue.h" +#include "nvim/ex_cmds_defs.h" #include "nvim/ex_eval.h" -#include "nvim/ex_getln.h" #include "nvim/fileio.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/getchar.h" +#include "nvim/gettext.h" +#include "nvim/globals.h" #include "nvim/grid.h" #include "nvim/highlight.h" #include "nvim/indent.h" #include "nvim/input.h" #include "nvim/keycodes.h" +#include "nvim/log.h" #include "nvim/main.h" #include "nvim/mbyte.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/mouse.h" -#include "nvim/normal.h" #include "nvim/ops.h" #include "nvim/option.h" #include "nvim/os/input.h" #include "nvim/os/os.h" -#include "nvim/os/time.h" +#include "nvim/pos.h" #include "nvim/regexp.h" #include "nvim/runtime.h" +#include "nvim/screen.h" #include "nvim/strings.h" -#include "nvim/syntax.h" #include "nvim/ui.h" #include "nvim/ui_compositor.h" #include "nvim/vim.h" -/* - * To be able to scroll back at the "more" and "hit-enter" prompts we need to - * store the displayed text and remember where screen lines start. - */ +// To be able to scroll back at the "more" and "hit-enter" prompts we need to +// store the displayed text and remember where screen lines start. typedef struct msgchunk_S msgchunk_T; struct msgchunk_S { msgchunk_T *sb_next; @@ -59,19 +64,21 @@ struct msgchunk_S { char sb_eol; // true when line ends after this text int sb_msg_col; // column in which text starts int sb_attr; // text attributes - char_u sb_text[1]; // text to be displayed, actually longer + char sb_text[1]; // text to be displayed, actually longer }; // Magic chars used in confirm dialog strings -#define DLG_BUTTON_SEP '\n' -#define DLG_HOTKEY_CHAR '&' +enum { + DLG_BUTTON_SEP = '\n', + DLG_HOTKEY_CHAR = '&', +}; static int confirm_msg_used = false; // displaying confirm_msg #ifdef INCLUDE_GENERATED_DECLARATIONS # include "message.c.generated.h" #endif -static char_u *confirm_msg = NULL; // ":confirm" message -static char_u *confirm_msg_tail; // tail of confirm_msg +static char *confirm_msg = NULL; // ":confirm" message +static char *confirm_msg_tail; // tail of confirm_msg MessageHistoryEntry *first_msg_hist = NULL; MessageHistoryEntry *last_msg_hist = NULL; @@ -82,41 +89,39 @@ static int verbose_did_open = false; bool keep_msg_more = false; // keep_msg was set by msgmore() -/* - * When writing messages to the screen, there are many different situations. - * A number of variables is used to remember the current state: - * msg_didany true when messages were written since the last time the - * user reacted to a prompt. - * Reset: After hitting a key for the hit-return prompt, - * hitting <CR> for the command line or input(). - * Set: When any message is written to the screen. - * msg_didout true when something was written to the current line. - * Reset: When advancing to the next line, when the current - * text can be overwritten. - * Set: When any message is written to the screen. - * msg_nowait No extra delay for the last drawn message. - * Used in normal_cmd() before the mode message is drawn. - * emsg_on_display There was an error message recently. Indicates that there - * should be a delay before redrawing. - * msg_scroll The next message should not overwrite the current one. - * msg_scrolled How many lines the screen has been scrolled (because of - * messages). Used in update_screen() to scroll the screen - * back. Incremented each time the screen scrolls a line. - * msg_scrolled_ign true when msg_scrolled is non-zero and msg_puts_attr() - * writes something without scrolling should not make - * need_wait_return to be set. This is a hack to make ":ts" - * work without an extra prompt. - * lines_left Number of lines available for messages before the - * more-prompt is to be given. -1 when not set. - * need_wait_return true when the hit-return prompt is needed. - * Reset: After giving the hit-return prompt, when the user - * has answered some other prompt. - * Set: When the ruler or typeahead display is overwritten, - * scrolling the screen for some message. - * keep_msg Message to be displayed after redrawing the screen, in - * main_loop(). - * This is an allocated string or NULL when not used. - */ +// When writing messages to the screen, there are many different situations. +// A number of variables is used to remember the current state: +// msg_didany true when messages were written since the last time the +// user reacted to a prompt. +// Reset: After hitting a key for the hit-return prompt, +// hitting <CR> for the command line or input(). +// Set: When any message is written to the screen. +// msg_didout true when something was written to the current line. +// Reset: When advancing to the next line, when the current +// text can be overwritten. +// Set: When any message is written to the screen. +// msg_nowait No extra delay for the last drawn message. +// Used in normal_cmd() before the mode message is drawn. +// emsg_on_display There was an error message recently. Indicates that there +// should be a delay before redrawing. +// msg_scroll The next message should not overwrite the current one. +// msg_scrolled How many lines the screen has been scrolled (because of +// messages). Used in update_screen() to scroll the screen +// back. Incremented each time the screen scrolls a line. +// msg_scrolled_ign true when msg_scrolled is non-zero and msg_puts_attr() +// writes something without scrolling should not make +// need_wait_return to be set. This is a hack to make ":ts" +// work without an extra prompt. +// lines_left Number of lines available for messages before the +// more-prompt is to be given. -1 when not set. +// need_wait_return true when the hit-return prompt is needed. +// Reset: After giving the hit-return prompt, when the user +// has answered some other prompt. +// Set: When the ruler or typeahead display is overwritten, +// scrolling the screen for some message. +// keep_msg Message to be displayed after redrawing the screen, in +// main_loop(). +// This is an allocated string or NULL when not used. // Extended msg state, currently used for external UIs with ext_messages static const char *msg_ext_kind = NULL; @@ -134,7 +139,6 @@ static bool msg_ext_history_visible = false; static bool msg_ext_keep_after_cmdline = false; static int msg_grid_pos_at_flush = 0; -static int msg_grid_scroll_discount = 0; static void ui_ext_msg_set_pos(int row, bool scrolled) { @@ -159,8 +163,7 @@ void msg_grid_set_pos(int row, bool scrolled) bool msg_use_grid(void) { - return default_grid.chars && msg_use_msgsep() - && !ui_has(kUIMessages); + return default_grid.chars && !ui_has(kUIMessages); } void msg_grid_validate(void) @@ -178,19 +181,17 @@ void msg_grid_validate(void) xfree(msg_grid.dirty_col); msg_grid.dirty_col = xcalloc((size_t)Rows, sizeof(*msg_grid.dirty_col)); - // Tricky: allow resize while pager is active - int pos = msg_scrolled ? msg_grid_pos : max_rows; + // Tricky: allow resize while pager or ex mode is active + int pos = MAX(max_rows - msg_scrolled, 0); + msg_grid.throttled = false; // don't throttle in 'cmdheight' area + msg_grid_set_pos(pos, msg_scrolled); ui_comp_put_grid(&msg_grid, pos, 0, msg_grid.rows, msg_grid.cols, false, true); ui_call_grid_resize(msg_grid.handle, msg_grid.cols, msg_grid.rows); - msg_grid.throttled = false; // don't throttle in 'cmdheight' area msg_scrolled_at_flush = msg_scrolled; msg_grid.focusable = false; msg_grid_adj.target = &msg_grid; - if (!msg_scrolled) { - msg_grid_set_pos(max_rows, false); - } } else if (!should_alloc && msg_grid.chars) { ui_comp_remove_grid(&msg_grid); grid_free(&msg_grid); @@ -204,7 +205,7 @@ void msg_grid_validate(void) msg_grid_set_pos(max_rows, false); } - if (msg_grid.chars && cmdline_row < msg_grid_pos) { + if (msg_grid.chars && !msg_scrolled && cmdline_row < msg_grid_pos) { // TODO(bfredl): this should already be the case, but fails in some // "batched" executions where compute_cmdrow() use stale positions or // something. @@ -213,7 +214,7 @@ void msg_grid_validate(void) } /// Displays the string 's' on the status line -/// When terminal not initialized (yet) mch_errmsg(..) is used. +/// When terminal not initialized (yet) os_errmsg(..) is used. /// /// @return true if wait_return() not called int msg(char *s) @@ -251,7 +252,7 @@ void msg_multiline_attr(const char *s, int attr, bool check_int, bool *need_clea if (next_spec != NULL) { // Printing all char that are before the char found by strpbrk - msg_outtrans_len_attr((const char_u *)s, (int)(next_spec - s), attr); + msg_outtrans_len_attr(s, (int)(next_spec - s), attr); if (*next_spec != TAB && *need_clear) { msg_clr_eos(); @@ -275,12 +276,12 @@ void msg_multiattr(HlMessage hl_msg, const char *kind, bool history) msg_start(); msg_clr_eos(); bool need_clear = false; + msg_ext_set_kind(kind); for (uint32_t i = 0; i < kv_size(hl_msg); i++) { HlMessageChunk chunk = kv_A(hl_msg, i); msg_multiline_attr((const char *)chunk.text.data, chunk.attr, true, &need_clear); } - msg_ext_set_kind(kind); if (history && kv_size(hl_msg)) { add_msg_hist_multiattr(NULL, 0, 0, true, hl_msg); } @@ -294,7 +295,7 @@ bool msg_attr_keep(const char *s, int attr, bool keep, bool multiline) { static int entered = 0; int retval; - char_u *buf = NULL; + char *buf = NULL; if (keep && multiline) { // Not implemented. 'multiline' is only used by nvim-added messages, @@ -313,11 +314,9 @@ bool msg_attr_keep(const char *s, int attr, bool keep, bool multiline) set_vim_var_string(VV_STATUSMSG, s, -1); } - /* - * It is possible that displaying a messages causes a problem (e.g., - * when redrawing the window), which causes another message, etc.. To - * break this loop, limit the recursiveness to 3 levels. - */ + // It is possible that displaying a messages causes a problem (e.g., + // when redrawing the window), which causes another message, etc.. To + // break this loop, limit the recursiveness to 3 levels. if (entered >= 3) { return true; } @@ -329,15 +328,15 @@ bool msg_attr_keep(const char *s, int attr, bool keep, bool multiline) || (*s != '<' && last_msg_hist != NULL && last_msg_hist->msg != NULL - && STRCMP(s, last_msg_hist->msg))) { + && strcmp(s, last_msg_hist->msg) != 0)) { add_msg_hist(s, -1, attr, multiline); } // Truncate the message if needed. msg_start(); - buf = msg_strtrunc((char_u *)s, false); + buf = msg_strtrunc((char *)s, false); if (buf != NULL) { - s = (const char *)buf; + s = buf; } bool need_clear = true; @@ -367,9 +366,9 @@ bool msg_attr_keep(const char *s, int attr, bool keep, bool multiline) /// @return an allocated string or NULL when no truncating is done. /// /// @param force always truncate -char_u *msg_strtrunc(char_u *s, int force) +char *msg_strtrunc(char *s, int force) { - char_u *buf = NULL; + char *buf = NULL; int len; int room; @@ -377,7 +376,7 @@ char_u *msg_strtrunc(char_u *s, int force) if ((!msg_scroll && !need_wait_return && shortmess(SHM_TRUNCALL) && !exmode_active && msg_silent == 0 && !ui_has(kUIMessages)) || force) { - len = vim_strsize((char *)s); + len = vim_strsize(s); if (msg_scrolled != 0) { // Use all the columns. room = (Rows - msg_row) * Columns - 1; @@ -390,7 +389,7 @@ char_u *msg_strtrunc(char_u *s, int force) // composing chars) len = (room + 2) * 18; buf = xmalloc((size_t)len); - trunc_string((char *)s, (char *)buf, room, len); + trunc_string(s, buf, room, len); } } return buf; @@ -441,10 +440,10 @@ void trunc_string(char *s, char *buf, int room_in, int buflen) } // Last part: End of the string. - half = i = (int)STRLEN(s); + half = i = (int)strlen(s); for (;;) { do { - half = half - utf_head_off((char_u *)s, (char_u *)s + half - 1) - 1; + half = half - utf_head_off(s, s + half - 1) - 1; } while (half > 0 && utf_iscomposing(utf_ptr2char(s + half))); n = ptr2cells(s + half); if (len + n > room || half == 0) { @@ -457,7 +456,7 @@ void trunc_string(char *s, char *buf, int room_in, int buflen) if (i <= e + 3) { // text fits without truncating if (s != buf) { - len = (int)STRLEN(s); + len = (int)strlen(s); if (len >= buflen) { len = buflen - 1; } @@ -471,7 +470,7 @@ void trunc_string(char *s, char *buf, int room_in, int buflen) } else if (e + 3 < buflen) { // set the middle and copy the last part memmove(buf + e, "...", (size_t)3); - len = (int)STRLEN(s + i) + 1; + len = (int)strlen(s + i) + 1; if (len >= buflen - e - 3) { len = buflen - e - 3 - 1; } @@ -483,10 +482,8 @@ void trunc_string(char *s, char *buf, int room_in, int buflen) } } -/* - * Note: Caller of smsg() and smsg_attr() must check the resulting string is - * shorter than IOSIZE!!! - */ +// Note: Caller of smsg() and smsg_attr() must check the resulting string is +// shorter than IOSIZE!!! int smsg(const char *s, ...) FUNC_ATTR_PRINTF(1, 2) @@ -494,10 +491,10 @@ int smsg(const char *s, ...) va_list arglist; va_start(arglist, s); - vim_vsnprintf((char *)IObuff, IOSIZE, s, arglist); + vim_vsnprintf(IObuff, IOSIZE, s, arglist); va_end(arglist); - return msg((char *)IObuff); + return msg(IObuff); } int smsg_attr(int attr, const char *s, ...) @@ -506,7 +503,7 @@ int smsg_attr(int attr, const char *s, ...) va_list arglist; va_start(arglist, s); - vim_vsnprintf((char *)IObuff, IOSIZE, s, arglist); + vim_vsnprintf(IObuff, IOSIZE, s, arglist); va_end(arglist); return msg_attr((const char *)IObuff, attr); } @@ -517,15 +514,13 @@ int smsg_attr_keep(int attr, const char *s, ...) va_list arglist; va_start(arglist, s); - vim_vsnprintf((char *)IObuff, IOSIZE, s, arglist); + vim_vsnprintf(IObuff, IOSIZE, s, arglist); va_end(arglist); return msg_attr_keep((const char *)IObuff, attr, true, false); } -/* - * Remember the last sourcing name/lnum used in an error message, so that it - * isn't printed each time when it didn't change. - */ +// Remember the last sourcing name/lnum used in an error message, so that it +// isn't printed each time when it didn't change. static int last_sourcing_lnum = 0; static char *last_sourcing_name = NULL; @@ -565,7 +560,7 @@ static char *get_emsg_source(void) } const char *const p = _("Error detected while processing %s:"); - const size_t buf_len = STRLEN(sname) + strlen(p) + 1; + const size_t buf_len = strlen(sname) + strlen(p) + 1; char *const buf = xmalloc(buf_len); snprintf(buf, buf_len, p, sname); xfree(tofree); @@ -608,10 +603,10 @@ void msg_source(int attr) } recursive = true; - msg_scroll = true; // this will take more than one line no_wait_return++; char *p = get_emsg_source(); if (p != NULL) { + msg_scroll = true; // this will take more than one line msg_attr(p, attr); xfree(p); } @@ -673,18 +668,23 @@ static bool emsg_multiline(const char *s, bool multiline) // interrupt message). if (cause_errthrow(s, severe, &ignore)) { if (!ignore) { - did_emsg = true; + did_emsg++; } return true; } + if (in_assert_fails && emsg_assert_fails_msg == NULL) { + emsg_assert_fails_msg = xstrdup(s); + emsg_assert_fails_lnum = SOURCING_LNUM; + xfree(emsg_assert_fails_context); + emsg_assert_fails_context = xstrdup(SOURCING_NAME == NULL ? "" : SOURCING_NAME); + } + // set "v:errmsg", also when using ":silent! cmd" set_vim_var_string(VV_ERRMSG, s, -1); - /* - * When using ":silent! cmd" ignore error messages. - * But do write it to the redirection file. - */ + // When using ":silent! cmd" ignore error messages. + // But do write it to the redirection file. if (emsg_silent != 0) { if (!emsg_noredir) { msg_start(); @@ -738,7 +738,7 @@ static bool emsg_multiline(const char *s, bool multiline) } else { flush_buffers(FLUSH_MINIMAL); // flush internal buffers } - did_emsg = true; // flag for DoOneCmd() + did_emsg++; // flag for DoOneCmd() } emsg_on_display = true; // remember there is an error message @@ -753,7 +753,7 @@ static bool emsg_multiline(const char *s, bool multiline) } // Display name and line number for the source of the error. - // Sets "msg_scroll". + msg_scroll = true; msg_source(attr); // Display the error message itself. @@ -764,7 +764,7 @@ static bool emsg_multiline(const char *s, bool multiline) /// 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. +/// When terminal not initialized (yet) os_errmsg(..) is used. /// /// @return true if wait_return() not called bool emsg(const char *s) @@ -881,10 +881,10 @@ void msg_schedule_semsg(const char *const fmt, ...) { va_list ap; va_start(ap, fmt); - vim_vsnprintf((char *)IObuff, IOSIZE, fmt, ap); + vim_vsnprintf(IObuff, IOSIZE, fmt, ap); va_end(ap); - char *s = xstrdup((char *)IObuff); + char *s = xstrdup(IObuff); loop_schedule_deferred(&main_loop, event_create(msg_semsg_event, 1, s)); } @@ -900,7 +900,7 @@ char *msg_trunc_attr(char *s, bool force, int attr) // Add message to history before truncating. add_msg_hist(s, -1, attr, false); - char *ts = (char *)msg_may_trunc(force, (char_u *)s); + char *ts = msg_may_trunc(force, s); msg_hist_off = true; n = msg_attr(ts, attr); @@ -917,14 +917,16 @@ char *msg_trunc_attr(char *s, bool force, int attr) /// @return a pointer to where the truncated message starts. /// /// @note: May change the message by replacing a character with '<'. -char_u *msg_may_trunc(bool force, char_u *s) +char *msg_may_trunc(bool force, char *s) { - int room; + if (ui_has(kUIMessages)) { + return s; + } - room = (Rows - cmdline_row - 1) * Columns + sc_col - 1; + int room = (Rows - cmdline_row - 1) * Columns + sc_col - 1; if ((force || (shortmess(SHM_TRUNC) && !exmode_active)) - && (int)STRLEN(s) - room > 0 && p_ch > 0) { - int size = vim_strsize((char *)s); + && (int)strlen(s) - room > 0) { + int size = vim_strsize(s); // There may be room anyway when there are multibyte chars. if (size <= room) { @@ -932,8 +934,8 @@ char_u *msg_may_trunc(bool force, char_u *s) } int n; for (n = 0; size >= room;) { - size -= utf_ptr2cells((char *)s + n); - n += utfc_ptr2len((char *)s + n); + size -= utf_ptr2cells(s + n); + n += utfc_ptr2len(s + n); } n--; s += n; @@ -950,15 +952,6 @@ void hl_msg_free(HlMessage hl_msg) kv_destroy(hl_msg); } -#define LINE_BUFFER_SIZE 4096 - -void add_hl_msg_hist(HlMessage hl_msg) -{ - if (kv_size(hl_msg)) { - add_msg_hist_multiattr(NULL, 0, 0, true, hl_msg); - } -} - /// @param[in] len Length of s or -1. static void add_msg_hist(const char *s, int len, int attr, bool multiline) { @@ -982,7 +975,7 @@ static void add_msg_hist_multiattr(const char *s, int len, int attr, bool multil struct msg_hist *p = xmalloc(sizeof(struct msg_hist)); if (s) { if (len < 0) { - len = (int)STRLEN(s); + len = (int)strlen(s); } // remove leading and trailing newlines while (len > 0 && *s == '\n') { @@ -992,7 +985,7 @@ static void add_msg_hist_multiattr(const char *s, int len, int attr, bool multil while (len > 0 && s[len - 1] == '\n') { len--; } - p->msg = (char_u *)xmemdupz(s, (size_t)len); + p->msg = xmemdupz(s, (size_t)len); } else { p->msg = NULL; } @@ -1042,7 +1035,7 @@ void ex_messages(void *const eap_p) struct msg_hist *p; int c = 0; - if (STRCMP(eap->arg, "clear") == 0) { + if (strcmp(eap->arg, "clear") == 0) { int keep = eap->addr_count == 0 ? 0 : eap->line2; while (msg_hist_len > keep) { @@ -1109,7 +1102,7 @@ void ex_messages(void *const eap_p) if (kv_size(p->multiattr)) { msg_multiattr(p->multiattr, p->kind, false); } else if (p->msg != NULL) { - msg_attr_keep((char *)p->msg, p->attr, false, p->multiline); + msg_attr_keep(p->msg, p->attr, false, p->multiline); } } msg_hist_off = false; @@ -1156,12 +1149,10 @@ void wait_return(int redraw) return; } - /* - * When inside vgetc(), we can't wait for a typed character at all. - * With the global command (and some others) we only need one return at - * the end. Adjust cmdline_row to avoid the next message overwriting the - * last one. - */ + // When inside vgetc(), we can't wait for a typed character at all. + // With the global command (and some others) we only need one return at + // the end. Adjust cmdline_row to avoid the next message overwriting the + // last one. if (vgetc_busy > 0) { return; } @@ -1184,10 +1175,6 @@ void wait_return(int redraw) c = CAR; // no need for a return in ex mode got_int = false; } else { - // Make sure the hit-return prompt is on screen when 'guioptions' was - // just changed. - screenalloc(); - State = MODE_HITRETURN; setmouse(); cmdline_row = msg_row; @@ -1226,12 +1213,10 @@ void wait_return(int redraw) reg_recording = save_reg_recording; scriptout = save_scriptout; - /* - * Allow scrolling back in the messages. - * Also accept scroll-down commands when messages fill the screen, - * to avoid that typing one 'j' too many makes the messages - * disappear. - */ + // Allow scrolling back in the messages. + // Also accept scroll-down commands when messages fill the screen, + // to avoid that typing one 'j' too many makes the messages + // disappear. if (p_more) { if (c == 'b' || c == 'k' || c == 'u' || c == 'g' || c == K_UP || c == K_PAGEUP) { @@ -1268,9 +1253,7 @@ void wait_return(int redraw) || c == K_MOUSEDOWN || c == K_MOUSEUP || c == K_MOUSEMOVE); os_breakcheck(); - /* - * Avoid that the mouse-up event causes visual mode to start. - */ + // Avoid that the mouse-up event causes visual mode to start. if (c == K_LEFTMOUSE || c == K_MIDDLEMOUSE || c == K_RIGHTMOUSE || c == K_X1MOUSE || c == K_X2MOUSE) { (void)jump_to_mouse(MOUSE_SETPOS, NULL, 0); @@ -1421,22 +1404,25 @@ void msg_start(void) need_fileinfo = false; } - const bool no_msg_area = !ui_has_messages(); - - if (need_clr_eos || (no_msg_area && redrawing_cmdline)) { + if (need_clr_eos || (p_ch == 0 && redrawing_cmdline)) { // Halfway an ":echo" command and getting an (error) message: clear // any text from the command. need_clr_eos = false; msg_clr_eos(); } + // if cmdheight=0, we need to scroll in the first line of msg_grid upon the screen + if (p_ch == 0 && !ui_has(kUIMessages) && !msg_scrolled) { + msg_grid_validate(); + msg_scroll_up(false, true); + msg_scrolled++; + cmdline_row = Rows - 1; + } + if (!msg_scroll && full_screen) { // overwrite last message msg_row = cmdline_row; msg_col = cmdmsg_rl ? Columns - 1 : 0; - if (no_msg_area && get_cmdprompt() == NULL) { - msg_row -= 1; - } - } else if (msg_didout || no_msg_area) { // start message on next line + } else if (msg_didout || (p_ch == 0 && !ui_has(kUIMessages))) { // start message on next line msg_putchar('\n'); did_return = true; cmdline_row = msg_row; @@ -1497,19 +1483,19 @@ void msg_outnum(long n) msg_puts(buf); } -void msg_home_replace(char_u *fname) +void msg_home_replace(char *fname) { msg_home_replace_attr(fname, 0); } -void msg_home_replace_hl(char_u *fname) +void msg_home_replace_hl(char *fname) { msg_home_replace_attr(fname, HL_ATTR(HLF_D)); } -static void msg_home_replace_attr(char_u *fname, int attr) +static void msg_home_replace_attr(char *fname, int attr) { - char *name = home_replace_save(NULL, (char *)fname); + char *name = home_replace_save(NULL, fname); msg_outtrans_attr(name, attr); xfree(name); } @@ -1526,12 +1512,12 @@ int msg_outtrans(char *str) int msg_outtrans_attr(const char *str, int attr) { - return msg_outtrans_len_attr((char_u *)str, (int)STRLEN(str), attr); + return msg_outtrans_len_attr(str, (int)strlen(str), attr); } int msg_outtrans_len(const char *str, int len) { - return msg_outtrans_len_attr((char_u *)str, len, 0); + return msg_outtrans_len_attr(str, len, 0); } /// Output one character at "p". @@ -1543,19 +1529,19 @@ char *msg_outtrans_one(char *p, int attr) int l; if ((l = utfc_ptr2len(p)) > 1) { - msg_outtrans_len_attr((char_u *)p, l, attr); + msg_outtrans_len_attr(p, l, attr); return p + l; } - msg_puts_attr((const char *)transchar_byte(*p), attr); + msg_puts_attr((const char *)transchar_byte((uint8_t)(*p)), attr); return p + 1; } -int msg_outtrans_len_attr(const char_u *msgstr, int len, int attr) +int msg_outtrans_len_attr(const char *msgstr, int len, int attr) { int retval = 0; - const char *str = (const char *)msgstr; - const char *plain_start = (const char *)msgstr; - char_u *s; + const char *str = msgstr; + const char *plain_start = msgstr; + char *s; int mb_l; int c; int save_got_int = got_int; @@ -1575,13 +1561,11 @@ int msg_outtrans_len_attr(const char_u *msgstr, int len, int attr) msg_puts_attr(" ", attr); } - /* - * Go over the string. Special characters are translated and printed. - * Normal characters are printed several at a time. - */ + // Go over the string. Special characters are translated and printed. + // Normal characters are printed several at a time. while (--len >= 0 && !got_int) { // Don't include composing chars after the end. - mb_l = utfc_ptr2len_len((char_u *)str, len + 1); + mb_l = utfc_ptr2len_len(str, len + 1); if (mb_l > 1) { c = utf_ptr2char(str); if (vim_isprintc(c)) { @@ -1601,7 +1585,7 @@ int msg_outtrans_len_attr(const char_u *msgstr, int len, int attr) len -= mb_l - 1; str += mb_l; } else { - s = transchar_byte((uint8_t)(*str)); + s = (char *)transchar_byte((uint8_t)(*str)); if (s[1] != NUL) { // Unprintable char: print the printable chars so far and the // translation of the unprintable char. @@ -1610,7 +1594,7 @@ int msg_outtrans_len_attr(const char_u *msgstr, int len, int attr) } plain_start = str + 1; msg_puts_attr((const char *)s, attr == 0 ? HL_ATTR(HLF_8) : attr); - retval += (int)STRLEN(s); + retval += (int)strlen(s); } else { retval++; } @@ -1663,12 +1647,12 @@ void msg_make(char *arg) /// /// @param from true for LHS of a mapping /// @param maxlen screen columns, 0 for unlimited -int msg_outtrans_special(const char_u *strstart, bool from, int maxlen) +int msg_outtrans_special(const char *strstart, bool from, int maxlen) { if (strstart == NULL) { return 0; // Do nothing. } - const char_u *str = strstart; + const char *str = strstart; int retval = 0; int attr = HL_ATTR(HLF_8); @@ -1679,7 +1663,7 @@ int msg_outtrans_special(const char_u *strstart, bool from, int maxlen) text = "<Space>"; str++; } else { - text = str2special((const char **)&str, from, false); + text = str2special(&str, from, false); } if (text[0] != NUL && text[1] == NUL) { // single-byte character or illegal byte @@ -1703,8 +1687,8 @@ int msg_outtrans_special(const char_u *strstart, bool from, int maxlen) /// Used for lhs or rhs of mappings. /// /// @param[in] str String to convert. -/// @param[in] replace_spaces Convert spaces into `<Space>`, normally used fo -/// lhs, but not rhs. +/// @param[in] replace_spaces Convert spaces into `<Space>`, normally used for +/// lhs of mapping and keytrans(), but not rhs. /// @param[in] replace_lt Convert `<` into `<lt>`. /// /// @return [allocated] Converted string. @@ -1726,8 +1710,8 @@ char *str2special_save(const char *const str, const bool replace_spaces, const b /// Convert character, replacing key with printable representation. /// /// @param[in,out] sp String to convert. Is advanced to the next key code. -/// @param[in] replace_spaces Convert spaces into <Space>, normally used for -/// lhs, but not rhs. +/// @param[in] replace_spaces Convert spaces into `<Space>`, normally used for +/// lhs of mapping and keytrans(), but not rhs. /// @param[in] replace_lt Convert `<` into `<lt>`. /// /// @return Converted key code, in a static buffer. Buffer is always one and the @@ -1818,20 +1802,20 @@ void str2specialbuf(const char *sp, char *buf, size_t len) } /// print line for :print or :list command -void msg_prt_line(char_u *s, int list) +void msg_prt_line(char *s, int list) { int c; int col = 0; int n_extra = 0; int c_extra = 0; int c_final = 0; - char_u *p_extra = NULL; // init to make SASC shut up + char *p_extra = NULL; // init to make SASC shut up int n; int attr = 0; - char_u *lead = NULL; + char *lead = NULL; bool in_multispace = false; int multispace_pos = 0; - char_u *trail = NULL; + char *trail = NULL; int l; if (curwin->w_p_list) { @@ -1841,7 +1825,7 @@ void msg_prt_line(char_u *s, int list) if (list) { // find start of trailing whitespace if (curwin->w_p_lcs_chars.trail) { - trail = s + STRLEN(s); + trail = s + strlen(s); while (trail > s && ascii_iswhite(trail[-1])) { trail--; } @@ -1873,16 +1857,16 @@ void msg_prt_line(char_u *s, int list) c = c_extra; } else { assert(p_extra != NULL); - c = *p_extra++; + c = (unsigned char)(*p_extra++); } - } else if ((l = utfc_ptr2len((char *)s)) > 1) { - col += utf_ptr2cells((char *)s); + } else if ((l = utfc_ptr2len(s)) > 1) { + col += utf_ptr2cells(s); char buf[MB_MAXBYTES + 1]; if (l >= MB_MAXBYTES) { xstrlcpy(buf, "?", sizeof(buf)); } else if (curwin->w_p_lcs_chars.nbsp != NUL && list - && (utf_ptr2char((char *)s) == 160 - || utf_ptr2char((char *)s) == 0x202f)) { + && (utf_ptr2char(s) == 160 + || utf_ptr2char(s) == 0x202f)) { int len = utf_char2bytes(curwin->w_p_lcs_chars.nbsp, buf); buf[len] = NUL; } else { @@ -1894,7 +1878,7 @@ void msg_prt_line(char_u *s, int list) continue; } else { attr = 0; - c = *s++; + c = (unsigned char)(*s++); in_multispace = c == ' ' && ((col > 0 && s[-2] == ' ') || *s == ' '); if (!in_multispace) { multispace_pos = 0; @@ -1920,7 +1904,7 @@ void msg_prt_line(char_u *s, int list) c = curwin->w_p_lcs_chars.nbsp; attr = HL_ATTR(HLF_0); } else if (c == NUL && list && curwin->w_p_lcs_chars.eol != NUL) { - p_extra = (char_u *)""; + p_extra = ""; c_extra = NUL; c_final = NUL; n_extra = 1; @@ -1929,10 +1913,10 @@ void msg_prt_line(char_u *s, int list) s--; } else if (c != NUL && (n = byte2cells(c)) > 1) { n_extra = n - 1; - p_extra = transchar_byte(c); + p_extra = (char *)transchar_byte(c); c_extra = NUL; c_final = NUL; - c = *p_extra++; + c = (unsigned char)(*p_extra++); // Use special coloring to be able to distinguish <hex> from // the same in plain text. attr = HL_ATTR(HLF_0); @@ -2023,12 +2007,12 @@ void msg_puts_title(const char *s) /// Show a message in such a way that it always fits in the line. Cut out a /// part in the middle and replace it with "..." when necessary. /// Does not handle multi-byte characters! -void msg_outtrans_long_attr(char_u *longstr, int attr) +void msg_outtrans_long_attr(char *longstr, int attr) { - msg_outtrans_long_len_attr(longstr, (int)STRLEN(longstr), attr); + msg_outtrans_long_len_attr(longstr, (int)strlen(longstr), attr); } -void msg_outtrans_long_len_attr(char_u *longstr, int len, int attr) +void msg_outtrans_long_len_attr(char *longstr, int len, int attr) { int slen = len; int room; @@ -2084,7 +2068,7 @@ void msg_puts_attr_len(const char *const str, const ptrdiff_t len, int attr) overflow = true; } } else { - overflow = msg_scrolled != 0; + overflow = msg_scrolled > (p_ch == 0 ? 1 : 0); } if (overflow && !msg_scrolled_ign && strcmp(str, "\r") != 0) { @@ -2105,7 +2089,7 @@ void msg_puts_attr_len(const char *const str, const ptrdiff_t len, int attr) } } if (!msg_use_printf() || (headless_mode && default_grid.chars)) { - msg_puts_display((const char_u *)str, (int)len, attr, false); + msg_puts_display(str, (int)len, attr, false); } need_fileinfo = false; @@ -2148,10 +2132,10 @@ static void msg_ext_emit_chunk(void) /// The display part of msg_puts_attr_len(). /// May be called recursively to display scroll-back text. -static void msg_puts_display(const char_u *str, int maxlen, int attr, int recurse) +static void msg_puts_display(const char *str, int maxlen, int attr, int recurse) { - const char_u *s = str; - const char_u *t_s = str; // String from "t_s" to "s" is still todo. + const char *s = str; + const char *t_s = str; // String from "t_s" to "s" is still todo. int t_col = 0; // Screen cells todo, 0 when "t_s" not used. int l; int cw; @@ -2168,7 +2152,7 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr, int recurs msg_ext_last_attr = attr; } // Concat pieces with the same highlight - size_t len = STRNLEN(str, maxlen); // -V781 + size_t len = strnlen(str, (size_t)maxlen); // -V781 ga_concat_len(&msg_ext_last_chunk, (char *)str, len); msg_ext_cur_len += len; return; @@ -2186,19 +2170,19 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr, int recurs && (*s == '\n' || (cmdmsg_rl ? (msg_col <= 1 || (*s == TAB && msg_col <= 7) - || (utf_ptr2cells((char *)s) > 1 + || (utf_ptr2cells(s) > 1 && msg_col <= 2)) : ((*s != '\r' && msg_col + t_col >= Columns - 1) || (*s == TAB && msg_col + t_col >= ((Columns - 1) & ~7)) - || (utf_ptr2cells((char *)s) > 1 + || (utf_ptr2cells(s) > 1 && msg_col + t_col >= Columns - 2))))) { // The screen is scrolled up when at the last row (some terminals // scroll automatically, some don't. To avoid problems we scroll // ourselves). if (t_col > 0) { // output postponed text - t_puts(&t_col, (char *)t_s, (char *)s, attr); + t_puts(&t_col, t_s, s, attr); } // When no more prompt and no more room, truncate here @@ -2207,8 +2191,8 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr, int recurs } // Scroll the screen up one line. - bool has_last_char = (*s >= ' ' && !cmdmsg_rl); - msg_scroll_up(!has_last_char); + bool has_last_char = ((uint8_t)(*s) >= ' ' && !cmdmsg_rl); + msg_scroll_up(!has_last_char, false); msg_row = Rows - 2; if (msg_col >= Columns) { // can happen after screen resize @@ -2221,9 +2205,9 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr, int recurs // Avoid including composing chars after the end. l = utfc_ptr2len_len(s, (int)((str + maxlen) - s)); } else { - l = utfc_ptr2len((char *)s); + l = utfc_ptr2len(s); } - s = (char_u *)screen_puts_mbyte((char *)s, l, attr); + s = screen_puts_mbyte((char *)s, l, attr); did_last_char = true; } else { did_last_char = false; @@ -2250,10 +2234,8 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr, int recurs cmdline_row--; } - /* - * If screen is completely filled and 'more' is set then wait - * for a character. - */ + // If screen is completely filled and 'more' is set then wait + // for a character. if (lines_left > 0) { lines_left--; } @@ -2276,13 +2258,13 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr, int recurs wrap = *s == '\n' || msg_col + t_col >= Columns - || (utf_ptr2cells((char *)s) > 1 + || (utf_ptr2cells(s) > 1 && msg_col + t_col >= Columns - 1) ; if (t_col > 0 && (wrap || *s == '\r' || *s == '\b' || *s == '\t' || *s == BELL)) { // Output any postponed text. - t_puts(&t_col, (char *)t_s, (char *)s, attr); + t_puts(&t_col, t_s, s, attr); } if (wrap && p_more && !recurse) { @@ -2312,20 +2294,20 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr, int recurs } while (msg_col & 7); } else if (*s == BELL) { // beep (from ":sh") vim_beep(BO_SH); - } else if (*s >= 0x20) { // printable char - cw = utf_ptr2cells((char *)s); + } else if ((uint8_t)(*s) >= 0x20) { // printable char + cw = utf_ptr2cells(s); if (maxlen >= 0) { // avoid including composing chars after the end l = utfc_ptr2len_len(s, (int)((str + maxlen) - s)); } else { - l = utfc_ptr2len((char *)s); + l = utfc_ptr2len(s); } // When drawing from right to left or when a double-wide character // doesn't fit, draw a single character here. Otherwise collect // characters and draw them all at once later. if (cmdmsg_rl || (cw > 1 && msg_col + t_col >= Columns - 1)) { if (l > 1) { - s = (char_u *)screen_puts_mbyte((char *)s, l, attr) - 1; + s = screen_puts_mbyte((char *)s, l, attr) - 1; } else { msg_screen_putchar(*s, attr); } @@ -2343,9 +2325,9 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr, int recurs // Output any postponed text. if (t_col > 0) { - t_puts(&t_col, (char *)t_s, (char *)s, attr); + t_puts(&t_col, t_s, s, attr); } - if (p_more && !recurse) { + if (p_more && !recurse && !(s == sb_str + 1 && *sb_str == '\n')) { store_sb_text((char **)&sb_str, (char *)s, attr, &sb_col, false); } @@ -2367,14 +2349,7 @@ bool message_filtered(char *msg) /// including horizontal separator int msg_scrollsize(void) { - return msg_scrolled + (int)p_ch + 1; -} - -bool msg_use_msgsep(void) -{ - // the full-screen scroll behavior doesn't really make sense with - // 'ext_multigrid' - return ((dy_flags & DY_MSGSEP) || ui_has(kUIMultigrid)); + return msg_scrolled + (int)p_ch + ((p_ch > 0 || msg_scrolled > 1) ? 1 : 0); } bool msg_do_throttle(void) @@ -2383,27 +2358,28 @@ bool msg_do_throttle(void) } /// Scroll the screen up one line for displaying the next message line. -void msg_scroll_up(bool may_throttle) +void msg_scroll_up(bool may_throttle, bool zerocmd) { if (may_throttle && msg_do_throttle()) { msg_grid.throttled = true; } msg_did_scroll = true; - if (msg_use_msgsep()) { - if (msg_grid_pos > 0) { - msg_grid_set_pos(msg_grid_pos - 1, true); - } else { - grid_del_lines(&msg_grid, 0, 1, msg_grid.rows, 0, msg_grid.cols); - memmove(msg_grid.dirty_col, msg_grid.dirty_col + 1, - (size_t)(msg_grid.rows - 1) * sizeof(*msg_grid.dirty_col)); - msg_grid.dirty_col[msg_grid.rows - 1] = 0; + if (msg_grid_pos > 0) { + msg_grid_set_pos(msg_grid_pos - 1, !zerocmd); + + // When displaying the first line with cmdheight=0, we need to draw over + // the existing last line of the screen. + if (zerocmd && msg_grid.chars) { + grid_clear_line(&msg_grid, msg_grid.line_offset[0], msg_grid.cols, false); } } else { - grid_del_lines(&msg_grid_adj, 0, 1, Rows, 0, Columns); + grid_del_lines(&msg_grid, 0, 1, msg_grid.rows, 0, msg_grid.cols); + memmove(msg_grid.dirty_col, msg_grid.dirty_col + 1, + (size_t)(msg_grid.rows - 1) * sizeof(*msg_grid.dirty_col)); + msg_grid.dirty_col[msg_grid.rows - 1] = 0; } - grid_fill(&msg_grid_adj, Rows - 1, Rows, 0, Columns, ' ', ' ', - HL_ATTR(HLF_MSG)); + grid_fill(&msg_grid_adj, Rows - 1, Rows, 0, Columns, ' ', ' ', HL_ATTR(HLF_MSG)); } /// Send throttled message output to UI clients @@ -2465,24 +2441,21 @@ void msg_reset_scroll(void) } // TODO(bfredl): some duplicate logic with update_screen(). Later on // we should properly disentangle message clear with full screen redraw. - if (msg_use_grid()) { - msg_grid.throttled = false; - // TODO(bfredl): risk for extra flicker i e with - // "nvim -o has_swap also_has_swap" - msg_grid_set_pos(Rows - (int)p_ch, false); - clear_cmdline = true; - if (msg_grid.chars) { - // non-displayed part of msg_grid is considered invalid. - for (int i = 0; i < MIN(msg_scrollsize(), msg_grid.rows); i++) { - grid_clear_line(&msg_grid, msg_grid.line_offset[i], - msg_grid.cols, false); - } + msg_grid.throttled = false; + // TODO(bfredl): risk for extra flicker i e with + // "nvim -o has_swap also_has_swap" + msg_grid_set_pos(Rows - (int)p_ch, false); + clear_cmdline = true; + if (msg_grid.chars) { + // non-displayed part of msg_grid is considered invalid. + for (int i = 0; i < MIN(msg_scrollsize(), msg_grid.rows); i++) { + grid_clear_line(&msg_grid, msg_grid.line_offset[i], + msg_grid.cols, false); } - } else { - redraw_all_later(UPD_NOT_VALID); } msg_scrolled = 0; msg_scrolled_at_flush = 0; + msg_grid_scroll_discount = 0; } /// Increment "msg_scrolled". @@ -2679,7 +2652,7 @@ void msg_sb_eol(void) static msgchunk_T *disp_sb_line(int row, msgchunk_T *smp) { msgchunk_T *mp = smp; - char_u *p; + char *p; for (;;) { msg_row = row; @@ -2755,9 +2728,9 @@ static void msg_puts_printf(const char *str, const ptrdiff_t maxlen) memcpy(p, s, (size_t)len); *(p + len) = '\0'; if (info_message) { - mch_msg(buf); + os_msg(buf); } else { - mch_errmsg(buf); + os_errmsg(buf); } } @@ -2828,9 +2801,7 @@ static int do_more_prompt(int typed_char) msg_moremsg(false); } for (;;) { - /* - * Get a typed character directly from the user. - */ + // Get a typed character directly from the user. if (used_typed_char != NUL) { c = used_typed_char; // was typed at hit-enter prompt used_typed_char = NUL; @@ -2976,6 +2947,11 @@ static int do_more_prompt(int typed_char) } } else { // First display any text that we scrolled back. + // if p_ch=0 we need to allocate a line for "press enter" messages! + if (cmdline_row >= Rows && !ui_has(kUIMessages)) { + msg_scroll_up(true, false); + msg_scrolled++; + } while (toscroll > 0 && mp_last != NULL) { if (msg_do_throttle() && !msg_grid.throttled) { // Tricky: we redraw at one line higher than usual. Therefore @@ -2984,7 +2960,7 @@ static int do_more_prompt(int typed_char) msg_grid_scroll_discount++; } // scroll up, display line at bottom - msg_scroll_up(true); + msg_scroll_up(true, false); inc_msg_scrolled(); grid_fill(&msg_grid_adj, Rows - 2, Rows - 1, 0, Columns, ' ', ' ', HL_ATTR(HLF_MSG)); @@ -3028,34 +3004,39 @@ static int do_more_prompt(int typed_char) return retval; } -#if defined(WIN32) -void mch_errmsg(char *str) +#if defined(MSWIN) +/// Headless (no UI) error message handler. +static void do_msg(char *str, bool errmsg) { + static bool did_err = false; assert(str != NULL); wchar_t *utf16str; int r = utf8_to_utf16(str, -1, &utf16str); - if (r != 0) { + if (r != 0 && !did_err) { + did_err = true; fprintf(stderr, "utf8_to_utf16 failed: %d", r); - } else { - fwprintf(stderr, L"%ls", utf16str); + ELOG("utf8_to_utf16 failed: %d", r); + } else if (r == 0) { + if (errmsg) { + fwprintf(stderr, L"%ls", utf16str); + } else { + wprintf(L"%ls", utf16str); + } xfree(utf16str); } } -/// Give a message. To be used when the UI is not initialized yet. -void mch_msg(char *str) +void os_errmsg(char *str) { - assert(str != NULL); - wchar_t *utf16str; - int r = utf8_to_utf16(str, -1, &utf16str); - if (r != 0) { - fprintf(stderr, "utf8_to_utf16 failed: %d", r); - } else { - wprintf(L"%ls", utf16str); - xfree(utf16str); - } + do_msg(str, true); } -#endif // WIN32 + +/// Headless (no UI) message handler. +void os_msg(char *str) +{ + do_msg(str, false); +} +#endif // MSWIN /// Put a character on the screen at the current message position and advance /// to the next position. Only for printable ASCII! @@ -3080,13 +3061,13 @@ static void msg_screen_putchar(int c, int attr) void msg_moremsg(int full) { int attr; - char_u *s = (char_u *)_("-- More --"); + char *s = _("-- More --"); attr = hl_combine_attr(HL_ATTR(HLF_MSG), HL_ATTR(HLF_M)); - grid_puts(&msg_grid_adj, (char *)s, Rows - 1, 0, attr); + grid_puts(&msg_grid_adj, s, Rows - 1, 0, attr); if (full) { grid_puts(&msg_grid_adj, _(" SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "), - Rows - 1, vim_strsize((char *)s), attr); + Rows - 1, vim_strsize(s), attr); } } @@ -3120,7 +3101,7 @@ void repeat_message(void) /// Skip this when ":silent" was used, no need to clear for redirection. void msg_clr_eos(void) { - if (msg_silent == 0 && p_ch > 0) { + if (msg_silent == 0) { msg_clr_eos_force(); } } @@ -3142,12 +3123,10 @@ void msg_clr_eos_force(void) msg_row = msg_grid_pos; } - if (ui_has_messages()) { - grid_fill(&msg_grid_adj, msg_row, msg_row + 1, msg_startcol, msg_endcol, - ' ', ' ', HL_ATTR(HLF_MSG)); - grid_fill(&msg_grid_adj, msg_row + 1, Rows, 0, Columns, - ' ', ' ', HL_ATTR(HLF_MSG)); - } + grid_fill(&msg_grid_adj, msg_row, msg_row + 1, msg_startcol, msg_endcol, + ' ', ' ', HL_ATTR(HLF_MSG)); + grid_fill(&msg_grid_adj, msg_row + 1, Rows, 0, Columns, + ' ', ' ', HL_ATTR(HLF_MSG)); redraw_cmdline = true; // overwritten the command line if (msg_row < Rows - 1 || msg_col == (cmdmsg_rl ? Columns : 0)) { @@ -3170,12 +3149,10 @@ void msg_clr_cmdline(void) /// @return true if wait_return() not called. int msg_end(void) { - /* - * If the string is larger than the window, - * or the ruler option is set and we run into it, - * we have to redraw the window. - * Do not do this if we are abandoning the file or editing the command line. - */ + // If the string is larger than the window, + // or the ruler option is set and we run into it, + // we have to redraw the window. + // Do not do this if we are abandoning the file or editing the command line. if (!exiting && need_wait_return && !(State & MODE_CMDLINE)) { wait_return(false); return false; @@ -3192,6 +3169,7 @@ int msg_end(void) void msg_ext_ui_flush(void) { if (!ui_has(kUIMessages)) { + msg_ext_kind = NULL; return; } @@ -3281,7 +3259,7 @@ void msg_check(void) /// @param maxlen if -1, write the whole string, otherwise up to "maxlen" bytes. static void redir_write(const char *const str, const ptrdiff_t maxlen) { - const char_u *s = (char_u *)str; + const char *s = str; static int cur_col = 0; if (maxlen == 0) { @@ -3306,7 +3284,7 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen) ga_concat_len(capture_ga, " ", 1); } if (redir_reg) { - write_reg_contents(redir_reg, (char_u *)" ", 1, true); + write_reg_contents(redir_reg, " ", 1, true); } else if (redir_vname) { var_redir_str(" ", -1); } else if (redir_fd != NULL) { @@ -3319,7 +3297,7 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen) } } - size_t len = maxlen == -1 ? STRLEN(s) : (size_t)maxlen; + size_t len = maxlen == -1 ? strlen(s) : (size_t)maxlen; if (capture_ga) { ga_concat_len(capture_ga, str, len); } @@ -3332,7 +3310,7 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen) // Write and adjust the current column. while (*s != NUL - && (maxlen < 0 || (int)(s - (const char_u *)str) < maxlen)) { + && (maxlen < 0 || (int)(s - str) < maxlen)) { if (!redir_reg && !redir_vname && !capture_ga) { if (redir_fd != NULL) { putc(*s, redir_fd); @@ -3469,10 +3447,10 @@ void give_warning(char *message, bool hl) no_wait_return--; } -void give_warning2(char_u *const message, char_u *const a1, bool hl) +void give_warning2(char *const message, char *const a1, bool hl) { - vim_snprintf((char *)IObuff, IOSIZE, (char *)message, a1); - give_warning((char *)IObuff, hl); + vim_snprintf(IObuff, IOSIZE, message, a1); + give_warning(IObuff, hl); } /// Advance msg cursor to column "col". @@ -3524,11 +3502,11 @@ void msg_advance(int col) /// @param textfiel IObuff for inputdialog(), NULL otherwise /// @param ex_cmd when true pressing : accepts default and starts Ex command /// @returns 0 if cancelled, otherwise the nth button (1-indexed). -int do_dialog(int type, char_u *title, char_u *message, char_u *buttons, int dfltbutton, - char_u *textfield, int ex_cmd) +int do_dialog(int type, char *title, char *message, char *buttons, int dfltbutton, char *textfield, + int ex_cmd) { int retval = 0; - char_u *hotkeys; + char *hotkeys; int c; int i; @@ -3545,10 +3523,8 @@ int do_dialog(int type, char_u *title, char_u *message, char_u *buttons, int dfl State = MODE_CONFIRM; setmouse(); - /* - * Since we wait for a keypress, don't make the - * user press RETURN as well afterwards. - */ + // Since we wait for a keypress, don't make the + // user press RETURN as well afterwards. no_wait_return++; hotkeys = msg_show_console_dialog(message, buttons, dfltbutton); @@ -3578,10 +3554,10 @@ int do_dialog(int type, char_u *title, char_u *message, char_u *buttons, int dfl c = mb_tolower(c); retval = 1; for (i = 0; hotkeys[i]; i++) { - if (utf_ptr2char((char *)hotkeys + i) == c) { + if (utf_ptr2char(hotkeys + i) == c) { break; } - i += utfc_ptr2len((char *)hotkeys + i) - 1; + i += utfc_ptr2len(hotkeys + i) - 1; retval++; } if (hotkeys[i]) { @@ -3608,14 +3584,14 @@ int do_dialog(int type, char_u *title, char_u *message, char_u *buttons, int dfl /// characters. Return the length of the character in bytes. /// /// @param lowercase make character lower case -static int copy_char(const char_u *from, char_u *to, bool lowercase) +static int copy_char(const char *from, char *to, bool lowercase) FUNC_ATTR_NONNULL_ALL { if (lowercase) { - int c = mb_tolower(utf_ptr2char((char *)from)); - return utf_char2bytes(c, (char *)to); + int c = mb_tolower(utf_ptr2char(from)); + return utf_char2bytes(c, to); } - int len = utfc_ptr2len((char *)from); + int len = utfc_ptr2len(from); memmove(to, from, (size_t)len); return len; } @@ -3635,7 +3611,7 @@ static int copy_char(const char_u *from, char_u *to, bool lowercase) /// corresponding button has a hotkey /// /// @return Pointer to memory allocated for storing hotkeys -static char_u *console_dialog_alloc(const char_u *message, char_u *buttons, bool has_hotkey[]) +static char *console_dialog_alloc(const char *message, char *buttons, bool has_hotkey[]) { int lenhotkey = HOTK_LEN; // count first button has_hotkey[0] = false; @@ -3643,7 +3619,7 @@ static char_u *console_dialog_alloc(const char_u *message, char_u *buttons, bool // Compute the size of memory to allocate. int len = 0; int idx = 0; - char_u *r = buttons; + char *r = buttons; while (*r) { if (*r == DLG_BUTTON_SEP) { len += 3; // '\n' -> ', '; 'x' -> '(x)' @@ -3663,9 +3639,9 @@ static char_u *console_dialog_alloc(const char_u *message, char_u *buttons, bool MB_PTR_ADV(r); } - len += (int)(STRLEN(message) + len += (int)(strlen(message) + 2 // for the NL's - + STRLEN(buttons) + + strlen(buttons) + 3); // for the ": " and NUL lenhotkey++; // for the NUL @@ -3689,11 +3665,11 @@ static char_u *console_dialog_alloc(const char_u *message, char_u *buttons, bool /// The hotkeys can be multi-byte characters, but without combining chars. /// /// @return an allocated string with hotkeys. -static char_u *msg_show_console_dialog(char_u *message, char_u *buttons, int dfltbutton) +static char *msg_show_console_dialog(char *message, char *buttons, int dfltbutton) FUNC_ATTR_NONNULL_RET { bool has_hotkey[HAS_HOTKEY_LEN] = { false }; - char_u *hotk = console_dialog_alloc(message, buttons, has_hotkey); + char *hotk = console_dialog_alloc(message, buttons, has_hotkey); copy_hotkeys_and_msg(message, buttons, dfltbutton, has_hotkey, hotk); @@ -3709,13 +3685,13 @@ static char_u *msg_show_console_dialog(char_u *message, char_u *buttons, int dfl /// @param has_hotkey An element in this array is true if corresponding button /// has a hotkey /// @param[out] hotkeys_ptr Pointer to the memory location where hotkeys will be copied -static void copy_hotkeys_and_msg(const char_u *message, char_u *buttons, int default_button_idx, - const bool has_hotkey[], char_u *hotkeys_ptr) +static void copy_hotkeys_and_msg(const char *message, char *buttons, int default_button_idx, + const bool has_hotkey[], char *hotkeys_ptr) { *confirm_msg = '\n'; STRCPY(confirm_msg + 1, message); - char_u *msgp = confirm_msg + 1 + STRLEN(message); + char *msgp = confirm_msg + 1 + strlen(message); // Define first default hotkey. Keep the hotkey string NUL // terminated to avoid reading past the end. @@ -3732,14 +3708,14 @@ static void copy_hotkeys_and_msg(const char_u *message, char_u *buttons, int def } int idx = 0; - char_u *r = buttons; + char *r = buttons; while (*r) { if (*r == DLG_BUTTON_SEP) { *msgp++ = ','; *msgp++ = ' '; // '\n' -> ', ' // Advance to next hotkey and set default hotkey - hotkeys_ptr += STRLEN(hotkeys_ptr); + hotkeys_ptr += strlen(hotkeys_ptr); hotkeys_ptr[copy_char(r + 1, hotkeys_ptr, true)] = NUL; if (default_button_idx) { @@ -3788,28 +3764,28 @@ void display_confirm_msg(void) confirm_msg_used++; if (confirm_msg != NULL) { msg_ext_set_kind("confirm"); - msg_puts_attr((const char *)confirm_msg, HL_ATTR(HLF_M)); + msg_puts_attr(confirm_msg, HL_ATTR(HLF_M)); } confirm_msg_used--; } -int vim_dialog_yesno(int type, char_u *title, char_u *message, int dflt) +int vim_dialog_yesno(int type, char *title, char *message, int dflt) { if (do_dialog(type, - title == NULL ? (char_u *)_("Question") : title, + title == NULL ? _("Question") : title, message, - (char_u *)_("&Yes\n&No"), dflt, NULL, false) == 1) { + _("&Yes\n&No"), dflt, NULL, false) == 1) { return VIM_YES; } return VIM_NO; } -int vim_dialog_yesnocancel(int type, char_u *title, char_u *message, int dflt) +int vim_dialog_yesnocancel(int type, char *title, char *message, int dflt) { switch (do_dialog(type, - title == NULL ? (char_u *)_("Question") : title, + title == NULL ? _("Question") : title, message, - (char_u *)_("&Yes\n&No\n&Cancel"), dflt, NULL, false)) { + _("&Yes\n&No\n&Cancel"), dflt, NULL, false)) { case 1: return VIM_YES; case 2: @@ -3818,12 +3794,12 @@ int vim_dialog_yesnocancel(int type, char_u *title, char_u *message, int dflt) return VIM_CANCEL; } -int vim_dialog_yesnoallcancel(int type, char_u *title, char_u *message, int dflt) +int vim_dialog_yesnoallcancel(int type, char *title, char *message, int dflt) { switch (do_dialog(type, - title == NULL ? (char_u *)"Question" : title, + title == NULL ? "Question" : title, message, - (char_u *)_("&Yes\n&No\nSave &All\n&Discard All\n&Cancel"), + _("&Yes\n&No\nSave &All\n&Discard All\n&Cancel"), dflt, NULL, false)) { case 1: return VIM_YES; |