mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
parent
7c9d4d971c
commit
3d1ed7c959
@ -672,29 +672,33 @@ of the cmdline.
|
||||
["msg_show", kind, content, replace_last]
|
||||
Display a message to the user.
|
||||
|
||||
`kind` will be one of the following
|
||||
`emsg`: Internal error message
|
||||
`echo`: temporary message from plugin (|:echo|)
|
||||
`echomsg`: ordinary message from plugin (|:echomsg|)
|
||||
`echoerr`: error message from plugin (|:echoerr|)
|
||||
`return_prompt`: |press-enter| prompt after a group of messages
|
||||
`quickfix`: Quickfix navigation message
|
||||
`kind` can also be the empty string. The message is then some internal
|
||||
informative or warning message, that hasn't yet been assigned a kind.
|
||||
New message kinds can be added in later versions; clients should
|
||||
handle messages of an unknown kind just like empty kind.
|
||||
kind
|
||||
Name indicating the message kind:
|
||||
"" (empty) Unknown, report a |feature-request|
|
||||
"confirm" |confirm()| or |:confirm| dialog
|
||||
"confirm_sub" |:substitute| confirm dialog |:s_c|
|
||||
"emsg" Error (|errors|, internal error, |:throw|, …)
|
||||
"echo" |:echo| message
|
||||
"echomsg" |:echomsg| message
|
||||
"echoerr" |:echoerr| message
|
||||
"return_prompt" |press-enter| prompt after a multiple messages
|
||||
"quickfix" Quickfix navigation message
|
||||
"wmsg" Warning ("search hit BOTTOM", |W10|, …)
|
||||
New kinds may be added in the future; clients should treat unknown
|
||||
kinds as the empty kind.
|
||||
|
||||
`content` will be an array of `[attr_id, text_chunk]` tuples,
|
||||
building up the message text of chunks of different highlights.
|
||||
No extra spacing should be added between chunks, the `text_chunk` by
|
||||
itself should contain any necessary whitespace. Messages can contain
|
||||
line breaks `"\n"`.
|
||||
content
|
||||
Array of `[attr_id, text_chunk]` tuples, building up the message
|
||||
text of chunks of different highlights. No extra spacing should be
|
||||
added between chunks, the `text_chunk` by itself contains any
|
||||
necessary whitespace. Messages can contain line breaks "\n".
|
||||
|
||||
`replace_last` controls how multiple messages should be displayed.
|
||||
If `replace_last` is false, this message should be displayed together
|
||||
with all previous messages that are still visible. If `replace_last`
|
||||
is true, this message should replace the message in the most recent
|
||||
`msg_show` call, but any other visible message should still remain.
|
||||
replace_last
|
||||
Decides how multiple messages should be displayed:
|
||||
false: Display the message together with all previous messages
|
||||
that are still visible.
|
||||
true: Replace the message in the most-recent `msg_show` call,
|
||||
but any other visible message should still remain.
|
||||
|
||||
["msg_clear"]
|
||||
Clear all messages currently displayed by "msg_show". (Messages sent
|
||||
|
@ -3692,10 +3692,9 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
|
||||
i = msg_scroll;
|
||||
msg_scroll = 0; /* truncate msg when
|
||||
needed */
|
||||
msg_no_more = TRUE;
|
||||
/* write message same highlighting as for
|
||||
* wait_return */
|
||||
smsg_attr(HL_ATTR(HLF_R),
|
||||
msg_no_more = true;
|
||||
msg_ext_set_kind("confirm_sub");
|
||||
smsg_attr(HL_ATTR(HLF_R), // Same highlight as wait_return().
|
||||
_("replace with %s (y/n/a/q/l/^E/^Y)?"), sub);
|
||||
msg_no_more = FALSE;
|
||||
msg_scroll = i;
|
||||
|
@ -839,9 +839,10 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
|
||||
sourcing_lnum = current_exception->throw_lnum;
|
||||
current_exception->throw_name = NULL;
|
||||
|
||||
discard_current_exception(); /* uses IObuff if 'verbose' */
|
||||
suppress_errthrow = TRUE;
|
||||
force_abort = TRUE;
|
||||
discard_current_exception(); // uses IObuff if 'verbose'
|
||||
suppress_errthrow = true;
|
||||
force_abort = true;
|
||||
msg_ext_set_kind("emsg"); // kind=emsg for :throw, exceptions. #9993
|
||||
|
||||
if (messages != NULL) {
|
||||
do {
|
||||
|
@ -3008,6 +3008,8 @@ void give_warning(char_u *message, bool hl) FUNC_ATTR_NONNULL_ARG(1)
|
||||
} else {
|
||||
keep_msg_attr = 0;
|
||||
}
|
||||
msg_ext_set_kind("wmsg");
|
||||
|
||||
if (msg_attr((const char *)message, keep_msg_attr) && msg_scrolled == 0) {
|
||||
set_keep_msg(message, keep_msg_attr);
|
||||
}
|
||||
@ -3348,6 +3350,7 @@ void display_confirm_msg(void)
|
||||
// Avoid that 'q' at the more prompt truncates the message here.
|
||||
confirm_msg_used++;
|
||||
if (confirm_msg != NULL) {
|
||||
msg_ext_set_kind("confirm");
|
||||
msg_puts_attr((const char *)confirm_msg, HL_ATTR(HLF_M));
|
||||
}
|
||||
confirm_msg_used--;
|
||||
|
@ -2248,6 +2248,7 @@ change_warning (
|
||||
if (msg_row == Rows - 1)
|
||||
msg_col = col;
|
||||
msg_source(HL_ATTR(HLF_W));
|
||||
msg_ext_set_kind("wmsg");
|
||||
MSG_PUTS_ATTR(_(w_readonly), HL_ATTR(HLF_W) | MSG_HIST);
|
||||
set_vim_var_string(VV_WARNINGMSG, _(w_readonly), -1);
|
||||
msg_clr_eos();
|
||||
|
@ -277,7 +277,6 @@ enum { FOLD_TEXT_LEN = 51 }; //!< buffer size for get_foldtext()
|
||||
|
||||
// Enums need a typecast to be used as array index (for Ultrix).
|
||||
#define HL_ATTR(n) highlight_attr[(int)(n)]
|
||||
#define TERM_STR(n) term_strings[(int)(n)]
|
||||
|
||||
/// Maximum number of bytes in a multi-byte character. It can be one 32-bit
|
||||
/// character of up to 6 bytes, or one 16-bit character of up to three bytes
|
||||
|
@ -22,8 +22,129 @@ describe('ui/ext_messages', function()
|
||||
[6] = {bold = true, reverse = true},
|
||||
})
|
||||
end)
|
||||
after_each(function()
|
||||
os.remove('Xtest')
|
||||
end)
|
||||
|
||||
it('supports :echoerr', function()
|
||||
it('msg_show kind=confirm,confirm_sub,emsg,wmsg', function()
|
||||
feed('iline 1\nline 2<esc>')
|
||||
|
||||
-- kind=confirm
|
||||
feed(':echo confirm("test")<cr>')
|
||||
screen:expect{grid=[[
|
||||
line 1 |
|
||||
line ^2 |
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
]], messages={ {
|
||||
content = {{"\ntest\n[O]k: ", 4}},
|
||||
kind = 'confirm',
|
||||
}}}
|
||||
feed('<cr><cr>')
|
||||
screen:expect{grid=[[
|
||||
line 1 |
|
||||
line ^2 |
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
]], messages={ {
|
||||
content = { { "\ntest\n[O]k: ", 4 } },
|
||||
kind = "confirm"
|
||||
}, {
|
||||
content = { { "1" } },
|
||||
kind = "echo"
|
||||
}, {
|
||||
content = { { "Press ENTER or type command to continue", 4 } },
|
||||
kind = "return_prompt"
|
||||
} }}
|
||||
feed('<cr><cr>')
|
||||
|
||||
-- kind=confirm_sub
|
||||
feed(':%s/i/X/gc<cr>')
|
||||
screen:expect{grid=[[
|
||||
l{7:i}ne 1 |
|
||||
l{8:i}ne ^2 |
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
]], attr_ids={
|
||||
[1] = {bold = true, foreground = Screen.colors.Blue1},
|
||||
[2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
|
||||
[3] = {bold = true},
|
||||
[4] = {bold = true, foreground = Screen.colors.SeaGreen4},
|
||||
[5] = {foreground = Screen.colors.Blue1},
|
||||
[6] = {bold = true, reverse = true},
|
||||
[7] = {reverse = true},
|
||||
[8] = {background = Screen.colors.Yellow},
|
||||
}, messages={ {
|
||||
content = { { "replace with X (y/n/a/q/l/^E/^Y)?", 4 } },
|
||||
kind = "confirm_sub"
|
||||
} }}
|
||||
feed('nq')
|
||||
|
||||
-- kind=wmsg (editing readonly file)
|
||||
command('write Xtest')
|
||||
command('set readonly nohls')
|
||||
feed('G$x')
|
||||
screen:expect{grid=[[
|
||||
line 1 |
|
||||
{IGNORE}|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
]], attr_ids={
|
||||
[1] = {bold = true, foreground = Screen.colors.Blue1},
|
||||
[7] = {foreground = Screen.colors.Red},
|
||||
}, messages={ {
|
||||
content = { { "W10: Warning: Changing a readonly file", 7 } },
|
||||
kind = "wmsg"
|
||||
}
|
||||
}}
|
||||
|
||||
-- kind=wmsg ('wrapscan' after search reaches EOF)
|
||||
feed('uG$/i<cr>')
|
||||
screen:expect{grid=[[
|
||||
l^ine 1 |
|
||||
line 2 |
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
]], attr_ids={
|
||||
[1] = {bold = true, foreground = Screen.colors.Blue1},
|
||||
[2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
|
||||
[3] = {bold = true},
|
||||
[4] = {bold = true, foreground = Screen.colors.SeaGreen4},
|
||||
[5] = {foreground = Screen.colors.Blue1},
|
||||
[6] = {bold = true, reverse = true},
|
||||
[7] = {foreground = Screen.colors.Red},
|
||||
}, messages={ {
|
||||
content = { { "search hit BOTTOM, continuing at TOP", 7 } },
|
||||
kind = "wmsg"
|
||||
} }}
|
||||
|
||||
-- kind=emsg after :throw
|
||||
feed(':throw "foo"<cr>')
|
||||
screen:expect{grid=[[
|
||||
l^ine 1 |
|
||||
line 2 |
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
{1:~ }|
|
||||
]], messages={ {
|
||||
content = { { "Error detected while processing :", 2 } },
|
||||
kind = "emsg"
|
||||
}, {
|
||||
content = { { "E605: Exception not caught: foo", 2 } },
|
||||
kind = ""
|
||||
}, {
|
||||
content = { { "Press ENTER or type command to continue", 4 } },
|
||||
kind = "return_prompt"
|
||||
} }
|
||||
}
|
||||
end)
|
||||
|
||||
it(':echoerr', function()
|
||||
feed(':echoerr "raa"<cr>')
|
||||
screen:expect{grid=[[
|
||||
^ |
|
||||
@ -142,7 +263,7 @@ describe('ui/ext_messages', function()
|
||||
}}
|
||||
end)
|
||||
|
||||
it('supports showmode', function()
|
||||
it('&showmode', function()
|
||||
command('imap <f2> <cmd>echomsg "stuff"<cr>')
|
||||
feed('i')
|
||||
screen:expect{grid=[[
|
||||
@ -230,7 +351,7 @@ describe('ui/ext_messages', function()
|
||||
}}
|
||||
end)
|
||||
|
||||
it('supports showmode with recording message', function()
|
||||
it('&showmode with macro-recording message', function()
|
||||
feed('qq')
|
||||
screen:expect{grid=[[
|
||||
^ |
|
||||
@ -268,7 +389,7 @@ describe('ui/ext_messages', function()
|
||||
]])
|
||||
end)
|
||||
|
||||
it('shows recording message with noshowmode', function()
|
||||
it('shows macro-recording message with &noshowmode', function()
|
||||
command("set noshowmode")
|
||||
feed('qq')
|
||||
-- also check mode to avoid immediate success
|
||||
@ -308,7 +429,7 @@ describe('ui/ext_messages', function()
|
||||
]], mode="normal"}
|
||||
end)
|
||||
|
||||
it('supports showcmd and ruler', function()
|
||||
it('supports &showcmd and &ruler', function()
|
||||
command('set showcmd ruler')
|
||||
screen:expect{grid=[[
|
||||
^ |
|
||||
|
@ -74,6 +74,7 @@
|
||||
local global_helpers = require('test.helpers')
|
||||
local deepcopy = global_helpers.deepcopy
|
||||
local shallowcopy = global_helpers.shallowcopy
|
||||
local concat_tables = global_helpers.concat_tables
|
||||
local helpers = require('test.functional.helpers')(nil)
|
||||
local request, run_session = helpers.request, helpers.run_session
|
||||
local eq = helpers.eq
|
||||
@ -413,26 +414,23 @@ screen:redraw_debug() to show all intermediate screen states. ]])
|
||||
end
|
||||
end
|
||||
|
||||
-- Extension features. The default expectations should cover the case of
|
||||
-- UI extensions. The default expectations should cover the case of
|
||||
-- the ext_ feature being disabled, or the feature currently not activated
|
||||
-- (for instance no external cmdline visible). Some extensions require
|
||||
-- (e.g. no external cmdline visible). Some extensions require
|
||||
-- preprocessing to represent highlights in a reproducible way.
|
||||
local extstate = self:_extstate_repr(attr_state)
|
||||
|
||||
-- convert assertion errors into invalid screen state descriptions
|
||||
local status, res = pcall(function()
|
||||
for _, k in ipairs(ext_keys) do
|
||||
-- Empty states is considered the default and need not be mentioned
|
||||
if not (expected[k] == nil and isempty(extstate[k])) then
|
||||
eq(expected[k], extstate[k], k)
|
||||
if expected['mode'] ~= nil then
|
||||
extstate['mode'] = self.mode
|
||||
end
|
||||
end
|
||||
if expected.mode ~= nil then
|
||||
eq(expected.mode, self.mode, "mode")
|
||||
end
|
||||
end)
|
||||
-- Convert assertion errors into invalid screen state descriptions.
|
||||
for _, k in ipairs(concat_tables(ext_keys, {'mode'})) do
|
||||
-- Empty states are considered the default and need not be mentioned.
|
||||
if (not (expected[k] == nil and isempty(extstate[k]))) then
|
||||
local status, res = pcall(eq, expected[k], extstate[k], k)
|
||||
if not status then
|
||||
return tostring(res)
|
||||
return (tostring(res)..'\nHint: full state of "'..k..'":\n '..inspect(extstate[k]))
|
||||
end
|
||||
end
|
||||
end
|
||||
end, expected)
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user