From a6fedd025529c2e694b8693f2c8f9a1270a9a939 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sat, 20 Jun 2026 14:58:55 +0200 Subject: [PATCH] Spec: define the version-only handshake record MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add §4.4: a conforming pager emits a version-only OSC 1717 record (no further fields) as its first output, so a host can probe it on an empty diff — which emits no per-line records — and tell "speaks the protocol" apart from "unsupported pager", content-independently. Used by the focused main view's raw-diff fallback to decide whether a pager's output is actionable. Co-Authored-By: Claude Opus 4.8 (1M context) --- diff-line-metadata-osc-spec.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/diff-line-metadata-osc-spec.md b/diff-line-metadata-osc-spec.md index 794202899..7c4e6243e 100644 --- a/diff-line-metadata-osc-spec.md +++ b/diff-line-metadata-osc-spec.md @@ -145,6 +145,33 @@ path is not carried. A pure rename with no content change emits no records at al | two consecutive deletions | `…;d;11;9;…` then `…;d;11;10;…` (same `new-line`, different `old-line` — see §5.3) | | whole-file deletion | `1717;1;d;0;9;old/path` (`new-line` 0 — see §5.4) | +### 4.4 The handshake record + +A conforming pager emits, as the **very first thing it writes** and **once per run**, +a **version-only** record naming the version it negotiated: + +``` +ESC ] 1717 ; ST +``` + +i.e. the OSC introducer and the version field **with no further fields** — +`\x1b]1717;1\x1b\` for v1. It is emitted whenever the handshake (§3) negotiates a +version, *before* any diff content (and before the first per-line record). + +Its purpose is to let the host **probe** a pager cheaply and definitively: run it on an +**empty diff** (no changed content) and look for this record. Without it, "does this +pager speak the protocol?" could only be inferred from the per-line records — but a +diff with no content lines (a binary file, or the empty diff a probe would use) emits +none, so the absence of records would be indistinguishable from an unsupported pager. +The handshake is **content-independent** (it precedes, and does not depend on, any +diff), so a single probe is conclusive and a binary file can't be mistaken for an +unsupported pager. It also tells the host the negotiated version up front. + +A host distinguishes it from a per-line record (§4.1) by **field count**: the handshake +carries only the version (no `;` after it); a per-line record always has the full five +fields. A host that doesn't care about probing may simply ignore any record it can't +parse as five fields — so the handshake is harmless to existing parsers. + --- ## 5. Semantics @@ -257,6 +284,9 @@ over the rendered buffer. ## 6. Emit rules (placement) +The pager first emits the handshake record (§4.4) — once, before any other output — +then a per-line record before each region as follows. + ### 6.1 One record per region, at the region's start The pager emits each region's record at the **start of that region**. Everything