aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/pack.lua
diff options
context:
space:
mode:
authorEvgeni Chasnovski <evgeni.chasnovski@gmail.com>2025-10-05 19:17:52 +0300
committerEvgeni Chasnovski <evgeni.chasnovski@gmail.com>2025-10-05 19:20:06 +0300
commit98e3a571ddf4bfa02fbd98f547b75f5335b3766d (patch)
tree5b8aa0179fe9cd8e61ac2cd18ff2a792f9be5053 /runtime/lua/vim/pack.lua
parent2728b4efe03056a14c2c6b09f8186f9244e8cf58 (diff)
downloadrneovim-98e3a571ddf4bfa02fbd98f547b75f5335b3766d.tar.gz
rneovim-98e3a571ddf4bfa02fbd98f547b75f5335b3766d.tar.bz2
rneovim-98e3a571ddf4bfa02fbd98f547b75f5335b3766d.zip
feat(pack): add code actions in confirmation buffer
Problem: No way to granularly operate on plugins when inside confirmation buffer. Solution: Implement code actions for in-process LSP that act on "plugin at cursor": - Update (if has updates). - Skip updating (if has updates). - Delete. Activate via default `gra` or `vim.lsp.buf.code_action()`.
Diffstat (limited to 'runtime/lua/vim/pack.lua')
-rw-r--r--runtime/lua/vim/pack.lua57
1 files changed, 42 insertions, 15 deletions
diff --git a/runtime/lua/vim/pack.lua b/runtime/lua/vim/pack.lua
index 35952243b9..b7e396febe 100644
--- a/runtime/lua/vim/pack.lua
+++ b/runtime/lua/vim/pack.lua
@@ -897,7 +897,7 @@ local function feedback_log(plug_list)
end
--- @param lines string[]
---- @param on_finish fun()
+--- @param on_finish fun(bufnr: integer)
local function show_confirm_buf(lines, on_finish)
-- Show buffer in a separate tabpage
local bufnr = api.nvim_create_buf(true, true)
@@ -917,7 +917,7 @@ local function show_confirm_buf(lines, on_finish)
-- Define action on accepting confirm
local function finish()
- on_finish()
+ on_finish(bufnr)
delete_buffer()
end
-- - Use `nested` to allow other events (useful for statuslines)
@@ -945,6 +945,28 @@ local function show_confirm_buf(lines, on_finish)
vim.lsp.buf_attach_client(bufnr, require('vim.pack._lsp').client_id)
end
+--- Get map of plugin names that need update based on confirmation buffer
+--- content: all plugin sections present in "# Update" section.
+--- @param bufnr integer
+--- @return table<string,boolean>
+local function get_update_map(bufnr)
+ local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
+ --- @type table<string,boolean>, boolean
+ local res, is_in_update = {}, false
+ for _, l in ipairs(lines) do
+ local name = l:match('^## (.+)$')
+ if name and is_in_update then
+ res[name] = true
+ end
+
+ local group = l:match('^# (%S+)')
+ if group then
+ is_in_update = group == 'Update'
+ end
+ end
+ return res
+end
+
--- @class vim.pack.keyset.update
--- @inlinedoc
--- @field force? boolean Whether to skip confirmation and make updates immediately. Default `false`.
@@ -966,6 +988,9 @@ end
--- - 'textDocument/hover' (`K` via |lsp-defaults| or |vim.lsp.buf.hover()|) -
--- show more information at cursor. Like details of particular pending
--- change or newer tag.
+--- - 'textDocument/codeAction' (`gra` via |lsp-defaults| or |vim.lsp.buf.code_action()|) -
+--- show code actions available for "plugin at cursor". Like "delete", "update",
+--- or "skip updating".
---
--- Execute |:write| to confirm update, execute |:quit| to discard the update.
--- - If `true`, make updates right away.
@@ -996,11 +1021,11 @@ function M.update(names, opts)
--- @param p vim.pack.Plug
local function do_update(p)
-- Fetch
- -- Using '--tags --force' means conflicting tags will be synced with remote
- git_cmd(
- { 'fetch', '--quiet', '--tags', '--force', '--recurse-submodules=yes', 'origin' },
- p.path
- )
+ if not opts._offline then
+ -- Using '--tags --force' means conflicting tags will be synced with remote
+ local args = { 'fetch', '--quiet', '--tags', '--force', '--recurse-submodules=yes', 'origin' }
+ git_cmd(args, p.path)
+ end
-- Compute change info: changelog if any, new tags if nothing to update
infer_update_details(p)
@@ -1010,7 +1035,8 @@ function M.update(names, opts)
checkout(p, timestamp, true)
end
end
- local progress_title = opts.force and 'Updating' or 'Downloading updates'
+ local progress_title = opts.force and (opts._offline and 'Applying updates' or 'Updating')
+ or 'Downloading updates'
run_list(plug_list, do_update, progress_title)
if opts.force then
@@ -1021,17 +1047,18 @@ function M.update(names, opts)
-- Show report in new buffer in separate tabpage
local lines = compute_feedback_lines(plug_list, false)
- show_confirm_buf(lines, function()
- -- TODO(echasnovski): Allow to not update all plugins via LSP code actions
- --- @param p vim.pack.Plug
- local plugs_to_checkout = vim.tbl_filter(function(p)
- return p.info.err == '' and p.info.sha_head ~= p.info.sha_target
- end, plug_list)
- if #plugs_to_checkout == 0 then
+ show_confirm_buf(lines, function(bufnr)
+ local to_update = get_update_map(bufnr)
+ if not next(to_update) then
notify('Nothing to update', 'WARN')
return
end
+ --- @param p vim.pack.Plug
+ local plugs_to_checkout = vim.tbl_filter(function(p)
+ return to_update[p.spec.name]
+ end, plug_list)
+
local timestamp2 = get_timestamp()
--- @async
--- @param p vim.pack.Plug