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.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
@@ -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)
|
||||||
|
|||||||
@@ -98,6 +98,32 @@ 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 = {}
|
local matches = {}
|
||||||
for _, ref in ipairs(M.list_refs(worktree)) do
|
for _, ref in ipairs(M.list_refs(worktree)) do
|
||||||
if ref:sub(1, #arg_lead) == arg_lead then
|
if ref:sub(1, #arg_lead) == arg_lead then
|
||||||
@@ -107,6 +133,63 @@ function M.complete_rev(arg_lead)
|
|||||||
return matches
|
return matches
|
||||||
end
|
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
|
---@param worktree string
|
||||||
---@param rev string
|
---@param rev string
|
||||||
---@param short boolean
|
---@param short boolean
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user