Setting 'foldmethod' in a WinLeave autocommand can cause the undo state to
break in certain situations.
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
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
>From 38b84836104b5ab0efe67dc437fff2fbca62e4f0 Mon Sep 17 00:00:00 2001
From: Jacob Niehus <[email protected]>
Date: Sat, 24 Oct 2015 11:25:57 -0700
Subject: [PATCH] Fix undo breaking when preview menu opens
---
src/popupmnu.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/popupmnu.c b/src/popupmnu.c
index 68ee2d5..9276057 100644
--- a/src/popupmnu.c
+++ b/src/popupmnu.c
@@ -568,7 +568,9 @@ pum_set_selected(n, repeat)
if (p_pvh > 0 && p_pvh < g_do_tagpreview)
g_do_tagpreview = p_pvh;
++RedrawingDisabled;
+ ++no_u_sync;
resized = prepare_tagpreview(FALSE);
+ --no_u_sync;
--RedrawingDisabled;
g_do_tagpreview = 0;
@@ -659,7 +661,9 @@ pum_set_selected(n, repeat)
* redraw. */
if (resized)
{
+ ++no_u_sync;
win_enter(curwin_save, TRUE);
+ --no_u_sync;
update_topline();
}
@@ -670,7 +674,11 @@ pum_set_selected(n, repeat)
pum_do_redraw = FALSE;
if (!resized && win_valid(curwin_save))
+ {
+ ++no_u_sync;
win_enter(curwin_save, TRUE);
+ --no_u_sync;
+ }
/* May need to update the screen again when there are
* autocommands involved. */
--
2.4.2