refactor(git): replace status_view URI scheme with path-style name
This commit is contained in:
+17
-76
@@ -7,8 +7,6 @@ local util = require("git.core.util")
|
||||
|
||||
local M = {}
|
||||
|
||||
M.URI_PREFIX = "gitstatus://"
|
||||
|
||||
---@type ow.Git.StatusView.Placement[]
|
||||
M.PLACEMENTS = { "sidebar", "split", "current" }
|
||||
|
||||
@@ -16,14 +14,10 @@ M.PLACEMENTS = { "sidebar", "split", "current" }
|
||||
local SECTIONS = { "untracked", "unstaged", "staged", "unmerged" }
|
||||
local WINDOW_WIDTH = 50
|
||||
|
||||
---@param name string
|
||||
---@return integer? bufnr
|
||||
local function find_buf(name)
|
||||
for _, b in ipairs(vim.api.nvim_list_bufs()) do
|
||||
if vim.api.nvim_buf_get_name(b) == name then
|
||||
return b
|
||||
end
|
||||
end
|
||||
---@param r ow.Git.Repo
|
||||
---@return string
|
||||
local function buf_name_for(r)
|
||||
return r.worktree .. "/Git Status"
|
||||
end
|
||||
|
||||
---@alias ow.Git.StatusView.Placement "sidebar"|"split"|"current"
|
||||
@@ -697,8 +691,9 @@ function M.open(opts)
|
||||
util.error("not in a git repository")
|
||||
return
|
||||
end
|
||||
|
||||
local previous_win = vim.api.nvim_get_current_win()
|
||||
local buf = vim.fn.bufadd(M.URI_PREFIX .. r.worktree)
|
||||
local buf = vim.fn.bufadd(buf_name_for(r))
|
||||
|
||||
local visible = vim.fn.bufwinid(buf)
|
||||
if visible ~= -1 then
|
||||
@@ -707,78 +702,24 @@ function M.open(opts)
|
||||
return
|
||||
end
|
||||
|
||||
local was_loaded = vim.api.nvim_buf_is_loaded(buf)
|
||||
local win = place(buf, placement)
|
||||
|
||||
vim.bo[buf].bufhidden = placement == "sidebar" and "wipe" or "hide"
|
||||
local s = state[buf]
|
||||
if s then
|
||||
s.win = win
|
||||
s.placement = placement
|
||||
if not state[buf] then
|
||||
vim.fn.bufload(buf)
|
||||
repo.bind(buf, r)
|
||||
util.setup_scratch(buf, {})
|
||||
vim.bo[buf].filetype = "gitstatus"
|
||||
setup_buffer(buf, r, placement)
|
||||
end
|
||||
vim.bo[buf].bufhidden = placement == "sidebar" and "wipe" or "hide"
|
||||
|
||||
local win = place(buf, placement)
|
||||
state[buf].win = win
|
||||
state[buf].placement = placement
|
||||
set_keymaps(buf, placement)
|
||||
|
||||
if placement == "sidebar" then
|
||||
vim.api.nvim_set_current_win(previous_win)
|
||||
end
|
||||
|
||||
if was_loaded then
|
||||
refresh(buf)
|
||||
end
|
||||
r:refresh()
|
||||
end
|
||||
|
||||
---@param buf integer
|
||||
function M.read_uri(buf)
|
||||
local name = vim.api.nvim_buf_get_name(buf)
|
||||
local raw = name:sub(#M.URI_PREFIX + 1)
|
||||
if raw == "" then
|
||||
return
|
||||
end
|
||||
local worktree = vim.fs.abspath(raw)
|
||||
local r = repo.resolve(worktree)
|
||||
if not r then
|
||||
util.error("not a git worktree: %s", raw)
|
||||
return
|
||||
end
|
||||
if r.worktree ~= worktree then
|
||||
util.warning("%s is not a worktree root, using %s", raw, r.worktree)
|
||||
end
|
||||
local canonical = M.URI_PREFIX .. r.worktree
|
||||
if name ~= canonical then
|
||||
local existing = find_buf(canonical)
|
||||
if existing and existing ~= buf then
|
||||
local win = vim.api.nvim_get_current_win()
|
||||
if vim.api.nvim_win_get_buf(win) == buf then
|
||||
vim.api.nvim_win_set_buf(win, existing)
|
||||
end
|
||||
vim.api.nvim_buf_delete(buf, { force = true })
|
||||
local s = state[existing]
|
||||
if s then
|
||||
s.win = win
|
||||
s.placement = "current"
|
||||
end
|
||||
refresh(existing)
|
||||
r:refresh()
|
||||
return
|
||||
end
|
||||
pcall(vim.api.nvim_buf_set_name, buf, canonical)
|
||||
end
|
||||
repo.bind(buf, r)
|
||||
|
||||
util.setup_scratch(buf, { bufhidden = "hide" })
|
||||
vim.bo[buf].filetype = "gitstatus"
|
||||
|
||||
---@type integer?
|
||||
local win = vim.fn.bufwinid(buf)
|
||||
if win == -1 then
|
||||
win = nil
|
||||
end
|
||||
if not state[buf] then
|
||||
setup_buffer(buf, r, "current", win)
|
||||
else
|
||||
state[buf].win = win
|
||||
end
|
||||
refresh(buf)
|
||||
r:refresh()
|
||||
end
|
||||
|
||||
+3
-8
@@ -103,14 +103,6 @@ vim.api.nvim_create_autocmd("BufReadCmd", {
|
||||
require("git.log_view").read_uri(args.buf)
|
||||
end,
|
||||
})
|
||||
vim.api.nvim_create_autocmd("BufReadCmd", {
|
||||
pattern = "gitstatus://*",
|
||||
group = group,
|
||||
callback = function(args)
|
||||
require("git.status_view").read_uri(args.buf)
|
||||
end,
|
||||
})
|
||||
|
||||
vim.api.nvim_create_user_command("G", function(opts)
|
||||
local cmd = require("git.cmd")
|
||||
cmd.run(cmd.parse_args(opts.args), { bang = opts.bang })
|
||||
@@ -233,6 +225,9 @@ vim.keymap.set("n", "<Plug>(git-diff-horizontal-head)", function()
|
||||
})
|
||||
end, { silent = true, desc = "Diff against HEAD (horizontal)" })
|
||||
|
||||
vim.keymap.set("n", "<Plug>(git-status-open)", function()
|
||||
require("git.status_view").open()
|
||||
end, { silent = true, desc = "Open git status sidebar" })
|
||||
vim.keymap.set("n", "<Plug>(git-status-toggle)", function()
|
||||
require("git.status_view").toggle()
|
||||
end, { silent = true, desc = "Toggle git status sidebar" })
|
||||
|
||||
@@ -315,3 +315,93 @@ t.test(
|
||||
)
|
||||
end
|
||||
)
|
||||
|
||||
t.test("sidebar buffer is named <worktree>/Git Status", function()
|
||||
local repo = h.make_repo({ ["foo.txt"] = "x\n" })
|
||||
vim.cmd("cd " .. repo)
|
||||
require("git.status_view").open({ placement = "sidebar" })
|
||||
local r = assert(require("git.core.repo").find(vim.fn.getcwd()))
|
||||
local buf = find_sidebar()
|
||||
assert(buf, "sidebar buffer should exist")
|
||||
t.eq(
|
||||
vim.api.nvim_buf_get_name(buf),
|
||||
r.worktree .. "/Git Status",
|
||||
"buffer name should be <worktree>/Git Status"
|
||||
)
|
||||
end)
|
||||
|
||||
t.test(
|
||||
"calling open twice without closing focuses the existing sidebar",
|
||||
function()
|
||||
local repo = h.make_repo({ ["foo.txt"] = "x\n" })
|
||||
vim.cmd("cd " .. repo)
|
||||
require("git.status_view").open({ placement = "sidebar" })
|
||||
local first = find_sidebar()
|
||||
assert(first, "first sidebar buffer should exist")
|
||||
|
||||
require("git.status_view").open({ placement = "sidebar" })
|
||||
local second = find_sidebar()
|
||||
assert(second, "second sidebar buffer should exist")
|
||||
t.eq(
|
||||
first,
|
||||
second,
|
||||
"consecutive opens should reuse the visible sidebar"
|
||||
)
|
||||
local count = 0
|
||||
for _, b in ipairs(vim.api.nvim_list_bufs()) do
|
||||
if vim.bo[b].filetype == "gitstatus" then
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
t.eq(count, 1, "only one gitstatus buffer should exist")
|
||||
end
|
||||
)
|
||||
|
||||
t.test("opening for different worktrees creates separate buffers", function()
|
||||
local repo_a = h.make_repo({ ["a.txt"] = "x\n" })
|
||||
local repo_b = h.make_repo({ ["b.txt"] = "y\n" })
|
||||
|
||||
vim.cmd("cd " .. repo_a)
|
||||
require("git.status_view").open({ placement = "sidebar" })
|
||||
local buf_a = find_sidebar()
|
||||
require("git.status_view").toggle()
|
||||
|
||||
vim.cmd("cd " .. repo_b)
|
||||
require("git.status_view").open({ placement = "sidebar" })
|
||||
local buf_b = find_sidebar()
|
||||
|
||||
assert(buf_a and buf_b)
|
||||
t.truthy(
|
||||
buf_a ~= buf_b,
|
||||
"different worktrees should produce different buffers"
|
||||
)
|
||||
end)
|
||||
|
||||
t.test("sidebar buffer is buftype=nofile and not buflisted", function()
|
||||
local repo = h.make_repo({ ["foo.txt"] = "x\n" })
|
||||
vim.cmd("cd " .. repo)
|
||||
require("git.status_view").open({ placement = "sidebar" })
|
||||
local buf = find_sidebar()
|
||||
assert(buf, "sidebar buffer should exist")
|
||||
t.eq(vim.bo[buf].buftype, "nofile", "buftype should be nofile")
|
||||
t.eq(vim.bo[buf].buflisted, false, "buflisted should be false")
|
||||
end)
|
||||
|
||||
t.test("sidebar buffer name does not get written to disk", function()
|
||||
local repo = h.make_repo({ ["foo.txt"] = "x\n" })
|
||||
vim.cmd("cd " .. repo)
|
||||
require("git.status_view").open({ placement = "sidebar" })
|
||||
local buf = find_sidebar()
|
||||
assert(buf, "sidebar buffer should exist")
|
||||
local name = vim.api.nvim_buf_get_name(buf)
|
||||
vim.api.nvim_buf_call(buf, function()
|
||||
pcall(function()
|
||||
vim.cmd("silent! write")
|
||||
end)
|
||||
end)
|
||||
t.eq(
|
||||
vim.uv.fs_stat(name),
|
||||
nil,
|
||||
"no real file should be created at the sidebar buffer's path"
|
||||
)
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user