* feat(keymap): make the prompt editor's soft newline a bindable action
Shift+Enter and Opt/Alt+Enter have inserted a literal newline into the
command editor since the multi-line prompt editor landed in 54825d3, and
only a plain Enter submits. But the chords were hardcoded in the editor's
key handler, so `InsertNewline` was not a name the keymap knew: nothing to
put in `keybindings` in config.json, no row in Settings -> Keybindings, and
no way to move the gesture to a chord of your own.
Register it like every other action. `InsertNewline` is Terminal-scoped
(the handler lives on the terminal surface, as ClearScrollback and the find
trio already are) and the "enter" arm of the editor dispatcher no longer
looks at modifiers at all — the keymap dispatches the action before the key
reaches the dispatcher, so there is one implementation rather than two that
can drift.
The action ships with both of today's chords. A binding spec cannot express
alternatives — whitespace in a spec means a sequence, `ctrl-b n`-style —
and the effective table holds exactly one keystroke per action, so the
table carries shift-enter and alt-enter is installed alongside it, but only
while the action still sits on its default. Rebind it and both old chords
are retired, which is what moving a binding is supposed to mean.
The prompt editor alone answers it. With a foreground application on the
pane, the search field focused, or a completion menu / reverse search
holding the keyboard, the handler propagates, so the chord takes the exact
path it took before this action existed — a full-screen program still
receives Shift+Enter as its own chord under the Kitty protocol. Plain Enter
still submits, and the secondary-enter / secondary-shift-enter window
bindings are untouched.
Refs #182
* fix(prompt): let the newline chords through an open completion menu
Follow-up to the InsertNewline action, from review findings, resolved
against Warp as the reference implementation.
The action declined whenever a completion menu was open, on the theory
that propagating preserved the old behaviour. It did for Shift+Enter,
which used to reach the picker's accept-line arm, but not for Alt+Enter:
the picker branch is gated on `!m.alt`, so Alt+Enter skipped it entirely
and fell through to the enter arm's newline. Propagating sent it to an
enter arm that now unconditionally submits, so Alt+Enter with a menu open
ran the command.
Warp does not let the popup take these chords at all. Only a bare Enter
reaches the popup-acceptance path (a fixed "enter" binding routed into
`input_enter`, where menus and the completion popup consume it); Shift+
Enter, Alt+Enter and Ctrl+J dispatch their own actions, which the editor
resolves as a newline against `EnterSettings` without the popup ever
seeing them. Its TUI has no popup in the input's dispatch path at all.
So insert unconditionally and close the menu — a newline ends the word
being completed, and a menu still filtered on that word would be stale.
Shift+Enter with a menu open therefore changes from accept-line to
insert, deliberately and in the direction of the reference; Alt+Enter
goes back to inserting, as it did before the action landed. Plain Enter
keeps accepting the highlighted candidate.
Also repeat the dispatcher's per-key state resets (`editor_goal_col`,
`last_word_nav`), which the inline branch inherited by running inside
`handle_editor_key` and the action bypassed — the same reason
`commit_text` repeats them for the IME path.
Shift+Alt+Enter, which the old `(m.shift || m.alt)` test caught by
accident, is left submitting: gpui matches modifiers exactly, and Warp's
key table has no arm for that chord either. Recorded in a comment and a
test so it is not "restored" later as a missing default.
Refs #182
* no-mistakes(review): scope rebind's NoAction to its context; see extra chords
* no-mistakes(document): document rebindable InsertNewline chords; fix rustfmt and changelog link
---------
Co-authored-by: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com>
9.6 KiB
功能
English · 简体中文
输入
- 影子建议 —— 边打字边用你的历史补全整条命令,→ 接受
- 带说明的 Tab 补全 —— 每个 flag、每个子命令都带说明,覆盖约 100 个常用命令;tty7 没有候选时 Tab 自动交给 shell 自己的补全,整个功能也可关闭(设置 → 终端 → 键盘,或
config.json里的tab_completion) - 语法高亮 —— 边打边亮,什么都不用装
- 模糊历史搜索 —— ⌃ R 看到每条命令在哪跑的、什么时候、有没有失败;关掉它(设置 → 终端 → 键盘,或
config.json里的history_search)后 ⌃ R 直接交给 shell,你绑的 fzf / percol 照常可用 - 历史开箱即用 —— 你已有的 shell 历史直接生效,并跨会话延续
- 行编辑 —— 点击定位光标、鼠标选区、词级移动、撤销
- 多行编辑 —— 折行和多行命令原地编辑;网格自动上移,光标始终可见。⇧ ⏎ · ⌥ ⏎ 插入换行而不提交(可改绑,动作名
InsertNewline),单独按 ⏎ 提交整个缓冲区
窗口
- 标签页与分屏 —— 永远开在当前目录
- 侧栏按仓库分组 —— 左侧标签栏按 git 仓库分组、每组一个标题行,不在仓库里的标签归入末尾的 Scratch 组;切分支、仓库内
cd都不会挪动行(config.json的sidebar_grouping:默认repo,none恢复扁平列表) - 命令面板 ⌘ P · 回滚搜索 ⌘ F
- ⌘ 点击打开链接 · 桌面通知 · 划选即复制(可选,设置 → 终端 → 剪贴板)
- 智能双击选中 —— 双击直接选中整条 URL、文件路径、括号/引号对,中文按词典分词出词;Shift 点击扩展选区(设置 → 终端 → 鼠标可开关;分隔符用
config.json的word_separators配置) - 9 套主题,也能自定义 — YAML 种子主题,背景支持纯色、渐变或图片;可导入 iTerm2
.itermcolors;应用内颜色编辑器带背景图选择 - 跟随系统外观 — 设置 → Appearance;分别选好浅色和深色主题,tty7 随系统深浅模式实时切换(
config.json中的theme_follow_system、theme_preset_light/theme_preset_dark) - 窗口透明与模糊 — 设置 → Appearance → Window;对所有主题生效,Follow theme 恢复主题自带的
opacity/blur - CJK / 输入法输入
字体
- 内置 Hack —— 打包进二进制,默认配置在各平台渲染完全一致,不依赖系统安装
- 主字体 + 有序 fallback ——
config.json里的font_family和font_fallbacks;可选font_family_bold/font_family_italic指定独立字面,font_features透传 OpenType 特性(上下文连字默认关闭) - 默认列表按平台分支 —— fallback 只写宿主系统真正自带的字体(macOS 用 PingFang SC / Apple Color Emoji,Windows 用 Microsoft YaHei / Segoe UI Emoji,Linux 用 Noto)。这些名字也会追加到你手写的列表后面,所以在别的平台写出来的
config.json一样能落地
中文与两列网格
一个格子等于主字体的一个 advance,宽字符(CJK)被钉死在正好两格上。所以中文 fallback 只有在汉字 advance 等于主字体西文 advance 的两倍时,才能严丝合缝地 填满自己的槽。
内置 Hack 的 advance 是 0.60205em,两格就是 1.2041em —— 而系统自带的中文字体 (Microsoft YaHei、PingFang SC、Noto Sans CJK)全都是 1.0em。这些字形在槽里左 对齐,多出来的约 0.2em 就变成每个字右边的一道空隙。
Maple Mono NF CN 在所有平台都排在 第一位正是因为这个 —— 西文 0.6em、中文 1.2em,对上 Hack 正好两格。它只按名字引 用,不打包(每字重约 20MB):装上即生效,不用改配置。
想让中文排得紧而不只是均匀,要换的是主字体:选一个 advance 为 0.5em 的 (比如 Sarasa Mono SC 更纱黑体等宽),两格就正好 1.0em。
Coding agent
tty7 能识别 pane 里跑着的第三方 coding agent(Claude Code、Codex、Gemini CLI、 Aider、Amp、OpenCode 等约 17 个)并在其外围加功能 —— 绝不包裹或替代 agent 本身。
- 品牌头像 —— 标签 chip / 侧栏行显示每个 pane 跑的是哪个 agent;自定义包装命令可通过
config.json的agent_commands映射 - 状态点 —— 工作中(蓝)/ 等你输入(琥珀)/ 完成(绿),由 agent 自己上报的 OSC 事件驱动;在 设置 → Agents 一键装好对应 hooks(Claude Code、Codex、Copilot CLI、OpenCode、Pi、Grok Build)
- 通知 —— agent 卡在等你批准的那一刻弹 "needs your permission…",每轮结束弹 "finished after Ns",遵循你的通知策略
- 一眼看分支 —— 侧栏每行显示该 pane 的 git 分支和工作区改动(
+N −M),cd或命令跑完时自动刷新 - 会话恢复 —— 重启后无法重连的 pane 会自动续上 agent 对话,并带上原始启动 flags(
claude --dangerously-skip-permissions --resume …;restore_agent_sessions,默认开启) - Fork 会话 —— 直接调 agent 自己的 fork 命令(
codex fork <id>、claude --resume <id> --fork-session,OpenCode 和 Grok Build 同样支持),把当前对话分叉成一个独立会话;原会话原封不动,两边各自往下走。在 pane 上右键可选择分屏位置,在标签 / 侧栏行上右键则直接开新标签。需要先装好该 agent 的 hooks(fork 认的是 hooks 上报的 session id);远程 pane 不能 fork,因为命令会跑在本机的 agent 上;另外 fork 会整份复制对话历史,反复 fork 会在 agent 自己的会话目录里占掉不少磁盘 - 复制 Session ID —— 把 agent 的原生 session id 复制到剪贴板,就在 Copy Working Directory 旁边,方便粘进
codex resume、bug 报告或别的工具 - 上下文回填 —— 面板命令把当前选区或仓库
git diff打包成 prompt 直接喂给正在跑的 agent - 托盘图标 —— 系统托盘 / 菜单栏常驻图标,任何 agent 等你输入时立即切换为提醒态;菜单列出所有 agent pane(品牌头像 + 状态点,点击直达)、可切换通知策略,并在保留会话的普通退出之外提供 Quit and Stop Daemon(
show_tray_icon,默认开启)
SSH
唯一路径就是原生 Rust SSH 栈(russh)—— profile、凭据、SFTP 全部内置,
不 shell 出 ssh,也没有系统 ssh 兼容模式。
- QuickConnect —— 面板里打
user@host[:port]回车即连;支持 IPv6[::1]:port - 保存 profile —— 完整连接配置,密码 / passphrase 进 OS keychain,不落盘
~/.ssh/configalias —— 直接输入 alias 即连(原生解析常用字段,尽力而为,走 russh),也可在设置页一键导入为 profile- GUI 认证 —— pane 内 sheet 输入密码、私钥 passphrase、2FA,并确认主机密钥(新主机 vs 已变更)
- 内置 SFTP —— 滑入式文件面板:浏览、上传 / 下载、重命名 / 删除 / chmod,可拖进 Finder
- 端口转发 —— Local / Remote / Dynamic,预配置或运行时增删,外加 ⌘ 点击
localhost:PORT一键转发 - 跳板与代理 —— 经 profile 引用或
ProxyJump多跳、ProxyCommand、SOCKS5 / HTTP
| 入口 | 连接方式 |
|---|---|
保存 profile · QuickConnect · 输入 user@host[:port] |
原生 russh —— SFTP · keychain · GUI 认证 · L/R/D 转发 |
~/.ssh/config alias |
原生解析后走 russh(Match/canonicalize/GSSAPI 不支持,且无回退) |
快捷键
下表按 macOS 记法书写 —— 在 Windows 和 Linux 上,把 ⌘ 读作 Ctrl。最常用的几个:
| ⌘ T · ⌘ W · ⌘ ⇧ T | 新建标签页 · 关闭标签页 · 恢复关闭的标签页 |
| ⌘ 1…⌘ 9 · ⌃ ⇥ · ⌃ ⇧ ⇥ | 跳到第 1–9 个标签页 · 下一个 · 上一个标签页 |
| ⌘ D · ⌘ ⇧ D | 向右分屏 · 向下分屏 |
| ⌘ ] · ⌘ [ | 下一个窗格 · 上一个窗格 |
| ⌘ ⌥ ←→↑↓ | 按方向切换焦点窗格 |
| ⌘ ⏎ · ⌘ ⇧ ⏎ | 切换全屏 · 最大化 / 还原窗格 |
| ⌘ K | 清屏并清空回滚缓冲区 |
| ⌘ P | 命令面板 |
| ⌘ F | 搜索回滚缓冲区 |
| ⌃ R | 模糊搜索 shell 历史 |
| ⌘ + · ⌘ − · ⌘ 0 | 字号增大 · 减小 · 重置 |
Settings → Keybindings(⌘ ,)列出全部快捷键。点一行、按下新键即可 (Esc 取消,Backspace 恢复默认),改完立即生效。窗格缩放与 交换默认不绑定键 —— 在这里绑定,或从命令面板执行。
tmux 预设 —— 把窗格/标签页操作映射到前缀键(默认 ⌃ B):
⌃ B C 新建标签页,⌃ B % 分屏,
⌃ B 接方向键切换焦点。单独按前缀键会在短暂延迟后送达 shell,
前缀 + 未绑定的键原样透传给终端。
性能说明
- 以设备速度读取 PTY,在渲染路径之外成批解析
- 热路径全程无锁 —— 再大的
cat也不会阻塞在渲染上 - 触发背压前,守护进程最多可领先窗口缓冲 16 MiB