Route OSC actions through a custom stream handler#299
Merged
Conversation
Wrap libghostty's standard terminal handler in `GhostelHandler` and override the OSC arms (semantic_prompt, color_operation, report_pwd, clipboard_contents, show_desktop_notification, progress_report) instead of byte-scanning the same OSC payloads in module.zig before and after every PTY write. Deletes ~395 lines of parallel scanner code (OscIterator, extractOscColorQueries, dispatchPostWriteOscs, OSC 9 / 777 dispatch, dynamic / palette color reply formatters) in favor of reading ghostty's parsed Command values directly. Behavioural notes carried in test fixtures: - OSC 7 with an embedded ESC truncates at the second `\\e]` (ghostty parser's behavior); test expects PWD="PARTIAL". - Empty notifications (`\\e]9;\\e\\\\` / `\\e]777;notify;;\\e\\\\`) are dropped at the FFI boundary. - OSC 9;4;1 → progress=0 (parser pre-fill); OSC 9;4;1;<garbage> → progress=nil (parser writes null over the pre-fill). Documented upstream quirk; no defensive default in the handler. - ConEmu OSC 9 sub-codes (9;5, 9;12<anything>) are swallowed by the parser before they can be re-interpreted as iTerm notifications. Only OSC 51 still uses a bespoke byte scan in module.zig because it is ghostel's elisp-eval extension and not a standard OSC.
Collaborator
|
Huge improvement! |
emil-e
requested changes
May 20, 2026
| /// scanner only sees one `data` slice at a time. Adding carry-over | ||
| /// would require per-`GhostelTerm` state; not worth it until an | ||
| /// OSC 51 chunk-spanning case actually shows up. | ||
| fn dispatchOsc51(env: emacs.Env, data: []const u8) void { |
Collaborator
There was a problem hiding this comment.
Doesn't libghostty have a parser for general OSCs? Might not be able to use the handler but I think we can at least us a parser?
Owner
Author
There was a problem hiding this comment.
I added a TODO, to replace it.
We can't use Ghostty's parser (see TODO comment).
But either they accept a change, OSC 51 is acually defined in xterm and reservered for "Emacs shell", so that would be best, but we could also use a unused clipboard sub-protocol.
I don't think someone cares if they emit 51;E or 52:E. but since 51 is the "Emacs shell" OSC, would be nice to use it.
4965270 to
df7ea9b
Compare
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.
Summary
module.zigwith a customgt.Streamhandler (src/GhostelHandler.zig) that wraps libghostty's standard terminal handler and overrides the OSC arms.Behavioural notes (carried in test fixtures)
\e](ghostty parser behavior); test expectsPWD="PARTIAL".\e]9;\e\\/\e]777;notify;;\e\\) drop at the FFI boundary.progress=0(parser pre-fill); OSC 9;4;1;<garbage>→progress=nil(parser writes null over the pre-fill). Documented quirk, no defensive default.9;5,9;12<anything>) are swallowed by ghostty's parser before they can re-route to iTerm notifications.N(new_command) maps to the sameAmarker ghostel already uses for fresh-line prompts.Test plan
make -j8 all test-evil— 78 ert + native + evil tests, lint, byte-compile cleanemacsclient: prompt navigation (OSC 133), shellpwdtracking (OSC 7 / 9;9), color-scheme query reply (OSC 10 / 11 / 4), clipboard set (OSC 52), notification (OSC 9 / 777), progress (OSC 9;4).