This commit is contained in:
2024-12-23 21:34:50 +01:00
parent 3d0d721896
commit dd6843091b
3 changed files with 242 additions and 172 deletions

View File

@@ -4,10 +4,16 @@ local curl = require("plenary.curl")
local M = {} local M = {}
------------------------------------------------------------------------------
-- Helper: get base URL from config
------------------------------------------------------------------------------
local function get_base_url() local function get_base_url()
return config.values.server_url return config.values.server_url
end end
------------------------------------------------------------------------------
-- Helper: get auth header by trimming token
------------------------------------------------------------------------------
local function get_auth_header() local function get_auth_header()
local token = auth.get_token() local token = auth.get_token()
if not token or token == "" then if not token or token == "" then
@@ -16,24 +22,36 @@ local function get_auth_header()
return "token " .. token return "token " .. token
end end
------------------------------------------------------------------------------
-- Main HTTP request helper (using plenary.curl)
------------------------------------------------------------------------------
local function request(method, endpoint, opts) local function request(method, endpoint, opts)
opts = opts or {} opts = opts or {}
local url = get_base_url() .. endpoint local url = get_base_url() .. endpoint
local headers = opts.headers or {} local headers = opts.headers or {}
headers["Authorization"] = get_auth_header() headers["Authorization"] = get_auth_header()
headers["Content-Type"] = "application/json" headers["Content-Type"] = "application/json"
local body_data
if opts.body then
body_data = vim.json.encode(opts.body)
end
local result = curl.request({ local result = curl.request({
url = url, url = url,
method = method, method = method,
headers = headers, headers = headers,
timeout = 10000, timeout = 10000,
body = opts.body and vim.json.encode(opts.body) or nil, body = body_data,
query = opts.query, query = opts.query,
}) })
return result return result
end end
------------------------------------------------------------------------------
-- Issues -- Issues
------------------------------------------------------------------------------
function M.list_issues(owner, repo, opts) function M.list_issues(owner, repo, opts)
local endpoint = string.format("/api/v1/repos/%s/%s/issues", owner, repo) local endpoint = string.format("/api/v1/repos/%s/%s/issues", owner, repo)
local result = request("GET", endpoint, { query = opts }) local result = request("GET", endpoint, { query = opts })
@@ -61,10 +79,11 @@ function M.create_issue(owner, repo, data)
return nil, result and result.status return nil, result and result.status
end end
-- CHANGED: treat both 200 and 201 as success, in case Gitea returns 201
function M.edit_issue(owner, repo, number, data) function M.edit_issue(owner, repo, number, data)
local endpoint = string.format("/api/v1/repos/%s/%s/issues/%d", owner, repo, number) local endpoint = string.format("/api/v1/repos/%s/%s/issues/%d", owner, repo, number)
local result = request("PATCH", endpoint, { body = data }) local result = request("PATCH", endpoint, { body = data })
if result and result.status == 200 then if result and (result.status == 200 or result.status == 201) then
return vim.json.decode(result.body) return vim.json.decode(result.body)
end end
return nil, result and result.status return nil, result and result.status
@@ -87,18 +106,16 @@ function M.comment_issue(owner, repo, number, body)
return nil, result and result.status return nil, result and result.status
end end
-- ADDED: edit_issue_comment -- CHANGED: treat both 200 and 201 as success
-- Gitea supports: PATCH /repos/{owner}/{repo}/issues/comments/{id}
function M.edit_issue_comment(owner, repo, number, comment_id, body) function M.edit_issue_comment(owner, repo, number, comment_id, body)
local endpoint = string.format("/api/v1/repos/%s/%s/issues/comments/%d", owner, repo, comment_id) local endpoint = string.format("/api/v1/repos/%s/%s/issues/comments/%d", owner, repo, comment_id)
local result = request("PATCH", endpoint, { body = { body = body } }) local result = request("PATCH", endpoint, { body = { body = body } })
if result and result.status == 200 then if result and (result.status == 200 or result.status == 201) then
return vim.json.decode(result.body) return vim.json.decode(result.body)
end end
return nil, result and result.status return nil, result and result.status
end end
-- ADDED: get_issue_comments
function M.get_issue_comments(owner, repo, number) function M.get_issue_comments(owner, repo, number)
local endpoint = string.format("/api/v1/repos/%s/%s/issues/%d/comments", owner, repo, number) local endpoint = string.format("/api/v1/repos/%s/%s/issues/%d/comments", owner, repo, number)
local result = request("GET", endpoint) local result = request("GET", endpoint)
@@ -108,7 +125,9 @@ function M.get_issue_comments(owner, repo, number)
return nil, result and result.status return nil, result and result.status
end end
-- PR ------------------------------------------------------------------------------
-- Pull Requests
------------------------------------------------------------------------------
function M.list_pull_requests(owner, repo, opts) function M.list_pull_requests(owner, repo, opts)
local endpoint = string.format("/api/v1/repos/%s/%s/pulls", owner, repo) local endpoint = string.format("/api/v1/repos/%s/%s/pulls", owner, repo)
local result = request("GET", endpoint, { query = opts }) local result = request("GET", endpoint, { query = opts })
@@ -136,10 +155,11 @@ function M.create_pull_request(owner, repo, data)
return nil, result and result.status return nil, result and result.status
end end
-- CHANGED: treat both 200 and 201 as success for PR edits
function M.edit_pull_request(owner, repo, number, data) function M.edit_pull_request(owner, repo, number, data)
local endpoint = string.format("/api/v1/repos/%s/%s/pulls/%d", owner, repo, number) local endpoint = string.format("/api/v1/repos/%s/%s/pulls/%d", owner, repo, number)
local result = request("PATCH", endpoint, { body = data }) local result = request("PATCH", endpoint, { body = data })
if result and result.status == 200 then if result and (result.status == 200 or result.status == 201) then
return vim.json.decode(result.body) return vim.json.decode(result.body)
end end
return nil, result and result.status return nil, result and result.status
@@ -169,6 +189,7 @@ function M.reopen_pull_request(owner, repo, number)
end end
function M.comment_pull_request(owner, repo, number, body) function M.comment_pull_request(owner, repo, number, body)
-- Uses same logic as comment_issue
return M.comment_issue(owner, repo, number, body) return M.comment_issue(owner, repo, number, body)
end end

View File

@@ -80,6 +80,8 @@ local function ensure_token_file()
local token_file = config.values.config_file local token_file = config.values.config_file
local token_data = read_token_file(token_file) local token_data = read_token_file(token_file)
if token_data and token_data ~= "" then if token_data and token_data ~= "" then
-- Trim leading/trailing whitespace/newlines so we don't send a trailing "\n"
token_data = token_data:gsub("^%s+", ""):gsub("%s+$", "")
token_cached = token_data token_cached = token_data
return return
end end

View File

@@ -3,7 +3,46 @@ local M = {}
local config = require("gitea.config") local config = require("gitea.config")
local api = require("gitea.api") local api = require("gitea.api")
local auth = require("gitea.auth") local auth = require("gitea.auth")
local highlights = require("gitea.highlights") -- we still require highlights local highlights = require("gitea.highlights")
------------------------------------------------------------------------------
-- Debug toggle
------------------------------------------------------------------------------
local DEBUG = true
------------------------------------------------------------------------------
-- Well create a namespace for our extmarks
------------------------------------------------------------------------------
local GITEA_NS = vim.api.nvim_create_namespace("gitea_nvim")
------------------------------------------------------------------------------
-- Utility: get all lines from the region defined by an extmark
------------------------------------------------------------------------------
local function get_extmark_region(bufnr, extmark_id)
-- extmark lookup with "details = true" returns: { row, col, details={ end_row=..., end_col=... } }
local markinfo = vim.api.nvim_buf_get_extmark_by_id(bufnr, GITEA_NS, extmark_id, { details = true })
if not markinfo or #markinfo == 0 then
return {}, 0, 0 -- no lines
end
local start_line = markinfo[1]
local end_line = markinfo[3].end_row
local lines = vim.api.nvim_buf_get_lines(bufnr, start_line, end_line + 1, false)
return lines, start_line, end_line
end
------------------------------------------------------------------------------
-- Utility: set an extmark covering a region from start_line..end_line
------------------------------------------------------------------------------
local function set_extmark_range(bufnr, start_line, end_line)
-- We store the extmark covering these lines from start_line..end_line
-- We do end_col=0 to anchor at column 0, but the end_row is inclusive
-- so we do { end_line, -1 } or end_col=0 with end_row=that line + 1
local extmark_id = vim.api.nvim_buf_set_extmark(bufnr, GITEA_NS, start_line, 0, {
end_line = end_line,
end_col = 0,
})
return extmark_id
end
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
-- DETECT OWNER/REPO -- DETECT OWNER/REPO
@@ -33,103 +72,79 @@ local function detect_owner_repo()
end end
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
-- BUFFER METADATA -- Well store "metadata" in a table like octo.nvims approach:
-- metadata.title_extmark -> ID
-- metadata.body_extmark -> ID
-- metadata.comments = { { id=..., extmark_id=... }, ... }
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
local function create_issue_buffer_metadata(issue) local function create_issue_buffer_metadata(issue)
return { return {
issue_number = issue.number, issue_number = issue.number,
title_start = nil, title_extmark = nil,
title_end = nil, body_extmark = nil,
body_start = nil, comments = {},
body_end = nil, new_comment_extmark = nil, -- region for new comment
comments = {}, -- each = { id, start_line, end_line }
new_comment_start = nil,
} }
end end
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
-- APPLY HIGHLIGHTS -- APPLY CUSTOM HIGHLIGHTS
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
local function apply_issue_highlights(bufnr, meta) local function apply_issue_highlights(bufnr)
-- The first line in the file is line 0 in Luas API, so we subtract 1 -- We can still highlight lines #0 and #1, or do it differently
-- from meta.* to convert to 0-based indexing.
------------------------------------------------------------------------
-- Lines #0 & #1 hold meta info (“# Gitea Issue #...”, “# STATE: ...”)
------------------------------------------------------------------------
vim.api.nvim_buf_add_highlight(bufnr, 0, "GiteaIssueMeta", 0, 0, -1) vim.api.nvim_buf_add_highlight(bufnr, 0, "GiteaIssueMeta", 0, 0, -1)
vim.api.nvim_buf_add_highlight(bufnr, 0, "GiteaIssueMeta", 1, 0, -1) vim.api.nvim_buf_add_highlight(bufnr, 0, "GiteaIssueMeta", 1, 0, -1)
------------------------------------------------------------------------
-- Title
------------------------------------------------------------------------
local title_line_0 = meta.title_start - 1
vim.api.nvim_buf_add_highlight(bufnr, 0, "GiteaIssueTitle", title_line_0, 0, -1)
------------------------------------------------------------------------
-- Body lines
------------------------------------------------------------------------
-- meta.body_start .. meta.body_end (inclusive, 1-based)
for line = meta.body_start, meta.body_end do
local line_0 = line - 1
vim.api.nvim_buf_add_highlight(bufnr, 0, "GiteaCommentBody", line_0, 0, -1)
end
------------------------------------------------------------------------
-- Comment headings & bodies
------------------------------------------------------------------------
for _, c in ipairs(meta.comments) do
-- The heading line has “COMMENT #123 by user”
local heading_line_0 = c.start_line - 1
vim.api.nvim_buf_add_highlight(bufnr, 0, "GiteaCommentHeading", heading_line_0, 0, -1)
-- The actual comment text is lines [heading_line_0+1 .. c.end_line-1]
for text_line = (c.start_line + 1), c.end_line do
local text_line_0 = text_line - 1
vim.api.nvim_buf_add_highlight(bufnr, 0, "GiteaCommentBody", text_line_0, 0, -1)
end
end
end end
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
-- RENDER ISSUE INTO BUFFER -- RENDER ISSUE INTO BUFFER (octo.nvim style)
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
local function render_issue_into_buf(bufnr, issue, comments) local function render_issue_into_buf(bufnr, issue, comments)
local lines = {} -- Clear buffer, extmarks, etc.
table.insert(lines, string.format("# Gitea Issue #%d: %s", issue.number, issue.title)) vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {})
table.insert(lines, "# STATE: " .. (issue.state or "unknown")) vim.api.nvim_buf_clear_namespace(bufnr, GITEA_NS, 0, -1)
table.insert(lines, "# Edit the title below, then the body, then any comments.")
table.insert(lines, "# On save (:w), changes to the title/body will be updated; changes to comment lines will be updated, and new text at the bottom becomes a new comment.")
table.insert(lines, "")
local meta = create_issue_buffer_metadata(issue) local meta = create_issue_buffer_metadata(issue)
meta.title_start = #lines + 1 local lines = {}
table.insert(lines, issue.title or "")
meta.title_end = #lines
-- Some short header lines
table.insert(lines, string.format("# Gitea Issue #%d: %s", issue.number, issue.title))
table.insert(lines, "# STATE: " .. (issue.state or "unknown"))
table.insert(lines, "# You can edit below. On save, the changes are applied.")
table.insert(lines, "") table.insert(lines, "")
meta.body_start = #lines + 1
if issue.body then -- Add placeholder for title
local body_lines = vim.split(issue.body, "\n", true) local title_start = #lines
table.insert(lines, issue.title or "")
local title_end = #lines
-- blank line
table.insert(lines, "")
-- Add placeholder for body
local body_start = #lines
local body_text = issue.body or ""
if body_text == "" then
body_text = "No issue description."
end
local body_lines = vim.split(body_text, "\n", true)
if #body_lines == 0 then if #body_lines == 0 then
table.insert(lines, "") table.insert(lines, "")
else else
for _, l in ipairs(body_lines) do for _, line in ipairs(body_lines) do
table.insert(lines, l) table.insert(lines, line)
end end
end end
else local body_end = #lines
table.insert(lines, "No issue description.")
end
meta.body_end = #lines
-- blank line
table.insert(lines, "") table.insert(lines, "")
table.insert(lines, "# --- Comments ---") table.insert(lines, "# --- Comments ---")
local comment_meta = {} local comment_meta = {}
for _, c in ipairs(comments) do for _, c in ipairs(comments or {}) do
table.insert(lines, "") table.insert(lines, "")
local start_line = #lines + 1 local start_line = #lines
local author = c.user and (c.user.login or c.user.username) or "?" local author = c.user and (c.user.login or c.user.username) or "?"
table.insert(lines, string.format("COMMENT #%d by %s", c.id, author)) table.insert(lines, string.format("COMMENT #%d by %s", c.id, author))
@@ -142,101 +157,137 @@ local function render_issue_into_buf(bufnr, issue, comments)
end end
end end
local end_line = #lines local end_line = #lines
table.insert(comment_meta, { table.insert(comment_meta, { id = c.id, extmark_id = nil, start_line = start_line, end_line = end_line })
id = c.id,
start_line = start_line,
end_line = end_line,
})
end end
-- final blank line for new comment
table.insert(lines, "") table.insert(lines, "")
table.insert(lines, "# --- Add a new comment below this line. If you leave it blank, no new comment is created. ---") table.insert(lines, "# --- Add a new comment below (multiline ok). ---")
meta.new_comment_start = #lines + 1 local new_comment_start = #lines + 1
table.insert(lines, "") table.insert(lines, "") -- at least one blank line
-- Save comment meta -- Actually write out
meta.comments = comment_meta
-- Put all lines into the buffer
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines) vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines)
-- Now apply highlight groups -- Now create extmark for the title
apply_issue_highlights(bufnr, meta) -- NOTE: extmark is zero-based, so set_extmark_range expects 0-based line indexes
meta.title_extmark = set_extmark_range(bufnr, title_start - 1, title_end - 1)
-- extmark for body
meta.body_extmark = set_extmark_range(bufnr, body_start - 1, body_end - 1)
-- extmarks for comments
for _, cmeta in ipairs(comment_meta) do
local mark_id = set_extmark_range(bufnr, cmeta.start_line - 1, cmeta.end_line - 1)
cmeta.extmark_id = mark_id
end
meta.comments = comment_meta
-- extmark for new comment region
meta.new_comment_extmark = set_extmark_range(bufnr, new_comment_start - 1, #lines - 1)
apply_issue_highlights(bufnr)
return meta return meta
end end
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
-- ON SAVE (BufWriteCmd) -- ON SAVE => PARSE & UPDATE (octo.nvim style)
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
local function on_issue_buf_write(bufnr, metadata, owner, repo) local function on_issue_buf_write(bufnr, metadata, owner, repo)
local new_lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
local new_title = table.concat(vim.list_slice(new_lines, metadata.title_start, metadata.title_end), "\n")
new_title = new_title:gsub("%s+$", "")
local current_issue_data = api.get_issue(owner, repo, metadata.issue_number) local current_issue_data = api.get_issue(owner, repo, metadata.issue_number)
if not current_issue_data then if not current_issue_data then
vim.notify("[gitea.nvim] Could not re-fetch the issue to verify updates", vim.log.levels.ERROR) vim.notify("[gitea.nvim] Could not re-fetch the issue", vim.log.levels.ERROR)
return return
end end
-- 1) Gather new title
local title_lines = get_extmark_region(bufnr, metadata.title_extmark)
local new_title = table.concat(title_lines, "\n")
-- Trim whitespace from the title (since GitHub disallows multi-line titles)
new_title = new_title:gsub("^%s+", ""):gsub("%s+$", ""):gsub("[\n\r]+", " ")
-- 2) Gather new body
local body_lines = get_extmark_region(bufnr, metadata.body_extmark)
local new_body = table.concat(body_lines, "\n") -- multiline is fine, do not trim
if DEBUG then
print("DEBUG: new_title = ", new_title)
print("DEBUG: new_body (lines) = ", vim.inspect(body_lines))
end
local changed_title = (current_issue_data.title or "") ~= new_title local changed_title = (current_issue_data.title or "") ~= new_title
local new_body_lines = vim.list_slice(new_lines, metadata.body_start, metadata.body_end)
local new_body = table.concat(new_body_lines, "\n")
local changed_body = (current_issue_data.body or "") ~= new_body local changed_body = (current_issue_data.body or "") ~= new_body
-- 3) Gather updates for existing comments
local changed_comments = {} local changed_comments = {}
for _, cmeta in ipairs(metadata.comments) do for _, cinfo in ipairs(metadata.comments) do
local c_lines = vim.list_slice(new_lines, cmeta.start_line, cmeta.end_line) local comment_lines = get_extmark_region(bufnr, cinfo.extmark_id)
-- first line => "COMMENT #<id> by <author>" -- The first line might be "COMMENT #ID by Author"
local c_body = {} -- So let's separate that from the actual text
for i = 2, #c_lines do local c_header = comment_lines[1] or ""
table.insert(c_body, c_lines[i]) local c_body_lines = {}
for i = 2, #comment_lines do
table.insert(c_body_lines, comment_lines[i])
end end
local new_comment_body = table.concat(c_body, "\n") local new_comment_body = table.concat(c_body_lines, "\n")
table.insert(changed_comments, { table.insert(changed_comments, {
id = cmeta.id, id = cinfo.id,
new_body = new_comment_body new_body = new_comment_body,
}) })
end end
local new_comment_body_lines = {} -- 4) Possibly new comment
for i = metadata.new_comment_start, #new_lines do local extra_comment_lines = get_extmark_region(bufnr, metadata.new_comment_extmark)
table.insert(new_comment_body_lines, new_lines[i]) -- remove lines that are just comment-hint if you want, but we can accept them all
end local new_comment_body = table.concat(extra_comment_lines, "\n"):gsub("^%s+", ""):gsub("%s+$", "")
local new_comment_body = table.concat(new_comment_body_lines, "\n"):gsub("^%s+", ""):gsub("%s+$", "") local create_new_comment = #new_comment_body > 0
local create_new_comment = (#new_comment_body > 0)
-- Edit issue if title or body changed if DEBUG then
print("DEBUG: new_comment_body = ", new_comment_body)
end
-- Validate title
if changed_title and new_title == "" then
vim.notify("[gitea.nvim] Title cannot be empty. Skipping.", vim.log.levels.ERROR)
if not changed_body and #changed_comments == 0 and not create_new_comment then
return
end
changed_title = false
end
-- Edit issue if needed
if changed_title or changed_body then if changed_title or changed_body then
local updated, st = api.edit_issue(owner, repo, metadata.issue_number, { local updated, st = api.edit_issue(owner, repo, metadata.issue_number, {
title = changed_title and new_title or current_issue_data.title, title = changed_title and new_title or current_issue_data.title,
body = changed_body and new_body or current_issue_data.body, body = changed_body and new_body or current_issue_data.body,
}) })
if updated then if updated then
vim.notify("[gitea.nvim] Issue updated!") vim.notify("[gitea.nvim] Issue updated.")
else else
vim.notify(string.format("[gitea.nvim] Failed to update issue (HTTP %s).", st or "?"), vim.log.levels.ERROR) vim.notify(string.format("[gitea.nvim] Failed to update issue (HTTP %s).", st or "?"), vim.log.levels.ERROR)
end end
end end
-- Edit each comment -- Update each existing comment
for _, cupd in ipairs(changed_comments) do for _, c in ipairs(changed_comments) do
local updated_comment, st = api.edit_issue_comment(owner, repo, metadata.issue_number, cupd.id, cupd.new_body) if (c.new_body or "") ~= "" then
local updated_comment, st = api.edit_issue_comment(owner, repo, metadata.issue_number, c.id, c.new_body)
if not updated_comment then if not updated_comment then
vim.notify(string.format("[gitea.nvim] Failed to update comment %d. (HTTP %s)", cupd.id, st or "?"), vim.log.levels.ERROR) vim.notify(string.format("[gitea.nvim] Failed to update comment %d", c.id), vim.log.levels.ERROR)
else else
vim.notify(string.format("[gitea.nvim] Comment #%d updated.", cupd.id)) vim.notify(string.format("[gitea.nvim] Comment #%d updated.", c.id))
end
end end
end end
-- Possibly add a new comment -- Possibly create new comment
if create_new_comment then if create_new_comment then
local created, st = api.comment_issue(owner, repo, metadata.issue_number, new_comment_body) local created, st = api.comment_issue(owner, repo, metadata.issue_number, new_comment_body)
if created then if created then
vim.notify("[gitea.nvim] New comment posted.") vim.notify("[gitea.nvim] New comment posted.")
else else
vim.notify(string.format("[gitea.nvim] Failed to create new comment (HTTP %s).", st or "?"), vim.log.levels.ERROR) vim.notify(string.format("[gitea.nvim] Failed to create comment (HTTP %s).", st or "?"), vim.log.levels.ERROR)
end end
end end
end end
@@ -250,7 +301,6 @@ local function open_full_issue_buffer(owner, repo, number)
vim.notify(string.format("[gitea.nvim] Error retrieving issue #%d (HTTP %s).", number, status or "?"), vim.log.levels.ERROR) vim.notify(string.format("[gitea.nvim] Error retrieving issue #%d (HTTP %s).", number, status or "?"), vim.log.levels.ERROR)
return return
end end
local all_comments, cstatus = api.get_issue_comments(owner, repo, number) local all_comments, cstatus = api.get_issue_comments(owner, repo, number)
if not all_comments then if not all_comments then
vim.notify(string.format("[gitea.nvim] Error retrieving issue #%d comments (HTTP %s).", number, cstatus or "?"), vim.log.levels.ERROR) vim.notify(string.format("[gitea.nvim] Error retrieving issue #%d comments (HTTP %s).", number, cstatus or "?"), vim.log.levels.ERROR)
@@ -259,18 +309,15 @@ local function open_full_issue_buffer(owner, repo, number)
local buf = vim.api.nvim_create_buf(false, true) local buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_option(buf, "buftype", "acwrite") vim.api.nvim_buf_set_option(buf, "buftype", "acwrite")
-- Use our new "gitea" filetype, so after/syntax/gitea.vim will load
vim.api.nvim_buf_set_option(buf, "filetype", "gitea") vim.api.nvim_buf_set_option(buf, "filetype", "gitea")
vim.api.nvim_buf_set_name(buf, string.format("gitea_issue_full_%d", number)) vim.api.nvim_buf_set_name(buf, string.format("gitea_issue_full_%d", number))
-- Load highlight definitions (e.g. GiteaIssueTitle, GiteaCommentBody, etc.)
highlights.setup() highlights.setup()
-- Render lines & create extmarks
local metadata = render_issue_into_buf(buf, issue_data, all_comments) local metadata = render_issue_into_buf(buf, issue_data, all_comments)
-- Auto command to handle saving -- Hook saving => parse extmarks & do updates
vim.api.nvim_create_autocmd("BufWriteCmd", { vim.api.nvim_create_autocmd("BufWriteCmd", {
buffer = buf, buffer = buf,
callback = function() callback = function()
@@ -287,7 +334,7 @@ end
local subcommands = {} local subcommands = {}
subcommands.issue = { subcommands.issue = {
list = function(args) list = function(_)
local owner, repo = detect_owner_repo() local owner, repo = detect_owner_repo()
if not owner or not repo then if not owner or not repo then
vim.notify("[gitea.nvim] Could not detect owner/repo.", vim.log.levels.ERROR) vim.notify("[gitea.nvim] Could not detect owner/repo.", vim.log.levels.ERROR)
@@ -305,9 +352,9 @@ subcommands.issue = {
local actions = require("telescope.actions") local actions = require("telescope.actions")
local action_state = require("telescope.actions.state") local action_state = require("telescope.actions.state")
local issues, status = api.list_issues(owner, repo, {}) local issues, st = api.list_issues(owner, repo, {})
if not issues then if not issues then
vim.notify(string.format("[gitea.nvim] Error fetching issues (HTTP %s).", status or "?"), vim.log.levels.ERROR) vim.notify(string.format("[gitea.nvim] Error fetching issues (HTTP %s).", st or "?"), vim.log.levels.ERROR)
return return
end end
@@ -356,11 +403,11 @@ subcommands.issue = {
} }
subcommands.pr = { subcommands.pr = {
-- your other PR-related commands, if any -- If you have PR subcommands, add them here
} }
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
-- REGISTER COMMAND -- REGISTER
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
function M.register() function M.register()
vim.api.nvim_create_user_command("Gitea", function(cmd_opts) vim.api.nvim_create_user_command("Gitea", function(cmd_opts)
@@ -380,11 +427,11 @@ function M.register()
end end
local sc = subcommands[object] local sc = subcommands[object]
if not sc then if not sc then
vim.notify("[gitea.nvim] Unknown object: "..object, vim.log.levels.ERROR) vim.notify("[gitea.nvim] Unknown object: " .. object, vim.log.levels.ERROR)
return return
end end
if not action then if not action then
vim.notify("[gitea.nvim] Please specify an action for "..object, vim.log.levels.ERROR) vim.notify("[gitea.nvim] Please specify an action for " .. object, vim.log.levels.ERROR)
return return
end end
local fn = sc[action] local fn = sc[action]
@@ -392,17 +439,17 @@ function M.register()
vim.notify(string.format("[gitea.nvim] Unknown action '%s' for object '%s'", action, object), vim.log.levels.ERROR) vim.notify(string.format("[gitea.nvim] Unknown action '%s' for object '%s'", action, object), vim.log.levels.ERROR)
return return
end end
table.remove(args, 1) -- remove object table.remove(args, 1)
table.remove(args, 1) -- remove action table.remove(args, 1)
fn(args) fn(args)
end, { end, {
nargs = "*", nargs = "*",
complete = function(arg_lead, cmd_line, cursor_pos) complete = function(arg_lead, cmd_line, _)
local parts = vim.split(cmd_line, "%s+") local parts = vim.split(cmd_line, "%s+")
if #parts == 2 then if #parts == 2 then
local objs = {} local objs = {}
for k, _ in pairs(subcommands) do for k, _ in pairs(subcommands) do
if k:match("^"..arg_lead) then if k:match("^" .. arg_lead) then
table.insert(objs, k) table.insert(objs, k)
end end
end end
@@ -412,7 +459,7 @@ function M.register()
local acts = {} local acts = {}
if subcommands[object] then if subcommands[object] then
for k, _ in pairs(subcommands[object]) do for k, _ in pairs(subcommands[object]) do
if k:match("^"..arg_lead) then if k:match("^" .. arg_lead) then
table.insert(acts, k) table.insert(acts, k)
end end
end end
@@ -421,7 +468,7 @@ function M.register()
else else
return {} return {}
end end
end end,
}) })
end end