Commit cbd0e97
## Summary
Closes #99.
`diffFile` and `diffDir` invoke delta with `--max-line-length=<width>`,
which is the **truncation** flag — not a wrap hint. Combined with
delta's default `--wrap-max-lines=2`, any source line longer than
roughly two viewport widths got silently dropped in side-by-side mode.
In unified mode (where delta does not wrap at all) the long line then
hit the post-processing truncation in the `diffContentMsg` handler,
which used an empty tail (`""`) and clipped without any visible signal.
The reporter pointed at both spots in the original issue — both [the
delta
args](https://github.com/dlvhdr/diffnav/blob/2898ff7523b89f683d52c639789e7d404627b0b9/pkg/ui/panes/diffviewer/diffviewer.go#L282-L294)
and [the post-processing
pass](https://github.com/dlvhdr/diffnav/blob/2898ff7523b89f683d52c639789e7d404627b0b9/pkg/ui/panes/diffviewer/diffviewer.go#L82-L95).
## Fix
Two changes in `pkg/ui/panes/diffviewer/diffviewer.go`, plus horizontal
scrolling added per review feedback:
1. **`diffFile` and `diffDir`** — replace `--max-line-length=<width>`
with `--max-line-length=0` (disable truncation) and add
`--wrap-max-lines=unlimited`. Side-by-side mode now wraps long lines all
the way through instead of stopping at the second wrap.
2. **`diffContentMsg` handler** — store the raw delta output, render the
visible window on every change. The cache now holds raw text, so cache
hits re-render through the same path.
3. **Horizontal scrolling** (added in response to
#133 (comment)):
- Left / right arrow keys scroll the diff viewport horizontally at
half-viewport step. `h`/`l` are taken by file-tree expand/collapse, so
arrows are the only sensible binding.
- `xOffset` resets to `0` whenever a new file or dir is loaded.
- The `…` markers are conditional: right when `lineWidth > xOffset +
viewportWidth`, left when `xOffset > 0 && lineWidth > xOffset`. A line
shorter than the viewport never shows either marker.
## Verification
Local repro with the canonical "very long line" diff at `-w=80`:
| Mode | Pre-fix | Post-fix |
|---|---|---|
| **Side-by-side** | clipped at *"what flags delta is invoked with"* (≈2
wraps) | reaches *"to see what happens here"* (full content) |
| **Unified** | line silently cut at viewport width with no marker |
line cut with `…` tail; right-arrow scrolls to reveal the rest, `…`
appears on the left once scrolled |
Verified delta args directly:
```
$ delta --paging=never -w=80 --max-line-length=0 --wrap-max-lines=unlimited --side-by-side < long.diff
…
│ │ │ 2 │const Long = "this is a very long↵
│ │ │ │ line that should be wrapped or t↵
│ │ │ │runcated depending on what flags ↵
│ │ │ │delta is invoked with and we want↵
│ │ │ │ to see what happens here"
…
```
Existing `pkg/ui/panes/diffviewer` test suite passes:
```
ok github.com/dlvhdr/diffnav/pkg/ui/panes/diffviewer 0.366s
```
The pre-existing `TestSearchResultsRenderWhenFileTreeIsHidden`,
`TestBuildFullFileTree`, and `TestCollapseTree` failures on `main` are
unrelated lipgloss-styling drift and are not touched by this PR.
## AI usage disclosure (per AI_POLICY.md)
Tool: Claude Code (Opus 4.7).
Extent: pattern analysis (delta flag semantics, charmbracelet `ansi.Cut`
usage), code drafting for the offset / render-window logic, and
commit-message wording. I reviewed every change manually, ran `go
build`, `go vet`, `go test ./pkg/ui/panes/diffviewer/...`, and confirmed
the long-line repro behaviour locally before pushing. Happy to walk
through any line on request.
Credit to @fgrehm for the report and the precise line references in the
issue.
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 6d660fb commit cbd0e97
3 files changed
Lines changed: 43 additions & 13 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
| 17 | + | |
| 18 | + | |
17 | 19 | | |
18 | 20 | | |
19 | 21 | | |
| |||
71 | 73 | | |
72 | 74 | | |
73 | 75 | | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
74 | 84 | | |
75 | 85 | | |
76 | 86 | | |
| |||
124 | 134 | | |
125 | 135 | | |
126 | 136 | | |
| 137 | + | |
| 138 | + | |
127 | 139 | | |
128 | 140 | | |
129 | 141 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | | - | |
14 | 13 | | |
15 | 14 | | |
16 | 15 | | |
| |||
68 | 67 | | |
69 | 68 | | |
70 | 69 | | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | | - | |
76 | | - | |
77 | | - | |
78 | | - | |
79 | 70 | | |
80 | | - | |
| 71 | + | |
81 | 72 | | |
82 | | - | |
| 73 | + | |
83 | 74 | | |
84 | 75 | | |
85 | 76 | | |
| |||
283 | 274 | | |
284 | 275 | | |
285 | 276 | | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
286 | 287 | | |
287 | 288 | | |
288 | 289 | | |
| |||
296 | 297 | | |
297 | 298 | | |
298 | 299 | | |
299 | | - | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
300 | 308 | | |
301 | 309 | | |
302 | 310 | | |
| |||
332 | 340 | | |
333 | 341 | | |
334 | 342 | | |
335 | | - | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
336 | 346 | | |
337 | 347 | | |
338 | 348 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
308 | 308 | | |
309 | 309 | | |
310 | 310 | | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
311 | 319 | | |
312 | 320 | | |
313 | 321 | | |
| |||
0 commit comments