diff options
author | Luuk van Baal <luukvbaal@gmail.com> | 2025-01-14 12:05:23 +0100 |
---|---|---|
committer | Luuk van Baal <luukvbaal@gmail.com> | 2025-01-15 10:51:52 +0100 |
commit | 5bae80899d9d29d80c129ca92cde75a1583b5efe (patch) | |
tree | c30d604cf4a84d2e5998297596a6ee4e9b0e62b6 | |
parent | c5f93d7ab04f93db1470d58ca1f70e947e716c2b (diff) | |
download | rneovim-5bae80899d9d29d80c129ca92cde75a1583b5efe.tar.gz rneovim-5bae80899d9d29d80c129ca92cde75a1583b5efe.tar.bz2 rneovim-5bae80899d9d29d80c129ca92cde75a1583b5efe.zip |
feat(messages): add :!cmd shell message kinds
Also print stderr error messages with ErrorMsg highlight group.
-rw-r--r-- | runtime/doc/news.txt | 2 | ||||
-rw-r--r-- | runtime/doc/ui.txt | 3 | ||||
-rw-r--r-- | src/nvim/event/proc.h | 4 | ||||
-rw-r--r-- | src/nvim/os/shell.c | 12 | ||||
-rw-r--r-- | test/functional/ui/messages_spec.lua | 38 |
5 files changed, 51 insertions, 8 deletions
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 89504ae244..e12c307b5f 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -96,7 +96,7 @@ EVENTS • `msg_show`: • `history` argument indicating if the message was added to the history. • new message kinds: "bufwrite", "completion", "list_cmd", "lua_print", - "search_cmd", "undo", "verbose", wildlist". + "search_cmd", "shell_out/err/ret", "undo", "verbose", wildlist". HIGHLIGHTS diff --git a/runtime/doc/ui.txt b/runtime/doc/ui.txt index 26ea03d2be..4d212e2779 100644 --- a/runtime/doc/ui.txt +++ b/runtime/doc/ui.txt @@ -805,6 +805,9 @@ must handle. "quickfix" Quickfix navigation message "search_cmd" Entered search command "search_count" Search count message ("S" flag of 'shortmess') + "shell_err" |:!cmd| shell stderr output + "shell_out" |:!cmd| shell stdout output + "shell_ret" |:!cmd| shell return code "undo" |:undo| and |:redo| message "verbose" 'verbose' message "wildlist" 'wildmode' "list" message diff --git a/src/nvim/event/proc.h b/src/nvim/event/proc.h index f525d46f87..fb14041049 100644 --- a/src/nvim/event/proc.h +++ b/src/nvim/event/proc.h @@ -21,8 +21,8 @@ static inline Proc proc_init(Loop *loop, ProcType type, void *data) .argv = NULL, .exepath = NULL, .in = { .closed = false }, - .out = { .s.closed = false }, - .err = { .s.closed = false }, + .out = { .s.closed = false, .s.fd = STDOUT_FILENO }, + .err = { .s.closed = false, .s.fd = STDERR_FILENO }, .cb = NULL, .closed = false, .internal_close_cb = NULL, diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index 81b75dc4d3..5347c8db9a 100644 --- a/src/nvim/os/shell.c +++ b/src/nvim/os/shell.c @@ -700,6 +700,7 @@ int os_call_shell(char *cmd, int opts, char *extra_args) } if (!emsg_silent && exitcode != 0 && !(opts & kShellOptSilent)) { + msg_ext_set_kind("shell_ret"); msg_puts(_("\nshell returned ")); msg_outnum(exitcode); msg_putchar('\n'); @@ -1067,7 +1068,7 @@ static void out_data_ring(const char *output, size_t size) } if (output == NULL && size == SIZE_MAX) { // Print mode - out_data_append_to_screen(last_skipped, &last_skipped_len, true); + out_data_append_to_screen(last_skipped, &last_skipped_len, STDOUT_FILENO, true); return; } @@ -1095,14 +1096,15 @@ static void out_data_ring(const char *output, size_t size) /// @param output Data to append to screen lines. /// @param count Size of data. /// @param eof If true, there will be no more data output. -static void out_data_append_to_screen(const char *output, size_t *count, bool eof) +static void out_data_append_to_screen(const char *output, size_t *count, int fd, bool eof) FUNC_ATTR_NONNULL_ALL { const char *p = output; const char *end = output + *count; + msg_ext_set_kind(fd == STDERR_FILENO ? "shell_err" : "shell_out"); while (p < end) { if (*p == '\n' || *p == '\r' || *p == TAB || *p == BELL) { - msg_putchar_hl((uint8_t)(*p), 0); + msg_putchar_hl((uint8_t)(*p), fd == STDERR_FILENO ? HLF_E : 0); p++; } else { // Note: this is not 100% precise: @@ -1118,7 +1120,7 @@ static void out_data_append_to_screen(const char *output, size_t *count, bool eo goto end; } - msg_outtrans_len(p, i, 0, false); + msg_outtrans_len(p, i, fd == STDERR_FILENO ? HLF_E : 0, false); p += i; } } @@ -1133,7 +1135,7 @@ static size_t out_data_cb(RStream *stream, const char *ptr, size_t count, void * // Save the skipped output. If it is the final chunk, we display it later. out_data_ring(ptr, count); } else if (count > 0) { - out_data_append_to_screen(ptr, &count, eof); + out_data_append_to_screen(ptr, &count, stream->s.fd, eof); } return count; diff --git a/test/functional/ui/messages_spec.lua b/test/functional/ui/messages_spec.lua index ea4edefe8a..4d53daa9d6 100644 --- a/test/functional/ui/messages_spec.lua +++ b/test/functional/ui/messages_spec.lua @@ -331,6 +331,7 @@ describe('ui/ext_messages', function() }, }) + -- kind=verbose for :verbose messages feed(':1verbose filter Diff[AC] hi<CR>') screen:expect({ cmdline = { { @@ -380,6 +381,43 @@ describe('ui/ext_messages', function() }, }, }) + + -- kind=shell for :!cmd messages + local cmd = t.is_os('win') and 'echo stdout& echo stderr>&2& exit 3' + or '{ echo stdout; echo stderr >&2; exit 3; }' + feed(('<CR>:!%s<CR>'):format(cmd)) + screen:expect({ + cmdline = { { + abort = false, + } }, + messages = { + { + content = { { (':!%s\r\n[No write since last change]\n'):format(cmd) } }, + history = false, + kind = '', + }, + { + 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, 6 } }, + 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', + }, + }, + }) end) it(':echoerr', function() |