Update 2015-06-28: I fixed a small bug, and released this as a
plugin. The plugin code is slightly
better, in that it warns again after moving the cursor; I recommend you use the
plugin.
The answer from superjer works great, but has the unfortunate side-effect that you can only undo changes from the last Vim session, and not all previous Vim sessions.
This is because wundo
overwrites the undo file; it's not merged. As far as I know, there is no way to fix this.
So here's my alternative solution, it will show a big red warning message when you're undoing changes from the undo file.
This is similar to Ingo Karkat's answer, but it doesn't require an external plugin and has some subtle differences (displays warning instead of beep, doesn't require you to press u
twice).
Note this only modifies the u
and <C-r>
binds, and not the U
, :undo
, and :redo
commands.
" Use the undo file
set undofile
" When loading a file, store the curent undo sequence
augroup undo
autocmd!
autocmd BufReadPost,BufCreate,BufNewFile * let b:undo_saved = undotree()['seq_cur'] | let b:undo_warned = 0
augroup end
" Remap the keys
nnoremap u :call Undo()<Cr>u
nnoremap <C-r> <C-r>:call Redo()<Cr>
fun! Undo()
" Don't do anything if we can't modify the buffer or there's no filename
if !&l:modifiable || expand('%') == '' | return | endif
" Warn if the current undo sequence is lower (older) than whatever it was
" when opening the file
if !b:undo_warned && undotree()['seq_cur'] <= b:undo_saved
let b:undo_warned = 1
echohl ErrorMsg | echo 'WARNING! Using undofile!' | echohl None
sleep 1
endif
endfun
fun! Redo()
" Don't do anything if we can't modify the buffer or there's no filename
if !&l:modifiable || expand('%') == '' | return | endif
" Reset the warning flag
if &l:modifiable && b:undo_warned && undotree()['seq_cur'] >= b:undo_saved
let b:undo_warned = 0
endif
endfun