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
2 changes: 1 addition & 1 deletion .agents/skills/verify-diff-lifecycle/covered.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ file lua/claudecode/config.lua b4eaec92b6d04b40
== lua/claudecode/cwd.lua
file lua/claudecode/cwd.lua 55d26ea362173afa
== lua/claudecode/diff.lua
file lua/claudecode/diff.lua 53c0f9034a7df662
file lua/claudecode/diff.lua a21129cdc802e417
block resolve_saved 46d5f3f732711fe1
block resolve_rejected c7a620816abff9a1
block open_blocking 92067df7f9d4d4d9
Expand Down
3 changes: 2 additions & 1 deletion lua/claudecode/diff.lua
Original file line number Diff line number Diff line change
Expand Up @@ -813,7 +813,8 @@ function M._open_native_diff(old_file_path, new_file_path, new_file_contents, ta
vim.cmd("edit " .. vim.fn.fnameescape(old_file_path))
vim.cmd("diffthis")
create_split()
vim.cmd("edit " .. vim.fn.fnameescape(tmp_file))
-- Without a swap file, the rename below cannot meet another Neovim's swap file for "<path> (New)" (E325).
vim.cmd("noswapfile edit " .. vim.fn.fnameescape(tmp_file))
vim.api.nvim_buf_set_name(0, new_file_path .. " (New)")

-- Propagate filetype to the proposed buffer for proper syntax highlighting (#20)
Expand Down
66 changes: 66 additions & 0 deletions tests/integration/diff_legacy_swap_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
-- Real-Neovim check that the legacy diff.open_diff opens its proposal when another Neovim left a swap file for the
-- proposal's name ("<path> (New)"). Swap files need a real Neovim, so under busted's mock vim this is pending;
-- scripts/run_integration_tests_individually.sh runs it in Neovim.
if vim == nil or vim.fn.has("nvim") ~= 1 then
describe("legacy open_diff and a swap file for its proposal", function()
pending("needs a real Neovim")
end)
return
end

describe("legacy open_diff and a swap file for its proposal", function()
local diff = require("claudecode.diff")
local dir, swap_dir, path, saved_directory

before_each(function()
dir = vim.fn.tempname()
swap_dir = dir .. "/swap"
vim.fn.mkdir(swap_dir, "p")
path = dir .. "/foo.lua"
vim.fn.writefile({ "local a = 1" }, path)
saved_directory = vim.o.directory
vim.o.directory = swap_dir .. "//"
diff.setup({ diff_opts = {} })
end)

after_each(function()
vim.cmd("silent! diffoff!")
vim.cmd("silent! only")
vim.cmd("silent! %bwipeout!")
vim.o.directory = saved_directory
vim.fn.delete(dir, "rf")
end)

it("opens the proposal when a killed Neovim left a swap file for '<path> (New)'", function()
-- Another Neovim changes a buffer named "<path> (New)", so its swap file records that name, and is killed.
vim.fn.system({
vim.v.progpath,
"--headless",
"-u",
"NONE",
"-i",
"NONE",
"--cmd",
"set directory=" .. vim.fn.fnameescape(swap_dir) .. "//",
"-c",
"edit " .. vim.fn.fnameescape(path .. " (New)"),
"-c",
"call setline(1, 'unsaved')",
"-c",
"preserve",
"-c",
"lua (vim.uv or vim.loop).kill(vim.fn.getpid(), 9)",
})
assert.are.equal(1, #vim.fn.glob(swap_dir .. "/*", false, true), "the killed Neovim left its swap file")

vim.cmd("edit " .. vim.fn.fnameescape(path))
local ok, result = pcall(diff.open_diff, path, path, "local a = 2\n", "legacy swap")

assert.is_true(ok, tostring(result))
assert.is_true(result.success)
local proposal = vim.api.nvim_get_current_buf()
assert.are.equal(path .. " (New)", vim.api.nvim_buf_get_name(proposal))
assert.is_false(vim.bo[proposal].swapfile)
assert.are.equal("", vim.fn.swapname(proposal))
end)
end)
Loading