When you want to leave insert mode, it's possible to avoid to trigger the
InsertLeave event by
pressing Ctrl-C instead of Esc.
But when I try to use this method inside an insert mapping, it still triggers the event.
For example, in a new buffer, let's run:
:au InsertLeave <buffer> call append('$', 'InsertLeave was triggered') :imap <buffer> <cr> <c-c>
Then if you press the (mapped) return key in order to exit insert mode, despite the use of
<c-c> in the mapping
definition, you can see that the
InsertLeave event is triggered.
How can I do to avoid the trigger of this event? The use of
:noautocmd does not help as well,
since we need to leave insert mode first to use this command.
To explain the aim of my question: I want to write a tiny plugin which would allow to easily edit several lines at the same start column, by hitting the return key. This 'table mode' should be togglable by hitting a quick shortkey in insert mode. For example, this kind of situation is quite usual:
" The following strings need to be filled with something: var1 = "" var2 = "" var3 = ""
The plugin looks pretty easy to write... But :
When my 'table mode' is active, I want that when leaving insert mode (by pressing Esc, or any other way, like the plugin
vim-easyescape - so remapping
<esc> is not an answer), then my 'table mode' just simply cancels and unmaps the return key.
So, I added an autocommand for the
InsertLeave event, which cancels all the stuff.
But my mapping for the
<cr> key (aka the main feature) does trigger this event as well (because it needs to go to normal mode, in order to move to the right position),
then it cancels my 'table mode' after the first press of the return key. I don't want this at all.
To sum it up, I need to:
- Cancel my 'table mode' each time insert mode is leaving
- Make an exception for the
<cr>mapping, which needs to go to normal mode to execute the
[count]|command, without cancelling anything.
Here is the code I started to write, with some comments about the issue:
let s:is_active = v:false function! tablemode#activate() if s:is_active return endif let s:is_active = v:true let s:start_col = virtcol('.') " Not needed for this question, running ":set ve=all" is enough: " call _#set_temp_option('virtualedit', 'all') exe printf("inoremap <buffer> <cr> <c-c>j%s<bar>i", s:start_col) " !!! Even when using <c-c> instead of <esc>, the InsertLeave event " is triggered, then cancels everything, which is not wanted at all augroup tablemode au! au InsertLeave <buffer> call tablemode#desactivate() " !!! This line is needed, but the <cr> mapping will " not work as expected (unless you comment this :au command) augroup END endf function! tablemode#desactivate() if !s:is_active return endif let s:is_active = v:false " Not needed for this question (restores old option state): " call _#restore_option('virtualedit') iunmap <buffer> <cr> augroup tablemode au! augroup END endf function! tablemode#toggle() if s:is_active call tablemode#desactivate() else call tablemode#activate() endif endf
Here's a mapping example, in order to test my script:
:imap <c-b> <c-o>:call tablemode#toggle()<cr>