I'm trying to make semi-automatic parentheses work using vim-arpeggio and ultisnips. Everything works fine except the undo story. What I have now is this:
Arpeggioinoremap () ()<c-r>=UltiSnips#ExpandSnippet()<cr>
snippet () "paren" i ($1)$0 endsnippet
in my snippets file.
What this does is this: When I type
() in very close succession, arpeggio will trigger its mapping. The mapping reinserts the same characters, then enters the expression register where it calls the ultisnips expand function for its side effect of replacing the
() characters with the expanded snippet. I end up the the pointer between the parentheses.
I like this solution because it does not replace
() with anything when typed at normal speed. It's really only the simultaneously typed parens that get interpreted specially.
What does not work: undoing all of the mapping in one go. When I hit
u, I get back to the stage where
() is already entered. I was unable to find out how to make
undojoin work here.
UltiSnips#ExpandSnippet appears to work only in insert mode, so I cannot simply exit into normal mode and call
:undojoin | eval UltiSnips#ExpandSnippet(), at least so it appears.
EDIT: the problem is not related to the arpeggio plugin. the same necessity for a double undo appears with
inoremap () ()<c-r>=UltiSnips#ExpandSnippet()<cr>
EDIT 2: I mis-stated the problem above, sorry for that! What's actually the problem is this:
u the expansion is undone and the cursor remains between
(). The next undo again reproduces
() without change. I believe this is because Arpeggio and Ultisnips both set an undo mark so to speak. I would like to get rid of the need for undoing twice. The desired behavior is: press
u once, get
u again, undo the previous text edit that includes insertion of
context: I have several more parentheses pairs defined in a similar way, for instance
;' which on my keyboard amounts to hitting the single quotation mark and the key left of it together. This is then mapped to
'' by Arpeggio and further expanded to
'$1'$0 by Ultisnips. Pressing undo once here gives
'' and pressing it again, gives
;' which is undesired.
&undolevels, in a PR from 2015. For anyone who may be interested, this behavior may be reverted by deleting the 4 lines containing
&undolevels(lines 158,168,811,819) in snippet_manager.py.