## TODO
1. docs (vimdoc + readme) - this is a non-trivial feature
2. push luarocks version
## Problem
diffs.nvim only activates on `fugitive`, `git`, and `gitcommit`
filetypes.
Neogit uses its own custom filetypes (`NeogitStatus`,
`NeogitCommitView`,
`NeogitDiffView`) and doesn't set `b:git_dir`, so the plugin never
attaches
and repo root resolution fails for filetype detection within diff hunks.
## Solution
Two changes:
1. **`lua/diffs/init.lua`** — Add the three Neogit filetypes to the
default
`filetypes` list. The `FileType` autocmd in `plugin/diffs.lua` already
handles them correctly since the `is_fugitive_buffer` guard only applies
to the `git` filetype.
2. **`lua/diffs/parser.lua`** — Add a CWD-based fallback in
`get_repo_root()`.
After the existing `b:diffs_repo_root` and `b:git_dir` checks, fall back
to
`vim.fn.getcwd()` via `git.get_repo_root()` (already cached). Without
this,
the parser can't resolve filetypes for files in Neogit buffers.
Neogit's expanded diffs use standard unified diff format, so the parser
handles
them without modification.
Closes#110.
## Problem
Fugitive shows combined diffs (`@@@` headers, 2-character prefixes like
`++`, ` +`, `+ `) for unmerged (`UU`) files. The parser and highlight
pipeline assumed unified diff format (`@@`, 1-char prefix), causing:
- Prefix concealment only hiding 1 of 2 prefix chars
- Missing background colors on ` +` and `+ ` lines (first char is space
→ misclassified as context)
- No treesitter highlights (extra prefix char poisoned code arrays)
- `U` file header not recognized by parser (missing from filename
pattern)
## Solution
Detect prefix width from leading `@` count in hunk headers (`@@` → 1,
`@@@` → 2). Propagate `prefix_width` through the pipeline:
- **Parser**: new `prefix_width` field on `diffs.Hunk`, `U` added to
filename pattern, combined diff range extraction
- **Highlight**: prefix stripping, `col_offset`, concealment width, and
line classification all use `prefix_width`
- **Intra-line**: skipped for combined diffs (`prefix_width > 1`) since
2-char prefix semantics don't produce meaningful change groups
Problem: treesitter parses each diff hunk in isolation, so incomplete
syntax constructs at hunk boundaries (e.g., a function definition with
no body) produce ERROR nodes and drop captures.
Solution: read N lines from the on-disk file before/after each hunk and
prepend/append them as unmapped padding lines. The line_map guard in
highlight_treesitter skips extmarks for unmapped lines, so padding
provides syntax context without visual output. Controlled by
highlights.context (default 25, 0 to disable). Also applies to the vim
syntax fallback path via a leading_offset filter.
When a file has no extension but contains a shebang (e.g., `#!/bin/bash`),
filetype detection now reads the first 10 lines from disk and uses
`vim.filetype.match({ filename, contents })` for content-based detection.
This enables syntax highlighting for files like `build` scripts that rely
on shebang detection, even when the file isn't open in a buffer.
Detection order:
1. Existing buffer's filetype (already implemented in #69)
2. File content (shebang/modeline) - NEW
3. Filename extension only
Also adds `filetype on` to test helpers to ensure `vim.g.ft_ignore_pat`
is set, which is required for shell detection.
Files detected via shebang or modeline (e.g., `build` with `#!/bin/bash`)
weren't getting syntax highlighting because `vim.filetype.match()` only
does filename-based detection.
Now `get_ft_from_filename()` first checks if a buffer already exists for
the file and uses its detected filetype. This requires knowing the repo
root to construct the full path, so:
- `parse_buffer()` reads `b:diffs_repo_root` or `b:git_dir` (fugitive)
- `commands.lua` sets `b:diffs_repo_root` on diff buffers it creates
Co-authored-by: phanen <phanen@qq.com>
Previously, hunks were discarded entirely if vim.filetype.match()
returned nil. This meant files with unrecognized extensions got no
highlighting at all - not even the basic green/red backgrounds for
added/deleted lines.
Remove the (current_lang or current_ft) condition from flush_hunk()
so all hunks are collected. highlight_hunk() already handles the
case where ft/lang are nil by skipping syntax highlighting but still
applying background colors.
Co-authored-by: phanen <phanen@qq.com>
Apply treesitter highlighting to diff metadata lines (diff --git, index,
---, +++) using the diff language parser. Header info is attached only
to the first hunk of each file to avoid duplicate highlighting.
Based on PR #52 by @phanen with fixes:
- header_lines now only contains diff metadata, not hunk content
- header info attached only to first hunk per file
- removed arbitrary hunk count restriction