local M = {} ---@class CmdWithSubcommand ---@field impl fun(args:string[], opts: table) The command implementation ---@field complete? fun(subcmd_arg_lead: string): string[] Command completions callback ---@param name string The command name ---@param desc string The command description ---@param subcommand_tbl table Table of sub commands M.register = function(name, desc, subcommand_tbl) ---@param opts table :h lua-guide-commands-create local function cmd(opts) local fargs = opts.fargs local subcommand_key = fargs[1] -- Get the subcommand's arguments, if any local args = #fargs > 1 and vim.list_slice(fargs, 2, #fargs) or {} local subcommand = subcommand_tbl[subcommand_key] if not subcommand then vim.notify( name .. ": Unknown command: " .. subcommand_key, vim.log.levels.ERROR ) return end -- Invoke the subcommand subcommand.impl(args, opts) end vim.api.nvim_create_user_command(name, cmd, { nargs = "+", desc = desc, complete = function(arg_lead, cmdline, _) -- Get the subcommand. local subcmd_key, subcmd_arg_lead = cmdline:match("^['<,'>]*" .. name .. "[!]*%s(%S+)%s(.*)$") if subcmd_key and subcmd_arg_lead and subcommand_tbl[subcmd_key] and subcommand_tbl[subcmd_key].complete then -- The subcommand has completions. Return them. return subcommand_tbl[subcmd_key].complete(subcmd_arg_lead) end -- Check if cmdline is a subcommand if cmdline:match("^['<,'>]*" .. name .. "[!]*%s+%w*$") then -- Filter subcommands that match local subcommand_keys = vim.tbl_keys(subcommand_tbl) return vim .iter(subcommand_keys) :filter(function(key) return key:find(arg_lead) ~= nil end) :totable() end end, -- bang = true, -- If you want to support ! modifiers }) end return M