Add per-connection terminal capability detection#226
Draft
lawik wants to merge 1 commit into
Draft
Conversation
Detect modern terminal features (Kitty graphics, sixel, Kitty keyboard protocol, synchronized output, terminal name/version) per SSH connection by querying the connecting terminal and reading its responses back over the pty. Environment-based detection (TERM/KITTY_PID/TERM_PROGRAM) doesn't work on a Nerves device: those variables live on the client and don't survive the hop over SSH. Instead, the IEx shell-startup callback runs a batch of capability queries terminated by a Primary Device Attributes (DA1) request. Reading with echo off routes input through the Erlang group's "dumb" state, where get_chars returns bytes immediately rather than waiting for a newline, so the raw response can be read without a custom ssh_cli. DA1 is answered by essentially every terminal and responses arrive in order, so its reply doubles as a completion sentinel. Results are stored per session (keyed by group leader, cleaned up on disconnect) and exposed via NervesSSH.TerminalCapabilities.get/0. Controlled by the new :detect_terminal_capabilities option (default on; Elixir 1.17+).
Member
|
This seems really useful, but my first reaction is shouldn't this be in OTP? Either that or some hook be in OTP? It seems generally useful to everyone and not just Nerves users. I'd also expect it to work in console. |
Author
|
Yeah. I don't know the world of tty, pty and the rest well enough to have a good sense. It does seem like it'd be neat to have in OTP but would also kind of be a bit bloaty? I don't know. |
Member
I feel like Nerves is more susceptible to bloat given its embedded focus than OTP. I kind of wish that it would be easier to make OTP less bloaty. 😢 |
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.
Lars' notes:
This is an experiment towards supporting modern terminal features over SSH. I'm not sure it is worthwhile since it raises a lot of fun compat concerns.
I was mostly interested in if it was possible to get some of this feature-set over SSH and in Elixir. Perhaps being able to detect support for the kitty image protocol and other fun madness.
Claude:
Detect modern terminal features (Kitty graphics, sixel, Kitty keyboard protocol, synchronized output, terminal name/version) per SSH connection by querying the connecting terminal and reading its responses back over the pty.
Environment-based detection (TERM/KITTY_PID/TERM_PROGRAM) doesn't work on a Nerves device: those variables live on the client and don't survive the hop over SSH. Instead, the IEx shell-startup callback runs a batch of capability queries terminated by a Primary Device Attributes (DA1) request. Reading with echo off routes input through the Erlang group's "dumb" state, where get_chars returns bytes immediately rather than waiting for a newline, so the raw response can be read without a custom ssh_cli. DA1 is answered by essentially every terminal and responses arrive in order, so its reply doubles as a completion sentinel.
Results are stored per session (keyed by group leader, cleaned up on disconnect) and exposed via NervesSSH.TerminalCapabilities.get/0. Controlled by the new :detect_terminal_capabilities option (default on; Elixir 1.17+).