aboutsummaryrefslogtreecommitdiff
path: root/src/nvim
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim')
-rw-r--r--src/nvim/api/private/helpers.c3
-rw-r--r--src/nvim/auevents.lua2
-rw-r--r--src/nvim/eval.c4
-rw-r--r--src/nvim/eval/typval.c23
-rw-r--r--src/nvim/ex_getln.c57
-rw-r--r--src/nvim/globals.h2
-rw-r--r--src/nvim/menu.c18
-rw-r--r--src/nvim/move.c4
-rw-r--r--src/nvim/testdir/test_autocmd.vim22
-rw-r--r--src/nvim/tui/input.c3
-rw-r--r--src/nvim/version.c1
11 files changed, 123 insertions, 16 deletions
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index 6808048ac8..629873998e 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -762,8 +762,7 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err)
case kObjectTypeTabpage:
case kObjectTypeInteger:
STATIC_ASSERT(sizeof(obj.data.integer) <= sizeof(varnumber_T),
- "Expected integer size to be less than or equal to VimL "
- "number size");
+ "Integer size must be <= VimL number size");
tv->v_type = VAR_NUMBER;
tv->vval.v_number = (varnumber_T)obj.data.integer;
break;
diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua
index 68a47c244f..7dfaf54ff0 100644
--- a/src/nvim/auevents.lua
+++ b/src/nvim/auevents.lua
@@ -19,6 +19,8 @@ return {
'BufWriteCmd', -- write buffer using command
'BufWritePost', -- after writing a buffer
'BufWritePre', -- before writing a buffer
+ 'CmdLineEnter', -- after entering cmdline mode
+ 'CmdLineLeave', -- before leaving cmdline mode
'CmdUndefined', -- command undefined
'CmdWinEnter', -- after entering the cmdline window
'CmdWinLeave', -- before leaving the cmdline window
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 39ce1ddcaa..f414e771d7 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -8729,8 +8729,8 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
foldend = (linenr_T)get_vim_var_nr(VV_FOLDEND);
dashes = get_vim_var_str(VV_FOLDDASHES);
if (foldstart > 0 && foldend <= curbuf->b_ml.ml_line_count) {
- /* Find first non-empty line in the fold. */
- for (lnum = foldstart; lnum < foldend; ++lnum) {
+ // Find first non-empty line in the fold.
+ for (lnum = foldstart; lnum < foldend; lnum++) {
if (!linewhite(lnum)) {
break;
}
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c
index c339a5cdd2..262ea922ef 100644
--- a/src/nvim/eval/typval.c
+++ b/src/nvim/eval/typval.c
@@ -1374,6 +1374,29 @@ int tv_dict_add_nr(dict_T *const d, const char *const key,
return OK;
}
+/// Add a special entry to dictionary
+///
+/// @param[out] d Dictionary to add entry to.
+/// @param[in] key Key to add.
+/// @param[in] key_len Key length.
+/// @param[in] val SpecialVarValue to add.
+///
+/// @return OK in case of success, FAIL when key already exists.
+int tv_dict_add_special(dict_T *const d, const char *const key,
+ const size_t key_len, SpecialVarValue val)
+{
+ dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
+
+ item->di_tv.v_lock = VAR_UNLOCKED;
+ item->di_tv.v_type = VAR_SPECIAL;
+ item->di_tv.vval.v_special = val;
+ if (tv_dict_add(d, item) == FAIL) {
+ tv_dict_item_free(item);
+ return FAIL;
+ }
+ return OK;
+}
+
/// Add a string entry to dictionary
///
/// @param[out] d Dictionary to add entry to.
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 9c9ccbca4d..c1500e3121 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -348,8 +348,57 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
got_int = false;
s->state.check = command_line_check;
s->state.execute = command_line_execute;
+
+ TryState tstate;
+ Error err = ERROR_INIT;
+ bool tl_ret = true;
+ dict_T *dict = get_vim_var_dict(VV_EVENT);
+ char firstcbuf[2];
+ firstcbuf[0] = 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, (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;
+ }
+
state_enter(&s->state);
+ if (has_event(EVENT_CMDLINELEAVE)) {
+ 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);
+ // not readonly:
+ tv_dict_add_special(dict, S_LEN("abort"),
+ s->gotesc ? kSpecialVarTrue : kSpecialVarFalse);
+ try_enter(&tstate);
+ apply_autocmds(EVENT_CMDLINELEAVE, (char_u *)firstcbuf, (char_u *)firstcbuf,
+ false, curbuf);
+ // error printed below, to avoid redraw issues
+ tl_ret = try_leave(&tstate, &err);
+ if (tv_dict_get_number(dict, "abort") != 0) {
+ s->gotesc = 1;
+ }
+ tv_dict_clear(dict);
+ }
+
cmdmsg_rl = false;
cmd_fkmap = 0;
@@ -410,8 +459,14 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
msg_scroll = s->save_msg_scroll;
redir_off = false;
+ 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);
+ }
+
// When the command line was typed, no need for a wait-return prompt.
- if (s->some_key_typed) {
+ if (s->some_key_typed && tl_ret) {
need_wait_return = false;
}
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 8f804ff888..2b025c2c50 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -1167,6 +1167,8 @@ EXTERN char_u e_dirnotf[] INIT(= N_(
EXTERN char_u e_unsupportedoption[] INIT(= N_("E519: Option not supported"));
EXTERN char_u e_fnametoolong[] INIT(= N_("E856: Filename too long"));
EXTERN char_u e_float_as_string[] INIT(= N_("E806: using Float as a String"));
+EXTERN char_u e_autocmd_err[] INIT(=N_(
+ "E920: autocmd has thrown an exception: %s"));
EXTERN char top_bot_msg[] INIT(= N_("search hit TOP, continuing at BOTTOM"));
diff --git a/src/nvim/menu.c b/src/nvim/menu.c
index 2876ba82a7..01c8e94bac 100644
--- a/src/nvim/menu.c
+++ b/src/nvim/menu.c
@@ -1419,16 +1419,18 @@ void ex_emenu(exarg_T *eap)
assert(idx != MENU_INDEX_INVALID);
if (menu->strings[idx] != NULL) {
- /* When executing a script or function execute the commands right now.
- * Otherwise put them in the typeahead buffer. */
- if (current_SID != 0)
+ // When executing a script or function execute the commands right now.
+ // Otherwise put them in the typeahead buffer.
+ if (current_SID != 0) {
exec_normal_cmd(menu->strings[idx], menu->noremap[idx],
- menu->silent[idx]);
- else
- ins_typebuf(menu->strings[idx], menu->noremap[idx], 0,
- TRUE, menu->silent[idx]);
- } else
+ menu->silent[idx]);
+ } else {
+ ins_typebuf(menu->strings[idx], menu->noremap[idx], 0, true,
+ menu->silent[idx]);
+ }
+ } else {
EMSG2(_("E335: Menu not defined for %s mode"), mode);
+ }
}
/*
diff --git a/src/nvim/move.c b/src/nvim/move.c
index 2debd90337..134ffcd7dc 100644
--- a/src/nvim/move.c
+++ b/src/nvim/move.c
@@ -1990,7 +1990,7 @@ void halfpage(bool flag, linenr_T Prenum)
if (curwin->w_topfill > 0) {
i = 1;
n--;
- --curwin->w_topfill;
+ curwin->w_topfill--;
} else {
i = plines_nofill(curwin->w_topline);
n -= i;
@@ -2067,7 +2067,7 @@ void halfpage(bool flag, linenr_T Prenum)
if (curwin->w_topfill < diff_check_fill(curwin, curwin->w_topline)) {
i = 1;
n--;
- ++curwin->w_topfill;
+ curwin->w_topfill++;
} else {
i = plines_nofill(curwin->w_topline - 1);
n -= i;
diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim
index 835df42a10..82c04abf5b 100644
--- a/src/nvim/testdir/test_autocmd.vim
+++ b/src/nvim/testdir/test_autocmd.vim
@@ -420,3 +420,25 @@ function Test_autocmd_bufwipe_in_SessLoadPost2()
call delete(file)
endfor
endfunc
+
+func Test_Cmdline()
+ au! CmdlineEnter : let g:entered = expand('<afile>')
+ au! CmdlineLeave : let g:left = expand('<afile>')
+ let g:entered = 0
+ let g:left = 0
+ call feedkeys(":echo 'hello'\<CR>", 'xt')
+ call assert_equal(':', g:entered)
+ call assert_equal(':', g:left)
+ au! CmdlineEnter
+ au! CmdlineLeave
+
+ au! CmdlineEnter / let g:entered = expand('<afile>')
+ au! CmdlineLeave / let g:left = expand('<afile>')
+ let g:entered = 0
+ let g:left = 0
+ call feedkeys("/hello<CR>", 'xt')
+ call assert_equal('/', g:entered)
+ call assert_equal('/', g:left)
+ au! CmdlineEnter
+ au! CmdlineLeave
+endfunc
diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c
index b76a11cc71..96bb692db9 100644
--- a/src/nvim/tui/input.c
+++ b/src/nvim/tui/input.c
@@ -204,7 +204,8 @@ static void forward_mouse_event(TermInput *input, TermKeyKey *key)
if (button == 4) {
len += (size_t)snprintf(buf + len, sizeof(buf) - len, "ScrollWheelUp");
} else if (button == 5) {
- len += (size_t)snprintf(buf + len, sizeof(buf) - len, "ScrollWheelDown");
+ len += (size_t)snprintf(buf + len, sizeof(buf) - len,
+ "ScrollWheelDown");
} else {
len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Mouse");
}
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 1ceda55cf1..205c25b6cd 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -78,6 +78,7 @@ static char *features[] = {
// clang-format off
static const int included_patches[] = {
+ 1206,
// 1026,
1025,
1024,