cmdline: support v:event in CmdlineChanged

This commit is contained in:
Björn Linse 2018-12-12 11:01:46 +01:00
parent 6c602be33a
commit 5f82889be7
2 changed files with 135 additions and 5 deletions

View File

@ -1805,11 +1805,35 @@ static int empty_pattern(char_u *p)
static int command_line_changed(CommandLineState *s)
{
// Trigger CmdlineChanged autocommands.
char firstcbuf[2];
firstcbuf[0] = s->firstc > 0 ? s->firstc : '-';
firstcbuf[1] = 0;
apply_autocmds(EVENT_CMDLINECHANGED, (char_u *)firstcbuf, (char_u *)firstcbuf,
false, curbuf);
if (has_event(EVENT_CMDLINECHANGED)) {
TryState tstate;
Error err = ERROR_INIT;
bool tl_ret = true;
dict_T *dict = get_vim_var_dict(VV_EVENT);
char firstcbuf[2];
firstcbuf[0] = s->firstc > 0 ? s->firstc : '-';
firstcbuf[1] = 0;
// 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_CMDLINECHANGED, (char_u *)firstcbuf,
(char_u *)firstcbuf, false, curbuf);
tv_dict_clear(dict);
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;
}
// 'incsearch' highlighting.
if (p_is && !cmd_silent && (s->firstc == '/' || s->firstc == '?')) {

View File

@ -5,6 +5,7 @@ local clear = helpers.clear
local command = helpers.command
local eq = helpers.eq
local expect = helpers.expect
local eval = helpers.eval
local next_msg = helpers.next_msg
local feed = helpers.feed
local meths = helpers.meths
@ -63,6 +64,7 @@ describe('cmdline autocommands', function()
})
command("autocmd CmdlineEnter * echoerr 'FAIL'")
command("autocmd CmdlineLeave * echoerr 'very error'")
feed(':')
screen:expect([[
|
@ -74,6 +76,7 @@ describe('cmdline autocommands', function()
{2:E5500: autocmd has thrown an exception: Vim(echoerr):FAIL} |
:^ |
]])
feed("put ='lorem ipsum'<cr>")
screen:expect([[
|
@ -86,6 +89,7 @@ describe('cmdline autocommands', function()
{3:Press ENTER or type command to continue}^ |
]])
-- cmdline was still executed
feed('<cr>')
screen:expect([[
|
@ -97,6 +101,71 @@ describe('cmdline autocommands', function()
{1:~ }|
|
]])
command("autocmd CmdlineChanged * echoerr 'change erreor'")
-- history recall still works
feed(":<c-p>")
screen:expect([[
|
lorem ipsum |
{4: }|
: |
{2:E5500: autocmd has thrown an exception: Vim(echoerr):FAIL} |
:put ='lorem ipsum' |
{2:E5500: autocmd has thrown an exception: Vim(echoerr):change erreor} |
:put ='lorem ipsum'^ |
]])
feed("<left>")
screen:expect([[
|
lorem ipsum |
{4: }|
: |
{2:E5500: autocmd has thrown an exception: Vim(echoerr):FAIL} |
:put ='lorem ipsum' |
{2:E5500: autocmd has thrown an exception: Vim(echoerr):change erreor} |
:put ='lorem ipsum^' |
]])
-- edit still works
feed(".")
screen:expect([[
{4: }|
: |
{2:E5500: autocmd has thrown an exception: Vim(echoerr):FAIL} |
:put ='lorem ipsum' |
{2:E5500: autocmd has thrown an exception: Vim(echoerr):change erreor} |
:put ='lorem ipsum.' |
{2:E5500: autocmd has thrown an exception: Vim(echoerr):change erreor} |
:put ='lorem ipsum.^' |
]])
feed('<cr>')
screen:expect([[
:put ='lorem ipsum' |
{2:E5500: autocmd has thrown an exception: Vim(echoerr):change erreor} |
:put ='lorem ipsum.' |
{2:E5500: autocmd has thrown an exception: Vim(echoerr):change erreor} |
:put ='lorem ipsum.' |
{2:E5500: autocmd has thrown an exception: Vim(echoerr):very error} |
|
{3:Press ENTER or type command to continue}^ |
]])
-- cmdline was still executed
feed('<cr>')
screen:expect([[
|
lorem ipsum |
^lorem ipsum. |
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
|
]])
end)
it('works with nested cmdline', function()
@ -115,4 +184,41 @@ describe('cmdline autocommands', function()
feed('1+2<cr>')
eq({'notification', 'CmdlineLeave', {{cmdtype='=', cmdlevel=2, abort=false}}}, next_msg())
end)
it('supports CmdlineChanged' ,function()
command("autocmd CmdlineChanged * call rpcnotify(g:channel, 'CmdlineChanged', v:event, getcmdline())")
feed(':')
eq({'notification', 'CmdlineEnter', {{cmdtype=':', cmdlevel=1}}}, next_msg())
feed('l')
eq({'notification', 'CmdlineChanged', {{cmdtype=':', cmdlevel=1}, "l"}}, next_msg())
feed('e')
eq({'notification', 'CmdlineChanged', {{cmdtype=':', cmdlevel=1}, "le"}}, next_msg())
feed('t')
eq({'notification', 'CmdlineChanged', {{cmdtype=':', cmdlevel=1}, "let"}}, next_msg())
feed('<space>')
eq({'notification', 'CmdlineChanged', {{cmdtype=':', cmdlevel=1}, "let "}}, next_msg())
feed('x')
eq({'notification', 'CmdlineChanged', {{cmdtype=':', cmdlevel=1}, "let x"}}, next_msg())
feed('<space>')
eq({'notification', 'CmdlineChanged', {{cmdtype=':', cmdlevel=1}, "let x "}}, next_msg())
feed('=')
eq({'notification', 'CmdlineChanged', {{cmdtype=':', cmdlevel=1}, "let x ="}}, next_msg())
feed('<space>')
eq({'notification', 'CmdlineChanged', {{cmdtype=':', cmdlevel=1}, "let x = "}}, next_msg())
feed('<c-r>=')
eq({'notification', 'CmdlineEnter', {{cmdtype='=', cmdlevel=2}}}, next_msg())
feed('1')
eq({'notification', 'CmdlineChanged', {{cmdtype='=', cmdlevel=2}, "1"}}, next_msg())
feed('+')
eq({'notification', 'CmdlineChanged', {{cmdtype='=', cmdlevel=2}, "1+"}}, next_msg())
feed('1')
eq({'notification', 'CmdlineChanged', {{cmdtype='=', cmdlevel=2}, "1+1"}}, next_msg())
feed('<cr>')
eq({'notification', 'CmdlineLeave', {{cmdtype='=', cmdlevel=2, abort=false}}}, next_msg())
eq({'notification', 'CmdlineChanged', {{cmdtype=':', cmdlevel=1}, "let x = "}}, next_msg())
eq({'notification', 'CmdlineChanged', {{cmdtype=':', cmdlevel=1}, "let x = 2"}}, next_msg())
feed('<cr>')
eq({'notification', 'CmdlineLeave', {{cmdtype=':', cmdlevel=1, abort=false}}}, next_msg())
eq(2, eval('x'))
end)
end)