Slight delay when switching modes in vim using tmux or screen

68

17

Switching to and from insert mode in Vim is no longer instantaneous since I use tmux. After pressing Esc in insert mode, it takes a noticeable amount of time to actually get out of insert mode. After pressing Esc and any other key afterwards the switch is immediate, and the command for the key pressed after Esc is executed. Any idea what might cause this?

The Vim configuration is not the problem as the delay does not occur when I run Vim outside tmux, so this is probably related to tmux somehow. I use gnome-terminal btw.

Also worth noting, it seems I can not define key bindings in tmux for Esc, my plan was to bind Esc to:

bind Escape send-keys ^[

Alas, it seems binding anything to Esc for tmux does not work. The same problem occurs in screen as well.

Ton van den Heuvel

Posted 2011-03-02T13:06:53.577

Reputation: 3 316

Answers

124

After plowing through the man pages it turns out tmux has an option for this. The following in ~/.tmux.conf fixes the delay problem:

 set -sg escape-time 0

You have to restart your tmux server or reload your config for this to take effect. To do this, issue source-file ~/.tmux.conf from the tmux prompt.

Ton van den Heuvel

Posted 2011-03-02T13:06:53.577

Reputation: 3 316

1This makes me wish I could give you 10 upvotes. Found this after an hour of battling timeouts in vim. Thank you! – malvim – 2014-07-11T14:30:01.063

This doesn't work for me. I even killed the server and restarted, but the delay in vim is still there. I'm using tmux 1.9-6 (in debian testing). – FrontierPsycho – 2014-12-10T14:51:08.493

It might be vim's own timeoutlen option. Reducing that from the default 1000 to 100 improved things a lot. – FrontierPsycho – 2014-12-10T15:03:15.063

@MarkZar, which version of tmux are you using? – Ton van den Heuvel – 2015-12-01T16:00:45.790

@TonvandenHeuvel It worked after I rebooted my PC, I don't know why it needs a restart, but any way it works. Now working with vim in tmux is like a joyful journey, thanks! – Searene – 2015-12-02T07:01:21.303

@Searene That is probably because you had the tmux daemon running, it needs to be restarted for any settings changes to take effect. – Ton van den Heuvel – 2016-01-29T20:29:47.673

@TonvandenHeuvel You changed my life!!! Thank you!!! – PiersyP – 2016-02-12T13:28:28.053

thanks! I never realised this could be fixed and it was driving me crazy, this is fantastic!! – the_velour_fog – 2016-02-15T05:10:28.637

This setting works with the vim plugin airline (or other plugins), but at first may look like it hasn't worked. I set this and killed the tmux server, and tested it. airline still takes about half a second to update the screen from showing INSERT to NORMAL, so I thought it wasn't working and went down a rabbit hole. After actually trying commands during that split second where it still showed INSERT, I realized this setting worked, and I was actually in command mode. – user1902689 – 2018-11-12T03:16:35.840

... To fix the apparent delay from plugins I mentioned, consider in vimrc set ttimeoutlen=0 or maybe =10. See https://stackoverflow.com/questions/15550100/exit-visual-mode-without-delay/15550436#15550436

– user1902689 – 2018-11-12T03:23:46.883

Funny, I never encountered this problem because I don't use esc in vim, I use ^[ always. It's a quicker movement than reaching for the esc key. – Michael Brown – 2019-08-28T16:29:36.793

1@MichaelBrown, I do as well, and still hit this problem. It should not matter actually, because the same key code is sent to the terminal emulator regardless of whether you press escape or ^[. – Ton van den Heuvel – 2019-08-29T09:17:48.317

2Where did you find this? I can't find escape-time anywhere in man tmux, and the command doesn't work for me. – djeikyb – 2011-04-05T15:41:48.793

I suspect is is only available in the development version. You can get it here: https://github.com/ThomasAdam/tmux

– Ton van den Heuvel – 2011-04-05T16:15:27.857

I love everything about you for this answer. This just solved an obscure emacs problem for me and now I can go to bed finally! – Bo Jeanes – 2012-08-19T05:13:25.823

5I had to use tmux kill-server before this setting worked for me. Thanks! – Sam – 2013-09-08T15:46:22.010

4

I had a different but similar issue that I was trying to solve when I found this page, so I'll post that here in case it's helpful to anyone else who is in search of this answer and finds this page in the same way.

Problem: vi mode in bash has a delay when switching from insert mode to command mode

Solution: In your ~/.inputrc file, add set keyseq-timeout n where n is some low value greater than 0. n defaults to 500ms, which is what causes the delay. See documentation here.

Also, if you want to be able to tell which mode you're in, check out Dylan Cali's fork of bash.

Kvass

Posted 2011-03-02T13:06:53.577

Reputation: 181

that is very helpful, i set it to 0.01 and now its pleasingly much more faster. thanks! – None – 2017-05-17T07:28:17.003

It could also be appended into /etc/inputrc to make it available for all users. – None – 2017-05-17T08:27:20.357

1

As the title mentions Screen, here is the solution to fix the behaviour of Escape key within GNU Screen. (Taken from here.)

Add

maptimeout 5

to .screenrc config file.

Twonky

Posted 2011-03-02T13:06:53.577

Reputation: 111

1

It sounds like you are using a mapping that starts with ESC. When you press the ESC, vim has to wait to see if the next key is the one in the mapping. If it is not, it can immediately continue.

The vim configuration can be terminal dependent, so the fact that it does not happen outside of tmux does not mean much. Vim can query the $TERM environment variable and choose different configuration depending on its value.

Since gnome-terminal uses, AFAIK, xterm as the value of the $TERM variable, and tmux uses screen, I would look through all your vim configuration files for settings that are only used is the $TERM variable is equal to screen. My guess is that some vim config file on your system sets mappings for handling of arrow keys (those start with the ESC character) when the terminal is screen.

You can test it by temporarily changing the $TERM variable in tmux before starting vim. If your shell is bash, call vim as

TERM=xterm vim

in tmux and see if the problem persists. You sould not use that as a fix, though, since there may be differences between the terminal capabilities of tmux and xterm, and you may run into some problems.

Jan Hlavacek

Posted 2011-03-02T13:06:53.577

Reputation: 1 175

Some good pointers here. I do use bash, but unfortunately TERM=xterm vim did not fix the problem. I'll have to dig a little deeper. – Ton van den Heuvel – 2011-03-02T21:13:30.673