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}
+