diff options
| author | Evgeni Chasnovski <evgeni.chasnovski@gmail.com> | 2026-03-04 02:16:24 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-03-03 19:16:24 -0500 |
| commit | f00abc6a56693b030bed2e9771141067712e2b2a (patch) | |
| tree | be231bf0138170fcb0706fd934288aa65148f5d4 /runtime/lua/vim/pack.lua | |
| parent | 6ddcc84a6cd725b386da5f6dea7f6512c1f501d3 (diff) | |
| download | rneovim-f00abc6a56693b030bed2e9771141067712e2b2a.tar.gz rneovim-f00abc6a56693b030bed2e9771141067712e2b2a.tar.bz2 rneovim-f00abc6a56693b030bed2e9771141067712e2b2a.zip | |
fix(pack): ensure `data` spec is passed in events during lockfile sync #38139
Problem: During initial "bootstrap" via lockfile synchronization, the
whole plugin specification is reconstructed from the lockfile data,
ignoring potential user changes added in the first `vim.pack.add()`.
This is enough in most situations since it is the only data needed
for actual installation.
However, this affects specification passed to `PackChanged[Pre]`
events. In particular, `data` field is missing which can be a problem
if there is a `PackChanged kind=install` hook that uses that field
(like with some kind of `build` method used during install).
And there might be different `version` set in `vim.pack.add()`.
Solution: Pass the `specs` input of the first `vim.pack.add()` down to
lockfile synchronization and use it to reconstruct plugin
specification for the to-be-installed plugin. If present among the
user's `specs`, it is used but with forced `src` from the lockfile (as
it is the one used during installation).
Note that this still has a caveat when using separate
`vim.pack.add()`, as only the specs from the first input (when the
lockfile synchronization happens) is taken into account.
Diffstat (limited to 'runtime/lua/vim/pack.lua')
| -rw-r--r-- | runtime/lua/vim/pack.lua | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/runtime/lua/vim/pack.lua b/runtime/lua/vim/pack.lua index f336a22c7a..0d01b5ab10 100644 --- a/runtime/lua/vim/pack.lua +++ b/runtime/lua/vim/pack.lua @@ -843,7 +843,10 @@ end --- - Install plugins that have proper lockfile data but are not on disk. --- - Repair corrupted lock data for installed plugins. --- - Remove unrepairable corrupted lock data and plugins. -local function lock_sync(confirm) +--- @param confirm boolean +--- @param specs vim.pack.Spec[] Plugin specs provided by the user. Can contain +--- fields outside of what is in the lockfile to be passed down to events. +local function lock_sync(confirm, specs) if type(plugin_lock.plugins) ~= 'table' then plugin_lock.plugins = {} end @@ -885,7 +888,22 @@ local function lock_sync(confirm) local t = installed[name] == 'directory' and to_repair or to_remove t[#t + 1] = name elseif not installed[name] then - local spec = { src = data.src, name = name, version = data.version } + local spec ---@type vim.pack.Spec + -- Try reusing spec from user's `vim.pack.add()` (matters for events) + -- Delay until this point when shaving milliseconds shouldn't matter much + for _, s in ipairs(specs) do + local ok, s_norm = pcall(normalize_spec, s) + if ok and s_norm.name == name then + spec = vim.deepcopy(s_norm) + end + end + + -- Force fields relevant to actual installation, try to preserve others + spec = spec or {} + spec.src = data.src + spec.name = name + spec.version = spec.version or data.version + to_install[#to_install + 1] = new_plug(spec, plug_dir) end end @@ -917,7 +935,7 @@ local function lock_sync(confirm) end end -local function lock_read(confirm) +local function lock_read(confirm, specs) if plugin_lock then return end @@ -932,7 +950,7 @@ local function lock_read(confirm) plugin_lock = { plugins = {} } end - lock_sync(vim.F.if_nil(confirm, true)) + lock_sync(vim.F.if_nil(confirm, true), vim.F.if_nil(specs, {})) end --- @class vim.pack.keyset.add @@ -973,7 +991,7 @@ function M.add(specs, opts) opts = vim.tbl_extend('force', { load = vim.v.vim_did_init == 1, confirm = true }, opts or {}) vim.validate('opts', opts, 'table') - lock_read(opts.confirm) + lock_read(opts.confirm, specs) local plug_dir = get_plug_dir() local plugs = {} --- @type vim.pack.Plug[] |