Keybindings

Keybindings 模块实现了一套完整的快捷键管理系统,包含 14 个快捷键上下文(Global、Chat、Autocomplete、Settings、Confirmation、Tabs、Transcript、HistorySearch、Task、Scroll、Help、Attachments、Footer、Select 等)。支持和弦组合键(如 ctrl+x ctrl+k)、平台自适应(Windows/macOS 差异处理)、用户自定义覆盖(keybindings.json)、保留键保护(ctrl+c/ctrl+d 不可重绑)。解析器(parser.ts)将字符串描述转换为结构化按键,解析器(resolver.ts)实现带状态的和弦匹配。

职责与设计理念

职责说明

可定制快捷键系统,支持多上下文、和弦组合与平台适配

设计理念

快捷键即分层状态机——14 个上下文形成优先级栈,和弦组合键引入时间维度,用户覆盖实现"最后声明胜出"。快捷键不是简单的键值映射,而是上下文感知的意图解析。

架构决策

为什么需要 14 个快捷键上下文?

按 UI 状态划分独立的快捷键上下文

同一个按键在不同 UI 状态下含义不同:Enter 在 Chat 上下文是发送消息,在 Confirmation 上下文是确认操作,在 Autocomplete 上下文是选择补全项。14 个上下文形成优先级栈,当前活跃的上下文优先匹配。

文件清单

文件名 用途
defaultBindings.ts 默认快捷键定义,14 个上下文 × 80+ 绑定
resolver.ts 快捷键解析器,实现带和弦状态的按键匹配
parser.ts 按键字符串解析器,将 "ctrl+x" 转为结构化对象
match.ts 按键匹配逻辑,处理修饰键组合和平台差异
KeybindingContext.tsx React Context Provider,向组件树分发快捷键状态
loadUserBindings.ts 用户自定义快捷键加载,从 keybindings.json 读取覆盖
validate.ts 快捷键校验,检测冲突和保留键违规
schema.ts 快捷键配置 JSON Schema 定义

使用场景

用户按 ctrl+x ctrl+k

和弦组合键:第一次按键进入 chord_started 状态,等待第二次按键完成匹配

用户自定义 keybindings.json

加载用户覆盖,与默认绑定合并,冲突时用户定义优先

loadUserBindings() → merge(defaults, userBindings) → validate()

依赖关系

  • Ink — 深度定制的终端渲染引擎,基于 Yoga 布局 + React Reconciler 实现终端 UI
  • Components — 100+ 终端 UI 组件库,覆盖对话、编辑、导航、设置等全场景

关键代码片段

和弦快捷键解析

function resolveKeyWithChordState(
  input: string, key: Key,
  activeContexts: KeybindingContextName[],
  bindings: ParsedBinding[],
  pending: ParsedKeystroke[] | null,
): ChordResolveResult {
  const testChord = pending
    ? [...pending, currentKeystroke]
    : [currentKeystroke]

  if (hasLongerChords) {
    return { type: 'chord_started', pending: testChord }
  }
  if (exactMatch) {
    return { type: 'match', action: exactMatch.action }
  }
  if (pending !== null) {
    return { type: 'chord_cancelled' }
  }
  return { type: 'none' }
}

四态和弦解析:chord_started(等待后续键)→ match/unbound/chord_cancelled

技术笔记

security

保留键保护

ctrl+c(中断)和 ctrl+d(EOF)被标记为保留键,用户无法通过 keybindings.json 重绑定,防止终端失控。