From 59597316a60b11e0cde262a9b55b3e326a754e29 Mon Sep 17 00:00:00 2001 From: Erdiansyah Date: Sat, 8 Aug 2026 00:09:22 +0800 Subject: [PATCH] fix(cwd): :bcd lost by nvim_win_set_buf, nvim_open_win #41218 Problem: :bcd (buffer-local directory) is not preserved after `nvim_open_win` or `nvim_win_set_buf` Analysis: set_curbuf() ends with update_cwd(), which falls back to os_chdir(globaldir) when the target buffer has no b_localdir. Solution: Pass kCtxKeepCwd to ctx_switch(). --- src/nvim/window.c | 2 +- test/functional/ex_cmds/cd_spec.lua | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/nvim/window.c b/src/nvim/window.c index 3c2874def24..37662d3b356 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -803,7 +803,7 @@ void win_set_buf(win_T *win, buf_T *buf, Error *err) bool win_ok; TRY_WRAP(err, { - win_ok = ctx_switch(&switchwin, win, tab, NULL, kCtxNoDisplay); + win_ok = ctx_switch(&switchwin, win, tab, NULL, kCtxNoDisplay | kCtxKeepCwd); if (win_ok) { const int save_acd = p_acd; if (!switchwin.cs_same_win) { diff --git a/test/functional/ex_cmds/cd_spec.lua b/test/functional/ex_cmds/cd_spec.lua index 245b58bbcf7..59ddd678709 100644 --- a/test/functional/ex_cmds/cd_spec.lua +++ b/test/functional/ex_cmds/cd_spec.lua @@ -562,6 +562,29 @@ describe('cd during temp context-switch', function() cd_in_buf_call(hidden, 'tcd', tabdir) eq({ 1, tabdir, tabdir }, { tlwd(), tcwd(), cwd() }) end) + + it("nvim_open_win / nvim_win_set_buf keep the caller's cwd", function() + local bufdir = join(startdir, directories.buffer) + command('bcd ' .. bufdir) + eq(bufdir, cwd()) + + -- A transient switch to a scratch float must not reset the caller's cwd. + local float = call('nvim_open_win', call('nvim_create_buf', true, true), false, { + relative = 'editor', + width = 20, + height = 5, + row = 1, + col = 1, + }) + eq(bufdir, cwd()) + + call('nvim_win_set_buf', float, call('nvim_create_buf', true, true)) + eq(bufdir, cwd()) + + call('nvim_win_close', float, true) + eq(bufdir, cwd()) + command('bcd!') + end) end) -- Test legal parameters for 'getcwd' and 'haslocaldir'