*diffs.nvim.txt* Syntax highlighting for diffs in Neovim Author: Barrett Ruth License: MIT ============================================================================== INTRODUCTION *diffs.nvim* diffs.nvim adds language-aware syntax highlighting to unified diff content in Neovim buffers. It replaces flat `diffAdded`/`diffRemoved` coloring with treesitter syntax, blended line backgrounds, and character-level intra-line diffs. With no configuration, diffs.nvim provides: - `gitcommit` diff highlighting (e.g., `git commit --verbose`) - Inline merge conflict detection, highlighting, and resolution - Background-only diff colors for `&diff` buffers (vimdiff, diffthis) All other integrations are opt-in. See |diffs-integrations|. Features: ~ - Treesitter syntax highlighting in diff hunks - Character-level intra-line diff highlighting - Vim syntax fallback for languages without a treesitter parser - Blended diff background colors that preserve syntax visibility - Optional diff prefix (`+`/`-`/` `) concealment - Gutter (line number) highlighting - |:Gdiff| unified diff against any revision - Email quoting/patch syntax support (`> diff ...`) ============================================================================== CONTENTS *diffs-contents* 1. Introduction ............................................... |diffs.nvim| 2. Requirements ....................................... |diffs-requirements| 3. Setup ..................................................... |diffs-setup| 4. Configuration ............................................ |diffs-config| 5. Commands ............................................... |diffs-commands| 6. Mappings ............................................... |diffs-mappings| 7. Integrations ..................................... |diffs-integrations| Fugitive .......................................... |diffs-fugitive| Neogit .............................................. |diffs-neogit| Gitsigns .......................................... |diffs-gitsigns| Telescope ........................................ |diffs-telescope| 8. Conflict Resolution .................................... |diffs-conflict| 9. Merge Diff Resolution ..................................... |diffs-merge| 10. API ......................................................... |diffs-api| 11. Implementation ................................... |diffs-implementation| 12. Known Limitations ................................... |diffs-limitations| 13. Highlight Groups ..................................... |diffs-highlights| 14. Health Check ............................................. |diffs-health| 15. Acknowledgements ............................... |diffs-acknowledgements| ============================================================================== REQUIREMENTS *diffs-requirements* - Neovim 0.9.0+ - Treesitter parsers for languages you want highlighted ============================================================================== SETUP *diffs-setup* Install with lazy.nvim: >lua { 'barrettruth/diffs.nvim' } < Do not lazy load with `event`, `lazy`, `ft`, `config`, or `keys` — diffs.nvim lazy-loads itself. NOTE: Load your colorscheme before diffs.nvim. With lazy.nvim, set `priority = 1000` and `lazy = false` on your colorscheme plugin. See |diffs-config| for customization, |diffs-integrations| for plugin support. ============================================================================== CONFIGURATION *diffs-config* Configuration is done via `vim.g.diffs`. Set this before the plugin loads: >lua vim.g.diffs = { debug = false, hide_prefix = false, integrations = { fugitive = false, neogit = false, gitsigns = false, committia = false, telescope = false, }, extra_filetypes = {}, highlights = { background = true, gutter = true, blend_alpha = 0.6, context = { enabled = true, lines = 25, }, treesitter = { enabled = true, max_lines = 500, }, vim = { enabled = true, max_lines = 200, }, intra = { enabled = true, algorithm = 'default', max_lines = 500, }, priorities = { clear = 198, syntax = 199, line_bg = 200, char_bg = 201, }, overrides = {}, }, conflict = { enabled = true, disable_diagnostics = true, show_virtual_text = true, show_actions = false, keymaps = { ours = 'doo', theirs = 'dot', both = 'dob', none = 'don', next = ']c', prev = '[c', }, }, } < *diffs.Config* Fields: ~ {debug} (boolean, default: false) Enable debug logging to |:messages| with `[diffs]` prefix. {hide_prefix} (boolean, default: false) Hide diff prefixes (`+`/`-`/` `) using virtual text overlay. Makes code appear without the leading diff character. When `highlights.background` is also enabled, the overlay inherits the line's background color. {integrations} (table, default: all false) Integration toggles. Each key accepts `true`, `false`, or a table with sub-options. Passing `true` or a table enables the integration; `false` disables it. See |diffs-integrations|. *diffs.IntegrationsConfig* Fields: ~ {fugitive} (boolean|table, default: false) Enable vim-fugitive integration. Pass `true` for defaults, or a table with sub-options (see |diffs.FugitiveConfig|). When active, the `fugitive` filetype is registered and status buffer keymaps are set. >lua vim.g.diffs = { integrations = { fugitive = true }, } vim.g.diffs = { integrations = { fugitive = { horizontal = 'dd' }, }, } < {neogit} (boolean|table, default: false) Enable Neogit integration. When active, `NeogitStatus`, `NeogitCommitView`, and `NeogitDiffView` filetypes are registered. See |diffs-neogit|. >lua integrations = { neogit = true } < {gitsigns} (boolean|table, default: false) Enable gitsigns.nvim blame popup highlighting. See |diffs-gitsigns|. >lua integrations = { gitsigns = true } < {committia} (boolean|table, default: false) Enable committia.vim integration. When active, committia's diff pane receives treesitter syntax and intra-line diffs. >lua integrations = { committia = true } < {telescope} (boolean|table, default: false) Enable telescope.nvim preview highlighting. See |diffs-telescope|. >lua integrations = { telescope = true } < Legacy top-level keys (`vim.g.diffs.fugitive`, etc.) still work but emit a deprecation warning. If both `integrations` and top-level keys are present, `integrations` wins and the stale keys are ignored with a warning. {extra_filetypes} (table, default: {}) Additional filetypes to attach to, beyond the built-in `git`, `gitcommit`, and any enabled integration filetypes. Use this to enable highlighting in plain `.diff` / `.patch` files: >lua vim.g.diffs = { extra_filetypes = { 'diff' }, } < Adding `'diff'` also enables highlighting in picker preview buffers that set `filetype=diff`: telescope.nvim (git_commits, git_bcommits, git_status), snacks.nvim (syntax style only), and fzf-lua (builtin previewer only). Terminal- based previewers are not supported. {highlights} (table, default: see below) Controls which highlight features are enabled. See |diffs.Highlights| for fields. {conflict} (table, default: see below) Inline merge conflict resolution options. See |diffs.ConflictConfig| for fields. *diffs.Highlights* Highlights table fields: ~ {background} (boolean, default: true) Apply background highlighting to `+`/`-` lines using `DiffsAdd`/`DiffsDelete` groups (derived from `DiffAdd`/`DiffDelete` backgrounds). {gutter} (boolean, default: true) Highlight line numbers with matching colors. Only visible if line numbers are enabled. {blend_alpha} (number, default: 0.6) Alpha value for character-level blend intensity. Controls how strongly changed characters stand out from the line-level background. Must be between 0 and 1 (inclusive). Higher values produce more vivid character-level highlights. {context} (table, default: see below) Syntax parsing context options. See |diffs.ContextConfig| for fields. {treesitter} (table, default: see below) Treesitter highlighting options. See |diffs.TreesitterConfig| for fields. {vim} (table, default: see below) Vim syntax fallback highlighting options. See |diffs.VimConfig| for fields. {intra} (table, default: see below) Character-level (intra-line) diff highlighting. See |diffs.IntraConfig| for fields. {priorities} (table, default: see below) Extmark priority values. See |diffs.PrioritiesConfig| for fields. {overrides} (table, default: {}) Map of highlight group names to highlight definitions (see |nvim_set_hl()|). Applied after all computed groups without `default`, so overrides always win over both computed defaults and colorscheme definitions. *diffs.ContextConfig* Context config fields: ~ {enabled} (boolean, default: true) Read surrounding code from the working tree file and feed it into the treesitter string parser. Uses the hunk's `@@ +start,count @@` line numbers to read lines before and after the hunk from disk. Improves syntax accuracy when the hunk is inside an incomplete construct (e.g., a table literal or function body whose opening is not visible in the hunk's own context lines). {lines} (integer, default: 25) Max context lines to read in each direction. Files are read once per parse and cached across hunks in the same file. *diffs.PrioritiesConfig* Priorities config fields: ~ {clear} (integer, default: 198) Priority for `DiffsClear` extmarks that reset underlying diff foreground colors. Must be below {syntax}. {syntax} (integer, default: 199) Priority for treesitter and vim syntax extmarks. Must be below {line_bg} so that colorscheme backgrounds on syntax groups do not obscure line-level diff backgrounds. {line_bg} (integer, default: 200) Priority for `DiffsAdd`/`DiffsDelete` line background extmarks. Must be below {char_bg}. {char_bg} (integer, default: 201) Priority for `DiffsAddText`/`DiffsDeleteText` character-level background extmarks. Highest priority so changed characters stand out. *diffs.TreesitterConfig* Treesitter config fields: ~ {enabled} (boolean, default: true) Apply treesitter syntax highlighting to code. {max_lines} (integer, default: 500) Skip treesitter highlighting for hunks larger than this many lines. Prevents lag on massive diffs. *diffs.VimConfig* Vim config fields: ~ {enabled} (boolean, default: true) Use vim syntax highlighting as fallback when no treesitter parser is available for a language. Creates a scratch buffer, sets the filetype, and queries |synID()| per character to extract highlight groups. Deferred via |vim.schedule()| so it never blocks the first paint. Slower than treesitter but covers languages without a TS parser installed (e.g., COBOL, Fortran). {max_lines} (integer, default: 200) Skip vim syntax highlighting for hunks larger than this many lines. Lower than the treesitter default due to the per-character cost of |synID()|. *diffs.IntraConfig* Intra config fields: ~ {enabled} (boolean, default: true) Enable character-level diff highlighting within changed lines. When a line changes from `local x = 1` to `local x = 2`, only the `1`/`2` characters get an intense background overlay while the rest of the line keeps the softer line-level background. {algorithm} (string, default: 'default') Diff algorithm for character-level analysis. `'default'`: use |vim.diff()| with settings inherited from |'diffopt'| (`algorithm` and `linematch`). `'vscode'`: use libvscodediff FFI (falls back to default if not available). {max_lines} (integer, default: 500) Skip character-level highlighting for hunks larger than this many lines. Note: Header context (e.g., `@@ -10,3 +10,4 @@ func()`) is always highlighted with treesitter when a parser is available. Language detection uses Neovim's built-in |vim.filetype.match()| and |vim.treesitter.language.get_lang()|. To customize filetype detection or register treesitter parsers for custom filetypes, use |vim.filetype.add()| and |vim.treesitter.language.register()|. ============================================================================== COMMANDS *diffs-commands* :Gdiff [revision] *:Gdiff* Open a unified diff of the current file against a git revision. Displays in a horizontal split below the current window. The diff buffer shows `+`/`-` lines with full syntax highlighting for the code language, plus diff header highlighting for `diff --git`, `---`, `+++`, and `@@` lines. If a `diffs://` window already exists in the current tabpage, the new diff replaces its buffer instead of creating another split. Parameters: ~ {revision} (string, optional) Git revision to diff against. Defaults to HEAD. Examples: >vim :Gdiff " diff against HEAD :Gdiff main " diff against main branch :Gdiff HEAD~3 " diff against 3 commits ago :Gdiff abc123 " diff against specific commit < :Gvdiff [revision] *:Gvdiff* Like |:Gdiff| but opens in a vertical split. :Ghdiff [revision] *:Ghdiff* Like |:Gdiff| but explicitly opens in a horizontal split. ============================================================================== MAPPINGS *diffs-mappings* *(diffs-gdiff)* (diffs-gdiff) Show unified diff against HEAD in a horizontal split. Equivalent to |:Gdiff| with no arguments. *(diffs-gvdiff)* (diffs-gvdiff) Show unified diff against HEAD in a vertical split. Equivalent to |:Gvdiff| with no arguments. Example configuration: >lua vim.keymap.set('n', 'gd', '(diffs-gdiff)') vim.keymap.set('n', 'gD', '(diffs-gvdiff)') < *(diffs-conflict-ours)* (diffs-conflict-ours) Accept current (ours) change. Replaces the conflict block with ours content. *(diffs-conflict-theirs)* (diffs-conflict-theirs) Accept incoming (theirs) change. Replaces the conflict block with theirs content. *(diffs-conflict-both)* (diffs-conflict-both) Accept both changes (ours then theirs). *(diffs-conflict-none)* (diffs-conflict-none) Reject both changes (delete entire block). *(diffs-conflict-next)* (diffs-conflict-next) Jump to next conflict marker. Wraps around. *(diffs-conflict-prev)* (diffs-conflict-prev) Jump to previous conflict marker. Wraps around. Example configuration: >lua vim.keymap.set('n', 'co', '(diffs-conflict-ours)') vim.keymap.set('n', 'ct', '(diffs-conflict-theirs)') vim.keymap.set('n', 'cb', '(diffs-conflict-both)') vim.keymap.set('n', 'cn', '(diffs-conflict-none)') vim.keymap.set('n', ']c', '(diffs-conflict-next)') vim.keymap.set('n', '[c', '(diffs-conflict-prev)') < *(diffs-merge-ours)* (diffs-merge-ours) Accept ours in a merge diff view. Resolves the conflict in the working file with ours content. *(diffs-merge-theirs)* (diffs-merge-theirs) Accept theirs in a merge diff view. *(diffs-merge-both)* (diffs-merge-both) Accept both (ours then theirs) in a merge diff view. *(diffs-merge-none)* (diffs-merge-none) Reject both in a merge diff view. *(diffs-merge-next)* (diffs-merge-next) Jump to next unresolved conflict hunk in merge diff. *(diffs-merge-prev)* (diffs-merge-prev) Jump to previous unresolved conflict hunk in merge diff. Diff buffer mappings: ~ *diffs-q* q Close the diff window. Available in all `diffs://` buffers created by |:Gdiff|, |:Gvdiff|, |:Ghdiff|, or the fugitive status keymaps. ============================================================================== INTEGRATIONS *diffs-integrations* diffs.nvim integrates with several plugins. There are two attachment patterns: Automatic: ~ Enable via config toggles. The plugin registers `FileType` autocmds for each integration's filetypes and attaches automatically. >lua vim.g.diffs = { integrations = { fugitive = true, neogit = true, gitsigns = true, }, } < Opt-in: ~ For filetypes not covered by a built-in integration, use `extra_filetypes` to attach to any buffer whose content looks like a diff. >lua vim.g.diffs = { extra_filetypes = { 'diff' } } < ------------------------------------------------------------------------------ FUGITIVE *diffs-fugitive* Enable vim-fugitive (https://github.com/tpope/vim-fugitive) support: >lua vim.g.diffs = { integrations = { fugitive = true } } < |:Git| status and commit views receive treesitter syntax, line backgrounds, and intra-line diffs. |:Gdiff| opens a unified diff against any revision (see |diffs-commands|). Fugitive status keymaps: ~ When inside a |:Git| status buffer, diffs.nvim provides keymaps to open unified diffs for files or entire sections. Keymaps: ~ *diffs-du* *diffs-dU* du Open unified diff in a horizontal split. dU Open unified diff in a vertical split. These keymaps work on: - File lines (e.g., `M src/foo.lua`) - opens diff for that file - Section headers (e.g., `Staged (3)`) - opens diff for all files in section - Hunk/context lines below a file - opens diff for the parent file Behavior by file status: ~ Status Section Base Current Result ~ M Unstaged index working tree unstaged changes M Staged HEAD index staged changes A Staged (empty) index file as all-added D Staged HEAD (empty) file as all-removed R Staged HEAD:oldname index:newname content diff U Unstaged :2: (ours) :3: (theirs) merge diff ? Untracked (empty) working tree file as all-added On section headers, the keymap runs `git diff` (or `git diff --cached` for staged) and displays all changes in that section as a single unified diff. Untracked section headers show a warning since there is no meaningful diff. Configuration: ~ *diffs.FugitiveConfig* >lua vim.g.diffs = { integrations = { fugitive = { horizontal = 'du', -- keymap for horizontal split, false to disable vertical = 'dU', -- keymap for vertical split, false to disable }, }, } < Passing a table enables fugitive integration. Use `fugitive = false` to disable. There is no `enabled` field; table presence is sufficient. Fields: ~ {horizontal} (string|false, default: 'du') Keymap for unified diff in horizontal split. Set to `false` to disable. {vertical} (string|false, default: 'dU') Keymap for unified diff in vertical split. Set to `false` to disable. ------------------------------------------------------------------------------ NEOGIT *diffs-neogit* Enable Neogit (https://github.com/NeogitOrg/neogit) support: >lua vim.g.diffs = { integrations = { neogit = true } } < Expanding a diff in a Neogit buffer (e.g., TAB on a file in the status view) applies treesitter syntax highlighting and intra-line diffs to the hunk lines. ------------------------------------------------------------------------------ GITSIGNS *diffs-gitsigns* Enable gitsigns.nvim (https://github.com/lewis6991/gitsigns.nvim) blame popup highlighting: >lua vim.g.diffs = { integrations = { gitsigns = true } } < `:Gitsigns blame_line full=true` popups receive treesitter syntax, line backgrounds, and intra-line diffs. Highlights are applied in a separate `diffs-gitsigns` namespace and do not interfere with the main decoration provider used for diff buffers. ------------------------------------------------------------------------------ TELESCOPE *diffs-telescope* Enable telescope.nvim (https://github.com/nvim-telescope/telescope.nvim) preview highlighting: >lua vim.g.diffs = { integrations = { telescope = true } } < Telescope does not set `filetype=diff` on preview buffers — it calls `vim.treesitter.start(bufnr, "diff")` directly, so diffs.nvim's `FileType` autocmd never fires. This integration listens for the `User TelescopePreviewerLoaded` event and attaches to the preview buffer. Pickers that show diff content (e.g. `git_bcommits`, `git_status`) will receive treesitter syntax, line backgrounds, and intra-line diffs in the preview pane. Known issue: Telescope's previewer may render the first line of the preview buffer with a black background regardless of colorscheme. This is a Telescope artifact unrelated to diffs.nvim. Tracked upstream: https://github.com/nvim-telescope/telescope.nvim/issues/3626 ============================================================================== CONFLICT RESOLUTION *diffs-conflict* diffs.nvim detects inline merge conflict markers (`<<<<<<<`/`=======`/ `>>>>>>>`) in working files and provides highlighting and resolution keymaps. Both standard and diff3 (`|||||||`) formats are supported. Conflict regions are detected automatically on `BufReadPost` and re-scanned on `TextChanged`. When all conflicts in a buffer are resolved, highlighting is removed and diagnostics are re-enabled. Configuration: ~ *diffs.ConflictConfig* >lua vim.g.diffs = { conflict = { enabled = true, disable_diagnostics = true, show_virtual_text = true, show_actions = false, priority = 200, keymaps = { ours = 'doo', theirs = 'dot', both = 'dob', none = 'don', next = ']c', prev = '[c', }, }, } < Fields: ~ {enabled} (boolean, default: true) Enable conflict marker detection and resolution. Set to `false` to disable entirely. {disable_diagnostics} (boolean, default: true) Suppress LSP diagnostics on buffers with conflict markers. Markers produce syntax errors that clutter the diagnostic list. Diagnostics are re-enabled when all conflicts are resolved. Set `false` to leave diagnostics alone. {show_virtual_text} (boolean, default: true) Show `(current)` and `(incoming)` labels at the end of `<<<<<<<` and `>>>>>>>` marker lines. Also controls hunk hints in merge diff views. {format_virtual_text} (function|nil, default: nil) Custom formatter for virtual text labels. Receives `(side, keymap)` where `side` is `"ours"` or `"theirs"` and `keymap` is the configured keymap string or `false`. Return a string (label text without parens) or `nil` to hide the label. Example: >lua format_virtual_text = function(side, keymap) if keymap then return side .. ' [' .. keymap .. ']' end return side end < {show_actions} (boolean, default: false) Show a codelens-style action line above each `<<<<<<<` marker listing available resolution keymaps. Renders as virtual lines using the `DiffsConflictActions` highlight group. Only keymaps that are not `false` appear. {priority} (integer, default: 200) Extmark priority for conflict region backgrounds and markers. Adjust if other plugins use the same priority range. {keymaps} (table, default: see above) Buffer-local keymaps for conflict resolution and navigation. Each value accepts a string (custom key) or `false` (disabled). *diffs.ConflictKeymaps* Keymap fields: ~ {ours} (string|false, default: 'doo') Accept current (ours) change. {theirs} (string|false, default: 'dot') Accept incoming (theirs) change. {both} (string|false, default: 'dob') Accept both changes (ours then theirs). {none} (string|false, default: 'don') Reject both changes (delete entire block). {next} (string|false, default: ']c') Jump to next conflict marker. Wraps around. {prev} (string|false, default: '[c') Jump to previous conflict marker. Wraps around. User events: ~ *DiffsConflictResolved* DiffsConflictResolved Fired when the last conflict in a buffer is resolved. Useful for triggering custom actions (e.g., auto-staging the file). >lua vim.api.nvim_create_autocmd('User', { pattern = 'DiffsConflictResolved', callback = function() print('all conflicts resolved!') end, }) < ============================================================================== MERGE DIFF RESOLUTION *diffs-merge* When pressing `du`/`dU` on an unmerged (`U`) file in the fugitive status buffer, diffs.nvim opens a unified diff of ours (`git show :2:path`) vs theirs (`git show :3:path`) with full treesitter and intra-line highlighting. The same conflict resolution keymaps (`doo`/`dot`/`dob`/`don`/`]c`/`[c`) are available on the diff buffer. They resolve conflicts in the working file by matching diff hunks to conflict markers: - `doo` replaces the conflict region with ours content - `dot` replaces the conflict region with theirs content - `dob` replaces with both (ours then theirs) - `don` removes the conflict region entirely - `]c`/`[c` navigate between unresolved conflict hunks Resolved hunks are marked with `(resolved)` virtual text. Hunks that correspond to auto-merged content (no conflict markers) show an informational notification and are left unchanged. The working file buffer is modified in place; save it when ready. Phase 1 inline conflict highlights (see |diffs-conflict|) are refreshed automatically after each resolution. ============================================================================== API *diffs-api* attach({bufnr}) *diffs.attach()* Manually attach highlighting to a buffer. Called automatically for fugitive buffers via the `FileType fugitive` autocmd. Parameters: ~ {bufnr} (integer, optional) Buffer number. Defaults to current buffer. refresh({bufnr}) *diffs.refresh()* Manually refresh highlighting for a buffer. Useful after external changes or for debugging. Parameters: ~ {bufnr} (integer, optional) Buffer number. Defaults to current buffer. ============================================================================== IMPLEMENTATION *diffs-implementation* Summary / commit detail views: ~ 1. `FileType` autocmd for computed filetypes (see |diffs-config|) triggers |diffs.attach()|. For `git` buffers, only `fugitive://` URIs are attached. 2. The buffer is parsed to detect file headers (`M path/to/file`, `diff --git a/... b/...`) and hunk headers (`@@ -10,3 +10,4 @@`) 3. For each hunk: - Language is detected from the filename using |vim.filetype.match()| - Diff prefixes (`+`/`-`/` `) are stripped from code lines - Code is parsed with |vim.treesitter.get_string_parser()| - If no treesitter parser and `vim.enabled`: vim syntax fallback via scratch buffer and |synID()| - `DiffsClear` extmarks at priority 198 clear underlying diff foreground - Syntax highlights are applied as extmarks at priority 199 - Background extmarks (`DiffsAdd`/`DiffsDelete`) at priority 200 - Character-level diff extmarks (`DiffsAddText`/`DiffsDeleteText`) at priority 201 overlay changed characters with an intense background - Conceal extmarks hide diff prefixes when `hide_prefix` is enabled - All priorities are configurable via |diffs.PrioritiesConfig| 4. A decoration provider re-highlights visible hunks on each redraw Diff mode views: ~ 1. `OptionSet diff` detects when any window enters diff mode 2. All `&diff` windows in the tabpage receive a window-local 'winhighlight' override that remaps `DiffAdd`/`DiffDelete`/`DiffChange`/`DiffText` to background-only variants, allowing existing treesitter highlighting to show through the diff colors ============================================================================== KNOWN LIMITATIONS *diffs-limitations* Incomplete Syntax Context ~ *diffs-syntax-context* Treesitter parses each diff hunk in isolation. When `highlights.context` is enabled (the default), surrounding code is read from the working tree file and fed into the parser to improve accuracy at hunk boundaries. This helps when a hunk is inside a table, function body, or loop whose opening is beyond the hunk's own context lines. Requires `repo_root` and `file_new_start` to be available on the hunk (true for standard unified diffs). In rare cases, hunks that start or end mid-expression may still produce imperfect highlights due to treesitter error recovery. Syntax Highlighting Flash ~ *diffs-flash* When opening a fugitive buffer, there is an unavoidable visual "flash" where the buffer briefly shows fugitive's default diff highlighting before diffs.nvim applies treesitter highlights. This occurs because diffs.nvim hooks into the `FileType fugitive` event, which fires after vim-fugitive has already painted the buffer. The decoration provider applies highlights on the next redraw cycle. Conflicting Diff Plugins ~ *diffs-plugin-conflicts* diffs.nvim may not interact well with other plugins that modify diff highlighting or the sign column in diff views. Known plugins that may conflict: - diffview.nvim (sindrets/diffview.nvim) Provides its own diff highlighting and conflict resolution UI. When using diffview.nvim for viewing diffs, you may want to disable diffs.nvim's diff mode attachment or use one plugin exclusively. - mini.diff (echasnovski/mini.diff) Visualizes buffer differences with its own highlighting system. May override or conflict with diffs.nvim's background highlighting. - gitsigns.nvim (lewis6991/gitsigns.nvim) Generally compatible for sign column decorations, but both plugins modifying line highlights may produce unexpected results. - git-conflict.nvim (akinsho/git-conflict.nvim) Provides conflict marker highlighting and resolution keymaps. diffs.nvim now has built-in conflict resolution (see |diffs-conflict|). Disable one or the other to avoid overlap. If you experience visual conflicts, try disabling the conflicting plugin's diff-related features. ============================================================================== HIGHLIGHT GROUPS *diffs-highlights* diffs.nvim defines custom highlight groups. All groups use `default = true`, so colorschemes can override them by defining the group before the plugin loads. All derived groups are computed by alpha-blending a source color into the `Normal` background. Line-level groups blend at 40% alpha for a subtle tint; character-level groups blend at 60% for more contrast. Line-number groups combine both: background from the line-level blend, foreground from the character-level blend. Fugitive unified diff highlights: ~ *DiffsAdd* DiffsAdd Background for `+` lines. Derived by blending `DiffAdd` background with `Normal` at 40% alpha. *DiffsDelete* DiffsDelete Background for `-` lines. Derived by blending `DiffDelete` background with `Normal` at 40% alpha. *DiffsAddNr* DiffsAddNr Line number for `+` lines. Foreground from `DiffsAddText`, background from `DiffsAdd`. *DiffsDeleteNr* DiffsDeleteNr Line number for `-` lines. Foreground from `DiffsDeleteText`, background from `DiffsDelete`. *DiffsAddText* DiffsAddText Character-level background for changed characters within `+` lines. Derived by blending `diffAdded` foreground with `Normal` background at 60% alpha. Only sets `bg`, so treesitter foreground colors show through. *DiffsDeleteText* DiffsDeleteText Character-level background for changed characters within `-` lines. Derived by blending `diffRemoved` foreground with `Normal` background at 60% alpha. Conflict highlights: ~ *DiffsConflictOurs* DiffsConflictOurs Background for "ours" (current) content lines. Derived by blending `DiffAdd` background with `Normal` at 40% alpha (green tint). *DiffsConflictTheirs* DiffsConflictTheirs Background for "theirs" (incoming) content lines. Derived by blending `DiffChange` background with `Normal` at 40% alpha. *DiffsConflictBase* DiffsConflictBase Background for base (ancestor) content lines in diff3 conflicts. Derived by blending `DiffText` background with `Normal` at 30% alpha (muted). *DiffsConflictMarker* DiffsConflictMarker Dimmed foreground with bold for `<<<<<<<`, `=======`, `>>>>>>>`, and `|||||||` marker lines. *DiffsConflictOursNr* DiffsConflictOursNr Line number for "ours" content lines. Foreground from higher-alpha blend, background from line-level blend. *DiffsConflictTheirsNr* DiffsConflictTheirsNr Line number for "theirs" content lines. *DiffsConflictBaseNr* DiffsConflictBaseNr Line number for base content lines (diff3). *DiffsConflictActions* DiffsConflictActions Dimmed foreground (no bold) for the codelens-style action line shown when `show_actions` is true. Diff mode window highlights: ~ These are used for |winhighlight| remapping in `&diff` windows. *DiffsDiffAdd* DiffsDiffAdd Background-only. Derived from `DiffAdd` bg. Treesitter provides foreground syntax highlighting. *DiffsDiffDelete* DiffsDiffDelete Foreground and background from `DiffDelete`. Used for filler lines (`/////`) which have no real code content to highlight. *DiffsDiffChange* DiffsDiffChange Background-only. Derived from `DiffChange` bg. Treesitter provides foreground syntax highlighting. *DiffsDiffText* DiffsDiffText Background-only. Derived from `DiffText` bg. Treesitter provides foreground syntax highlighting. To customize these in your colorscheme: >lua vim.api.nvim_set_hl(0, 'DiffsAdd', { bg = '#2e4a3a' }) vim.api.nvim_set_hl(0, 'DiffsDiffDelete', { link = 'DiffDelete' }) < Or via `highlights.overrides` in config: >lua vim.g.diffs = { highlights = { overrides = { DiffsAdd = { bg = '#2e4a3a' }, DiffsDiffDelete = { link = 'DiffDelete' }, }, }, } < ============================================================================== HEALTH CHECK *diffs-health* Run |:checkhealth| diffs to verify your setup. Checks performed: - Neovim version >= 0.9.0 - vim-fugitive is installed (optional) - libvscode_diff shared library is available (optional) ============================================================================== ACKNOWLEDGEMENTS *diffs-acknowledgements* - vim-fugitive (https://github.com/tpope/vim-fugitive) - codediff.nvim (https://github.com/esmuellert/codediff.nvim) - diffview.nvim (https://github.com/sindrets/diffview.nvim) - @phanen (https://github.com/phanen) - diff header highlighting, treesitter injection support, blame_hl.nvim (gitsigns blame popup highlighting inspiration) ============================================================================== vim:tw=78:ts=8:ft=help:norl: