diff options
| author | Evgeni Chasnovski <evgeni.chasnovski@gmail.com> | 2025-10-05 19:17:52 +0300 |
|---|---|---|
| committer | Evgeni Chasnovski <evgeni.chasnovski@gmail.com> | 2025-10-05 19:20:06 +0300 |
| commit | 98e3a571ddf4bfa02fbd98f547b75f5335b3766d (patch) | |
| tree | 5b8aa0179fe9cd8e61ac2cd18ff2a792f9be5053 /runtime/lua/vim/pack.lua | |
| parent | 2728b4efe03056a14c2c6b09f8186f9244e8cf58 (diff) | |
| download | rneovim-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.lua | 57 |
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 |