Minimal (not-)working example:
fun! Test()
let save=changenr()
call append(0, "THIS MUST BE UNDONE")
exe "undo ".save
endfun
command! -nargs=0 T :call Test()
Now open a file, insert some garbage (because "undo 0" won't work), then call the command :T
three times in a row.
On my machine at least, the first two times it works as expected (i.e. does nothing). But the last time the text THIS MUST BE UNDONE
is added to the buffer. On closer inspection, the value of save
used on the third execution is 2, while the two previous ones were both 1.
What happened? (Probably something mysterious related to undotree
)?
edit: while I'm at it, the fact that undo 0
does not work looks like a bug in itself. If I open a file and then do two modifications A and B, then undo 1
puts me after A, undo 2
puts me after A+B, but vim refuses to undo 0
to put me before A...
changenr()
which sometimes returns a value that you (and I) don't understand. Most of the time, it returns what you (and I) expect, but sometimes (when you go back to the root), instead of returning the change number of the current leaf, it returns the change number of the deepest leaf in the nearest "inactive branch". – saginaw Feb 12 '16 at 19:05save
variable contains a value which is too high, therefore yourexe "undo " . save
doesn't bring you back to the expected leaf and your textthis must be undone
is not removed. – saginaw Feb 12 '16 at 19:13undo
. The full function would be a:w
filter (make changes, save file, undo changes). @saginaw, also @mMontu's answer below: so far nothing new, I did write all thoseecho
lines in my function, (again MWE...) – Circonflexe Feb 15 '16 at 10:23changenr()
is not a reliable way to get this info, because when you undo, it doesn't return the current id, it returns this:After undo it is one less than the number of the undone change.
Maybe this link will help you a little: reddit.com/r/vim/comments/dszuz/… What this person says is that you must look in the dictionary returned byundotree()
. – saginaw Feb 16 '16 at 10:12