diff --git a/src/ui/views/PromptInput.tsx b/src/ui/views/PromptInput.tsx index 19342da..48eb659 100644 --- a/src/ui/views/PromptInput.tsx +++ b/src/ui/views/PromptInput.tsx @@ -43,7 +43,13 @@ import { } from "../core/file-mentions"; import type { FileMentionItem } from "../core/file-mentions"; import { readClipboardImageAsync } from "../core/clipboard"; -import { useTerminalInput, usePasteHandling, useHistoryNavigation } from "../hooks"; +import { + useTerminalInput, + usePasteHandling, + useHistoryNavigation, + getPromptCursorPlacement, + usePromptTerminalCursor, +} from "../hooks"; import type { InputKey } from "../hooks"; import { useHiddenTerminalCursor, @@ -108,7 +114,11 @@ const PromptPrefixLine = React.memo(function PromptPrefixLine({ busy }: { busy: }, [busy]); const prefix = busy ? `${SPINNER_FRAMES[spinnerIndex]} ` : "> "; - return {prefix}; + return ( + + {prefix} + + ); }); export const PromptInput = React.memo(function PromptInput({ @@ -202,9 +212,17 @@ export const PromptInput = React.memo(function PromptInput({ () => showMenu || showSkillsDropdown || openRawModelDropdown || showModelDropdown || showFileMentionMenu, [showMenu, showSkillsDropdown, showModelDropdown, openRawModelDropdown, showFileMentionMenu] ); - // The prompt draws its own inverse-video cursor inside the text. Keep the - // native terminal cursor hidden so wrapping edges do not show two cursors. - const hideNativeCursor = !disabled; + + const cursorPlacement = useMemo( + () => getPromptCursorPlacement(buffer, screenWidth, 2, footerText), + [buffer, footerText, screenWidth] + ); + const usePositionedCursor = !disabled && hasTerminalFocus && !showFooterText; + useTerminalFocusReporting(stdout, !disabled); + useTerminalExtendedKeys(stdout, !disabled); + useBracketedPaste(stdout, !disabled); + usePromptTerminalCursor(stdout, cursorPlacement, usePositionedCursor); + useHiddenTerminalCursor(stdout, !disabled && !usePositionedCursor); const refreshFileMentionItems = React.useCallback(() => { setFileMentionItems(scanFileMentionItems(projectRoot)); @@ -560,10 +578,6 @@ export const PromptInput = React.memo(function PromptInput({ }, { isActive: !disabled } ); - useTerminalFocusReporting(stdout, !disabled); - useTerminalExtendedKeys(stdout, !disabled); - useBracketedPaste(stdout, !disabled); - useHiddenTerminalCursor(stdout, hideNativeCursor); function undo(): void { const previous = undoPromptEdit(undoRedoRef.current, buffer); @@ -742,6 +756,7 @@ export const PromptInput = React.memo(function PromptInput({ ) : null} {/* Input */} - {renderBufferWithCursor(buffer, !disabled && hasTerminalFocus, placeholder, pastesRef.current)} - {inlineHint ? {inlineHint} : null} + + {renderBufferWithCursor(buffer, !disabled && hasTerminalFocus, placeholder, pastesRef.current)} + {inlineHint ? {inlineHint} : null} +