mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 03:18:16 +00:00
feat(exrc): search in parent directories (#33889)
feat(exrc): search exrc in parent directories Problem: `.nvim.lua` is only loaded from current directory, which is not flexible when working from a subfolder of the project. Solution: Also search parent directories for configuration file.
This commit is contained in:

committed by
GitHub

parent
2c07428966
commit
23bf4c0531
@@ -122,6 +122,7 @@ DEFAULTS
|
|||||||
|
|
||||||
• 'statusline' default is exposed as a statusline expression (previously it
|
• 'statusline' default is exposed as a statusline expression (previously it
|
||||||
was implemented as an internal C routine).
|
was implemented as an internal C routine).
|
||||||
|
• Project-local configuration ('exrc') is also loaded from parent directories.
|
||||||
|
|
||||||
DIAGNOSTICS
|
DIAGNOSTICS
|
||||||
|
|
||||||
|
@@ -2412,9 +2412,9 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
'exrc' 'ex' boolean (default off)
|
'exrc' 'ex' boolean (default off)
|
||||||
global
|
global
|
||||||
Enables project-local configuration. Nvim will execute any .nvim.lua,
|
Enables project-local configuration. Nvim will execute any .nvim.lua,
|
||||||
.nvimrc, or .exrc file found in the |current-directory|, if the file is
|
.nvimrc, or .exrc file found in the |current-directory| and all parent
|
||||||
in the |trust| list. Use |:trust| to manage trusted files. See also
|
directories (ordered upwards), if the files are in the |trust| list.
|
||||||
|vim.secure.read()|.
|
Use |:trust| to manage trusted files. See also |vim.secure.read()|.
|
||||||
|
|
||||||
Compare 'exrc' to |editorconfig|:
|
Compare 'exrc' to |editorconfig|:
|
||||||
- 'exrc' can execute any code; editorconfig only specifies settings.
|
- 'exrc' can execute any code; editorconfig only specifies settings.
|
||||||
|
@@ -209,6 +209,10 @@ nvim.swapfile:
|
|||||||
swapfile is owned by a running Nvim process. Shows |W325| "Ignoring
|
swapfile is owned by a running Nvim process. Shows |W325| "Ignoring
|
||||||
swapfile…" message.
|
swapfile…" message.
|
||||||
|
|
||||||
|
nvim.find_exrc:
|
||||||
|
- VimEnter: Extend 'exrc' to also search for project-local configuration files
|
||||||
|
in all parent directories.
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
New Features *nvim-features*
|
New Features *nvim-features*
|
||||||
|
|
||||||
|
@@ -925,6 +925,29 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
vim.api.nvim_create_autocmd('VimEnter', {
|
||||||
|
group = vim.api.nvim_create_augroup('nvim.find_exrc', {}),
|
||||||
|
desc = 'Find project-local configuration',
|
||||||
|
callback = function()
|
||||||
|
if vim.o.exrc then
|
||||||
|
local files = vim.fs.find(
|
||||||
|
{ '.nvim.lua', '.nvimrc', '.exrc' },
|
||||||
|
{ type = 'file', upward = true, limit = math.huge }
|
||||||
|
)
|
||||||
|
for _, file in ipairs(files) do
|
||||||
|
local trusted = vim.secure.read(file) --[[@as string|nil]]
|
||||||
|
if trusted then
|
||||||
|
if vim.endswith(file, '.lua') then
|
||||||
|
loadstring(trusted)()
|
||||||
|
else
|
||||||
|
vim.api.nvim_exec2(trusted, {})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Default options
|
--- Default options
|
||||||
|
6
runtime/lua/vim/_meta/options.lua
generated
6
runtime/lua/vim/_meta/options.lua
generated
@@ -2076,9 +2076,9 @@ vim.bo.expandtab = vim.o.expandtab
|
|||||||
vim.bo.et = vim.bo.expandtab
|
vim.bo.et = vim.bo.expandtab
|
||||||
|
|
||||||
--- Enables project-local configuration. Nvim will execute any .nvim.lua,
|
--- Enables project-local configuration. Nvim will execute any .nvim.lua,
|
||||||
--- .nvimrc, or .exrc file found in the `current-directory`, if the file is
|
--- .nvimrc, or .exrc file found in the `current-directory` and all parent
|
||||||
--- in the `trust` list. Use `:trust` to manage trusted files. See also
|
--- directories (ordered upwards), if the files are in the `trust` list.
|
||||||
--- `vim.secure.read()`.
|
--- Use `:trust` to manage trusted files. See also `vim.secure.read()`.
|
||||||
---
|
---
|
||||||
--- Compare 'exrc' to `editorconfig`:
|
--- Compare 'exrc' to `editorconfig`:
|
||||||
--- - 'exrc' can execute any code; editorconfig only specifies settings.
|
--- - 'exrc' can execute any code; editorconfig only specifies settings.
|
||||||
|
@@ -2745,9 +2745,9 @@ local options = {
|
|||||||
defaults = false,
|
defaults = false,
|
||||||
desc = [=[
|
desc = [=[
|
||||||
Enables project-local configuration. Nvim will execute any .nvim.lua,
|
Enables project-local configuration. Nvim will execute any .nvim.lua,
|
||||||
.nvimrc, or .exrc file found in the |current-directory|, if the file is
|
.nvimrc, or .exrc file found in the |current-directory| and all parent
|
||||||
in the |trust| list. Use |:trust| to manage trusted files. See also
|
directories (ordered upwards), if the files are in the |trust| list.
|
||||||
|vim.secure.read()|.
|
Use |:trust| to manage trusted files. See also |vim.secure.read()|.
|
||||||
|
|
||||||
Compare 'exrc' to |editorconfig|:
|
Compare 'exrc' to |editorconfig|:
|
||||||
- 'exrc' can execute any code; editorconfig only specifies settings.
|
- 'exrc' can execute any code; editorconfig only specifies settings.
|
||||||
@@ -2765,7 +2765,7 @@ local options = {
|
|||||||
full_name = 'exrc',
|
full_name = 'exrc',
|
||||||
scope = { 'global' },
|
scope = { 'global' },
|
||||||
secure = true,
|
secure = true,
|
||||||
short_desc = N_('read .nvimrc and .exrc in the current directory'),
|
short_desc = N_('read project-local configuration in parent directories'),
|
||||||
tags = { 'project-config', 'workspace-config' },
|
tags = { 'project-config', 'workspace-config' },
|
||||||
type = 'boolean',
|
type = 'boolean',
|
||||||
varname = 'p_exrc',
|
varname = 'p_exrc',
|
||||||
|
@@ -1108,6 +1108,7 @@ describe('user config init', function()
|
|||||||
string.format(
|
string.format(
|
||||||
[[
|
[[
|
||||||
vim.g.exrc_file = "%s"
|
vim.g.exrc_file = "%s"
|
||||||
|
vim.g.exrc_count = (vim.g.exrc_count or 0) + 1
|
||||||
]],
|
]],
|
||||||
exrc_path
|
exrc_path
|
||||||
)
|
)
|
||||||
@@ -1118,6 +1119,7 @@ describe('user config init', function()
|
|||||||
string.format(
|
string.format(
|
||||||
[[
|
[[
|
||||||
let g:exrc_file = "%s"
|
let g:exrc_file = "%s"
|
||||||
|
let g:exrc_count = get(g:, 'exrc_count', 0) + 1
|
||||||
]],
|
]],
|
||||||
exrc_path
|
exrc_path
|
||||||
)
|
)
|
||||||
@@ -1141,8 +1143,8 @@ describe('user config init', function()
|
|||||||
rmdir(xstate)
|
rmdir(xstate)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
for _, filename in ipairs({ '.exrc', '.nvimrc', '.nvim.lua' }) do
|
for _, filename in ipairs({ '.exrc', '.nvimrc', '.nvim.lua', '../.nvim.lua', '../.nvimrc' }) do
|
||||||
it(filename .. ' in cwd', function()
|
it(filename .. ' from cwd', function()
|
||||||
setup_exrc_file(filename)
|
setup_exrc_file(filename)
|
||||||
|
|
||||||
clear { args_rm = { '-u' }, env = xstateenv }
|
clear { args_rm = { '-u' }, env = xstateenv }
|
||||||
@@ -1185,6 +1187,36 @@ describe('user config init', function()
|
|||||||
eq(filename, eval('g:exrc_file'))
|
eq(filename, eval('g:exrc_file'))
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it('exrc from all parent directories', function()
|
||||||
|
-- make sure that there are not any exrc files left from previous tests
|
||||||
|
for _, file in ipairs({ '.exrc', '.nvimrc', '.nvim.lua', '../.nvim.lua', '../.nvimrc' }) do
|
||||||
|
os.remove(file)
|
||||||
|
end
|
||||||
|
setup_exrc_file('../.exrc')
|
||||||
|
setup_exrc_file('.nvim.lua')
|
||||||
|
clear { args_rm = { '-u' }, env = xstateenv }
|
||||||
|
local screen = Screen.new(50, 8)
|
||||||
|
screen._default_attr_ids = nil
|
||||||
|
fn.jobstart({ nvim_prog }, {
|
||||||
|
term = true,
|
||||||
|
env = {
|
||||||
|
VIMRUNTIME = os.getenv('VIMRUNTIME'),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
-- current directory exrc is found first
|
||||||
|
screen:expect({ any = '.nvim.lua' })
|
||||||
|
screen:expect({ any = pesc('[i]gnore, (v)iew, (d)eny, (a)llow:') })
|
||||||
|
feed('ia')
|
||||||
|
|
||||||
|
-- after that the exrc in the parent directory
|
||||||
|
screen:expect({ any = '.exrc' })
|
||||||
|
screen:expect({ any = pesc('[i]gnore, (v)iew, (d)eny, (a)llow:') })
|
||||||
|
feed('ia')
|
||||||
|
clear { args_rm = { '-u' }, env = xstateenv }
|
||||||
|
-- a total of 2 exrc files are executed
|
||||||
|
eq(2, eval('g:exrc_count'))
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('with explicitly provided config', function()
|
describe('with explicitly provided config', function()
|
||||||
|
Reference in New Issue
Block a user