mirror of
https://github.com/aljazceru/opencode.git
synced 2025-12-24 03:04:21 +01:00
tui: restore full text when editing prompts with summarized content (#4030)
This commit is contained in:
@@ -101,16 +101,81 @@ export function Prompt(props: PromptProps) {
|
||||
value: "prompt.editor",
|
||||
onSelect: async (dialog, trigger) => {
|
||||
dialog.clear()
|
||||
const value = trigger === "prompt" ? "" : input.plainText
|
||||
|
||||
// replace summarized text parts with the actual text
|
||||
const text = store.prompt.parts
|
||||
.filter((p) => p.type === "text")
|
||||
.reduce((acc, p) => {
|
||||
if (!p.source) return acc
|
||||
return acc.replace(p.source.text.value, p.text)
|
||||
}, store.prompt.input)
|
||||
|
||||
const nonTextParts = store.prompt.parts.filter((p) => p.type !== "text")
|
||||
|
||||
const value = trigger === "prompt" ? "" : text
|
||||
const content = await Editor.open({ value, renderer })
|
||||
if (content) {
|
||||
input.setText(content, { history: false })
|
||||
setStore("prompt", {
|
||||
input: content,
|
||||
parts: [],
|
||||
if (!content) return
|
||||
|
||||
input.setText(content, { history: false })
|
||||
|
||||
// Update positions for nonTextParts based on their location in new content
|
||||
// Filter out parts whose virtual text was deleted
|
||||
// this handles a case where the user edits the text in the editor
|
||||
// such that the virtual text moves around or is deleted
|
||||
const updatedNonTextParts = nonTextParts
|
||||
.map((part) => {
|
||||
let virtualText = ""
|
||||
if (part.type === "file" && part.source?.text) {
|
||||
virtualText = part.source.text.value
|
||||
} else if (part.type === "agent" && part.source) {
|
||||
virtualText = part.source.value
|
||||
}
|
||||
|
||||
if (!virtualText) return part
|
||||
|
||||
const newStart = content.indexOf(virtualText)
|
||||
// if the virtual text is deleted, remove the part
|
||||
if (newStart === -1) return null
|
||||
|
||||
const newEnd = newStart + virtualText.length
|
||||
|
||||
if (part.type === "file" && part.source?.text) {
|
||||
return {
|
||||
...part,
|
||||
source: {
|
||||
...part.source,
|
||||
text: {
|
||||
...part.source.text,
|
||||
start: newStart,
|
||||
end: newEnd,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if (part.type === "agent" && part.source) {
|
||||
return {
|
||||
...part,
|
||||
source: {
|
||||
...part.source,
|
||||
start: newStart,
|
||||
end: newEnd,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return part
|
||||
})
|
||||
input.cursorOffset = Bun.stringWidth(content)
|
||||
}
|
||||
.filter((part) => part !== null)
|
||||
|
||||
setStore("prompt", {
|
||||
input: content,
|
||||
// keep only the non-text parts because the text parts were
|
||||
// already expanded inline
|
||||
parts: updatedNonTextParts,
|
||||
})
|
||||
restoreExtmarksFromParts(updatedNonTextParts)
|
||||
input.cursorOffset = Bun.stringWidth(content)
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user