diff options
Diffstat (limited to 'src/nvim/message.c')
-rw-r--r-- | src/nvim/message.c | 282 |
1 files changed, 138 insertions, 144 deletions
diff --git a/src/nvim/message.c b/src/nvim/message.c index 79e6bc8be7..47f33c8967 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -36,6 +36,7 @@ #include "nvim/grid.h" #include "nvim/highlight.h" #include "nvim/highlight_defs.h" +#include "nvim/highlight_group.h" #include "nvim/indent.h" #include "nvim/input.h" #include "nvim/keycodes.h" @@ -73,7 +74,7 @@ struct msgchunk_S { msgchunk_T *sb_prev; char sb_eol; // true when line ends after this text int sb_msg_col; // column in which text starts - int sb_attr; // text attributes + int sb_hl_id; // text highlight id char sb_text[]; // text to be displayed }; @@ -118,7 +119,7 @@ bool keep_msg_more = false; // keep_msg was set by msgmore() // 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() +// msg_scrolled_ign true when msg_scrolled is non-zero and msg_puts_hl_id() // 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. @@ -138,6 +139,7 @@ static const char *msg_ext_kind = NULL; static Array *msg_ext_chunks = NULL; static garray_T msg_ext_last_chunk = GA_INIT(sizeof(char), 40); static sattr_T msg_ext_last_attr = -1; +static int msg_ext_last_hl_id; static size_t msg_ext_cur_len = 0; static bool msg_ext_overwrite = false; ///< will overwrite last message @@ -199,7 +201,7 @@ void msg_grid_validate(void) ui_call_grid_resize(msg_grid.handle, msg_grid.cols, msg_grid.rows); msg_scrolled_at_flush = msg_scrolled; - msg_grid.focusable = false; + msg_grid.mouse_enabled = false; msg_grid_adj.target = &msg_grid; } else if (!should_alloc && msg_grid.chars) { ui_comp_remove_grid(&msg_grid); @@ -231,7 +233,7 @@ void msg_grid_validate(void) int verb_msg(const char *s) { verbose_enter(); - int n = msg_attr_keep(s, 0, false, false); + int n = msg_hl_keep(s, 0, false, false); verbose_leave(); return n; @@ -241,45 +243,43 @@ int verb_msg(const char *s) /// When terminal not initialized (yet) printf("%s", ..) is used. /// /// @return true if wait_return() not called -bool msg(const char *s, const int attr) +bool msg(const char *s, const int hl_id) FUNC_ATTR_NONNULL_ARG(1) { - return msg_attr_keep(s, attr, false, false); + return msg_hl_keep(s, hl_id, false, false); } -/// Similar to msg_outtrans, but support newlines and tabs. -void msg_multiline(const char *s, int attr, bool check_int, bool *need_clear) +/// Similar to msg_outtrans_len, but support newlines and tabs. +void msg_multiline(String str, int hl_id, bool check_int, bool hist, bool *need_clear) FUNC_ATTR_NONNULL_ALL { - const char *next_spec = s; - - while (next_spec != NULL) { + const char *s = str.data; + const char *chunk = s; + while ((size_t)(s - str.data) < str.size) { if (check_int && got_int) { return; } - 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(s, (int)(next_spec - s), attr); + if (*s == '\n' || *s == TAB || *s == '\r') { + // Print all chars before the delimiter + msg_outtrans_len(chunk, (int)(s - chunk), hl_id, hist); - if (*next_spec != TAB && *need_clear) { + if (*s != TAB && *need_clear) { msg_clr_eos(); *need_clear = false; } - msg_putchar_attr((uint8_t)(*next_spec), attr); - s = next_spec + 1; + msg_putchar_hl((uint8_t)(*s), hl_id); + chunk = s + 1; } + s++; } - // Print the rest of the message. We know there is no special - // character because strpbrk returned NULL - if (*s != NUL) { - msg_outtrans(s, attr); + // Print the rest of the message + if (*chunk != NUL) { + msg_outtrans_len(chunk, (int)(str.size - (size_t)(chunk - str.data)), hl_id, hist); } } -void msg_multiattr(HlMessage hl_msg, const char *kind, bool history) +void msg_multihl(HlMessage hl_msg, const char *kind, bool history) { no_wait_return++; msg_start(); @@ -288,17 +288,17 @@ void msg_multiattr(HlMessage hl_msg, const char *kind, bool history) 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(chunk.text.data, chunk.attr, true, &need_clear); + msg_multiline(chunk.text, chunk.hl_id, true, false, &need_clear); } if (history && kv_size(hl_msg)) { - add_msg_hist_multiattr(NULL, 0, 0, true, hl_msg); + add_msg_hist_multihl(NULL, 0, 0, true, hl_msg); } no_wait_return--; msg_end(); } /// @param keep set keep_msg if it doesn't scroll -bool msg_attr_keep(const char *s, int attr, bool keep, bool multiline) +bool msg_hl_keep(const char *s, int hl_id, bool keep, bool multiline) FUNC_ATTR_NONNULL_ALL { static int entered = 0; @@ -316,7 +316,7 @@ bool msg_attr_keep(const char *s, int attr, bool keep, bool multiline) return true; } - if (attr == 0) { + if (hl_id == 0) { set_vim_var_string(VV_STATUSMSG, s, -1); } @@ -335,7 +335,7 @@ bool msg_attr_keep(const char *s, int attr, bool keep, bool multiline) && last_msg_hist != NULL && last_msg_hist->msg != NULL && strcmp(s, last_msg_hist->msg) != 0)) { - add_msg_hist(s, -1, attr, multiline); + add_msg_hist(s, -1, hl_id, multiline); } // Truncate the message if needed. @@ -347,9 +347,9 @@ bool msg_attr_keep(const char *s, int attr, bool keep, bool multiline) bool need_clear = true; if (multiline) { - msg_multiline(s, attr, false, &need_clear); + msg_multiline(cstr_as_string(s), hl_id, false, false, &need_clear); } else { - msg_outtrans(s, attr); + msg_outtrans(s, hl_id, false); } if (need_clear) { msg_clr_eos(); @@ -484,7 +484,7 @@ void trunc_string(const char *s, char *buf, int room_in, int buflen) } } -/// Shows a printf-style message with attributes. +/// Shows a printf-style message with highlight id. /// /// Note: Caller must check the resulting string is shorter than IOSIZE!!! /// @@ -492,7 +492,7 @@ void trunc_string(const char *s, char *buf, int room_in, int buflen) /// @see swmsg /// /// @param s printf-style format message -int smsg(int attr, const char *s, ...) +int smsg(int hl_id, const char *s, ...) FUNC_ATTR_PRINTF(2, 3) { va_list arglist; @@ -500,10 +500,10 @@ int smsg(int attr, const char *s, ...) va_start(arglist, s); vim_vsnprintf(IObuff, IOSIZE, s, arglist); va_end(arglist); - return msg(IObuff, attr); + return msg(IObuff, hl_id); } -int smsg_attr_keep(int attr, const char *s, ...) +int smsg_hl_keep(int hl_id, const char *s, ...) FUNC_ATTR_PRINTF(2, 3) { va_list arglist; @@ -511,7 +511,7 @@ int smsg_attr_keep(int attr, const char *s, ...) va_start(arglist, s); vim_vsnprintf(IObuff, IOSIZE, s, arglist); va_end(arglist); - return msg_attr_keep(IObuff, attr, true, false); + return msg_hl_keep(IObuff, hl_id, true, false); } // Remember the last sourcing name/lnum used in an error message, so that it @@ -588,7 +588,7 @@ static char *get_emsg_lnum(void) /// Display name and line number for the source of an error. /// Remember the file name and line number, so that for the next error the info /// is only displayed if it changed. -void msg_source(int attr) +void msg_source(int hl_id) { static bool recursive = false; @@ -602,12 +602,12 @@ void msg_source(int attr) char *p = get_emsg_source(); if (p != NULL) { msg_scroll = true; // this will take more than one line - msg(p, attr); + msg(p, hl_id); xfree(p); } p = get_emsg_lnum(); if (p != NULL) { - msg(p, HL_ATTR(HLF_N)); + msg(p, HLF_N); xfree(p); last_sourcing_lnum = SOURCING_LNUM; // only once for each line } @@ -736,7 +736,7 @@ bool emsg_multiline(const char *s, bool multiline) } emsg_on_display = true; // remember there is an error message - int attr = HL_ATTR(HLF_E); // set highlight mode for error messages + int hl_id = HLF_E; // set highlight mode for error messages if (msg_scrolled != 0) { need_wait_return = true; // needed in case emsg() is called after } // wait_return() has reset need_wait_return @@ -748,11 +748,11 @@ bool emsg_multiline(const char *s, bool multiline) // Display name and line number for the source of the error. msg_scroll = true; - msg_source(attr); + msg_source(hl_id); // Display the error message itself. msg_nowait = false; // Wait for this msg. - return msg_attr_keep(s, attr, false, multiline); + return msg_hl_keep(s, hl_id, false, multiline); } /// emsg() - display an error message @@ -907,15 +907,15 @@ void msg_schedule_semsg_multiline(const char *const fmt, ...) /// Careful: The string may be changed by msg_may_trunc()! /// /// @return a pointer to the printed message, if wait_return() not called. -char *msg_trunc(char *s, bool force, int attr) +char *msg_trunc(char *s, bool force, int hl_id) { // Add message to history before truncating. - add_msg_hist(s, -1, attr, false); + add_msg_hist(s, -1, hl_id, false); char *ts = msg_may_trunc(force, s); msg_hist_off = true; - bool n = msg(ts, attr); + bool n = msg(ts, hl_id); msg_hist_off = false; if (n) { @@ -965,21 +965,21 @@ void hl_msg_free(HlMessage hl_msg) } /// @param[in] len Length of s or -1. -static void add_msg_hist(const char *s, int len, int attr, bool multiline) +static void add_msg_hist(const char *s, int len, int hl_id, bool multiline) { - add_msg_hist_multiattr(s, len, attr, multiline, (HlMessage)KV_INITIAL_VALUE); + add_msg_hist_multihl(s, len, hl_id, multiline, (HlMessage)KV_INITIAL_VALUE); } -static void add_msg_hist_multiattr(const char *s, int len, int attr, bool multiline, - HlMessage multiattr) +static void add_msg_hist_multihl(const char *s, int len, int hl_id, bool multiline, + HlMessage multihl) { if (msg_hist_off || msg_silent != 0) { - hl_msg_free(multiattr); + hl_msg_free(multihl); return; } // Don't let the message history get too big - while (msg_hist_len > MAX_MSG_HIST_LEN) { + while (msg_hist_len > p_mhi) { delete_first_msg(); } @@ -1002,9 +1002,9 @@ static void add_msg_hist_multiattr(const char *s, int len, int attr, bool multil p->msg = NULL; } p->next = NULL; - p->attr = attr; + p->hl_id = hl_id; p->multiline = multiline; - p->multiattr = multiattr; + p->multihl = multihl; p->kind = msg_ext_kind; if (last_msg_hist != NULL) { last_msg_hist->next = p; @@ -1031,7 +1031,7 @@ int delete_first_msg(void) last_msg_hist = NULL; } xfree(p->msg); - hl_msg_free(p->multiattr); + hl_msg_free(p->multihl); xfree(p); msg_hist_len--; return OK; @@ -1077,22 +1077,24 @@ void ex_messages(exarg_T *eap) } Array entries = ARRAY_DICT_INIT; for (; p != NULL; p = p->next) { - if (kv_size(p->multiattr) || (p->msg && p->msg[0])) { + if (kv_size(p->multihl) || (p->msg && p->msg[0])) { Array entry = ARRAY_DICT_INIT; ADD(entry, CSTR_TO_OBJ(p->kind)); Array content = ARRAY_DICT_INIT; - if (kv_size(p->multiattr)) { - for (uint32_t i = 0; i < kv_size(p->multiattr); i++) { - HlMessageChunk chunk = kv_A(p->multiattr, i); + if (kv_size(p->multihl)) { + for (uint32_t i = 0; i < kv_size(p->multihl); i++) { + HlMessageChunk chunk = kv_A(p->multihl, i); Array content_entry = ARRAY_DICT_INIT; - ADD(content_entry, INTEGER_OBJ(chunk.attr)); + ADD(content_entry, INTEGER_OBJ(chunk.hl_id ? syn_id2attr(chunk.hl_id) : 0)); ADD(content_entry, STRING_OBJ(copy_string(chunk.text, NULL))); + ADD(content_entry, INTEGER_OBJ(chunk.hl_id)); ADD(content, ARRAY_OBJ(content_entry)); } } else if (p->msg && p->msg[0]) { Array content_entry = ARRAY_DICT_INIT; - ADD(content_entry, INTEGER_OBJ(p->attr)); + ADD(content_entry, INTEGER_OBJ(p->hl_id ? syn_id2attr(p->hl_id) : 0)); ADD(content_entry, CSTR_TO_OBJ(p->msg)); + ADD(content_entry, INTEGER_OBJ(p->hl_id)); ADD(content, ARRAY_OBJ(content_entry)); } ADD(entry, ARRAY_OBJ(content)); @@ -1106,10 +1108,10 @@ void ex_messages(exarg_T *eap) } else { msg_hist_off = true; for (; p != NULL && !got_int; p = p->next) { - if (kv_size(p->multiattr)) { - msg_multiattr(p->multiattr, p->kind, false); + if (kv_size(p->multihl)) { + msg_multihl(p->multihl, p->kind, false); } else if (p->msg != NULL) { - msg_attr_keep(p->msg, p->attr, false, p->multiline); + msg_hl_keep(p->msg, p->hl_id, false, p->multiline); } } msg_hist_off = false; @@ -1338,7 +1340,7 @@ static void hit_return_msg(bool newline_sb) msg_puts(_("Interrupt: ")); } - msg_puts_attr(_("Press ENTER or type command to continue"), HL_ATTR(HLF_R)); + msg_puts_hl(_("Press ENTER or type command to continue"), HLF_R, false); if (!msg_use_printf()) { msg_clr_eos(); } @@ -1346,7 +1348,7 @@ static void hit_return_msg(bool newline_sb) } /// Set "keep_msg" to "s". Free the old value and check for NULL pointer. -void set_keep_msg(const char *s, int attr) +void set_keep_msg(const char *s, int hl_id) { xfree(keep_msg); if (s != NULL && msg_silent == 0) { @@ -1355,7 +1357,7 @@ void set_keep_msg(const char *s, int attr) keep_msg = NULL; } keep_msg_more = false; - keep_msg_attr = attr; + keep_msg_hl_id = hl_id; } /// Return true if printing messages should currently be done. @@ -1480,10 +1482,10 @@ void msg_starthere(void) void msg_putchar(int c) { - msg_putchar_attr(c, 0); + msg_putchar_hl(c, 0); } -void msg_putchar_attr(int c, int attr) +void msg_putchar_hl(int c, int hl_id) { char buf[MB_MAXCHAR + 1]; @@ -1495,7 +1497,7 @@ void msg_putchar_attr(int c, int attr) } else { buf[utf_char2bytes(c, buf)] = NUL; } - msg_puts_attr(buf, attr); + msg_puts_hl(buf, hl_id, false); } void msg_outnum(int n) @@ -1508,48 +1510,42 @@ void msg_outnum(int n) void msg_home_replace(const char *fname) { - msg_home_replace_attr(fname, 0); -} - -void msg_home_replace_hl(const char *fname) -{ - msg_home_replace_attr(fname, HL_ATTR(HLF_D)); + msg_home_replace_hl(fname, 0); } -static void msg_home_replace_attr(const char *fname, int attr) +static void msg_home_replace_hl(const char *fname, int hl_id) { char *name = home_replace_save(NULL, fname); - msg_outtrans(name, attr); + msg_outtrans(name, hl_id, false); xfree(name); } -/// Output 'len' characters in 'str' (including NULs) with translation -/// if 'len' is -1, output up to a NUL character. -/// Use attributes 'attr'. +/// Output "len" characters in "str" (including NULs) with translation +/// if "len" is -1, output up to a NUL character. Use highlight "hl_id". /// /// @return the number of characters it takes on the screen. -int msg_outtrans(const char *str, int attr) +int msg_outtrans(const char *str, int hl_id, bool hist) { - return msg_outtrans_len(str, (int)strlen(str), attr); + return msg_outtrans_len(str, (int)strlen(str), hl_id, hist); } /// Output one character at "p". /// Handles multi-byte characters. /// /// @return pointer to the next character. -const char *msg_outtrans_one(const char *p, int attr) +const char *msg_outtrans_one(const char *p, int hl_id, bool hist) { int l; if ((l = utfc_ptr2len(p)) > 1) { - msg_outtrans_len(p, l, attr); + msg_outtrans_len(p, l, hl_id, hist); return p + l; } - msg_puts_attr(transchar_byte_buf(NULL, (uint8_t)(*p)), attr); + msg_puts_hl(transchar_byte_buf(NULL, (uint8_t)(*p)), hl_id, hist); return p + 1; } -int msg_outtrans_len(const char *msgstr, int len, int attr) +int msg_outtrans_len(const char *msgstr, int len, int hl_id, bool hist) { int retval = 0; const char *str = msgstr; @@ -1561,10 +1557,8 @@ int msg_outtrans_len(const char *msgstr, int len, int attr) // Only quit when got_int was set in here. got_int = false; - // if MSG_HIST flag set, add message to history - if (attr & MSG_HIST) { - add_msg_hist(str, len, attr, false); - attr &= ~MSG_HIST; + if (hist) { + add_msg_hist(str, len, hl_id, false); } // When drawing over the command line no need to clear it later or remove @@ -1588,10 +1582,10 @@ int msg_outtrans_len(const char *msgstr, int len, int attr) // Unprintable multi-byte char: print the printable chars so // far and the translation of the unprintable char. if (str > plain_start) { - msg_puts_len(plain_start, str - plain_start, attr); + msg_puts_len(plain_start, str - plain_start, hl_id, hist); } plain_start = str + mb_l; - msg_puts_attr(transchar_buf(NULL, c), attr == 0 ? HL_ATTR(HLF_8) : attr); + msg_puts_hl(transchar_buf(NULL, c), hl_id == 0 ? HLF_8 : hl_id, false); retval += char2cells(c); } len -= mb_l - 1; @@ -1602,10 +1596,10 @@ int msg_outtrans_len(const char *msgstr, int len, int attr) // Unprintable char: print the printable chars so far and the // translation of the unprintable char. if (str > plain_start) { - msg_puts_len(plain_start, str - plain_start, attr); + msg_puts_len(plain_start, str - plain_start, hl_id, hist); } plain_start = str + 1; - msg_puts_attr(s, attr == 0 ? HL_ATTR(HLF_8) : attr); + msg_puts_hl(s, hl_id == 0 ? HLF_8 : hl_id, false); retval += (int)strlen(s); } else { retval++; @@ -1616,7 +1610,7 @@ int msg_outtrans_len(const char *msgstr, int len, int attr) if (str > plain_start && !got_int) { // Print the printable chars at the end. - msg_puts_len(plain_start, str - plain_start, attr); + msg_puts_len(plain_start, str - plain_start, hl_id, hist); } got_int |= save_got_int; @@ -1666,7 +1660,7 @@ int msg_outtrans_special(const char *strstart, bool from, int maxlen) } const char *str = strstart; int retval = 0; - int attr = HL_ATTR(HLF_8); + int hl_id = HLF_8; while (*str != NUL) { const char *text; @@ -1686,9 +1680,7 @@ int msg_outtrans_special(const char *strstart, bool from, int maxlen) break; } // Highlight special keys - msg_puts_attr(text, (len > 1 - && utfc_ptr2len(text) <= 1 - ? attr : 0)); + msg_puts_hl(text, (len > 1 && utfc_ptr2len(text) <= 1 ? hl_id : 0), false); retval += len; } return retval; @@ -1856,7 +1848,7 @@ void msg_prt_line(const char *s, bool list) schar_T sc_final = 0; const char *p_extra = NULL; // init to make SASC shut up. ASCII only! int n; - int attr = 0; + int hl_id = 0; const char *lead = NULL; bool in_multispace = false; int multispace_pos = 0; @@ -1920,7 +1912,7 @@ void msg_prt_line(const char *s, bool list) s += l; continue; } else { - attr = 0; + hl_id = 0; int c = (uint8_t)(*s++); sc_extra = NUL; sc_final = NUL; @@ -1944,13 +1936,13 @@ void msg_prt_line(const char *s, bool list) : curwin->w_p_lcs_chars.tab1; sc_extra = curwin->w_p_lcs_chars.tab2; sc_final = curwin->w_p_lcs_chars.tab3; - attr = HL_ATTR(HLF_0); + hl_id = HLF_0; } } else if (c == NUL && list && curwin->w_p_lcs_chars.eol != NUL) { p_extra = ""; n_extra = 1; sc = curwin->w_p_lcs_chars.eol; - attr = HL_ATTR(HLF_AT); + hl_id = HLF_AT; s--; } else if (c != NUL && (n = byte2cells(c)) > 1) { n_extra = n - 1; @@ -1958,7 +1950,7 @@ void msg_prt_line(const char *s, bool list) sc = schar_from_ascii(*p_extra++); // Use special coloring to be able to distinguish <hex> from // the same in plain text. - attr = HL_ATTR(HLF_0); + hl_id = HLF_0; } else if (c == ' ') { if (lead != NULL && s <= lead && in_multispace && curwin->w_p_lcs_chars.leadmultispace != NULL) { @@ -1966,23 +1958,23 @@ void msg_prt_line(const char *s, bool list) if (curwin->w_p_lcs_chars.leadmultispace[multispace_pos] == NUL) { multispace_pos = 0; } - attr = HL_ATTR(HLF_0); + hl_id = HLF_0; } else if (lead != NULL && s <= lead && curwin->w_p_lcs_chars.lead != NUL) { sc = curwin->w_p_lcs_chars.lead; - attr = HL_ATTR(HLF_0); + hl_id = HLF_0; } else if (trail != NULL && s > trail) { sc = curwin->w_p_lcs_chars.trail; - attr = HL_ATTR(HLF_0); + hl_id = HLF_0; } else if (in_multispace && curwin->w_p_lcs_chars.multispace != NULL) { sc = curwin->w_p_lcs_chars.multispace[multispace_pos++]; if (curwin->w_p_lcs_chars.multispace[multispace_pos] == NUL) { multispace_pos = 0; } - attr = HL_ATTR(HLF_0); + hl_id = HLF_0; } else if (list && curwin->w_p_lcs_chars.space != NUL) { sc = curwin->w_p_lcs_chars.space; - attr = HL_ATTR(HLF_0); + hl_id = HLF_0; } else { sc = schar_from_ascii(' '); // SPACE! } @@ -1998,7 +1990,7 @@ void msg_prt_line(const char *s, bool list) // TODO(bfredl): this is such baloney. need msg_put_schar char buf[MAX_SCHAR_SIZE]; schar_get(buf, sc); - msg_puts_attr(buf, attr); + msg_puts_hl(buf, hl_id, false); col++; } msg_clr_eos(); @@ -2008,42 +2000,42 @@ void msg_prt_line(const char *s, bool list) /// Update msg_row and msg_col for the next message. void msg_puts(const char *s) { - msg_puts_attr(s, 0); + msg_puts_hl(s, 0, false); } void msg_puts_title(const char *s) { - msg_puts_attr(s, HL_ATTR(HLF_T)); + msg_puts_hl(s, HLF_T, false); } /// 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(const char *longstr, int attr) +void msg_outtrans_long(const char *longstr, int hl_id) { int len = (int)strlen(longstr); int slen = len; int room = Columns - msg_col; if (len > room && room >= 20) { slen = (room - 3) / 2; - msg_outtrans_len(longstr, slen, attr); - msg_puts_attr("...", HL_ATTR(HLF_8)); + msg_outtrans_len(longstr, slen, hl_id, false); + msg_puts_hl("...", HLF_8, false); } - msg_outtrans_len(longstr + len - slen, slen, attr); + msg_outtrans_len(longstr + len - slen, slen, hl_id, len); } -/// Basic function for writing a message with highlight attributes. -void msg_puts_attr(const char *const s, const int attr) +/// Basic function for writing a message with highlight id. +void msg_puts_hl(const char *const s, const int hl_id, const bool hist) { - msg_puts_len(s, -1, attr); + msg_puts_len(s, -1, hl_id, hist); } -/// Write a message with highlight attributes +/// Write a message with highlight id. /// /// @param[in] str NUL-terminated message string. /// @param[in] len Length of the string or -1. -/// @param[in] attr Highlight attribute. -void msg_puts_len(const char *const str, const ptrdiff_t len, int attr) +/// @param[in] hl_id Highlight id. +void msg_puts_len(const char *const str, const ptrdiff_t len, int hl_id, bool hist) FUNC_ATTR_NONNULL_ALL { assert(len < 0 || memchr(str, 0, (size_t)len) == NULL); @@ -2055,10 +2047,8 @@ void msg_puts_len(const char *const str, const ptrdiff_t len, int attr) return; } - // if MSG_HIST flag set, add message to history - if (attr & MSG_HIST) { - add_msg_hist(str, (int)len, attr, false); - attr &= ~MSG_HIST; + if (hist) { + add_msg_hist(str, (int)len, hl_id, false); } // When writing something to the screen after it has scrolled, requires a @@ -2095,7 +2085,7 @@ void msg_puts_len(const char *const str, const ptrdiff_t len, int attr) } } if (!msg_use_printf() || (headless_mode && default_grid.chars)) { - msg_puts_display(str, (int)len, attr, false); + msg_puts_display(str, (int)len, hl_id, false); } need_fileinfo = false; @@ -2104,11 +2094,11 @@ void msg_puts_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(). +/// msg_puts_hl_id(). /// -/// @param[in] attr Highlight attributes. +/// @param[in] hl_id Highlight id. /// @param[in] fmt Format string. -void msg_printf_attr(const int attr, const char *const fmt, ...) +void msg_printf_hl(const int hl_id, const char *const fmt, ...) FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_PRINTF(2, 3) { static char msgbuf[IOSIZE]; @@ -2119,7 +2109,7 @@ void msg_printf_attr(const int attr, const char *const fmt, ...) va_end(ap); msg_scroll = true; - msg_puts_len(msgbuf, (ptrdiff_t)len, attr); + msg_puts_len(msgbuf, (ptrdiff_t)len, hl_id, true); } static void msg_ext_emit_chunk(void) @@ -2136,16 +2126,18 @@ static void msg_ext_emit_chunk(void) msg_ext_last_attr = -1; String text = ga_take_string(&msg_ext_last_chunk); ADD(chunk, STRING_OBJ(text)); + ADD(chunk, INTEGER_OBJ(msg_ext_last_hl_id)); ADD(*msg_ext_chunks, ARRAY_OBJ(chunk)); } /// The display part of msg_puts_len(). /// May be called recursively to display scroll-back text. -static void msg_puts_display(const char *str, int maxlen, int attr, int recurse) +static void msg_puts_display(const char *str, int maxlen, int hl_id, int recurse) { const char *s = str; const char *sb_str = str; int sb_col = msg_col; + int attr = hl_id ? syn_id2attr(hl_id) : 0; did_wait_return = false; @@ -2153,6 +2145,7 @@ static void msg_puts_display(const char *str, int maxlen, int attr, int recurse) if (attr != msg_ext_last_attr) { msg_ext_emit_chunk(); msg_ext_last_attr = attr; + msg_ext_last_hl_id = hl_id; } // Concat pieces with the same highlight size_t len = maxlen < 0 ? strlen(str) : strnlen(str, (size_t)maxlen); @@ -2172,7 +2165,7 @@ static void msg_puts_display(const char *str, int maxlen, int attr, int recurse) if (msg_col >= Columns) { if (p_more && !recurse) { // Store text for scrolling back. - store_sb_text(&sb_str, s, attr, &sb_col, true); + store_sb_text(&sb_str, s, hl_id, &sb_col, true); } if (msg_no_more && lines_left == 0) { break; @@ -2262,7 +2255,7 @@ static void msg_puts_display(const char *str, int maxlen, int attr, int recurse) msg_row++; if (p_more && !recurse) { // Store text for scrolling back. - store_sb_text(&sb_str, s, attr, &sb_col, true); + store_sb_text(&sb_str, s, hl_id, &sb_col, true); } } else if (c == '\r') { // go to column 0 msg_col = 0; @@ -2291,7 +2284,7 @@ static void msg_puts_display(const char *str, int maxlen, int attr, int recurse) msg_cursor_goto(msg_row, msg_col); if (p_more && !recurse) { - store_sb_text(&sb_str, s, attr, &sb_col, false); + store_sb_text(&sb_str, s, hl_id, &sb_col, false); } msg_check(); @@ -2481,7 +2474,7 @@ static sb_clear_T do_clear_sb_text = SB_CLEAR_NONE; /// @param sb_str start of string /// @param s just after string /// @param finish line ends -static void store_sb_text(const char **sb_str, const char *s, int attr, int *sb_col, int finish) +static void store_sb_text(const char **sb_str, const char *s, int hl_id, int *sb_col, int finish) { msgchunk_T *mp; @@ -2499,7 +2492,7 @@ static void store_sb_text(const char **sb_str, const char *s, int attr, int *sb_ mp = xmalloc(offsetof(msgchunk_T, sb_text) + (size_t)(s - *sb_str) + 1); mp->sb_eol = (char)finish; mp->sb_msg_col = *sb_col; - mp->sb_attr = attr; + mp->sb_hl_id = hl_id; memcpy(mp->sb_text, *sb_str, (size_t)(s - *sb_str)); mp->sb_text[s - *sb_str] = NUL; @@ -2637,7 +2630,7 @@ static msgchunk_T *disp_sb_line(int row, msgchunk_T *smp) msg_row = row; msg_col = mp->sb_msg_col; char *p = mp->sb_text; - msg_puts_display(p, -1, mp->sb_attr, true); + msg_puts_display(p, -1, mp->sb_hl_id, true); if (mp->sb_eol || mp->sb_next == NULL) { break; } @@ -2694,12 +2687,13 @@ static void msg_puts_printf(const char *str, const ptrdiff_t maxlen) // primitive way to compute the current column if (*s == '\r' || *s == '\n') { msg_col = 0; + msg_didout = false; } else { msg_col += cw; + msg_didout = true; } s += len; } - msg_didout = true; // assume that line is not empty } /// Show the more-prompt and handle the user response. @@ -3321,17 +3315,17 @@ void give_warning(const char *message, bool hl) set_vim_var_string(VV_WARNINGMSG, message, -1); XFREE_CLEAR(keep_msg); if (hl) { - keep_msg_attr = HL_ATTR(HLF_W); + keep_msg_hl_id = HLF_W; } else { - keep_msg_attr = 0; + keep_msg_hl_id = 0; } if (msg_ext_kind == NULL) { msg_ext_set_kind("wmsg"); } - if (msg(message, keep_msg_attr) && msg_scrolled == 0) { - set_keep_msg(message, keep_msg_attr); + if (msg(message, keep_msg_hl_id) && msg_scrolled == 0) { + set_keep_msg(message, keep_msg_hl_id); } msg_didout = false; // Overwrite this message. msg_nowait = true; // Don't wait for this message. @@ -3664,7 +3658,7 @@ void display_confirm_msg(void) confirm_msg_used++; if (confirm_msg != NULL) { msg_ext_set_kind("confirm"); - msg_puts_attr(confirm_msg, HL_ATTR(HLF_M)); + msg_puts_hl(confirm_msg, HLF_M, false); } confirm_msg_used--; } |