From 2e533e364e2d52bcfe531d8ddd4a148d3f3bfed1 Mon Sep 17 00:00:00 2001 From: Evgeni Chasnovski Date: Thu, 13 Nov 2025 15:49:16 +0200 Subject: 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. --- test/functional/plugin/pack_spec.lua | 40 ++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'test/functional/plugin/pack_spec.lua') diff --git a/test/functional/plugin/pack_spec.lua b/test/functional/plugin/pack_spec.lua index 82e0277775..48155e2743 100644 --- a/test/functional/plugin/pack_spec.lua +++ b/test/functional/plugin/pack_spec.lua @@ -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() -- cgit