barrettruth/diffs.nvim

github github
git
stars 169
issues 1
subscribers 3
forks 4
CREATED

UPDATED


diffs.nvim

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.

Features

  • Treesitter syntax highlighting in vim-fugitive, Neogit, builtin diff filetype, and more!
  • Word and chatacer-level diff highlighting
  • :Diff for pierre-style unified, stacked, or split diffs against any revision
  • :Diff review full-repo review diff with qflist/loclist navigation
  • :Diff files {a} {b} to diff two arbitrary files
  • Inline and 3-way merge conflict detection, highlighting, and resolution
  • Email quoting/patch syntax support (> diff ...)
  • Vim syntax fallback
  • Difftastic highlight support
  • Configurable highlighting

Requirements

  • Neovim 0.9.0+
  • Optional: the Treesitter diff parser for the best experience

Installation

With vim.pack (Neovim 0.12+):

vim.pack.add({
  'https://github.com/barrettruth/diffs.nvim',
})

Or via luarocks:

luarocks install diffs.nvim

Documentation

:help diffs.nvim

FAQ

Q: Does diffs.nvim support vim-fugitive/Neogit/neojj/gitsigns/fzf-lua?

Yes. Enable integrations in your config:

vim.g.diffs = {
  integrations = {
    fugitive = true,
    neogit = true,
    neojj = true,
    gitsigns = true,
  }
}

fzf-lua is supported out-of-the-box.

See the documentation for more information.

Q: Can I use diffs.nvim as a Git mergetool?

Yes. Configure Git to open $MERGED with Neovim; diffs.nvim will detect conflict markers automatically. See :help diffs.nvim-git-mergetool.

Q: Can I exclude untracked files from :Diff review?

Yes. Run :Diff review ++nountracked. To make it the default, wrap it in your own command, e.g. :command! Review Diff review ++nountracked.

Known Limitations

  • Incomplete syntax context: Treesitter parses each diff hunk in isolation. Context lines within the hunk provide syntactic context for the parser. With or without context, hunks that start or end mid-expression may produce imperfect highlights due to treesitter error recovery.

  • Syntax "flashing": diffs.nvim hooks into the FileType fugitive event triggered by vim-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.nvim may 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 UI
    • mini.diff - visualizes buffer differences with its own highlighting system
    • gitsigns.nvim - generally compatible, but both plugins modifying line highlights may produce unexpected results
    • git-conflict.nvim - diffs.nvim now includes built-in conflict resolution; disable one or the other to avoid overlap

Acknowledgements