feat: first implementation for issues and pull requests
This commit is contained in:
@@ -1,474 +1,128 @@
|
||||
----------------------------------------------------------------------------
|
||||
-- lua/gitea/commands.lua
|
||||
--
|
||||
-- Single :Gitea command with subcommands for issues, PRs, etc.
|
||||
-- Removed "pr open" as requested. Only "list" and "create" remain for PR.
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
local M = {}
|
||||
|
||||
local config = require("gitea.config")
|
||||
local api = require("gitea.api")
|
||||
local auth = require("gitea.auth")
|
||||
local highlights = require("gitea.highlights")
|
||||
--------------------------------------------------------------------------
|
||||
-- A simple completion function for the :Gitea command
|
||||
--------------------------------------------------------------------------
|
||||
function M._gitea_cmd_complete(arg_lead, cmd_line, cursor_pos)
|
||||
local tokens = vim.split(cmd_line, "%s+")
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Debug toggle
|
||||
------------------------------------------------------------------------------
|
||||
local DEBUG = true
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- We’ll 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
|
||||
-- If the user hasn't typed anything after ":Gitea", suggest top-level words
|
||||
if #tokens <= 1 then
|
||||
return { "issue", "pr" }
|
||||
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
|
||||
local main_sub = tokens[2]
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- DETECT OWNER/REPO
|
||||
------------------------------------------------------------------------------
|
||||
local function detect_owner_repo()
|
||||
local cmd = "git config remote.origin.url"
|
||||
local url = vim.fn.systemlist(cmd)[1]
|
||||
if vim.v.shell_error ~= 0 or not url or url == "" then
|
||||
return nil, nil
|
||||
end
|
||||
url = url:gsub("%.git$", "")
|
||||
local _, after = url:match("^(https?://)(.*)$")
|
||||
if after then
|
||||
local path = after:match("[^/]+/(.*)$")
|
||||
if not path then
|
||||
return nil, nil
|
||||
end
|
||||
local owner, repo = path:match("^(.-)/(.*)$")
|
||||
return owner, repo
|
||||
end
|
||||
local user_host, path = url:match("^(.-):(.*)$")
|
||||
if user_host and path then
|
||||
local owner, repo = path:match("^(.-)/(.*)$")
|
||||
return owner, repo
|
||||
end
|
||||
return nil, nil
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- We’ll store "metadata" in a table like octo.nvim’s approach:
|
||||
-- metadata.title_extmark -> ID
|
||||
-- metadata.body_extmark -> ID
|
||||
-- metadata.comments = { { id=..., extmark_id=... }, ... }
|
||||
------------------------------------------------------------------------------
|
||||
local function create_issue_buffer_metadata(issue)
|
||||
return {
|
||||
issue_number = issue.number,
|
||||
title_extmark = nil,
|
||||
body_extmark = nil,
|
||||
comments = {},
|
||||
new_comment_extmark = nil, -- region for new comment
|
||||
}
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- APPLY CUSTOM HIGHLIGHTS
|
||||
------------------------------------------------------------------------------
|
||||
local function apply_issue_highlights(bufnr)
|
||||
-- We can still highlight lines #0 and #1, or do it differently
|
||||
vim.api.nvim_buf_add_highlight(bufnr, 0, "GiteaIssueMeta", 0, 0, -1)
|
||||
vim.api.nvim_buf_add_highlight(bufnr, 0, "GiteaIssueMeta", 1, 0, -1)
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- RENDER ISSUE INTO BUFFER (octo.nvim style)
|
||||
------------------------------------------------------------------------------
|
||||
local function render_issue_into_buf(bufnr, issue, comments)
|
||||
-- Clear buffer, extmarks, etc.
|
||||
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {})
|
||||
vim.api.nvim_buf_clear_namespace(bufnr, GITEA_NS, 0, -1)
|
||||
|
||||
local meta = create_issue_buffer_metadata(issue)
|
||||
local 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, "")
|
||||
|
||||
-- Add placeholder for title
|
||||
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
|
||||
table.insert(lines, "")
|
||||
else
|
||||
for _, line in ipairs(body_lines) do
|
||||
table.insert(lines, line)
|
||||
end
|
||||
end
|
||||
local body_end = #lines
|
||||
|
||||
-- blank line
|
||||
table.insert(lines, "")
|
||||
table.insert(lines, "# --- Comments ---")
|
||||
|
||||
local comment_meta = {}
|
||||
for _, c in ipairs(comments or {}) do
|
||||
table.insert(lines, "")
|
||||
local start_line = #lines
|
||||
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))
|
||||
|
||||
local c_body_lines = vim.split(c.body or "", "\n", true)
|
||||
if #c_body_lines == 0 then
|
||||
table.insert(lines, "")
|
||||
else
|
||||
for _, cb in ipairs(c_body_lines) do
|
||||
table.insert(lines, cb)
|
||||
if #tokens == 2 then
|
||||
local candidates = { "issue", "pr" }
|
||||
local results = {}
|
||||
for _, c in ipairs(candidates) do
|
||||
if c:find("^" .. arg_lead) then
|
||||
table.insert(results, c)
|
||||
end
|
||||
end
|
||||
local end_line = #lines
|
||||
table.insert(comment_meta, { id = c.id, extmark_id = nil, start_line = start_line, end_line = end_line })
|
||||
return results
|
||||
end
|
||||
|
||||
-- final blank line for new comment
|
||||
table.insert(lines, "")
|
||||
table.insert(lines, "# --- Add a new comment below (multiline ok). ---")
|
||||
local new_comment_start = #lines + 1
|
||||
table.insert(lines, "") -- at least one blank line
|
||||
|
||||
-- Actually write out
|
||||
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines)
|
||||
|
||||
-- Now create extmark for the title
|
||||
-- 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
|
||||
-- If "issue" was selected, next subcommands can be list, create
|
||||
if main_sub == "issue" then
|
||||
if #tokens == 3 then
|
||||
local candidates = { "list", "create" }
|
||||
local results = {}
|
||||
for _, c in ipairs(candidates) do
|
||||
if c:find("^" .. arg_lead) then
|
||||
table.insert(results, c)
|
||||
end
|
||||
end
|
||||
return results
|
||||
end
|
||||
return {}
|
||||
end
|
||||
meta.comments = comment_meta
|
||||
|
||||
-- extmark for new comment region
|
||||
meta.new_comment_extmark = set_extmark_range(bufnr, new_comment_start - 1, #lines - 1)
|
||||
-- If "pr" was selected, next subcommands can be list, create
|
||||
-- (removed "open" and "merge" as subcommands)
|
||||
if main_sub == "pr" then
|
||||
if #tokens == 3 then
|
||||
local candidates = { "list", "create" }
|
||||
local results = {}
|
||||
for _, c in ipairs(candidates) do
|
||||
if c:find("^" .. arg_lead) then
|
||||
table.insert(results, c)
|
||||
end
|
||||
end
|
||||
return results
|
||||
end
|
||||
return {}
|
||||
end
|
||||
|
||||
apply_issue_highlights(bufnr)
|
||||
return meta
|
||||
return {}
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- ON SAVE => PARSE & UPDATE (octo.nvim style)
|
||||
------------------------------------------------------------------------------
|
||||
local function on_issue_buf_write(bufnr, metadata, owner, repo)
|
||||
local current_issue_data = api.get_issue(owner, repo, metadata.issue_number)
|
||||
if not current_issue_data then
|
||||
vim.notify("[gitea.nvim] Could not re-fetch the issue", vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
function M.setup_commands(core)
|
||||
local issues_mod = require("gitea.issues")
|
||||
local telescope_mod = require("gitea.telescope")
|
||||
-- local pulls_mod = require("gitea.pulls") -- if needed
|
||||
|
||||
-- 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]+", " ")
|
||||
vim.api.nvim_create_user_command("Gitea", function(opts)
|
||||
local args = vim.split(opts.args, "%s+")
|
||||
local main = args[1] or ""
|
||||
|
||||
-- 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 main == "issue" then
|
||||
local sub = args[2] or ""
|
||||
if sub == "list" then
|
||||
-- :Gitea issue list
|
||||
telescope_mod.list_issues_in_telescope()
|
||||
|
||||
if DEBUG then
|
||||
print("DEBUG: new_title = ", new_title)
|
||||
print("DEBUG: new_body (lines) = ", vim.inspect(body_lines))
|
||||
end
|
||||
elseif sub == "create" then
|
||||
-- :Gitea issue create [owner] [repo] <title> ...
|
||||
if #args < 3 then
|
||||
vim.cmd([[echoerr "Usage: :Gitea issue create <title> [body...]"]])
|
||||
return
|
||||
end
|
||||
local owner, repo, title, body
|
||||
if #args >= 5 then
|
||||
owner = args[3]
|
||||
repo = args[4]
|
||||
title = args[5]
|
||||
body = table.concat(vim.list_slice(args, 6), " ")
|
||||
else
|
||||
title = args[3]
|
||||
body = table.concat(vim.list_slice(args, 4), " ")
|
||||
end
|
||||
issues_mod.create_issue(owner, repo, title, body)
|
||||
|
||||
local changed_title = (current_issue_data.title or "") ~= new_title
|
||||
local changed_body = (current_issue_data.body or "") ~= new_body
|
||||
|
||||
-- 3) Gather updates for existing comments
|
||||
local changed_comments = {}
|
||||
for _, cinfo in ipairs(metadata.comments) do
|
||||
local comment_lines = get_extmark_region(bufnr, cinfo.extmark_id)
|
||||
-- The first line might be "COMMENT #ID by Author"
|
||||
-- So let's separate that from the actual text
|
||||
local c_header = comment_lines[1] or ""
|
||||
local c_body_lines = {}
|
||||
for i = 2, #comment_lines do
|
||||
table.insert(c_body_lines, comment_lines[i])
|
||||
end
|
||||
local new_comment_body = table.concat(c_body_lines, "\n")
|
||||
|
||||
table.insert(changed_comments, {
|
||||
id = cinfo.id,
|
||||
new_body = new_comment_body,
|
||||
})
|
||||
end
|
||||
|
||||
-- 4) Possibly new comment
|
||||
local extra_comment_lines = get_extmark_region(bufnr, metadata.new_comment_extmark)
|
||||
-- remove lines that are just comment-hint if you want, but we can accept them all
|
||||
local new_comment_body = table.concat(extra_comment_lines, "\n"):gsub("^%s+", ""):gsub("%s+$", "")
|
||||
local create_new_comment = #new_comment_body > 0
|
||||
|
||||
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
|
||||
local updated, st = api.edit_issue(owner, repo, metadata.issue_number, {
|
||||
title = changed_title and new_title or current_issue_data.title,
|
||||
body = changed_body and new_body or current_issue_data.body,
|
||||
})
|
||||
if updated then
|
||||
vim.notify("[gitea.nvim] Issue updated.")
|
||||
else
|
||||
vim.notify(string.format("[gitea.nvim] Failed to update issue (HTTP %s).", st or "?"), vim.log.levels.ERROR)
|
||||
end
|
||||
end
|
||||
|
||||
-- Update each existing comment
|
||||
for _, c in ipairs(changed_comments) do
|
||||
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
|
||||
vim.notify(string.format("[gitea.nvim] Failed to update comment %d", c.id), vim.log.levels.ERROR)
|
||||
else
|
||||
vim.notify(string.format("[gitea.nvim] Comment #%d updated.", c.id))
|
||||
print("Unknown issue subcommand: " .. sub)
|
||||
print("Available subcommands: list, create")
|
||||
end
|
||||
|
||||
elseif main == "pr" then
|
||||
local sub = args[2] or ""
|
||||
if sub == "list" then
|
||||
vim.cmd([[echo "TODO: :Gitea pr list"]])
|
||||
elseif sub == "create" then
|
||||
vim.cmd([[echo "TODO: :Gitea pr create"]])
|
||||
else
|
||||
print("Unknown PR subcommand: " .. sub)
|
||||
print("Available subcommands: list, create")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Possibly create new comment
|
||||
if create_new_comment then
|
||||
local created, st = api.comment_issue(owner, repo, metadata.issue_number, new_comment_body)
|
||||
if created then
|
||||
vim.notify("[gitea.nvim] New comment posted.")
|
||||
else
|
||||
vim.notify(string.format("[gitea.nvim] Failed to create comment (HTTP %s).", st or "?"), vim.log.levels.ERROR)
|
||||
print("Usage: :Gitea <issue|pr> <subcommand> [arguments...]")
|
||||
print("For issues: list, create")
|
||||
print("For PRs: list, create")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- OPEN ISSUE BUFFER
|
||||
------------------------------------------------------------------------------
|
||||
local function open_full_issue_buffer(owner, repo, number)
|
||||
local issue_data, status = api.get_issue(owner, repo, number)
|
||||
if not issue_data then
|
||||
vim.notify(string.format("[gitea.nvim] Error retrieving issue #%d (HTTP %s).", number, status or "?"), vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
local all_comments, cstatus = api.get_issue_comments(owner, repo, number)
|
||||
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)
|
||||
return
|
||||
end
|
||||
|
||||
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, "filetype", "gitea")
|
||||
vim.api.nvim_buf_set_name(buf, string.format("gitea_issue_full_%d", number))
|
||||
|
||||
highlights.setup()
|
||||
|
||||
-- Render lines & create extmarks
|
||||
local metadata = render_issue_into_buf(buf, issue_data, all_comments)
|
||||
|
||||
-- Hook saving => parse extmarks & do updates
|
||||
vim.api.nvim_create_autocmd("BufWriteCmd", {
|
||||
buffer = buf,
|
||||
callback = function()
|
||||
on_issue_buf_write(buf, metadata, owner, repo)
|
||||
end
|
||||
})
|
||||
|
||||
vim.api.nvim_set_current_buf(buf)
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- SUBCOMMANDS
|
||||
------------------------------------------------------------------------------
|
||||
local subcommands = {}
|
||||
|
||||
subcommands.issue = {
|
||||
list = function(_)
|
||||
local owner, repo = detect_owner_repo()
|
||||
if not owner or not repo then
|
||||
vim.notify("[gitea.nvim] Could not detect owner/repo.", vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
local has_telescope, _ = pcall(require, "telescope")
|
||||
if not has_telescope then
|
||||
vim.notify("[gitea.nvim] telescope.nvim is not installed", vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
local pickers = require("telescope.pickers")
|
||||
local finders = require("telescope.finders")
|
||||
local conf = require("telescope.config").values
|
||||
local actions = require("telescope.actions")
|
||||
local action_state = require("telescope.actions.state")
|
||||
|
||||
local issues, st = api.list_issues(owner, repo, {})
|
||||
if not issues then
|
||||
vim.notify(string.format("[gitea.nvim] Error fetching issues (HTTP %s).", st or "?"), vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
pickers.new({}, {
|
||||
prompt_title = string.format("Issues: %s/%s", owner, repo),
|
||||
finder = finders.new_table {
|
||||
results = issues,
|
||||
entry_maker = function(issue)
|
||||
return {
|
||||
value = issue,
|
||||
display = string.format("#%d %s", issue.number, issue.title),
|
||||
ordinal = issue.number .. " " .. issue.title
|
||||
}
|
||||
end
|
||||
},
|
||||
sorter = conf.generic_sorter({}),
|
||||
attach_mappings = function(prompt_bufnr, map)
|
||||
local function select_issue()
|
||||
local selection = action_state.get_selected_entry()
|
||||
actions.close(prompt_bufnr)
|
||||
if not selection or not selection.value then
|
||||
return
|
||||
end
|
||||
open_full_issue_buffer(owner, repo, selection.value.number)
|
||||
end
|
||||
map("i", "<CR>", select_issue)
|
||||
map("n", "<CR>", select_issue)
|
||||
return true
|
||||
end,
|
||||
}):find()
|
||||
end,
|
||||
|
||||
show = function(args)
|
||||
local number = tonumber(args[1])
|
||||
if not number then
|
||||
vim.notify("[gitea.nvim] Usage: :Gitea issue show <number>", vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
local owner, repo = detect_owner_repo()
|
||||
if not owner or not repo then
|
||||
vim.notify("[gitea.nvim] Could not detect owner/repo.", vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
open_full_issue_buffer(owner, repo, number)
|
||||
end,
|
||||
}
|
||||
|
||||
subcommands.pr = {
|
||||
-- If you have PR subcommands, add them here
|
||||
}
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- REGISTER
|
||||
------------------------------------------------------------------------------
|
||||
function M.register()
|
||||
vim.api.nvim_create_user_command("Gitea", function(cmd_opts)
|
||||
auth.ensure_token()
|
||||
local args = {}
|
||||
for w in string.gmatch(cmd_opts.args, "%S+") do
|
||||
table.insert(args, w)
|
||||
end
|
||||
local object = args[1]
|
||||
local action = args[2]
|
||||
if not object then
|
||||
print("Usage: :Gitea <object> <action> [args]")
|
||||
print("Examples:")
|
||||
print(" :Gitea issue list")
|
||||
print(" :Gitea issue show 123")
|
||||
return
|
||||
end
|
||||
local sc = subcommands[object]
|
||||
if not sc then
|
||||
vim.notify("[gitea.nvim] Unknown object: " .. object, vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
if not action then
|
||||
vim.notify("[gitea.nvim] Please specify an action for " .. object, vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
local fn = sc[action]
|
||||
if not fn then
|
||||
vim.notify(string.format("[gitea.nvim] Unknown action '%s' for object '%s'", action, object), vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
table.remove(args, 1)
|
||||
table.remove(args, 1)
|
||||
fn(args)
|
||||
end, {
|
||||
nargs = "*",
|
||||
complete = function(arg_lead, cmd_line, _)
|
||||
local parts = vim.split(cmd_line, "%s+")
|
||||
if #parts == 2 then
|
||||
local objs = {}
|
||||
for k, _ in pairs(subcommands) do
|
||||
if k:match("^" .. arg_lead) then
|
||||
table.insert(objs, k)
|
||||
end
|
||||
end
|
||||
return objs
|
||||
elseif #parts == 3 then
|
||||
local object = parts[2]
|
||||
local acts = {}
|
||||
if subcommands[object] then
|
||||
for k, _ in pairs(subcommands[object]) do
|
||||
if k:match("^" .. arg_lead) then
|
||||
table.insert(acts, k)
|
||||
end
|
||||
end
|
||||
end
|
||||
return acts
|
||||
else
|
||||
return {}
|
||||
end
|
||||
end,
|
||||
desc = "Unified Gitea command with subcommands",
|
||||
complete = M._gitea_cmd_complete,
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user