Ports the parsing half of ZIG/src/terminal into the ghostty-vt crate: - Parser state machine with a compile-time generated parse table and the UTF-8 decoder - OSC parser incl. all sub-parsers (titles, colors, clipboard, hyperlinks, semantic prompts/OSC 133, OSC 9 / ConEmu, iTerm2, kitty clipboard, color and text-sizing protocols, context signals) - CSI, SGR, modes table with save/restore, charsets, ansi, device status, mouse shapes, APC, DCS (incl. XTGETTCAP), tmux control-mode parser - color palette / X11 color names, kitty color and graphics command parser Deviations from Zig (documented in docs/rewrite/notes/ghostty-vt-W*.md): parser actions own their payloads instead of borrowing parser buffers; OSC strings are Vec<u8>; non-exhaustive Zig enums gain an Other(raw) variant; tmux regexes replaced by equivalent hand-written matchers. Known follow-up: semantic_prompt.rs carries local copies of the printf-q and percent decoders that belong in ghostty-os. Test Plan: - cargo test -p ghostty-vt: 395 passed, 1 ignored (skipped in Zig too) - cargo clippy -p ghostty-vt --all-targets -- -D warnings: clean
2.7 KiB
2.7 KiB
ghostty-vt W2 notes
Ported (Zig -> Rust, all in crates/ghostty-vt/src)
- csi.zig -> csi.rs (EraseDisplay, EraseLine/TabClear with
Other(u8)for the non-exhaustive Zig enums, SizeReportStyle, TitlePushPop) - sgr.zig -> sgr.rs (
Attribute<'a>,Parser<'a>implementingIterator; usescrate::color::{Name, Rgb}andcrate::parser::{SepList, MAX_PARAMS}) - modes.zig -> modes.rs (
Modeenum,ENTRIEStable,ModePacked(u64),ModeState,mode_from_int) - charsets.zig -> charsets.rs (const-built 256-entry tables)
- ansi.zig -> ansi.rs; device_status.zig -> device_status.rs; mouse_shape.zig -> mouse_shape.rs
- kitty/key.zig: three remaining tests added to existing kitty/key.rs
- kitty/graphics_command.zig -> kitty/graphics_command.rs (parser + Response + all command structs;
pub mod graphics_commandin kitty/mod.rs) - apc.zig -> apc.rs; dcs.zig -> dcs.rs; tmux/control.zig -> tmux/control.rs (+ tmux/mod.rs, only control)
- Dependencies added:
thiserror,base64.
Deviations
- Non-exhaustive Zig enums (EraseLine, TabClear, RenditionAspect, StatusLineType) are Rust enums with
Other(raw); C0 usesfrom_int -> Option. - tmux Notification owns its data (
Vec<u8>) instead of borrowing the parser buffer. Oniguruma regexes replaced by hand-written matchers with the same greedy semantics. IDs overflowing usize are treated as non-match (Zig:unreachable). - DCS/APC handlers drop allocator params;
tmuxstate holdsBox<tmux::control::Parser>. - graphics_command base64:
simd.base64replaced bybase64crate (standard alphabet, padding optional, ASCII whitespace ignored like simdutf). zlib is not decoded in the parser (Zig does not either), so no flate2 dependency. Parser::completemoves the decoded payload out (ZigdecodeDataalso consumes the buffer).- modes: Zig tests
ModePackedsize == 8; Rust has an equivalentpacked_sizetest (u64). Mode bit index = enum discriminant = position in ENTRIES. - sgr uses a bounds-tolerant
sep_is_set(Zig's StaticBitSet would assert past MAX_PARAMS). Attributevariant names:Fg8/Bg8/Fg8Bright/Bg8Bright/Fg256/Bg256/UnderlineColor256for Zig@"8_fg"etc.
Skipped (Zig-only)
- sgr "Attribute C compat",
Attribute.C/cval/lib.Enum/lib.TaggedUnion(C ABI). - mouse_shape "ghostty.h MouseShape" (C header check) and GObject type registration (belongs to apprt-gtk;
MouseShapeisrepr(i32)in declaration order). - modes
test { _ = Mode; _ = ModePacked }and charsets/tests reflection-only bits (replaced by explicit tests). - Allocator-failure aspects (
deinit, arenas) have no Rust equivalent.
Known gaps / integration
- dcs.rs uses
crate::parser::Dcs(W1).sgr/dcsdepend on W1 modules compiling. - tmux layout/output/viewer are NOT here (ghostty-terminal).