commit 328640aed0ff43680e0d58a045ec3eca83f04571
parent 92596a37e721c5d4cf4327e9c5348b0355ec29d0
Author: zeertzjq <zeertzjq@outlook.com>
Date: Wed, 14 Jan 2026 09:37:53 +0800
vim-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: vim/vim#17113
closes: vim/vim#17133
https://github.com/vim/vim/commit/baa8c90cc0d214e036a3a7980d5cf95cae88a68d
Cherry-pick test_filetype.vim changes from patch 9.1.1325.
Co-authored-by: Christian Brabandt <cb@256bit.org>
Diffstat:
3 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
@@ -129,6 +129,18 @@ typedef enum {
kBffInitChangedtick = 2,
} BufFreeFlags;
+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("if exists('b:undo_ftplugin') | exe b:undo_ftplugin | endif");
+ buf->b_locked--;
+ win->w_locked = false;
+ window_layout_unlock();
+}
+
/// Calculate the percentage that `part` is of the `whole`.
int calc_percentage(int64_t part, int64_t whole)
{
@@ -1945,6 +1957,7 @@ buf_T *buflist_new(char *ffname_arg, char *sfname_arg, linenr_T lnum, int flags)
assert(curbuf != NULL);
buf = curbuf;
set_bufref(&bufref, buf);
+ 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/nvim/window.c b/src/nvim/window.c
@@ -117,13 +117,13 @@ static int close_disallowed = 0;
/// Used for autocommands that temporarily use another window and need to
/// make sure the previously selected window is still there.
/// Must be matched with exactly one call to window_layout_unlock()!
-static void window_layout_lock(void)
+void window_layout_lock(void)
{
split_disallowed++;
close_disallowed++;
}
-static void window_layout_unlock(void)
+void window_layout_unlock(void)
{
split_disallowed--;
close_disallowed--;
diff --git a/test/old/testdir/test_filetype.vim b/test/old/testdir/test_filetype.vim
@@ -1196,6 +1196,34 @@ func Test_filetype_indent_off()
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.