feat(plugins): nvim.difftool can compare directories #35448

Problem:
Built-in diff mode (nvim -d) does not support directory diffing
as required by git difftool -d. This makes it difficult to compare
entire directories, detect renames, and navigate changes efficiently.

Solution:
Add a DiffTool plugin and command that enables side-by-side diffing of
files and directories in Neovim. The plugin supports rename detection,
highlights changes in the quickfix list, and provides a user command for
easy invocation. This allows proper integration with git difftool -d for
directory comparison.

Example git config:

```ini
[diff]
    tool = nvim_difftool

[difftool "nvim_difftool"]
    cmd = nvim -c "packadd nvim.difftool" -c "DiffTool $LOCAL $REMOTE"
```

Signed-off-by: Tomas Slusny <slusnucky@gmail.com>
Co-authored-by: Phạm Bình An <111893501+brianhuster@users.noreply.github.com>
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
This commit is contained in:
Tomas Slusny
2025-10-12 04:24:39 +02:00
committed by GitHub
parent bc2fe135d1
commit fec02ae8e4
7 changed files with 650 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
local M = {}
--- Edit a file in a specific window
--- @param winnr number
--- @param file string
--- @return number buffer number of the edited buffer
M.edit_in = function(winnr, file)
return vim.api.nvim_win_call(winnr, function()
local current = vim.fs.abspath(vim.api.nvim_buf_get_name(vim.api.nvim_win_get_buf(winnr)))
-- Check if the current buffer is already the target file
if current == (file and vim.fs.abspath(file) or '') then
return vim.api.nvim_get_current_buf()
end
-- Read the file into the buffer
vim.cmd.edit(vim.fn.fnameescape(file))
return vim.api.nvim_get_current_buf()
end)
end
--- Read a chunk of data from a file
--- @param file string
--- @param size number
--- @return string? chunk or nil on error
function M.read_chunk(file, size)
local fd = io.open(file, 'rb')
if not fd then
return nil
end
local chunk = fd:read(size)
fd:close()
return tostring(chunk)
end
return M