From 9f44c9de40647c9640d94485c35d729c2cad2fd3 Mon Sep 17 00:00:00 2001 From: Oscar Wallberg Date: Thu, 30 Apr 2026 17:20:12 +0200 Subject: [PATCH] feat(git): rev completion for :Gdiffsplit family --- lua/git/init.lua | 33 ++++++++++++++++++--------------- lua/git/repo.lua | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 15 deletions(-) diff --git a/lua/git/init.lua b/lua/git/init.lua index 18c8a1d..84a844e 100644 --- a/lua/git/init.lua +++ b/lua/git/init.lua @@ -85,21 +85,24 @@ function M.init() }) end end - vim.api.nvim_create_user_command( - "Gdiffsplit", - diff_split_cmd(true), - { nargs = "?", desc = "Diff against " } - ) - vim.api.nvim_create_user_command( - "Gvdiffsplit", - diff_split_cmd(true), - { nargs = "?", desc = "Diff against (vertical split)" } - ) - vim.api.nvim_create_user_command( - "Ghdiffsplit", - diff_split_cmd(false), - { nargs = "?", desc = "Diff against (horizontal split)" } - ) + local function complete_rev(...) + return require("git.repo").complete_rev(...) + end + vim.api.nvim_create_user_command("Gdiffsplit", diff_split_cmd(true), { + nargs = "?", + complete = complete_rev, + desc = "Diff against ", + }) + vim.api.nvim_create_user_command("Gvdiffsplit", diff_split_cmd(true), { + nargs = "?", + complete = complete_rev, + desc = "Diff against (vertical split)", + }) + vim.api.nvim_create_user_command("Ghdiffsplit", diff_split_cmd(false), { + nargs = "?", + complete = complete_rev, + desc = "Diff against (horizontal split)", + }) vim.api.nvim_create_user_command("G", function(opts) require("git.cmd").run(opts.fargs) diff --git a/lua/git/repo.lua b/lua/git/repo.lua index f70abae..5302ebd 100644 --- a/lua/git/repo.lua +++ b/lua/git/repo.lua @@ -111,6 +111,41 @@ function M.head(path) return nil end +---@param worktree string +---@return string[] +function M.list_refs(worktree) + local out = util.exec({ + "git", + "for-each-ref", + "--format=%(refname:short)", + "refs/heads", + "refs/tags", + "refs/remotes", + }, { cwd = worktree, silent = true }) + if not out then + return {} + end + local refs = util.split_lines(out) + table.insert(refs, 1, "HEAD") + return refs +end + +---@param arg_lead string +---@return string[] +function M.complete_rev(arg_lead) + local _, worktree = M.resolve_cwd() + if not worktree then + return {} + end + local matches = {} + for _, ref in ipairs(M.list_refs(worktree)) do + if ref:sub(1, #arg_lead) == arg_lead then + table.insert(matches, ref) + end + end + return matches +end + ---@param worktree string ---@param rev string ---@param short boolean