|
|
@@ -25,10 +25,11 @@ import { useSync } from "@tui/context/sync"
|
|
|
import { useEvent } from "@tui/context/event"
|
|
|
import { editorSelectionKey, useEditorContext, type EditorSelection } from "@tui/context/editor"
|
|
|
import { MessageID, PartID } from "@/session/schema"
|
|
|
+import { promptOffsetWidth } from "@/cli/cmd/prompt-display"
|
|
|
import { createStore, produce, unwrap } from "solid-js/store"
|
|
|
import { usePromptHistory, type PromptInfo } from "./history"
|
|
|
import { computePromptTraits } from "./traits"
|
|
|
-import { assign, expandPastedTextPlaceholders } from "./part"
|
|
|
+import { assign, expandPastedTextPlaceholders, expandTrackedPastedText } from "./part"
|
|
|
import { usePromptStash } from "./stash"
|
|
|
import { DialogStash } from "../dialog-stash"
|
|
|
import { type AutocompleteRef, Autocomplete } from "./autocomplete"
|
|
|
@@ -1109,23 +1110,15 @@ export function Prompt(props: PromptProps) {
|
|
|
}
|
|
|
|
|
|
const messageID = MessageID.ascending()
|
|
|
- let inputText = store.prompt.input
|
|
|
-
|
|
|
- // Expand pasted text inline before submitting
|
|
|
- const allExtmarks = input.extmarks.getAllForTypeId(promptPartTypeId)
|
|
|
- const sortedExtmarks = allExtmarks.sort((a: { start: number }, b: { start: number }) => b.start - a.start)
|
|
|
-
|
|
|
- for (const extmark of sortedExtmarks) {
|
|
|
- const partIndex = store.extmarkToPartIndex.get(extmark.id)
|
|
|
- if (partIndex !== undefined) {
|
|
|
- const part = store.prompt.parts[partIndex]
|
|
|
- if (part?.type === "text" && part.text) {
|
|
|
- const before = inputText.slice(0, extmark.start)
|
|
|
- const after = inputText.slice(extmark.end)
|
|
|
- inputText = before + part.text + after
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ const inputText = expandTrackedPastedText(
|
|
|
+ store.prompt.input,
|
|
|
+ input.extmarks.getAllForTypeId(promptPartTypeId).flatMap((extmark) => {
|
|
|
+ const partIndex = store.extmarkToPartIndex.get(extmark.id)
|
|
|
+ const part = partIndex === undefined ? undefined : store.prompt.parts[partIndex]
|
|
|
+ if (part?.type !== "text") return []
|
|
|
+ return [{ start: extmark.start, end: extmark.end, text: part.text }]
|
|
|
+ }),
|
|
|
+ )
|
|
|
|
|
|
// Filter out text parts (pasted content) since they're now expanded inline
|
|
|
const nonTextParts = store.prompt.parts.filter((part) => part.type !== "text")
|
|
|
@@ -1242,9 +1235,9 @@ export function Prompt(props: PromptProps) {
|
|
|
const exit = useExit()
|
|
|
|
|
|
function pasteText(text: string, virtualText: string) {
|
|
|
- const currentOffset = input.visualCursor.offset
|
|
|
+ const currentOffset = input.cursorOffset
|
|
|
const extmarkStart = currentOffset
|
|
|
- const extmarkEnd = extmarkStart + virtualText.length
|
|
|
+ const extmarkEnd = extmarkStart + promptOffsetWidth(virtualText)
|
|
|
|
|
|
input.insertText(virtualText + " ")
|
|
|
|
|
|
@@ -1336,7 +1329,7 @@ export function Prompt(props: PromptProps) {
|
|
|
}
|
|
|
|
|
|
async function pasteAttachment(file: { filename?: string; filepath?: string; content: string; mime: string }) {
|
|
|
- const currentOffset = input.visualCursor.offset
|
|
|
+ const currentOffset = input.cursorOffset
|
|
|
const extmarkStart = currentOffset
|
|
|
const pdf = file.mime === "application/pdf"
|
|
|
const count = store.prompt.parts.filter((x) => {
|