patch 9.1.1323: b:undo_ftplugin not executed when re-using buffer
Problem: b:undo_ftplugin not executed when re-using buffer
(archy3)
Solution: explicitly execute b:undo_ftplugin in buflist_new() when
re-using the current buffer
fixes: #17113
closes: #17133
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/buffer.c b/src/buffer.c
index eed3e8d..0624f9d 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -72,6 +72,20 @@
static int top_file_num = 1; // highest file number
static garray_T buf_reuse = GA_EMPTY; // file numbers to recycle
+ static void
+trigger_undo_ftplugin(buf_T *buf, win_T *win)
+{
+ window_layout_lock();
+ buf->b_locked++;
+ win->w_locked = TRUE;
+ // b:undo_ftplugin may be set, undo it
+ do_cmdline_cmd((char_u*)"if exists('b:undo_ftplugin') | :legacy :exe \
+ b:undo_ftplugin | endif");
+ buf->b_locked--;
+ win->w_locked = FALSE;
+ window_layout_unlock();
+}
+
/*
* Calculate the percentage that `part` is of the `whole`.
*/
@@ -2206,6 +2220,7 @@
if ((flags & BLN_CURBUF) && curbuf_reusable())
{
buf = curbuf;
+ trigger_undo_ftplugin(buf, curwin);
// It's like this buffer is deleted. Watch out for autocommands that
// change curbuf! If that happens, allocate a new buffer anyway.
buf_freeall(buf, BFA_WIPE | BFA_DEL);
diff --git a/src/proto/window.pro b/src/proto/window.pro
index ccb69ef..d92a5af 100644
--- a/src/proto/window.pro
+++ b/src/proto/window.pro
@@ -1,4 +1,6 @@
/* window.c */
+void window_layout_lock(void);
+void window_layout_unlock(void);
int window_layout_locked(enum CMD_index cmd);
int check_can_set_curbuf_disabled(void);
int check_can_set_curbuf_forceit(int forceit);
diff --git a/src/testdir/test_filetype.vim b/src/testdir/test_filetype.vim
index 6ec55ae..1411559 100644
--- a/src/testdir/test_filetype.vim
+++ b/src/testdir/test_filetype.vim
@@ -1131,6 +1131,34 @@
close
endfunc
+func Test_undo_ftplugin_on_buffer_reuse()
+ filetype on
+
+ new
+ let b:undo_ftplugin = ":let g:var='exists'"
+ let g:bufnr = bufnr('%')
+ " no changes done to the buffer, so the buffer will be re-used
+ e $VIMRUNTIME/defaults.vim
+ call assert_equal(g:bufnr, bufnr('%'))
+ call assert_equal('exists', get(g:, 'var', 'fail'))
+ unlet! g:bufnr g:var
+
+ " try to wipe the buffer
+ enew
+ bw defaults.vim
+ let b:undo_ftplugin = ':bw'
+ call assert_fails(':e $VIMRUNTIME/defaults.vim', 'E937')
+
+ " try to split the window
+ enew
+ bw defaults.vim
+ let b:undo_ftplugin = ':sp $VIMRUNTIME/defaults.vim'
+ call assert_fails(':e $VIMRUNTIME/defaults.vim', 'E242')
+
+ bwipe!
+ filetype off
+endfunc
+
"""""""""""""""""""""""""""""""""""""""""""""""""
" Tests for specific extensions and filetypes.
" Keep sorted.
diff --git a/src/version.c b/src/version.c
index 4990e44..db77e45 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1323,
+/**/
1322,
/**/
1321,
diff --git a/src/window.c b/src/window.c
index 21f81e5..9ea6810 100644
--- a/src/window.c
+++ b/src/window.c
@@ -97,14 +97,14 @@
* make sure the previously selected window is still there.
* Must be matched with exactly one call to window_layout_unlock()!
*/
- static void
+ void
window_layout_lock(void)
{
++split_disallowed;
++close_disallowed;
}
- static void
+ void
window_layout_unlock(void)
{
--split_disallowed;