Skip to content

Commit bf10167

Browse files
committed
fix(inquirerer): limit multiline input height with scrolling
When input has too many lines, limit visible lines to prevent overflow. Shows scroll indicators when there are hidden lines above/below. Keeps cursor line visible by centering the view around it.
1 parent 6c67f5e commit bf10167

1 file changed

Lines changed: 37 additions & 4 deletions

File tree

packages/inquirerer/src/ui/aicode.ts

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -918,14 +918,42 @@ export class AICodeUI {
918918
}
919919

920920
/**
921-
* Render the input lines (supports multiline)
921+
* Render the input lines (supports multiline with scrolling)
922922
*/
923923
private renderInputLines(width: number): string[] {
924924
const lines: string[] = [];
925925
const inputText = this.getInput();
926926
const hasContent = inputText.length > 0;
927927

928-
this.lineEditor.lines.forEach((line, idx) => {
928+
// Limit visible input lines to prevent overflow
929+
// Reserve space for: welcome/conversation, separator, status bar
930+
const maxInputLines = Math.min(this.lineEditor.lines.length, Math.max(3, this.viewportHeight - 10));
931+
932+
// Calculate which lines to show (keep cursor line visible)
933+
const cursorLine = this.lineEditor.lineIndex;
934+
let startLine = 0;
935+
let endLine = this.lineEditor.lines.length;
936+
937+
if (this.lineEditor.lines.length > maxInputLines) {
938+
// Center the view around the cursor line
939+
const halfVisible = Math.floor(maxInputLines / 2);
940+
startLine = Math.max(0, cursorLine - halfVisible);
941+
endLine = startLine + maxInputLines;
942+
943+
// Adjust if we're near the end
944+
if (endLine > this.lineEditor.lines.length) {
945+
endLine = this.lineEditor.lines.length;
946+
startLine = Math.max(0, endLine - maxInputLines);
947+
}
948+
}
949+
950+
// Show scroll indicator at top if there are hidden lines above
951+
if (startLine > 0) {
952+
lines.push(dim(` [${startLine} more lines above]`));
953+
}
954+
955+
for (let idx = startLine; idx < endLine; idx++) {
956+
const line = this.lineEditor.lines[idx];
929957
const prefix = idx === 0 ? cyan('> ') : ' ';
930958
let lineContent: string;
931959

@@ -941,7 +969,7 @@ export class AICodeUI {
941969
lineContent = line;
942970
}
943971

944-
// Add send hint on last line if there's content
972+
// Add send hint on last visible line if there's content and it's the actual last line
945973
if (idx === this.lineEditor.lines.length - 1 && hasContent) {
946974
const hint = dim(' ↵ send');
947975
const lineWidth = displayWidth(prefix + lineContent);
@@ -953,7 +981,12 @@ export class AICodeUI {
953981
}
954982

955983
lines.push(prefix + lineContent);
956-
});
984+
}
985+
986+
// Show scroll indicator at bottom if there are hidden lines below
987+
if (endLine < this.lineEditor.lines.length) {
988+
lines.push(dim(` [${this.lineEditor.lines.length - endLine} more lines below]`));
989+
}
957990

958991
return lines;
959992
}

0 commit comments

Comments
 (0)