mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-09-21 16:02:20 +00:00
* fix(input): give the PTY back the Ctrl chords tty7 was eating Follow-up to #682, which handed Ctrl+V to a full-screen program but left three neighbouring holes of the same shape: a key the terminal answers without the keymap ever seeing it. The C0 table was half a table. `input.rs` mapped the alphabet, `[ \ ]` and Ctrl+2, and nothing else — so `Ctrl-^` (Ctrl+6, vim's alternate file), `Ctrl-_` (readline's undo, typed as Ctrl+/ or Ctrl+Shift+-) and Ctrl+3..8 produced no bytes at all. They were not mis-encoded, they were silent: gpui filters control characters out of `key_char` on all three backends, so the text fallback had nothing to offer either. The table is now the VT-220 one, each digit beside the punctuation that shares its key, because every platform hands Ctrl+Shift+6 over as `^` with the Shift already spent. Ctrl+/ is xterm's addition rather than VT-220's and is spelled out with the reason. The twenty-six letters fold to `& 0x1f`. `on_key_down` swallowed plain Ctrl+1..9 off macOS with a bare `return`, left over from when tabs lived on ctrl-digits — they have been on Alt+1..9 for a long time, so nothing claimed those chords and the block only deleted keys. It also sat before `keystroke_to_bytes`, so not even the kitty protocol got through it. Gone. Ctrl+V is now a binding. `AlternatePaste` carries `ctrl-v` off macOS in a `Terminal && !alt_screen` context, and the pane declares `alt_screen` whenever a full-screen program owns the grid, so the behaviour #682 settled on is unchanged — paste at a prompt, SYN inside vim — while the keymap can finally express it, the Keybindings page lists it, and the user gets a say: `"AlternatePaste": ""` hands Ctrl+V to the shell everywhere, including readline's `quoted-insert`, and `"PasteText": "ctrl-v"` pastes on every screen the way Windows Terminal does. That cohort is real — Warp keeps Ctrl+V pasting on Windows on purpose, as a removable binding, for exactly this reason. The hardcoded arm in `handle_cmd_shortcut` now answers Cmd+V alone, which is macOS's only paste chord and carries no control code to lose. Last, the rule about control codes is one function instead of an assertion buried in a test. `steals_a_control_code` plus a commented `control_code_binding_allowed` back both the defaults test and a new runtime warning, so a hand-edited config.json that takes EOF away from every shell says so in the log. It warns rather than refuses: a chord the user asked for by name is theirs to spend, the way the tmux preset spends Ctrl+B. The invariant that still fails a build is that no *default* spends one silently. Tests: `cargo test --bin tty7-app` 1360 passed, 1 known flake (`a_routed_auth_prompt_carries_the_machine_that_raised_it`, green on a rerun and on a clean tree). New: the whole VT-220 table asserted byte by byte, with Ctrl+- held out; `ctrl_6_reaches_the_pty_as_rs`, `ctrl_v_pastes_at_a_prompt` and `ctrl_v_reaches_a_full_screen_program_as_syn` drive the real keymap through `simulate_keystrokes` rather than calling into the view; the keymap tests cover both escape hatches and the context that withholds the binding. #682's two `handle_cmd_shortcut` tests are replaced by those three, which assert the same behaviour at the layer that now decides it; its end-to-end SYN test stands unchanged. The gpui tests are unix-only, so CI is what runs them. * fix(input): ask the grid, not the last frame, before Ctrl+V pastes `AlternatePaste` carries `Terminal && !alt_screen`, but gpui matches a keystroke against the frame it last painted, so the context outlives the switch: a full-screen program that took the screen after that paint is still "at a prompt" as far as the keymap is concerned, and the clipboard lands in it. In vim's normal mode that runs as commands. The action now re-reads the terminal mode and propagates instead, which hands the chord to `on_key_down` and encodes it as the SYN the program is waiting for. Also: - the two escape-hatch assertions in `paste_ships_both_terminal_chords_off_macos_and_retires_together` built a one-entry binding table instead of the default one, so both passed without the hatch working — an emptied `AlternatePaste` cannot dispatch anything when it is the only entry in the table. They now apply the config line on top of the whole default table, and the `PasteText: ctrl-v` case checks both screens; - the keyboard-shortcuts page claimed every other Ctrl chord reaches the program, which Ctrl+Tab and the Windows/Linux font-size chords do not; - `steals_a_control_code` documents `@` and the backtick, which are in the set it walks but were not in the list beside it.
132 lines
5.8 KiB
Plaintext
132 lines
5.8 KiB
Plaintext
---
|
||
title: "Keyboard shortcuts"
|
||
description: "Every default binding, plus the action names for rebinding."
|
||
---
|
||
|
||
**Settings → Keybindings** (<kbd>⌘ ,</kbd>) is the live version of this page —
|
||
it shows what *your* copy is bound to. This is the shipped default.
|
||
|
||
## Tabs and workspaces
|
||
|
||
| Action | macOS | Windows / Linux |
|
||
|---|---|---|
|
||
| New Tab | <kbd>⌘ T</kbd> | <kbd>Ctrl ⇧ T</kbd> |
|
||
| Close Pane / Tab | <kbd>⌘ W</kbd> | <kbd>Ctrl ⇧ W</kbd> |
|
||
| Reopen Closed Tab | <kbd>⌘ ⇧ T</kbd> | <kbd>Alt ⇧ T</kbd> |
|
||
| Next Tab · Previous Tab | <kbd>⌃ ⇥</kbd> · <kbd>⌃ ⇧ ⇥</kbd> | same |
|
||
| Go to Tab 1–9 | <kbd>⌘ 1</kbd>…<kbd>⌘ 9</kbd> | <kbd>Alt 1</kbd>…<kbd>Alt 9</kbd> |
|
||
| New Workspace | <kbd>⌘ ⇧ N</kbd> | <kbd>Ctrl ⇧ N</kbd> |
|
||
| Switch Workspace | <kbd>⌘ ⇧ O</kbd> | <kbd>Ctrl ⇧ O</kbd> |
|
||
|
||
## Panes
|
||
|
||
| Action | macOS | Windows / Linux |
|
||
|---|---|---|
|
||
| Split Right | <kbd>⌘ D</kbd> | <kbd>Ctrl ⇧ D</kbd> |
|
||
| Split Down | <kbd>⌘ ⇧ D</kbd> | <kbd>Ctrl Alt ⇧ D</kbd> |
|
||
| Next Pane · Previous Pane | <kbd>⌘ ]</kbd> · <kbd>⌘ [</kbd> | <kbd>Ctrl ⇧ ]</kbd> · <kbd>Ctrl ⇧ [</kbd> |
|
||
| Focus Pane Left / Right / Up / Down | <kbd>⌘ ⌥ ←→↑↓</kbd> | <kbd>Alt ←→↑↓</kbd> |
|
||
| Zoom Pane | <kbd>⌘ ⇧ ⏎</kbd> | <kbd>Ctrl ⇧ ⏎</kbd> |
|
||
| Enter Full Screen | <kbd>⌘ ⏎</kbd> | <kbd>F11</kbd> |
|
||
|
||
## View
|
||
|
||
| Action | macOS | Windows / Linux |
|
||
|---|---|---|
|
||
| Command Palette | <kbd>⌘ P</kbd> | <kbd>Ctrl ⇧ P</kbd> |
|
||
| Toggle Left Sidebar | <kbd>⌘ B</kbd> | <kbd>Ctrl ⇧ B</kbd> |
|
||
| Toggle Right Panel | <kbd>⌘ J</kbd> | <kbd>Ctrl ⇧ J</kbd> |
|
||
| Toggle Code Panel | <kbd>⌘ ⇧ E</kbd> | <kbd>Ctrl ⇧ E</kbd> |
|
||
| Font Size Up · Down · Reset | <kbd>⌘ +</kbd> · <kbd>⌘ −</kbd> · <kbd>⌘ 0</kbd> | <kbd>Ctrl +</kbd> · <kbd>Ctrl −</kbd> · <kbd>Ctrl 0</kbd> |
|
||
| Zoom the font | <kbd>⌘</kbd> + wheel | <kbd>Ctrl</kbd> + wheel |
|
||
|
||
## Terminal
|
||
|
||
| Action | macOS | Windows / Linux |
|
||
|---|---|---|
|
||
| Find in Terminal | <kbd>⌘ F</kbd> | <kbd>Ctrl ⇧ F</kbd> |
|
||
| Find Next · Previous | <kbd>⌘ G</kbd> · <kbd>⌘ ⇧ G</kbd> | <kbd>F3</kbd> · <kbd>⇧ F3</kbd> |
|
||
| Clear Scrollback | <kbd>⌘ K</kbd> | <kbd>Ctrl ⇧ K</kbd> |
|
||
| Copy · Paste | <kbd>⌘ C</kbd> · <kbd>⌘ V</kbd> | <kbd>Ctrl ⇧ C</kbd> · <kbd>Ctrl ⇧ V</kbd> · <kbd>⇧ Insert</kbd> |
|
||
| Insert Newline (at the prompt) | <kbd>⇧ ⏎</kbd> · <kbd>⌥ ⏎</kbd> | same |
|
||
| Fuzzy history search | <kbd>⌃ R</kbd> | same |
|
||
| Accept ghost suggestion | <kbd>→</kbd> | same |
|
||
| Completion menu | <kbd>⇥</kbd> | same |
|
||
|
||
On Windows and Linux plain <kbd>Ctrl V</kbd> also pastes at a shell prompt.
|
||
Inside a full-screen application — vim, less, tmux — it is passed through as
|
||
the key, so it means what the application says it means (blockwise Visual mode
|
||
in vim); paste there with <kbd>Ctrl ⇧ V</kbd> or <kbd>⇧ Insert</kbd>.
|
||
|
||
That convenience is the **Paste (outside full-screen apps)** binding, and it is
|
||
yours to move. Clearing it hands <kbd>Ctrl V</kbd> to the shell everywhere,
|
||
including readline's `quoted-insert`:
|
||
|
||
```json
|
||
{ "keybindings": { "AlternatePaste": "" } }
|
||
```
|
||
|
||
Putting Paste itself on the chord goes the other way, pasting on every screen
|
||
the way Windows Terminal does out of the box:
|
||
|
||
```json
|
||
{ "keybindings": { "PasteText": "ctrl-v" } }
|
||
```
|
||
|
||
Every <kbd>Ctrl</kbd> chord that stands for a control code reaches the program
|
||
you are running: <kbd>Ctrl 6</kbd> and <kbd>Ctrl ⇧ 6</kbd> are `^^` (vim's
|
||
alternate file), <kbd>Ctrl /</kbd> and <kbd>Ctrl ⇧ −</kbd> are `^_` (readline's
|
||
undo), <kbd>Ctrl 3</kbd> is Escape. The plain <kbd>Ctrl</kbd> chords tty7 keeps
|
||
are the ones that stand for nothing: <kbd>Ctrl ⇥</kbd> for the next tab, and on
|
||
Windows and Linux <kbd>Ctrl +</kbd> · <kbd>Ctrl −</kbd> · <kbd>Ctrl 0</kbd> for
|
||
the font size.
|
||
|
||
## Git and SSH
|
||
|
||
| Action | macOS | Windows / Linux |
|
||
|---|---|---|
|
||
| Commit (caret in the message box) | <kbd>⌘ ⏎</kbd> | <kbd>Ctrl ⏎</kbd> |
|
||
| Save (in the editor) | <kbd>⌘ S</kbd> | <kbd>Ctrl S</kbd> |
|
||
| Restart SSH Session | <kbd>⌘ ⇧ R</kbd> | <kbd>Ctrl ⇧ R</kbd> |
|
||
|
||
## Application
|
||
|
||
| Action | macOS | Windows / Linux |
|
||
|---|---|---|
|
||
| Settings | <kbd>⌘ ,</kbd> | <kbd>Ctrl ,</kbd> |
|
||
| Keyboard Shortcuts | <kbd>⌘ /</kbd> | — |
|
||
| Hide tty7 · Hide Others · Minimize | <kbd>⌘ H</kbd> · <kbd>⌘ ⌥ H</kbd> · <kbd>⌘ M</kbd> | — |
|
||
| Quit | <kbd>⌘ Q</kbd> | <kbd>Ctrl ⇧ Q</kbd> |
|
||
|
||
## Actions with no default key
|
||
|
||
All of these are in the command palette, and all are bindable under **Settings →
|
||
Keybindings**:
|
||
|
||
| Group | Actions |
|
||
|---|---|
|
||
| Tabs | `RenameTab` · `NewWorktreeTab` · `CloseOtherTabs` · `CloseTabsToTheRight` · `CopyWorkingDirectory` · `MarkTabUnread` · `ToggleTabSidebar` |
|
||
| Panes | `ResizePaneLeft/Right/Up/Down` · `SwapPaneNext` · `SwapPanePrev` |
|
||
| Workspaces | `SelectWorkspace1`…`SelectWorkspace9` · `RenameWorkspace` · `StopWorkspace` · `DeleteWorkspace` |
|
||
| Agents | `ForkAgentSession` (+ `Right` / `Left` / `Down` / `Up`) · `CopyAgentSessionId` |
|
||
| Git | `ScmStageAll` · `ScmUnstageAll` · `ScmDiscardAll` · `ScmCommitAmend` · `ScmRefresh` · `ScmSync` · `ScmPush` · `ScmPull` · `ScmFetch` · `ScmCheckoutBranch` · `ScmCreateBranch` · `ScmToggleGraph` · `ToggleDiffViewMode` |
|
||
| Panels | `ShowRightPanelInfo` · `ShowRightPanelChanges` · `ShowRightPanelFiles` |
|
||
| SSH | `ToggleSftp` · `ShowSshForwards` · `OpenSshProfiles` |
|
||
| Application | `About` · `CheckForUpdates` · `OpenDocumentation` · `OpenDiscord` · `ReportIssue` · `ShowAll` · `ZoomWindow` |
|
||
|
||
## Rebinding syntax
|
||
|
||
```json
|
||
{
|
||
"keybindings": {
|
||
"ResizePaneLeft": "ctrl-alt-left",
|
||
"ToggleSftp": "secondary-shift-u",
|
||
"ScmSync": "ctrl-b s"
|
||
}
|
||
}
|
||
```
|
||
|
||
`secondary` means <kbd>⌘</kbd> on macOS and <kbd>Ctrl</kbd> elsewhere. A space
|
||
separates the steps of a chord.
|
||
[More →](/customization/keybindings)
|