# HG changeset patch # User Bram Moolenaar # Date 1658855703 -7200 # Node ID 2a327999c05ceeaac2463fe26f0e0d2a44308fe2 # Parent c7ad677e8d590b01d856f3089462b5a43904bd43 patch 9.0.0083: ModeChanged event not triggered when leaving cmdline window Commit: https://github.com/vim/vim/commit/c9e8fd6fc7d2027d0645b376d95a6ed51098036c Author: zeertzjq Date: Tue Jul 26 18:12:38 2022 +0100 patch 9.0.0083: ModeChanged event not triggered when leaving cmdline window Problem: ModeChanged event not triggered when leaving the cmdline window. Solution: Call may_trigger_modechanged(). (closes https://github.com/vim/vim/issues/10791) diff --git a/src/ex_getln.c b/src/ex_getln.c --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -4649,6 +4649,7 @@ open_cmdwin(void) # endif State = save_State; + may_trigger_modechanged(); setmouse(); return cmdwin_result; diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim --- a/src/testdir/test_autocmd.vim +++ b/src/testdir/test_autocmd.vim @@ -3253,6 +3253,110 @@ func Test_v_event_readonly() au! TextYankPost endfunc +" Test for ModeChanged pattern +func Test_mode_changes() + let g:index = 0 + 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")) + call assert_equal(mode(1), get(v:event, "new_mode")) + let g:index += 1 + endfunc + + au ModeChanged * :call TestMode() + let g:n_to_any = 0 + au ModeChanged n:* let g:n_to_any += 1 + call feedkeys("i\vVca\\\\ggdG", 'tnix') + + let g:V_to_v = 0 + au ModeChanged V:v let g:V_to_v += 1 + call feedkeys("Vv\\", '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 + au ModeChanged n:i let g:n_to_i += 1 + let g:n_to_niI = 0 + au ModeChanged i:niI let g:n_to_niI += 1 + let g:niI_to_i = 0 + au ModeChanged niI:i let g:niI_to_i += 1 + let g:nany_to_i = 0 + au ModeChanged n*:i let g:nany_to_i += 1 + let g:i_to_n = 0 + au ModeChanged i:n let g:i_to_n += 1 + let g:nori_to_any = 0 + au ModeChanged [ni]:* let g:nori_to_any += 1 + let g:i_to_any = 0 + au ModeChanged i:* let g:i_to_any += 1 + let g:index = 0 + let g:mode_seq = ['n', 'i', 'niI', 'i', 'n'] + call feedkeys("a\l\", '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(3, g:nori_to_any) + + if has('terminal') + let g:mode_seq += ['c', 'n', 't', 'nt', 'c', 'nt', 'n'] + call feedkeys(":term\\N:bd!\", '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 + + if has('cmdwin') + let g:n_to_c = 0 + au ModeChanged n:c let g:n_to_c += 1 + let g:c_to_n = 0 + au ModeChanged c:n let g:c_to_n += 1 + let g:mode_seq += ['c', 'n', 'c', 'n'] + call feedkeys("q:\\", 'tnix') + call assert_equal(len(g:mode_seq) - 1, g:index) + call assert_equal(2, g:n_to_c) + call assert_equal(2, g:c_to_n) + unlet g:n_to_c + unlet g:c_to_n + endif + + au! ModeChanged + delfunc TestMode + unlet! g:mode_seq + unlet! g:index + 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 + +func Test_recursive_ModeChanged() + au! ModeChanged * norm 0u + sil! norm  + au! ModeChanged +endfunc + +func Test_ModeChanged_starts_visual() + " This was triggering ModeChanged before setting VIsual, causing a crash. + au! ModeChanged * norm 0u + sil! norm  + + au! ModeChanged +endfunc func Test_noname_autocmd() augroup test_noname_autocmd_group diff --git a/src/testdir/test_edit.vim b/src/testdir/test_edit.vim --- a/src/testdir/test_edit.vim +++ b/src/testdir/test_edit.vim @@ -2033,97 +2033,6 @@ func Test_edit_put_CTRL_E() set encoding=utf-8 endfunc -" Test for ModeChanged pattern -func Test_mode_changes() - let g:index = 0 - 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")) - call assert_equal(mode(1), get(v:event, "new_mode")) - let g:index += 1 - endfunc - - au ModeChanged * :call TestMode() - let g:n_to_any = 0 - au ModeChanged n:* let g:n_to_any += 1 - call feedkeys("i\vVca\\\\ggdG", 'tnix') - - let g:V_to_v = 0 - au ModeChanged V:v let g:V_to_v += 1 - call feedkeys("Vv\\", '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 - au ModeChanged n:i let g:n_to_i += 1 - let g:n_to_niI = 0 - au ModeChanged i:niI let g:n_to_niI += 1 - let g:niI_to_i = 0 - au ModeChanged niI:i let g:niI_to_i += 1 - let g:nany_to_i = 0 - au ModeChanged n*:i let g:nany_to_i += 1 - let g:i_to_n = 0 - au ModeChanged i:n let g:i_to_n += 1 - let g:nori_to_any = 0 - au ModeChanged [ni]:* let g:nori_to_any += 1 - let g:i_to_any = 0 - au ModeChanged i:* let g:i_to_any += 1 - let g:index = 0 - let g:mode_seq = ['n', 'i', 'niI', 'i', 'n'] - call feedkeys("a\l\", '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(3, g:nori_to_any) - - if has('terminal') - let g:mode_seq += ['c', 'n', 't', 'nt', 'c', 'nt', 'n'] - call feedkeys(":term\\N:bd!\", '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 - 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 - -func Test_recursive_ModeChanged() - au! ModeChanged * norm 0u - sil! norm  - au! ModeChanged -endfunc - -func Test_ModeChanged_starts_visual() - " This was triggering ModeChanged before setting VIsual, causing a crash. - au! ModeChanged * norm 0u - sil! norm  - - au! ModeChanged -endfunc - " Test toggling of input method. See :help i_CTRL-^ func Test_edit_CTRL_hat() CheckFeature xim diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -736,6 +736,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 83, +/**/ 82, /**/ 81,