neovim

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

commit 7852993f4927c2d004d627bbe244dbbe09edb94f
parent 34b3bd1ac5758813743836b1bd559102191d57a6
Author: zeertzjq <zeertzjq@outlook.com>
Date:   Thu, 26 Feb 2026 21:30:44 +0800

vim-patch:9.2.0061: Not possible to know when a session will be loaded (#38071)

Problem:  Not possible to know when a session will be loaded.
Solution: Add the SessionLoadPre autocommand (Colin Kennedy).

fixes:  vim/vim#19084
closes: vim/vim#19306

https://github.com/vim/vim/commit/1c0d468d72e0220d4cb25936043ac35439a981b5

Co-authored-by: Colin Kennedy <colinvfx@gmail.com>
Diffstat:
Mruntime/doc/autocmd.txt | 3+++
Mruntime/doc/news.txt | 1+
Mruntime/doc/options.txt | 1+
Mruntime/doc/starting.txt | 4++--
Mruntime/lua/vim/_meta/api_keysets.lua | 1+
Mruntime/lua/vim/_meta/options.lua | 1+
Msrc/nvim/auevents.lua | 1+
Msrc/nvim/ex_session.c | 3+++
Mtest/old/testdir/test_autocmd.vim | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 78 insertions(+), 2 deletions(-)

diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt @@ -961,6 +961,9 @@ SafeState When nothing is pending, going to wait for the check more with `state()`, e.g. whether the screen was scrolled for messages. + *SessionLoadPre* +SessionLoadPre Before loading the session file created using + the |:mksession| command. *SessionLoadPost* SessionLoadPost After loading the session file created using the |:mksession| command. diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt @@ -240,6 +240,7 @@ EVENTS • Creating or updating a progress message with |nvim_echo()| triggers a |Progress| event. • |MarkSet| is triggered after a |mark| is set by the user (currently doesn't support implicit marks like |'[| or |'<|, …). +• |SessionLoadPre| is triggered before loading a |Session| file. • |TabClosedPre| is triggered before closing a |tabpage|. • New `terminator` parameter for |TermRequest| event. diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt @@ -2553,6 +2553,7 @@ A jump table for the options with a short description can be found at |Q_op|. |RemoteReply|, |SafeState|, |SessionLoadPost|, + |SessionLoadPre|, |SessionWritePost|, |ShellCmdPost|, |Signal|, diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt @@ -852,8 +852,8 @@ This saves the current Session, and starts off the command to load another. A session includes all tab pages, unless "tabpages" was removed from 'sessionoptions'. |tab-page| -The |SessionLoadPost| autocmd event is triggered after a session file is -loaded/sourced. +The |SessionLoadPre| autocmd event is triggered before a session file is +loaded/sourced and |SessionLoadPost| autocmd event is triggered after. *SessionLoad-variable* While the session file is loading, the SessionLoad global variable is set to 1. Plugins can use this to postpone some work until the SessionLoadPost event diff --git a/runtime/lua/vim/_meta/api_keysets.lua b/runtime/lua/vim/_meta/api_keysets.lua @@ -176,6 +176,7 @@ error('Cannot require a meta file') --- |'SafeState' --- |'SearchWrapped' --- |'SessionLoadPost' +--- |'SessionLoadPre' --- |'SessionWritePost' --- |'ShellCmdPost' --- |'ShellFilterPost' diff --git a/runtime/lua/vim/_meta/options.lua b/runtime/lua/vim/_meta/options.lua @@ -2231,6 +2231,7 @@ vim.go.ei = vim.go.eventignore --- `RemoteReply`, --- `SafeState`, --- `SessionLoadPost`, +--- `SessionLoadPre`, --- `SessionWritePost`, --- `ShellCmdPost`, --- `Signal`, diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua @@ -97,6 +97,7 @@ return { SafeState = false, -- going to wait for a character SearchWrapped = true, -- after the search wrapped around SessionLoadPost = false, -- after loading a session file + SessionLoadPre = false, -- before loading a session file SessionWritePost = false, -- after writing a session file ShellCmdPost = false, -- after ":!cmd" ShellFilterPost = true, -- after ":1,2!cmd", ":w !cmd", ":r !cmd". diff --git a/src/nvim/ex_session.c b/src/nvim/ex_session.c @@ -600,6 +600,9 @@ static int makeopens(FILE *fd, char *dirnow) // Begin by setting v:this_session, and then other sessionable variables. PUTLINE_FAIL("let v:this_session=expand(\"<sfile>:p\")"); + + PUTLINE_FAIL("doautoall SessionLoadPre"); + if (ssop_flags & kOptSsopFlagGlobals) { if (store_session_globals(fd) == FAIL) { return FAIL; diff --git a/test/old/testdir/test_autocmd.vim b/test/old/testdir/test_autocmd.vim @@ -1135,6 +1135,71 @@ func Test_BufEnter() only endfunc +func Test_autocmd_SessLoadPre() + tabnew + set noswapfile + mksession! Session.vim + + call assert_false(exists('g:session_loaded_var')) + + let content =<< trim [CODE] + set nocp noswapfile + + func! Assert(cond, msg) + if !a:cond + echomsg "ASSERT_FAIL: " .. a:msg + else + echomsg "ASSERT_OK: " .. a:msg + endif + endfunc + + func! OnSessionLoadPre() + call Assert(!exists('g:session_loaded_var'), + \ 'SessionLoadPre: var NOT set') + endfunc + au SessionLoadPre * call OnSessionLoadPre() + + func! OnSessionLoadPost() + call Assert(exists('g:session_loaded_var'), + \ 'SessionLoadPost: var IS set') + echomsg "SessionLoadPost DONE" + endfunc + au SessionLoadPost * call OnSessionLoadPost() + + func! WriteErrors() + call writefile([execute("messages")], "XerrorsPost") + endfunc + au VimLeave * call WriteErrors() + [CODE] + + call writefile(content, 'Xvimrc', 'D') + + call writefile( + \ ['let g:session_loaded_var = 1'], + \ 'Sessionx.vim', + \ 'b' + \ ) + + " --- Run child Vim --- + call system( + \ GetVimCommand('Xvimrc') + \ .. ' --headless --noplugins -S Session.vim -c cq' + \ ) + + call WaitForAssert({-> assert_true(filereadable('XerrorsPost'))}) + + let errors = join(readfile('XerrorsPost'), "\n") + call assert_notmatch('ASSERT_FAIL', errors) + call assert_match('ASSERT_OK: SessionLoadPre: var NOT set', errors) + call assert_match('ASSERT_OK: SessionLoadPost: var IS set', errors) + call assert_match('SessionLoadPost DONE', errors) + + set swapfile + for file in ['Session.vim', 'Sessionx.vim', 'XerrorsPost'] + call delete(file) + endfor +endfunc + " Closing a window might cause an endless loop " E814 for older Vims func Test_autocmd_bufwipe_in_SessLoadPost()