refactor: use configurable keybindings for all UI hints (#724)

Follow-up to #717. Replaces all remaining hardcoded keybinding hints with configurable ones.

- Add pasteImage to AppAction so it can be configured in keybindings.json
- Create keybinding-hints.ts with reusable helper functions:
  - editorKey(action) / appKey(keybindings, action) - get key display string
  - keyHint(action, desc) / appKeyHint(kb, action, desc) / rawKeyHint(key, desc) - styled hints
- Export helpers from components/index.ts for extensions
- Update all components to use configured keybindings
- Remove now-unused getDisplayString() from KeybindingsManager and EditorKeybindingsManager
- Use keybindings.matches() instead of matchesKey() for pasteImage in custom-editor.ts
This commit is contained in:
Danila Poyarkov 2026-01-14 17:42:03 +03:00 committed by GitHub
parent 558a77b45f
commit a497fccd06
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 195 additions and 170 deletions

View file

@ -3,7 +3,6 @@ import {
Box,
Container,
getCapabilities,
getEditorKeybindings,
getImageDimensions,
Image,
imageFallback,
@ -20,6 +19,7 @@ import { convertToPng } from "../../../utils/image-convert.js";
import { sanitizeBinaryOutput } from "../../../utils/shell.js";
import { getLanguageFromPath, highlightCode, theme } from "../theme/theme.js";
import { renderDiff } from "./diff.js";
import { keyHint } from "./keybinding-hints.js";
import { truncateToVisualLines } from "./visual-truncate.js";
// Preview line limit for bash when not expanded
@ -376,11 +376,9 @@ export class ToolExecutionComponent extends Container {
cachedWidth = width;
}
if (cachedSkipped && cachedSkipped > 0) {
const expandKey = getEditorKeybindings().getKeys("expandTools")[0]!;
const hint =
theme.fg("muted", `... (${cachedSkipped} earlier lines, `) +
theme.fg("dim", expandKey) +
theme.fg("muted", " to expand)");
theme.fg("muted", `... (${cachedSkipped} earlier lines,`) +
` ${keyHint("expandTools", "to expand")})`;
return ["", hint, ...cachedLines];
}
return cachedLines;
@ -476,11 +474,7 @@ export class ToolExecutionComponent extends Container {
.map((line: string) => (lang ? replaceTabs(line) : theme.fg("toolOutput", replaceTabs(line))))
.join("\n");
if (remaining > 0) {
const expandKey = getEditorKeybindings().getKeys("expandTools")[0]!;
text +=
theme.fg("muted", `\n... (${remaining} more lines, `) +
theme.fg("dim", expandKey) +
theme.fg("muted", " to expand)");
text += `${theme.fg("muted", `\n... (${remaining} more lines,`)} ${keyHint("expandTools", "to expand")})`;
}
const truncation = this.result.details?.truncation;
@ -537,11 +531,9 @@ export class ToolExecutionComponent extends Container {
.map((line: string) => (lang ? replaceTabs(line) : theme.fg("toolOutput", replaceTabs(line))))
.join("\n");
if (remaining > 0) {
const expandKey = getEditorKeybindings().getKeys("expandTools")[0]!;
text +=
theme.fg("muted", `\n... (${remaining} more lines, ${totalLines} total, `) +
theme.fg("dim", expandKey) +
theme.fg("muted", " to expand)");
theme.fg("muted", `\n... (${remaining} more lines, ${totalLines} total,`) +
` ${keyHint("expandTools", "to expand")})`;
}
}
} else if (this.toolName === "edit") {
@ -599,11 +591,7 @@ export class ToolExecutionComponent extends Container {
text += `\n\n${displayLines.map((line: string) => theme.fg("toolOutput", line)).join("\n")}`;
if (remaining > 0) {
const expandKey = getEditorKeybindings().getKeys("expandTools")[0]!;
text +=
theme.fg("muted", `\n... (${remaining} more lines, `) +
theme.fg("dim", expandKey) +
theme.fg("muted", " to expand)");
text += `${theme.fg("muted", `\n... (${remaining} more lines,`)} ${keyHint("expandTools", "to expand")})`;
}
}
@ -644,11 +632,7 @@ export class ToolExecutionComponent extends Container {
text += `\n\n${displayLines.map((line: string) => theme.fg("toolOutput", line)).join("\n")}`;
if (remaining > 0) {
const expandKey = getEditorKeybindings().getKeys("expandTools")[0]!;
text +=
theme.fg("muted", `\n... (${remaining} more lines, `) +
theme.fg("dim", expandKey) +
theme.fg("muted", " to expand)");
text += `${theme.fg("muted", `\n... (${remaining} more lines,`)} ${keyHint("expandTools", "to expand")})`;
}
}
@ -693,11 +677,7 @@ export class ToolExecutionComponent extends Container {
text += `\n\n${displayLines.map((line: string) => theme.fg("toolOutput", line)).join("\n")}`;
if (remaining > 0) {
const expandKey = getEditorKeybindings().getKeys("expandTools")[0]!;
text +=
theme.fg("muted", `\n... (${remaining} more lines, `) +
theme.fg("dim", expandKey) +
theme.fg("muted", " to expand)");
text += `${theme.fg("muted", `\n... (${remaining} more lines,`)} ${keyHint("expandTools", "to expand")})`;
}
}