I set a couple terminal options so that Vim changes the cursor shape to a vertical bar when I enter Insert mode, an underbar for Replace mode, and a block when I return to Normal mode:
let &t_SI="\<Esc>[6 q" let &t_SR="\<Esc>[4 q" let &t_EI="\<Esc>[0 q"
'ttimeoutlen' has a high enough setting, there's a noticeable delay when leaving Insert mode, because you type Escape and Vim waits to see if it was the beginning of an
<Esc>[0 q sequence. It waits
'ttimeoutlen' milliseconds before deciding the
<Esc> was an actual Escape keypress.
I usually keep
'ttimeoutlen' set at 5, so it's not really noticeable. But I was also curious to try a "sledgehammer" workaround:
inoremap <Esc> <Esc><Esc>
and it works. Even more interesting is this works as well:
inoremap <Esc> <Esc>
I guess because Vim knows the right-hand-side of a mapping is the result of a keypress, not an input keycode, so it doesn't apply
'ttimeoutlen' (but would apply
'timoutlen' if you had other
imaps that started with
It seems a little weird, but I'm having a hard time thinking of any downside this approach could have. I plan on keeping my
'ttimeoutlen' low anyway, but maybe this could shave a couple extra milliseconds off the delay? Not that I'll actually notice :P
Is there any reason not to do this? What could it break?
Or is there a better solution altogether that I've missed? I suspect the answer is to just leave
'ttimeoutlen' set to a low number and forget about it, but I am curious if anyone else has found different solutions.
I found a caveat to this approach. The
imap effects escaping from Insert and Replace modes, and you can do the same for Visual mode with
vmap, but none of these affects the timeout when canceling an
r command in Normal mode using Escape.
It still seems like a useful hack -- escaping from an
r command is a corner case -- but it's not a full solution.
Update-2: I found what this breaks. If you want to use a Meta/Alt key in an
inoremap <M-d> foo, the
inoremap <Esc> <Esc> breaks that functionality because
<M-d> consists of an Escape byte (
0x1b) followed by the D byte. To take it to the extreme, imagine you'd defined a mapping:
inoremap <M-d>d bar
<M-d>d in insert mode would end up deleting the current line! That's a corner case, but mapping Meta/Alt keys is not, so this is enough to convince me that
<Esc> to itself is a bad idea. It is, after all, a hack.
The above won't apply if your terminal runs in 8-bit mode, since Alt/Meta will be represented by the high-bit instead of a leading Esc byte, but on 7-bit terminals (gnome-terminal, alacritty, etc.) it does apply.