DiffBase: custom function for Neovim

This commit is contained in:
Mathias Schneider
2026-08-05 09:46:57 +02:00
parent 2a48013090
commit 9066c62080
2 changed files with 114 additions and 0 deletions
+2
View File
@@ -44,6 +44,8 @@ require("basic-settings")
-- ============================================================================
require("lazy").setup("plugins")
require("diff-base")
-- ============================================================================
-- STEP 4: LSP KEYMAPS
-- ============================================================================
+112
View File
@@ -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,
})