feat: add ANSI parsing support on Windows (VT input hybrid)#1030
Open
eitsupi wants to merge 10 commits intocrossterm-rs:masterfrom
Open
feat: add ANSI parsing support on Windows (VT input hybrid)#1030eitsupi wants to merge 10 commits intocrossterm-rs:masterfrom
eitsupi wants to merge 10 commits intocrossterm-rs:masterfrom
Conversation
Move the ANSI escape sequence parser to a platform-shared module so it can be reused on Windows. Replace internal is_raw_mode_enabled() calls with the public API (crate::terminal::is_raw_mode_enabled()) which has a uniform Result<bool> signature on all platforms. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Make CursorPosition, KeyboardEnhancementFlags, and PrimaryDeviceAttributes variants available on all platforms. Unify EventFilter::eval to use the matches! pattern for all platforms. Remove cfg gates from filter structs, impls, and test functions. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Move the identical Parser struct from mio.rs and tty.rs into sys/parse.rs. Add push_event() method for Windows hybrid source to enqueue non-ANSI events alongside parsed events. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Enable ENABLE_VIRTUAL_TERMINAL_INPUT on Windows console input to receive ANSI escape sequences (including bracketed paste). The hybrid approach feeds KEY_EVENT unicode characters through the shared ANSI parser when VT input is available, and falls back to VK code handling for keys without character data or when VT input is unsupported (legacy conhost). Also fix enable_mouse_capture() to OR flags instead of replacing, which would clobber the VT input flag. Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Add comment about init_original_console_mode ordering dependency - Add comment about potential stale event count in batch reading - Add comment about surrogate buffer invariant across event types - Clarify VT key-up skip comment re: behavioral consistency - Extract decode_utf16_char to shared free function with unit tests (BMP chars, surrogate pairs, orphaned high/low surrogates) Co-Authored-By: Claude Opus 4.6 <[email protected]>
…arnings - Split surrogate_buffer into vt_surrogate and legacy_surrogate to prevent interference between VT and non-VT code paths within a single batch of input events - Add comment explaining unwrap_or(false) rationale for is_raw_mode_enabled on Windows - Add #[allow(dead_code)] to push_event and decode_utf16_char (only used on Windows, but defined in shared module for testability) - Expand try_enable_vt_input comment explaining why all set_mode errors are treated as "VT not supported" Co-Authored-By: Claude Opus 4.6 <[email protected]>
Re-add comment explaining that non-key events don't touch vt_surrogate, so interleaved events between surrogate pair halves are harmless. Co-Authored-By: Claude Opus 4.6 <[email protected]>
After removing #[cfg(unix)] from InternalEvent variants (CursorPosition, KeyboardEnhancementFlags, PrimaryDeviceAttributes), the wildcard match arms in event.rs and stream.rs also need their #[cfg(unix)] guards removed to remain exhaustive on Windows. Co-Authored-By: Claude Opus 4.6 <[email protected]>
CursorPositionFilter, KeyboardEnhancementFlagsFilter, and PrimaryDeviceAttributesFilter are only used on Unix (for terminal queries). Use #[cfg_attr(windows, allow(dead_code))] to suppress warnings specifically on Windows without hiding them on Unix. Co-Authored-By: Claude Opus 4.6 <[email protected]>
This was referenced Feb 6, 2026
|
I verified this with Forge code -> reedline -> crossterm. // Patches to enable Windows VT input and bracketed paste support It works, THANKS! I just hope the maintainers will merge and release a new version soon 🙏 |
sinelaw
pushed a commit
to sinelaw/fresh
that referenced
this pull request
Mar 7, 2026
Crossterm's Windows backend uses ReadConsoleInput which delivers structured INPUT_RECORD events. The console strips VT escape sequences (including bracketed paste markers) from these events. This is a known crossterm limitation (crossterm-rs/crossterm#737). Fix by enabling ENABLE_VIRTUAL_TERMINAL_INPUT on the console input handle and reading VT sequences from KEY_EVENT_RECORD.uChar. This is the hybrid approach recommended by Microsoft and used by Cygwin, MSYS2, and OpenSSH (see crossterm-rs/crossterm#1030). Changes: - New win_vt_input module: enables VT input mode, reads INPUT_RECORD events, extracts raw VT bytes from key events, handles resize/focus as structured events, supports UTF-16 surrogate pairs - relay_windows.rs: forwards raw VT bytes to server (matching Unix relay behavior) with crossterm fallback for legacy Windows - main.rs: Windows direct mode uses InputParser to parse VT bytes into crossterm Events, with crossterm fallback if VT input unavailable https://claude.ai/code/session_01NRqCzMiQM41Low1HvSNaLc
sinelaw
pushed a commit
to sinelaw/fresh
that referenced
this pull request
Mar 7, 2026
Crossterm's Windows backend uses ReadConsoleInput which delivers structured INPUT_RECORD events. The console strips VT escape sequences (including bracketed paste markers) from these events. This is a known crossterm limitation (crossterm-rs/crossterm#737). Fix by enabling ENABLE_VIRTUAL_TERMINAL_INPUT on the console input handle and reading VT sequences from KEY_EVENT_RECORD.uChar. This is the hybrid approach recommended by Microsoft and used by Cygwin, MSYS2, and OpenSSH (see crossterm-rs/crossterm#1030). Changes: - New win_vt_input module: enables VT input mode, reads INPUT_RECORD events, extracts raw VT bytes from key events, handles resize/focus as structured events, supports UTF-16 surrogate pairs - relay_windows.rs: forwards raw VT bytes to server (matching Unix relay behavior) with crossterm fallback for legacy Windows - main.rs: Windows direct mode uses InputParser to parse VT bytes into crossterm Events, with crossterm fallback if VT input unavailable https://claude.ai/code/session_01NRqCzMiQM41Low1HvSNaLc
sinelaw
pushed a commit
to sinelaw/fresh
that referenced
this pull request
Mar 7, 2026
Crossterm's Windows backend uses ReadConsoleInput which delivers structured INPUT_RECORD events. The console strips VT escape sequences (including bracketed paste markers) from these events. This is a known crossterm limitation (crossterm-rs/crossterm#737). Fix by enabling ENABLE_VIRTUAL_TERMINAL_INPUT on the console input handle and reading VT sequences from KEY_EVENT_RECORD.uChar. This is the hybrid approach recommended by Microsoft and used by Cygwin, MSYS2, and OpenSSH (see crossterm-rs/crossterm#1030). Changes: - New win_vt_input module: enables VT input mode, reads INPUT_RECORD events, extracts raw VT bytes from key events, handles resize/focus as structured events, supports UTF-16 surrogate pairs - relay_windows.rs: forwards raw VT bytes to server (matching Unix relay behavior) with crossterm fallback for legacy Windows - main.rs: Windows direct mode uses InputParser to parse VT bytes into crossterm Events, with crossterm fallback if VT input unavailable https://claude.ai/code/session_01NRqCzMiQM41Low1HvSNaLc
This was referenced Apr 15, 2026
This was referenced Apr 17, 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.
Fix #737
Fix #962
Summary
ESC[200~...ESC[201~) from modern terminals like Windows TerminalChanges
Refactoring (no behavior change)
sys/unix/parse.rsto sharedsys/parse.rsmio.rsandtty.rs)#[cfg(unix)]guards fromInternalEventvariants and filtersWindows VT input
try_enable_vt_input()to enableENABLE_VIRTUAL_TERMINAL_INPUTwith graceful fallbackenable_mouse_capture()to OR flags instead of replacing (preserves VT input)WindowsEventSource: batch-read all available input records, feed unicode chars toANSI parser (VT path), fall back to VK codes (non-VT path)
Tested
cargo teston Linuxcargo teston Windows (1 pre-existing failure unrelated to changes)cargo run --example event-read --features "events,bracketed-paste"on Windows Terminal: bracketed paste producesEvent::Paste(...)correctly