feat(git): open commits from gitlog in the same window

This commit is contained in:
2026-04-28 07:55:25 +02:00
parent 9ef5180a6a
commit 01c0f82e18
3 changed files with 28 additions and 12 deletions
+1 -1
View File
@@ -9,7 +9,7 @@ vim.keymap.set("n", "<CR>", function()
.nvim_get_current_line() .nvim_get_current_line()
:match("^[*|/\\_ ]*(%x%x%x%x%x%x%x+)") :match("^[*|/\\_ ]*(%x%x%x%x%x%x%x+)")
if sha then if sha then
require("git.show").open_commit(worktree, sha) require("git.show").open_commit(worktree, sha, { split = false })
else else
-- "n" mode = no remap, so this doesn't recurse into our mapping. -- "n" mode = no remap, so this doesn't recurse into our mapping.
vim.api.nvim_feedkeys(cr, "n", false) vim.api.nvim_feedkeys(cr, "n", false)
+7 -2
View File
@@ -28,9 +28,9 @@ end
---@class ow.Git.NewScratchOpts ---@class ow.Git.NewScratchOpts
---@field name string? ---@field name string?
---@field bufhidden ("hide"|"wipe")? defaults to "hide" ---@field bufhidden ("hide"|"wipe")? defaults to "hide"
---@field split ("above"|"below"|"left"|"right")? defaults to splitbelow-aware horizontal ---@field split (false|"above"|"below"|"left"|"right")? defaults to splitbelow-aware horizontal. `false` places the buffer in the current window (drops a `'` mark first so the user can jump back).
---Open a split with a fresh non-modifiable scratch buffer. Default split ---Create a fresh non-modifiable scratch buffer and place it. Default split
---direction is horizontal, honouring `splitbelow`. Caller flips ---direction is horizontal, honouring `splitbelow`. Caller flips
---`modifiable`, fills the buffer, and sets `filetype` once content lands. ---`modifiable`, fills the buffer, and sets `filetype` once content lands.
---@param opts ow.Git.NewScratchOpts? ---@param opts ow.Git.NewScratchOpts?
@@ -47,6 +47,11 @@ function M.new_scratch(opts)
if opts.name then if opts.name then
pcall(vim.api.nvim_buf_set_name, buf, opts.name) pcall(vim.api.nvim_buf_set_name, buf, opts.name)
end end
if opts.split == false then
vim.cmd.normal({ "m'", bang = true })
vim.api.nvim_set_current_buf(buf)
return buf, vim.api.nvim_get_current_win()
end
local split = opts.split or (vim.o.splitbelow and "below" or "above") local split = opts.split or (vim.o.splitbelow and "below" or "above")
local win = vim.api.nvim_open_win(buf, true, { split = split }) local win = vim.api.nvim_open_win(buf, true, { split = split })
return buf, win return buf, win
+20 -9
View File
@@ -127,9 +127,14 @@ local function show_diff(ctx, section)
vim.api.nvim_set_current_win(left_win) vim.api.nvim_set_current_win(left_win)
end end
---@class ow.Git.OpenCommitOpts
---@field split (false|"above"|"below"|"left"|"right")? forwarded to `git.new_scratch`. Default opens a new horizontal split.
---@param worktree string ---@param worktree string
---@param ref string ---@param ref string
function M.open_commit(worktree, ref) ---@param opts ow.Git.OpenCommitOpts?
function M.open_commit(worktree, ref, opts)
local split = opts and opts.split
repo.rev_parse(worktree, ref, true, function(resolved) repo.rev_parse(worktree, ref, true, function(resolved)
local sha = resolved or ref local sha = resolved or ref
local name = "git://" .. sha .. "//" local name = "git://" .. sha .. "//"
@@ -137,13 +142,18 @@ function M.open_commit(worktree, ref)
-- are immutable so the content is stable. -- are immutable so the content is stable.
local existing = vim.fn.bufnr(name) local existing = vim.fn.bufnr(name)
if existing ~= -1 and vim.api.nvim_buf_is_loaded(existing) then if existing ~= -1 and vim.api.nvim_buf_is_loaded(existing) then
vim.api.nvim_open_win(existing, true, { if split == false then
split = vim.o.splitbelow and "below" or "above", vim.cmd.normal({ "m'", bang = true })
}) vim.api.nvim_set_current_buf(existing)
else
vim.api.nvim_open_win(existing, true, {
split = split or (vim.o.splitbelow and "below" or "above"),
})
end
return return
end end
local buf, win = git.new_scratch({ name = name }) local buf, win = git.new_scratch({ name = name, split = split })
vim.b[buf].git_worktree = worktree vim.b[buf].git_worktree = worktree
vim.b[buf].git_ref = sha vim.b[buf].git_ref = sha
@@ -157,10 +167,11 @@ function M.open_commit(worktree, ref)
ref, ref,
vim.trim(result.stderr or "") vim.trim(result.stderr or "")
) )
-- Tear down the empty placeholder window+buffer so a -- Drop the empty placeholder so a retry runs a fresh
-- retry runs a fresh fetch instead of hitting the -- fetch. With `split = false` the window falls back to
-- cached-buffer branch and reopening an empty pane. -- its alternate buffer (the gitlog); for a real split
if vim.api.nvim_win_is_valid(win) then -- we close the dedicated window to keep the layout tidy.
if split ~= false and vim.api.nvim_win_is_valid(win) then
pcall(vim.api.nvim_win_close, win, true) pcall(vim.api.nvim_win_close, win, true)
end end
if vim.api.nvim_buf_is_valid(buf) then if vim.api.nvim_buf_is_valid(buf) then