You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Tapes that use Ctrl+1 through Ctrl+9 are not supported. xterm.js in legacy mode (used by ttyd) has no escape-sequence mapping for Ctrl+Digit combinations, so the keypress is silently dropped and never reaches the PTY.
Bubbletea uses the kitty keyboard protocol to handle these combinations. Without this, any app that binds ctrl+1-ctrl+9 (e.g. tab switching, workspace selection) cannot be demonstrated with VHS. I ran into this while recording a demo of my TUI app, It uses Ctrl+digit for navigation between tabs, and I couldn't capture those interactions at all. So I had to make changes locally.
Describe the solution you'd like
Emit the kitty keyboard protocol sequence (\x1b[<codepoint>;<modifier>u) directly via term.input() in ExecuteCtrl, the same approach already used by ExecuteScroll for term.scrollLines().
Also, a parser change to accept NUMBER tokens in parseCtrl(), following the same pattern as the arrow-key support added in #673.
Example in tape:
Ctrl+1
Ctrl+Shift+2
...
Describe alternatives you've considered
An alternative would be to attach a custom key event handler to xterm.js via attachCustomKeyEventHandler in the terminal setup. This intercepts the DOM keydown event and calls term.input() with the kitty sequence directly from JavaScript. However, this adds a global side effect at setup time, present for every tape even when Ctrl+digit is never used, and splits the execution logic across two files instead of keeping it self-contained in ExecuteCtrl.
Additional context
The solution I'm proposing follows the same pattern as the Ctrl+arrow key support added in #673: a one-line parser change to accept the new token type, and a new case in ExecuteCtrl for execution. The digit path reuses the same direct term.input() approach already used by ExecuteScroll (term.scrollLines()).
I have a local implementation of this working, including unit tests covering Ctrl+0 through Ctrl+9 and the Shift/Alt modifier combinations. I also have a GIF on my project's repo changing tabs using Ctrl+Digit. Happy to open a PR if the approach looks good to you.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
Tapes that use
Ctrl+1throughCtrl+9are not supported. xterm.js in legacy mode (used by ttyd) has no escape-sequence mapping forCtrl+Digitcombinations, so the keypress is silently dropped and never reaches the PTY.Bubbletea uses the kitty keyboard protocol to handle these combinations. Without this, any app that binds
ctrl+1-ctrl+9(e.g. tab switching, workspace selection) cannot be demonstrated with VHS. I ran into this while recording a demo of my TUI app, It uses Ctrl+digit for navigation between tabs, and I couldn't capture those interactions at all. So I had to make changes locally.Describe the solution you'd like
Emit the kitty keyboard protocol sequence (
\x1b[<codepoint>;<modifier>u) directly viaterm.input()inExecuteCtrl, the same approach already used byExecuteScrollforterm.scrollLines().Also, a parser change to accept
NUMBERtokens inparseCtrl(), following the same pattern as the arrow-key support added in #673.Example in tape:
Ctrl+1
Ctrl+Shift+2
...
Describe alternatives you've considered
An alternative would be to attach a custom key event handler to xterm.js via
attachCustomKeyEventHandlerin the terminal setup. This intercepts the DOM keydown event and callsterm.input()with the kitty sequence directly from JavaScript. However, this adds a global side effect at setup time, present for every tape even whenCtrl+digitis never used, and splits the execution logic across two files instead of keeping it self-contained inExecuteCtrl.Additional context
The solution I'm proposing follows the same pattern as the
Ctrl+arrow keysupport added in #673: a one-line parser change to accept the new token type, and a new case inExecuteCtrlfor execution. The digit path reuses the same direct term.input() approach already used byExecuteScroll(term.scrollLines()).I have a local implementation of this working, including unit tests covering
Ctrl+0throughCtrl+9and theShift/Altmodifier combinations. I also have a GIF on my project's repo changing tabs usingCtrl+Digit. Happy to open a PR if the approach looks good to you.Beta Was this translation helpful? Give feedback.
All reactions