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
3 changes: 2 additions & 1 deletion lua/guh/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ M.s = {
html_comments_command = { 'lynx', '-stdin', '-dump' },
keymaps = {
diff = {
comment = 'cc',
open_file = 'gf',
open_file_tab = '',
open_file_split = 'o',
Expand All @@ -27,7 +28,7 @@ M.s = {
approve = 'cA',
request_changes = 'cR',
merge = 'cM',
comment = 'ca',
comment = 'cc',
diff = 'cp',
},
},
Expand Down
103 changes: 40 additions & 63 deletions lua/guh/diff.lua
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,12 @@ function M.load_pr_diff()
local diff_content_lines = vim.split(diff_content, '\n')
construct_mappings(diff_content_lines, function()
vim.schedule(function()
vim.api.nvim_buf_set_name(
buf,
'PR Diff: ' .. selected_pr.number .. ' (' .. os.date('%Y-%m-%d %H:%M:%S') .. ')'
)
buf = state.try_set_buf_name(buf, 'diff', selected_pr.number)
Copy link
Owner Author

@justinmk justinmk Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test diff.lua line 82

state.diff_buffer_id = buf

vim.bo[buf].buftype = 'nofile'
vim.bo[buf].readonly = false
vim.bo[buf].modifiable = true
Copy link
Owner Author

@justinmk justinmk Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test diff.lua line 87


vim.api.nvim_buf_set_lines(buf, 0, -1, false, diff_content_lines)

Expand All @@ -99,65 +98,43 @@ function M.load_pr_diff()
vim.bo[buf].readonly = true
vim.bo[buf].modifiable = false

if not utils.is_empty(config.s.keymaps.diff.open_file) then
vim.api.nvim_buf_set_keymap(
buf,
'n',
config.s.keymaps.diff.open_file,
'',
{ desc = 'Open file', noremap = true, silent = true, callback = open_file_from_diff('edit') }
)
end

if not utils.is_empty(config.s.keymaps.diff.open_file_tab) then
vim.api.nvim_buf_set_keymap(
buf,
'n',
config.s.keymaps.diff.open_file_tab,
'',
{ desc = 'Open file in tab', noremap = true, silent = true, callback = open_file_from_diff('tabedit') }
)
end

if not utils.is_empty(config.s.keymaps.diff.open_file_split) then
vim.api.nvim_buf_set_keymap(
buf,
'n',
config.s.keymaps.diff.open_file_split,
'',
{ desc = 'Open file in split', noremap = true, silent = true, callback = open_file_from_diff('split') }
)
end

if not utils.is_empty(config.s.keymaps.diff.open_file_vsplit) then
vim.api.nvim_buf_set_keymap(
buf,
'n',
config.s.keymaps.diff.open_file_vsplit,
'',
{ desc = 'Open file in vertical split', noremap = true, silent = true, callback = open_file_from_diff('vsplit') }
)
end

if not utils.is_empty(config.s.keymaps.diff.approve) then
vim.api.nvim_buf_set_keymap(
buf,
'n',
config.s.keymaps.diff.approve,
'',
{ desc = 'Approve PR', noremap = true, silent = true, callback = pr_commands.approve_pr }
)
end

if not utils.is_empty(config.s.keymaps.diff.request_changes) then
vim.api.nvim_buf_set_keymap(
buf,
'n',
config.s.keymaps.diff.request_changes,
'',
{ desc = 'Request PR changes', noremap = true, silent = true, callback = pr_commands.request_changes_pr }
)
end
utils.buf_keymap(buf, 'n', config.s.keymaps.diff.open_file, 'Open file', open_file_from_diff('edit'))
Copy link
Owner Author

@justinmk justinmk Sep 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test comment line 101 diff.lua

Copy link
Owner Author

@justinmk justinmk Oct 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test diff.lua line 101

Copy link
Owner Author

@justinmk justinmk Oct 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another comment on diff.lua line 101

utils.buf_keymap(
buf,
'n',
config.s.keymaps.diff.comment,
'Comment on current line',
'<cmd>GuhCommentLine<cr>'
)
utils.buf_keymap(
buf,
'n',
config.s.keymaps.diff.open_file_tab,
'Open file in tab',
open_file_from_diff('tabedit')
)
utils.buf_keymap(
buf,
'n',
config.s.keymaps.diff.open_file_split,
'Open file in split',
open_file_from_diff('split')
)
utils.buf_keymap(
buf,
'n',
config.s.keymaps.diff.open_file_vsplit,
'Open file in vertical split',
open_file_from_diff('vsplit')
)
utils.buf_keymap(buf, 'n', config.s.keymaps.diff.approve, 'Approve PR', pr_commands.approve_pr)
utils.buf_keymap(
buf,
'n',
config.s.keymaps.diff.request_changes,
'Request PR changes',
pr_commands.request_changes_pr
)

progress('success')
progress = utils.new_progress_report('Loading diff comments')
Expand Down
38 changes: 18 additions & 20 deletions lua/guh/gh.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,26 @@ end
function M.get_current_pr(cb)
utils.system_str_cb(
'gh pr view --json headRefName,headRefOid,number,baseRefName,baseRefOid,reviewDecision',
vim.schedule_wrap(
function(result, stderr)
local prefix = 'Unknown JSON field'
if result == nil then
cb(nil)
return
elseif string.sub(stderr, 1, #prefix) == prefix then
utils.system_str_cb(
'gh pr view --json headRefName,headRefOid,number,baseRefName,reviewDecision',
function(result2)
if result2 == nil then
cb(nil)
return
end
cb(parse_or_default(result2, nil))
vim.schedule_wrap(function(result, stderr)
local prefix = 'Unknown JSON field'
if result == nil then
cb(nil)
return
elseif string.sub(stderr, 1, #prefix) == prefix then
utils.system_str_cb(
'gh pr view --json headRefName,headRefOid,number,baseRefName,reviewDecision',
function(result2)
if result2 == nil then
cb(nil)
return
end
)
else
cb(parse_or_default(result, nil))
end
cb(parse_or_default(result2, nil))
end
)
else
cb(parse_or_default(result, nil))
end
)
end)
)
end

Expand Down
61 changes: 13 additions & 48 deletions lua/guh/pr_commands.lua
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,12 @@ local function show_pr_info(pr_info)
end

local buf = state.get_buf('info', pr_info.number)
vim.api.nvim_buf_set_name(buf, 'PR View: ' .. pr_info.number .. ' (' .. os.date('%Y-%m-%d %H:%M:%S') .. ')')
buf = state.try_set_buf_name(buf, 'info', pr_info.number)

vim.bo[buf].buftype = 'nofile'
vim.bo[buf].filetype = 'markdown'
vim.bo[buf].readonly = false
vim.bo[buf].modifiable = true

vim.api.nvim_buf_set_lines(buf, 0, -1, false, pr_view)

Expand All @@ -181,52 +183,13 @@ local function show_pr_info(pr_info)
vim.bo[buf].readonly = true
vim.bo[buf].modifiable = false

if not utils.is_empty(config.s.keymaps.pr.approve) then
vim.api.nvim_buf_set_keymap(
buf,
'n',
config.s.keymaps.pr.approve,
'',
{ desc = 'Approve PR', noremap = true, silent = true, callback = M.approve_pr }
)
end
if not utils.is_empty(config.s.keymaps.pr.request_changes) then
vim.api.nvim_buf_set_keymap(
buf,
'n',
config.s.keymaps.pr.request_changes,
'',
{ desc = 'Request PR changes', noremap = true, silent = true, callback = M.request_changes_pr }
)
end
if not utils.is_empty(config.s.keymaps.pr.merge) then
vim.api.nvim_buf_set_keymap(
buf,
'n',
config.s.keymaps.pr.merge,
'',
{ desc = 'Merge PR in remote repo', noremap = true, silent = true, callback = M.merge_pr }
)
end
if not utils.is_empty(config.s.keymaps.pr.comment) then
vim.api.nvim_buf_set_keymap(buf, 'n', config.s.keymaps.pr.comment, '', {
desc = 'Comment on PR',
noremap = true,
silent = true,
callback = function()
M.comment_on_pr(M.load_pr_view)
end,
})
end
if not utils.is_empty(config.s.keymaps.pr.diff) then
vim.api.nvim_buf_set_keymap(
buf,
'n',
config.s.keymaps.pr.diff,
':GuhDiff<cr>',
{ desc = 'View the PR diff', noremap = true, silent = true }
)
end
utils.buf_keymap(buf, 'n', config.s.keymaps.pr.approve, 'Approve PR', M.approve_pr)
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test comment around line 200 in pr_commands.lua

utils.buf_keymap(buf, 'n', config.s.keymaps.pr.request_changes, 'Request PR changes', M.request_changes_pr)
utils.buf_keymap(buf, 'n', config.s.keymaps.pr.merge, 'Merge PR in remote repo', M.merge_pr)
utils.buf_keymap(buf, 'n', config.s.keymaps.pr.comment, 'Comment on PR', function()
M.comment_on_pr(M.load_pr_view)
end)
utils.buf_keymap(buf, 'n', config.s.keymaps.pr.diff, 'View the PR diff', ':GuhDiff<cr>')

vim.bo.busy = 0
end)
Expand All @@ -238,7 +201,9 @@ local function load_pr_view_for_pr(selected_pr)
return
end

vim.bo.busy = 1
vim.schedule(function()
vim.bo.busy = 1
end)
gh.get_pr_info(selected_pr.number, show_pr_info)
end

Expand Down
36 changes: 24 additions & 12 deletions lua/guh/state.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,45 @@ M.comments_list = {}
--- @type integer|nil Diff view buffer id
M.diff_buffer_id = nil

--- @type table<string, table<number, number>>
M.filename_line_to_diff_line = {}

--- @type table<number, FileNameAndLinePair>
M.diff_line_to_filename_line = {}

--- feat+prnum => bufnr
local bufs = {
---@type table<string, integer>
diff = {
},
diff = {},
---@type table<string, integer>
info = {
},
info = {},
}

--- Gets the buf for the given PR + feature, or creates a new one if not found.
--- @param feat 'diff'|'info'
--- @param prnum string
--- @param prnum string|number
function M.get_buf(feat, prnum)
local prnumstr = tostring(prnum)
local b = bufs[feat][prnumstr]
if type(b) ~= 'number' or vim.api.nvim_buf_is_valid(b) then
b = vim.api.nvim_create_buf(false, true)
b = vim.api.nvim_create_buf(true, true)
bufs[feat][prnumstr] = b
assert(type(b) == 'number')
end
return b
end

function M.try_set_buf_name(buf, feat, prnum)
local bufname = ('guh://%s/%s'):format(feat, prnum)
local foundbuf = vim.fn.bufnr(bufname)
if foundbuf > 0 and buf ~= foundbuf then
vim.api.nvim_set_current_buf(foundbuf)
-- XXX fucking hack because Vim creates new buffer after (re)naming it.
bufs[feat][tostring(prnum)] = foundbuf
return foundbuf
end
-- if not vim.api.nvim_buf_get_name(buf):match('guh%:') then
vim.api.nvim_buf_set_name(buf, ('guh://%s/%s'):format(feat, prnum))
-- XXX fucking hack because Vim creates new buffer after (re)naming it.
bufs[feat][tostring(prnum)] = buf
return buf
-- end
end
Comment on lines +47 to +51
Copy link
Owner Author

@justinmk justinmk Oct 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test comment state.lua lines 47-51

wefa
ewf
awe
fa
wef

code sample:

print('')


M.bufs = bufs

return M
27 changes: 13 additions & 14 deletions lua/guh/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,17 @@ function M.new_progress_report(action)
end)
end

function M.buf_keymap(buf, mode, lhs, desc, rhs)
if not M.is_empty(lhs) then
local opts = {}
opts.desc = opts.desc == nil and desc or opts.desc
opts.noremap = opts.noremap == nil and true or opts.noremap
opts.silent = opts.silent == nil and true or opts.silent
opts.buffer = buf
vim.keymap.set(mode, lhs, rhs, opts)
end
end

function M.get_comment(buf_name, split_command, prompt, content, key_binding, callback)
local buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_name(buf, buf_name)
Expand All @@ -105,20 +116,8 @@ function M.get_comment(buf_name, split_command, prompt, content, key_binding, ca
callback(input)
end

vim.api.nvim_buf_set_keymap(
buf,
'n',
key_binding,
'',
{ noremap = true, silent = true, callback = capture_input_and_close }
)
vim.api.nvim_buf_set_keymap(
buf,
'i',
key_binding,
'',
{ noremap = true, silent = true, callback = capture_input_and_close }
)
M.buf_keymap(buf, 'n', key_binding, '', capture_input_and_close)
M.buf_keymap(buf, 'i', key_binding, '', capture_input_and_close)
Comment on lines +119 to +120
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test comment utils.lua

end

return M
2 changes: 1 addition & 1 deletion plugin/guh.lua
Original file line number Diff line number Diff line change
@@ -1 +1 @@
require('guh').setup{}
require('guh').setup({})