mirror of
https://github.com/neovim/neovim.git
synced 2026-08-27 09:31:47 +00:00
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`.
This commit is contained in:
@@ -615,14 +615,14 @@ DiffUpdated After diffs have been updated. Depending on
|
||||
*DirChanged*
|
||||
DirChanged After the |current-directory| was changed.
|
||||
The pattern can be:
|
||||
"auto" to trigger on 'autochdir'.
|
||||
"buffer" to trigger on `:bcd`
|
||||
"global" to trigger on `:cd`
|
||||
"tabpage" to trigger on `:tcd`
|
||||
"window" to trigger on `:lcd`
|
||||
"auto" triggered on 'autochdir'.
|
||||
"buffer" triggered on `:bcd`.
|
||||
"global" triggered on `:cd`.
|
||||
"tabpage" triggered on `:tcd`.
|
||||
"window" triggered on `:lcd`.
|
||||
Sets these |v:event| keys:
|
||||
cwd: current working directory
|
||||
scope: "global", "tabpage", "window"
|
||||
scope: "global", "tabpage", "window", "buffer"
|
||||
changed_window: v:true if we fired the event
|
||||
switching window (or tab)
|
||||
<afile> is set to the new directory name.
|
||||
|
||||
@@ -1418,6 +1418,10 @@ scope in the hierarchy applies.
|
||||
current buffer. The current directory for other
|
||||
tabs, windows, or buffers is not changed.
|
||||
|
||||
Unlike :lcd and :tcd, this is not "sticky": a new
|
||||
buffer or window will not "inherit" a buffer-local
|
||||
directory.
|
||||
|
||||
*:bcd-*
|
||||
:bc[d][!] - Change to the previous buffer-local current directory
|
||||
(before the last ":bcd [path]" command).
|
||||
@@ -1448,22 +1452,24 @@ scope in the hierarchy applies.
|
||||
:verbose pwd
|
||||
[buffer] /path/to/current
|
||||
|
||||
So long as no |:tcd|, |:lcd| or |:bcd| command has been used, all windows
|
||||
share the same current directory. Using a command to jump to another window
|
||||
doesn't change anything for the current directory.
|
||||
So long as |:tcd|, |:lcd| or |:bcd| has not been used, all buffers and windows
|
||||
share the same directory. Using a command to jump to another window doesn't
|
||||
change anything for the current directory.
|
||||
|
||||
When |:lcd| has been used for a window, the specified directory becomes the
|
||||
current directory for that window. Windows where the |:lcd| command has not
|
||||
been used stick to the buffer-local, tab-local or global directory. When
|
||||
jumping to another window the current directory is changed to the last
|
||||
specified local current directory. If none was specified, the buffer-local,
|
||||
tab-local or global directory is used. When creating a new window it
|
||||
inherits the local directory of the current window.
|
||||
specified window-local directory. If none was specified, the buffer-local,
|
||||
tab-local or global directory is used. When creating a new window it inherits
|
||||
the current window-local directory ("sticky" behavior).
|
||||
|
||||
When |:bcd| has been used for a buffer, the specified directory becomes the
|
||||
current directory whenever that buffer is entered, unless the window has its
|
||||
own window-local directory. A new buffer created with |:edit| or |:enew|
|
||||
inherits the buffer-local directory of the previous current buffer.
|
||||
own window-local directory. The buffer-local directory is never inherited
|
||||
(not "sticky"): a buffer created with |:edit|, |:enew|, etc., ignores the
|
||||
current buffer-local (:bcd) directory, if any. Use |:lcd| if you want "sticky"
|
||||
behavior.
|
||||
|
||||
When changing tabs the same behaviour applies. If the current tab has no
|
||||
local working directory the global working directory is used.
|
||||
|
||||
@@ -1323,7 +1323,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
'cdhome' 'cdh' boolean (default on on Unix, off on Windows)
|
||||
global
|
||||
Disallowed in |modeline|. |no-modeline-option|
|
||||
When on, |:cd|, |:tcd| and |:lcd| without an argument changes the
|
||||
When on, |:cd|, |:tcd|, |:lcd| and |:bcd| without an argument changes the
|
||||
current working directory to the |$HOME| directory like in Unix.
|
||||
When off, those commands just print the current directory name.
|
||||
|
||||
@@ -1332,7 +1332,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
global
|
||||
Disallowed in |modeline|. |no-modeline-option|
|
||||
This is a list of directories which will be searched when using the
|
||||
|:cd|, |:tcd| and |:lcd| commands, provided that the directory being
|
||||
|:cd|, |:tcd|, |:lcd| and |:bcd| commands, provided that the directory being
|
||||
searched for has a relative path, not an absolute part starting with
|
||||
"/", "./" or "../", the 'cdpath' option is not used then.
|
||||
The 'cdpath' option's value has the same form and semantics as
|
||||
@@ -2058,7 +2058,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
following occurrence.
|
||||
*cpo-~*
|
||||
~ When included, don't resolve symbolic links when
|
||||
changing directory with |:cd|, |:lcd|, or |:tcd|.
|
||||
changing directory with |:cd|, |:tcd|, |:lcd|, or |:bcd|.
|
||||
This preserves the symbolic link path in buffer names
|
||||
and when displaying the current directory. When
|
||||
excluded (default), symbolic links are resolved to
|
||||
|
||||
@@ -1125,8 +1125,8 @@ chdir({dir} [, {scope}]) *chdir()*
|
||||
|
||||
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|
|
||||
|
||||
@@ -3759,23 +3759,27 @@ getcwd([{winnr} [, {tabnr} [, {bufnr}]]])
|
||||
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
|
||||
@@ -5019,8 +5023,9 @@ haslocaldir([{winnr} [, {tabnr} [, {bufnr} ]]]) *haslocaldir()*
|
||||
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)
|
||||
|
||||
6
runtime/lua/vim/_meta/options.gen.lua
generated
6
runtime/lua/vim/_meta/options.gen.lua
generated
@@ -734,7 +734,7 @@ vim.o.cmp = vim.o.casemap
|
||||
vim.go.casemap = vim.o.casemap
|
||||
vim.go.cmp = vim.go.casemap
|
||||
|
||||
--- When on, `:cd`, `:tcd` and `:lcd` without an argument changes the
|
||||
--- When on, `:cd`, `:tcd`, `:lcd` and `:bcd` without an argument changes the
|
||||
--- current working directory to the `$HOME` directory like in Unix.
|
||||
--- When off, those commands just print the current directory name.
|
||||
---
|
||||
@@ -745,7 +745,7 @@ vim.go.cdhome = vim.o.cdhome
|
||||
vim.go.cdh = vim.go.cdhome
|
||||
|
||||
--- This is a list of directories which will be searched when using the
|
||||
--- `:cd`, `:tcd` and `:lcd` commands, provided that the directory being
|
||||
--- `:cd`, `:tcd`, `:lcd` and `:bcd` commands, provided that the directory being
|
||||
--- searched for has a relative path, not an absolute part starting with
|
||||
--- "/", "./" or "../", the 'cdpath' option is not used then.
|
||||
--- The 'cdpath' option's value has the same form and semantics as
|
||||
@@ -1572,7 +1572,7 @@ vim.bo.ci = vim.bo.copyindent
|
||||
--- following occurrence.
|
||||
--- *cpo-~*
|
||||
--- ~ When included, don't resolve symbolic links when
|
||||
--- changing directory with `:cd`, `:lcd`, or `:tcd`.
|
||||
--- changing directory with `:cd`, `:tcd`, `:lcd`, or `:bcd`.
|
||||
--- This preserves the symbolic link path in buffer names
|
||||
--- and when displaying the current directory. When
|
||||
--- excluded (default), symbolic links are resolved to
|
||||
|
||||
23
runtime/lua/vim/_meta/vimfn.gen.lua
generated
23
runtime/lua/vim/_meta/vimfn.gen.lua
generated
@@ -960,8 +960,8 @@ function vim.fn.charidx(string, idx, countcc, utf16) end
|
||||
---
|
||||
--- 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|
|
||||
---
|
||||
@@ -3326,23 +3326,27 @@ function vim.fn.getcursorcharpos(winid) end
|
||||
--- 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
|
||||
@@ -4468,8 +4472,9 @@ function vim.fn.has_key(dict, key) end
|
||||
--- 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)
|
||||
|
||||
Reference in New Issue
Block a user