mirror of
https://github.com/neovim/neovim.git
synced 2026-03-30 20:32:08 +00:00
feat(ui): specify whether msg_show event comes from typed command
Problem: Unable to tell whether a msg_show event is emitted as a result
a command typed on the cmdline (UI may want to represent these
differently from other messages).
Solution: Add trigger parameter that is set to "typed_cmd" for
a message emitted due to an interactively typed command.
Possible extensions are mapping/timer/event but it's hard to
imagine a UI distinguishing those so not added here.
This commit is contained in:
@@ -829,9 +829,9 @@ 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, append, msg_id] ~
|
||||
["msg_show", kind, content, replace_last, history, append, id, trigger] ~
|
||||
Display a message to the user. Update (replace) any existing message
|
||||
matching `msg_id`.
|
||||
matching `id`.
|
||||
|
||||
kind
|
||||
Name indicating the message kind:
|
||||
@@ -887,9 +887,14 @@ must handle.
|
||||
True if the message should be appended to the previous message,
|
||||
rather than started on a new line. Is set for |:echon|.
|
||||
|
||||
msg_id
|
||||
id
|
||||
Unique identifier for the message. It can either be an integer or
|
||||
string. When message of same id appears it should replace the older message.
|
||||
string. A (visible) message with the same id should be replaced.
|
||||
|
||||
trigger
|
||||
Type of action that triggered the message:
|
||||
"" (empty) Unknown (consider a |feature-request|)
|
||||
"typed_cmd" Interactively typed command on the |cmdline|
|
||||
|
||||
["msg_clear"] ~
|
||||
Clear all messages currently displayed by "msg_show", emitted after
|
||||
|
||||
@@ -234,8 +234,7 @@ EVENTS
|
||||
• A new `empty` message kind is emitted for an empty (e.g. `:echo ""`) message.
|
||||
• |CmdlineLeave| sets |v:char| to the character that stops the Cmdline mode.
|
||||
• |CmdlineLeavePre| triggered before preparing to leave the command line.
|
||||
• New `append` parameter for |ui-messages| `msg_show` event.
|
||||
• New `msg_id` parameter for |ui-messages| `msg_show` event.
|
||||
• New `append`, `id` and `trigger` parameter for |ui-messages| `msg_show` event.
|
||||
• 'rulerformat' is emitted as `msg_ruler` when not part of the statusline.
|
||||
• Creating or updating a progress message with |nvim_echo()| triggers a |Progress| event.
|
||||
• |MarkSet| is triggered after a |mark| is set by the user (currently doesn't
|
||||
|
||||
@@ -165,7 +165,7 @@ void wildmenu_hide(void)
|
||||
FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
|
||||
|
||||
void msg_show(String kind, Array content, Boolean replace_last, Boolean history, Boolean append,
|
||||
Object id)
|
||||
Object id, String trigger)
|
||||
FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY;
|
||||
void msg_clear(void)
|
||||
FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY;
|
||||
|
||||
@@ -152,6 +152,7 @@ bool keep_msg_more = false; // keep_msg was set by msgmore()
|
||||
|
||||
// Extended msg state, currently used for external UIs with ext_messages
|
||||
static const char *msg_ext_kind = NULL;
|
||||
static const char *msg_ext_trigger = NULL;
|
||||
static MsgID msg_ext_id = { .type = kObjectTypeInteger, .data.integer = 1 };
|
||||
static Array *msg_ext_chunks = NULL;
|
||||
static garray_T msg_ext_last_chunk = GA_INIT(sizeof(char), 40);
|
||||
@@ -1650,6 +1651,13 @@ void msg_ext_set_kind(const char *msg_kind)
|
||||
redir_col = msg_ext_append ? redir_col : 0;
|
||||
}
|
||||
|
||||
void msg_ext_set_trigger(const char *trigger)
|
||||
{
|
||||
// Don't change the trigger of an existing batch:
|
||||
msg_ext_ui_flush();
|
||||
msg_ext_trigger = trigger;
|
||||
}
|
||||
|
||||
/// Prepare for outputting characters in the command line.
|
||||
void msg_start(void)
|
||||
{
|
||||
@@ -2285,7 +2293,7 @@ void msg_puts_len(const char *const str, const ptrdiff_t len, int hl_id, bool hi
|
||||
if (msg_silent != 0 || *str == NUL) {
|
||||
if (*str == NUL && ui_has(kUIMessages)) {
|
||||
ui_call_msg_show(cstr_as_string("empty"), (Array)ARRAY_DICT_INIT, false, false, false,
|
||||
INTEGER_OBJ(-1));
|
||||
INTEGER_OBJ(-1), (String)STRING_INIT);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -3317,7 +3325,7 @@ void msg_ext_ui_flush(void)
|
||||
Array *tofree = msg_ext_init_chunks();
|
||||
|
||||
ui_call_msg_show(cstr_as_string(msg_ext_kind), *tofree, msg_ext_overwrite, msg_ext_history,
|
||||
msg_ext_append, msg_ext_id);
|
||||
msg_ext_append, msg_ext_id, cstr_as_string(msg_ext_trigger));
|
||||
// clear info after emitting message.
|
||||
if (msg_ext_history) {
|
||||
api_free_array(*tofree);
|
||||
|
||||
@@ -3186,9 +3186,9 @@ static void nv_colon(cmdarg_T *cap)
|
||||
}
|
||||
}
|
||||
|
||||
// When typing, don't type below an old message
|
||||
if (KeyTyped) {
|
||||
compute_cmdrow();
|
||||
msg_ext_set_trigger("typed_cmd"); // distinguish msg_show emitted for typed cmd
|
||||
compute_cmdrow(); // when typing, don't type below an old message
|
||||
}
|
||||
|
||||
if (is_lua) {
|
||||
@@ -3198,6 +3198,7 @@ static void nv_colon(cmdarg_T *cap)
|
||||
cmd_result = do_cmdline(NULL, is_cmdkey ? getcmdkeycmd : getexline, NULL,
|
||||
cap->oap->op_type != OP_NOP ? DOCMD_KEEPLINE : 0);
|
||||
}
|
||||
msg_ext_set_trigger("");
|
||||
|
||||
if (cmd_result == false) {
|
||||
// The Ex command failed, do not execute the operator.
|
||||
|
||||
@@ -1636,6 +1636,34 @@ stack traceback:
|
||||
},
|
||||
})
|
||||
end)
|
||||
|
||||
it('trigger', function()
|
||||
command('echo "foo"')
|
||||
screen:expect({
|
||||
grid = [[
|
||||
^ |
|
||||
{1:~ }|*4
|
||||
]],
|
||||
messages = { { content = { { 'foo' } }, kind = 'echo', trigger = '' } },
|
||||
})
|
||||
command('map Q :echo "foo"<CR>')
|
||||
feed('Q')
|
||||
screen:expect({
|
||||
grid = [[
|
||||
^ |
|
||||
{1:~ }|*4
|
||||
]],
|
||||
messages = { { content = { { 'foo' } }, kind = 'echo', trigger = '' } },
|
||||
})
|
||||
feed(':echo "foo"<CR>')
|
||||
screen:expect({
|
||||
grid = [[
|
||||
^ |
|
||||
{1:~ }|*4
|
||||
]],
|
||||
messages = { { content = { { 'foo' } }, kind = 'echo', trigger = 'typed_cmd' } },
|
||||
})
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('ui/builtin messages', function()
|
||||
|
||||
@@ -671,7 +671,7 @@ screen:redraw_debug() to show all intermediate screen states.]]
|
||||
-- the ext_ feature being disabled, or the feature currently not activated
|
||||
-- (e.g. no external cmdline visible). Some extensions require
|
||||
-- preprocessing to represent highlights in a reproducible way.
|
||||
local extstate = self:_extstate_repr(attr_state)
|
||||
local extstate = self:_extstate_repr(attr_state, expected)
|
||||
if expected.mode ~= nil then
|
||||
extstate.mode = self.mode
|
||||
end
|
||||
@@ -1440,7 +1440,7 @@ function Screen:_handle_wildmenu_hide()
|
||||
self.wildmenu_items, self.wildmenu_pos = nil, nil
|
||||
end
|
||||
|
||||
function Screen:_handle_msg_show(kind, chunks, replace_last, history, append, id, progress)
|
||||
function Screen:_handle_msg_show(kind, chunks, replace_last, history, append, id, trigger)
|
||||
local pos = #self.messages
|
||||
if not replace_last or pos == 0 then
|
||||
pos = pos + 1
|
||||
@@ -1451,7 +1451,7 @@ function Screen:_handle_msg_show(kind, chunks, replace_last, history, append, id
|
||||
history = history,
|
||||
append = append,
|
||||
id = id,
|
||||
progress = progress,
|
||||
trigger = trigger,
|
||||
}
|
||||
end
|
||||
|
||||
@@ -1560,7 +1560,7 @@ local function hl_id_to_name(self, id)
|
||||
return id and self.hl_names[id] or nil
|
||||
end
|
||||
|
||||
function Screen:_extstate_repr(attr_state)
|
||||
function Screen:_extstate_repr(attr_state, exp)
|
||||
local cmdline = {}
|
||||
for i, entry in pairs(self.cmdline) do
|
||||
entry = shallowcopy(entry)
|
||||
@@ -1578,13 +1578,18 @@ function Screen:_extstate_repr(attr_state)
|
||||
|
||||
local messages = {}
|
||||
for i, entry in ipairs(self.messages) do
|
||||
local trigger = nil
|
||||
if exp and exp.messages and exp.messages[i] and exp.messages[i].trigger ~= nil then
|
||||
-- Late addition, only include when expected state includes it.
|
||||
trigger = entry.trigger
|
||||
end
|
||||
messages[i] = {
|
||||
kind = entry.kind,
|
||||
content = self:_chunks_repr(entry.content, attr_state),
|
||||
history = entry.history or nil,
|
||||
append = entry.append or nil,
|
||||
id = entry.kind == 'progress' and entry.id or nil,
|
||||
progress = entry.kind == 'progress' and entry.progress or nil,
|
||||
trigger = trigger,
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user