feat(gh): when selecting lines in a diff to add a review comment, you can now suggest code changes. See #2463

This commit is contained in:
Folke Lemaitre 2025-11-07 06:37:04 +01:00
parent a4e46becca
commit e896fb93f6
No known key found for this signature in database
GPG key ID: 9B52594D560070AB
3 changed files with 26 additions and 3 deletions

View file

@ -280,14 +280,29 @@ M.actions.gh_comment = {
local line = m.diff.line ---@type number
local start_line ---@type number?
if visual then
local line_diff = vim.tbl_get(meta, visual.end_pos[1], "diff") or m.diff --[[@as {file: string, line: number, side: string}]]
local start_diff = vim.tbl_get(meta, visual.pos[1], "diff") or m.diff --[[@as {file: string, line: number, side: string}]]
local from, to = math.min(visual.pos[1], visual.end_pos[1]), math.max(visual.pos[1], visual.end_pos[1])
local line_diff = vim.tbl_get(meta, to, "diff") or m.diff --[[@as snacks.diff.Meta]]
local start_diff = vim.tbl_get(meta, from, "diff") or m.diff --[[@as snacks.diff.Meta]]
if line_diff.file ~= start_diff.file then
Snacks.notify.error("Cannot add comment: visual selection spans multiple files")
return
end
local code = {} ---@type string[]
for i = from, to do
code[#code + 1] = vim.tbl_get(meta, i, "diff", "code") or ""
end
line, start_line = line_diff.line, start_diff.line
start_line, line = math.min(start_line or line, line), math.max(start_line or line, line)
local ft = vim.filetype.match({ filename = m.diff.file }) or ""
local code_header = "```" .. (ft == "" and "" or (ft .. " ")) .. "suggestion\n"
action.template = ("\n%s%s\n```\n"):format(code_header, table.concat(code, "\n"))
action.on_submit = function(body)
local s, e = body:find(action.template, 1, true)
if s and e then -- suggestion not edited, so remove it
body = body:sub(1, s - 1) .. body:sub(e + 1)
end
body = body:gsub(code_header, "```suggestion\n") -- remove ft from suggestion
return body
end
end
start_line = start_line ~= line and start_line or nil
if start_line then
@ -768,6 +783,10 @@ function M.submit(ctx)
return -- error already shown in M.parse
end
if ctx.opts.on_submit then
body = ctx.opts.on_submit(body, ctx) or body
end
if body:find("%S") then
if edit == "body-file" then
if ctx.opts.api then

View file

@ -60,6 +60,7 @@
---@field success? string -- success message to show after the action
---@field confirm? string -- confirmation message to show before performing the action
---@field refresh? boolean -- whether to refresh the item after performing the action (default: true)
---@field on_submit? fun(body: string, ctx: snacks.gh.cli.Action.ctx): string?
---@class snacks.gh.api.Fetch: snacks.gh.api.Cmd
---@field fields string[]

View file

@ -17,6 +17,7 @@ local M = {}
---@field side "left" | "right"
---@field file string
---@field line number
---@field code string
---@class snacks.diff.ctx
---@field diff snacks.picker.Diff
@ -407,10 +408,12 @@ function M.format_hunk(ctx)
line[#line + 1] = {
"",
meta = {
---@type snacks.diff.Meta
diff = {
side = have_right and "right" or "left",
file = block.file,
line = have_right and index[l][#parse.versions] or index[l][1],
code = parse.lines[l],
},
},
}