Treesitter-powered Diff Syntax highlighting for Neovim
Enhance Neovim's built-in diff mode (and much more!) with language-aware syntax highlighting driven by treesitter.
diffs.nvim-v0.2.0-preview.mp4
- Treesitter syntax highlighting in
vim-fugitive,
Neogit, builtin
difffiletype, and more! - Character-level intra-line diff highlighting (with optional vscode-diff FFI backend for word-level accuracy)
:Gdiffunified diff against any revision:Greviewfull-repo review diff with qflist/loclist navigation- Inline merge conflict detection, highlighting, and resolution
- gitsigns.nvim blame popup highlighting
- Email quoting/patch syntax support (
> diff ...) - Vim syntax fallback
- Configurable highlighiting blend & priorities
- Context-inclusive, high-accuracy highlights
- Neovim 0.9.0+
Install with your package manager of choice or via luarocks:
luarocks install diffs.nvim
:help diffs.nvimQ: How do I install with lazy.nvim?
{
'barrettruth/diffs.nvim',
init = function()
vim.g.diffs = {
...
}
end,
}Do not lazy load diffs.nvim with event, lazy, ft, config, or keys to
control loading - diffs.nvim lazy-loads itself.
Q: Does diffs.nvim support vim-fugitive/Neogit/neojj/gitsigns?
Yes. Enable integrations in your config:
vim.g.diffs = {
integrations = {
fugitive = true,
neogit = true,
neojj = true,
gitsigns = true,
}
}See the documentation for more information.
-
Incomplete syntax context: Treesitter parses each diff hunk in isolation. Context lines within the hunk provide syntactic context for the parser. In rare cases, hunks that start or end mid-expression may produce imperfect highlights due to treesitter error recovery.
-
Syntax "flashing":
diffs.nvimhooks into theFileType fugitiveevent triggered byvim-fugitive, at which point the buffer is preliminarily painted. The decoration provider applies highlights on the next redraw cycle, so a brief first-paint flash may still occur. -
Cold Start: Treesitter grammar loading (~10ms) and query compilation (~4ms) are one-time costs per language per Neovim session. Each language pays this cost on first encounter, which may cause a brief stutter when a diff containing a new language first enters the viewport.
-
Vim syntax fallback is deferred: The vim syntax fallback (for languages without a treesitter parser) cannot run inside the decoration provider's redraw cycle due to Neovim's restriction on buffer mutations. Vim syntax highlights for cold hunks may appear one frame later. Warm hunks can reuse cached vim syntax spans, and stale deferred renders are ignored after buffer changes.
-
Conflicting diff plugins:
diffs.nvimmay not interact well with other plugins that modify diff highlighting. Known plugins that may conflict:diffview.nvim- provides its own diff highlighting and conflict resolution UImini.diff- visualizes buffer differences with its own highlighting systemgitsigns.nvim- generally compatible, but both plugins modifying line highlights may produce unexpected resultsgit-conflict.nvim-diffs.nvimnow includes built-in conflict resolution; disable one or the other to avoid overlap
vim-fugitive- @esmuellert /
codediff.nvim- vscode-diff algorithm FFI backend for word-level intra-line accuracy diffview.nvimdifftasticmini.diffgitsigns.nvimgit-conflict.nvim- @phanen - diff header highlighting, unknown filetype fix, shebang/modeline detection, treesitter injection support, decoration provider highlighting architecture, gitsigns blame popup highlighting, intra-line bg visibility fix
- @tris203 - support for transparent backgrounds
- @letientai299 -
diff.mnemonicPrefixsupport