summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/components/prompt-input.tsx
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-02-12 19:58:43 -0600
committerAdam <[email protected]>2026-02-12 19:58:57 -0600
commit7f95cc64c57b439f58833d0300a1da93b3b893df (patch)
treed9a75b27dac2f1fcf5865bb3c98fbee28f489eb5 /packages/app/src/components/prompt-input.tsx
parentb525c03d205e37ad7527e6bd1749b324395dd6b7 (diff)
downloadopencode-7f95cc64c57b439f58833d0300a1da93b3b893df.tar.gz
opencode-7f95cc64c57b439f58833d0300a1da93b3b893df.zip
fix(app): prompt input quirks
Diffstat (limited to 'packages/app/src/components/prompt-input.tsx')
-rw-r--r--packages/app/src/components/prompt-input.tsx33
1 files changed, 26 insertions, 7 deletions
diff --git a/packages/app/src/components/prompt-input.tsx b/packages/app/src/components/prompt-input.tsx
index abc203aa1..8e8c3c895 100644
--- a/packages/app/src/components/prompt-input.tsx
+++ b/packages/app/src/components/prompt-input.tsx
@@ -38,7 +38,12 @@ import { useLanguage } from "@/context/language"
import { usePlatform } from "@/context/platform"
import { createTextFragment, getCursorPosition, setCursorPosition, setRangeEdge } from "./prompt-input/editor-dom"
import { createPromptAttachments, ACCEPTED_FILE_TYPES } from "./prompt-input/attachments"
-import { navigatePromptHistory, prependHistoryEntry, promptLength } from "./prompt-input/history"
+import {
+ canNavigateHistoryAtCursor,
+ navigatePromptHistory,
+ prependHistoryEntry,
+ promptLength,
+} from "./prompt-input/history"
import { createPromptSubmit } from "./prompt-input/submit"
import { PromptPopover, type AtOption, type SlashCommand } from "./prompt-input/slash-popover"
import { PromptContextItems } from "./prompt-input/context-items"
@@ -473,10 +478,7 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
const prev = node.previousSibling
const next = node.nextSibling
const prevIsBr = prev?.nodeType === Node.ELEMENT_NODE && (prev as HTMLElement).tagName === "BR"
- const nextIsBr = next?.nodeType === Node.ELEMENT_NODE && (next as HTMLElement).tagName === "BR"
- if (!prevIsBr && !nextIsBr) return false
- if (nextIsBr && !prevIsBr && prev) return false
- return true
+ return !!prevIsBr && !next
}
if (node.nodeType !== Node.ELEMENT_NODE) return false
const el = node as HTMLElement
@@ -496,6 +498,11 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
editorRef.appendChild(createPill(part))
}
}
+
+ const last = editorRef.lastChild
+ if (last?.nodeType === Node.ELEMENT_NODE && (last as HTMLElement).tagName === "BR") {
+ editorRef.appendChild(document.createTextNode("\u200B"))
+ }
}
createEffect(
@@ -729,7 +736,17 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
}
}
if (last.nodeType !== Node.TEXT_NODE) {
- range.setStartAfter(last)
+ const isBreak = last.nodeType === Node.ELEMENT_NODE && (last as HTMLElement).tagName === "BR"
+ const next = last.nextSibling
+ const emptyText = next?.nodeType === Node.TEXT_NODE && (next.textContent ?? "") === ""
+ if (isBreak && (!next || emptyText)) {
+ const placeholder = next && emptyText ? next : document.createTextNode("\u200B")
+ if (!next) last.parentNode?.insertBefore(placeholder, null)
+ placeholder.textContent = "\u200B"
+ range.setStart(placeholder, 0)
+ } else {
+ range.setStartAfter(last)
+ }
}
}
range.collapse(true)
@@ -899,6 +916,8 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
.current()
.map((part) => ("content" in part ? part.content : ""))
.join("")
+ const direction = event.key === "ArrowUp" ? "up" : "down"
+ if (!canNavigateHistoryAtCursor(direction, textContent, cursorPosition)) return
const isEmpty = textContent.trim() === "" || textLength <= 1
const hasNewlines = textContent.includes("\n")
const inHistory = store.historyIndex >= 0
@@ -907,7 +926,7 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
const allowUp = isEmpty || atStart || (!hasNewlines && !inHistory) || (inHistory && atEnd)
const allowDown = isEmpty || atEnd || (!hasNewlines && !inHistory) || (inHistory && atStart)
- if (event.key === "ArrowUp") {
+ if (direction === "up") {
if (!allowUp) return
if (navigateHistory("up")) {
event.preventDefault()