diff --git a/runtime/lua/vim/pack.lua b/runtime/lua/vim/pack.lua index fc889f6780..fb6ff2958f 100644 --- a/runtime/lua/vim/pack.lua +++ b/runtime/lua/vim/pack.lua @@ -1122,6 +1122,7 @@ function M.get(names, opts) active[p_active.id] = p_active.plug end + lock_read() local res = {} --- @type vim.pack.PlugData[] local used_names = {} --- @type table for i = 1, n_active_plugins do @@ -1131,21 +1132,16 @@ function M.get(names, opts) end end - --- @async - local function do_get() - -- Process not active plugins - local plug_dir = get_plug_dir() - for n, t in vim.fs.dir(plug_dir, { depth = 1 }) do - local path = vim.fs.joinpath(plug_dir, n) - local is_in_names = not names or vim.tbl_contains(names, n) - if t == 'directory' and not active_plugins[path] and is_in_names then - local spec = { name = n, src = git_cmd({ 'remote', 'get-url', 'origin' }, path) } - res[#res + 1] = { spec = spec, path = path, active = false } - used_names[n] = true - end + local plug_dir = get_plug_dir() + for name, l_data in vim.spairs(plugin_lock.plugins) do + local path = vim.fs.joinpath(plug_dir, name) + local is_in_names = not names or vim.tbl_contains(names, name) + if not active_plugins[path] and is_in_names then + local spec = { name = name, src = l_data.src, version = l_data.version } + res[#res + 1] = { spec = spec, path = path, active = false } + used_names[name] = true end end - async.run(do_get):wait() if names ~= nil then -- Align result with input diff --git a/test/functional/plugin/pack_spec.lua b/test/functional/plugin/pack_spec.lua index 41f7c69cbc..700182c22a 100644 --- a/test/functional/plugin/pack_spec.lua +++ b/test/functional/plugin/pack_spec.lua @@ -135,6 +135,12 @@ end function repos_setup.plugindirs() init_test_repo('plugindirs') + -- Add semver tag + repo_write_file('plugindirs', 'lua/plugindirs.lua', 'return "plugindirs v0.0.1"') + git_add_commit('Add version v0.0.1', 'plugindirs') + git_cmd({ 'tag', 'v0.0.1' }, 'plugindirs') + + -- Add various 'plugin/' files repo_write_file('plugindirs', 'lua/plugindirs.lua', 'return "plugindirs main"') repo_write_file('plugindirs', 'plugin/dirs.lua', 'vim.g._plugin = true') repo_write_file('plugindirs', 'plugin/dirs_log.lua', '_G.DL = _G.DL or {}; DL[#DL+1] = "p"') @@ -1367,41 +1373,65 @@ describe('vim.pack', function() return res end + local make_plugindirs_data = function(active, info) + local spec = + { name = 'plugindirs', src = repos_src.plugindirs, version = vim.version.range('*') } + local path = pack_get_plug_path('plugindirs') + local rev = git_get_hash('v0.0.1', 'plugindirs') + local res = { active = active, path = path, spec = spec, rev = rev } + if info then + res.branches = { 'main' } + res.tags = { 'v0.0.1' } + end + return res + end + it('returns list with necessary data', function() - local basic_data, defbranch_data + local basic_data, defbranch_data, plugindirs_data -- Should work just after installation exec_lua(function() - vim.pack.add({ repos_src.defbranch, { src = repos_src.basic, version = 'feat-branch' } }) + vim.pack.add({ + repos_src.defbranch, + { src = repos_src.basic, version = 'feat-branch' }, + { src = repos_src.plugindirs, version = vim.version.range('*') }, + }) end) defbranch_data = make_defbranch_data(true, true) basic_data = make_basic_data(true, true) + plugindirs_data = make_plugindirs_data(true, true) -- Should preserve order in which plugins were `vim.pack.add()`ed - eq({ defbranch_data, basic_data }, exec_lua('return vim.pack.get()')) + eq({ defbranch_data, basic_data, plugindirs_data }, exec_lua('return vim.pack.get()')) -- Should also list non-active plugins n.clear() exec_lua(function() - vim.pack.add({ { src = repos_src.basic, version = 'feat-branch' } }) + vim.pack.add({ repos_src.defbranch }) end) - defbranch_data = make_defbranch_data(false, true) - basic_data = make_basic_data(true, true) - -- Should first list active, then non-active - eq({ basic_data, defbranch_data }, exec_lua('return vim.pack.get()')) + defbranch_data = make_defbranch_data(true, true) + basic_data = make_basic_data(false, true) + plugindirs_data = make_plugindirs_data(false, true) + -- Should first list active, then non-active (including their latest + -- set `version` which is inferred from lockfile) + eq({ defbranch_data, basic_data, plugindirs_data }, exec_lua('return vim.pack.get()')) -- Should respect `names` for both active and not active plugins eq({ basic_data }, exec_lua('return vim.pack.get({ "basic" })')) eq({ defbranch_data }, exec_lua('return vim.pack.get({ "defbranch" })')) - eq({ defbranch_data, basic_data }, exec_lua('return vim.pack.get({ "defbranch", "basic" })')) + eq({ basic_data, defbranch_data }, exec_lua('return vim.pack.get({ "basic", "defbranch" })')) local bad_get_cmd = 'return vim.pack.get({ "ccc", "basic", "aaa" })' matches('Plugin `ccc` is not installed', pcall_err(exec_lua, bad_get_cmd)) -- Should respect `opts.info` - defbranch_data = make_defbranch_data(false, false) - basic_data = make_basic_data(true, false) - eq({ basic_data, defbranch_data }, exec_lua('return vim.pack.get(nil, { info = false })')) + defbranch_data = make_defbranch_data(true, false) + basic_data = make_basic_data(false, false) + plugindirs_data = make_plugindirs_data(false, false) + eq( + { defbranch_data, basic_data, plugindirs_data }, + exec_lua('return vim.pack.get(nil, { info = false })') + ) eq({ basic_data }, exec_lua('return vim.pack.get({ "basic" }, { info = false })')) eq({ defbranch_data }, exec_lua('return vim.pack.get({ "defbranch" }, { info = false })')) end)