feat(git): :Gedit, path/stage completion, status.statusline()
This commit is contained in:
@@ -77,7 +77,7 @@ vim.opt.inccommand = "split"
|
||||
vim.opt.winborder = "rounded"
|
||||
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()%}"
|
||||
.. " %{&filetype} %{&fileencoding} %{&fileformat}"
|
||||
|
||||
+10
-4
@@ -13,10 +13,6 @@ local HIGHLIGHTS = {
|
||||
|
||||
local M = {}
|
||||
|
||||
function M.status()
|
||||
return vim.b.git_status or ""
|
||||
end
|
||||
|
||||
function M.init()
|
||||
for name, link in pairs(HIGHLIGHTS) do
|
||||
vim.api.nvim_set_hl(0, name, { link = link, default = true })
|
||||
@@ -103,6 +99,16 @@ function M.init()
|
||||
complete = complete_rev,
|
||||
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)
|
||||
require("git.cmd").run(opts.fargs)
|
||||
|
||||
@@ -98,6 +98,32 @@ function M.complete_rev(arg_lead)
|
||||
if not worktree then
|
||||
return {}
|
||||
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
|
||||
@@ -105,6 +131,63 @@ function M.complete_rev(arg_lead)
|
||||
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 seen = {}
|
||||
for _, full_path in ipairs(util.split_lines(out)) do
|
||||
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
|
||||
return matches
|
||||
end
|
||||
|
||||
---@param worktree string
|
||||
|
||||
@@ -49,4 +49,9 @@ function M.format(code)
|
||||
return string.format("%%#%s#%s%%*", hl, char)
|
||||
end
|
||||
|
||||
---@return string
|
||||
function M.statusline()
|
||||
return vim.b.git_status or ""
|
||||
end
|
||||
|
||||
return M
|
||||
|
||||
Reference in New Issue
Block a user