From 1aa81290a4116f9e15039ee10c4bfa2ae76f0d31 Mon Sep 17 00:00:00 2001 From: Evgeni Chasnovski Date: Thu, 29 Jan 2026 16:24:33 +0200 Subject: [PATCH 1/2] docs(pack): clarify caveats about installing based on the lockfile --- runtime/doc/pack.txt | 11 ++++++++--- runtime/lua/vim/pack.lua | 9 ++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/runtime/doc/pack.txt b/runtime/doc/pack.txt index aaf1bc7ba0..1c6658e9a8 100644 --- a/runtime/doc/pack.txt +++ b/runtime/doc/pack.txt @@ -226,9 +226,11 @@ located at `$XDG_CONFIG_HOME/nvim/nvim-pack-lock.json`. It is a JSON file that is used to persistently track data about plugins. For a more robust config treat lockfile like its part: put under version control, etc. In this case all plugins from the lockfile will be installed at once and at lockfile's revision -(instead of inferring from `version`). Should not be edited by hand. Corrupted -data for installed plugins is repaired (including after deleting whole file), -but `version` fields will be missing for not yet added plugins. +(instead of inferring from `version`). This is done on the very first +`vim.pack` function call to ensure that lockfile is aligned with what is +actually on the disk. Lockfile should not be edited by hand. Corrupted data +for installed plugins is repaired (including after deleting whole file), but +`version` fields will be missing for not yet added plugins. *vim.pack-examples* @@ -351,6 +353,8 @@ Remove plugins from disk ~ < *vim.pack-events* + +Performing actions via `vim.pack` functions can trigger these events: • *PackChangedPre* - before trying to change plugin's state. • *PackChanged* - after plugin's state has changed. @@ -385,6 +389,7 @@ These events can be used to execute plugin hooks. For example: >lua end -- If hooks need to run on install, run this before `vim.pack.add()` + -- To act on install from lockfile, run before very first `vim.pack.add()` vim.api.nvim_create_autocmd('PackChanged', { callback = hooks }) < diff --git a/runtime/lua/vim/pack.lua b/runtime/lua/vim/pack.lua index 780e5f278a..b68856a0a6 100644 --- a/runtime/lua/vim/pack.lua +++ b/runtime/lua/vim/pack.lua @@ -18,9 +18,10 @@ ---located at `$XDG_CONFIG_HOME/nvim/nvim-pack-lock.json`. It is a JSON file that ---is used to persistently track data about plugins. ---For a more robust config treat lockfile like its part: put under version control, etc. ----In this case all plugins from the lockfile will be installed at once and ----at lockfile's revision (instead of inferring from `version`). ----Should not be edited by hand. Corrupted data for installed plugins is repaired +---In this case all plugins from the lockfile will be installed at once and at lockfile's revision +---(instead of inferring from `version`). This is done on the very first `vim.pack` function call +---to ensure that lockfile is aligned with what is actually on the disk. +---Lockfile should not be edited by hand. Corrupted data for installed plugins is repaired ---(including after deleting whole file), but `version` fields will be missing ---for not yet added plugins. --- @@ -160,6 +161,7 @@ --- ---[vim.pack-events]() --- +---Performing actions via `vim.pack` functions can trigger these events: ---- [PackChangedPre]() - before trying to change plugin's state. ---- [PackChanged]() - after plugin's state has changed. --- @@ -195,6 +197,7 @@ ---end --- ----- If hooks need to run on install, run this before `vim.pack.add()` +----- To act on install from lockfile, run before very first `vim.pack.add()` ---vim.api.nvim_create_autocmd('PackChanged', { callback = hooks }) ---``` From 164cab405bc68b96db61dabe01d7c53dd5abd53d Mon Sep 17 00:00:00 2001 From: Evgeni Chasnovski Date: Thu, 29 Jan 2026 16:25:02 +0200 Subject: [PATCH 2/2] test(pack): cover that events work when installing from the lockfile --- test/functional/plugin/pack_spec.lua | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/functional/plugin/pack_spec.lua b/test/functional/plugin/pack_spec.lua index 0f2e7898dc..bf9598aa90 100644 --- a/test/functional/plugin/pack_spec.lua +++ b/test/functional/plugin/pack_spec.lua @@ -612,6 +612,7 @@ describe('vim.pack', function() -- Mock clean initial install, but with lockfile present vim.fs.rm(pack_get_dir(), { force = true, recursive = true }) n.clear() + watch_events({ 'PackChangedPre', 'PackChanged' }) local basic_rev = git_get_hash('feat-branch', 'basic') local defbranch_rev = git_get_hash('HEAD', 'defbranch') @@ -637,6 +638,17 @@ describe('vim.pack', function() eq(true, pack_exists('defbranch')) eq(false, exec_lua('return pcall(require, "defbranch")')) + -- Should trigger `kind=install` events + local log = exec_lua('return _G.event_log') + local find_event = make_find_packchanged(log) + local installpre_basic = find_event('Pre', 'install', 'basic', 'feat-branch', false) + local installpre_defbranch = find_event('Pre', 'install', 'defbranch', nil, false) + local install_basic = find_event('', 'install', 'basic', 'feat-branch', false) + local install_defbranch = find_event('', 'install', 'defbranch', nil, false) + eq(4, #log) + eq(true, installpre_basic < install_basic) + eq(true, installpre_defbranch < install_defbranch) + -- Running `update()` should still update to use `main` exec_lua(function() vim.pack.update({ 'basic' }, { force = true })