mirror of
https://github.com/neovim/neovim.git
synced 2025-12-11 17:12:40 +00:00
fix(pack)!: make default opts.load in add() to work inside 'plugin/'
Problem: Plain `vim.pack.add()` calls (with default `opts.load`) does not fully work if called inside 'plugin/' runtime directory. In particular, 'plugin/' files of newly added plugins are not sourced. This is because `opts.load` is `false` during the whole startup, which means `:packadd!` is used (modify 'runtimepath' but not force source newly added 'plugin/' files). This use case is common due to users organizing their config as separate files in '~/.config/nvim/plugin/'. Solution: Use newly added `v:vim_did_init` to decide default `opts.load` value instead of `v:vim_did_enter`.
This commit is contained in:
@@ -379,7 +379,7 @@ add({specs}, {opts}) *vim.pack.add()*
|
|||||||
Load `plugin/` files and `ftdetect/` scripts. If `false`,
|
Load `plugin/` files and `ftdetect/` scripts. If `false`,
|
||||||
works like `:packadd!`. If function, called with plugin
|
works like `:packadd!`. If function, called with plugin
|
||||||
data and is fully responsible for loading plugin. Default
|
data and is fully responsible for loading plugin. Default
|
||||||
`false` during startup and `true` afterwards.
|
`false` during |init.lua| sourcing and `true` afterwards.
|
||||||
• {confirm}? (`boolean`) Whether to ask user to confirm
|
• {confirm}? (`boolean`) Whether to ask user to confirm
|
||||||
initial install. Default `true`.
|
initial install. Default `true`.
|
||||||
|
|
||||||
|
|||||||
@@ -743,8 +743,9 @@ local function pack_add(plug, load)
|
|||||||
-- NOTE: The `:packadd` specifically seems to not handle spaces in dir name
|
-- NOTE: The `:packadd` specifically seems to not handle spaces in dir name
|
||||||
vim.cmd.packadd({ vim.fn.escape(plug.spec.name, ' '), bang = not load, magic = { file = false } })
|
vim.cmd.packadd({ vim.fn.escape(plug.spec.name, ' '), bang = not load, magic = { file = false } })
|
||||||
|
|
||||||
-- Execute 'after/' scripts if not during startup (when they will be sourced
|
-- The `:packadd` only sources plain 'plugin/' files. Execute 'after/' scripts
|
||||||
-- automatically), as `:packadd` only sources plain 'plugin/' files.
|
-- if not during startup (when they will be sourced later, even if
|
||||||
|
-- `vim.pack.add` is inside user's 'plugin/')
|
||||||
-- See https://github.com/vim/vim/issues/15584
|
-- See https://github.com/vim/vim/issues/15584
|
||||||
-- Deliberately do so after executing all currently known 'plugin/' files.
|
-- Deliberately do so after executing all currently known 'plugin/' files.
|
||||||
if vim.v.vim_did_enter == 1 and load then
|
if vim.v.vim_did_enter == 1 and load then
|
||||||
@@ -760,7 +761,7 @@ end
|
|||||||
--- @inlinedoc
|
--- @inlinedoc
|
||||||
--- Load `plugin/` files and `ftdetect/` scripts. If `false`, works like `:packadd!`.
|
--- Load `plugin/` files and `ftdetect/` scripts. If `false`, works like `:packadd!`.
|
||||||
--- If function, called with plugin data and is fully responsible for loading plugin.
|
--- If function, called with plugin data and is fully responsible for loading plugin.
|
||||||
--- Default `false` during startup and `true` afterwards.
|
--- Default `false` during |init.lua| sourcing and `true` afterwards.
|
||||||
--- @field load? boolean|fun(plug_data: {spec: vim.pack.Spec, path: string})
|
--- @field load? boolean|fun(plug_data: {spec: vim.pack.Spec, path: string})
|
||||||
---
|
---
|
||||||
--- @field confirm? boolean Whether to ask user to confirm initial install. Default `true`.
|
--- @field confirm? boolean Whether to ask user to confirm initial install. Default `true`.
|
||||||
@@ -788,7 +789,7 @@ end
|
|||||||
--- @param opts? vim.pack.keyset.add
|
--- @param opts? vim.pack.keyset.add
|
||||||
function M.add(specs, opts)
|
function M.add(specs, opts)
|
||||||
vim.validate('specs', specs, vim.islist, false, 'list')
|
vim.validate('specs', specs, vim.islist, false, 'list')
|
||||||
opts = vim.tbl_extend('force', { load = vim.v.vim_did_enter == 1, confirm = true }, opts or {})
|
opts = vim.tbl_extend('force', { load = vim.v.vim_did_init == 1, confirm = true }, opts or {})
|
||||||
vim.validate('opts', opts, 'table')
|
vim.validate('opts', opts, 'table')
|
||||||
|
|
||||||
local plug_dir = get_plug_dir()
|
local plug_dir = get_plug_dir()
|
||||||
|
|||||||
@@ -620,35 +620,42 @@ describe('vim.pack', function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
describe('startup', function()
|
describe('startup', function()
|
||||||
local init_lua = ''
|
local config_dir, pack_add_cmd = '', ''
|
||||||
|
|
||||||
before_each(function()
|
before_each(function()
|
||||||
init_lua = vim.fs.joinpath(fn.stdpath('config'), 'init.lua')
|
config_dir = fn.stdpath('config')
|
||||||
fn.mkdir(vim.fs.dirname(init_lua), 'p')
|
fn.mkdir(vim.fs.joinpath(config_dir, 'plugin'), 'p')
|
||||||
|
|
||||||
|
pack_add_cmd = ('vim.pack.add({ %s })'):format(vim.inspect(repos_src.plugindirs))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
after_each(function()
|
after_each(function()
|
||||||
pcall(vim.fs.rm, init_lua, { force = true })
|
vim.fs.rm(config_dir, { recursive = true, force = true })
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('works in init.lua', function()
|
local function assert_loaded()
|
||||||
local pack_add_cmd = ('vim.pack.add({ %s })'):format(vim.inspect(repos_src.plugindirs))
|
eq('plugindirs main', exec_lua('return require("plugindirs")'))
|
||||||
fn.writefile({ pack_add_cmd, '_G.done = true' }, init_lua)
|
|
||||||
|
|
||||||
local function assert_loaded()
|
-- Should source 'plugin/' and 'after/plugin/' exactly once
|
||||||
eq('plugindirs main', exec_lua('return require("plugindirs")'))
|
eq({ true, true }, n.exec_lua('return { vim.g._plugin, vim.g._after_plugin }'))
|
||||||
|
eq({ 'p', 'a' }, n.exec_lua('return _G.DL'))
|
||||||
-- Should source 'plugin/' and 'after/plugin/' exactly once
|
end
|
||||||
eq({ true, true }, n.exec_lua('return { vim.g._plugin, vim.g._after_plugin }'))
|
|
||||||
eq({ 'p', 'a' }, n.exec_lua('return _G.DL'))
|
|
||||||
end
|
|
||||||
|
|
||||||
|
local function assert_works()
|
||||||
-- Should auto-install but wait before executing code after it
|
-- Should auto-install but wait before executing code after it
|
||||||
n.clear({ args_rm = { '-u' } })
|
n.clear({ args_rm = { '-u' } })
|
||||||
n.exec_lua('vim.wait(500, function() return _G.done end, 50)')
|
n.exec_lua('vim.wait(500, function() return _G.done end, 50)')
|
||||||
assert_loaded()
|
assert_loaded()
|
||||||
|
|
||||||
-- Should only `:packadd!` already installed plugin
|
-- Should only `:packadd!`/`:packadd` already installed plugin
|
||||||
n.clear({ args_rm = { '-u' } })
|
n.clear({ args_rm = { '-u' } })
|
||||||
assert_loaded()
|
assert_loaded()
|
||||||
|
end
|
||||||
|
|
||||||
|
it('works in init.lua', function()
|
||||||
|
local init_lua = vim.fs.joinpath(config_dir, 'init.lua')
|
||||||
|
fn.writefile({ pack_add_cmd, '_G.done = true' }, init_lua)
|
||||||
|
assert_works()
|
||||||
|
|
||||||
-- Should not load plugins if `--noplugin`, only adjust 'runtimepath'
|
-- Should not load plugins if `--noplugin`, only adjust 'runtimepath'
|
||||||
n.clear({ args = { '--noplugin' }, args_rm = { '-u' } })
|
n.clear({ args = { '--noplugin' }, args_rm = { '-u' } })
|
||||||
@@ -656,6 +663,13 @@ describe('vim.pack', function()
|
|||||||
eq({}, n.exec_lua('return { vim.g._plugin, vim.g._after_plugin }'))
|
eq({}, n.exec_lua('return { vim.g._plugin, vim.g._after_plugin }'))
|
||||||
eq(vim.NIL, n.exec_lua('return _G.DL'))
|
eq(vim.NIL, n.exec_lua('return _G.DL'))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('works in plugin/', function()
|
||||||
|
local plugin_file = vim.fs.joinpath(config_dir, 'plugin', 'mine.lua')
|
||||||
|
fn.writefile({ pack_add_cmd, '_G.done = true' }, plugin_file)
|
||||||
|
-- Should source plugin's 'plugin/' files without explicit `load=true`
|
||||||
|
assert_works()
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('shows progress report during installation', function()
|
it('shows progress report during installation', function()
|
||||||
|
|||||||
Reference in New Issue
Block a user