How to exit visual mode without a delay in Vim?

vim
21,802

Solution 1

Executing following command helped me:

set timeoutlen=1000 ttimeoutlen=0

see: http://www.johnhawthorn.com/2012/09/vi-escape-delays/.

Solution 2

As Ingo explained. Just thought I would post the solution: https://github.com/Greduan/dotfiles/blob/47f92e4db29d4ead778d877a85082b271de130ed/vim/vimrc.vim#L332-L346

Works pretty well. It's a little bit confusing for me as well, so I can't really explain, but the code explains itself pretty well.

The point is it works, it simply makes <Esc> work immediately even when on Terminal. I believe if you do have mappings set to <Esc> it'll give you time to do those as well. However I'm not sure.

EDIT

Studied a bit and I can now explain it. Basically, if you're not using a GUI (like MacVim) then when you enter insert mode the ttimeoutlen will be set to 0. Meaning that as soon as you click <Esc> that'll work. However once you're in normal mode then it'll set the ttimeoutlen to the number you prefer, letting you do mappings with <Esc>.

Perfect solution I think, since if you have mappings in insert mode it'll be using control or something like that.

EDIT 2

Here's the code:

set timeout " Do time out on mappings and others
set timeoutlen=2000 " Wait {num} ms before timing out a mapping

" When you’re pressing Escape to leave insert mode in the terminal, it will by
" default take a second or another keystroke to leave insert mode completely
" and update the statusline. This fixes that. I got this from:
" https://powerline.readthedocs.org/en/latest/tipstricks.html#vim
if !has('gui_running')
    set ttimeoutlen=10
    augroup FastEscape
        autocmd!
        au InsertEnter * set timeoutlen=0
        au InsertLeave * set timeoutlen=1000
    augroup END
endif

With time I've removed the condition that the GUI isn't running and it still works as far as I can tell.

Solution 3

A quick workaround is using <C-c> instead, but you probably want to fix the timeout on <Esc>, which is caused by a mapping that starts with <Esc>, which makes Vim wait for 'timeoutlen' to check whether the mapping is complete.

This does not necessarily need to be a "real" mapping; many terminal workarounds (e.g. to make certain keys work) advise to set up such a mapping. (Unfortunately, this is a difficult and complex issue.)

You can find the mapping via:

:verbose map <Esc>

Solution 4

I have no mapping bound to <ESC> globally or for Visual mode (calling :verbose vmap <ESC> gives no results) but there is still a significant delay when exiting Visual mode. Even on fresh installs with no vimrc the delay is present. Using <C-c> does exit visual mode without delay.

Since I don't like pressing <C-c> to exit any mode, I currently map <ESC> to <C-c> in visual mode. This exits visual mode using <ESC> without any delay.

:vmap <ESC> <C-c>

Or put the following line in your vimrc

vnoremap <ESC> <C-c>

This will not work if you do have global or visual mode mappings bound to <ESC>.

Share:
21,802
Ozkan
Author by

Ozkan

Improving and broadening my knowledge since 2010 in designing, developing and testing software. Experienced in OOP in C# .NET. Specialties: Message Queueing (RMQ, IBMMQ) Preferred Text Editor: Sublime Text.

Updated on July 09, 2022

Comments

  • Ozkan
    Ozkan almost 2 years

    In Vim, when in Visual mode, I have to press Esc twice to exit it and turn off the selection. After one press of Esc I have to wait 2 seconds for the selection to turn off.

    What can I do to exit Visual mode immediately when Esc is pressed?

  • Ozkan
    Ozkan about 11 years
    when doing <C-c> there is no delay indeed. But I want to use ESC. I get No mapping found
  • Ingo Karkat
    Ingo Karkat about 11 years
    Hm, it may also be caused by one of the :set t_... settings, but I don't know how to troubleshoot that.
  • mMontu
    mMontu over 10 years
    I wonder why someone has downvoted this answer, as it works fine. I found useful the setting for tmux on the reference: set -sg escape-time 0
  • Fred Deschenes
    Fred Deschenes about 9 years
    @mMontu Omg thank you, I was getting mad trying to figure out why the setting wasn't being used in vim, I had no idea tmux had its own separate setting!
  • Paul
    Paul over 8 years
    for me this seemed to manifest itself while using tmux. The mMontu comment pointed me to the link, which worked wonders
  • etal
    etal over 7 years
    what the difference between the 2000ms from the second line and the 1000ms? Thanks!
  • greduan
    greduan over 7 years
    @etal not sure honestly. I did this so long ago. :P They're the same option so they could probably be set the same. Reading :h timeout, :h timeoutlen and :h ttimeoutlen should help you figure it out though. I'm pretty sure the reason is simply a workaround for quirks created by the difference between how GUI version of Vim handles this and how the terminal version of Vim handles this. Hope that helps. :)
  • Sebastian Blask
    Sebastian Blask about 7 years
    This does not work when you have any mappings that start with <Esc>, you will still have the delay. In my case I have Alt and j and k mapped to move lines and they translate to <Esc>j and <Esc>k. Really not obvious. stackoverflow.com/a/15550787/520061 helped in this case.
  • Quasímodo
    Quasímodo about 4 years
    This also removed the delay when doing repeated insert (e.g. 2itext<Esc>)!