Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions doc/diffview.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1417,7 +1417,9 @@ conflict_choose_all({version}) *diffview-actions-conflict_choos
copy_hash *diffview-actions-copy_hash*
Contexts: `file_history_panel`

Copy the commit hash of the commit under the cursor.
Copy the commit hash of the commit under the cursor. Honors the
register prefix, so e.g. `"+y` copies the hash to the system
clipboard, while a bare `y` uses the unnamed register.

diffget({target}) *diffview-actions-diffget*
Contexts: `merge_tool`
Expand Down Expand Up @@ -1999,7 +2001,8 @@ gf Open the local version of the file in a different
<leader>e Bring focus to the file panel.

*diffview-maps-copy_hash*
y Copy the commit hash of the entry under the cursor.
y Copy the commit hash of the entry under the cursor
(accepts a register prefix, e.g. `"+y`).

*diffview-maps-file-panel*
File panel maps ~
Expand Down
77 changes: 21 additions & 56 deletions lua/diffview/scene/views/file_history/listeners.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,15 @@ return function(view)
return {
tab_enter = function()
local file = view.panel.cur_item[2]
if file then
view:set_file(file)
end
if file then view:set_file(file) end

view:restore_panel_cursor()
end,
tab_leave = function()
local file = view.panel.cur_item[2]
view:save_panel_cursor()

if file then
file.layout:detach_files()
end
if file then file.layout:detach_files() end

for _, entry in ipairs(view.panel.entries) do
for _, f in ipairs(entry.files) do
Expand Down Expand Up @@ -75,23 +71,15 @@ return function(view)
lib.add_view(new_view)
new_view:open()
end,
select_next_entry = function()
view:next_item()
end,
select_prev_entry = function()
view:prev_item()
end,
select_next_entry = function() view:next_item() end,
select_prev_entry = function() view:prev_item() end,
select_first_entry = function()
local entry = view.panel.entries[1]
if entry and #entry.files > 0 then
view:set_file(entry.files[1])
end
if entry and #entry.files > 0 then view:set_file(entry.files[1]) end
end,
select_last_entry = function()
local entry = view.panel.entries[#view.panel.entries]
if entry and #entry.files > 0 then
view:set_file(entry.files[#entry.files])
end
if entry and #entry.files > 0 then view:set_file(entry.files[#entry.files]) end
end,
select_next_commit = function()
local cur_entry = view.panel.cur_item[1]
Expand Down Expand Up @@ -161,12 +149,8 @@ return function(view)
end
view:set_file(cur_entry.files[prev_idx])
end,
next_entry = function()
view.panel:highlight_next_file()
end,
prev_entry = function()
view.panel:highlight_prev_item()
end,
next_entry = function() view.panel:highlight_next_file() end,
prev_entry = function() view.panel:highlight_prev_item() end,
select_entry = function()
if view.panel:is_focused() then
local item = view.panel:get_item_at_cursor()
Expand All @@ -183,9 +167,7 @@ return function(view)
end
elseif view.panel.option_panel:is_focused() then
local option = view.panel.option_panel:get_item_at_cursor()
if option then
view.panel.option_panel.emitter:emit("set_option", option.key)
end
if option then view.panel.option_panel.emitter:emit("set_option", option.key) end
end
end,
focus_entry = function()
Expand All @@ -208,25 +190,15 @@ return function(view)
local file = view:infer_cur_file()
if file then
local entry = view.panel:find_entry(file)
if entry then
view.commit_log_panel:update(view.adapter.Rev.to_range(entry.commit.hash))
end
if entry then view.commit_log_panel:update(view.adapter.Rev.to_range(entry.commit.hash)) end
end
end,
focus_files = function()
view.panel:focus()
end,
toggle_files = function()
view.panel:toggle(true)
end,
focus_files = function() view.panel:focus() end,
toggle_files = function() view.panel:toggle(true) end,
refresh_files = function()
view.panel:update_entries(function(_, status)
if status >= JobStatus.ERROR then
return
end
if not view:cur_file() then
view:next_item()
end
if status >= JobStatus.ERROR then return end
if not view:cur_file() then view:next_item() end
end)
end,
open_all_folds = function()
Expand Down Expand Up @@ -271,28 +243,23 @@ return function(view)
-- Don't close the view if a floating window is focused; the float's
-- own close listener should handle it.
local win_conf = api.nvim_win_get_config(0)
if win_conf.relative == "" then
view:close()
end
if win_conf.relative == "" then view:close() end
end
end,
options = function()
view.panel.option_panel:focus()
end,
options = function() view.panel.option_panel:focus() end,
copy_hash = function()
if view.panel:is_focused() then
local item = view.panel:get_item_at_cursor()
if item then
vim.fn.setreg('"', item.commit.hash)
utils.info(string.format("Copied '%s' to the default register.", item.commit.hash))
local reg = vim.v.register
vim.fn.setreg(reg, item.commit.hash)
utils.info(string.format("Copied '%s' to register '%s'.", item.commit.hash, reg))
end
end
end,
open_commit_in_browser = function()
local item = view.panel:get_item_at_cursor()
if not item then
item = view.panel.cur_item[1]
end
if not item then item = view.panel.cur_item[1] end
if not item or not item.commit then return end

if not view.adapter.get_commit_url then
Expand All @@ -317,9 +284,7 @@ return function(view)
cmd = { "cmd", "/c", "start", "", url }
end

if cmd then
vim.fn.jobstart(cmd, { detach = true })
end
if cmd then vim.fn.jobstart(cmd, { detach = true }) end
end,
restore_entry = async.void(function()
local item = view:infer_cur_file()
Expand Down
37 changes: 19 additions & 18 deletions lua/diffview/tests/functional/actions_features_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,12 @@ describe("diffview.actions.set_layout (59237ad)", function()
end)

-----------------------------------------------------------------------
-- f728b1f: copy_hash writes to the unnamed register ("), not the
-- system clipboard (+).
-- f728b1f: copy_hash honors the register prefix (vim.v.register),
-- defaulting to the unnamed register (") when none is given.
-----------------------------------------------------------------------

describe("copy_hash uses unnamed register (f728b1f)", function()
it("setreg is called with the unnamed register ('\"')", function()
describe("copy_hash honors vim.v.register (f728b1f)", function()
it("setreg target follows vim.v.register", function()
local setreg_args = {}
local orig_setreg = vim.fn.setreg

Expand All @@ -165,38 +165,39 @@ describe("copy_hash uses unnamed register (f728b1f)", function()

-- Simulate what the copy_hash listener does.
local hash = "abc123def456"
vim.fn.setreg('"', hash)
local reg = vim.v.register
vim.fn.setreg(reg, hash)

vim.fn.setreg = orig_setreg

eq('"', setreg_args.reg)
eq(reg, setreg_args.reg)
eq(hash, setreg_args.val)
end)

it("does not write to the clipboard register", function()
it("writes to the clipboard register when vim.v.register is '+'", function()
local regs_written = {}
local orig_setreg = vim.fn.setreg

vim.fn.setreg = function(reg, val)
regs_written[reg] = val
vim.fn.setreg = function(r, val)
regs_written[r] = val
end

-- Replicate the exact call from the listener.
local hash = "deadbeef1234"
vim.fn.setreg('"', hash)
-- Emulate the user prefixing the mapping with "+.
local reg = "+"
vim.fn.setreg(reg, hash)

vim.fn.setreg = orig_setreg

assert.is_not_nil(regs_written['"'])
assert.is_nil(regs_written['+'])
assert.is_nil(regs_written['*'])
eq(hash, regs_written['+'])
assert.is_nil(regs_written['"'])
end)

it("info message says default register, not clipboard", function()
it("info message names the register that was written", function()
local hash = "abc123def"
local msg = string.format("Copied '%s' to the default register.", hash)
assert.truthy(msg:find("default register"))
assert.falsy(msg:find("clipboard"))
local reg = "a"
local msg = string.format("Copied '%s' to register '%s'.", hash, reg)
assert.truthy(msg:find("register 'a'"))
end)
end)

Expand Down
Loading