diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 96ebfe6293..85cb824389 100644 --- 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 index 1514c26558..4fcf1ad85a 100644 --- 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 index 4cd6b764ca..022091b06a 100644 --- 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.