1
0
Эх сурвалжийг харах

fix(tui): copy pasted prompt content (#28156)

Shoubhit Dash 3 сар өмнө
parent
commit
564cde393e

+ 4 - 1
packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx

@@ -28,7 +28,7 @@ import { MessageID, PartID } from "@/session/schema"
 import { createStore, produce, unwrap } from "solid-js/store"
 import { usePromptHistory, type PromptInfo } from "./history"
 import { computePromptTraits } from "./traits"
-import { assign } from "./part"
+import { assign, expandPastedTextPlaceholders } from "./part"
 import { usePromptStash } from "./stash"
 import { DialogStash } from "../dialog-stash"
 import { type AutocompleteRef, Autocomplete } from "./autocomplete"
@@ -1544,6 +1544,9 @@ export function Prompt(props: PromptProps) {
               }}
               ref={(r: TextareaRenderable) => {
                 input = r
+                Object.assign(r, {
+                  getClipboardText: (text: string) => expandPastedTextPlaceholders(text, store.prompt.parts),
+                })
                 setInputTarget(r)
                 if (promptPartTypeId === 0) {
                   promptPartTypeId = input.extmarks.registerType("prompt-part")

+ 7 - 0
packages/opencode/src/cli/cmd/tui/component/prompt/part.ts

@@ -14,3 +14,10 @@ export function assign(part: Item): Item & { id: PartID } {
     id: PartID.ascending(),
   }
 }
+
+export function expandPastedTextPlaceholders(text: string, parts: PromptInfo["parts"]) {
+  return parts.reduce((result, part) => {
+    if (part.type !== "text" || !part.source?.text) return result
+    return result.replace(part.source.text.value, part.text)
+  }, text)
+}

+ 10 - 2
packages/opencode/src/cli/cmd/tui/util/selection.ts

@@ -7,6 +7,7 @@ type Toast = {
 
 type FocusableSelectionTarget = {
   hasSelection: () => boolean
+  getClipboardText?: (text: string) => string
 }
 
 type Renderer = {
@@ -23,10 +24,17 @@ type SelectionKeyEvent = {
 }
 
 export function copy(renderer: Renderer, toast: Toast): boolean {
-  const text = renderer.getSelection()?.getSelectedText()
+  const selection = renderer.getSelection()
+  if (!selection) return false
+
+  const text = selection.getSelectedText()
   if (!text) return false
 
-  Clipboard.copy(text)
+  const focus = renderer.currentFocusedRenderable
+  const clipboardText =
+    focus?.getClipboardText && selection.selectedRenderables.includes(focus) ? focus.getClipboardText(text) : text
+
+  Clipboard.copy(clipboardText)
     .then(() => toast.show({ message: "Copied to clipboard", variant: "info" }))
     .catch(toast.error)