fix(cmdline): trigger CmdlineEnter and ModeChanged earlier (#19474)

Match Vim's ordering in code.
These tests are unrelated to ext_cmdline. Move them out of that block.
This commit is contained in:
zeertzjq
2022-07-26 10:21:30 +08:00
committed by GitHub
parent 88c6e02c12
commit 147cce29a6
2 changed files with 179 additions and 143 deletions

View File

@@ -828,6 +828,36 @@ static uint8_t *command_line_enter(int firstc, long count, int indent, bool init
setmouse();
ui_cursor_shape(); // may show different cursor shape
TryState tstate;
Error err = ERROR_INIT;
bool tl_ret = true;
save_v_event_T save_v_event;
dict_T *dict = get_v_event(&save_v_event);
char firstcbuf[2];
firstcbuf[0] = (char)(firstc > 0 ? firstc : '-');
firstcbuf[1] = 0;
if (has_event(EVENT_CMDLINEENTER)) {
// set v:event to a dictionary with information about the commandline
tv_dict_add_str(dict, S_LEN("cmdtype"), firstcbuf);
tv_dict_add_nr(dict, S_LEN("cmdlevel"), ccline.level);
tv_dict_set_keys_readonly(dict);
try_enter(&tstate);
apply_autocmds(EVENT_CMDLINEENTER, firstcbuf, firstcbuf, false, curbuf);
restore_v_event(dict, &save_v_event);
tl_ret = try_leave(&tstate, &err);
if (!tl_ret && ERROR_SET(&err)) {
msg_putchar('\n');
msg_printf_attr(HL_ATTR(HLF_E)|MSG_HIST, (char *)e_autocmd_err, err.msg);
api_clear_error(&err);
redrawcmd();
}
tl_ret = true;
}
may_trigger_modechanged();
init_history();
s->hiscnt = hislen; // set hiscnt to impossible history value
s->histype = hist_char2type(s->firstc);
@@ -860,36 +890,6 @@ static uint8_t *command_line_enter(int firstc, long count, int indent, bool init
s->state.check = command_line_check;
s->state.execute = command_line_execute;
TryState tstate;
Error err = ERROR_INIT;
bool tl_ret = true;
save_v_event_T save_v_event;
dict_T *dict = get_v_event(&save_v_event);
char firstcbuf[2];
firstcbuf[0] = (char)(firstc > 0 ? firstc : '-');
firstcbuf[1] = 0;
if (has_event(EVENT_CMDLINEENTER)) {
// set v:event to a dictionary with information about the commandline
tv_dict_add_str(dict, S_LEN("cmdtype"), firstcbuf);
tv_dict_add_nr(dict, S_LEN("cmdlevel"), ccline.level);
tv_dict_set_keys_readonly(dict);
try_enter(&tstate);
apply_autocmds(EVENT_CMDLINEENTER, firstcbuf, firstcbuf, false, curbuf);
restore_v_event(dict, &save_v_event);
tl_ret = try_leave(&tstate, &err);
if (!tl_ret && ERROR_SET(&err)) {
msg_putchar('\n');
msg_printf_attr(HL_ATTR(HLF_E)|MSG_HIST, (char *)e_autocmd_err, err.msg);
api_clear_error(&err);
redrawcmd();
}
tl_ret = true;
}
may_trigger_modechanged();
state_enter(&s->state);
if (has_event(EVENT_CMDLINELEAVE)) {
@@ -959,6 +959,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent, bool init
cmdpreview = save_cmdpreview; // restore preview state
redraw_all_later(SOME_VALID);
}
may_trigger_modechanged();
setmouse();
ui_cursor_shape(); // may show different cursor shape
sb_text_end_cmdline();

View File

@@ -96,119 +96,6 @@ local function test_cmdline(linegrid)
]]}
end)
describe("redraws statusline on entering", function()
before_each(function()
command('set laststatus=2')
command('set statusline=%{mode()}')
end)
it('from normal mode', function()
screen:expect{grid=[[
^ |
{1:~ }|
{1:~ }|
{3:n }|
|
]]}
feed(':')
screen:expect{grid=[[
^ |
{1:~ }|
{1:~ }|
{3:c }|
|
]], cmdline={{
firstc = ":",
content = {{""}},
pos = 0,
}}}
end)
it('from normal mode when : is mapped', function()
command('nnoremap ; :')
screen:expect{grid=[[
^ |
{1:~ }|
{1:~ }|
{3:n }|
|
]]}
feed(';')
screen:expect{grid=[[
^ |
{1:~ }|
{1:~ }|
{3:c }|
|
]], cmdline={{
firstc = ":",
content = {{""}},
pos = 0,
}}}
end)
it('but not with scrolled messages', function()
screen:try_resize(35,10)
feed(':echoerr doesnotexist<cr>')
screen:expect{grid=[[
|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{3: }|
{4:E121: Undefined variable: doesnotex}|
{4:ist} |
{5:Press ENTER or type command to cont}|
{5:inue}^ |
]]}
feed(':echoerr doesnotexist<cr>')
screen:expect{grid=[[
|
{1:~ }|
{3: }|
{4:E121: Undefined variable: doesnotex}|
{4:ist} |
{5:Press ENTER or type command to cont}|
{4:E121: Undefined variable: doesnotex}|
{4:ist} |
{5:Press ENTER or type command to cont}|
{5:inue}^ |
]]}
feed(':echoerr doesnotexist<cr>')
screen:expect{grid=[[
{4:E121: Undefined variable: doesnotex}|
{4:ist} |
{5:Press ENTER or type command to cont}|
{4:E121: Undefined variable: doesnotex}|
{4:ist} |
{5:Press ENTER or type command to cont}|
{4:E121: Undefined variable: doesnotex}|
{4:ist} |
{5:Press ENTER or type command to cont}|
{5:inue}^ |
]]}
feed('<cr>')
screen:expect{grid=[[
^ |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{3:n }|
|
]]}
end)
end)
it("works with input()", function()
feed(':call input("input", "default")<cr>')
screen:expect{grid=[[
@@ -883,6 +770,154 @@ describe('cmdline redraw', function()
end)
end)
describe('statusline is redrawn on entering cmdline', function()
local screen
before_each(function()
clear()
screen = new_screen()
command('set laststatus=2')
end)
it('from normal mode', function()
command('set statusline=%{mode()}')
screen:expect{grid=[[
^ |
{1:~ }|
{1:~ }|
{3:n }|
|
]]}
feed(':')
screen:expect{grid=[[
|
{1:~ }|
{1:~ }|
{3:c }|
:^ |
]]}
end)
it('from normal mode when : is mapped', function()
command('set statusline=%{mode()}')
command('nnoremap ; :')
screen:expect{grid=[[
^ |
{1:~ }|
{1:~ }|
{3:n }|
|
]]}
feed(';')
screen:expect{grid=[[
|
{1:~ }|
{1:~ }|
{3:c }|
:^ |
]]}
end)
it('but not with scrolled messages', function()
command('set statusline=%{mode()}')
screen:try_resize(35,10)
feed(':echoerr doesnotexist<cr>')
screen:expect{grid=[[
|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{3: }|
{4:E121: Undefined variable: doesnotex}|
{4:ist} |
{5:Press ENTER or type command to cont}|
{5:inue}^ |
]]}
feed(':echoerr doesnotexist<cr>')
screen:expect{grid=[[
|
{1:~ }|
{3: }|
{4:E121: Undefined variable: doesnotex}|
{4:ist} |
{5:Press ENTER or type command to cont}|
{4:E121: Undefined variable: doesnotex}|
{4:ist} |
{5:Press ENTER or type command to cont}|
{5:inue}^ |
]]}
feed(':echoerr doesnotexist<cr>')
screen:expect{grid=[[
{4:E121: Undefined variable: doesnotex}|
{4:ist} |
{5:Press ENTER or type command to cont}|
{4:E121: Undefined variable: doesnotex}|
{4:ist} |
{5:Press ENTER or type command to cont}|
{4:E121: Undefined variable: doesnotex}|
{4:ist} |
{5:Press ENTER or type command to cont}|
{5:inue}^ |
]]}
feed('<cr>')
screen:expect{grid=[[
^ |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{3:n }|
|
]]}
end)
describe('if custom statusline is set by', function()
before_each(function()
command('set statusline=')
screen:expect{grid=[[
^ |
{1:~ }|
{1:~ }|
{3:[No Name] }|
|
]]}
end)
it('CmdlineEnter autocommand', function()
command('autocmd CmdlineEnter * set statusline=command')
feed(':')
screen:expect{grid=[[
|
{1:~ }|
{1:~ }|
{3:command }|
:^ |
]]}
end)
it('ModeChanged autocommand', function()
command('autocmd ModeChanged *:c set statusline=command')
feed(':')
screen:expect{grid=[[
|
{1:~ }|
{1:~ }|
{3:command }|
:^ |
]]}
end)
end)
end)
describe("cmdline height", function()
it("does not crash resized screen #14263", function()
clear()