Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 46 additions & 1 deletion lua/snacks/gh/actions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,24 @@ local function get_meta(item, ctx)
return
end
local meta = Snacks.picker.highlight.meta(buf)
---@type {comment_id?: number, diff?: snacks.diff.Meta}?
---@type {comment_id?: number, edit_comment_id?: number, diff?: snacks.diff.Meta}?
local m = meta and meta[vim.api.nvim_win_get_cursor(win)[1]] or nil
return m, meta, buf, win
end

---@param item snacks.picker.gh.Item
---@param id number
---@return snacks.gh.Comment?
local function find_comment(item, id)
for _, review in ipairs(item.reviews or {}) do
for _, comment in ipairs(review.comments or {}) do
if comment.databaseId == id then
return comment
end
end
end
end

---@class snacks.gh.actions: {[string]:snacks.gh.Action}
M.actions = setmetatable({}, {
__index = function(_, key)
Expand Down Expand Up @@ -295,6 +308,38 @@ M.actions.gh_reply_to_comment = {
end,
}

M.actions.gh_edit_comment = {
desc = "Edit comment",
title = "Edit comment on {type} #{number}",
priority = 150,
icon = " ",
enabled = function(item, ctx)
local m = get_meta(item, ctx)
return m and m.edit_comment_id ~= nil or false
end,
action = function(item, ctx)
local m = get_meta(item, ctx)
if not (m and m.edit_comment_id) then
Snacks.notify.error("No comment found to edit")
return
end
local comment = find_comment(item, m.edit_comment_id)
if not comment then
Snacks.notify.error("Could not find comment to edit")
return
end
local action = vim.deepcopy(M.cli_actions.gh_comment)
action.title = "Edit comment on {type} #{number}"
action.success = "Edited comment on {type} #{number}"
action.template = comment.body
action.api = {
endpoint = "/repos/{repo}/pulls/comments/" .. m.edit_comment_id,
method = "PATCH",
}
M.run(item, action, ctx)
end,
}

M.actions.gh_diff_comment = {
desc = "Add diff comment",
title = "Comment on diff in {type} #{number}",
Expand Down
1 change: 1 addition & 0 deletions lua/snacks/gh/api.lua
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@ function M.comments(item, cb)
createdAt
subjectType
author { login }
viewerDidAuthor
replyTo { id databaseId }
reactionGroups {
content
Expand Down
10 changes: 9 additions & 1 deletion lua/snacks/gh/render/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -534,18 +534,26 @@ function M.comment(comment, ctx)
end

vim.list_extend(ret, M.comment_body(comment, ctx))
-- lines belonging to this comment alone, before any replies get appended below.
-- comment_id (added further down) always resolves to the thread's root comment,
-- since replying requires anchoring to the root; edit_comment_id instead tags
-- only these lines, so editing targets the exact comment under the cursor.
local own_lines = #ret
local replies = M.find_reply(comment.id, ctx)
for _, reply in ipairs(replies) do
ret[#ret + 1] = {} -- empty line between comment and reply
vim.list_extend(ret, M.comment(reply, ctx))
ctx.comment_skip[reply.id] = true
end
if ctx.is_review then
for _, line in ipairs(ret) do
for i, line in ipairs(ret) do
local reply_id = comment.replyTo and comment.replyTo.databaseId or comment.databaseId
if reply_id then
line[#line + 1] = { "", meta = { comment_id = reply_id } }
end
if i <= own_lines and comment.viewerDidAuthor and comment.databaseId then
line[#line + 1] = { "", meta = { edit_comment_id = comment.databaseId } }
end
end
end
ret = M.indent(ret, ctx)
Expand Down