MCPcopy Create free account
hub / github.com/MoonshotAI/kimi-code / doRender

Method doRender

packages/pi-tui/src/tui.ts:1264–1774  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

1262 }
1263
1264 private doRender(): void {
1265 if (this.stopped) return;
1266 const width = this.terminal.columns;
1267 const height = this.terminal.rows;
1268 const widthChanged = this.previousWidth !== 0 && this.previousWidth !== width;
1269 const heightChanged = this.previousHeight !== 0 && this.previousHeight !== height;
1270 const previousBufferLength = this.previousHeight > 0 ? this.previousViewportTop + this.previousHeight : height;
1271 let prevViewportTop = heightChanged ? Math.max(0, previousBufferLength - height) : this.previousViewportTop;
1272 let viewportTop = prevViewportTop;
1273 let hardwareCursorRow = this.hardwareCursorRow;
1274 const computeLineDiff = (targetRow: number): number => {
1275 const currentScreenRow = hardwareCursorRow - prevViewportTop;
1276 const targetScreenRow = targetRow - viewportTop;
1277 return targetScreenRow - currentScreenRow;
1278 };
1279
1280 // Render all components to get new lines
1281 let newLines = this.render(width);
1282
1283 // Composite overlays into the rendered lines (before differential compare)
1284 if (this.overlayStack.length > 0) {
1285 newLines = this.compositeOverlays(newLines, width, height);
1286 }
1287
1288 // Extract cursor position before applying line resets (marker must be found first)
1289 const cursorPos = this.extractCursorPosition(newLines, height);
1290
1291 // Never write a line wider than the terminal: truncate defensively
1292 // instead of crashing. Extremely narrow terminals can make
1293 // components overflow by a column (e.g. wide graphemes at width 1).
1294 // applyLineResets() runs afterwards, so truncated lines still get
1295 // their trailing reset and cannot leak styles.
1296 for (let i = 0; i < newLines.length; i++) {
1297 const line = newLines[i]!;
1298 if (isImageLine(line)) continue;
1299 const lineWidth = asciiVisibleWidth(line, width) ?? visibleWidth(line);
1300 if (lineWidth > width) {
1301 newLines[i] = sliceByColumn(line, 0, width, true);
1302 }
1303 }
1304
1305 newLines = this.applyLineResets(newLines);
1306
1307 // Helper to clear scrollback and viewport and render all new lines
1308 const fullRender = (clear: boolean): void => {
1309 this.fullRedrawCount += 1;
1310 let buffer = "\x1b[?2026h"; // Begin synchronized output
1311 if (clear) {
1312 buffer += this.deleteKittyImages(this.previousKittyImageIds);
1313 buffer += "\x1b[2J\x1b[H\x1b[3J"; // Clear screen, home, then clear scrollback
1314 }
1315 for (let i = 0; i < newLines.length; i++) {
1316 if (i > 0) buffer += "\r\n";
1317 const line = newLines[i]!;
1318 const isImage = isImageLine(line);
1319 const imageReservedRows = isImage ? this.getKittyImageReservedRows(newLines, i) : 1;
1320 if (imageReservedRows > 1 && imageReservedRows <= height) {
1321 for (let row = 1; row < imageReservedRows; row++) {

Callers 2

requestRenderMethod · 0.95
scheduleRenderMethod · 0.95

Calls 15

compositeOverlaysMethod · 0.95
extractCursorPositionMethod · 0.95
applyLineResetsMethod · 0.95
collectKittyImageIdsMethod · 0.95
isImageLineFunction · 0.90
asciiVisibleWidthFunction · 0.90
visibleWidthFunction · 0.90
sliceByColumnFunction · 0.90

Tested by

no test coverage detected