Steps to reproduce:
1. Put this in .vimrc:
set nocompatible hidden backspace=indent,eol,start
set history=5000 undofile undolevels=1000 undoreload=10000
filetype plugin on
syntax enable
function! BreakStuff()
let win = winnr()
windo if !&previewwindow | set foldmethod=manual | endif
execute win . "wincmd w"
endfunction
autocmd WinLeave * call BreakStuff()
2. Edit a Python file in vim. I'm using Python here just to have omnicompletion
that opens the preview window.
3. Insert the following:
import os
pass
4. Open a new line between those two lines, and type the key sequence
'os.<C-x><C-o><CR>test<Esc>'. This adds two lines - one with "os." plus an
omnicompletion result and a second line with just "test". It should also open
the preview window which triggers the WinLeave autocommand. At this point, the
buffer should look like this:
import os
os.EX_CANTCREAT
test
pass
5. Type 'u' in normal mode. Only the first of the two inserted lines is
removed. Now the buffer contains three lines:
import os
test
pass
When this happens in a buffer with a non-trivial undo tree, the extra line that
wasn't deleted stays in the buffer even after multiple undo commands. If the
buffer is saved at that point, the undo file's history is permanently broken.
I attached a patch that fixes the problem. In the code that opens the preview
window, I put "++no_u_sync" and "--no_u_sync" around the lines that may sync
undo. There's already a comment there stating "NOTE: Be very careful not to
sync undo!"
-Jake