undo/redo

This commit is contained in:
Dax Raad 2025-09-28 03:44:11 -04:00
parent 44e8bea4bb
commit c61cc1b635
3 changed files with 72 additions and 2 deletions

View file

@ -110,12 +110,47 @@ export function Autocomplete(props: {
{
display: "/undo",
description: "undo the last message",
onSelect: () => {},
onSelect: () => {
const revert = s.revert?.messageID
const message = (sync.data.message[s.id] ?? []).findLast(
(x) => (!revert || x.id < revert) && x.role === "user",
)
if (!message) return
sdk.session.revert({
path: {
id: s.id,
},
body: {
messageID: message.id,
},
})
},
},
{
display: "/redo",
description: "redo the last message",
onSelect: () => {},
onSelect: () => {
const messageID = s.revert?.messageID
if (!messageID) return
const messages = sync.data.message[s.id] ?? []
const message = messages.find((x) => x.role === "user" && x.id > messageID)
if (!message) {
sdk.session.unrevert({
path: {
id: s.id,
},
})
return
}
sdk.session.revert({
path: {
id: s.id,
},
body: {
messageID: message.id,
},
})
},
},
{
display: "/compact",

View file

@ -56,6 +56,9 @@ export const { use: useKeybind, provider: KeybindProvider } = createSimpleContex
if (store.leader && evt.name) {
setImmediate(() => {
if (focus && renderer.currentFocusedRenderable === focus) {
focus.focus()
}
leader(false)
})
}

View file

@ -102,6 +102,19 @@ export function Session() {
},
])
const revert = createMemo(() => {
const s = session()
if (!s) return
const messageID = s.revert?.messageID
if (!messageID) return
const reverted = messages().filter((x) => x.id >= messageID && x.role === "user")
return {
messageID,
reverted,
}
})
return (
<box paddingTop={1} paddingBottom={1} paddingLeft={2} paddingRight={2} flexGrow={1}>
<Show when={session()}>
@ -118,6 +131,25 @@ export function Session() {
<For each={messages()}>
{(message, index) => (
<Switch>
<Match when={message.id === revert()?.messageID}>
<box
marginTop={1}
flexShrink={0}
border={["left"]}
customBorderChars={SplitBorder.customBorderChars}
borderColor={Theme.backgroundPanel}
>
<box paddingTop={1} paddingBottom={1} paddingLeft={2} backgroundColor={Theme.backgroundPanel}>
<text fg={Theme.textMuted}>{revert()!.reverted.length} message reverted</text>
<text fg={Theme.textMuted}>
<span style={{ fg: Theme.text }}>{keybind.print("messages_redo")}</span> or /redo to restore
</text>
</box>
</box>
</Match>
<Match when={revert()?.messageID && message.id >= revert()!.messageID}>
<></>
</Match>
<Match when={message.role === "user"}>
<UserMessage message={message as UserMessage} parts={sync.data.part[message.id] ?? []} />
</Match>