mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-18 19:03:41 +00:00
fix: use configurable expandTools keybinding instead of hardcoded ctrl+o (#717)
- Add expandTools to EditorAction in pi-tui so components can access it
- Update bash-execution, compaction-summary-message, branch-summary-message,
and tool-execution to use getEditorKeybindings().getKeys('expandTools')
- Pass expandTools config to setEditorKeybindings in KeybindingsManager.create()
- Style keybinding with 'dim' color, description with 'muted' (matches startup hints)
This commit is contained in:
parent
30a126f2bd
commit
7f2d2f106e
6 changed files with 70 additions and 17 deletions
|
|
@ -111,9 +111,10 @@ export class KeybindingsManager {
|
||||||
const manager = new KeybindingsManager(config);
|
const manager = new KeybindingsManager(config);
|
||||||
|
|
||||||
// Set up editor keybindings globally
|
// Set up editor keybindings globally
|
||||||
|
// Include both editor actions and expandTools (shared between app and editor)
|
||||||
const editorConfig: EditorKeybindingsConfig = {};
|
const editorConfig: EditorKeybindingsConfig = {};
|
||||||
for (const [action, keys] of Object.entries(config)) {
|
for (const [action, keys] of Object.entries(config)) {
|
||||||
if (!isAppAction(action)) {
|
if (!isAppAction(action) || action === "expandTools") {
|
||||||
editorConfig[action as EditorAction] = keys;
|
editorConfig[action as EditorAction] = keys;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
* Component for displaying bash command execution with streaming output.
|
* Component for displaying bash command execution with streaming output.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Container, Loader, Spacer, Text, type TUI } from "@mariozechner/pi-tui";
|
import { Container, getEditorKeybindings, Loader, Spacer, Text, type TUI } from "@mariozechner/pi-tui";
|
||||||
import stripAnsi from "strip-ansi";
|
import stripAnsi from "strip-ansi";
|
||||||
import {
|
import {
|
||||||
DEFAULT_MAX_BYTES,
|
DEFAULT_MAX_BYTES,
|
||||||
|
|
@ -166,10 +166,15 @@ export class BashExecutionComponent extends Container {
|
||||||
|
|
||||||
// Show how many lines are hidden (collapsed preview)
|
// Show how many lines are hidden (collapsed preview)
|
||||||
if (hiddenLineCount > 0) {
|
if (hiddenLineCount > 0) {
|
||||||
|
const expandKey = getEditorKeybindings().getKeys("expandTools")[0]!;
|
||||||
if (this.expanded) {
|
if (this.expanded) {
|
||||||
statusParts.push(theme.fg("dim", "(ctrl+o to collapse)"));
|
statusParts.push(`(${theme.fg("dim", expandKey)}${theme.fg("muted", " to collapse")})`);
|
||||||
} else {
|
} else {
|
||||||
statusParts.push(theme.fg("dim", `... ${hiddenLineCount} more lines (ctrl+o to expand)`));
|
statusParts.push(
|
||||||
|
theme.fg("muted", `... ${hiddenLineCount} more lines (`) +
|
||||||
|
theme.fg("dim", expandKey) +
|
||||||
|
theme.fg("muted", " to expand)"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { Box, Markdown, Spacer, Text } from "@mariozechner/pi-tui";
|
import { Box, getEditorKeybindings, Markdown, Spacer, Text } from "@mariozechner/pi-tui";
|
||||||
import type { BranchSummaryMessage } from "../../../core/messages.js";
|
import type { BranchSummaryMessage } from "../../../core/messages.js";
|
||||||
import { getMarkdownTheme, theme } from "../theme/theme.js";
|
import { getMarkdownTheme, theme } from "../theme/theme.js";
|
||||||
|
|
||||||
|
|
@ -41,7 +41,16 @@ export class BranchSummaryMessageComponent extends Box {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this.addChild(new Text(theme.fg("customMessageText", "Branch summary (ctrl+o to expand)"), 0, 0));
|
const expandKey = getEditorKeybindings().getKeys("expandTools")[0]!;
|
||||||
|
this.addChild(
|
||||||
|
new Text(
|
||||||
|
theme.fg("customMessageText", "Branch summary (") +
|
||||||
|
theme.fg("dim", expandKey) +
|
||||||
|
theme.fg("customMessageText", " to expand)"),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { Box, Markdown, Spacer, Text } from "@mariozechner/pi-tui";
|
import { Box, getEditorKeybindings, Markdown, Spacer, Text } from "@mariozechner/pi-tui";
|
||||||
import type { CompactionSummaryMessage } from "../../../core/messages.js";
|
import type { CompactionSummaryMessage } from "../../../core/messages.js";
|
||||||
import { getMarkdownTheme, theme } from "../theme/theme.js";
|
import { getMarkdownTheme, theme } from "../theme/theme.js";
|
||||||
|
|
||||||
|
|
@ -42,8 +42,15 @@ export class CompactionSummaryMessageComponent extends Box {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
const expandKey = getEditorKeybindings().getKeys("expandTools")[0]!;
|
||||||
this.addChild(
|
this.addChild(
|
||||||
new Text(theme.fg("customMessageText", `Compacted from ${tokenStr} tokens (ctrl+o to expand)`), 0, 0),
|
new Text(
|
||||||
|
theme.fg("customMessageText", `Compacted from ${tokenStr} tokens (`) +
|
||||||
|
theme.fg("dim", expandKey) +
|
||||||
|
theme.fg("customMessageText", " to expand)"),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import {
|
||||||
Box,
|
Box,
|
||||||
Container,
|
Container,
|
||||||
getCapabilities,
|
getCapabilities,
|
||||||
|
getEditorKeybindings,
|
||||||
getImageDimensions,
|
getImageDimensions,
|
||||||
Image,
|
Image,
|
||||||
imageFallback,
|
imageFallback,
|
||||||
|
|
@ -374,9 +375,15 @@ export class ToolExecutionComponent extends Container {
|
||||||
cachedSkipped = result.skippedCount;
|
cachedSkipped = result.skippedCount;
|
||||||
cachedWidth = width;
|
cachedWidth = width;
|
||||||
}
|
}
|
||||||
return cachedSkipped && cachedSkipped > 0
|
if (cachedSkipped && cachedSkipped > 0) {
|
||||||
? ["", theme.fg("toolOutput", `... (${cachedSkipped} earlier lines)`), ...cachedLines]
|
const expandKey = getEditorKeybindings().getKeys("expandTools")[0]!;
|
||||||
: cachedLines;
|
const hint =
|
||||||
|
theme.fg("muted", `... (${cachedSkipped} earlier lines, `) +
|
||||||
|
theme.fg("dim", expandKey) +
|
||||||
|
theme.fg("muted", " to expand)");
|
||||||
|
return ["", hint, ...cachedLines];
|
||||||
|
}
|
||||||
|
return cachedLines;
|
||||||
},
|
},
|
||||||
invalidate: () => {
|
invalidate: () => {
|
||||||
cachedWidth = undefined;
|
cachedWidth = undefined;
|
||||||
|
|
@ -469,7 +476,11 @@ export class ToolExecutionComponent extends Container {
|
||||||
.map((line: string) => (lang ? replaceTabs(line) : theme.fg("toolOutput", replaceTabs(line))))
|
.map((line: string) => (lang ? replaceTabs(line) : theme.fg("toolOutput", replaceTabs(line))))
|
||||||
.join("\n");
|
.join("\n");
|
||||||
if (remaining > 0) {
|
if (remaining > 0) {
|
||||||
text += theme.fg("toolOutput", `\n... (${remaining} more lines)`);
|
const expandKey = getEditorKeybindings().getKeys("expandTools")[0]!;
|
||||||
|
text +=
|
||||||
|
theme.fg("muted", `\n... (${remaining} more lines, `) +
|
||||||
|
theme.fg("dim", expandKey) +
|
||||||
|
theme.fg("muted", " to expand)");
|
||||||
}
|
}
|
||||||
|
|
||||||
const truncation = this.result.details?.truncation;
|
const truncation = this.result.details?.truncation;
|
||||||
|
|
@ -526,7 +537,11 @@ export class ToolExecutionComponent extends Container {
|
||||||
.map((line: string) => (lang ? replaceTabs(line) : theme.fg("toolOutput", replaceTabs(line))))
|
.map((line: string) => (lang ? replaceTabs(line) : theme.fg("toolOutput", replaceTabs(line))))
|
||||||
.join("\n");
|
.join("\n");
|
||||||
if (remaining > 0) {
|
if (remaining > 0) {
|
||||||
text += theme.fg("toolOutput", `\n... (${remaining} more lines, ${totalLines} total)`);
|
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)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (this.toolName === "edit") {
|
} else if (this.toolName === "edit") {
|
||||||
|
|
@ -584,7 +599,11 @@ export class ToolExecutionComponent extends Container {
|
||||||
|
|
||||||
text += `\n\n${displayLines.map((line: string) => theme.fg("toolOutput", line)).join("\n")}`;
|
text += `\n\n${displayLines.map((line: string) => theme.fg("toolOutput", line)).join("\n")}`;
|
||||||
if (remaining > 0) {
|
if (remaining > 0) {
|
||||||
text += theme.fg("toolOutput", `\n... (${remaining} more lines)`);
|
const expandKey = getEditorKeybindings().getKeys("expandTools")[0]!;
|
||||||
|
text +=
|
||||||
|
theme.fg("muted", `\n... (${remaining} more lines, `) +
|
||||||
|
theme.fg("dim", expandKey) +
|
||||||
|
theme.fg("muted", " to expand)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -625,7 +644,11 @@ export class ToolExecutionComponent extends Container {
|
||||||
|
|
||||||
text += `\n\n${displayLines.map((line: string) => theme.fg("toolOutput", line)).join("\n")}`;
|
text += `\n\n${displayLines.map((line: string) => theme.fg("toolOutput", line)).join("\n")}`;
|
||||||
if (remaining > 0) {
|
if (remaining > 0) {
|
||||||
text += theme.fg("toolOutput", `\n... (${remaining} more lines)`);
|
const expandKey = getEditorKeybindings().getKeys("expandTools")[0]!;
|
||||||
|
text +=
|
||||||
|
theme.fg("muted", `\n... (${remaining} more lines, `) +
|
||||||
|
theme.fg("dim", expandKey) +
|
||||||
|
theme.fg("muted", " to expand)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -670,7 +693,11 @@ export class ToolExecutionComponent extends Container {
|
||||||
|
|
||||||
text += `\n\n${displayLines.map((line: string) => theme.fg("toolOutput", line)).join("\n")}`;
|
text += `\n\n${displayLines.map((line: string) => theme.fg("toolOutput", line)).join("\n")}`;
|
||||||
if (remaining > 0) {
|
if (remaining > 0) {
|
||||||
text += theme.fg("toolOutput", `\n... (${remaining} more lines)`);
|
const expandKey = getEditorKeybindings().getKeys("expandTools")[0]!;
|
||||||
|
text +=
|
||||||
|
theme.fg("muted", `\n... (${remaining} more lines, `) +
|
||||||
|
theme.fg("dim", expandKey) +
|
||||||
|
theme.fg("muted", " to expand)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,9 @@ export type EditorAction =
|
||||||
| "selectConfirm"
|
| "selectConfirm"
|
||||||
| "selectCancel"
|
| "selectCancel"
|
||||||
// Clipboard
|
// Clipboard
|
||||||
| "copy";
|
| "copy"
|
||||||
|
// Tool output
|
||||||
|
| "expandTools";
|
||||||
|
|
||||||
// Re-export KeyId from keys.ts
|
// Re-export KeyId from keys.ts
|
||||||
export type { KeyId };
|
export type { KeyId };
|
||||||
|
|
@ -75,6 +77,8 @@ export const DEFAULT_EDITOR_KEYBINDINGS: Required<EditorKeybindingsConfig> = {
|
||||||
selectCancel: ["escape", "ctrl+c"],
|
selectCancel: ["escape", "ctrl+c"],
|
||||||
// Clipboard
|
// Clipboard
|
||||||
copy: "ctrl+c",
|
copy: "ctrl+c",
|
||||||
|
// Tool output
|
||||||
|
expandTools: "ctrl+o",
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue