DiffBase: custom function for Neovim
This commit is contained in:
@@ -44,6 +44,8 @@ require("basic-settings")
|
|||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
require("lazy").setup("plugins")
|
require("lazy").setup("plugins")
|
||||||
|
|
||||||
|
require("diff-base")
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- STEP 4: LSP KEYMAPS
|
-- 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