4

I have two remaps in my .vimrc for the insert mode:

inoremap jk <ESC>
inoremap {<CR> {<CR>}

The first remap should have a short timeoutlen, whereas the latter should have no timeout at all. Reason: I need a timeout for the first remap, as jk might be used as regular characters. The latter on the other hand is code completion, where a timeout makes no sense.

Is it possible to assign different timeoutlen's for different remaps? Thanks & BR

earthling
  • 620
  • 6
  • 20
  • https://stackoverflow.com/questions/26829086/key-specific-timeoutlen-in-vim . Let me know if this helps – dlmeetei Feb 19 '20 at 13:04
  • @dlmeetei It does not, as both of my remaps are in insert mode. Your link would only help, if the other command is outside the insert mode. On a side note: I have already been using autocmd to reduce the timeout in insert mode, exactly as in your link. However the new remap for the code completion makes this void. Thank you! – earthling Feb 19 '20 at 13:16
  • Ok, I believe they are also in insert mode. Will take a close look – dlmeetei Feb 19 '20 at 13:41
  • `:h map-` – Matt Feb 19 '20 at 13:41
  • @Matt That is almost it! I played with it for a while, but it seems that `` only works, if a single key is remapped. `inoremap { {}` does not work, whereas `inoremap { {}` works as desired. However I did not find a solution, that applies `` to multiple characters. More suggestions are welcome. Thanks. – earthling Feb 19 '20 at 14:28

1 Answers1

3

One way to extend the timeout of your second mapping is to actually only map <CR> and then use an expression to check that it's being typed after a { character.

The behavior is somewhat different from a two-character mapping in that the mapping will also work if you're typing a <CR> after a { that was already there, which might be acceptable to you (or might even be exactly what you wanted.)

Since you're using an expression to do checks, you can do additional checks such as only applying the mapping if you're typing the <CR> at the end of a line (so you avoid it if you're using it to split an existing long line.)

A possible implementation of that would be:

inoremap <expr> <CR>
    \ col('.') ==# col('$')
    \ && getline('.')[col('.')-2] ==# '{'
    \ ? "\<CR>}\<C-O>O"
    \ : "\<CR>"

We're using a ternary operator here to produce a different output based on the condition holding or not. If it doesn't, we simply map back to the keystroke itself, so it keeps working as it usually does in all other contexts.

For the part that inserts a closing curly brace, I also added a CTRL-O O to the end, so after inserting the brace, it will add a new line before it and leave the cursor in an indented column inside the block. I hope you'll find this helpful, but feel free to disregard that part if it's not really what you had in mind.

filbranden
  • 8,522
  • 2
  • 16
  • 32