From d13a2a7cf63f1bedcfc35a546cda79a8fbafa7ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Thu, 26 Feb 2026 19:32:51 +0100 Subject: [PATCH] fix(chat): fix ghost text overlay positioning for caret sync Move ghost text into a separate absolutely-positioned overlay div that mirrors the textarea's scroll position, replacing the previous inline span approach. Add a hidden span to offset the visible ghost text to the correct position after the current input, ensuring the ghost text stays aligned with the caret regardless of scroll state. --- .../src/components/chat/PromptInput.tsx | 13 +++++++++--- .../webview-ui/src/styles/chat.css | 21 +++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/packages/kilo-vscode/webview-ui/src/components/chat/PromptInput.tsx b/packages/kilo-vscode/webview-ui/src/components/chat/PromptInput.tsx index fbdca63beab..c0417d3fa0d 100644 --- a/packages/kilo-vscode/webview-ui/src/components/chat/PromptInput.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/chat/PromptInput.tsx @@ -39,6 +39,7 @@ export const PromptInput: Component = () => { let textareaRef: HTMLTextAreaElement | undefined let highlightRef: HTMLDivElement | undefined + let ghostRef: HTMLDivElement | undefined let dropdownRef: HTMLDivElement | undefined let debounceTimer: ReturnType | undefined let requestCounter = 0 @@ -158,6 +159,9 @@ export const PromptInput: Component = () => { if (highlightRef && textareaRef) { highlightRef.scrollTop = textareaRef.scrollTop } + if (ghostRef && textareaRef) { + ghostRef.scrollTop = textareaRef.scrollTop + } } const adjustHeight = () => { @@ -316,10 +320,13 @@ export const PromptInput: Component = () => { )} - - {ghostText()} - + + +