Skip to content

Commit 0cb332d

Browse files
author
SqlRush
committed
Accept super keybinding aliases
1 parent 2d1a26e commit 0cb332d

4 files changed

Lines changed: 23 additions & 19 deletions

File tree

docs/claude-code-go-rewrite-plan.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ test/parity/ # golden tests against TS/official behavior
334334
- 本轮补充:scripted task runtime 的 task payload、expectation 和 remove-task mutation 现在共享 `operationId``requestId``threadId``workflowId``toolUseId` 等相邻 task ID aliases,录制脚本可用 operation/request 风格 ID 追踪和移除任务。
335335
- 本轮补充:permission runtime 会把 `Reject`/`deny`/`decline`/`disallow`/`no` 等 permission action 归一为 denied 结果,把 `Cancel`/`abort` 归一为 cancelled 结果,并让 scripted dialog-result status 断言接受 `rejected`/`approved` 等状态别名。
336336
- 本轮补充:scripted permission payload、dialog expectation、event、cancel-permission 和 dialog-result expectation 现在接受 `ID`/`ToolName`/`Actions``permissionID``requestID``toolUseID``operationID``operation``commandName``resourcePath``body``reasonText``allowedActions``buttons` 等相邻字段,并支持数字 request ID。
337-
- 本轮补充:configurable keybinding name parser 现在接受 macOS 风格 `cmd`/`command` modifier aliases,和现有 `meta`/`option` 一样映射到 prompt word motion、yank-pop、delete-word-back 与 modified left/right arrow key。
337+
- 本轮补充:configurable keybinding name parser 现在接受 macOS/DOM 风格 `cmd`/`command`/`super` modifier aliases,和现有 `meta`/`option` 一样映射到 prompt word motion、yank-pop、delete-word-back 与 modified left/right arrow key。
338338
- 本轮补充:scripted runtime 的 permission/task payload 现在会递归解包 `value`/`payload`/`data`/`resource`/`attributes`/`properties`/`attrs`/`edge`/`node``included`/`collection`/`list`/`values` 等 JSON:API/GraphQL wrapper;resource/node 顶层 ID 会回填到内层 permission/task,带明确非 permission/task `type` 的 included resource 会被跳过,并避免仅因 wrapper 顶层 ID 生成半空 runtime 对象。
339339
- 本轮补充:scripted runtime mutation 的 `removeTask`/`cancelPermission`/`cancelTasks` 现在也会从 wrapped `value`/`payload`/`data`/`resource`/`edge.node` 中递归读取 task/permission ID 和 cancellation detail,兼容 resource/action fixture 直接驱动 runtime mutation。
340340
- 本轮补充:scripted runtime mutation 的直接 alias 字段现在也接受 object payload,例如 `removeTask: {resource:{id}}``cancelPermission: {edge:{node:{id}}}``cancelTasks: {resource:{attributes:{reasonText}}}` 不再因 string/bool 强类型字段提前解析失败。

docs/first-second-parity-audit.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ M7 progress now includes:
275275
- `internal/tui`: scripted task runtime payloads, task expectations, and remove-task mutations now also share adjacent task ID aliases such as `operationId`, `requestId`, `threadId`, `workflowId`, and `toolUseId`, so recorded runtime actions can address tasks through operation/request-style IDs.
276276
- `internal/tui`: permission runtime now treats action aliases such as `Reject`, `deny`, `decline`, `disallow`, and `no` as denied results, `Cancel`/`abort` as cancelled results, and keeps allowed aliases canonical for scripted dialog-result status checks.
277277
- `internal/tui`: scripted permission payloads, dialog expectations, events, cancellation, and dialog-result expectations now accept adjacent ID and field aliases such as `permissionID`, `requestID`, `toolUseID`, `operationID`, `operation`, `commandName`, `resourcePath`, `body`, `reasonText`, `allowedActions`, `buttons`, and numeric request IDs.
278-
- `internal/tui`: configurable keybinding names now accept macOS-style `cmd`/`command` modifier aliases for the same prompt-editing keys already covered by `meta`/`option`, including word motions, yank-pop, delete-word-back, and modified left/right arrows.
278+
- `internal/tui`: configurable keybinding names now accept macOS/DOM-style `cmd`/`command`/`super` modifier aliases for the same prompt-editing keys already covered by `meta`/`option`, including word motions, yank-pop, delete-word-back, and modified left/right arrows.
279279
- `internal/tui`: scripted runtime permission/task payloads now recursively unwrap JSON:API/GraphQL-style envelopes such as `value`, `payload`, `data`, `resource`, `attributes`, `properties`, `attrs`, `edge`, `node`, `included`, `collection`, `list`, and `values`, while carrying resource/node IDs into nested permission/task objects, skipping explicitly non-permission/task typed included resources, and avoiding empty objects created from wrapper-only payloads.
280280
- `internal/tui`: scripted runtime mutations now recursively unwrap wrapped IDs/details for `removeTask`, `cancelPermission`, and `cancelTasks`, so action fixtures can carry task IDs, permission IDs, and cancellation reasons inside `payload.resource.attributes`, `edge.node`, or adjacent API envelopes.
281281
- `internal/tui`: scripted runtime mutation alias fields now accept object payloads directly, so `removeTask`, `cancelPermission`, and `cancelTasks` can carry wrapped resource/edge payloads without failing early on string/bool-only unmarshalling.

internal/tui/keybinding_config.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -80,15 +80,15 @@ func ParseKeyName(raw string) (KeyType, error) {
8080
return KeyShiftEnter, nil
8181
case "esc", "escape", "ctrl+[", "ctrl-[", "control+[", "control-[":
8282
return KeyEsc, nil
83-
case "alt+b", "alt-b", "meta+b", "meta-b", "option+b", "option-b", "cmd+b", "cmd-b", "command+b", "command-b":
83+
case "alt+b", "alt-b", "meta+b", "meta-b", "option+b", "option-b", "cmd+b", "cmd-b", "command+b", "command-b", "super+b", "super-b":
8484
return KeyAltB, nil
85-
case "alt+d", "alt-d", "meta+d", "meta-d", "option+d", "option-d", "cmd+d", "cmd-d", "command+d", "command-d":
85+
case "alt+d", "alt-d", "meta+d", "meta-d", "option+d", "option-d", "cmd+d", "cmd-d", "command+d", "command-d", "super+d", "super-d":
8686
return KeyAltD, nil
87-
case "alt+f", "alt-f", "meta+f", "meta-f", "option+f", "option-f", "cmd+f", "cmd-f", "command+f", "command-f":
87+
case "alt+f", "alt-f", "meta+f", "meta-f", "option+f", "option-f", "cmd+f", "cmd-f", "command+f", "command-f", "super+f", "super-f":
8888
return KeyAltF, nil
89-
case "alt+y", "alt-y", "meta+y", "meta-y", "option+y", "option-y", "cmd+y", "cmd-y", "command+y", "command-y":
89+
case "alt+y", "alt-y", "meta+y", "meta-y", "option+y", "option-y", "cmd+y", "cmd-y", "command+y", "command-y", "super+y", "super-y":
9090
return KeyAltY, nil
91-
case "alt+backspace", "alt-backspace", "meta+backspace", "meta-backspace", "option+backspace", "option-backspace", "cmd+backspace", "cmd-backspace", "command+backspace", "command-backspace":
91+
case "alt+backspace", "alt-backspace", "meta+backspace", "meta-backspace", "option+backspace", "option-backspace", "cmd+backspace", "cmd-backspace", "command+backspace", "command-backspace", "super+backspace", "super-backspace":
9292
return KeyAltBS, nil
9393
case "backspace", "bs", "ctrl+?", "ctrl-?", "control+?", "control-?", "ctrl+h", "ctrl-h", "control+h", "control-h":
9494
return KeyBackspace, nil
@@ -98,9 +98,9 @@ func ParseKeyName(raw string) (KeyType, error) {
9898
return KeyLeft, nil
9999
case "right", "arrow-right", "arrowright":
100100
return KeyRight, nil
101-
case "alt+left", "alt-left", "meta+left", "meta-left", "option+left", "option-left", "cmd+left", "cmd-left", "command+left", "command-left", "alt+arrow-left", "alt-arrow-left", "meta+arrow-left", "meta-arrow-left", "option+arrow-left", "option-arrow-left", "cmd+arrow-left", "cmd-arrow-left", "command+arrow-left", "command-arrow-left":
101+
case "alt+left", "alt-left", "meta+left", "meta-left", "option+left", "option-left", "cmd+left", "cmd-left", "command+left", "command-left", "super+left", "super-left", "alt+arrow-left", "alt-arrow-left", "meta+arrow-left", "meta-arrow-left", "option+arrow-left", "option-arrow-left", "cmd+arrow-left", "cmd-arrow-left", "command+arrow-left", "command-arrow-left", "super+arrow-left", "super-arrow-left":
102102
return KeyAltLeft, nil
103-
case "alt+right", "alt-right", "meta+right", "meta-right", "option+right", "option-right", "cmd+right", "cmd-right", "command+right", "command-right", "alt+arrow-right", "alt-arrow-right", "meta+arrow-right", "meta-arrow-right", "option+arrow-right", "option-arrow-right", "cmd+arrow-right", "cmd-arrow-right", "command+arrow-right", "command-arrow-right":
103+
case "alt+right", "alt-right", "meta+right", "meta-right", "option+right", "option-right", "cmd+right", "cmd-right", "command+right", "command-right", "super+right", "super-right", "alt+arrow-right", "alt-arrow-right", "meta+arrow-right", "meta-arrow-right", "option+arrow-right", "option-arrow-right", "cmd+arrow-right", "cmd-arrow-right", "command+arrow-right", "command-arrow-right", "super+arrow-right", "super-arrow-right":
104104
return KeyAltRight, nil
105105
case "ctrl+left", "ctrl-left", "control+left", "control-left", "ctrl+arrow-left", "ctrl-arrow-left", "control+arrow-left", "control-arrow-left":
106106
return KeyCtrlLeft, nil
@@ -186,23 +186,23 @@ func ParseKeyName(raw string) (KeyType, error) {
186186
return KeyShiftEnter, nil
187187
case "shifttab", "backtab", "btab":
188188
return KeyShiftTab, nil
189-
case "altb", "metab", "optionb", "cmdb", "commandb":
189+
case "altb", "metab", "optionb", "cmdb", "commandb", "superb":
190190
return KeyAltB, nil
191-
case "altd", "metad", "optiond", "cmdd", "commandd":
191+
case "altd", "metad", "optiond", "cmdd", "commandd", "superd":
192192
return KeyAltD, nil
193-
case "altf", "metaf", "optionf", "cmdf", "commandf":
193+
case "altf", "metaf", "optionf", "cmdf", "commandf", "superf":
194194
return KeyAltF, nil
195-
case "alty", "metay", "optiony", "cmdy", "commandy":
195+
case "alty", "metay", "optiony", "cmdy", "commandy", "supery":
196196
return KeyAltY, nil
197-
case "altbackspace", "metabackspace", "optionbackspace", "cmdbackspace", "commandbackspace":
197+
case "altbackspace", "metabackspace", "optionbackspace", "cmdbackspace", "commandbackspace", "superbackspace":
198198
return KeyAltBS, nil
199199
case "ctrl?", "control?", "ctrlh", "controlh":
200200
return KeyBackspace, nil
201201
case "ctrli", "controli":
202202
return KeyTab, nil
203-
case "altleft", "metaleft", "optionleft", "cmdleft", "commandleft":
203+
case "altleft", "metaleft", "optionleft", "cmdleft", "commandleft", "superleft":
204204
return KeyAltLeft, nil
205-
case "altright", "metaright", "optionright", "cmdright", "commandright":
205+
case "altright", "metaright", "optionright", "cmdright", "commandright", "superright":
206206
return KeyAltRight, nil
207207
case "ctrlleft", "controlleft":
208208
return KeyCtrlLeft, nil
@@ -300,7 +300,7 @@ func expandCompactShortKeyModifierAlias(compact string) string {
300300
}
301301

302302
func expandCompactModifierArrowAlias(compact string) string {
303-
for _, prefix := range []string{"ctrl", "control", "alt", "meta", "option", "cmd", "command"} {
303+
for _, prefix := range []string{"ctrl", "control", "alt", "meta", "option", "cmd", "command", "super"} {
304304
if suffix, ok := strings.CutPrefix(compact, prefix); ok {
305305
navigation := compactNavigationKeySuffix(suffix)
306306
if navigation != suffix {

internal/tui/tui_test.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,7 +1449,7 @@ func TestKeymapFromSpecsOverridesAndRemovesBindings(t *testing.T) {
14491449
t.Fatalf("ParseActionName(%q) = %q, %v", tc.name, action, err)
14501450
}
14511451
}
1452-
for _, name := range []string{"paste", "image-hint", "mouse", "focus-out", "shift-enter", "shift+return", "shiftEnter", "shiftReturn", "shiftTab", "backtab", "back-tab", "backTab", "btab", "s-tab", "sTab", "s-enter", "sReturn", "page-up", "pgup", "pg-up", "prior", "page-down", "pgdn", "pg-dn", "pgdown", "pg-down", "next", "arrowLeft", "arrowRight", "arrowUp", "arrowDown", "alt-b", "alt-d", "alt-f", "alt-y", "alt-backspace", "alt-left", "alt-right", "alt-arrow-left", "alt-arrow-right", "altB", "metaD", "optionF", "cmdY", "commandF", "cmd-arrow-left", "command-arrow-right", "altY", "altBackspace", "altLeft", "optionRight", "altArrowLeft", "metaArrowRight", "optionArrowLeft", "cmdArrowLeft", "commandArrowRight", "m-b", "mB", "a-d", "aD", "opt-f", "optF", "m-left", "m-arrow-left", "mArrowLeft", "a-right", "aArrowRight", "optRight", "optArrowRight", "meta-b", "meta-d", "meta-f", "meta-y", "meta-backspace", "meta-left", "meta-right", "option-arrow-left", "option-arrow-right", "cmd-b", "cmd-d", "cmd-f", "cmd-y", "cmd-backspace", "cmd-left", "cmd-right", "command-b", "command-d", "command-f", "command-y", "command-backspace", "command-left", "command-right", "ctrl-b", "ctrl-d", "ctrl-f", "ctrl-g", "ctrl-u", "ctrl-k", "ctrl-l", "ctrl-n", "ctrl-o", "ctrl-p", "ctrl-q", "ctrl-s", "ctrl-t", "ctrl-v", "ctrl-w", "ctrl-x", "ctrl-y", "ctrl-z", "ctrl-h", "ctrl-i", "ctrl-m", "control-h", "control-i", "control-m", "c-h", "c-i", "c-m", "c-[", "c-?", "ctrlH", "controlI", "ctrlM", "cH", "cI", "cM", "ctrl-left", "ctrl-right", "ctrl-arrow-left", "ctrl-arrow-right", "ctrlArrowLeft", "controlArrowRight", "c-left", "c-arrow-left", "c-right", "c-arrow-right", "ctrlA", "controlX", "ctrlLeft", "controlRight", "cA", "cQ", "cV", "cZ", "cLeft", "cArrowRight", "control-left", "control-right", "control-arrow-left", "control-arrow-right"} {
1452+
for _, name := range []string{"paste", "image-hint", "mouse", "focus-out", "shift-enter", "shift+return", "shiftEnter", "shiftReturn", "shiftTab", "backtab", "back-tab", "backTab", "btab", "s-tab", "sTab", "s-enter", "sReturn", "page-up", "pgup", "pg-up", "prior", "page-down", "pgdn", "pg-dn", "pgdown", "pg-down", "next", "arrowLeft", "arrowRight", "arrowUp", "arrowDown", "alt-b", "alt-d", "alt-f", "alt-y", "alt-backspace", "alt-left", "alt-right", "alt-arrow-left", "alt-arrow-right", "altB", "metaD", "optionF", "cmdY", "commandF", "superB", "superF", "cmd-arrow-left", "command-arrow-right", "super-arrow-left", "super-arrow-right", "altY", "altBackspace", "altLeft", "optionRight", "altArrowLeft", "metaArrowRight", "optionArrowLeft", "cmdArrowLeft", "commandArrowRight", "superArrowLeft", "superArrowRight", "m-b", "mB", "a-d", "aD", "opt-f", "optF", "m-left", "m-arrow-left", "mArrowLeft", "a-right", "aArrowRight", "optRight", "optArrowRight", "meta-b", "meta-d", "meta-f", "meta-y", "meta-backspace", "meta-left", "meta-right", "option-arrow-left", "option-arrow-right", "cmd-b", "cmd-d", "cmd-f", "cmd-y", "cmd-backspace", "cmd-left", "cmd-right", "command-b", "command-d", "command-f", "command-y", "command-backspace", "command-left", "command-right", "super-b", "super-d", "super-f", "super-y", "super-backspace", "super-left", "super-right", "ctrl-b", "ctrl-d", "ctrl-f", "ctrl-g", "ctrl-u", "ctrl-k", "ctrl-l", "ctrl-n", "ctrl-o", "ctrl-p", "ctrl-q", "ctrl-s", "ctrl-t", "ctrl-v", "ctrl-w", "ctrl-x", "ctrl-y", "ctrl-z", "ctrl-h", "ctrl-i", "ctrl-m", "control-h", "control-i", "control-m", "c-h", "c-i", "c-m", "c-[", "c-?", "ctrlH", "controlI", "ctrlM", "cH", "cI", "cM", "ctrl-left", "ctrl-right", "ctrl-arrow-left", "ctrl-arrow-right", "ctrlArrowLeft", "controlArrowRight", "c-left", "c-arrow-left", "c-right", "c-arrow-right", "ctrlA", "controlX", "ctrlLeft", "controlRight", "cA", "cQ", "cV", "cZ", "cLeft", "cArrowRight", "control-left", "control-right", "control-arrow-left", "control-arrow-right"} {
14531453
if key, err := ParseKeyName(name); err != nil || key == KeyUnknown {
14541454
t.Fatalf("ParseKeyName(%q) = %q, %v", name, key, err)
14551455
}
@@ -1462,10 +1462,11 @@ func TestKeymapFromSpecsOverridesAndRemovesBindings(t *testing.T) {
14621462
}
14631463
}
14641464

1465-
func TestKeymapFromSpecsAcceptsCommandModifierAliases(t *testing.T) {
1465+
func TestKeymapFromSpecsAcceptsCommandAndSuperModifierAliases(t *testing.T) {
14661466
keymap, err := KeymapFromSpecs(DefaultKeymap(), []BindingSpec{
14671467
{Key: "cmdB", Action: ActionMoveStart},
14681468
{Key: "command-arrow-right", Action: ActionMoveEnd},
1469+
{Key: "super-backspace", Action: ActionDeleteWordBack},
14691470
})
14701471
if err != nil {
14711472
t.Fatal(err)
@@ -1476,6 +1477,9 @@ func TestKeymapFromSpecsAcceptsCommandModifierAliases(t *testing.T) {
14761477
if action := keymap.Resolve(Key{Type: KeyAltRight}); action != ActionMoveEnd {
14771478
t.Fatalf("command-arrow-right action = %q", action)
14781479
}
1480+
if action := keymap.Resolve(Key{Type: KeyAltBS}); action != ActionDeleteWordBack {
1481+
t.Fatalf("super-backspace action = %q", action)
1482+
}
14791483
}
14801484

14811485
func TestKeymapFromSpecsAcceptsTerminalControlCharacterAliases(t *testing.T) {

0 commit comments

Comments
 (0)