feat(forge): add find_refs() inline token scanner

Problem: forge tokens were extracted by `parse.body()` which stripped
them from the description, making editing awkward and multi-ref lines
impossible.

Solution: add `find_refs(text)` that scans a string for all forge
tokens by whitespace tokenization, returning byte offsets and parsed
refs without modifying the input. Remove unused `conceal_patterns()`.
This commit is contained in:
Barrett Ruth 2026-03-10 18:58:00 -04:00
parent 2321dab457
commit e98b5a8e4a

View file

@ -196,6 +196,39 @@ function M.parse_ref(token)
return M._parse_github_url(token) or M._parse_gitlab_url(token) or M._parse_codeberg_url(token)
end
---@class pending.ForgeSpan
---@field ref pending.ForgeRef
---@field start_byte integer
---@field end_byte integer
---@field raw string
---@param text string
---@return pending.ForgeSpan[]
function M.find_refs(text)
local results = {}
local pos = 1
while pos <= #text do
local ws = text:find('%S', pos)
if not ws then
break
end
local token_end = text:find('%s', ws)
local token = token_end and text:sub(ws, token_end - 1) or text:sub(ws)
local ref = M.parse_ref(token)
if ref then
local eb = token_end and (token_end - 1) or #text
table.insert(results, {
ref = ref,
start_byte = ws - 1,
end_byte = eb,
raw = token,
})
end
pos = token_end and token_end or (#text + 1)
end
return results
end
---@param ref pending.ForgeRef
---@return string
function M._api_url(ref)
@ -395,25 +428,5 @@ function M.refresh(s)
end
end
---@return string[]
function M.conceal_patterns()
local patterns = {
'gh:[A-Za-z0-9._-]\\+\\/[A-Za-z0-9._-]\\+#\\d\\+',
'gl:[A-Za-z0-9._-]\\+\\/[A-Za-z0-9._-]\\+#\\d\\+',
'cb:[A-Za-z0-9._-]\\+\\/[A-Za-z0-9._-]\\+#\\d\\+',
'https\\?:\\/\\/github\\.com\\/\\S\\+',
'https\\?:\\/\\/gitlab\\.com\\/\\S\\+',
'https\\?:\\/\\/codeberg\\.org\\/\\S\\+',
}
local cfg = config.get().forge or {}
for _, forge_key in ipairs({ 'github', 'gitlab', 'codeberg' }) do
local forge_cfg = cfg[forge_key] or {}
for _, inst in ipairs(forge_cfg.instances or {}) do
local escaped = inst:gsub('%.', '\\.'):gsub('/', '\\/')
table.insert(patterns, 'https\\?:\\/\\/' .. escaped .. '\\/\\S\\+')
end
end
return patterns
end
return M