Undo is nice to have in Vim. But sometimes, at a known good point, I want to erase my undo history - to be able to use u to undo individual changes, but only back to a certain point. (For instance, this might be when I last committed.)

One way to accomplish this would be to close and reopen the file - the undo history starts clean at that point. But that's a hassle.

In the past, I accomplished this with :edit!. But in Vim 7.3, that doesn't discard the undo history.

Is there another way to do this, apart from closing the file?

link|improve this question

62% accept rate
so you actually just want to restore the state of the file as it was on your last commit? you want essentially just remap the 'u' key to something like git checkout -f file or hg rollback file? – akira Nov 24 '10 at 18:34
@akira - no, I want to be able to use u to undo individual changes, but not past the point where I last committed. Exactly as if, every time I committed, I closed the file and re-opened it. Which is what :edit! used to do - it was like closing the file and reopening it. This doesn't HAVE to be tied to a commit point, that's just the time when I'd most frequently want it. – Nathan Long Nov 24 '10 at 20:08
ah, that makes the problem much clearer. you should change your question a bit. – akira Nov 24 '10 at 20:24
@akira - thanks, I updated it. – Nathan Long Nov 24 '10 at 20:32
feedback

4 Answers

Probably:

:let old_ul=&ul
:set ul=-1
:let &ul=old_ul
:unlet old_ul

('ul' is alias for 'undolevels').

link|improve this answer
This works! Now I'm trying to make a single command do that - preferably :edit!. As a start, I've made a function called ClearUndos() with the commands you listed, but calling it doesn't seem to do anything, whereas doing the commands individually does... – Nathan Long Nov 24 '10 at 20:25
2  
:command -nargs=0 Reset let old_ul=&ul | set ul=-1 | e! | let &ul = old_ul | unlet old_ul – Benoit Nov 24 '10 at 21:38
is that meant to be the contents of the function? It's not working for me, but maybe I misunderstood. Also - maybe move this to its own answer? – Nathan Long Nov 29 '10 at 13:32
Maybe you cannot put raw | in a command content. Then create a function that does what I told in my answer, and set the command to call thefunction(). – Benoit Nov 29 '10 at 13:36
feedback

Benoit's function didn't work for me, but I found something similar in the vim manual, here:

http://www.polarhome.com/vim/manual/v73/undo.html#undo-remarks

I slapped it into a function, added to my vimrc and it seems to be working fine on vim 7.3:

" A function to clear the undo history
function! <SID>ForgetUndo()
    let old_undolevels = &undolevels
    set undolevels=-1
    exe "normal a \<BS>\<Esc>"
    let &undolevels = old_undolevels
    unlet old_undolevels
endfunction
command -nargs=0 ClearUndo call <SID>ForgetUndo()
link|improve this answer
feedback

In a script:

function! <SID>ForgetUndo
     let old_ul = &ul
     set ul=-1
     let &ul = old_ul
     unlet old_ul
endfunction
command -nargs=0 Reset call <SID>ForgetUndo()

Then use :Reset to call it.

link|improve this answer
Your function definition line needs () at the end. – Nathan Long Nov 29 '10 at 17:13
This is odd - running those commands individually works fine, and echoing the values throughout the function shows that they are set and unset appropriately. But running the function doesn't reset my undo history - afterwards, I can still undo multiple times. Maybe the set ul= command only affects a local variable until the script exits, and since we change it back before the script exits, it never affect the environment? Did you test this function and have it work - meaning, is there something odd about my setup? – Nathan Long Nov 29 '10 at 17:15
feedback
:set undoreload=0

should do what you're asking for.

link|improve this answer
feedback

Your Answer

 
or
required, but never shown

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