diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 17bf29f93c..940bd94603 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -141,6 +141,7 @@ EDITOR EVENTS • |CmdlineLeavePre| triggered before preparing to leave the command line. +• New `append` paremeter for |ui-messages| `msg_show` event. HIGHLIGHTS diff --git a/runtime/doc/ui.txt b/runtime/doc/ui.txt index fe2fbad0cd..a4c440a94c 100644 --- a/runtime/doc/ui.txt +++ b/runtime/doc/ui.txt @@ -810,7 +810,7 @@ will be set to zero, but can be changed and used for the replacing cmdline or message window. Cmdline state is emitted as |ui-cmdline| events, which the UI must handle. -["msg_show", kind, content, replace_last, history] ~ +["msg_show", kind, content, replace_last, history, append] ~ Display a message to the user. kind @@ -860,6 +860,10 @@ must handle. history True if the message was added to the |:messages| history. + append + True if the message should be appeneded to the previous message, + rather than started on a new line. Is set for |:echon|. + ["msg_clear"] ~ Clear all messages currently displayed by "msg_show". (Messages sent by other "msg_" events below will not be affected). diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h index 96489d1903..c859f5f8ee 100644 --- a/src/nvim/api/ui_events.in.h +++ b/src/nvim/api/ui_events.in.h @@ -160,7 +160,7 @@ void wildmenu_select(Integer selected) void wildmenu_hide(void) FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; -void msg_show(String kind, Array content, Boolean replace_last, Boolean history) +void msg_show(String kind, Array content, Boolean replace_last, Boolean history, Boolean append) FUNC_API_SINCE(6) FUNC_API_FAST FUNC_API_REMOTE_ONLY; void msg_clear(void) FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY; diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 2d54fe2ecf..156c56d2ff 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -7863,6 +7863,7 @@ void ex_echo(exarg_T *eap) char *tofree = encode_tv2echo(&rettv, NULL); if (*tofree != NUL) { msg_ext_set_kind("echo"); + msg_ext_append = eap->cmdidx == CMD_echon; msg_multiline(cstr_as_string(tofree), echo_hl_id, true, false, &need_clear); } xfree(tofree); diff --git a/src/nvim/message.c b/src/nvim/message.c index 0f6fc3d192..d8ac0a2a77 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -3185,7 +3185,8 @@ void msg_ext_ui_flush(void) msg_ext_emit_chunk(); if (msg_ext_chunks->size > 0) { Array *tofree = msg_ext_init_chunks(); - ui_call_msg_show(cstr_as_string(msg_ext_kind), *tofree, msg_ext_overwrite, msg_ext_history); + ui_call_msg_show(cstr_as_string(msg_ext_kind), *tofree, msg_ext_overwrite, msg_ext_history, + msg_ext_append); if (msg_ext_history || strequal(msg_ext_kind, "return_prompt")) { api_free_array(*tofree); } else { @@ -3205,6 +3206,7 @@ void msg_ext_ui_flush(void) } msg_ext_overwrite = false; msg_ext_history = false; + msg_ext_append = false; msg_ext_kind = NULL; } } diff --git a/src/nvim/message.h b/src/nvim/message.h index 66340d79b0..c56d66055d 100644 --- a/src/nvim/message.h +++ b/src/nvim/message.h @@ -33,6 +33,8 @@ extern MessageHistoryEntry *msg_hist_last; EXTERN bool msg_ext_need_clear INIT( = false); // Set to true to force grouping a set of message chunks into a single `cmdline_show` event. EXTERN bool msg_ext_skip_flush INIT( = false); +// Set to true when message should be appended to previous message line. +EXTERN bool msg_ext_append INIT( = false); /// allocated grid for messages. Used unless ext_messages is active. /// See also the description at msg_scroll_flush() diff --git a/test/functional/lua/ui_event_spec.lua b/test/functional/lua/ui_event_spec.lua index 86cf705e19..7f1bd328ae 100644 --- a/test/functional/lua/ui_event_spec.lua +++ b/test/functional/lua/ui_event_spec.lua @@ -221,7 +221,6 @@ describe('vim.ui_attach', function() messages = { { content = { { '\nSave changes?\n', 6, 10 } }, - history = false, kind = 'confirm', }, }, @@ -477,7 +476,6 @@ describe('vim.ui_attach', function() }, { content = { { 'Press ENTER or type command to continue', 100, 18 } }, - history = false, kind = 'return_prompt', }, }, @@ -530,7 +528,6 @@ describe('vim.ui_attach', function() }, { content = { { 'Press ENTER or type command to continue', 100, 18 } }, - history = false, kind = 'return_prompt', }, }, diff --git a/test/functional/ui/messages_spec.lua b/test/functional/ui/messages_spec.lua index 9deb306cd4..6c24483c64 100644 --- a/test/functional/ui/messages_spec.lua +++ b/test/functional/ui/messages_spec.lua @@ -60,7 +60,6 @@ describe('ui/ext_messages', function() messages = { { content = { { '\ntest\n', 6, 10 } }, - history = false, kind = 'confirm', }, }, @@ -92,7 +91,6 @@ describe('ui/ext_messages', function() messages = { { content = { { '\ntest\n', 6, 10 } }, - history = false, kind = 'confirm', }, }, @@ -104,17 +102,14 @@ describe('ui/ext_messages', function() messages = { { content = { { '\ntest\n', 6, 10 } }, - history = false, kind = 'confirm', }, { content = { { '1' } }, - history = false, kind = 'echo', }, { content = { { 'Press ENTER or type command to continue', 6, 18 } }, - history = false, kind = 'return_prompt', }, }, @@ -214,7 +209,6 @@ describe('ui/ext_messages', function() messages = { { content = { { '?line ' } }, - history = false, kind = 'search_cmd', }, }, @@ -238,7 +232,6 @@ describe('ui/ext_messages', function() { 'links to', 18, 5 }, { ' SpecialChar' }, }, - history = false, kind = 'list_cmd', }, }, @@ -285,7 +278,6 @@ describe('ui/ext_messages', function() messages = { { content = { { 'The only match' } }, - history = false, kind = 'completion', }, }, @@ -337,12 +329,10 @@ describe('ui/ext_messages', function() { 'guibg=', 18, 5 }, { 'LightBlue' }, }, - history = false, kind = 'list_cmd', }, { content = { { '\n\tLast set from Lua (run Nvim with -V1 for more details)' } }, - history = false, kind = 'verbose', }, { @@ -355,17 +345,14 @@ describe('ui/ext_messages', function() { 'guibg=', 18, 5 }, { 'LightMagenta' }, }, - history = false, kind = 'list_cmd', }, { content = { { '\n\tLast set from Lua (run Nvim with -V1 for more details)' } }, - history = false, kind = 'verbose', }, { content = { { 'Press ENTER or type command to continue', 6, 18 } }, - history = false, kind = 'return_prompt', }, }, @@ -406,7 +393,6 @@ describe('ui/ext_messages', function() }, { content = { { 'Press ENTER or type command to continue', 6, 18 } }, - history = false, kind = 'return_prompt', }, }, @@ -462,27 +448,22 @@ describe('ui/ext_messages', function() messages = { { content = { { (':!%s\r\n[No write since last change]\n'):format(cmd) } }, - history = false, kind = 'shell_cmd', }, { content = { { ('stdout%s\n'):format(t.is_os('win') and '\r' or '') } }, - history = false, kind = 'shell_out', }, { content = { { ('stderr%s\n'):format(t.is_os('win') and '\r' or ''), 9, 71 } }, - history = false, kind = 'shell_err', }, { content = { { '\nshell returned 3\n\n' } }, - history = false, kind = 'shell_ret', }, { content = { { 'Press ENTER or type command to continue', 6, 18 } }, - history = false, kind = 'return_prompt', }, }, @@ -497,7 +478,6 @@ describe('ui/ext_messages', function() messages = { { content = { { '\nType Name Content', 101, 23 }, { '\n c ". ' } }, - history = false, kind = 'list_cmd', }, }, @@ -517,7 +497,6 @@ describe('ui/ext_messages', function() { 'ChanInfo', 101, 23 }, { '\n*foo' }, }, - history = false, kind = 'list_cmd', }, }, @@ -534,7 +513,6 @@ describe('ui/ext_messages', function() messages = { { content = { { 'line 1\nline ' } }, - history = false, kind = 'list_cmd', }, }, @@ -592,7 +570,6 @@ describe('ui/ext_messages', function() }, { content = { { 'Press ENTER or type command to continue', 6, 18 } }, - history = false, kind = 'return_prompt', }, }, @@ -623,7 +600,6 @@ describe('ui/ext_messages', function() }, { content = { { 'Press ENTER or type command to continue', 6, 18 } }, - history = false, kind = 'return_prompt', }, }, @@ -688,7 +664,6 @@ describe('ui/ext_messages', function() messages = { { content = { { 'Press ENTER or type command to continue', 6, 18 } }, - history = false, kind = 'return_prompt', }, }, @@ -731,7 +706,6 @@ describe('ui/ext_messages', function() messages = { { content = { { 'Press ENTER or type command to continue', 6, 18 } }, - history = false, kind = 'return_prompt', }, }, @@ -757,7 +731,7 @@ describe('ui/ext_messages', function() ]], cmdline = { { abort = false } }, messages = { - { content = { { '/line W [1/2]' } }, kind = 'search_count', history = false }, + { content = { { '/line W [1/2]' } }, kind = 'search_count' }, }, } @@ -769,7 +743,7 @@ describe('ui/ext_messages', function() {1:~ }|*3 ]], messages = { - { content = { { '/line [2/2]' } }, kind = 'search_count', history = false }, + { content = { { '/line [2/2]' } }, kind = 'search_count' }, }, } end) @@ -784,11 +758,10 @@ describe('ui/ext_messages', function() ]], cmdline = { { abort = false } }, messages = { - { content = { { 'x #1' } }, kind = 'list_cmd', history = false }, - { content = { { 'y #2' } }, kind = 'list_cmd', history = false }, + { content = { { 'x #1' } }, kind = 'list_cmd' }, + { content = { { 'y #2' } }, kind = 'list_cmd' }, { content = { { 'Press ENTER or type command to continue', 6, 18 } }, - history = false, kind = 'return_prompt', }, }, @@ -908,7 +881,6 @@ describe('ui/ext_messages', function() messages = { { content = { { 'Press ENTER or type command to continue', 6, 18 } }, - history = false, kind = 'return_prompt', }, }, @@ -1156,7 +1128,6 @@ describe('ui/ext_messages', function() messages = { { content = { { 'xyz' } }, - history = false, kind = 'echo', }, }, @@ -1194,7 +1165,6 @@ describe('ui/ext_messages', function() messages = { { content = { { 'Press ENTER or type command to continue', 6, 18 } }, - history = false, kind = 'return_prompt', }, }, @@ -1326,7 +1296,6 @@ stack traceback: { '*', 18, 1 }, { ' k' }, }, - history = false, kind = 'list_cmd', }, }, @@ -1347,7 +1316,6 @@ stack traceback: messages = { { content = { { 'wildmenu wildmode\n' } }, - history = false, kind = 'wildlist', }, }, @@ -1382,7 +1350,6 @@ stack traceback: messages = { { content = { { 'Change "helllo" to:\n 1 "Hello"\n 2 "Hallo"\n 3 "Hullo"' } }, - history = false, kind = 'confirm', }, }, @@ -1405,7 +1372,6 @@ stack traceback: messages = { { content = { { 'Change "helllo" to:\n 1 "Hello"\n 2 "Hallo"\n 3 "Hullo"' } }, - history = false, kind = 'confirm', }, }, @@ -1437,7 +1403,6 @@ stack traceback: messages = { { content = { { 'input0\ninput1' } }, - history = false, kind = 'confirm', }, }, @@ -1487,7 +1452,6 @@ stack traceback: { content = { { '\n 1 %a "[No Name]" line 1' } }, kind = 'list_cmd', - history = false, }, }, } @@ -1502,7 +1466,6 @@ stack traceback: messages = { { content = { { 'Press ENTER or type command to continue', 6, 18 } }, - history = false, kind = 'return_prompt', }, }, @@ -1631,11 +1594,7 @@ stack traceback: {1:~ }|*4 ]], messages = { - { - content = { { 'bar' } }, - history = false, - kind = 'echo', - }, + { content = { { 'bar' } }, kind = 'echo' }, }, }) feed('g') @@ -1647,7 +1606,6 @@ stack traceback: messages = { { content = { { 'Press ENTER or type command to continue', 6, 18 } }, - history = false, kind = 'return_prompt', }, }, @@ -1685,7 +1643,6 @@ stack traceback: messages = { { content = { { 'Press ENTER or type command to continue', 6, 18 } }, - history = false, kind = 'return_prompt', }, }, @@ -1708,7 +1665,6 @@ stack traceback: messages = { { content = { { ' shiftwidth=8\n tabstop=8\n softtabstop=0' } }, - history = false, kind = 'list_cmd', }, }, @@ -1730,6 +1686,25 @@ stack traceback: {1:~ }|*4 ]]) end) + + it(':echon sets append', function() + command('echo "foo" | echon " bar" | echon " baz"') + screen:expect({ + grid = [[ + ^ | + {1:~ }|*4 + ]], + messages = { + { content = { { 'foo' } }, kind = 'echo' }, + { content = { { ' bar' } }, kind = 'echo', append = true }, + { content = { { ' baz' } }, kind = 'echo', append = true }, + { + content = { { 'Press ENTER or type command to continue', 6, 18 } }, + kind = 'return_prompt', + }, + }, + }) + end) end) describe('ui/builtin messages', function() @@ -2394,7 +2369,6 @@ describe('ui/ext_messages', function() messages = { { content = { { 'Press ENTER or type command to continue', 6, 18 } }, - history = false, kind = 'return_prompt', }, }, @@ -2476,7 +2450,7 @@ describe('ui/ext_messages', function() ]], cmdline = { { abort = false } }, messages = { - { content = { { ' cmdheight=0' } }, kind = 'list_cmd', history = false }, + { content = { { ' cmdheight=0' } }, kind = 'list_cmd' }, }, }) @@ -2493,7 +2467,7 @@ describe('ui/ext_messages', function() ]], cmdline = { { abort = false } }, messages = { - { content = { { ' laststatus=3' } }, kind = 'list_cmd', history = false }, + { content = { { ' laststatus=3' } }, kind = 'list_cmd' }, }, }) @@ -2514,7 +2488,7 @@ describe('ui/ext_messages', function() ]], cmdline = { { abort = false } }, messages = { - { content = { { ' cmdheight=0' } }, kind = 'list_cmd', history = false }, + { content = { { ' cmdheight=0' } }, kind = 'list_cmd' }, }, }) end) diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua index bc3b294238..4a16347bb1 100644 --- a/test/functional/ui/screen.lua +++ b/test/functional/ui/screen.lua @@ -1383,12 +1383,12 @@ function Screen:_handle_wildmenu_hide() self.wildmenu_items, self.wildmenu_pos = nil, nil end -function Screen:_handle_msg_show(kind, chunks, replace_last, history) +function Screen:_handle_msg_show(kind, chunks, replace_last, history, append) local pos = #self.messages if not replace_last or pos == 0 then pos = pos + 1 end - self.messages[pos] = { kind = kind, content = chunks, history = history } + self.messages[pos] = { kind = kind, content = chunks, history = history, append = append } end function Screen:_handle_msg_clear() @@ -1507,7 +1507,8 @@ function Screen:_extstate_repr(attr_state) messages[i] = { kind = entry.kind, content = self:_chunks_repr(entry.content, attr_state), - history = entry.history, + history = entry.history or nil, + append = entry.append or nil, } end