Bläddra i källkod

fix(app): only navigate prompt history at input boundaries (#13690)

Shoubhit Dash 6 månader sedan
förälder
incheckning
3c85cf4fac

+ 2 - 20
packages/app/src/components/prompt-input.tsx

@@ -911,31 +911,13 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
       if (!collapsed) return
 
       const cursorPosition = getCursorPosition(editorRef)
-      const textLength = promptLength(prompt.current())
       const textContent = prompt
         .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
-      const atStart = cursorPosition <= (isEmpty ? 1 : 0)
-      const atEnd = cursorPosition >= (isEmpty ? textLength - 1 : textLength)
-      const allowUp = isEmpty || atStart || (!hasNewlines && !inHistory) || (inHistory && atEnd)
-      const allowDown = isEmpty || atEnd || (!hasNewlines && !inHistory) || (inHistory && atStart)
-
-      if (direction === "up") {
-        if (!allowUp) return
-        if (navigateHistory("up")) {
-          event.preventDefault()
-        }
-        return
-      }
-
-      if (!allowDown) return
-      if (navigateHistory("down")) {
+      if (!canNavigateHistoryAtCursor(direction, textContent, cursorPosition, store.historyIndex >= 0)) return
+      if (navigateHistory(direction)) {
         event.preventDefault()
       }
       return

+ 12 - 3
packages/app/src/components/prompt-input/history.test.ts

@@ -73,7 +73,7 @@ describe("prompt-input history", () => {
     expect(original[1].selection?.startLine).toBe(1)
   })
 
-  test("canNavigateHistoryAtCursor only allows multiline boundaries", () => {
+  test("canNavigateHistoryAtCursor only allows prompt boundaries", () => {
     const value = "a\nb\nc"
 
     expect(canNavigateHistoryAtCursor("up", value, 0)).toBe(true)
@@ -85,7 +85,16 @@ describe("prompt-input history", () => {
     expect(canNavigateHistoryAtCursor("up", value, 5)).toBe(false)
     expect(canNavigateHistoryAtCursor("down", value, 5)).toBe(true)
 
-    expect(canNavigateHistoryAtCursor("up", "abc", 1)).toBe(true)
-    expect(canNavigateHistoryAtCursor("down", "abc", 1)).toBe(true)
+    expect(canNavigateHistoryAtCursor("up", "abc", 0)).toBe(true)
+    expect(canNavigateHistoryAtCursor("down", "abc", 3)).toBe(true)
+    expect(canNavigateHistoryAtCursor("up", "abc", 1)).toBe(false)
+    expect(canNavigateHistoryAtCursor("down", "abc", 1)).toBe(false)
+
+    expect(canNavigateHistoryAtCursor("up", "abc", 0, true)).toBe(true)
+    expect(canNavigateHistoryAtCursor("up", "abc", 3, true)).toBe(true)
+    expect(canNavigateHistoryAtCursor("down", "abc", 0, true)).toBe(true)
+    expect(canNavigateHistoryAtCursor("down", "abc", 3, true)).toBe(true)
+    expect(canNavigateHistoryAtCursor("up", "abc", 1, true)).toBe(false)
+    expect(canNavigateHistoryAtCursor("down", "abc", 1, true)).toBe(false)
   })
 })

+ 6 - 4
packages/app/src/components/prompt-input/history.ts

@@ -4,11 +4,13 @@ const DEFAULT_PROMPT: Prompt = [{ type: "text", content: "", start: 0, end: 0 }]
 
 export const MAX_HISTORY = 100
 
-export function canNavigateHistoryAtCursor(direction: "up" | "down", text: string, cursor: number) {
-  if (!text.includes("\n")) return true
+export function canNavigateHistoryAtCursor(direction: "up" | "down", text: string, cursor: number, inHistory = false) {
   const position = Math.max(0, Math.min(cursor, text.length))
-  if (direction === "up") return !text.slice(0, position).includes("\n")
-  return !text.slice(position).includes("\n")
+  const atStart = position === 0
+  const atEnd = position === text.length
+  if (inHistory) return atStart || atEnd
+  if (direction === "up") return position === 0
+  return position === text.length
 }
 
 export function clonePromptParts(prompt: Prompt): Prompt {