mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-09-21 16:02:20 +00:00
Found by driving a dev instance and measuring what an idle window costs. Two of them were frame loops that never stopped. A `Head` diff overlay calls itself stale when the cached git status disagrees with the snapshot on screen, and every landed probe wakes that check by touching the cache — but the read published its counts and left the branch behind, so a branch switched outside tty7 made the disagreement permanent: two `git` processes a lap, forever, with `refreshing…` pinned to the header and an idle window at 7% of a core. And the home page asked for a frame sixty times a second to change one glyph's opacity twice, which made a window with nothing open in it eight times more expensive than one running a shell. Both now settle: the diff read publishes the branch it found, and the home cursor flips a bool on a timer the way the terminal's own does. The rest: - The tab sidebar and the right panel each capped themselves at half the window and knew nothing about the other, so together they could take all of it — 260 points of terminal on a 720-point window. Both now cap at whichever binds harder: half the window, or what is left after the terminal's floor and the other panel's floor. The same cap bounds the drag, so a panel dragged to its limit stays where it was dropped. - Only a HEAD diff may correct the sidebar's counts. Those numbers mean `git diff --numstat HEAD`; an unstaged or staged patch answers a smaller question, so opening an untracked file from the Source Control panel took the staged lines off the total on the click. - An untracked row in the diff overlay had no click target, and once focused could not be left — the breadcrumb looks the path up in `files`, where an untracked file has no entry. Both ends fixed. - A new pane keeps the name its directory was reached by. `cwd()` alone loses it: the shell falls back to `getcwd()`, so `/tmp/x` became `/private/tmp/x` in every tab opened from the first. `PWD` carries it, and POSIX has the shell discard a `PWD` that names the wrong directory, so this can correct the name and cannot invent one. - The settings search now sees into the Keybindings page, which is generated from the binding table rather than the static index — so searching for a feature finds its shortcut, and the page filters to the matches. Closes #444. - The settings reading column is centred rather than pinned to the nav: on a window as wide as the display it was made for, 640 points of settings sat beside 1600 points of nothing. - `New Workspace…` takes the ellipsis its three sibling actions already carry — it opens a form asking for a name and a host. Every fix has a test. The re-probe loop is pinned end-to-end with `render_probe::draws() == 0` against a real repository, confirmed to fail on the old behaviour before it was kept.
99 lines
3.6 KiB
Plaintext
99 lines
3.6 KiB
Plaintext
---
|
|
title: "Keybindings"
|
|
description: "Rebinding anything, chord sequences, and the tmux preset."
|
|
---
|
|
|
|
**Settings → Keybindings** (<kbd>⌘ ,</kbd>) lists every shortcut in the app,
|
|
grouped the same way the command palette is. The search box at the top of
|
|
Settings reaches this page too: type what a feature is called — `split`,
|
|
`commit`, `sftp` — and the page narrows to the shortcuts for it. Action names
|
|
work as well as labels, so a binding you read about in `keybindings.json` is
|
|
one search away from the row that sets it.
|
|
|
|
## Rebinding
|
|
|
|
Click a shortcut and press the new keys. It saves after a brief pause.
|
|
|
|
| | |
|
|
|---|---|
|
|
| Press keys | Set the binding |
|
|
| Press more keys | Chain a sequence — <kbd>⌃ B</kbd> then <kbd>X</kbd> |
|
|
| <kbd>Esc</kbd> | Cancel |
|
|
| <kbd>⌫</kbd> | Remove the last key — or, pressed first, reset the shortcut to its default |
|
|
|
|
**Restore all defaults** at the bottom undoes every rebinding at once. There is
|
|
no undo for that one.
|
|
|
|
<Frame caption="Placeholder — screenshot: the Keybindings page mid-capture, showing “Press keys…”">
|
|
<img src="/images/placeholder.svg" alt="Rebinding a shortcut" />
|
|
</Frame>
|
|
|
|
## Actions with no default key
|
|
|
|
Some actions ship deliberately unbound, because there is no obvious key left to
|
|
take: pane resize and swap, workspace selection, most git commands, SFTP, and
|
|
the panel tabs. They are all in the command palette, and all bindable here.
|
|
|
|
## Editing `config.json` instead
|
|
|
|
```json
|
|
{
|
|
"keybindings": {
|
|
"SplitRight": "cmd-d",
|
|
"ResizePaneLeft": "ctrl-alt-left",
|
|
"ToggleSftp": "cmd-shift-u"
|
|
}
|
|
}
|
|
```
|
|
|
|
The syntax is modifiers joined by `-`, then the key. Chords are separated by a
|
|
space.
|
|
|
|
| Token | Means |
|
|
|---|---|
|
|
| `secondary` | <kbd>⌘</kbd> on macOS, <kbd>Ctrl</kbd> elsewhere |
|
|
| `cmd` · `ctrl` · `alt` · `shift` | Literal modifiers |
|
|
| `ctrl-b n` | A two-key sequence |
|
|
|
|
An unknown action name or an invalid keystroke is skipped with a warning in the
|
|
log rather than breaking the rest of your bindings.
|
|
|
|
The full action list is on the [keyboard shortcuts](/reference/keyboard-shortcuts)
|
|
page.
|
|
|
|
## The tmux preset
|
|
|
|
**Settings → Keybindings → Preset → tmux** remaps pane and tab actions onto a
|
|
prefix — <kbd>⌃ B</kbd> by default, changeable in the **Prefix** field beside
|
|
it.
|
|
|
|
| | |
|
|
|---|---|
|
|
| <kbd>⌃ B</kbd> <kbd>C</kbd> · <kbd>X</kbd> | New tab · close tab |
|
|
| <kbd>⌃ B</kbd> <kbd>%</kbd> · <kbd>"</kbd> | Split right · split down |
|
|
| <kbd>⌃ B</kbd> <kbd>←→↑↓</kbd> | Move focus |
|
|
| <kbd>⌃ B</kbd> <kbd>⌃ ←→↑↓</kbd> | Resize the pane |
|
|
| <kbd>⌃ B</kbd> <kbd>O</kbd> · <kbd>;</kbd> | Next pane · previous pane |
|
|
| <kbd>⌃ B</kbd> <kbd>{</kbd> · <kbd>}</kbd> | Swap with the previous · next pane |
|
|
| <kbd>⌃ B</kbd> <kbd>Z</kbd> | Zoom the pane |
|
|
| <kbd>⌃ B</kbd> <kbd>N</kbd> · <kbd>P</kbd> | Next tab · previous tab |
|
|
| <kbd>⌃ B</kbd> <kbd>1</kbd>…<kbd>9</kbd> | Jump to a tab |
|
|
|
|
Two details that make it livable:
|
|
|
|
- A **bare prefix** reaches the shell after about a second, so <kbd>⌃ B</kbd>
|
|
still works as "back one character" when you meant it.
|
|
- **Prefix plus an unbound key** is passed straight through to the terminal, so
|
|
a tmux binding you did not remap still lands in whatever is running.
|
|
|
|
## Some non-obvious defaults
|
|
|
|
| | |
|
|
|---|---|
|
|
| <kbd>⇧ ⏎</kbd> · <kbd>⌥ ⏎</kbd> | Insert a newline at the prompt instead of submitting (`InsertNewline`) |
|
|
| <kbd>⌘ ⇧ ⏎</kbd> | Zoom the focused pane |
|
|
| <kbd>⌘ ⇧ E</kbd> | Toggle the code panel |
|
|
| <kbd>⌘ ⇧ R</kbd> | Restart the SSH session in this pane |
|
|
| <kbd>⌘ ⇧ O</kbd> | Workspace switcher |
|
|
| <kbd>⌘ ⇧ N</kbd> | New workspace |
|