commit 72110da567d761195912236222e0cbdebb0cc003
parent d2517acdc5fb16ff7aff038d421622322f20ecd6
Author: Justin M. Keyes <justinkz@gmail.com>
Date: Thu, 13 Nov 2025 02:00:05 -0500
Merge #36468 from echasnovski/pack-consistency
`vim.pack` consistency improvements: full hashes, state->revision, buffer URI name
Diffstat:
6 files changed, 64 insertions(+), 60 deletions(-)
diff --git a/runtime/doc/lua-plugin.txt b/runtime/doc/lua-plugin.txt
@@ -282,8 +282,8 @@ mappings to a specific action by invoking `vim.lsp.buf.code_action()` with the
<
Example: See `runtime/lua/vim/pack/_lsp.lua` for how vim.pack defines an
-in-process LSP server to provide interactive features in its `nvim-pack://`
-buffer.
+in-process LSP server to provide interactive features in its
+`nvim://pack-confirm` buffer.
==============================================================================
Troubleshooting *lua-plugin-troubleshooting*
diff --git a/runtime/doc/pack.txt b/runtime/doc/pack.txt
@@ -273,7 +273,7 @@ Basic install and management:
Switch plugin's version:
• Update 'init.lua' for plugin to have desired `version`. Let's say, plugin
named 'plugin1' has changed to `vim.version.range('*')`.
-• |:restart|. The plugin's actual state on disk is not yet changed. Only
+• |:restart|. The plugin's actual revision on disk is not yet changed. Only
plugin's `version` in |vim.pack-lockfile| is updated.
• Execute `vim.pack.update({ 'plugin1' })`.
• Review changes and either confirm or discard them. If discarded, revert any
@@ -356,7 +356,7 @@ add({specs}, {opts}) *vim.pack.add()*
|vim.pack-directory|:
• If exists, do nothing in this step.
• If doesn't exist, install it by downloading from `src` into `name`
- subdirectory (via `git clone`) and update state to match `version`
+ subdirectory (via `git clone`) and update revision to follow `version`
(via `git checkout`).
• For each plugin execute |:packadd| (or customizable `load` function)
making it reachable by Nvim.
@@ -365,7 +365,7 @@ add({specs}, {opts}) *vim.pack.add()*
• Installation is done in parallel, but waits for all to finish before
continuing next code execution.
• If plugin is already present on disk, there are no checks about its
- present state. The specified `version` can be not the one actually
+ current revision. The specified `version` can be not the one actually
present on disk. Execute |vim.pack.update()| to synchronize.
• Adding plugin second and more times during single session does nothing:
only the data from the first adding is registered.
@@ -416,7 +416,7 @@ get({names}, {opts}) *vim.pack.get()*
update({names}, {opts}) *vim.pack.update()*
Update plugins
• Download new changes from source.
- • Infer update info (current/target state, changelog, etc.).
+ • Infer update info (current/target revisions, changelog, etc.).
• Depending on `force`:
• If `false`, show confirmation buffer. It lists data about all set to
update plugins. Pending changes starting with `>` will be applied
diff --git a/runtime/ftplugin/nvim-pack.lua b/runtime/ftplugin/nvim-pack.lua
@@ -18,7 +18,7 @@ local cur_header_hl_group = nil
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
for i, l in ipairs(lines) do
local cur_group = l:match('^# (%S+)')
- local cur_info = l:match('^Path: +') or l:match('^Source: +') or l:match('^State[^:]*: +')
+ local cur_info = l:match('^Path: +') or l:match('^Source: +') or l:match('^Revision[^:]*: +')
if cur_group ~= nil then
--- @cast cur_group string
-- Header 1
@@ -32,7 +32,7 @@ for i, l in ipairs(lines) do
local end_col = l:match('(). +%b()$') or l:len()
hi_range(i, cur_info:len(), end_col, 'DiagnosticInfo')
- -- Plugin state after update
+ -- Plugin version after update
local col = l:match('() %b()$')
if col then
hi_range(i, col, l:len(), 'DiagnosticHint')
diff --git a/runtime/lua/vim/pack.lua b/runtime/lua/vim/pack.lua
@@ -70,7 +70,7 @@
---Switch plugin's version:
---- Update 'init.lua' for plugin to have desired `version`. Let's say, plugin
---named 'plugin1' has changed to `vim.version.range('*')`.
----- |:restart|. The plugin's actual state on disk is not yet changed.
+---- |:restart|. The plugin's actual revision on disk is not yet changed.
--- Only plugin's `version` in |vim.pack-lockfile| is updated.
---- Execute `vim.pack.update({ 'plugin1' })`.
---- Review changes and either confirm or discard them. If discarded, revert
@@ -193,7 +193,7 @@ end
local function git_get_hash(ref, cwd)
-- Using `rev-list -1` shows a commit of reference, while `rev-parse` shows
-- hash of reference. Those are different for annotated tags.
- return git_cmd({ 'rev-list', '-1', '--abbrev-commit', ref }, cwd)
+ return git_cmd({ 'rev-list', '-1', ref }, cwd)
end
--- @async
@@ -602,7 +602,7 @@ end
--- @async
--- @param p vim.pack.Plug
-local function infer_states(p)
+local function infer_revisions(p)
p.info.sha_head = p.info.sha_head or git_get_hash('HEAD', p.path)
resolve_version(p)
@@ -616,7 +616,7 @@ end
--- @param p vim.pack.Plug
--- @param timestamp string
local function checkout(p, timestamp)
- infer_states(p)
+ infer_revisions(p)
local msg = ('vim.pack: %s Stash before checkout'):format(timestamp)
git_cmd({ 'stash', '--quiet', '--message', msg }, p.path)
@@ -668,7 +668,7 @@ end
--- @param p vim.pack.Plug
local function infer_update_details(p)
p.info.update_details = ''
- infer_states(p)
+ infer_revisions(p)
local sha_head = assert(p.info.sha_head)
local sha_target = assert(p.info.sha_target)
@@ -756,14 +756,14 @@ end
--- - For each specification check that plugin exists on disk in |vim.pack-directory|:
--- - If exists, do nothing in this step.
--- - If doesn't exist, install it by downloading from `src` into `name`
---- subdirectory (via `git clone`) and update state to match `version` (via `git checkout`).
+--- subdirectory (via `git clone`) and update revision to follow `version` (via `git checkout`).
--- - For each plugin execute |:packadd| (or customizable `load` function) making
--- it reachable by Nvim.
---
--- Notes:
--- - Installation is done in parallel, but waits for all to finish before
--- continuing next code execution.
---- - If plugin is already present on disk, there are no checks about its present state.
+--- - If plugin is already present on disk, there are no checks about its current revision.
--- The specified `version` can be not the one actually present on disk.
--- Execute |vim.pack.update()| to synchronize.
--- - Adding plugin second and more times during single session does nothing:
@@ -850,9 +850,9 @@ local function compute_feedback_lines_single(p)
if p.info.sha_head == p.info.sha_target then
parts[#parts + 1] = table.concat({
- 'Path: ' .. p.path,
- 'Source: ' .. p.spec.src,
- 'State: ' .. p.info.sha_target .. version_suffix,
+ 'Path: ' .. p.path,
+ 'Source: ' .. p.spec.src,
+ 'Revision: ' .. p.info.sha_target .. version_suffix,
}, '\n')
if p.info.update_details ~= '' then
@@ -861,10 +861,10 @@ local function compute_feedback_lines_single(p)
end
else
parts[#parts + 1] = table.concat({
- 'Path: ' .. p.path,
- 'Source: ' .. p.spec.src,
- 'State before: ' .. p.info.sha_head,
- 'State after: ' .. p.info.sha_target .. version_suffix,
+ 'Path: ' .. p.path,
+ 'Source: ' .. p.spec.src,
+ 'Revision before: ' .. p.info.sha_head,
+ 'Revision after: ' .. p.info.sha_target .. version_suffix,
'',
'Pending updates:',
p.info.update_details,
@@ -923,7 +923,7 @@ end
local function show_confirm_buf(lines, on_finish)
-- Show buffer in a separate tabpage
local bufnr = api.nvim_create_buf(true, true)
- api.nvim_buf_set_name(bufnr, 'nvim-pack://' .. bufnr .. '/confirm-update')
+ api.nvim_buf_set_name(bufnr, 'nvim://pack-confirm#' .. bufnr)
api.nvim_buf_set_lines(bufnr, 0, -1, false, lines)
vim.cmd.sbuffer({ bufnr, mods = { tab = vim.fn.tabpagenr() } })
local tab_id = api.nvim_get_current_tabpage()
@@ -996,7 +996,7 @@ end
--- Update plugins
---
--- - Download new changes from source.
---- - Infer update info (current/target state, changelog, etc.).
+--- - Infer update info (current/target revisions, changelog, etc.).
--- - Depending on `force`:
--- - If `false`, show confirmation buffer. It lists data about all set to
--- update plugins. Pending changes starting with `>` will be applied while
diff --git a/runtime/lua/vim/pack/_lsp.lua b/runtime/lua/vim/pack/_lsp.lua
@@ -20,7 +20,7 @@ function methods.shutdown(_, callback)
end
local get_confirm_bufnr = function(uri)
- return tonumber(uri:match('^nvim%-pack://(%d+)/confirm%-update$'))
+ return tonumber(uri:match('^nvim://pack%-confirm#(%d+)$'))
end
local group_header_pattern = '^# (%S+)'
@@ -194,7 +194,7 @@ methods['textDocument/hover'] = function(params, callback)
local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
local lnum = params.position.line + 1
- local commit = lines[lnum]:match('^[<>] (%x+) │') or lines[lnum]:match('^State.*:%s+(%x+)')
+ local commit = lines[lnum]:match('^[<>] (%x+) │') or lines[lnum]:match('^Revision.*:%s+(%x+)')
local tag = lines[lnum]:match('^• (.+)$')
if commit == nil and tag == nil then
return
diff --git a/test/functional/plugin/pack_spec.lua b/test/functional/plugin/pack_spec.lua
@@ -103,6 +103,10 @@ local function git_add_commit(msg, repo_name)
end
local function git_get_hash(rev, repo_name)
+ return git_cmd({ 'rev-list', '-1', rev }, repo_name)
+end
+
+local function git_get_short_hash(rev, repo_name)
return git_cmd({ 'rev-list', '-1', '--abbrev-commit', rev }, repo_name)
end
@@ -906,8 +910,9 @@ describe('vim.pack', function()
describe('update()', function()
-- Lua source code for the tested plugin named "fetch"
local fetch_lua_file = vim.fs.joinpath(pack_get_plug_path('fetch'), 'lua', 'fetch.lua')
- -- Table with hashes used to test confirmation buffer and log content
+ -- Tables with hashes used to test confirmation buffer and log content
local hashes --- @type table<string,string>
+ local short_hashes --- @type table<string,string>
before_each(function()
-- Create a dedicated clean repo for which "push changes" will be mocked
@@ -920,6 +925,7 @@ describe('vim.pack', function()
git_add_commit('Commit from `main` to be removed', 'fetch')
hashes = { fetch_head = git_get_hash('HEAD', 'fetch') }
+ short_hashes = { fetch_head = git_get_short_hash('HEAD', 'fetch') }
-- Install initial versions of tested plugins
exec_lua(function()
@@ -981,7 +987,7 @@ describe('vim.pack', function()
local confirm_bufnr = api.nvim_get_current_buf()
local confirm_winnr = api.nvim_get_current_win()
local confirm_tabpage = api.nvim_get_current_tabpage()
- eq(api.nvim_buf_get_name(0), 'nvim-pack://' .. confirm_bufnr .. '/confirm-update')
+ eq(api.nvim_buf_get_name(0), 'nvim://pack-confirm#' .. confirm_bufnr)
-- Adjust lines for a more robust screenshot testing
local fetch_src = repos_src.fetch
@@ -1027,13 +1033,14 @@ describe('vim.pack', function()
screen = Screen.new(85, 35)
hashes.fetch_new = git_get_hash('main', 'fetch')
- hashes.fetch_new_prev = git_get_hash('main~', 'fetch')
+ short_hashes.fetch_new = git_get_short_hash('main', 'fetch')
+ short_hashes.fetch_new_prev = git_get_short_hash('main~', 'fetch')
hashes.semver_head = git_get_hash('v0.3.0', 'semver')
- local tab_name = 'n' .. (t.is_os('win') and ':' or '') .. '//2/confirm-update'
+ local tab_name = 'n' .. (t.is_os('win') and ':' or '') .. '//pack-confirm#2'
local screen_lines = {
- ('{24: [No Name] }{5: %s }{2:%s }{24:X}|'):format(
+ ('{24: [No Name] }{5: %s }{2:%s }{24:X}|'):format(
tab_name,
t.is_os('win') and '' or ' '
),
@@ -1048,32 +1055,28 @@ describe('vim.pack', function()
'{101:# Update ───────────────────────────────────────────────────────────────────────} |',
' |',
'{101:## fetch} |',
- 'Path: {103:FETCH_PATH} |',
- 'Source: {103:FETCH_SRC} |',
- ('State before: {103:%s} |'):format(
- hashes.fetch_head
- ),
- ('State after: {103:%s} {102:(main)} |'):format(
- hashes.fetch_new
- ),
+ 'Path: {103:FETCH_PATH} |',
+ 'Source: {103:FETCH_SRC} |',
+ ('Revision before: {103:%s} |'):format(hashes.fetch_head),
+ ('Revision after: {103:%s} {102:(main)} |'):format(hashes.fetch_new),
' |',
'Pending updates: |',
('{19:< %s │ Commit from `main` to be removed} |'):format(
- hashes.fetch_head
+ short_hashes.fetch_head
),
('{104:> %s │ Commit to be added 2} |'):format(
- hashes.fetch_new
+ short_hashes.fetch_new
),
('{104:> %s │ Commit to be added 1 (tag: dev-tag)} |'):format(
- hashes.fetch_new_prev
+ short_hashes.fetch_new_prev
),
' |',
'{102:# Same ─────────────────────────────────────────────────────────────────────────} |',
' |',
'{102:## semver} |',
- 'Path: {103:SEMVER_PATH} |',
- 'Source: {103:SEMVER_SRC} |',
- ('State: {103:%s} {102:(v0.3.0)} |'):format(
+ 'Path: {103:SEMVER_PATH} |',
+ 'Source: {103:SEMVER_SRC} |',
+ ('Revision: {103:%s} {102:(v0.3.0)} |'):format(
hashes.semver_head
),
' |',
@@ -1116,10 +1119,10 @@ describe('vim.pack', function()
# Update ───────────────────────────────────────────────────────────────────────
## fetch
- Path: %s
- Source: %s
- State before: %s
- State after: %s (main)
+ Path: %s
+ Source: %s
+ Revision before: %s
+ Revision after: %s (main)
Pending updates:
< %s │ Commit from `main` to be removed
@@ -1129,9 +1132,9 @@ describe('vim.pack', function()
fetch_src,
hashes.fetch_head,
hashes.fetch_new,
- hashes.fetch_head,
- hashes.fetch_new,
- hashes.fetch_new_prev
+ short_hashes.fetch_head,
+ short_hashes.fetch_new,
+ short_hashes.fetch_new_prev
)
eq(vim.text.indent(0, ref_log_lines), vim.trim(log_rest))
end)
@@ -1456,7 +1459,8 @@ describe('vim.pack', function()
-- Write to log file
hashes.fetch_new = git_get_hash('main', 'fetch')
- hashes.fetch_new_prev = git_get_hash('main~', 'fetch')
+ short_hashes.fetch_new = git_get_short_hash('main', 'fetch')
+ short_hashes.fetch_new_prev = git_get_short_hash('main~', 'fetch')
local log_path = vim.fs.joinpath(fn.stdpath('log'), 'nvim-pack.log')
local log_text = fn.readblob(log_path)
@@ -1466,10 +1470,10 @@ describe('vim.pack', function()
# Update ───────────────────────────────────────────────────────────────────────
## fetch
- Path: %s
- Source: %s
- State before: %s
- State after: %s (main)
+ Path: %s
+ Source: %s
+ Revision before: %s
+ Revision after: %s (main)
Pending updates:
< %s │ Commit from `main` to be removed
@@ -1479,9 +1483,9 @@ describe('vim.pack', function()
fetch_src,
hashes.fetch_head,
hashes.fetch_new,
- hashes.fetch_head,
- hashes.fetch_new,
- hashes.fetch_new_prev
+ short_hashes.fetch_head,
+ short_hashes.fetch_new,
+ short_hashes.fetch_new_prev
)
eq(vim.text.indent(0, ref_log_lines), vim.trim(log_rest))