When I press <Esc> from insert mode, it delayed about 1 sec, but if I just do <ctrl+c> instead it is fast.

I checked if there were mapping with escape with :verbose imap <Esc>, but I didn't find any.

  • 2
    Are you using neovim and/or tmux/screen at all? – Jay Dorsey Jan 4 '19 at 4:12
  • @JayDorsey - Thanks for the suggestion, that was indeed the issue for me as I was using neovim with tmux. Here is the solution. You should post it as one of the answers. – Plasty Grove Mar 14 at 2:12

There are two kinds of delay when you press <esc> in insert mode:

mapping delay

If you create some improper mapping that starts with <esc> :

inoremap <esc>x <esc>:echom "balabala"<cr>

When you press <esc>, vim will wait :h 'timeoutlen' milliseconds to see if next key is x.

You should avoid this kind of mapping in all modes, executes following commands to check if there exists this kind of mapping in all modes:

:verbose map <c-v><esc>
:verbose map! <c-v><esc>
               ^----------------press <c-v><esc> on your keyboard      

Mapping delay is controlled by :h 'timeout' and :h 'timeoutlen'.

keycode delay

Lots of terminal key code starts with <esc>, in my machine, <f5> is ^[[15~, ^[ is literal <esc>. When vim receives <esc> from your terminal, it waits :h 'ttimeoutlen' milliseconds to see if there are more characters in this key code, if there are none, then vim know it's truly a <esc>, otherwise it must be something else. This kind of delay is normal, you can change ttimeoutlen to reduce it.

Keycode delay is controlled by :h 'ttimeout' and :h 'ttimeoutlen' (not quite true, see :h 'ttimeout' for detail).

Common setting

set timeoutlen=1000
set ttimeoutlen=50

To be honest, i set ttimeoutlen to 5, 50 is still too much delay.

| improve this answer | |

The latency you experience is most probably the consequence of some plugin. See this post on how to track possible culprits :-)

In resume:

:profile start profile.log
:profile func *
:profile file *
" Go into insert mode, do some editing (to force updates)
" Exit Insert mode with ESC
:profile pause
:noautocmd qall!
| improve this answer | |
  • 1
    Or it could be timeout/ttimeout related... – D. Ben Knoble May 5 '18 at 19:27
  • Thank you so much for the profiling method, I didn t know about it is very useful. I gave it a try and found out lots of function call, so I remove my vimrc and give it another try, this second time the log is empty but my problem is still present – user1946989 May 7 '18 at 15:55
  • Can you provide more details for some more meaningful assistance? – JM. Marcastel May 16 '18 at 13:07
  • 1
    (continued) - what kind of files do you normally edit (i.e. could this be syntax related) - could you post a copy of you RC file - a listing of the plugins you use If profiling shows no lags, then the issue may be else where. The fact that Esc is slow and CTRL-C is fast implies most probably that a Vimscript is running. The CTRL-C is an immediate abort command that interrupts the vim script. If you experience the same problem on small and medium size files, then the culprit is probably I/O related. – JM. Marcastel May 16 '18 at 13:14

You might want to try changing ttimeoutlen.

As an example, Vim 8.0 introduces a $VIMRUNTIME/defaults.vim file which configures vim using more sane/modern settings. It contains these lines:

set ttimeout        " time out for key codes
set ttimeoutlen=100 " wait up to 100ms after Esc for special key

I personally have ttimeoutlen=0.

(Disclaimer: I don't fully understand everything that's going on with vim's timeout logic.)

| improve this answer | |
  • Thank for timeout suggestion I try setting it to 0 too, but it didn't solve my problem. – user1946989 May 7 '18 at 15:57
  • Thanks this solved my problem. – Wong Jia Hau Oct 24 at 10:58

You could try set noesckeys. Here are its docs:

Function keys that start with an <Esc> are recognized in Insert
mode.  When this option is off, the cursor and function keys cannot be
used in Insert mode if they start with an <Esc>.  The advantage of
this is that the single <Esc> is recognized immediately, instead of
after one second.  Instead of resetting this option, you might want to
try changing the values for 'timeoutlen' and 'ttimeoutlen'.  Note that
when 'esckeys' is off, you can still map anything, but the cursor keys
won't work by default.
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.