From b6eee49172119104b201fee988bcd60cb8eca45f Mon Sep 17 00:00:00 2001 From: cpacker Date: Sun, 30 Nov 2025 19:47:51 -0800 Subject: [PATCH] fix: patch newline inserts in input --- src/cli/components/PasteAwareTextInput.tsx | 17 ++++++++++++----- src/cli/helpers/pasteRegistry.ts | 6 +++++- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/cli/components/PasteAwareTextInput.tsx b/src/cli/components/PasteAwareTextInput.tsx index 444a49b..69e66a3 100644 --- a/src/cli/components/PasteAwareTextInput.tsx +++ b/src/cli/components/PasteAwareTextInput.tsx @@ -28,6 +28,11 @@ function countLines(text: string): number { return (text.match(/\r\n|\r|\n/g) || []).length + 1; } +/** Replace newlines with visual indicator for display */ +function sanitizeForDisplay(text: string): string { + return text.replace(/\r\n|\r|\n/g, "↵"); +} + export function PasteAwareTextInput({ value, onChange, @@ -110,14 +115,15 @@ export function PasteAwareTextInput({ setNudgeCursorOffset(nextCaret); caretOffsetRef.current = nextCaret; } else { + const displayText = sanitizeForDisplay(translated); const newDisplay = - displayValue.slice(0, at) + translated + displayValue.slice(at); + displayValue.slice(0, at) + displayText + displayValue.slice(at); const newActual = actualValue.slice(0, at) + translated + actualValue.slice(at); setDisplayValue(newDisplay); setActualValue(newActual); onChange(newDisplay); - const nextCaret = at + translated.length; + const nextCaret = at + displayText.length; setNudgeCursorOffset(nextCaret); caretOffsetRef.current = nextCaret; } @@ -211,9 +217,10 @@ export function PasteAwareTextInput({ return; } - // Otherwise, insert the translated text inline + // Otherwise, insert the translated text inline (sanitize newlines for display) + const displayText = sanitizeForDisplay(translated); const newDisplayValue = - a.slice(0, lcp) + translated + a.slice(a.length - lcs); + a.slice(0, lcp) + displayText + a.slice(a.length - lcs); const newActualValue = actualValue.slice(0, lcp) + translated + @@ -222,7 +229,7 @@ export function PasteAwareTextInput({ setDisplayValue(newDisplayValue); setActualValue(newActualValue); onChange(newDisplayValue); - const nextCaret = lcp + translated.length; + const nextCaret = lcp + displayText.length; setNudgeCursorOffset(nextCaret); caretOffsetRef.current = nextCaret; return; diff --git a/src/cli/helpers/pasteRegistry.ts b/src/cli/helpers/pasteRegistry.ts index 14f5909..8988954 100644 --- a/src/cli/helpers/pasteRegistry.ts +++ b/src/cli/helpers/pasteRegistry.ts @@ -25,7 +25,8 @@ export function allocatePaste(content: string): number { export function resolvePlaceholders(text: string): string { if (!text) return text; - return text.replace( + // First resolve text placeholders + let result = text.replace( /\[Pasted text #(\d+) \+(\d+) lines\]/g, (_match, idStr) => { const id = Number(idStr); @@ -33,6 +34,9 @@ export function resolvePlaceholders(text: string): string { return content !== undefined ? content : _match; }, ); + // Then convert visual newline indicators back to real newlines + result = result.replace(/↵/g, "\n"); + return result; } export function extractTextPlaceholderIds(text: string): number[] {