neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

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:
Mruntime/doc/lua-plugin.txt | 4++--
Mruntime/doc/pack.txt | 8++++----
Mruntime/ftplugin/nvim-pack.lua | 4++--
Mruntime/lua/vim/pack.lua | 32++++++++++++++++----------------
Mruntime/lua/vim/pack/_lsp.lua | 4++--
Mtest/functional/plugin/pack_spec.lua | 72++++++++++++++++++++++++++++++++++++++----------------------------------
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))