mirror of
https://github.com/neovim/neovim.git
synced 2026-06-15 16:23:48 +00:00
Problem:
Using the `DiffTool` plugin (e.g. through `nvim -d ...` or `:DiffTool
<file1> <file2>` fails if a space is in one of the paths. This occurs
because the `diff` wraps the paths with quotes (`'`) if space
characters are present, which the line diff regex fails to parse.
Solution:
Update regex to handle quoted paths by matching the string within the
quotes, if it exists.
(cherry picked from commit 1e09b020e5)
156 lines
5.0 KiB
Lua
156 lines
5.0 KiB
Lua
local t = require('test.testutil')
|
|
local n = require('test.functional.testnvim')()
|
|
|
|
local clear = n.clear
|
|
local command = n.command
|
|
local eq = t.eq
|
|
local fn = n.fn
|
|
|
|
local pathsep = n.get_pathsep()
|
|
local testdir_left = 'Xtest-difftool-left'
|
|
local testdir_right = 'Xtest-difftool-right'
|
|
|
|
setup(function()
|
|
n.mkdir_p(testdir_left)
|
|
n.mkdir_p(testdir_right)
|
|
t.write_file(testdir_left .. pathsep .. 'file1.txt', 'hello')
|
|
t.write_file(testdir_left .. pathsep .. 'file2.txt', 'foo')
|
|
t.write_file(testdir_left .. pathsep .. 'file4 with space.txt', 'hello')
|
|
t.write_file(testdir_right .. pathsep .. 'file1.txt', 'hello world') -- modified
|
|
t.write_file(testdir_right .. pathsep .. 'file3.txt', 'bar') -- added
|
|
t.write_file(testdir_right .. pathsep .. 'file4 with space.txt', 'hello world') -- modified
|
|
end)
|
|
|
|
teardown(function()
|
|
n.rmdir(testdir_left)
|
|
n.rmdir(testdir_right)
|
|
end)
|
|
|
|
describe('nvim.difftool', function()
|
|
before_each(function()
|
|
clear()
|
|
command('packadd nvim.difftool')
|
|
end)
|
|
|
|
it('shows added, modified, and deleted files in quickfix', function()
|
|
command(('DiffTool %s %s'):format(testdir_left, testdir_right))
|
|
local qflist = fn.getqflist()
|
|
local entries = {}
|
|
for _, item in ipairs(qflist) do
|
|
table.insert(entries, { text = item.text, rel = item.user_data and item.user_data.rel })
|
|
end
|
|
|
|
-- Should show:
|
|
-- file1.txt as modified (M)
|
|
-- file2.txt as deleted (D)
|
|
-- file3.txt as added (A)
|
|
-- file4 with space.txt as modified (M)
|
|
eq({
|
|
{ text = 'M', rel = 'file1.txt' },
|
|
{ text = 'D', rel = 'file2.txt' },
|
|
{ text = 'A', rel = 'file3.txt' },
|
|
{ text = 'M', rel = 'file4 with space.txt' },
|
|
}, entries)
|
|
end)
|
|
|
|
it('has consistent split layout', function()
|
|
command('set nosplitright')
|
|
command(('DiffTool %s %s'):format(testdir_left, testdir_right))
|
|
local wins = fn.getwininfo()
|
|
local left_win_col = wins[1].wincol
|
|
local right_win_col = wins[2].wincol
|
|
assert(
|
|
left_win_col < right_win_col,
|
|
'Left window should be to the left of right window even with nosplitright set'
|
|
)
|
|
end)
|
|
|
|
it('handles symlinks', function()
|
|
-- Create a symlink in right dir pointing to file2.txt in left dir
|
|
local symlink_path = vim.fs.joinpath(testdir_right, 'file2.txt')
|
|
local target_path = vim.fs.joinpath('..', testdir_left, 'file2.txt')
|
|
assert(vim.uv.fs_symlink(target_path, symlink_path) == true)
|
|
finally(function()
|
|
os.remove(symlink_path)
|
|
end)
|
|
assert(fn.getftype(symlink_path) == 'link')
|
|
|
|
-- Run difftool
|
|
command(('DiffTool %s %s'):format(testdir_left, testdir_right))
|
|
local qflist = fn.getqflist()
|
|
local entries = {}
|
|
for _, item in ipairs(qflist) do
|
|
table.insert(entries, { text = item.text, rel = item.user_data and item.user_data.rel })
|
|
end
|
|
|
|
-- file2.txt should not be reported as added or deleted anymore
|
|
eq({
|
|
{ text = 'M', rel = 'file1.txt' },
|
|
{ text = 'A', rel = 'file3.txt' },
|
|
{ text = 'M', rel = 'file4 with space.txt' },
|
|
}, entries)
|
|
end)
|
|
|
|
it('has autocmds when diff window is opened', function()
|
|
command(('DiffTool %s %s'):format(testdir_left, testdir_right))
|
|
local autocmds = fn.nvim_get_autocmds({ group = 'nvim.difftool.events' })
|
|
assert(#autocmds > 0)
|
|
end)
|
|
|
|
it('cleans up autocmds when diff window is closed', function()
|
|
command(('DiffTool %s %s'):format(testdir_left, testdir_right))
|
|
command('q')
|
|
local ok = pcall(fn.nvim_get_autocmds, { group = 'nvim.difftool.events' })
|
|
eq(false, ok)
|
|
end)
|
|
|
|
it('does not reset quickfix list when closing quickfix window', function()
|
|
command(('DiffTool %s %s'):format(testdir_left, testdir_right))
|
|
local qflist_before = fn.getqflist()
|
|
assert(#qflist_before > 0, 'quickfix list should not be empty')
|
|
|
|
-- Close the quickfix window
|
|
command('cclose')
|
|
|
|
-- Quickfix list should still be intact
|
|
local qflist_after = fn.getqflist()
|
|
eq(#qflist_before, #qflist_after)
|
|
|
|
-- Autocmds should still be active
|
|
local autocmds = fn.nvim_get_autocmds({ group = 'nvim.difftool.events' })
|
|
assert(#autocmds > 0, 'autocmds should still exist after closing quickfix window')
|
|
end)
|
|
|
|
it('opens difftool automatically when started with nvim -d', function()
|
|
-- Start Neovim with -d flag for directory diff
|
|
clear({
|
|
args = {
|
|
'--cmd',
|
|
'packadd nvim.difftool',
|
|
'-d',
|
|
testdir_left,
|
|
testdir_right,
|
|
},
|
|
})
|
|
|
|
-- Wait for difftool to open
|
|
n.poke_eventloop()
|
|
|
|
-- Verify we have 3 windows (left, right, and quickfix)
|
|
eq(3, #fn.getwininfo())
|
|
|
|
-- Verify quickfix list has the expected entries
|
|
local qflist = fn.getqflist()
|
|
local entries = {}
|
|
for _, item in ipairs(qflist) do
|
|
table.insert(entries, { text = item.text, rel = item.user_data and item.user_data.rel })
|
|
end
|
|
eq({
|
|
{ text = 'M', rel = 'file1.txt' },
|
|
{ text = 'D', rel = 'file2.txt' },
|
|
{ text = 'A', rel = 'file3.txt' },
|
|
{ text = 'M', rel = 'file4 with space.txt' },
|
|
}, entries)
|
|
end)
|
|
end)
|