From e5899d81c47bf66318f26679fce4768a4eae7ca9 Mon Sep 17 00:00:00 2001 From: Michael Chihlas Date: Sat, 14 Mar 2026 19:34:45 -0400 Subject: [PATCH] fix: param block detection with nested parens + cursor alignment The paren depth counter started at 0 and immediately matched before any '(' was counted, causing param blocks to be detected as ending on line 0. Added foundOpen flag to require at least one '(' before checking for balanced depth. For cursor alignment: switch both textarea and overlay to whitespace-pre with wrap=off, use explicit 21px line-height (14px * 1.5), and strip all default pre element margins/padding/borders. Co-Authored-By: Claude Opus 4.6 (1M context) --- frontend/src/components/script-editor/ScriptBodyEditor.tsx | 5 +++-- frontend/src/lib/scriptParameterDetector.ts | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/script-editor/ScriptBodyEditor.tsx b/frontend/src/components/script-editor/ScriptBodyEditor.tsx index e16246d8..762311cc 100644 --- a/frontend/src/components/script-editor/ScriptBodyEditor.tsx +++ b/frontend/src/components/script-editor/ScriptBodyEditor.tsx @@ -37,7 +37,7 @@ export function ScriptBodyEditor({ value, onChange, disabled }: Props) {
{/* Highlighted overlay (read-only visual layer) — scroll synced to textarea */}
- +
{/* Editable textarea (transparent text, visible caret) */} @@ -48,8 +48,9 @@ export function ScriptBodyEditor({ value, onChange, disabled }: Props) { onScroll={handleScroll} onKeyDown={handleTab} disabled={disabled} + wrap="off" spellCheck={false} - className="relative z-10 w-full min-h-[300px] resize-y font-label text-sm leading-[1.5] bg-transparent text-transparent caret-foreground p-4 whitespace-pre-wrap break-words focus:outline-none focus:ring-1 focus:ring-[rgba(6,182,212,0.2)] disabled:cursor-not-allowed disabled:opacity-50" + className="relative z-10 w-full min-h-[300px] resize-y font-label text-sm leading-[21px] bg-transparent text-transparent caret-foreground p-4 whitespace-pre overflow-auto focus:outline-none focus:ring-1 focus:ring-[rgba(6,182,212,0.2)] disabled:cursor-not-allowed disabled:opacity-50" placeholder="# Enter your PowerShell script here… # Use {{ param_name }} for parameter placeholders" />
diff --git a/frontend/src/lib/scriptParameterDetector.ts b/frontend/src/lib/scriptParameterDetector.ts index bce72650..cbf631ec 100644 --- a/frontend/src/lib/scriptParameterDetector.ts +++ b/frontend/src/lib/scriptParameterDetector.ts @@ -155,11 +155,12 @@ function findScriptLevelParamBlock(script: string): { start: number; end: number if (functionBraceDepth === 0 && /^param\s*\(/i.test(trimmed) && paramStart === -1) { paramStart = i + let foundOpen = false for (let j = i; j < lines.length; j++) { for (const ch of lines[j]) { - if (ch === '(') parenDepth++ + if (ch === '(') { parenDepth++; foundOpen = true } if (ch === ')') parenDepth-- - if (parenDepth === 0 && paramStart !== -1) { + if (foundOpen && parenDepth === 0) { return { start: paramStart, end: j } } }