summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAriane Emory <[email protected]>2025-12-03 13:30:11 -0500
committerGitHub <[email protected]>2025-12-03 12:30:11 -0600
commit921b98066d4f3d1f464435eaa3d28c1edd949cc0 (patch)
treecbb56f823b4b6406d0d47c086f8e4dc5fbbe9aa6
parentc5b4cc80cc4ad07dfe68847fec518779f2cce65c (diff)
downloadopencode-921b98066d4f3d1f464435eaa3d28c1edd949cc0.tar.gz
opencode-921b98066d4f3d1f464435eaa3d28c1edd949cc0.zip
feat: add messages_last_user command to scroll TUI to last user message (implements #4847) (#4855)
Co-authored-by: GitHub Action <[email protected]> Co-authored-by: Aiden Cline <[email protected]>
-rw-r--r--packages/opencode/src/cli/cmd/tui/routes/session/index.tsx31
-rw-r--r--packages/opencode/src/config/config.ts1
-rw-r--r--packages/sdk/js/src/gen/types.gen.ts4
-rw-r--r--packages/web/src/content/docs/keybinds.mdx1
4 files changed, 37 insertions, 0 deletions
diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
index 54020af93..b97b89c12 100644
--- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
+++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
@@ -558,6 +558,37 @@ export function Session() {
},
},
{
+ title: "Jump to last user message",
+ value: "session.messages_last_user",
+ keybind: "messages_last_user",
+ category: "Session",
+ onSelect: () => {
+ const messages = sync.data.message[route.sessionID]
+ if (!messages || !messages.length) return
+
+ // Find the most recent user message with non-ignored, non-synthetic text parts
+ for (let i = messages.length - 1; i >= 0; i--) {
+ const message = messages[i]
+ if (!message || message.role !== "user") continue
+
+ const parts = sync.data.part[message.id]
+ if (!parts || !Array.isArray(parts)) continue
+
+ const hasValidTextPart = parts.some(
+ (part) => part && part.type === "text" && !part.synthetic && !part.ignored,
+ )
+
+ if (hasValidTextPart) {
+ const child = scroll.getChildren().find((child) => {
+ return child.id === message.id
+ })
+ if (child) scroll.scrollBy(child.y - scroll.y - 1)
+ break
+ }
+ }
+ },
+ },
+ {
title: "Copy last assistant message",
value: "messages.copy",
keybind: "messages_copy",
diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts
index 9cae9370d..09a9e63b9 100644
--- a/packages/opencode/src/config/config.ts
+++ b/packages/opencode/src/config/config.ts
@@ -418,6 +418,7 @@ export namespace Config {
.describe("Scroll messages down by half page"),
messages_first: z.string().optional().default("ctrl+g,home").describe("Navigate to first message"),
messages_last: z.string().optional().default("ctrl+alt+g,end").describe("Navigate to last message"),
+ messages_last_user: z.string().optional().default("none").describe("Navigate to last user message"),
messages_copy: z.string().optional().default("<leader>y").describe("Copy message"),
messages_undo: z.string().optional().default("<leader>u").describe("Undo message"),
messages_redo: z.string().optional().default("<leader>r").describe("Redo message"),
diff --git a/packages/sdk/js/src/gen/types.gen.ts b/packages/sdk/js/src/gen/types.gen.ts
index d26c6ec2c..8ecb12935 100644
--- a/packages/sdk/js/src/gen/types.gen.ts
+++ b/packages/sdk/js/src/gen/types.gen.ts
@@ -797,6 +797,10 @@ export type KeybindsConfig = {
*/
messages_last?: string
/**
+ * Navigate to last user message
+ */
+ messages_last_user?: string
+ /**
* Copy message
*/
messages_copy?: string
diff --git a/packages/web/src/content/docs/keybinds.mdx b/packages/web/src/content/docs/keybinds.mdx
index 80a74c159..a32756e18 100644
--- a/packages/web/src/content/docs/keybinds.mdx
+++ b/packages/web/src/content/docs/keybinds.mdx
@@ -35,6 +35,7 @@ OpenCode has a list of keybinds that you can customize through the OpenCode conf
"messages_copy": "<leader>y",
"messages_undo": "<leader>u",
"messages_redo": "<leader>r",
+ "messages_last_user": "none",
"messages_toggle_conceal": "<leader>h",
"model_list": "<leader>m",
"model_cycle_recent": "f2",