1# Keybindings
2
3Customize shortcuts in **Settings → Keybindings** on web and desktop. That page
4also lists the command IDs and defaults available in your version.
5
6## Composer controls
7
8`mod+shift+d` starts dictation in the focused editor, or the composer, and finishes it on the next press;
9`Esc` discards the recording. Change the chord under **Composer: Start or Finish
10Dictation**, and the hold or toggle behavior in **Settings → Voice**. See
11[Voice input](./voice-input.md).
12
13In **Settings → Chat → Send shortcut**, choose whether Enter sends, requires
14`mod+Enter` for multiline prompts, or always requires `mod+Enter`. `Shift+Enter`
15inserts a new line. This applies to the web and desktop composer at desktop widths.
16
17**Follow-up behavior** chooses Queue or Steer while the agent runs. Use
18`mod+Enter` to do the opposite for one message, even when the send shortcut
19requires a modifier. `mod+Alt+Enter` sends, keeps that thread running in the
20background, and opens a fresh new-thread composer. In a new thread, `mod+Enter`
21does the same. Change these shortcuts in **Settings → Keybindings** under
22**Composer: Opposite Queue or Steer Action**, **Composer: Start in Background**,
23or **Composer: Send and Start New Thread**. These bindings take priority over the
24send shortcut. Click the send button to use the configured follow-up behavior.
25
26When a thread has queued messages, `mod+Shift+Enter` sends the first one as a steer
27while a turn is running, or as a new turn when the thread is stopped. Change it under
28**Queue: Send First Queued Message** in Keybindings.
29
30Use `mod+shift+m` to choose a model and `mod+shift+h` to choose a host.
31To step a new thread to the next machine instead of opening the menu, bind
32**Composer: Cycle Host** in Keybindings. It has no default shortcut.
33Use `mod+shift+e` for effort, `mod+shift+a` for permissions, `mod+shift+x` for the
34workspace, and `mod+shift+g` for the Git branch. The workspace menu includes the
35current checkout, a new worktree, and the previous worktree when available.
36Use `mod+shift+l` to reuse the previous worktree directly.
37
38To change effort one step without opening the picker, bind
39**Composer: Increase Effort** and **Composer: Decrease Effort** in Keybindings.
40Both are unbound by default. Increase wraps from the highest level to the
41lowest, and decrease wraps from the lowest level to the highest.
42
43In the model picker, press Left in an empty search field or Shift+Tab to reach
44the provider list. Use Up/Down to move and Enter to choose. Right returns to
45model search. Right at the end of the search moves to the highlighted model's effort
46levels, and Left comes back. Choosing a model keeps the picker open on its effort. `mod+shift+up` and `mod+shift+down` switch providers directly and clear the
47search. These provider shortcuts can also be changed in Settings.
48
49These shortcuts run inside the focused web or desktop client. `mod` uses Command
50on macOS and Ctrl on Windows and Linux, including GNOME, KDE Plasma, Niri, and
51Hyprland. If a custom desktop shortcut takes the same keys, choose another binding
52in Settings.
53
54## Copy pull request references
55
56With a PR open in the right panel or on the Pull requests page, use `mod+shift+c`
57to copy its URL and `mod+shift+k` to copy its number with a `#` prefix.
58Both shortcuts can be changed in Settings. Search for “Copy Link or Thread”
59or “Copy Number”. They copy the selected PR and leave terminal input alone.
60Without a PR, `mod+shift+c` copies the thread itself, which pastes into a
61composer as a thread chip.
62
63## Find in a diff
64
65Click into a diff in the Diff panel or a pull request's Code tab, then press
66`mod+f` to search every file in it, including folded files and unchanged lines
67hidden between changes. Enter and `Shift+Enter` move between matches, and a
68match in a folded file opens it. Escape closes the search. This shortcut is not
69configurable. A very large uncommitted diff loads its files as you scroll, and
70find only searches the files loaded so far.
71
72## iPad
73
74With a hardware keyboard, use `Cmd+1` through `Cmd+9` to open the first nine
75displayed threads. The shortcuts follow the current list filters and order.
76`Cmd+K` opens the command palette to search commands, projects, and threads.
77Use the arrow keys and Return to choose a result, or `Cmd+1` through `Cmd+9` to
78choose directly. Escape or `Cmd+K` closes the palette. Start a search with `>`
79to show only actions.
80
81In a new thread, `Cmd+Shift+H` moves the draft to the next machine.
82
83In the composer, Return sends and `Shift+Return` inserts a new line. While a
84turn is running, `Cmd+Return` sends with the other follow-up action. To make
85Return insert a new line instead, change the Return key behavior in Settings →
86Keyboard; `Cmd+Return` then sends.
87
88## Android
89
90With a hardware keyboard, the composer handles Return as on iPad, with `Ctrl` in
91place of `Cmd`. The on-screen keyboard's Return always inserts a new line.
92
93## Edit the configuration file
94
95Keybindings live on the environment's machine, in
96`~/.t3/userdata/keybindings.json` by default. You can edit this file directly.
97It is a JSON array of rules:
98
99```json
100[
101 { "key": "mod+g", "command": "terminal.toggle" },
102 { "key": "mod+shift+g", "command": "terminal.new", "when": "terminalFocus" }
103]
104```
105
106T3 Code creates the file with its defaults and adds new defaults on later startups.
107New defaults do not replace commands you customized. If a new default overlaps one
108of your shortcuts, [rule order](#precedence) decides which runs.
109Invalid rules are ignored; if the file cannot be parsed, T3 Code uses defaults.
110
111## Rule shape
112
113Each rule requires a `key` shortcut and a `command` ID. An optional `when`
114expression restricts when it runs.
115
116Project scripts use `script.{id}.run`, such as `script.test.run`.
117
118## Key syntax
119
120Join modifiers and a key with `+`, such as `mod+shift+d` or `ctrl+l`.
121`mod` means Command on macOS and Control elsewhere. Other modifiers are
122`cmd` / `meta`, `ctrl` / `control`, `alt` / `option`, and `shift`.
123
124## When conditions
125
126Available context keys are `terminalFocus`, `terminalOpen`, `previewFocus`,
127`previewOpen`, `rightPanelOpen`, `modelPickerOpen`, `usagePageOpen`, `composerFocus`,
128`draftThreadRoute`, `turnRunning`, `editableFocus`, `isWeb`, and `isDesktop`.
129`rightPanelOpen` applies only to `rightPanel.new` and is true while the right panel is
130open; the default `mod+t` uses it to open the panel's new-tab menu.
131`draftThreadRoute` is true on a draft thread, including a restored draft, until it is first sent.
132`editableFocus` is true while a text field, the composer, or another editor has
133the keyboard. `isWeb` is true in a browser tab. `isDesktop` is true in the
134desktop app. Unknown keys evaluate to `false`.
135
136`mod+1` through `mod+9` jump to the first nine threads, and to models while the
137model picker is open. The thread jumps do not run while the model picker is open.
138Those defaults use `isDesktop` so they do not steal the
139browser's tab-switch shortcuts. Remove that condition in Settings if you want
140the same jumps in a browser.
141
142Combine keys with `!` for not, `&&` for and, `||` for or, and parentheses:
143
144```json
145{ "key": "mod+j", "command": "terminal.toggle", "when": "terminalOpen && !terminalFocus" }
146```
147
148## Find in the current thread
149
150`chat.find` searches conversation messages and proposed plans in the active thread. Entering a
151query searches the entire thread, including older messages. Thread search requires server support;
152update an older server to enable it. Select **Retry** if a search fails. It defaults to
153`mod+f` outside terminals and previews. Press **Enter** or **Shift+Enter** to move between matches,
154and **Escape** to close find.
155
156## Find on a browser page
157
158`preview.find` (`mod+f` while a browser has focus) searches the open page in the desktop app. It
159is also in the browser's **⋮** menu and the command palette. A page that handles `mod+f` itself,
160such as a code editor, keeps its own find. Use the **⋮** menu to reach the browser's find there.
161Streamed browser tabs and T3 Code in a web browser do not support it.
162
163## Precedence
164
165The last rule whose key and condition both match wins, even if it belongs to a
166different command. Put a more specific rule after a general one when they share
167a shortcut.
168
169## Commands with special behavior
170
171`thread.stop` interrupts the running turn in the focused thread. It has no default
172shortcut; assign one in **Settings → Keybindings**.
173
174`thread.regenerateTitle` generates a new title for the focused thread, like
175**Regenerate title** in the thread menu. It has no default shortcut.
176
177`thread.undo` (`mod+z` by default) reverses the actions shown in the notice at the
178bottom of the sidebar, such as unpin, settle, snooze, archive, or discarding a
179draft. Consecutive
180actions of the same kind undo together. The notice remains available for five
181seconds after the latest action. Right after an action, the shortcut works even
182in a text field such as the composer. Once you type or press another key, the
183field gets its own undo back. Terminals always keep their native shortcut.
184
185`navigation.back` (`mod+[` by default) and `navigation.forward` (`mod+]`) move
186through the pages you have visited, like a browser's back and forward buttons.
187
188`chat.new` may ask you to choose a project when there is more than one.
189`chat.newLocal` skips that chooser. Both use your
190[new-thread defaults](./thread-sidebar.md#start-a-thread). `chat.newWithoutProject`
191(`mod+alt+n`) starts a thread [without a project](./thread-sidebar.md#start-without-a-project).
192
193## Reserved shortcuts
194
195In the desktop app, `mod+w` closes the focused terminal or the active right-panel
196tab. When nothing remains to close, it does nothing; it never closes the window. In a browser, `mod+w`
197closes the browser tab; rebind `rightPanel.close` and `terminal.close` to an available
198shortcut such as `alt+w`.
199
200`mod+shift+t` reopens the last closed tab across the app, including files,
201diffs, pull requests, browsers, and devices, in the order you closed them.
202A browser opens in a fresh session without its old page history. Incognito tabs
203can reopen until you reload or quit the app. This shortcut does not undo deleted work.
204Browsers also use it to reopen browser tabs; choose another binding in Settings
205if the browser takes it first.
206
207Many defaults include `!terminalFocus` so they do not intercept terminal input.
208Keep that condition when remapping them if you want the same behavior.
209
210## Desktop quit shortcut
211
212Use `Cmd+Q` on macOS or `Ctrl+Q` on Windows and Linux. In the default **Hold** mode,
213hold for 1.2 seconds or press twice within 500 milliseconds. Holding requires
214keyboard repeat; if repeat is disabled, use two presses or the application menu.
215
216Change **Settings → General → Confirmations → Quit shortcut** to **Direct** for a
217single press or **Double press** for two presses only. Choosing **Quit** from the
218application menu always quits immediately.