From b97a47db42f062e866f7de84a13ecc73e2fb3f73 Mon Sep 17 00:00:00 2001 From: deseltrus Date: Sun, 15 Mar 2026 07:23:55 +0100 Subject: [PATCH] feat(tui): add placeholder support to Input component MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Input component had no placeholder text support — when empty, it showed only "> " with a blinking cursor and no hint of expected input. The ExtensionInputComponent received a placeholder parameter but discarded it (_placeholder with underscore = intentionally unused). Fix: Input now has a public placeholder property. When value is empty, renders the placeholder in dim text. ExtensionInputComponent passes the placeholder through to Input. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../modes/interactive/components/extension-input.ts | 5 ++++- packages/pi-tui/src/components/input.ts | 11 +++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/pi-coding-agent/src/modes/interactive/components/extension-input.ts b/packages/pi-coding-agent/src/modes/interactive/components/extension-input.ts index 4c0e816bd..06d7ee933 100644 --- a/packages/pi-coding-agent/src/modes/interactive/components/extension-input.ts +++ b/packages/pi-coding-agent/src/modes/interactive/components/extension-input.ts @@ -33,7 +33,7 @@ export class ExtensionInputComponent extends Container implements Focusable { constructor( title: string, - _placeholder: string | undefined, + placeholder: string | undefined, onSubmit: (value: string) => void, onCancel: () => void, opts?: ExtensionInputOptions, @@ -61,6 +61,9 @@ export class ExtensionInputComponent extends Container implements Focusable { } this.input = new Input(); + if (placeholder) { + this.input.placeholder = placeholder; + } this.addChild(this.input); this.addChild(new Spacer(1)); this.addChild(new Text(`${keyHint("selectConfirm", "submit")} ${keyHint("selectCancel", "cancel")}`, 1, 0)); diff --git a/packages/pi-tui/src/components/input.ts b/packages/pi-tui/src/components/input.ts index e5c3b4f7f..13714b138 100644 --- a/packages/pi-tui/src/components/input.ts +++ b/packages/pi-tui/src/components/input.ts @@ -20,6 +20,7 @@ export class Input implements Component, Focusable { private cursor: number = 0; // Cursor position in the value public onSubmit?: (value: string) => void; public onEscape?: () => void; + public placeholder: string = ""; /** Focusable interface - set by TUI when focus changes */ focused: boolean = false; @@ -440,6 +441,16 @@ export class Input implements Component, Focusable { return [prompt]; } + // Show placeholder when value is empty + if (this.value === "" && this.placeholder) { + const placeholderText = this.placeholder.slice(0, availableWidth - 1); + const marker = this.focused ? CURSOR_MARKER : ""; + const cursorChar = "\x1b[7m \x1b[27m"; // inverse space for cursor + const dimPlaceholder = `\x1b[2m${placeholderText}\x1b[22m`; // dim text + const padding = " ".repeat(Math.max(0, availableWidth - visibleWidth(placeholderText) - 1)); + return [prompt + marker + cursorChar + dimPlaceholder + padding]; + } + let visibleText = ""; let cursorDisplay = this.cursor;