Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoiding timeoutlen for shortcuts #212

Closed
protist opened this issue Feb 22, 2021 · 10 comments
Closed

Avoiding timeoutlen for shortcuts #212

protist opened this issue Feb 22, 2021 · 10 comments

Comments

@protist
Copy link

protist commented Feb 22, 2021

Vanilla vim keybindings involving multiple keys (e.g. dd) don't seem to time out. I can press the first key d, wait several seconds, then press the second d.

However, it seems like the vim-unimpaired shortcuts (e.g. yow) respect timeoutlen. That is, I can't wait indefinitely between keys, but instead have to press each subsequent key within timeoutlen. Is that the expected behaviour? Is there or should there a way to avoid this timeout?

@systemmonkey42
Copy link

systemmonkey42 commented Feb 22, 2021

Commands like 'dd' are operators where the first 'd' represents a command and the second 'd' is the parameter. Timeoutlen does not apply between and operator and it's parameters.

'yow' on the other hand is a key binding, so timeoutlen applies. You can use set notimeout if you don't want the timeout to apply at all.

@protist
Copy link
Author

protist commented Feb 22, 2021

Thanks @systemmonkey42. I actually ran into this issue because my timeoutlen was too low. So apart from turning it off completely, it sounds like there's no real workaround then?

@systemmonkey42
Copy link

Not really no. A complete rewrite of vim unimpaired where [ and ] were operators might get you there, along with yo and many others but it wouldn't really solve anything

Incidentally I have timeout turn off permanently. Why do you find you need it?

@protist
Copy link
Author

protist commented Feb 22, 2021

Fair enough. Thanks again for that information. I'll just increase timeoutlen then.

I use this setting in combination with inoremap jk <Esc>, so I don't need to move my hands from the home row to press <Esc>. Instead, I just type jk quickly (within timeoutlen) to do the same thing. I keep timeoutlen relatively low "just in case" I need to type a literal jk… although I can't actually ever recall having to do so.

@protist protist closed this as completed Feb 22, 2021
@protist
Copy link
Author

protist commented Feb 22, 2021

Ahhh… I remember now why I like timeoutlen low. If I start typing :command, then change my mind and hit <Esc> to cancel, it's disconcerting to wait timeoutlen before it actually cancels. (I can actually continue with another command, but it's just a bit odd to see it sitting there still.)

@systemmonkey42
Copy link

systemmonkey42 commented Feb 22, 2021

Ah, the old jk for Esc. I've used that in the past but could never get used to it.

The problem with Esc hanging around when leaving insert mode, or while typing a command is the old "mappings starting with escape" (newbie?) mistake.

Eg,

The command:

map ^[[P [somefunction]

causes vim to treat "escape" as the beginning of a key mapping (which it is). Any time you press escape, it must wait timeoutlen to determine if you are going to complete the mapping...

On the other hand;
set <F35>=^[[P
Followed by
map <F35> [somefunction]
causes vim to treat the sequence <escape>[P as a "terminal code" and thus ttimeoutlen is used.

Essentially, If you, (or a plugin you've installed) has created a mapping starting with an escape it creates this problem.

If you create a Terminal code (I use unused function keys because vim understands up to <F35>), it treats it as a terminal code.

Once you have NO mappings starting with Esc, pressing Esc on its own is no longer subject to timeoutlen.

Try
:set termcap
To see all the existing terminal codes, and how many are free to be redefined as needed.

EDIT: A bunch of < and > disappeared due to bad juju

@tpope
Copy link
Owner

tpope commented Feb 22, 2021

For posterity, this is what I use:

setglobal timeoutlen=1200
setglobal ttimeoutlen=50

One second is a tad too tight for me. Bump to 1.2 seconds is adequate. Your mileage may vary.

The timeout for escape can be set separately with 'ttimeoutlen'.

@protist
Copy link
Author

protist commented Mar 2, 2021

The problem with Esc hanging around when leaving insert mode, or while typing a command is the old "mappings starting with escape" (newbie?) mistake.

Huh, I had never heard of that before. Thanks @systemmonkey42! I had a look at :map and :imap and couldn't find any reference to \[ in there however, so does this mean there aren't any key mappings starting with Esc?

@systemmonkey42
Copy link

Huh, I had never heard of that before. Thanks @systemmonkey42! I had a look at :map and :imap and couldn't find any reference to \[ in there however, so does this mean there aren't any key mappings starting with Esc?

You will need to check the ttimeout and ttimeoutlen settings.

:set timeout?
timeout
:set timeoutlen?
timeoutlen=1000
:set ttimeout?
nottimeout
:set ttimeoutlen?
ttimeoutlen=-1

With this default configuration, pressing escape at any time triggers the 1000ms timeoutlen pause before accepting escape.

As @tpope mentioned, consider using

setglobal timeout timeoutlen=1200
setglobal ttimeout ttimeoutlen=50

With ttimeoutlen=50, pressing escape will only wait 50ms for additional characters, unless vim has been told to expect a MAPPING starting with escape.

Eg, press : and type something, pressing Esc should exit command mode in 50ms

Create a mapping starting with Esc...

:exe "cmap \<Esc>p mycmd"

(The "exe" wrapper allows vim to expand \<x> codes before executing commands. Less messy than typing Ctrl-V and littering your config with escape codes.)

Now press : and type something, then press Esc. Vim now goes back to waiting 1000ms before accepting the escape because the escape could be the beginning of a terminal code OR a mapping.

@protist
Copy link
Author

protist commented Mar 3, 2021

@systemmonkey42 sorry I should have been clearer. I indeed do have those settings you recommend.

:set timeout?
  timeout
:set timeoutlen?
  timeoutlen=1000
:set ttimeout?
  timeout
:set ttimeoutlen?
  ttimeoutlen=50

But I still experience the 1000 ms delay when pressing Esc in command/insert mode. I don't think I have any mappings starting with Esc though, at least according to :map and :imap, which don't contain \[.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants