[vim/vim] Trigger ModeChanged on all minor mode changes (#8999)

33 views
Skip to first unread message

Magnus Groß

unread,
Oct 14, 2021, 5:14:35 PM10/14/21
to vim/vim, Subscribed

This is the follow-up patch to trigger ModeChanged in more cases, as discussed in #8856.

I added a few more tests (e.g. SELECT mode, normal operator pending mode, ctrl_x mode).

I hope this covers all cases now. If you find anything where ModeChanged still does not fire, please tell me how to reproduce.

One more thing: I wanted to fixup the doc for the usecase example:

au ModeChanged [vV<C-V]*:* let &l:relativenumber = mode() =~# '^[vV�]'

au ModeChanged *:[vV<C-V]* let &l:relativenumber = mode() =~# '^[vV�]'

au WinEnter * let &l:relativenumber = mode() =~# '^[vV�]'

au WinLeave * let &l:relativenumber = mode() =~# '^[vV�]'

But obviously the <C-V inside the regex does not match the ^V mode. I also tried ^V and \^V, but both don't match. What do I need to use to match properly? Or perhaps we should come up with another usecase example, as this one is getting quite large.


You can view, comment on, or merge this pull request online at:

  https://github.com/vim/vim/pull/8999

Commit Summary

File Changes

Patch Links:


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

codecov[bot]

unread,
Oct 14, 2021, 5:24:03 PM10/14/21
to vim/vim, Subscribed

Codecov Report

Merging #8999 (e361ea0) into master (0a7984a) will decrease coverage by 87.61%.
The diff coverage is 0.00%.

Impacted file tree graph

@@             Coverage Diff             @@

##           master    #8999       +/-   ##

===========================================

- Coverage   90.06%    2.45%   -87.62%     

===========================================

  Files         151      149        -2     

  Lines      168353   165975     -2378     

===========================================

- Hits       151631     4077   -147554     

- Misses      16722   161898   +145176     
Flag Coverage Δ
huge-clang-none ?
huge-gcc-none ?
huge-gcc-testgui ?
huge-gcc-unittests 2.45% <0.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
src/insexpand.c 0.00% <0.00%> (-92.45%) ⬇️
src/misc1.c 13.40% <0.00%> (-75.62%) ⬇️
src/normal.c 0.50% <0.00%> (-95.28%) ⬇️
src/terminal.c 0.00% <0.00%> (-91.23%) ⬇️
src/float.c 0.00% <0.00%> (-99.22%) ⬇️
src/gui_gtk_f.c 0.00% <0.00%> (-97.43%) ⬇️
src/crypt_zip.c 0.00% <0.00%> (-97.06%) ⬇️
src/sound.c 0.00% <0.00%> (-97.03%) ⬇️
src/cmdhist.c 0.00% <0.00%> (-97.00%) ⬇️
src/sha256.c 0.00% <0.00%> (-96.94%) ⬇️
... and 141 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0a7984a...e361ea0. Read the comment docs.

zeertzjq

unread,
Oct 14, 2021, 6:35:57 PM10/14/21
to vim/vim, Subscribed

But obviously the <C-V inside the regex does not match the ^V mode. I also tried ^V and \^V, but both don't match. What do I need to use to match properly? Or perhaps we should come up with another usecase example, as this one is getting quite large.

Try pressing CTRL-V twice in Insert mode.

zeertzjq

unread,
Oct 14, 2021, 6:43:15 PM10/14/21
to vim/vim, Subscribed

@zeertzjq commented on this pull request.


In runtime/doc/autocmd.txt:

>  				|InsertLeave|.
 				The following values of |v:event| are set:
 				   old_mode	The mode before it changed.
 				   new_mode	The new mode as also returned
-						by |mode()|.
+						by |mode(1)|.

Pressing K on this fails. Maybe you can change it to |mode()| called with a non-zero argument.

zeertzjq

unread,
Oct 14, 2021, 6:46:13 PM10/14/21
to vim/vim, Subscribed

@zeertzjq commented on this pull request.


In runtime/doc/autocmd.txt:

> @@ -930,18 +930,20 @@ MenuPopup			Just before showing the popup menu (under the
 							*ModeChanged*
 ModeChanged			After changing the mode. The pattern is
 				matched against `'old_mode:new_mode'`, for
-				example match against `i:*` to simulate
+				example match against `i*:*` to simulate

InsertLeave is also triggered when leaving Replace mode and Virtual Replace mode. I think this should be [iR]*:[^iR]*.

Magnus Groß

unread,
Oct 14, 2021, 7:28:01 PM10/14/21
to vim/vim, Subscribed

@vimpostor commented on this pull request.


In runtime/doc/autocmd.txt:

>  				|InsertLeave|.
 				The following values of |v:event| are set:
 				   old_mode	The mode before it changed.
 				   new_mode	The new mode as also returned
-						by |mode()|.
+						by |mode(1)|.

Good catch, done.

zeertzjq

unread,
Oct 14, 2021, 7:30:11 PM10/14/21
to vim/vim, Subscribed

The change from i to ic may be fired too late. Try this:

  1. :set noshowmode
  2. :set shortmess+=c
  3. :autocmd ModeChanged * echomsg v:event mode(1)
  4. :inoremap <F2> <Cmd>echomsg mode(1)<CR>
  5. Press i<C-X><C-F><F2><F2><F2><F2><F2><C-N>.
  6. The <F2>s print ic, but ModeChanged from i to ic is only triggered on <C-N>.

Magnus Groß

unread,
Oct 14, 2021, 7:30:16 PM10/14/21
to vim/vim, Subscribed

@vimpostor commented on this pull request.


In runtime/doc/autocmd.txt:

> @@ -930,18 +930,20 @@ MenuPopup			Just before showing the popup menu (under the
 							*ModeChanged*
 ModeChanged			After changing the mode. The pattern is
 				matched against `'old_mode:new_mode'`, for
-				example match against `i:*` to simulate
+				example match against `i*:*` to simulate

I only compared it to InsertLeave because it was a simple way to present and understand the wildcard mechanism, I don't like this becoming complicated due to the intrinsics of InsertLeave. Therefore I have now replaced this comparision with CmdlineEnter and *:c*, I think it is better to keep the Regex simple here and CmdlineEnter should be just c in this case.

Magnus Groß

unread,
Oct 14, 2021, 7:30:29 PM10/14/21
to vim/vim, Push

@vimpostor pushed 1 commit.

  • 8a5747c Trigger ModeChanged on minor mode changes


You are receiving this because you are subscribed to this thread.

View it on GitHub.

Magnus Groß

unread,
Oct 14, 2021, 7:44:19 PM10/14/21
to vim/vim, Push

@vimpostor pushed 1 commit.

  • da16fc0 Trigger ModeChanged on minor mode changes


You are receiving this because you are subscribed to this thread.

View it on GitHub.

Magnus Groß

unread,
Oct 14, 2021, 7:45:46 PM10/14/21
to vim/vim, Subscribed

The change from i to ic may be fired too late.

Good catch again! It should work now.

Try pressing CTRL-V twice in Insert mode.

This inserts ^V, but I already tried matching against that and it did not work.

zeertzjq

unread,
Oct 14, 2021, 7:55:51 PM10/14/21
to vim/vim, Subscribed

You may also need to trigger ModeChanged in set_completion().

zeertzjq

unread,
Oct 14, 2021, 7:57:51 PM10/14/21
to vim/vim, Subscribed

Not sure about ins_compl_clear() and ins_compl_restart().

zeertzjq

unread,
Oct 14, 2021, 8:07:55 PM10/14/21
to vim/vim, Subscribed

@zeertzjq commented on this pull request.


In src/testdir/test_edit.vim:

>    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', 'n', 'no', 'n', 'V', 'v', 's', 'n']

I think tests are failing because you didn't add ic here.

zeertzjq

unread,
Oct 14, 2021, 11:13:04 PM10/14/21
to vim/vim, Subscribed

The change from i to ic may be fired too late.

Good catch again! It should work now.

Try pressing CTRL-V twice in Insert mode.

This inserts ^V, but I already tried matching against that and it did not work.

It inserts a control character that is displayed as ^V, but it is a control character.

zeertzjq

unread,
Oct 14, 2021, 11:19:41 PM10/14/21
to vim/vim, Subscribed

For that example, paste the following into Vim and run :%!xxd -r:

00000000: 6175 204d 6f64 6543 6861 6e67 6564 205b  au ModeChanged [
00000010: 7656 165d 2a3a 2a20 6c65 7420 266c 3a72  vV.]*:* let &l:r
00000020: 656c 6174 6976 656e 756d 6265 7220 3d20  elativenumber = 
00000030: 6d6f 6465 2829 203d 7e23 2027 5e5b 7656  mode() =~# '^[vV
00000040: 165d 270a 6175 204d 6f64 6543 6861 6e67  .]'.au ModeChang
00000050: 6564 202a 3a5b 7656 165d 2a20 6c65 7420  ed *:[vV.]* let 
00000060: 266c 3a72 656c 6174 6976 656e 756d 6265  &l:relativenumbe
00000070: 7220 3d20 6d6f 6465 2829 203d 7e23 2027  r = mode() =~# '
00000080: 5e5b 7656 165d 270a 6175 2057 696e 456e  ^[vV.]'.au WinEn
00000090: 7465 7220 2a20 6c65 7420 266c 3a72 656c  ter * let &l:rel
000000a0: 6174 6976 656e 756d 6265 7220 3d20 6d6f  ativenumber = mo
000000b0: 6465 2829 203d 7e23 2027 5e5b 7656 165d  de() =~# '^[vV.]
000000c0: 270a 6175 2057 696e 4c65 6176 6520 2a20  '.au WinLeave * 
000000d0: 6c65 7420 266c 3a72 656c 6174 6976 656e  let &l:relativen
000000e0: 756d 6265 7220 3d20 6d6f 6465 2829 203d  umber = mode() =
000000f0: 7e23 2027 5e5b 7656 165d 270a            ~# '^[vV.]'.

Christian Brabandt

unread,
Oct 15, 2021, 3:55:53 AM10/15/21
to vim/vim, Subscribed

But obviously the <C-V inside the regex does not match the ^V mode. I also tried ^V and ^V, but both don't match. What do I need to use to match properly? Or perhaps we should come up with another usecase example, as this one is getting quite large.

Use double quoted strings and key-notation, e.g. something like this: "\<c-v>"

zeertzjq

unread,
Oct 15, 2021, 4:04:06 AM10/15/21
to vim/vim, Subscribed

But obviously the <C-V inside the regex does not match the ^V mode. I also tried ^V and ^V, but both don't match. What do I need to use to match properly? Or perhaps we should come up with another usecase example, as this one is getting quite large.

Use double quoted strings and key-notation, e.g. something like this: "\<c-v>"

I think this requires :execute to be used in autocmd pattern.

lacygoill

unread,
Oct 15, 2021, 5:22:56 AM10/15/21
to vim/vim, Subscribed

This seems to work for me:

vim9script
autocmd ModeChanged [vV\x16]*:*,*:[vV\x16]* &l:relativenumber = mode() =~ '^[vV\x16]'
autocmd WinEnter,WinLeave * &l:relativenumber = mode() =~ '^[vV\x16]'

zeertzjq

unread,
Oct 15, 2021, 5:44:47 AM10/15/21
to vim/vim, Subscribed

Oh, \x16 works without vim9script:

	:au ModeChanged [vV\x16]*:*,*:[vV\x16]* let &l:rnu = mode() =~# '^[vV\x16]'
	:au WinEnter,WinLeave * let &l:rnu = mode() =~# '^[vV\x16]'

Magnus Groß

unread,
Oct 15, 2021, 6:06:04 AM10/15/21
to vim/vim, Push

@vimpostor pushed 1 commit.

  • 7efb5d6 Trigger ModeChanged on minor mode changes


You are receiving this because you are subscribed to this thread.

View it on GitHub.

Magnus Groß

unread,
Oct 15, 2021, 6:06:27 AM10/15/21
to vim/vim, Subscribed

Thanks guys, I have updated the doc now.

You may also need to trigger ModeChanged in set_completion().

Why? What minor mode change is not yet covered by the other trigger_modechanged() in that file?

zeertzjq

unread,
Oct 15, 2021, 6:20:56 AM10/15/21
to vim/vim, Subscribed

Thanks guys, I have updated the doc now.

You may also need to trigger ModeChanged in set_completion().

Why? What minor mode change is not yet covered by the other trigger_modechanged() in that file?

complete() completion.

zeertzjq

unread,
Oct 15, 2021, 6:25:55 AM10/15/21
to vim/vim, Subscribed

Thanks guys, I have updated the doc now.

You may also need to trigger ModeChanged in set_completion().

Why? What minor mode change is not yet covered by the other trigger_modechanged() in that file?

Try this:

    1. :set noshowmode
    2. :set shortmess+=c
    3. :autocmd ModeChanged * echomsg v:event mode(1)
    4. :inoremap <F2> <Cmd>echomsg mode(1)<CR>
    1. :inoremap <F3> <Cmd>call complete(col('.'), ['a', 'b', 'c'])<CR>
    2. Press i<F3><F2><F2><F2><F2><F2><C-N>.
    1. The <F2>s print ic, but ModeChanged from i to ic is only triggered on <C-N>.

      zeertzjq

      unread,
      Oct 15, 2021, 7:10:23 AM10/15/21
      to vim/vim, Subscribed

      @zeertzjq commented on this pull request.


      In src/misc1.c:

      >      tv[0].v_type = VAR_NUMBER;
           tv[0].vval.v_number = 1;	    // get full mode
           tv[1].v_type = VAR_UNKNOWN;
           f_mode(tv, &rettv);
      +    if (!STRCMP(rettv.vval.v_string, last_mode))
      +	return;
      

      You didn't free rettv.vval.v_string.

      Magnus Groß

      unread,
      Oct 15, 2021, 7:25:34 AM10/15/21
      to vim/vim, Push

      @vimpostor pushed 1 commit.

      • 27f2704 Trigger ModeChanged on minor mode changes


      You are receiving this because you are subscribed to this thread.

      View it on GitHub.

      Magnus Groß

      unread,
      Oct 15, 2021, 7:26:13 AM10/15/21
      to vim/vim, Subscribed

      Try this (complete() function):

      1. :set noshowmode
      2. :set shortmess+=c
      3. :autocmd ModeChanged * echomsg v:event mode(1)
      4. :inoremap <F2> <Cmd>echomsg mode(1)<CR>
      5. :inoremap <F3> <Cmd>call complete(col('.'), ['a', 'b', 'c'])<CR>
      6. Press i<F3><F2><F2><F2><F2><F2><C-N>.
      7. The <F2>s print ic, but ModeChanged from i to ic is only triggered on <C-N>.

      Thanks for the clear example, fixed now.


      You are receiving this because you are subscribed to this thread.

      Reply to this email directly, view it on GitHub.

      zeertzjq

      unread,
      Oct 15, 2021, 8:07:09 PM10/15/21
      to vim/vim, Subscribed

      @zeertzjq commented on this pull request.


      In src/normal.c:

      > @@ -521,6 +521,7 @@ normal_cmd(
       #ifdef CURSOR_SHAPE
           if (finish_op != c)
           {
      +	trigger_modechanged();
      

      This line is not executed if CURSOR_SHAPE is not defined.

      zeertzjq

      unread,
      Oct 15, 2021, 8:52:13 PM10/15/21
      to vim/vim, Subscribed

      Some edge cases not covered:

      From Terminal-Job to another buffer:

      1. :set noshowmode
      1. :autocmd ModeChanged * echomsg v:event
      1. :edit foo
      2. :terminal
      3. Press <C-\><C-N>
      4. :set bufhidden=hide
      5. :tnoremap <F2> <Cmd>bnext<CR>
      6. Press i<F2>v
      7. The <F2> didn't trigger ModeChanged, and the v shows {'old_mode': 't', 'new_mode': 'v'} in messages.

      From Terminal-Job to another window:

      1. :set noshowmode
      1. :autocmd ModeChanged * echomsg v:event
      1. :tnoremap <F2> <Cmd>wincmd w<CR>
      2. :terminal
      3. Press <F2>v
      4. The <F2> didn't trigger ModeChanged, and the v shows {'old_mode': 't', 'new_mode': 'v'} in messages.

      zeertzjq

      unread,
      Oct 16, 2021, 1:18:31 AM10/16/21
      to vim/vim, Subscribed

      Another problem I found:

      1. :set noshowmode
      2. :xnoremap <F2> <Cmd>autocmd ModeChanged * echomsg v:event<CR>
      3. Press v<F2>
      4. The <F2> shows {'old_mode': 'n', 'new_mode': 'v'}

      This is because last_mode is initialized to "n". My suggestion:

      1. If has_modechanged returns FALSE, set last_mode to an empty string (I think this just needs last_mode[0] = NUL;).
      2. If has_modechanged returns TRUE but last_mode is an empty string (which means a ModeChanged event has just been added and there were none previously), copy new mode to last_mode, but do not trigger ModeChanged event.

      Magnus Groß

      unread,
      Oct 16, 2021, 5:57:55 AM10/16/21
      to vim/vim, Push

      @vimpostor pushed 1 commit.

      • 5362e79 Trigger ModeChanged on minor mode changes


      You are receiving this because you are subscribed to this thread.

      View it on GitHub.

      Magnus Groß

      unread,
      Oct 16, 2021, 6:05:51 AM10/16/21
      to vim/vim, Subscribed

      Some edge cases not covered:

      From Terminal-Job to another buffer:

      1. :set noshowmode
      2. :set hidden
      3. :autocmd ModeChanged * echomsg v:event
      1. :tnoremap <F2> <Cmd>bnext<CR>
      1. :edit foo
      1. :terminal
      2. Press <F2>v
      3. The <F2> didn't trigger ModeChanged, and the v shows {'old_mode': 't', 'new_mode': 'v'} in messages.

        From Terminal-Job to another window:

        1. :set noshowmode
        2. :autocmd ModeChanged * echomsg v:event
        3. :tnoremap <F2> <Cmd>wincmd w<CR>
        4. :terminal
        5. Press <F2>v
        6. The <F2> didn't trigger ModeChanged, and the v shows {'old_mode': 't', 'new_mode': 'v'} in messages.

        I can't reproduce both of these. Are you sure you had the latest version of my branch checked out? For me the <F2> does trigger in both cases the correct modechange.

        Another problem I found:

        1. :set noshowmode
        2. :xnoremap <F2> <Cmd>autocmd ModeChanged * echomsg v:event<CR>
        3. Press v<F2>
        4. The <F2> shows {'old_mode': 'n', 'new_mode': 'v'}

        This is because last_mode is initialized to "n". My suggestion:

        1. If has_modechanged returns FALSE, set last_mode to an empty string (I think this just needs last_mode[0] = NUL;).
        2. If has_modechanged returns TRUE but last_mode is an empty string (which means a ModeChanged event has just been added and there were none previously), copy new mode to last_mode, but do not trigger ModeChanged event.

        Yes I actually thought about this edge case, but didn't realize that the first ModeChanged could be created somewhere else than leaving CMD-mode to Normal mode (which would have been just right).
        The problem with your proposed solution is that the first ModeChanged would not trigger at all, which I consider just as broken. I think it would be better to initialize last_mode a second time when creating the first ModeChanged autocmd. Maybe somewhere at the end of do_autocmd(). That way we don't miss the first ModeChanged. Do you agree?


        You are receiving this because you are subscribed to this thread.

        Reply to this email directly, view it on GitHub.

        zeertzjq

        unread,
        Oct 16, 2021, 8:18:19 AM10/16/21
        to vim/vim, Subscribed

        Maybe I forgot to git fetch. I'll check again later.

        zeertzjq

        unread,
        Oct 16, 2021, 8:43:29 AM10/16/21
        to vim/vim, Subscribed

        Indeed I can no longer reproduce these two.

        zeertzjq

        unread,
        Oct 16, 2021, 8:58:41 AM10/16/21
        to vim/vim, Subscribed

        Yes I actually thought about this edge case, but didn't realize that the first ModeChanged autocmd could be created somewhere else than leaving CMD-mode to Normal mode (which would have been just right). The problem with your proposed solution is that the first ModeChanged would not trigger at all, which I consider just as broken. I think it would be better to initialize last_mode a second time when creating the first ModeChanged autocmd. Maybe somewhere at the end of do_autocmd(). That way we don't miss the first ModeChanged. Do you agree?

        Oh, I also didn't think about ++once. You solution indeed seem better.

        A script can create an autocommand in any mode.

        Magnus Groß

        unread,
        Oct 17, 2021, 3:58:11 PM10/17/21
        to vim/vim, Subscribed

        Fixed the problem by initializing last_mode inside do_autocmd_event() for EVENT_MODECHANGED.

        Perhaps it is time to add an internal get_mode() command, since we are now assigning to last_mode with duplicated f_mode() boilerplate code in two different places...

        Magnus Groß

        unread,
        Oct 17, 2021, 4:00:49 PM10/17/21
        to vim/vim, Push

        @vimpostor pushed 1 commit.

        • b8c090c Trigger ModeChanged on minor mode changes


        You are receiving this because you are subscribed to this thread.

        View it on GitHub.

        Magnus Groß

        unread,
        Oct 18, 2021, 5:08:43 AM10/18/21
        to vim/vim, Push

        @vimpostor pushed 1 commit.

        • 4920829 Trigger ModeChanged on minor mode changes

        Magnus Groß

        unread,
        Oct 18, 2021, 7:01:26 AM10/18/21
        to vim/vim, Push

        @vimpostor pushed 1 commit.

        • 38ba2f9 Trigger ModeChanged on minor mode changes

        Magnus Groß

        unread,
        Oct 18, 2021, 7:38:11 AM10/18/21
        to vim/vim, Push

        @vimpostor pushed 1 commit.

        • ee394e9 Trigger ModeChanged on minor mode changes

        Bram Moolenaar

        unread,
        Oct 18, 2021, 8:07:03 AM10/18/21
        to vim/vim, Subscribed

        Do we anticipate any more changes, or should the be ready to include now?
        I do expect some fine tuning later, when users start to use it, that should be OK.


        You are receiving this because you are subscribed to this thread.

        Reply to this email directly, view it on GitHub.

        Magnus Groß

        unread,
        Oct 18, 2021, 1:28:45 PM10/18/21
        to vim/vim, Push

        @vimpostor pushed 1 commit.

        • bcbb1e2 Trigger ModeChanged on minor mode changes


        You are receiving this because you are subscribed to this thread.

        View it on GitHub.

        Magnus Groß

        unread,
        Oct 18, 2021, 1:30:31 PM10/18/21
        to vim/vim, Subscribed

        Do we anticipate any more changes, or should the be ready to include now? I do expect some fine tuning later, when users start to use it, that should be OK.

        I just added another simple test case for terminal-normal mode. If @zeertzjq doesn't have anything to add, I think this should be good to go now.


        You are receiving this because you are subscribed to this thread.

        Reply to this email directly, view it on GitHub.

        Magnus Groß

        unread,
        Oct 18, 2021, 1:59:17 PM10/18/21
        to vim/vim, Push

        @vimpostor pushed 1 commit.

        • 0bd115f Trigger ModeChanged on minor mode changes


        You are receiving this because you are subscribed to this thread.

        View it on GitHub.

        zeertzjq

        unread,
        Oct 18, 2021, 5:49:19 PM10/18/21
        to vim/vim, Subscribed

        Vim can be compiled without the Terminal feature, so I think it is better to wrap tests for Terminal inside a has('terminal') block.


        You are receiving this because you are subscribed to this thread.

        Reply to this email directly, view it on GitHub.

        Magnus Groß

        unread,
        Oct 18, 2021, 5:55:27 PM10/18/21
        to vim/vim, Subscribed

        Vim can be compiled without the Terminal feature, so I think it is better to wrap tests for Terminal inside a has('terminal') block.

        I am already using CheckFeature terminal, is that not enough?

        zeertzjq

        unread,
        Oct 18, 2021, 5:58:29 PM10/18/21
        to vim/vim, Subscribed

        Vim can be compiled without the Terminal feature, so I think it is better to wrap tests for Terminal inside a has('terminal') block.

        I am already using CheckFeature terminal, is that not enough?

        That skips the whole function. I'm thinking about how to skip less.

        zeertzjq

        unread,
        Oct 18, 2021, 6:07:40 PM10/18/21
        to vim/vim, Subscribed

        Try this diff:

        diff --git a/src/testdir/test_edit.vim b/src/testdir/test_edit.vim
        index 22b7b222c..17ef31bcc 100644
        --- a/src/testdir/test_edit.vim
        +++ b/src/testdir/test_edit.vim
        @@ -1996,8 +1996,8 @@ func Test_mode_changes()
           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', 'c', 'n', 't', 'nt', 'c', 'nt', 'n']
        -  call feedkeys("a\<C-O>l\<esc>:term\<CR>\<C-W>N:bd!\<CR>", 'tnix')
        +  let g:mode_seq = ['n', 'i', 'niI', 'i', 'n']
        +  call feedkeys("a\<C-O>l\<esc>", '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)
        @@ -2005,7 +2005,20 @@ func Test_mode_changes()
           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)
        +  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
        

        I haven't tested it, so it may fail.

        zeertzjq

        unread,
        Oct 18, 2021, 6:10:27 PM10/18/21
        to vim/vim, Subscribed

        Try this diff:

        diff --git a/src/testdir/test_edit.vim b/src/testdir/test_edit.vim
        index 22b7b222c..9627140ee 100644
        --- a/src/testdir/test_edit.vim
        +++ b/src/testdir/test_edit.vim
        @@ -1959,7 +1959,6 @@ endfunc
         
         " Test for ModeChanged pattern
         func Test_mode_changes()
        -  CheckFeature terminal
           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()
        @@ -1996,8 +1995,8 @@ func Test_mode_changes()
           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', 'c', 'n', 't', 'nt', 'c', 'nt', 'n']
        -  call feedkeys("a\<C-O>l\<esc>:term\<CR>\<C-W>N:bd!\<CR>", 'tnix')
        +  let g:mode_seq = ['n', 'i', 'niI', 'i', 'n']
        +  call feedkeys("a\<C-O>l\<esc>", '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)
        
        @@ -2005,7 +2004,20 @@ func Test_mode_changes()
           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)
        +  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

        I haven't tested it yet, so it may fail.

        zeertzjq

        unread,
        Oct 18, 2021, 6:34:35 PM10/18/21
        to vim/vim, Subscribed

        Try this diff:

        diff --git a/src/testdir/test_edit.vim b/src/testdir/test_edit.vim
        index 22b7b222c..f0f04f049 100644
        
        --- a/src/testdir/test_edit.vim
        +++ b/src/testdir/test_edit.vim
        @@ -1959,7 +1959,6 @@ endfunc
         
         " Test for ModeChanged pattern
         func Test_mode_changes()
        -  CheckFeature terminal
           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()
        @@ -1996,8 +1995,8 @@ func Test_mode_changes()
           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', 'c', 'n', 't', 'nt', 'c', 'nt', 'n']
        -  call feedkeys("a\<C-O>l\<esc>:term\<CR>\<C-W>N:bd!\<CR>", 'tnix')
        +  let g:mode_seq = ['n', 'i', 'niI', 'i', 'n']
        +  call feedkeys("a\<C-O>l\<esc>", '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)
        
        @@ -2005,12 +2004,34 @@ func Test_mode_changes()
           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)
        +  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
        +  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

        Magnus Groß

        unread,
        Oct 19, 2021, 11:54:51 AM10/19/21
        to vim/vim, Push

        @vimpostor pushed 1 commit.

        • 7049158 Trigger ModeChanged on minor mode changes


        You are receiving this because you are subscribed to this thread.

        View it on GitHub.

        Magnus Groß

        unread,
        Oct 19, 2021, 11:55:44 AM10/19/21
        to vim/vim, Subscribed

        Try this diff: (...)

        Applied, I think this should be good to go then now.


        You are receiving this because you are subscribed to this thread.

        Reply to this email directly, view it on GitHub.

        Magnus Groß

        unread,
        Oct 19, 2021, 5:01:33 PM10/19/21
        to vim/vim, Subscribed

        When Ctrl-C is used to exit insert mode to normal mode, got_int is set which means that the autocmd is not received. But I guess this is intentional?

        Bram Moolenaar

        unread,
        Oct 19, 2021, 5:42:49 PM10/19/21
        to vim...@googlegroups.com, Magnus Groß

        > When `Ctrl-C` is used to exit insert mode to normal mode, `got_int` is
        > set which means that the autocmd is not received. But I guess this is
        > intentional?

        I suppose so. If someone is in the habit of using CTRL-C to exit Insert
        mode some side effects are to be expected. At least let's keep it this
        way until someone can provide a good reason to do otherwise.

        --
        $ echo pizza > /dev/oven

        /// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
        /// \\\
        \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
        \\\ help me help AIDS victims -- http://ICCF-Holland.org ///

        Bram Moolenaar

        unread,
        Oct 22, 2021, 1:57:27 PM10/22/21
        to vim/vim, Subscribed

        Closed #8999 via 25def2c.

        David Briscoe

        unread,
        Nov 16, 2021, 1:12:51 PM11/16/21
        to vim/vim, Subscribed

        @vimpostor What is [vV\x16] trying to match?

        The docs says:

        The pattern is matched against 'old_mode:new_mode'

        So I'd expect a mode name. :help mode() lists a bunch of characters used as mode names, but doesn't mention \x16.

        From the conversation above about ^V, maybe it means that, but how is a user supposed to guess? Could the match regex accept ^V (inserted with C-v C-v), but convert it under the hood to \x16? Same for Ctrl-S.

        Bram Moolenaar

        unread,
        Nov 16, 2021, 4:49:30 PM11/16/21
        to vim/vim, Subscribed

        CTRL-V is returned by mode() for Visual block mode. Not the easiest to work with, but we can't change that now.
        Using \x16 inside square brackets in a pattern works to match the CTRL-V. See :help /] (slash backslash right square bracket)

        Reply all
        Reply to author
        Forward
        0 new messages