neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

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:
Msrc/nvim/buffer.c | 13+++++++++++++
Msrc/nvim/window.c | 4++--
Mtest/old/testdir/test_filetype.vim | 28++++++++++++++++++++++++++++
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.