diff --git a/packages/opencode/src/cli/cmd/tui/component/dialog-command.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-command.tsx index 91150da9..0dfefe42 100644 --- a/packages/opencode/src/cli/cmd/tui/component/dialog-command.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/dialog-command.tsx @@ -47,6 +47,9 @@ function init() { } } }, + show() { + dialog.replace(() => ) + }, register(cb: () => CommandOption[]) { const results = createMemo(cb) setRegistrations((arr) => [results, ...arr]) @@ -90,7 +93,10 @@ function DialogCommand(props: { options: CommandOption[] }) { return ( ({ ...x, footer: x.keybind ? keybind.print(x.keybind) : undefined }))} + options={props.options.map((x) => ({ + ...x, + footer: x.keybind ? keybind.print(x.keybind) : undefined, + }))} /> ) } diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx index 92798b94..e455f99b 100644 --- a/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx @@ -270,6 +270,11 @@ export function Autocomplete(props: { description: "show help", onSelect: () => command.trigger("help.show"), }, + { + display: "/commands", + description: "show all commands", + onSelect: () => command.show(), + }, ) const max = firstBy(results, [(x) => x.display.length, "desc"])?.display.length if (!max) return results diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx index c5a195f3..8c52ba3a 100644 --- a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx @@ -563,10 +563,11 @@ export function Prompt(props: PromptProps) { if (store.mode === "normal") autocomplete.onKeyDown(e) if (!autocomplete.visible) { if ( - (e.name === "up" && input.cursorOffset === 0) || - (e.name === "down" && input.cursorOffset === input.plainText.length) + (keybind.match("history_previous", e) && input.cursorOffset === 0) || + (keybind.match("history_next", e) && + input.cursorOffset === input.plainText.length) ) { - const direction = e.name === "up" ? -1 : 1 + const direction = keybind.match("history_previous", e) ? -1 : 1 const item = history.move(direction, input.plainText) if (item) { diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index ac1165ea..f84cca73 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -385,7 +385,11 @@ export namespace Config { .optional() .default("ctrl+x") .describe("Leader key for keybind combinations"), - app_exit: z.string().optional().default("ctrl+c,ctrl+d,q").describe("Exit the application"), + app_exit: z + .string() + .optional() + .default("ctrl+c,ctrl+d,q") + .describe("Exit the application"), editor_open: z.string().optional().default("e").describe("Open external editor"), theme_list: z.string().optional().default("t").describe("List available themes"), sidebar_toggle: z.string().optional().default("b").describe("Toggle sidebar"), @@ -462,6 +466,8 @@ export namespace Config { .optional() .default("shift+enter,ctrl+j") .describe("Insert newline in input"), + history_previous: z.string().optional().default("up").describe("Previous history item"), + history_next: z.string().optional().default("down").describe("Previous history item"), }) .strict() .meta({ diff --git a/packages/sdk/js/src/gen/types.gen.ts b/packages/sdk/js/src/gen/types.gen.ts index fce8d203..994fa824 100644 --- a/packages/sdk/js/src/gen/types.gen.ts +++ b/packages/sdk/js/src/gen/types.gen.ts @@ -150,6 +150,14 @@ export type KeybindsConfig = { * Insert newline in input */ input_newline?: string + /** + * Previous history item + */ + history_previous?: string + /** + * Previous history item + */ + history_next?: string } export type AgentConfig = {