mirror of
https://github.com/neovim/neovim.git
synced 2025-12-12 17:42:37 +00:00
feat(pack): update add() to handle source change for installed plugin
Problem: Changing `src` of an existing plugin cleanly requires manual `vim.pack.del()` prior to executing `vim.pack.add()` with a new `src`. Solution: Autodetect `src` change for an existing plugin (by comparing against lockfile data). If different - properly delete immediately and treat this as new plugin installation. Alternative solution might be to update `origin` remote in the installed plugin after calling `vim.pack.update()`. Although, doable, this 1) requires more code; and 2) works only for Git plugins (which might be not the only type of plugins in the future). Automatic "delete and clean install" feels more robust.
This commit is contained in:
@@ -280,6 +280,10 @@ Switch plugin's version:
|
||||
changes in 'init.lua' as well or you will be prompted again next time you
|
||||
run |vim.pack.update()|.
|
||||
|
||||
Switch plugin's source:
|
||||
• Update 'init.lua' for plugin to have desired `src`.
|
||||
• |:restart|. This will cleanly reinstall plugin from the new source.
|
||||
|
||||
Freeze plugin from being updated:
|
||||
• Update 'init.lua' for plugin to have `version` set to current revision. Get
|
||||
it from |vim.pack-lockfile| (plugin's field `rev`; looks like `abc12345`).
|
||||
@@ -354,10 +358,12 @@ add({specs}, {opts}) *vim.pack.add()*
|
||||
Add plugin to current session
|
||||
• For each specification check that plugin exists on disk in
|
||||
|vim.pack-directory|:
|
||||
• If exists, do nothing in this step.
|
||||
• If exists, check if its `src` is the same as input. If not - delete
|
||||
immediately to clean install from the new source. Otherwise do
|
||||
nothing.
|
||||
• If doesn't exist, install it by downloading from `src` into `name`
|
||||
subdirectory (via `git clone`) and update revision to follow `version`
|
||||
(via `git checkout`).
|
||||
subdirectory (via partial blobless `git clone`) and update revision to
|
||||
match `version` (via `git checkout`).
|
||||
• For each plugin execute |:packadd| (or customizable `load` function)
|
||||
making it reachable by Nvim.
|
||||
|
||||
|
||||
@@ -77,6 +77,10 @@
|
||||
---any changes in 'init.lua' as well or you will be prompted again next time
|
||||
---you run |vim.pack.update()|.
|
||||
---
|
||||
---Switch plugin's source:
|
||||
---- Update 'init.lua' for plugin to have desired `src`.
|
||||
---- |:restart|. This will cleanly reinstall plugin from the new source.
|
||||
---
|
||||
---Freeze plugin from being updated:
|
||||
---- Update 'init.lua' for plugin to have `version` set to current revision.
|
||||
---Get it from |vim.pack-lockfile| (plugin's field `rev`; looks like `abc12345`).
|
||||
@@ -769,9 +773,11 @@ end
|
||||
--- Add plugin to current session
|
||||
---
|
||||
--- - For each specification check that plugin exists on disk in |vim.pack-directory|:
|
||||
--- - If exists, do nothing in this step.
|
||||
--- - If exists, check if its `src` is the same as input. If not - delete
|
||||
--- immediately to clean install from the new source. Otherwise do nothing.
|
||||
--- - If doesn't exist, install it by downloading from `src` into `name`
|
||||
--- subdirectory (via `git clone`) and update revision to follow `version` (via `git checkout`).
|
||||
--- subdirectory (via partial blobless `git clone`) and update revision
|
||||
--- to match `version` (via `git checkout`).
|
||||
--- - For each plugin execute |:packadd| (or customizable `load` function) making
|
||||
--- it reachable by Nvim.
|
||||
---
|
||||
@@ -804,13 +810,19 @@ function M.add(specs, opts)
|
||||
local plugs_to_install = {} --- @type vim.pack.Plug[]
|
||||
local needs_lock_write = false
|
||||
for _, p in ipairs(plugs) do
|
||||
-- TODO(echasnovski): check that lock's `src` is the same as in spec.
|
||||
-- If not - cleanly reclone (delete directory and mark as not installed).
|
||||
-- Allow to cleanly change `src` of an already installed plugin
|
||||
if p.info.installed and plugin_lock.plugins[p.spec.name].src ~= p.spec.src then
|
||||
M.del({ p.spec.name })
|
||||
p.info.installed = false
|
||||
end
|
||||
|
||||
-- Detect `version` change
|
||||
local p_lock = plugin_lock.plugins[p.spec.name] or {}
|
||||
needs_lock_write = needs_lock_write or p_lock.version ~= p.spec.version
|
||||
p_lock.version = p.spec.version
|
||||
plugin_lock.plugins[p.spec.name] = p_lock
|
||||
|
||||
-- Register for install
|
||||
if not p.info.installed then
|
||||
plugs_to_install[#plugs_to_install + 1] = p
|
||||
needs_lock_write = true
|
||||
|
||||
@@ -611,6 +611,46 @@ describe('vim.pack', function()
|
||||
eq({ { '.git', 'directory' } }, entries)
|
||||
end)
|
||||
|
||||
it('allows changing `src` of installed plugin', function()
|
||||
local basic_src = repos_src.basic
|
||||
local defbranch_src = repos_src.defbranch
|
||||
exec_lua(function()
|
||||
vim.pack.add({ basic_src })
|
||||
end)
|
||||
eq('basic main', exec_lua('return require("basic")'))
|
||||
|
||||
n.clear()
|
||||
watch_events({ 'PackChangedPre', 'PackChanged' })
|
||||
exec_lua(function()
|
||||
vim.pack.add({ { src = defbranch_src, name = 'basic' } })
|
||||
end)
|
||||
eq('defbranch dev', exec_lua('return require("defbranch")'))
|
||||
|
||||
-- Should first properly delete and then cleanly install
|
||||
local log_simple = vim.tbl_map(function(x) --- @param x table
|
||||
return { x.event, x.data.kind, x.data.spec }
|
||||
end, exec_lua('return _G.event_log'))
|
||||
|
||||
local ref_log_simple = {
|
||||
{ 'PackChangedPre', 'delete', { name = 'basic', src = basic_src } },
|
||||
{ 'PackChanged', 'delete', { name = 'basic', src = basic_src } },
|
||||
{ 'PackChangedPre', 'install', { name = 'basic', src = defbranch_src } },
|
||||
{ 'PackChanged', 'install', { name = 'basic', src = defbranch_src } },
|
||||
}
|
||||
eq(ref_log_simple, log_simple)
|
||||
|
||||
local ref_messages = table.concat({
|
||||
"vim.pack: Removed plugin 'basic'",
|
||||
'vim.pack: Installing plugins (0/1)',
|
||||
'vim.pack: 100% Installing plugins (1/1)',
|
||||
}, '\n')
|
||||
eq(ref_messages, n.exec_capture('messages'))
|
||||
|
||||
local defbranch_rev = git_get_hash('dev', 'defbranch')
|
||||
local ref_lock_tbl = { plugins = { basic = { rev = defbranch_rev, src = defbranch_src } } }
|
||||
eq(ref_lock_tbl, get_lock_tbl())
|
||||
end)
|
||||
|
||||
it('can install from the Internet', function()
|
||||
t.skip(skip_integ, 'NVIM_TEST_INTEG not set: skipping network integration test')
|
||||
exec_lua(function()
|
||||
|
||||
Reference in New Issue
Block a user