Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
fd5b8cf
feat: inial implementation to resolve 4847, seems to work so far.
ariane-emory Nov 28, 2025
3dad45f
tidy: rename it to messages_last_user for consistency with other comm…
ariane-emory Nov 28, 2025
4bd7470
Add messages_last_user to generated TypeScript SDK types
ariane-emory Nov 28, 2025
d425494
Merge remote-tracking branch 'upstream/dev' into feat/messages-last-u…
ariane-emory Nov 28, 2025
a97f5f2
Merge remote-tracking branch 'upstream/dev' into feat/messages-last-u…
ariane-emory Nov 28, 2025
6b5ed91
...
ariane-emory Nov 28, 2025
2134af4
...
ariane-emory Nov 28, 2025
d3ed479
Merge remote-tracking branch 'upstream/dev' into feat/messages-last-u…
ariane-emory Nov 28, 2025
fb404c0
Merge remote-tracking branch 'upstream/dev' into feat/messages-last-u…
ariane-emory Nov 29, 2025
96b4ddd
Merge remote-tracking branch 'upstream/dev' into feat/messages-last-u…
ariane-emory Nov 29, 2025
1e03cbf
Merge remote-tracking branch 'upstream/dev' into feat/messages-last-u…
ariane-emory Nov 29, 2025
fbe6aa6
Merge remote-tracking branch 'upstream/dev' into feat/messages-last-u…
ariane-emory Nov 30, 2025
4c0cdc1
Merge remote-tracking branch 'upstream/dev' into feat/messages-last-u…
ariane-emory Nov 30, 2025
d9cd2a4
Merge remote-tracking branch 'upstream/dev' into feat/messages-last-u…
ariane-emory Nov 30, 2025
ddd8a60
Merge remote-tracking branch 'upstream/dev' into feat/messages-last-u…
ariane-emory Dec 1, 2025
b972987
chore: format code
actions-user Dec 1, 2025
dc217d0
Update Nix flake.lock and hashes
actions-user Dec 1, 2025
b596472
Merge remote-tracking branch 'upstream/dev' into feat/messages-last-u…
ariane-emory Dec 1, 2025
3700106
Merge upstream/dev into feat/messages-last-user-command
ariane-emory Dec 1, 2025
cb63cb6
Merge remote-tracking branch 'upstream/dev' into feat/messages-last-u…
ariane-emory Dec 2, 2025
b67fe55
Merge remote-tracking branch 'upstream/dev' into feat/messages-last-u…
ariane-emory Dec 2, 2025
63012c8
Merge remote-tracking branch 'upstream/dev' into feat/messages-last-u…
ariane-emory Dec 2, 2025
f03026c
tweak: use <leader>p as a default keybinding for messages_user_last.
ariane-emory Dec 2, 2025
c40ba27
Merge remote-tracking branch 'upstream/dev' into feat/messages-last-u…
ariane-emory Dec 2, 2025
36e50ad
Merge remote-tracking branch 'upstream/dev' into feat/messages-last-u…
ariane-emory Dec 3, 2025
bb75d23
Merge remote-tracking branch 'upstream/dev' into feat/messages-last-u…
ariane-emory Dec 3, 2025
c5cde9f
tweak: do not assign a default keybinding for messages_last_user.
ariane-emory Dec 3, 2025
b97a839
Change keybind for messages_last_user to 'none'
rekram1-node Dec 3, 2025
c0c809f
Set default for messages_last_user to 'none'
rekram1-node Dec 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,37 @@ export function Session() {
dialog.clear()
},
},
{
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",
Expand Down
1 change: 1 addition & 0 deletions packages/opencode/src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand Down
4 changes: 4 additions & 0 deletions packages/sdk/js/src/gen/types.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,10 @@ export type KeybindsConfig = {
* Navigate to last message
*/
messages_last?: string
/**
* Navigate to last user message
*/
messages_last_user?: string
/**
* Copy message
*/
Expand Down
1 change: 1 addition & 0 deletions packages/web/src/content/docs/keybinds.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down