aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval.lua
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2026-08-04 17:13:32 +0200
committerJustin M. Keyes <justinkz@gmail.com>2026-08-04 20:48:44 +0200
commit9cd4dd1c1934b21cf4acc7950da6b2b811c41b71 (patch)
treecd3617cd49d1eaae8cd5f5fa04f2102b58c414d5 /src/nvim/eval.lua
parent46ca2365256e9d9fa7d845d6757b15ea96e47fbc (diff)
downloadrneovim-9cd4dd1c1934b21cf4acc7950da6b2b811c41b71.tar.gz
rneovim-9cd4dd1c1934b21cf4acc7950da6b2b811c41b71.tar.bz2
rneovim-9cd4dd1c1934b21cf4acc7950da6b2b811c41b71.zip
fix(:bcd): do not "inherit" buffer-local dir
Problem: Buffer-local CWD (:bcd) is "sticky", similar to window-local CWD (:lcd). But this contradicts one of its main benefits: per-buffer "project root" for LSP, OSC7. Other problems: - A buffer created with :edit/:enew/:new silently inherits b_localdir (and b_prevdir) from the previous buffer. - curbuf_reusable() refuses to recycle a scratch buffer that has `b_localdir`. - After :new/:vnew/:tabnew the CWD sticks to previous buffer's `b_localdir` even though the new curbuf has none, so :new is not equivalent to ":split | enew", and getcwd() disagrees with haslocaldir(). - Requires "which buffer spawned this buffer" semantics that no other buffer-local state has. Solution: Drop sticky/inherit behavior of buffer-local CWD (:bcd). - do_ecmd: always apply the new curbuf's dir (`fix_current_dir`), like `do_autochdir` already does. :tabnew from a :bcd buffer now reverts to global CWD (and fires DirChanged), same as :tabnew from a :lcd window. - curbuf_reusable(): recycling a scratch buffer frees its b_localdir. To get sticky/inherit behavior of CWD, use `:lcd`.
Diffstat (limited to 'src/nvim/eval.lua')
-rw-r--r--src/nvim/eval.lua23
1 files changed, 14 insertions, 9 deletions
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index 4df067481e..3181857b53 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -1265,8 +1265,8 @@ M.funcs = {
If {scope} is present, changes the current working directory
for the specified scope:
- "window" Changes the window local directory. |:lcd|
"buffer" Changes the buffer local directory. |:bcd|
+ "window" Changes the window local directory. |:lcd|
"tabpage" Changes the tabpage local directory. |:tcd|
"global" Changes the global directory. |:cd|
@@ -4101,23 +4101,27 @@ M.funcs = {
is ignored.
Tabs, windows and buffers are identified by their respective
- numbers, 0 means current tab or window or buffer. Missing tab
- number
- implies 0. Thus the following are equivalent: >vim
+ numbers, 0 means current tab/window/buffer. Missing {tabnr}
+ implies 0 (missing {bufnr} does not; see below). Thus the
+ following are equivalent: >vim
getcwd(0)
getcwd(0, 0)
<If {winnr} is -1 it is ignored, only the tab is resolved.
{winnr} is a |window-number| or |window-ID|.
+
If both {winnr} and {tabnr} are -1 and {bufnr} is missing the
global working directory is returned.
+
Note: When {tabnr} is -1 Vim returns an empty string to
signal that it is invalid, whereas Nvim returns either the
global working directory if {winnr} is -1 or the working
directory of the window indicated by {winnr}.
- If {bufnr} is provided, {winnr} and {tabnr} must be -1 and the
- working directory of that buffer is returned. An argument may
- be -1 only if all preceding arguments are -1.
+ If {bufnr} is provided, {winnr} and {tabnr} must be -1, then
+ the buffer-local working directory is returned.
+
+ An argument may be -1 only if all preceding arguments are -1.
+
Examples of buffer usage: >vim
getcwd(-1, -1, 0) " Get current buffer's directory
getcwd(-1, -1, 3) " Get directory of buffer #3
@@ -5435,8 +5439,9 @@ M.funcs = {
and {bufnr} has set a local path via |:bcd|, otherwise 0.
Tabs, windows and buffers are identified by their respective
- numbers, 0 means current tab, window or buffer. Missing
- argument implies 0. Thus the following are equivalent: >vim
+ numbers, 0 means current tab/window/buffer. Missing {winnr}
+ or {tabnr} implies 0 (missing {bufnr} does not; see below).
+ Thus the following are equivalent: >vim
echo haslocaldir()
echo haslocaldir(0)
echo haslocaldir(0, 0)