Adds an OSC 72 parser following the kitty drag and drop protocol
specification. Parses metadata and payload into a Command.kitty_dnd_protocol
variant. Reassembly of chunked transfers and any action handling are
intentionally out of scope here; stream.zig logs the command as
unimplemented for now.
Includes a walkthrough document covering the design and each touched file.
Trailing state capture now is encapsulated in a struct `Capture` and all
parsers access the data via `p.capture.trailing()` rather than directly
from the writer.
This is primarily to prep for the OSC parser to be able to capture the
entire sequence (not just the trailing part) so we can setup libghostty
for fallback handlers so libghostty implementers can have custom OSC
behaviors.
But, it has the benefit of making our OSC parser much cleaner too.
Previously every file in the terminal package independently imported
build_options and ../lib/main.zig, then computed the same
lib_target constant. This was repetitive and meant each file needed
both imports just to get the target.
Introduce src/terminal/lib.zig which computes the target once and
re-exports the commonly used lib types (Enum, TaggedUnion, Struct,
String, checkGhosttyHEnum, structSizedFieldFits). All terminal
package files now import lib.zig and use lib.target instead of the
local lib_target constant, removing the per-file boilerplate.
Implements parsing for OSC 3008, which allows terminal emulators to keep
track of the stack of processes that have current control over the tty.
The implementation mirrors existing `semantic_prompt.zig` architecture
and natively maps UAPI definitions to Zig structures with lazy
evaluation for optional metadata.
Fixes#10900
- Use `std.meta.stringToEnum` in ContextType and ExitStatus
- Ensure `parseInt` only accepts digits for pids
- Use `@tagName` for string representation in Field
- Rename `fields_raw` to `metadata`
- Rename `readField` to `readOption`
Implements parsing for OSC 3008, which allows terminal emulators to keep track of the stack of processes that have current control over the tty. The implementation mirrors existing `semantic_prompt.zig` architecture and natively maps UAPI definitions to Zig structures with lazy evaluation for optional metadata.
Fixes#10900
This changes our OSC133 parser to parse options lazily. We do this for
multiple reasons:
1. Parsing all our options ahead of time balloons our required
osc.Command tagged union type which has C ABI implications. Adding
all supported options (including Kitty extensions) today already
breaks our C ABI.
2. Invalid options are allowed by the specification and should be
explicitly ignored, so we don't need to validate options at all
during parse time.
3. Semantic prompt markers don't need to be high throughput, so we
can afford to do some extra work at processing time to gather
the options. They're also rather short usually.
This adds a new single-file library called "Tripwire" in
`src/tripwire.zig`. This library helps inject failures around `try`
cases for the purpose of testing `errdefer`. It is fully optimized away
in non-test builds (even debug), turning into zero space and zero
assembly.
From this, I've verified (via unit tests w/ tripwire) and fixed a number
of errdefer issues:
* PageList init with non-standard pages that requires more than 1 page
can leak on allocation error on the 2nd+ loop
* Tabstop allocation failure on resize corrupts the internal state
(invalid cols)
* `Screen.selectionString` would leak memory on late allocation failures
* Screen search could leak memory on late allocation failures
* `SharedGrid.renderGlyph` in our font subsystem would corrupt the glyph
cache if failure occurred
* `SharedGrid.init` could leak memory if loading font metrics failed
In addition to the bugs found, there is now tripwire coverage around
more of our core and we should continue to add more. I've also added
significantly more explicit error sets as I found them.
**AI disclosure:** AI wrote some of the tests, but tripwire itself is
all handwritten and everything was reviewed.