Using Vim's persistent undo?

39,052

Solution 1

Put this in your .vimrc to create an undodir if it doesn't exist and enable persistent undo. Tested on both Windows and Linux.

" Put plugins and dictionaries in this dir (also on Windows)
let vimDir = '$HOME/.vim'

if stridx(&runtimepath, expand(vimDir)) == -1
  " vimDir is not on runtimepath, add it
  let &runtimepath.=','.vimDir
endif

" Keep undo history across sessions by storing it in a file
if has('persistent_undo')
    let myUndoDir = expand(vimDir . '/undodir')
    " Create dirs
    call system('mkdir ' . vimDir)
    call system('mkdir ' . myUndoDir)
    let &undodir = myUndoDir
    set undofile
endif

Solution 2

I tried this in my _gvimrc:

" Persistent undo
try 
    set undodir=C:\vim\undodir
    set undofile
catch
endtry

It started working as advertised when I deleted the try-catch bracket, thus:

" Persistent undo
set undodir=C:\vim\undodir
set undofile

I had to create the directory.

Solution 3

I suppose $HOME doesn't work as advertised.

On my system, :echo $HOME shows H:\, but : e $HOME/ says: ~/ invalid filename.

You could try with an absolute path to see whether it cures it

Solution 4

This now works as expected: file.txt open in a Vim 7.4 buffer on Windows 7, :setlocal undofile, then save a change to the buffer, and the undofile .file.txt.un~ is created alongside because :set undodir? reports that "undodir=." by default - ie no need to specify this manually. You can also :set undofile in a modeline.

Share:
39,052

Related videos on Youtube

duckworthd
Author by

duckworthd

Updated on July 08, 2022

Comments

  • duckworthd
    duckworthd almost 2 years

    One of the new features in Vim 7.3 is 'persistent undo', which allows for the undotree to be saved to a file when exiting a buffer.

    Unfortunately, I haven't quite been able to get it properly enabled, or I must be using it wrong. Here's what I've tried so far:

    I added the following to ~/.vimrc

    set undofile                " Save undos after file closes
    set undodir=$HOME/.vim/undo " where to save undo histories
    set undolevels=1000         " How many undos
    set undoreload=10000        " number of lines to save for undo
    

    After this, I supposedly should be able to open any file, edit it, then save-close it, and when I open it again I should be able to undo/redo as if I'd never left. Unfortunately, this doesn't seem to be the case, as no undofile is ever written.

    Notes:

    1. I'm on Win 7 using Vim 7.3 from the Vim without cream project. Persistent undo is baked-in.

    2. $HOME/.vim/undo exists on my file system

    • puk
      puk over 12 years
      Just to stress, point 2) is very important. Vim will not create the directory for you and persistent undo will not work until you mkdir ~/.vim/undo
    • Ciro Santilli OurBigBook.com
      Ciro Santilli OurBigBook.com over 10 years
      +1. Sorry, on Linux it works... thanks for telling me about it!
    • naiveai
      naiveai over 5 years
      For any future visitors to this question: Do NOT put quotes around the value of undodir! I got stuck on this problem for a while - use an absolute paht, without quotes around it.
  • duckworthd
    duckworthd about 13 years
    I could |:echo $HOME| and |:e $HOME/| without problems, but I tried changing things anyways. It seemed to work at times, and not at others. Particularly, it never saves backups when I'm editing my ~/.vimrc file.
  • slawek
    slawek over 10 years
    On windows 7 I'm using $TEMP. When I look set undodir? it shows ~/AppData/Local/Temp. Undo file is persisted and loads itself correctly. Maybe $TEMP will be more reliable?
  • Kyle Strand
    Kyle Strand about 9 years
    This may be preferable for creating the directory: :silent call system('mkdir -p ' . &undodir)
  • Kyle Strand
    Kyle Strand about 9 years
    I use & because I set the undodir rather than letting it. (In my mind this distinction between let and set is one of the many, many, many mind-bogglingly awful "features" of Vimscript, but YMMV.)
  • Matthias Braun
    Matthias Braun about 9 years
    Thanks Kyle, it's a good idea to create .vim if it doesn't exist. Unfortunately the -p flag doesn't exist on Windows so I edited the answer to call mkdir twice to ensure Windows compatibility.
  • Kyle Strand
    Kyle Strand about 9 years
    Ah. My primary reason for using the -p flag is actually to avoid an error when the directory exists. I have my command inside an if has('win32') block, so I just use mkdir without -p on Windows.
  • nelstrom
    nelstrom almost 7 years
    Why not use mkdir()? Then this can become: call mkdir(myUndoDir, 'p'), which behaves like mkdir -p.
  • Matthias Braun
    Matthias Braun almost 7 years
    Thanks for the hint, @nelstrom. call mkdir(myUndoDir, 'p') gives me an error (probably because the directory already exists): Cannot create directory: C:\Users\me\.vim\undodir
  • nelstrom
    nelstrom almost 7 years
    @MatthiasBraun I just realised that the documentation for mkdir() is different in Vim and Neovim. When I suggested this I had been looking at Neovim's documentation, which states that: "If you try to create an existing directory with {path} set to "p" mkdir() will silently exit.". Apparently this is not the case in Vim. My bad!
  • Kyle Strand
    Kyle Strand over 6 years
    @nelstrom That's an excellent modification. Thanks. (The answer to your "why not" question is "because I didn't know that existed.")
  • Arelav
    Arelav almost 6 years
    if has('persistent_undo')
  • Arelav
    Arelav almost 6 years
    silent !mkdir ~/.config/nvim/backups > /dev/null 2>&1
  • Arelav
    Arelav almost 6 years
    set undodir=~/.config/nvim/backups
  • Arelav
    Arelav almost 6 years
    endif " adding commented message to increase message length