Support OSC-1717 metadata#2181
Open
stefanhaller wants to merge 3 commits into
Open
Conversation
A host that renders delta's output (e.g. lazygit) needs to map a rendered diff row back to its patch-space identity -- file, line type, and new/old line numbers -- to act on the line the user points at. delta's default rendering drops the +/- markers and conveys the side by color, so that identity cannot be recovered from the painted text; the pager, which still has it at render time, has to state it. Gate the emission on the OSC1717_METADATA environment variable so output is byte-for-byte unchanged outside such a host -- harmless in a raw terminal, less, or tmux. The host advertises the protocol versions it understands and delta emits the highest mutually-understood one (currently always v1 because that's the only version that exists, but the mechanism is extensible). The metadata rides on a dedicated, purely-additive emitter rather than reusing LineNumbersData: delta only maintains its line-number counters when --line-numbers is enabled, and forcing that on would also render a gutter and change wrap-width math. The emitter tracks its own counters (seeded from the hunk header, mirroring LineNumbersData::initialize_hunk) and only injects OSC bytes, leaving all styling and layout untouched. This commmit covers the normal unified single-column path only; side-by-side mode is going to be supported in the next commit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The unified emitter funnels every content line through Painter::paint_lines, but side-by-side renders each visual row as two panel halves painted directly via Painter::paint_line, so the unified emit point never fired for it. Attach the OSC per cell instead: the left panel's cell carries the minus line's identity, the right panel's the plus line's, and a context line -- shown in both panels -- carries the same record before each half. The line-number counters in side-by-side are advanced per aligned row (with increment flags and post-hoc fixups), not in the unified "all minus, then all plus" order that osc_for_line's arithmetic assumes. So rather than call osc_for_line inline at each panel paint, precompute the per-line OSC strings for the whole minus block and then the whole plus block -- the unified order -- and look them up by the same index that selects each line's state. The emitted records stay byte-identical to the single-column emitter, and the shared counters still land where the next hunk block expects them. Side-by-side is also the only mode that wraps a long line, into several output rows with Hunk*Wrapped states. delta emits each wrapped row as a distinct output line, so a host sees them as distinct lines and needs the identity on each -- otherwise acting on a continuation row, or treating the wrapped line as one block when navigating, breaks. Each wrapped row therefore re-emits the record of the primary line it continues, without advancing the counters (so the next line's numbers stay correct); empty counterpart cells still get no OSC. Context lines were previously not routed through the emitter at all in side-by-side (paint_zero_lines_side_by_side never saw it), which would have desynced the counters; thread it through there too. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A host can already learn delta's per-line diff metadata, but only from the records emitted before content lines — so a diff with no content (a binary file, or the empty diff a host would use to probe) emits nothing, and "speaks the protocol" is indistinguishable from "unsupported pager". Emit a version-only OSC 1717 record (no further fields) once, before consuming the diff, whenever a version is negotiated. It's content-independent, so a host can probe delta on an empty diff and get a conclusive answer. See the diff-line-metadata OSC spec, §4.4. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
d5973a0 to
3358842
Compare
dandavison
added a commit
to dandavison/dotfiles
that referenced
this pull request
Jul 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This adds support for the OSC-1717 spec described in jesseduffield/lazygit#5731; see also jesseduffield/lazygit#5732 for more context.
The spec is still in draft mode, so we may want to hold off merging this until we got more feedback on it. On the other hand, we want pagers to be ready by the time lazygit releases the feature, that's why I'm opening this for review already.
Closes #2180.