aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/autocmd.c7
-rw-r--r--src/nvim/edit.c7
-rw-r--r--src/nvim/misc1.c9
-rw-r--r--src/nvim/normal.c7
-rw-r--r--src/nvim/testdir/test_edit.vim46
5 files changed, 57 insertions, 19 deletions
diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c
index ae81b6a808..490fe5a0ac 100644
--- a/src/nvim/autocmd.c
+++ b/src/nvim/autocmd.c
@@ -925,6 +925,13 @@ static int do_autocmd_event(event_T event, char_u *pat, bool once, int nested, c
return FAIL;
}
}
+
+ // need to initialize last_mode for the first ModeChanged autocmd
+ if (event == EVENT_MODECHANGED && !has_event(EVENT_MODECHANGED)) {
+ xfree(last_mode);
+ last_mode = get_mode();
+ }
+
ap->cmds = NULL;
*prev_ap = ap;
last_autopat[(int)event] = ap;
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index cbb93c88ee..a6b7461c59 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -2049,6 +2049,8 @@ static void ins_ctrl_x(void)
// CTRL-V look like CTRL-N
ctrl_x_mode = CTRL_X_CMDLINE_CTRL_X;
}
+
+ trigger_modechanged();
}
// Whether other than default completion has been selected.
@@ -2661,6 +2663,7 @@ void set_completion(colnr_T startcol, list_T *list)
show_pum(save_w_wrow, save_w_leftcol);
}
+ trigger_modechanged();
ui_flush();
}
@@ -3839,6 +3842,8 @@ static bool ins_compl_prep(int c)
ins_apply_autocmds(EVENT_COMPLETEDONE);
}
+ trigger_modechanged();
+
/* reset continue_* if we left expansion-mode, if we stay they'll be
* (re)set properly in ins_complete() */
if (!vim_is_ctrl_x_key(c)) {
@@ -4587,6 +4592,8 @@ static int ins_compl_get_exp(pos_T *ini)
compl_curr_match = compl_old_match;
}
}
+ trigger_modechanged();
+
return i;
}
diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c
index 4c495ee9db..b50d8682eb 100644
--- a/src/nvim/misc1.c
+++ b/src/nvim/misc1.c
@@ -1067,12 +1067,13 @@ void trigger_modechanged(void)
return;
}
- dict_T *v_event = get_vim_var_dict(VV_EVENT);
-
char *mode = get_mode();
- if (last_mode == NULL) {
- last_mode = (char *)vim_strsave((char_u *)"n");
+ if (STRCMP(mode, last_mode) == 0) {
+ xfree(mode);
+ return;
}
+
+ dict_T *v_event = get_vim_var_dict(VV_EVENT);
tv_dict_add_str(v_event, S_LEN("new_mode"), mode);
tv_dict_add_str(v_event, S_LEN("old_mode"), last_mode);
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 81e8251361..686eddfb14 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -487,6 +487,7 @@ static void normal_prepare(NormalState *s)
if (finish_op != c) {
ui_cursor_shape(); // may show different cursor shape
}
+ trigger_modechanged();
// When not finishing an operator and no register name typed, reset the count.
if (!finish_op && !s->oa.regname) {
@@ -928,6 +929,7 @@ normal_end:
// Reset finish_op, in case it was set
s->c = finish_op;
finish_op = false;
+ trigger_modechanged();
// Redraw the cursor with another shape, if we were in Operator-pending
// mode or did a replace command.
if (s->c || s->ca.cmdchar == 'r') {
@@ -965,6 +967,7 @@ normal_end:
&& s->oa.regname == 0) {
if (restart_VIsual_select == 1) {
VIsual_select = true;
+ trigger_modechanged();
showmode();
restart_VIsual_select = 0;
}
@@ -3050,7 +3053,6 @@ static int get_mouse_class(char_u *p)
void end_visual_mode(void)
{
VIsual_active = false;
- trigger_modechanged();
setmouse();
mouse_dragging = 0;
@@ -3067,6 +3069,7 @@ void end_visual_mode(void)
may_clear_cmdline();
adjust_cursor_eol();
+ trigger_modechanged();
}
/*
@@ -4852,6 +4855,7 @@ static void nv_ctrlg(cmdarg_T *cap)
{
if (VIsual_active) { // toggle Selection/Visual mode
VIsual_select = !VIsual_select;
+ trigger_modechanged();
showmode();
} else if (!checkclearop(cap->oap)) {
// print full name if count given or :cd used
@@ -4895,6 +4899,7 @@ static void nv_ctrlo(cmdarg_T *cap)
{
if (VIsual_active && VIsual_select) {
VIsual_select = false;
+ trigger_modechanged();
showmode();
restart_VIsual_select = 2; // restart Select mode later
} else {
diff --git a/src/nvim/testdir/test_edit.vim b/src/nvim/testdir/test_edit.vim
index 690558a44a..95eb5a0c8b 100644
--- a/src/nvim/testdir/test_edit.vim
+++ b/src/nvim/testdir/test_edit.vim
@@ -1646,12 +1646,8 @@ endfunc
" Test for ModeChanged pattern
func Test_mode_changes()
- let g:count = 0
- func! DoIt()
- let g:count += 1
- endfunc
let g:index = 0
- let g:mode_seq = ['n', 'i', 'n', 'v', 'V', 'n', 'V', 'v', 'n']
+ let g:mode_seq = ['n', 'i', 'n', 'v', 'V', 'i', 'ix', 'i', 'ic', 'i', 'n', 'no', 'n', 'V', 'v', 's', 'n']
func! TestMode()
call assert_equal(g:mode_seq[g:index], get(v:event, "old_mode"))
call assert_equal(g:mode_seq[g:index + 1], get(v:event, "new_mode"))
@@ -1660,13 +1656,15 @@ func Test_mode_changes()
endfunc
au ModeChanged * :call TestMode()
- au ModeChanged n:* :call DoIt()
- call feedkeys("i\<esc>vV\<esc>", 'tnix')
- call assert_equal(2, g:count)
-
- au ModeChanged V:v :call DoIt()
- call feedkeys("Vv\<esc>", 'tnix')
- call assert_equal(4, g:count)
+ let g:n_to_any = 0
+ au ModeChanged n:* let g:n_to_any += 1
+ call feedkeys("i\<esc>vVca\<CR>\<C-X>\<C-L>\<esc>ggdG", 'tnix')
+
+ let g:V_to_v = 0
+ au ModeChanged V:v let g:V_to_v += 1
+ call feedkeys("Vv\<C-G>\<esc>", 'tnix')
+ call assert_equal(len(filter(g:mode_seq[1:], {idx, val -> val == 'n'})), g:n_to_any)
+ call assert_equal(1, g:V_to_v)
call assert_equal(len(g:mode_seq) - 1, g:index)
let g:n_to_i = 0
@@ -1695,12 +1693,32 @@ func Test_mode_changes()
call assert_equal(2, g:i_to_any)
call assert_equal(3, g:nori_to_any)
+ if has('terminal')
+ let g:mode_seq += ['c', 'n', 't', 'nt', 'c', 'nt', 'n']
+ call feedkeys(":term\<CR>\<C-W>N:bd!\<CR>", 'tnix')
+ call assert_equal(len(g:mode_seq) - 1, g:index)
+ call assert_equal(1, g:n_to_i)
+ call assert_equal(1, g:n_to_niI)
+ call assert_equal(1, g:niI_to_i)
+ call assert_equal(2, g:nany_to_i)
+ call assert_equal(1, g:i_to_n)
+ call assert_equal(2, g:i_to_any)
+ call assert_equal(5, g:nori_to_any)
+ endif
+
au! ModeChanged
delfunc TestMode
unlet! g:mode_seq
unlet! g:index
- delfunc DoIt
- unlet! g:count
+ unlet! g:n_to_any
+ unlet! g:V_to_v
+ unlet! g:n_to_i
+ unlet! g:n_to_niI
+ unlet! g:niI_to_i
+ unlet! g:nany_to_i
+ unlet! g:i_to_n
+ unlet! g:nori_to_any
+ unlet! g:i_to_any
endfunc
" vim: shiftwidth=2 sts=2 expandtab