diff options
| author | Evgeni Chasnovski <evgeni.chasnovski@gmail.com> | 2025-12-26 17:35:25 +0200 |
|---|---|---|
| committer | Evgeni Chasnovski <evgeni.chasnovski@gmail.com> | 2025-12-26 18:32:59 +0200 |
| commit | 8c28507fcf6fa5e39adba2a7f9dc07442aa3bbeb (patch) | |
| tree | 72cb0cae91820689107b41b47f45a775ddc190a1 /runtime/lua/vim/pack.lua | |
| parent | 899ec829be85b52202f0ce32c455ae4f4d60b85b (diff) | |
| download | rneovim-8c28507fcf6fa5e39adba2a7f9dc07442aa3bbeb.tar.gz rneovim-8c28507fcf6fa5e39adba2a7f9dc07442aa3bbeb.tar.bz2 rneovim-8c28507fcf6fa5e39adba2a7f9dc07442aa3bbeb.zip | |
feat(pack): allow choosing update target in `update()`
Problem: There are two fairly common workflows that involve lockfile and
can be made more straightforward in `vim.pack`:
1. Revert latest update. Like if it introduced unwanted behavior.
2. Update to a revision in the lockfile. Like if already updated
on another machine, verified that everything works, `git add` +
`git commit` + `git push` the config, and want to have the same
plugin states on current machine.
Solution: Make `update` allow `opts.target`. By default it uses
`version` from a plugin specification (like a regular "get new changes
from source" workflow). But it also allows `"lockfile"` value to
indicate that target revision after update should be taken from the
current lockfile verbatim.
With this, the workflows are:
1. Revert (somehow) to the lockfile before the update, restart, and
`vim.pack.update({ 'plugin' }, { target = 'lockfile' })`. If Git
tracked, revert with `git checkout HEAD -- nvim-pack-lock.json`.
For non-VCS tracked lockfile, the revisions can be taken from the
log file. It would be nicer if `update()` would backup a lockfile
before doing an update, but that might require discussions.
2. `git pull` + `:restart` +
`vim.pack.update(nil, { target = 'lockfile' })`.
The only caveats are for new and deleted plugins:
- New plugins (not present locally but present in the lockfile)
will be installed at lockfile revision during restart.
- Deleted plugins (present locally but not present in the
lockfile) will still be present: both locally *and* in the
lockfile. They can be located by
`git diff -- nvim-pack-lock.json` and require manual
`vim.pack.del({ 'old-plugin1', 'old-plugin2' })`.
Diffstat (limited to 'runtime/lua/vim/pack.lua')
| -rw-r--r-- | runtime/lua/vim/pack.lua | 47 |
1 files changed, 35 insertions, 12 deletions
diff --git a/runtime/lua/vim/pack.lua b/runtime/lua/vim/pack.lua index 736e78335a..a808ce8683 100644 --- a/runtime/lua/vim/pack.lua +++ b/runtime/lua/vim/pack.lua @@ -113,16 +113,28 @@ --- ---Revert plugin after an update ~ --- ----- Locate plugin's revision at working state. For example: ---- - If there is a previous version of |vim.pack-lockfile| (like from version ---- control history), use it to get plugin's `rev` field. ---- - If there is a log file ("nvim-pack.log" at "log" |stdpath()|), open it ---- and navigate to latest updates (at the bottom). Locate lines about plugin ---- update details and use revision from "State before". ----- Freeze plugin to target revision (set `version` and |:restart|). ----- Run `vim.pack.update({ 'plugin-name' }, { force = true })` to make plugin ---- state on disk follow target revision. |:restart|. ----- When ready to deal with updating plugin, unfreeze it. +---- Revert the |vim.pack-lockfile| to the state before the update: +--- - If Git tracked: `git checkout HEAD -- nvim-pack-lock.json` +--- - If not tracked: examine log file ("nvim-pack.log" at "log" |stdpath()|), +--- locate the revisions before the latest update, and (carefully) adjust +--- current lockfile to have those revisions. +---- |:restart|. +---- `vim.pack.update({ 'plugin' }, { target = 'lockfile' })`. Read and confirm. +--- +---Synchronize config across machines ~ +--- +---- On main machine: +--- - Add |vim.pack-lockfile| to VCS. +--- - Push to the remote server. +---- On secondary machine: +--- - Pull from the server. +--- - |:restart|. New plugins (not present locally, but present in the lockfile) +--- are installed at proper revision. +--- - `vim.pack.update(nil, { target = 'lockfile' })`. Read and confirm. +--- - Manually delete outdated plugins (present locally, but were not present +--- in the lockfile prior to restart) with `vim.pack.del( { 'plugin' })`. +--- They can be located by examining the VCS difference of the lockfile +--- (`git diff -- nvim-pack-lock.json` for Git). --- ---Remove plugins from disk ~ --- @@ -1139,6 +1151,12 @@ end --- @class vim.pack.keyset.update --- @inlinedoc --- @field force? boolean Whether to skip confirmation and make updates immediately. Default `false`. +--- +--- How to compute a new plugin revision. One of: +--- - "version" (default) - use latest revision matching `version` from plugin specification. +--- - "lockfile" - use revision from the lockfile. Useful for reverting or performing controlled +--- update. +--- @field target? string --- Update plugins --- @@ -1173,7 +1191,7 @@ end --- @param opts? vim.pack.keyset.update function M.update(names, opts) vim.validate('names', names, vim.islist, true, 'list') - opts = vim.tbl_extend('force', { force = false }, opts or {}) + opts = vim.tbl_extend('force', { force = false, target = 'version' }, opts or {}) local plug_list = plug_list_from_names(names) if #plug_list == 0 then @@ -1190,8 +1208,9 @@ function M.update(names, opts) --- @async --- @param p vim.pack.Plug local function do_update(p) + local l_data = plugin_lock.plugins[p.spec.name] -- Ensure proper `origin` if needed - if plugin_lock.plugins[p.spec.name].src ~= p.spec.src then + if l_data.src ~= p.spec.src then git_cmd({ 'remote', 'set-url', 'origin', p.spec.src }, p.path) plugin_lock.plugins[p.spec.name].src = p.spec.src needs_lock_write = true @@ -1205,6 +1224,10 @@ function M.update(names, opts) end -- Compute change info: changelog if any, new tags if nothing to update + if opts.target == 'lockfile' then + p.info.version_str = '*lockfile*' + p.info.sha_target = l_data.rev + end infer_update_details(p) -- Checkout immediately if no need to confirm |