Imported as a linear vendor commit so forge rebases do not replay the upstream root tree. git-subtree-dir: third_party/pi git-subtree-split: 71023aec1546d6d677a65669c5665c0927ce0dd0
234 lines
8.9 KiB
Markdown
234 lines
8.9 KiB
Markdown
# Configure your terminal
|
|
|
|
Most modern terminals work with Pi without additional setup. Use this page when modified keys, scrolling, links, images, colors, or input-method editor (IME) positioning do not behave as expected.
|
|
|
|
Pi uses extended-key protocols so terminals can distinguish combinations such as `Shift+Enter` and `Alt+Enter` from plain `Enter`. Terminal proxies, multiplexers, and built-in IDE terminals can change or discard that information.
|
|
|
|
## Troubleshooting
|
|
|
|
| Symptom | Start here |
|
|
|---|---|
|
|
| `Shift+Enter` submits instead of inserting a line | Your terminal's section below; for tmux, see [Run Pi in tmux](tmux.md) |
|
|
| `Alt+Enter` does not queue a follow-up | [WezTerm](#wezterm), [Alacritty](#alacritty), or [Windows Terminal](#windows-terminal) |
|
|
| Fullscreen scrolling is unusually slow | [iTerm2](#iterm2) |
|
|
| Links work but show no hover preview | [Ghostty](#ghostty) |
|
|
| Inline images or colors are not detected | [Override detected capabilities](#override-detected-capabilities) |
|
|
| An IME candidate window appears in the wrong place | [WezTerm](#wezterm) or [IntelliJ IDEA](#intellij-idea-integrated-terminal) |
|
|
| Modified keys fail only inside tmux | [Run Pi in tmux](tmux.md) |
|
|
|
|
Use `/hotkeys` to inspect Pi's active shortcuts. See [Keybindings](keybindings.md) to change them.
|
|
|
|
## Kitty
|
|
|
|
Kitty supports the required keyboard protocol without additional configuration.
|
|
|
|
## iTerm2
|
|
|
|
Regular terminal mode works without additional configuration.
|
|
|
|
### Fix slow fullscreen scrolling
|
|
|
|
In fullscreen mode, Pi owns the viewport, so iTerm2 sends mouse-wheel reports instead of scrolling native terminal history. Fast trackpad gestures can then move only about one line at a time.
|
|
|
|
To change this behavior:
|
|
|
|
1. Open **iTerm2 > Settings > Advanced**.
|
|
2. Search for **Trackpad scrolls fast?**.
|
|
3. Set it to **No**.
|
|
|
|
This is an iTerm2-wide setting and can also change native trackpad scrolling. The underlying behavior is tracked in [iTerm2 issue 9619](https://gitlab.com/gnachman/iterm2/-/work_items/9619).
|
|
|
|
## Apple Terminal
|
|
|
|
Pi enables enhanced key reporting when available. If Terminal.app still sends plain Return for `Shift+Enter`, Pi uses a local macOS modifier fallback and treats it as `Shift+Enter`.
|
|
|
|
The fallback works only when Pi runs on the same Mac as Terminal.app. It cannot inspect the local modifier state when Pi runs on another machine over SSH.
|
|
|
|
## Ghostty
|
|
|
|
Add this mapping to Ghostty's configuration if `Alt+Backspace` does not work:
|
|
|
|
```text
|
|
keybind = alt+backspace=text:\x1b\x7f
|
|
```
|
|
|
|
The configuration file is `~/Library/Application Support/com.mitchellh.ghostty/config` on macOS and `~/.config/ghostty/config` on Linux.
|
|
|
|
Older Claude Code configurations may contain:
|
|
|
|
```text
|
|
keybind = shift+enter=text:\n
|
|
```
|
|
|
|
This sends a raw linefeed, which Pi cannot distinguish from `Ctrl+J`. Remove the mapping if an older Claude Code installation is the only reason you added it. Pi already binds `Ctrl+J` as a newline alternative, so the mapping may appear to work while still preventing Pi and tmux from receiving a real `Shift+Enter` event.
|
|
|
|
### Open links in fullscreen mode
|
|
|
|
Links remain clickable in fullscreen mode, but Ghostty does not show its normal hover underline or URL preview while Pi captures mouse input. Hold `Shift+Command` on macOS or `Shift+Ctrl` on Linux to use Ghostty's native link handling.
|
|
|
|
## WezTerm
|
|
|
|
WezTerm normally reports `Shift+Enter` through xterm extended keys. To enable the Kitty keyboard protocol explicitly, create `~/.wezterm.lua`:
|
|
|
|
```lua
|
|
local wezterm = require 'wezterm'
|
|
local config = wezterm.config_builder()
|
|
config.enable_kitty_keyboard = true
|
|
return config
|
|
```
|
|
|
|
### Forward Alt+Enter on macOS
|
|
|
|
WezTerm binds `Option+Enter` to fullscreen by default on macOS. To use it for Pi's follow-up queue, add this entry to your `config.keys` table:
|
|
|
|
```lua
|
|
{
|
|
key = 'Enter',
|
|
mods = 'ALT',
|
|
action = wezterm.action.SendString('\x1b[13;3u'),
|
|
}
|
|
```
|
|
|
|
A complete minimal configuration is:
|
|
|
|
```lua
|
|
local wezterm = require 'wezterm'
|
|
local config = wezterm.config_builder()
|
|
config.keys = {
|
|
{
|
|
key = 'Enter',
|
|
mods = 'ALT',
|
|
action = wezterm.action.SendString('\x1b[13;3u'),
|
|
},
|
|
}
|
|
return config
|
|
```
|
|
|
|
### Position an IME candidate window in WSL
|
|
|
|
If CJK IME candidates do not follow Pi's text cursor in WSL, show the hardware cursor:
|
|
|
|
```bash
|
|
export PI_HARDWARE_CURSOR=1
|
|
pi
|
|
```
|
|
|
|
You can instead set `showHardwareCursor` to `true` in Pi settings.
|
|
|
|
## Alacritty
|
|
|
|
Alacritty normally reports `Shift+Enter`. On macOS, `Option+Enter` can arrive as plain `Enter`. Add this to `~/.config/alacritty/alacritty.toml` to forward it to Pi:
|
|
|
|
```toml
|
|
[[keyboard.bindings]]
|
|
key = "Enter"
|
|
mods = "Alt"
|
|
chars = "\u001b[13;3u"
|
|
```
|
|
|
|
Restart Alacritty after changing the file.
|
|
|
|
## VS Code integrated terminal
|
|
|
|
VS Code 1.109.5 and newer enable the Kitty keyboard protocol in the integrated terminal by default.
|
|
|
|
For an older version, add a `Shift+Enter` terminal binding to `keybindings.json`:
|
|
|
|
```json
|
|
{
|
|
"key": "shift+enter",
|
|
"command": "workbench.action.terminal.sendSequence",
|
|
"args": { "text": "\u001b[13;2u" },
|
|
"when": "terminalFocus"
|
|
}
|
|
```
|
|
|
|
The user `keybindings.json` file is normally located at:
|
|
|
|
- macOS: `~/Library/Application Support/Code/User/keybindings.json`
|
|
- Linux: `~/.config/Code/User/keybindings.json`
|
|
- Windows: `%APPDATA%\\Code\\User\\keybindings.json`
|
|
|
|
## Zed integrated terminal
|
|
|
|
Add these bindings to Zed's `keymap.json`:
|
|
|
|
```json
|
|
{
|
|
"context": "Terminal",
|
|
"bindings": {
|
|
"shift-enter": ["terminal::SendText", "\u001b[13;2u"],
|
|
"ctrl--": ["terminal::SendText", "\u001b[45;5u"],
|
|
"ctrl-alt-]": ["terminal::SendText", "\u001b[93;7u"]
|
|
}
|
|
}
|
|
```
|
|
|
|
## Windows Terminal
|
|
|
|
Windows Terminal uses Pi's Windows and WSL shortcut defaults. See [Keybindings](keybindings.md) for the complete list.
|
|
|
|
### Forward Shift+Enter
|
|
|
|
Open Windows Terminal's `settings.json` with `Ctrl+Shift+,` or **Settings > Open JSON file**. Add this object to its `actions` array:
|
|
|
|
```json
|
|
{
|
|
"command": { "action": "sendInput", "input": "\u001b[13;2u" },
|
|
"keys": "shift+enter"
|
|
}
|
|
```
|
|
|
|
Fully close and reopen Windows Terminal, then verify that `Shift+Enter` inserts a new line in Pi.
|
|
|
|
### Use Alt+Enter for follow-ups
|
|
|
|
Windows Terminal binds `Alt+Enter` to fullscreen by default. Pi therefore uses `Ctrl+Q` for follow-ups on Windows and WSL.
|
|
|
|
To use `Alt+Enter` instead, configure Windows Terminal to forward the key and bind `app.message.followUp` to `alt+enter` in Pi's `keybindings.json`. See [Keybindings](keybindings.md#assign-keybindings).
|
|
|
|
## xfce4-terminal and Terminator
|
|
|
|
These terminals cannot reliably distinguish modified Enter keys from plain `Enter`. Custom bindings such as `Ctrl+Enter` or `Shift+Enter` therefore may not work.
|
|
|
|
Use a terminal with modern extended-key support when you need those shortcuts, such as Kitty, Ghostty, WezTerm, iTerm2, Windows Terminal, or a compatible Alacritty build.
|
|
|
|
## IntelliJ IDEA integrated terminal
|
|
|
|
IntelliJ IDEA's built-in terminal cannot reliably distinguish `Shift+Enter` from plain `Enter`. Use `Ctrl+J` for a newline or run Pi in a terminal with modern extended-key support.
|
|
|
|
If an IME candidate window does not follow the text cursor, show the hardware cursor:
|
|
|
|
```bash
|
|
export PI_HARDWARE_CURSOR=1
|
|
pi
|
|
```
|
|
|
|
## Override detected capabilities
|
|
|
|
Pi automatically detects OSC 8 hyperlinks, inline image protocols, and truecolor support. A terminal proxy or multiplexer can make that detection inaccurate.
|
|
|
|
| Capability | Environment variable | Setting |
|
|
|---|---|---|
|
|
| Hyperlinks | `PI_HYPERLINKS=1\|0\|auto` | `terminal.hyperlinks: true\|false\|"auto"` |
|
|
| Inline images | `PI_IMAGE_PROTOCOL=kitty\|iterm2\|none\|auto` | `terminal.images: "kitty"\|"iterm2"\|false\|"auto"` |
|
|
| Truecolor | `PI_TRUE_COLOR=1\|0\|auto` | `terminal.trueColor: true\|false\|"auto"` |
|
|
|
|
Settings take precedence over environment variables. An unset value or `auto` preserves automatic detection.
|
|
|
|
Only force a capability supported by the complete terminal path. Unsupported escape sequences can corrupt rendering. See [Environment Variables](environment-variables.md#pi-process-configuration) and [Settings](settings.md) for the canonical value definitions.
|
|
|
|
## Program status
|
|
|
|
Pi reports its state with the [Program Status Protocol (OSC 7501)](https://www.superlogical.com/rex/docs/build/program-status), so terminals and agent dashboards can show whether it is working, waiting for you, done, or failed:
|
|
|
|
| State | When |
|
|
|---|---|
|
|
| `working` | An agent run or compaction is in progress. The message is the session name. |
|
|
| `blocked` | An extension dialog or login waits for you. The message is the dialog title. |
|
|
| `done` | A run finished. The message is the session name. |
|
|
| `error` | A run ended with an error that is not retried. The message is the first line of the error. |
|
|
| `idle` | Pi started, or you cancelled the run. |
|
|
|
|
Reports never contain prompts or model output. Pi sends them only after the terminal answers the protocol's support query; tmux and screen do not forward them. Set `PI_PROGRAM_STATUS=1` to send reports without asking, or `PI_PROGRAM_STATUS=0` to turn them off.
|