6

I have the following bindings in my ~/.vimrc to make it easier to "disengage" some of my insert-mode key-bindings.

Here's an example. ` for <Nop> and `` to enter a literal `.

inoremap ` <Nop>
inoremap `` `

For the most part this works pretty well. However, when inserting ` normally and then allowing the possible-completion to time out I can't enter `` for a literal ` anymore. Nothing happens. I can insert other characters like a just fine though. (I tested this with only the above file as my .vimrc)

However, if instead of <Nop> I use a different do-nothing command combination like <esc>a, then I don't see this behavior at all.

inoremap ` <esc>a
inoremap `` `

With this configuration, I can type a `, wait for it to time out, and then type `` ... and the result will be a `.

Why does the first example have this odd behavior?

1

1 Answer 1

6

hardenedapple has given an excellent explanation for this, and a proposed fix, but I will describe what is happening in more non-technical terms:

Once a vim mapping "times out," vim does not like to wait again. Instead, at any point after timeout, it will always immediately expand the longest complete mapping entered up to that point. Here is another example that displays this behavior:

nnoremap aaaa :echom 'aaaa mapping'<CR>
nnoremap bb :echom 'just to ensure timeout matters'<CR>
nmap b aaa

Once b times out, vim decides on aaa (i.e., append aa) and will not wait to see if aaaa would have been possible.

In the original <nop> case this is a bigger problem because <nop> expands to '' (i.e., empty string). So, after timeout, when pressing ` vim gets into an unfortunate loop; every ` is consumed and expanded to '' empty string immediately, but the mapping does not end. Entering something other than ` can end the mapping. It nearly impossible to press `` quickly enough.

Whether or not this is a bug is a matter of taste. It appears to be a problem only when dealing with maps to <nop>. Bram has stated that there is not sufficient justification for a change. However, it is possible that he hasn't been made aware of this particular case.

In support of this being called a "bug," there are very few "do nothing" commands in insert mode- the most benign map I know of is <c-g><c-g> (really there are many nonsense commands starting with <c-g>), which actually causes beeps, if beeps are enabled. An alternative fix to vim may be to introduce a new i_<c-g>-prefix mapping which is documented to do nothing and cause no beeps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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