feat(forge): add gx keymap to open forge links in browser
Problem: Forge shorthand tokens like `gh:user/repo#42` are concealed in the buffer so Neovim's built-in `gx` cannot recognize them as URLs. Full URLs are also concealed, making `gx` unreliable. Solution: Add `open_link` action (default `gx`) that reads `forge_spans` from line metadata. If the cursor is on a forge token, that link opens; otherwise the last ref on the line is used. Delegates to `vim.ui.open()`.
This commit is contained in:
parent
f3ef1ca0db
commit
5c8320f5b5
4 changed files with 42 additions and 0 deletions
|
|
@ -349,6 +349,7 @@ Default buffer-local keys: ~
|
||||||
`gb` Toggle blocked status (`blocked`)
|
`gb` Toggle blocked status (`blocked`)
|
||||||
`g/` Toggle cancelled status (`cancelled`)
|
`g/` Toggle cancelled status (`cancelled`)
|
||||||
`ge` Open markdown detail buffer for task notes (`edit_notes`)
|
`ge` Open markdown detail buffer for task notes (`edit_notes`)
|
||||||
|
`gx` Open the forge link under the cursor in a browser (`open_link`)
|
||||||
`gf` Prompt for filter predicates (`filter`)
|
`gf` Prompt for filter predicates (`filter`)
|
||||||
`<Tab>` Switch between category / queue view (`view`)
|
`<Tab>` Switch between category / queue view (`view`)
|
||||||
`gz` Undo the last `:w` save (`undo`)
|
`gz` Undo the last `:w` save (`undo`)
|
||||||
|
|
@ -494,6 +495,13 @@ old keys to `false`: >lua
|
||||||
Shows a read-only metadata header and editable notes below a `---`
|
Shows a read-only metadata header and editable notes below a `---`
|
||||||
separator. Press `q` to return to the task list. Default key: `ge`.
|
separator. Press `q` to return to the task list. Default key: `ge`.
|
||||||
|
|
||||||
|
*<Plug>(pending-open-link)*
|
||||||
|
<Plug>(pending-open-link)
|
||||||
|
Open the forge link under the cursor in a browser via |vim.ui.open()|.
|
||||||
|
If the cursor is positioned on a forge token (`gh:user/repo#42` or a
|
||||||
|
full URL), that link is opened. Otherwise, the last forge reference on
|
||||||
|
the line is used. No-op on lines without forge links. Default key: `gx`.
|
||||||
|
|
||||||
*<Plug>(pending-open-line)*
|
*<Plug>(pending-open-line)*
|
||||||
<Plug>(pending-open-line)
|
<Plug>(pending-open-line)
|
||||||
Insert a correctly-formatted blank task line below the cursor.
|
Insert a correctly-formatted blank task line below the cursor.
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,7 @@
|
||||||
---@field priority_down_visual? string|false
|
---@field priority_down_visual? string|false
|
||||||
---@field cancelled? string|false
|
---@field cancelled? string|false
|
||||||
---@field edit_notes? string|false
|
---@field edit_notes? string|false
|
||||||
|
---@field open_link? string|false
|
||||||
|
|
||||||
---@class pending.CategoryViewConfig
|
---@class pending.CategoryViewConfig
|
||||||
---@field order? string[]
|
---@field order? string[]
|
||||||
|
|
@ -165,6 +166,7 @@ local defaults = {
|
||||||
blocked = 'gb',
|
blocked = 'gb',
|
||||||
cancelled = 'g/',
|
cancelled = 'g/',
|
||||||
edit_notes = 'ge',
|
edit_notes = 'ge',
|
||||||
|
open_link = 'gx',
|
||||||
priority_up = '<C-a>',
|
priority_up = '<C-a>',
|
||||||
priority_down = '<C-x>',
|
priority_down = '<C-x>',
|
||||||
priority_up_visual = 'g<C-a>',
|
priority_up_visual = 'g<C-a>',
|
||||||
|
|
|
||||||
|
|
@ -404,6 +404,9 @@ function M._setup_buf_mappings(bufnr)
|
||||||
edit_notes = function()
|
edit_notes = function()
|
||||||
M.open_detail()
|
M.open_detail()
|
||||||
end,
|
end,
|
||||||
|
open_link = function()
|
||||||
|
M.open_link()
|
||||||
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, fn in pairs(actions) do
|
for name, fn in pairs(actions) do
|
||||||
|
|
@ -931,6 +934,31 @@ function M.open_detail()
|
||||||
end, { buffer = detail_bufnr })
|
end, { buffer = detail_bufnr })
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@return nil
|
||||||
|
function M.open_link()
|
||||||
|
local bufnr = buffer.bufnr()
|
||||||
|
if not bufnr then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local row = vim.api.nvim_win_get_cursor(0)[1]
|
||||||
|
local meta = buffer.meta()
|
||||||
|
if not meta[row] or meta[row].type ~= 'task' then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local spans = meta[row].forge_spans
|
||||||
|
if not spans or #spans == 0 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local col = vim.api.nvim_win_get_cursor(0)[2]
|
||||||
|
for _, span in ipairs(spans) do
|
||||||
|
if col >= span.col_start and col < span.col_end then
|
||||||
|
vim.ui.open(span.ref.url)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
vim.ui.open(spans[#spans].ref.url)
|
||||||
|
end
|
||||||
|
|
||||||
---@param direction 'up'|'down'
|
---@param direction 'up'|'down'
|
||||||
---@return nil
|
---@return nil
|
||||||
function M.move_task(direction)
|
function M.move_task(direction)
|
||||||
|
|
|
||||||
|
|
@ -411,6 +411,10 @@ vim.keymap.set('n', '<Plug>(pending-edit-notes)', function()
|
||||||
require('pending').open_detail()
|
require('pending').open_detail()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
vim.keymap.set('n', '<Plug>(pending-open-link)', function()
|
||||||
|
require('pending').open_link()
|
||||||
|
end)
|
||||||
|
|
||||||
vim.keymap.set('n', '<Plug>(pending-priority-up)', function()
|
vim.keymap.set('n', '<Plug>(pending-priority-up)', function()
|
||||||
require('pending').increment_priority()
|
require('pending').increment_priority()
|
||||||
end)
|
end)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue