diff --git a/packages/app/src/components/prompt-input.tsx b/packages/app/src/components/prompt-input.tsx index 8e8c3c895b4..984888c35d8 100644 --- a/packages/app/src/components/prompt-input.tsx +++ b/packages/app/src/components/prompt-input.tsx @@ -911,31 +911,13 @@ export const PromptInput: Component = (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 diff --git a/packages/app/src/components/prompt-input/history.test.ts b/packages/app/src/components/prompt-input/history.test.ts index a37fdad6777..b7a4f896b88 100644 --- a/packages/app/src/components/prompt-input/history.test.ts +++ b/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) }) }) diff --git a/packages/app/src/components/prompt-input/history.ts b/packages/app/src/components/prompt-input/history.ts index f26f8084871..c279a3ed563 100644 --- a/packages/app/src/components/prompt-input/history.ts +++ b/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 {