Skip to content

Commit 921b980

Browse files
ariane-emoryactions-userrekram1-node
authored
feat: add messages_last_user command to scroll TUI to last user message (implements anomalyco#4847) (anomalyco#4855)
Co-authored-by: GitHub Action <action@github.com> Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
1 parent c5b4cc8 commit 921b980

4 files changed

Lines changed: 37 additions & 0 deletions

File tree

packages/opencode/src/cli/cmd/tui/routes/session/index.tsx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,37 @@ export function Session() {
557557
dialog.clear()
558558
},
559559
},
560+
{
561+
title: "Jump to last user message",
562+
value: "session.messages_last_user",
563+
keybind: "messages_last_user",
564+
category: "Session",
565+
onSelect: () => {
566+
const messages = sync.data.message[route.sessionID]
567+
if (!messages || !messages.length) return
568+
569+
// Find the most recent user message with non-ignored, non-synthetic text parts
570+
for (let i = messages.length - 1; i >= 0; i--) {
571+
const message = messages[i]
572+
if (!message || message.role !== "user") continue
573+
574+
const parts = sync.data.part[message.id]
575+
if (!parts || !Array.isArray(parts)) continue
576+
577+
const hasValidTextPart = parts.some(
578+
(part) => part && part.type === "text" && !part.synthetic && !part.ignored,
579+
)
580+
581+
if (hasValidTextPart) {
582+
const child = scroll.getChildren().find((child) => {
583+
return child.id === message.id
584+
})
585+
if (child) scroll.scrollBy(child.y - scroll.y - 1)
586+
break
587+
}
588+
}
589+
},
590+
},
560591
{
561592
title: "Copy last assistant message",
562593
value: "messages.copy",

packages/opencode/src/config/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@ export namespace Config {
418418
.describe("Scroll messages down by half page"),
419419
messages_first: z.string().optional().default("ctrl+g,home").describe("Navigate to first message"),
420420
messages_last: z.string().optional().default("ctrl+alt+g,end").describe("Navigate to last message"),
421+
messages_last_user: z.string().optional().default("none").describe("Navigate to last user message"),
421422
messages_copy: z.string().optional().default("<leader>y").describe("Copy message"),
422423
messages_undo: z.string().optional().default("<leader>u").describe("Undo message"),
423424
messages_redo: z.string().optional().default("<leader>r").describe("Redo message"),

packages/sdk/js/src/gen/types.gen.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,10 @@ export type KeybindsConfig = {
796796
* Navigate to last message
797797
*/
798798
messages_last?: string
799+
/**
800+
* Navigate to last user message
801+
*/
802+
messages_last_user?: string
799803
/**
800804
* Copy message
801805
*/

packages/web/src/content/docs/keybinds.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ OpenCode has a list of keybinds that you can customize through the OpenCode conf
3535
"messages_copy": "<leader>y",
3636
"messages_undo": "<leader>u",
3737
"messages_redo": "<leader>r",
38+
"messages_last_user": "none",
3839
"messages_toggle_conceal": "<leader>h",
3940
"model_list": "<leader>m",
4041
"model_cycle_recent": "f2",

0 commit comments

Comments
 (0)