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