Skip to main content
T3 Code supports fully customizable keyboard shortcuts through a JSON configuration file. You can override default keybindings or add new ones for project scripts.

Configuration File

Keybindings are configured in:
~/.t3/keybindings.json
If you’ve set a custom T3CODE_STATE_DIR, the keybindings file will be located at $T3CODE_STATE_DIR/keybindings.json.

File Format

The configuration file must be a JSON array of keybinding rules:
keybindings.json
[
  { "key": "mod+j", "command": "terminal.toggle" },
  { "key": "mod+d", "command": "terminal.split", "when": "terminalFocus" },
  { "key": "mod+n", "command": "chat.new", "when": "!terminalFocus" }
]

Rule Schema

Each keybinding rule has the following structure:
key
string
required
The keyboard shortcut string.Format: modifier+modifier+keyExamples:
  • mod+j
  • ctrl+shift+k
  • cmd+alt+d
command
string
required
The command to execute when the shortcut is pressed.See Available Commands below.
when
string
Optional boolean expression that determines when the shortcut is active.See When Conditions below.

Available Commands

Terminal Commands

Open or close the terminal drawer.
{ "key": "mod+j", "command": "terminal.toggle" }
Split the current terminal into a new pane.Best used with when: "terminalFocus" to only activate when terminal is focused.
{ "key": "mod+d", "command": "terminal.split", "when": "terminalFocus" }
Create a new terminal tab.Best used with when: "terminalFocus" to avoid conflicts.
{ "key": "mod+t", "command": "terminal.new", "when": "terminalFocus" }
Close or kill the focused terminal.Best used with when: "terminalFocus" to only activate when terminal is focused.
{ "key": "mod+w", "command": "terminal.close", "when": "terminalFocus" }

Chat Commands

Create a new chat thread that preserves the active thread’s branch and worktree state.Best used with when: "!terminalFocus" to avoid conflicts with terminal commands.
{ "key": "mod+n", "command": "chat.new", "when": "!terminalFocus" }
Create a new local chat thread for the active project without worktree context.
{ "key": "mod+shift+n", "command": "chat.newLocal", "when": "!terminalFocus" }

Editor Commands

Open the current project or worktree in your last-used external editor.
{ "key": "mod+o", "command": "editor.openFavorite" }

Diff Commands

Toggle the diff viewer.
{ "key": "mod+d", "command": "diff.toggle", "when": "!terminalFocus" }

Project Script Commands

Run a project script by its ID.The script ID must match a script configured in your project settings. The ID must:
  • Be 1-24 characters long
  • Start with a lowercase letter or digit
  • Contain only lowercase letters, digits, and hyphens
[
  { "key": "mod+shift+t", "command": "script.test.run" },
  { "key": "mod+shift+b", "command": "script.build.run" },
  { "key": "mod+shift+l", "command": "script.lint.run" }
]

Key Syntax

Modifiers

T3 Code supports the following modifier keys:
mod
modifier
Platform-specific modifier:
  • Cmd on macOS
  • Ctrl on Windows/Linux
This is the recommended modifier for cross-platform shortcuts.
cmd
modifier
Command key (⌘) on macOS, ignored on other platforms.Alias: meta
ctrl
modifier
Control key on all platforms.Alias: control
shift
modifier
Shift key on all platforms.
alt
modifier
Alt key (⌥ on macOS) on all platforms.Alias: option

Special Keys

{ "key": "mod+a", "command": "..." }
{ "key": "mod+1", "command": "..." }
To bind the + key itself, use a trailing + in your shortcut: "mod+" (note the empty modifier after the plus).

When Conditions

The when field accepts boolean expressions to control when a keybinding is active.

Context Keys

terminalFocus
boolean
True when a terminal pane has keyboard focus.
terminalOpen
boolean
True when the terminal drawer is open.
Unknown context keys evaluate to false.

Operators

{
  "key": "mod+n",
  "command": "chat.new",
  "when": "!terminalFocus"
}

Precedence Rules

When multiple keybinding rules match a keyboard event:
  1. Rules are evaluated in array order (top to bottom)
  2. The last matching rule wins where both key matches AND when evaluates to true
  3. Precedence is across all commands, not just within the same command
Example:
[
  { "key": "mod+n", "command": "terminal.new", "when": "terminalFocus" },
  { "key": "mod+n", "command": "chat.new", "when": "!terminalFocus" }
]
In this example:
  • mod+n creates a new terminal when terminal is focused
  • mod+n creates a new chat when terminal is not focused

Default Keybindings

T3 Code ships with these default keybindings:
Default Keybindings
[
  { "key": "mod+j", "command": "terminal.toggle" },
  { "key": "mod+d", "command": "terminal.split", "when": "terminalFocus" },
  { "key": "mod+n", "command": "terminal.new", "when": "terminalFocus" },
  { "key": "mod+w", "command": "terminal.close", "when": "terminalFocus" },
  { "key": "mod+d", "command": "diff.toggle", "when": "!terminalFocus" },
  { "key": "mod+n", "command": "chat.new", "when": "!terminalFocus" },
  { "key": "mod+shift+o", "command": "chat.new", "when": "!terminalFocus" },
  { "key": "mod+shift+n", "command": "chat.newLocal", "when": "!terminalFocus" },
  { "key": "mod+o", "command": "editor.openFavorite" }
]
When you override a command in your custom configuration, the default keybinding for that command is automatically removed.

Configuration Validation

T3 Code validates your keybindings configuration:
  • Invalid rules are ignored - The server logs warnings for invalid entries
  • Invalid files are ignored - If the entire file is malformed, defaults are used
  • Maximum 256 keybindings - Exceeding the limit truncates oldest entries

Common Validation Errors

// ❌ Invalid - empty modifiers
{ "key": "mod++", "command": "terminal.toggle" }

// ✅ Valid - trailing plus for + key
{ "key": "mod+", "command": "terminal.toggle" }
// ❌ Invalid - unknown command
{ "key": "mod+x", "command": "unknown.command" }

// ❌ Invalid - script ID too long
{ "key": "mod+s", "command": "script.very-long-script-id-exceeding-limit.run" }

// ✅ Valid
{ "key": "mod+t", "command": "script.test.run" }
// ❌ Invalid - syntax error
{ "key": "mod+k", "command": "terminal.close", "when": "terminalFocus &&" }

// ✅ Valid
{ "key": "mod+k", "command": "terminal.close", "when": "terminalFocus" }

Live Reloading

Keybindings are watched for changes:
  1. Edit ~/.t3/keybindings.json
  2. Save the file
  3. Changes are automatically applied
  4. Invalid changes are logged to the server console
No server restart required! Changes take effect immediately.

Example Configurations

VS Code Style

VS Code-like keybindings
[
  { "key": "ctrl+`", "command": "terminal.toggle" },
  { "key": "ctrl+shift+5", "command": "terminal.split", "when": "terminalFocus" },
  { "key": "ctrl+shift+`", "command": "terminal.new", "when": "terminalFocus" },
  { "key": "ctrl+k", "command": "chat.new", "when": "!terminalFocus" },
  { "key": "ctrl+p", "command": "editor.openFavorite" }
]

Vim-inspired

Vim-style keybindings
[
  { "key": "mod+shift+;", "command": "terminal.toggle" },
  { "key": "mod+shift+s", "command": "terminal.split", "when": "terminalFocus" },
  { "key": "mod+shift+n", "command": "chat.new", "when": "!terminalFocus" },
  { "key": "mod+shift+o", "command": "editor.openFavorite" }
]

Project Scripts

Development workflow
[
  { "key": "mod+shift+t", "command": "script.test.run" },
  { "key": "mod+shift+b", "command": "script.build.run" },
  { "key": "mod+shift+l", "command": "script.lint.run" },
  { "key": "mod+shift+d", "command": "script.dev.run" },
  { "key": "f5", "command": "script.debug.run" }
]

Troubleshooting

Keybinding Not Working

  1. Check the server console for validation errors
  2. Verify the command name is correct
  3. Check if another rule with higher precedence is matching
  4. Ensure the when condition is met

File Not Being Watched

# Check file location
echo ~/.t3/keybindings.json

# Verify state directory
# If you set T3CODE_STATE_DIR, use that instead
ls -la ~/.t3/

# Check file permissions
chmod 644 ~/.t3/keybindings.json

Reset to Defaults

# Delete your custom keybindings
rm ~/.t3/keybindings.json

# Restart the server
# Defaults will be automatically restored

Limits and Constraints

Maximum keybindings
256
Configuration is truncated to the last 256 entries if exceeded.
Maximum key length
64 characters
Key strings longer than 64 characters are rejected.
Maximum when length
256 characters
When expressions longer than 256 characters are rejected.
Maximum expression depth
64 levels
When expressions deeper than 64 nested levels are rejected.
Maximum script ID length
24 characters
Script IDs in script.{id}.run commands must be 24 characters or less.

Project Scripts

Configure project scripts for keybindings

Server Options

Server configuration and CLI flags

Build docs developers (and LLMs) love