feat(git): :Gedit, path/stage completion, status.statusline()

This commit is contained in:
2026-04-30 18:13:49 +02:00
parent 1c91753500
commit af7e187aa9
4 changed files with 102 additions and 8 deletions
+1 -1
View File
@@ -77,7 +77,7 @@ vim.opt.inccommand = "split"
vim.opt.winborder = "rounded" vim.opt.winborder = "rounded"
vim.opt.confirm = true vim.opt.confirm = true
vim.opt.statusline = "%{expand('%:.')} %{%v:lua.require('git').status()%} %3(%m%)" vim.opt.statusline = "%{expand('%:.')} %{%v:lua.require('git.status').statusline()%} %3(%m%)"
.. " %=" .. " %="
.. " %{%v:lua.vim.diagnostic.status()%}" .. " %{%v:lua.vim.diagnostic.status()%}"
.. " %{&filetype} %{&fileencoding} %{&fileformat}" .. " %{&filetype} %{&fileencoding} %{&fileformat}"
+10 -4
View File
@@ -13,10 +13,6 @@ local HIGHLIGHTS = {
local M = {} local M = {}
function M.status()
return vim.b.git_status or ""
end
function M.init() function M.init()
for name, link in pairs(HIGHLIGHTS) do for name, link in pairs(HIGHLIGHTS) do
vim.api.nvim_set_hl(0, name, { link = link, default = true }) vim.api.nvim_set_hl(0, name, { link = link, default = true })
@@ -103,6 +99,16 @@ function M.init()
complete = complete_rev, complete = complete_rev,
desc = "Diff against <rev> (horizontal split)", desc = "Diff against <rev> (horizontal split)",
}) })
vim.api.nvim_create_user_command("Gedit", function(opts)
vim.cmd.edit({
args = { "git://" .. opts.args },
magic = { file = false },
})
end, {
nargs = 1,
complete = complete_rev,
desc = "Edit a git object (<rev>)",
})
vim.api.nvim_create_user_command("G", function(opts) vim.api.nvim_create_user_command("G", function(opts)
require("git.cmd").run(opts.fargs) require("git.cmd").run(opts.fargs)
+86 -3
View File
@@ -98,10 +98,93 @@ function M.complete_rev(arg_lead)
if not worktree then if not worktree then
return {} return {}
end end
local stage, stage_path_lead = arg_lead:match("^:([0-3]):(.*)$")
if stage then
local out = util.exec(
{ "git", "ls-files", "--stage" },
{ cwd = worktree, silent = true }
)
if not out then
return {}
end
local matches = {}
for _, line in ipairs(util.split_lines(out)) do
local row_stage, row_path = line:match("^%S+ %S+ (%d)\t(.*)$")
if
row_stage == stage
and row_path
and row_path:sub(1, #stage_path_lead) == stage_path_lead
then
table.insert(matches, ":" .. stage .. ":" .. row_path)
end
end
return matches
end
local colon = arg_lead:find(":", 1, true)
if not colon then
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
local rev = arg_lead:sub(1, colon - 1)
local path_lead = arg_lead:sub(colon + 1)
local dir, name_lead = path_lead:match("^(.*/)([^/]*)$")
dir = dir or ""
name_lead = name_lead or path_lead
if rev ~= "" then
local cmd = { "git", "ls-tree", rev }
if dir ~= "" then
table.insert(cmd, dir)
end
local out = util.exec(cmd, { cwd = worktree, silent = true })
if not out then
return {}
end
local matches = {}
for _, line in ipairs(util.split_lines(out)) do
local typ, full_path = line:match("^%S+ (%S+) %S+\t(.*)$")
if typ and full_path then
local basename = dir == "" and full_path
or full_path:sub(#dir + 1)
if typ == "tree" then
basename = basename .. "/"
end
if basename:sub(1, #name_lead) == name_lead then
table.insert(matches, rev .. ":" .. dir .. basename)
end
end
end
return matches
end
local cmd = { "git", "ls-files" }
if dir ~= "" then
table.insert(cmd, dir)
end
local out = util.exec(cmd, { cwd = worktree, silent = true })
if not out then
return {}
end
local matches = {} local matches = {}
for _, ref in ipairs(M.list_refs(worktree)) do local seen = {}
if ref:sub(1, #arg_lead) == arg_lead then for _, full_path in ipairs(util.split_lines(out)) do
table.insert(matches, ref) local rel = dir == "" and full_path or full_path:sub(#dir + 1)
local slash = rel:find("/", 1, true)
local segment = slash and rel:sub(1, slash) or rel
if
not seen[segment]
and segment:sub(1, #name_lead) == name_lead
then
seen[segment] = true
table.insert(matches, ":" .. dir .. segment)
end end
end end
return matches return matches
+5
View File
@@ -49,4 +49,9 @@ function M.format(code)
return string.format("%%#%s#%s%%*", hl, char) return string.format("%%#%s#%s%%*", hl, char)
end end
---@return string
function M.statusline()
return vim.b.git_status or ""
end
return M return M