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 = {