# 快捷键

> 自定义 pi 的全部键盘快捷键：按键格式、动作清单与 Emacs/Vim 配置示例。

---

LLMS 索引： [llms.txt](/llms.txt)

---

所有键盘快捷键都可以通过 `~/.pi/agent/keybindings.json` 自定义。每个动作可以绑定一个或多个按键。

该配置文件使用与 pi 内部以及扩展作者在 `keyHint()` 和注入的 `keybindings` 管理器中相同的带命名空间快捷键 ID。

使用 `cursorUp` 或 `expandTools` 等旧版无命名空间 ID 的配置会在启动时自动迁移为带命名空间的 ID。

编辑 `keybindings.json` 后，在 pi 中运行 `/reload` 即可应用更改，无需重启会话。

## 按键格式 {#key-format}

格式为 `modifier+key`，其中修饰键为 `ctrl`、`shift`、`alt`、`super`（可组合），按键包括：

- **字母：** `a-z`
- **数字：** `0-9`
- **特殊键：** `escape`、`esc`、`enter`、`return`、`tab`、`space`、`backspace`、`delete`、`insert`、`clear`、`home`、`end`、`pageUp`、`pageDown`、`up`、`down`、`left`、`right`
- **功能键：** `f1`-`f12`
- **符号：** `` ` ``、`-`、`=`、`[`、`]`、`\`、`;`、`'`、`,`、`.`、`/`、`!`、`@`、`#`、`$`、`%`、`^`、`&`、`*`、`(`、`)`、`_`、`+`、`|`、`~`、`{`、`}`、`:`、`<`、`>`、`?`

修饰键组合：`ctrl+shift+x`、`alt+ctrl+x`、`ctrl+shift+alt+x`、`super+k`、`ctrl+super+k`、`ctrl+1` 等。

`super` 绑定要求终端能够单独上报该修饰键，通常需要 Kitty 键盘协议。在不支持的终端中可能无法工作。

## 全部动作 {#all-actions}

### TUI 编辑器光标移动 {#tui-editor-cursor-movement}

| 快捷键 ID | 默认值 | 说明 |
|--------|---------|-------------|
| `tui.editor.cursorUp` | `up` | 光标上移，到达顶部后浏览更早的历史 |
| `tui.editor.cursorDown` | `down` | 光标下移，到达底部后浏览更新的历史 |
| `tui.editor.historyPrevious` | *（无）* | 选择上一条提示词历史 |
| `tui.editor.historyNext` | *（无）* | 选择下一条提示词历史 |
| `tui.editor.cursorLeft` | `left`、`ctrl+b` | 光标左移 |
| `tui.editor.cursorRight` | `right`、`ctrl+f` | 光标右移 |
| `tui.editor.cursorWordLeft` | `alt+left`、`ctrl+left`、`alt+b` | 光标左移一个单词 |
| `tui.editor.cursorWordRight` | `alt+right`、`ctrl+right`、`alt+f` | 光标右移一个单词 |
| `tui.editor.cursorLineStart` | `home`、`ctrl+home`、`ctrl+a` | 移动到行首 |
| `tui.editor.cursorLineEnd` | `end`、`ctrl+end`、`ctrl+e` | 移动到行尾 |
| `tui.editor.jumpForward` | `ctrl+]` | 向前跳转到指定字符 |
| `tui.editor.jumpBackward` | `ctrl+alt+]` | 向后跳转到指定字符 |
| `tui.editor.pageUp` | `pageUp`、`ctrl+pageUp` | 向上翻页 |
| `tui.editor.pageDown` | `pageDown`、`ctrl+pageDown` | 向下翻页 |

专用的历史动作始终切换历史条目，与多行提示词中的光标位置无关。当主编辑器获得焦点时，显式的历史绑定优先于应用动作，因此将 `tui.editor.historyPrevious` 绑定到 `ctrl+p` 只会在该上下文中覆盖模型循环切换，而不会改变选择器中的 `Ctrl+P`。

### TUI 编辑器删除 {#tui-editor-deletion}

| 快捷键 ID | 默认值 | 说明 |
|--------|---------|-------------|
| `tui.editor.deleteCharBackward` | `backspace` | 向后删除一个字符 |
| `tui.editor.deleteCharForward` | `delete`、`ctrl+d` | 向前删除一个字符 |
| `tui.editor.deleteWordBackward` | `ctrl+w`、`alt+backspace` | 向后删除一个单词 |
| `tui.editor.deleteWordForward` | `alt+d`、`alt+delete` | 向前删除一个单词 |
| `tui.editor.deleteToLineStart` | `ctrl+u` | 删除到行首 |
| `tui.editor.deleteToLineEnd` | `ctrl+k` | 删除到行尾 |

### TUI 输入 {#tui-input}

| 快捷键 ID | 默认值 | 说明 |
|--------|---------|-------------|
| `tui.input.newLine` | `shift+enter`、`ctrl+j` | 插入新行 |
| `tui.input.submit` | `enter` | 提交输入 |
| `tui.input.tab` | `tab` | Tab / 自动补全 |

### TUI 剪切环 {#tui-kill-ring}

| 快捷键 ID | 默认值 | 说明 |
|--------|---------|-------------|
| `tui.editor.yank` | `ctrl+y` | 粘贴最近删除的文本 |
| `tui.editor.yankPop` | `alt+y` | 在粘贴后循环切换已删除的文本 |
| `tui.editor.undo` | `ctrl+-`（Windows 上为 `ctrl+z`；WSL 上为 `alt+z`） | 撤销上次编辑 |

### TUI 剪贴板与选择 {#tui-clipboard-and-selection}

| 快捷键 ID | 默认值 | 说明 |
|--------|---------|-------------|
| `tui.input.copy` | `ctrl+c` | 复制选区 |
| `tui.select.up` | `up` | 选区上移 |
| `tui.select.down` | `down` | 选区下移 |
| `tui.select.pageUp` | `pageUp` | 列表中向上翻页 |
| `tui.select.pageDown` | `pageDown` | 列表中向下翻页 |
| `tui.select.confirm` | `enter` | 确认选择 |
| `tui.select.cancel` | `escape`、`ctrl+c` | 取消选择 |

### TUI 全屏视口 {#tui-fullscreen-viewport}

这些动作在交互模式使用 `--tui-mode fullscreen` 时生效，作用于主对话记录滚动区域。双指触控板和鼠标滚轮输入会滚动指针所在区域；当指针位于固定的编辑器/状态栏/底部栏停靠区上时，则回退为滚动对话记录。点击 OSC 8 超链接会用默认处理器打开它。按住主鼠标键拖动会选择文本并复制到剪贴板；在对话记录的上、下边缘按住不动时会自动滚动到屏幕外的内容。对话记录向上滚动时，其底部行会显示可点击的 "Jump to latest message" 标签，展示 `tui.altScreen.bottom` 快捷键。各终端专属的鼠标与触控行为参见[终端设置](/book/pi/terminal-setup/)。

全屏对话记录绑定优先于编辑器绑定。因此在全屏模式下，默认的无修饰导航键控制对话记录，而它们的 `ctrl` 变体继续控制编辑器。在非全屏模式下，两种变体都控制编辑器。

对话记录搜索面板会显示已配置的上一个/下一个快捷键以及可点击的箭头控件。再次按下 `tui.altScreen.search`，或使用 `tui.altScreen.searchClose`，即可关闭它。

| 按键 | 默认模式 | 全屏模式 |
|-----|--------------|-----------------|
| `home`、`end` | 编辑器 | 对话记录 |
| `ctrl+home`、`ctrl+end` | 编辑器 | 编辑器 |
| `pageUp`、`pageDown` | 编辑器 | 对话记录 |
| `ctrl+pageUp`、`ctrl+pageDown` | 编辑器 | 编辑器 |

这一路由仍可通过常规的动作绑定进行配置。例如，`"tui.altScreen.pageUp": "ctrl+pageUp"` 会让全屏模式下的 `pageUp` 控制编辑器、`ctrl+pageUp` 控制对话记录。绑定 `tui.altScreen.halfPageUp` 和 `tui.altScreen.halfPageDown` 可以按半页步进，绑定 `tui.altScreen.lineUp` 和 `tui.altScreen.lineDown` 可以按单行步进。设置 `"tui.altScreen.pageUp": []` 会完全禁用该对话记录快捷键。用户绑定会替换该动作的默认值。

| 快捷键 ID | 默认值 | 说明 |
|--------|---------|-------------|
| `tui.altScreen.pageUp` | `pageUp` | 将对话记录向上滚动一页 |
| `tui.altScreen.pageDown` | `pageDown` | 将对话记录向下滚动一页 |
| `tui.altScreen.halfPageUp` | *（无）* | 将对话记录向上滚动半页 |
| `tui.altScreen.halfPageDown` | *（无）* | 将对话记录向下滚动半页 |
| `tui.altScreen.lineUp` | *（无）* | 将对话记录向上滚动一行 |
| `tui.altScreen.lineDown` | *（无）* | 将对话记录向下滚动一行 |
| `tui.altScreen.previousPrompt` | `ctrl+shift+up`、`ctrl+up`（Windows 和 WSL 上仅为 `ctrl+up`） | 跳转到上一个标记消息 |
| `tui.altScreen.nextPrompt` | `ctrl+shift+down`、`ctrl+down`（Windows 和 WSL 上仅为 `ctrl+down`） | 跳转到下一个标记消息 |
| `tui.altScreen.search` | `ctrl+shift+f`（Windows 和 WSL 上为 `ctrl+f`） | 搜索渲染后的对话记录 |
| `tui.altScreen.searchNext` | `enter`、`ctrl+g` | 搜索时选择下一个匹配项 |
| `tui.altScreen.searchPrevious` | `shift+enter`、`ctrl+shift+g` | 搜索时选择上一个匹配项 |
| `tui.altScreen.searchClose` | `escape` | 关闭对话记录搜索 |
| `tui.altScreen.top` | `home` | 滚动到对话记录开头 |
| `tui.altScreen.bottom` | `end` | 滚动到对话记录末尾并跟随新输出 |

### 应用 {#application}

| 快捷键 ID | 默认值 | 说明 |
|--------|---------|-------------|
| `app.interrupt` | `escape` | 取消 / 中止 |
| `app.clear` | `ctrl+c` | 清空编辑器（第一次）/ 退出（第二次） |
| `app.exit` | `ctrl+d` | 退出（编辑器为空时） |
| `app.suspend` | `ctrl+z`（Windows 上无） | 挂起到后台 |
| `app.editor.external` | `ctrl+g` | 在外部编辑器中打开（`externalEditor`、`$VISUAL`、`$EDITOR`、Windows 上的记事本或其他平台上的 `nano`） |
| `app.clipboard.pasteImage` | `ctrl+v`（Windows 和 WSL 上为 `alt+v`） | 从剪贴板粘贴图片或文本 |

### 会话 {#sessions}

| 快捷键 ID | 默认值 | 说明 |
|--------|---------|-------------|
| `app.session.new` | *（无）* | 开始新会话（`/new`） |
| `app.session.tree` | *（无）* | 打开会话树导航器（`/tree`） |
| `app.session.fork` | *（无）* | 分叉当前会话（`/fork`） |
| `app.session.resume` | *（无）* | 打开会话恢复选择器（`/resume`） |
| `app.session.togglePath` | `ctrl+p` | 切换路径显示 |
| `app.session.toggleSort` | `ctrl+s` | 切换排序方式 |
| `app.session.toggleNamedFilter` | `ctrl+n` | 切换"仅已命名"过滤器 |
| `app.session.rename` | `ctrl+r` | 重命名会话 |
| `app.session.delete` | `ctrl+d` | 删除会话 |
| `app.session.deleteNoninvasive` | `ctrl+backspace` | 查询为空时删除会话 |

### 模型与思考 {#models-and-thinking}

| 快捷键 ID | 默认值 | 说明 |
|--------|---------|-------------|
| `app.model.select` | `ctrl+l` | 打开模型选择器 |
| `app.model.cycleForward` | `ctrl+p` | 循环切换到下一个模型 |
| `app.model.cycleBackward` | `shift+ctrl+p`（Windows 和 WSL 上为 `alt+p`） | 循环切换到上一个模型 |
| `app.models.save` | `ctrl+s` | 将选定的默认模型或范围模型配置保存到设置 |
| `app.thinking.cycle` | `shift+tab` | 循环切换思考级别 |
| `app.thinking.save` | `ctrl+s` | 将当前思考级别保存到设置 |
| `app.thinking.toggle` | `ctrl+t` | 折叠或展开思考块 |

### 显示与消息队列 {#display-and-message-queue}

| 快捷键 ID | 默认值 | 说明 |
|--------|---------|-------------|
| `app.tools.expand` | `ctrl+o` | 折叠或展开工具输出 |
| `app.message.copy` | `ctrl+x` | 在 `/tree` 中复制选中的消息；否则复制上一条助手消息；当 `fullscreenCopyOnSelect` 禁用时，复制全屏模式下活动的文本选区 |
| `app.message.followUp` | `alt+enter`（Windows 和 WSL 上为 `ctrl+q`） | 将后续消息加入队列 |
| `app.message.dequeue` | `alt+up`（Windows 和 WSL 上为 `alt+q`） | 将排队消息恢复到编辑器 |

### 树状导航 {#tree-navigation}

| 快捷键 ID | 默认值 | 说明 |
|--------|---------|-------------|
| `app.tree.foldOrUp` | `ctrl+left`、`alt+left` | 折叠当前分支段，或跳转到上一段起点 |
| `app.tree.unfoldOrDown` | `ctrl+right`、`alt+right` | 展开当前分支段，或跳转到下一段起点或分支末尾 |
| `app.tree.editLabel` | `shift+l` | 编辑所选树节点的标签 |
| `app.tree.toggleLabelTimestamp` | `shift+t` | 切换树中标签时间戳的显示 |
| `app.tree.filter.default` | `ctrl+d` | 将树过滤器设为默认视图 |
| `app.tree.filter.noTools` | `ctrl+t` | 切换隐藏工具结果的树过滤器 |
| `app.tree.filter.userOnly` | `ctrl+u` | 切换仅显示用户消息的树过滤器 |
| `app.tree.filter.labeledOnly` | `ctrl+l` | 切换仅显示已标记条目的树过滤器 |
| `app.tree.filter.all` | `ctrl+a` | 切换显示所有条目的树过滤器 |
| `app.tree.filter.cycleForward` | `ctrl+o` | 向前循环切换树过滤器 |
| `app.tree.filter.cycleBackward` | `shift+ctrl+o` | 向后循环切换树过滤器 |

### 作用域模型选择器 {#scoped-models-selector}

用于作用域模型选择器内部（通过 `/scoped-models` 打开）。

| 快捷键 ID | 默认值 | 说明 |
|--------|---------|-------------|
| `app.models.enableAll` | `ctrl+a` | 启用所有模型（或当前搜索匹配的所有模型） |
| `app.models.clearAll` | `ctrl+x` | 清除所有模型（或当前搜索匹配的所有模型） |
| `app.models.toggleProvider` | `ctrl+p` | 切换当前提供商的所有模型 |
| `app.models.reorderUp` | `alt+up` | 在循环顺序中将所选模型上移 |
| `app.models.reorderDown` | `alt+down` | 在循环顺序中将所选模型下移 |

## 自定义配置 {#custom-configuration}

创建 `~/.pi/agent/keybindings.json`：

```json
{
  "tui.editor.historyPrevious": "ctrl+p",
  "tui.editor.historyNext": "ctrl+n",
  "tui.editor.deleteWordBackward": ["ctrl+w", "alt+backspace"]
}
```

每个动作可以绑定单个按键或一个按键数组。用户配置会覆盖默认值。

在原生 Windows 上，`app.suspend` 没有默认绑定，因为 Windows 终端不支持 Unix 作业控制。如果你手动绑定它，pi 会显示一条状态消息而不是挂起进程。在 WSL 中，正常的 Linux `ctrl+z`/`fg` 行为仍然适用。

### Emacs 示例 {#emacs-example}

```json
{
  "tui.editor.historyPrevious": "ctrl+p",
  "tui.editor.historyNext": "ctrl+n",
  "tui.editor.cursorLeft": ["left", "ctrl+b"],
  "tui.editor.cursorRight": ["right", "ctrl+f"],
  "tui.editor.cursorWordLeft": ["alt+left", "alt+b"],
  "tui.editor.cursorWordRight": ["alt+right", "alt+f"],
  "tui.editor.deleteCharForward": ["delete", "ctrl+d"],
  "tui.editor.deleteCharBackward": ["backspace", "ctrl+h"],
  "tui.input.newLine": ["shift+enter", "ctrl+j"]
}
```

### Vim 示例 {#vim-example}

```json
{
  "tui.editor.cursorUp": ["up", "alt+k"],
  "tui.editor.cursorDown": ["down", "alt+j"],
  "tui.editor.cursorLeft": ["left", "alt+h"],
  "tui.editor.cursorRight": ["right", "alt+l"],
  "tui.editor.cursorWordLeft": ["alt+left", "alt+b"],
  "tui.editor.cursorWordRight": ["alt+right", "alt+w"]
}
```

---

反链：

- [扩展](/book/pi/extensions/)
- [快速开始](/book/pi/quickstart/)
- [使用 Pi](/book/pi/usage/)
