MCPcopy
hub / github.com/Doorman11991/smallcode / _renderCommandPalette

Method _renderCommandPalette

src/tui/fullscreen.js:518–599  ·  view source on GitHub ↗
(inputRow)

Source from the content-addressed store, hash-verified

516 }
517
518 _renderCommandPalette(inputRow) {
519 let buf = '';
520 const filter = this.inputBuffer.slice(1).toLowerCase(); // Remove leading /
521 const filtered = this.commands.filter(c =>
522 c.cmd.slice(1).startsWith(filter) || (c.alias && c.alias.slice(1).startsWith(filter))
523 );
524
525 // Keep layout stable: fixed 8 visible rows
526 const availableRows = inputRow - 3;
527 const maxVisible = Math.max(1, Math.min(8, availableRows));
528 this._paletteMaxVisible = maxVisible;
529
530 // Clamp selection
531 if (filtered.length > 0) {
532 this.commandPaletteSelection = Math.max(0, Math.min(this.commandPaletteSelection, filtered.length - 1));
533 } else {
534 this.commandPaletteSelection = 0;
535 }
536
537 // Keep scroll offset in sync
538 if (this.commandPaletteSelection < this._paletteScrollOffset) {
539 this._paletteScrollOffset = this.commandPaletteSelection;
540 } else if (this.commandPaletteSelection >= this._paletteScrollOffset + maxVisible) {
541 this._paletteScrollOffset = this.commandPaletteSelection - maxVisible + 1;
542 }
543 const maxOffset = Math.max(0, filtered.length - maxVisible);
544 this._paletteScrollOffset = Math.max(0, Math.min(this._paletteScrollOffset, maxOffset));
545
546 const paletteWidth = Math.max(20, Math.min(this.width - 4, 60));
547 const startRow = inputRow - maxVisible - 1;
548
549 // Draw top border with result count (e.g. [5 of 12])
550 buf += ANSI.moveTo(startRow, 2);
551 const countLabel = filtered.length > 0
552 ? ` ${this.commandPaletteSelection + 1}/${filtered.length} `
553 : ' 0/0 ';
554 const topLabel = ` Commands ${countLabel}`;
555 const topFill = paletteWidth - 2 - topLabel.length;
556 buf += this.theme.border + BOX.rTopLeft + this.theme.accent + topLabel + this.theme.border + BOX.horizontal.repeat(Math.max(0, topFill)) + BOX.rTopRight + ANSI.reset;
557
558 // Render fixed maxVisible rows
559 for (let i = 0; i < maxVisible; i++) {
560 const row = startRow + 1 + i;
561 buf += ANSI.moveTo(row, 2);
562 buf += this.theme.border + BOX.vertical + ANSI.reset;
563
564 const itemIdx = i + this._paletteScrollOffset;
565 if (itemIdx < filtered.length) {
566 const cmd = filtered[itemIdx];
567 const isSelected = itemIdx === this.commandPaletteSelection;
568
569 // Columns: Command (width 16) | Divider (width 3) | Description
570 const CMD_COL_WIDTH = 16;
571 const descWidth = Math.max(1, paletteWidth - 2 - 1 - CMD_COL_WIDTH - 3);
572
573 const cmdText = cmd.cmd + (cmd.alias ? ` (${cmd.alias})` : '');
574 const col1 = fitAnsi(cmdText, CMD_COL_WIDTH);
575 const col2 = fitAnsi(cmd.desc, descWidth);

Callers 2

_renderInputMethod · 0.95
tui_layout.test.jsFile · 0.80

Calls 1

fitAnsiFunction · 0.85

Tested by

no test coverage detected