From 8b0f33a1abe70266119ad7dd97fda007e86f09f5 Mon Sep 17 00:00:00 2001 From: Barrett Ruth <62671086+barrettruth@users.noreply.github.com> Date: Thu, 6 Aug 2026 02:39:53 -0500 Subject: [PATCH] feat(dir): set buffer-local CWD #41174 --- runtime/doc/plugins.txt | 4 ++++ runtime/lua/nvim/dir/fs.lua | 10 +++++++++- test/functional/plugin/dir_spec.lua | 7 ++++++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/runtime/doc/plugins.txt b/runtime/doc/plugins.txt index eeb9bfd5fa..0d4f05befe 100644 --- a/runtime/doc/plugins.txt +++ b/runtime/doc/plugins.txt @@ -76,6 +76,10 @@ The listing is read-only and does not modify the filesystem. Opening an entry leaves the |alternate-file| on the buffer you came from, so that |CTRL-^| returns to it rather than to the listing. +The listed directory is the buffer's directory (|:bcd|), so entry names resolve +without a prefix for |gf|, |:!|, and friends. Being buffer-local it is not +"sticky": it does not follow you out of the listing. + Directory buffers follow the global 'hidden' option by default. To delete them after use: >vim autocmd FileType directory setlocal bufhidden=delete diff --git a/runtime/lua/nvim/dir/fs.lua b/runtime/lua/nvim/dir/fs.lua index 6c8eb86c1f..0af9d3229f 100644 --- a/runtime/lua/nvim/dir/fs.lua +++ b/runtime/lua/nvim/dir/fs.lua @@ -97,10 +97,18 @@ function M.open_parent(_, path) end ---@param buf integer -function M.init(buf) +---@param path string +function M.init(buf, path) if api.nvim_get_option_value('filetype', { buf = buf }) ~= 'directory' then api.nvim_set_option_value('filetype', 'directory', { buf = buf }) end + api.nvim_buf_call(buf, function() + pcall(api.nvim_cmd, { + cmd = 'bcd', + args = { path }, + magic = { file = false, bar = false }, + }) + end) end return M diff --git a/test/functional/plugin/dir_spec.lua b/test/functional/plugin/dir_spec.lua index 3d5ab7b6e2..bf2787ce78 100644 --- a/test/functional/plugin/dir_spec.lua +++ b/test/functional/plugin/dir_spec.lua @@ -45,7 +45,7 @@ end local function assert_directory(path) local ffname = path:sub(-1) == '/' and path or path .. '/' eq(ffname, api.nvim_buf_get_name(0)) - eq(path, vim.fs.normalize(fn.bufname('%'))) + eq(path, vim.fs.normalize(fn.fnamemodify(fn.bufname('%'), ':p'))) eq('directory', bufopt('filetype')) eq(true, bufopt('buflisted')) end @@ -576,19 +576,24 @@ describe('nvim.dir', function() it('navigates entries and refreshes the listing', function() make_fixture() n.clear({ args = { '--clean' } }) + local cwd = fn.getcwd() edit(root) assert_directory(root) + eq(vim.uv.fs_realpath(root), vim.uv.fs_realpath(fn.getcwd())) + eq('alpha.txt', fn.findfile('alpha.txt')) api.nvim_win_set_cursor(0, { line_of('alpha.txt'), 0 }) feed('') poke_eventloop() eq(file, api.nvim_buf_get_name(0)) eq({ 'alpha' }, lines()) + eq(cwd, fn.getcwd()) edit(subdir) assert_directory(subdir) eq({ '' }, lines()) + eq(vim.uv.fs_realpath(subdir), vim.uv.fs_realpath(fn.getcwd())) feed('-') poke_eventloop()