DiffBase: custom function for Neovim
This commit is contained in:
@@ -44,6 +44,8 @@ require("basic-settings")
|
||||
-- ============================================================================
|
||||
require("lazy").setup("plugins")
|
||||
|
||||
require("diff-base")
|
||||
|
||||
-- ============================================================================
|
||||
-- STEP 4: LSP KEYMAPS
|
||||
-- ============================================================================
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
local git = require("neo-tree.git")
|
||||
local parser = require("neo-tree.git.parser")
|
||||
local git_cmd = require("neo-tree.git.cmd")
|
||||
local utils = require("neo-tree.utils")
|
||||
|
||||
local diff_base = nil
|
||||
local status_cache = {}
|
||||
local orig_find_status
|
||||
|
||||
local function find_worktree_root()
|
||||
local root = git.find_worktree_info(vim.fn.getcwd())
|
||||
if not root then
|
||||
local buf = vim.api.nvim_buf_get_name(0)
|
||||
if buf ~= "" then
|
||||
root = git.find_worktree_info(buf)
|
||||
end
|
||||
end
|
||||
return root
|
||||
end
|
||||
|
||||
local function run_git(args)
|
||||
local result = vim.system(args):wait()
|
||||
if result.code ~= 0 then
|
||||
return nil
|
||||
end
|
||||
return result.stdout
|
||||
end
|
||||
|
||||
local function compute_status(wr, base)
|
||||
local args = git_cmd.with_args({ "-C", wr, "diff", base, "--name-status", "-z" })
|
||||
local out = run_git(args)
|
||||
if not out then
|
||||
vim.notify("DiffBase: invalid ref " .. base, vim.log.levels.WARN)
|
||||
return nil
|
||||
end
|
||||
local status = parser.parse_diff_name_status_output(wr, false, utils.gsplit_plain(out, "\000"))
|
||||
local ut = run_git(git_cmd.with_args({ "-C", wr, "ls-files", "--others", "--exclude-standard", "-z" }))
|
||||
if ut then
|
||||
for _, p in ipairs(parser.parse_ls_files_output(wr, utils.gsplit_plain(ut, "\000"))) do
|
||||
status[p] = "?"
|
||||
end
|
||||
end
|
||||
return status
|
||||
end
|
||||
|
||||
local function patch()
|
||||
if not orig_find_status then
|
||||
orig_find_status = git.find_existing_status_code
|
||||
end
|
||||
git.find_existing_status_code = function(path, base_lookup)
|
||||
if diff_base then
|
||||
local wr, _ = git.find_existing_worktree(path)
|
||||
local cached = wr and status_cache[wr]
|
||||
local hit = cached and cached[path]
|
||||
if hit then
|
||||
return hit, true
|
||||
end
|
||||
end
|
||||
return orig_find_status(path, base_lookup)
|
||||
end
|
||||
end
|
||||
|
||||
local function set(base)
|
||||
base = base or ""
|
||||
if base == "" or base == "HEAD" then
|
||||
diff_base = nil
|
||||
status_cache = {}
|
||||
pcall(function()
|
||||
require("gitsigns").change_base(nil, true)
|
||||
end)
|
||||
local e = require("neo-tree.events")
|
||||
vim.schedule(function()
|
||||
e.fire_event(e.GIT_EVENT, {})
|
||||
end)
|
||||
vim.notify("DiffBase: reset to HEAD")
|
||||
return
|
||||
end
|
||||
local wr = find_worktree_root()
|
||||
if not wr then
|
||||
vim.notify("DiffBase: not in a git repo", vim.log.levels.WARN)
|
||||
return
|
||||
end
|
||||
local s = compute_status(wr, base)
|
||||
if not s then
|
||||
return
|
||||
end
|
||||
diff_base = base
|
||||
status_cache[wr] = s
|
||||
pcall(function()
|
||||
require("gitsigns").change_base(base, true)
|
||||
end)
|
||||
patch()
|
||||
local events = require("neo-tree.events")
|
||||
if git.worktrees[wr] then
|
||||
git.worktrees[wr].status = s
|
||||
end
|
||||
vim.schedule(function()
|
||||
events.fire_event(events.GIT_STATUS_CHANGED, { git_root = wr, git_status = s, base = base })
|
||||
end)
|
||||
vim.notify("DiffBase: set to " .. base)
|
||||
end
|
||||
|
||||
vim.api.nvim_create_user_command("DiffBase", function(opts)
|
||||
set(opts.args)
|
||||
end, {
|
||||
nargs = "?",
|
||||
complete = function(l)
|
||||
return vim.tbl_filter(function(s)
|
||||
return s:find(l, 1, true) == 1
|
||||
end, { "HEAD", "HEAD~1", "HEAD~2", "HEAD~3", "main", "master", "origin/main", "origin/master" })
|
||||
end,
|
||||
})
|
||||
Reference in New Issue
Block a user