These are the two lines of code responsible for inserting matching characters in my matching plugin

let s:cur_split = [s:cur_split[0], s:match[press] . s:cur_split[1]]
cal setline(".", join(s:cur_split, ""))

This is in a TextChangedI event

press is the character that was inserted

s:cur_split is a length 2 array holding the parts of the line that were before and after the cursor

s:match is a dictionary that maps a character to its match.

This works great, accept when I try to use macros. A macro won't trigger the event and the matching character is not inserted. Is there any simple way around this or is this just not the right way to go about achieving this functionality?

Edit: another related issues that I'll tack on here is that if I type No{<Esc>, I get


All the other lines don't copy the inserted character.


:help TextChanged has this:

Not triggered when there is typeahead or when an operator is pending.

Typeahead means the input buffer has keys about to be executed. A mapping (e.g. :nmap <F12> aTEXT<Esc>) fills it (and therefore, no TextChangedI events are fired for the TEXT here, neither), and macro playback is treated the same way as execution of a mapping.

I think that there are good implementation reasons for this behavior. Unfortunately, this means that using TextChangedI for your use case of inserting matching characters is fundamentally flawed. In order to support mappings and macros, you'd have to directly hook the matching characters (:imap <expr> ) ..., :imap <expr> ] ..., ...)

  • Ah, I see. For some reason I was under the impression that :map <expr> ... created static map by evaluating the expression once. What it actually is is waaay more useful. I'll rewrite my plugin using maps, thanks. – Mason Oct 26 '19 at 5:54
  • Yes, :map <expr> evaluates on each invocation. A static one-time evaluation would be `:execute 'map ...' . <expr> . '...' – Ingo Karkat Oct 26 '19 at 16:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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