Problem: fugitive shows combined diffs (@@@ headers, 2-char prefixes)
for unmerged (UU) files. The parser and highlight pipeline assumed
unified diff format (@@, 1-char prefix), causing broken prefix
concealment, missing background colors on ` +`/`+ ` lines, and no
treesitter highlights due to garbage prefix chars in code arrays.
Solution: detect prefix width from the number of leading @ signs in
hunk headers. Propagate prefix_width through the parser (new field on
diffs.Hunk) and highlight pipeline (prefix stripping, col_offset,
concealment, line classification). Add U to filename pattern for
unmerged file detection. Skip intra-line diffing for combined diffs
since the 2-char prefix semantics don't produce meaningful change
groups.
## Problem
Three minor issues remain before the v0.2.0 release:
1. Git quotes filenames containing spaces, unicode, or special
characters
in the fugitive status buffer. `parse_file_line` passed the quotes
through verbatim, causing file-not-found errors on diff operations.
2. Navigation wrap-around in both conflict and merge modules was silent,
giving no indication when jumping past the last/first item back to the
beginning/end.
3. `resolved_hunks` and `(resolved)` virtual text in the merge module
persisted across buffer re-reads, showing stale markers for hunks that
were no longer resolved.
## Solution
1. Add an `unquote()` helper to fugitive.lua that strips surrounding
quotes and unescapes `\\`, `\"`, `\n`, `\t`, and octal `\NNN`
sequences. Applied to both return paths in `parse_file_line`.
2. Add `vim.notify` before the wrap-around jump in all four navigation
functions (`goto_next`/`goto_prev` in conflict.lua and merge.lua).
3. Clear `resolved_hunks[bufnr]` and the merge namespace at the top of
`setup_keymaps` so each buffer init starts fresh.
Closes#66
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