()
| 282 | } |
| 283 | |
| 284 | private render() { |
| 285 | const frame = wrapAnsi(this._render(this) ?? '', process.stdout.columns, { |
| 286 | hard: true, |
| 287 | trim: false, |
| 288 | }); |
| 289 | if (frame === this._prevFrame) return; |
| 290 | |
| 291 | if (this.state === 'initial') { |
| 292 | this.output.write(cursor.hide); |
| 293 | } else { |
| 294 | const diff = diffLines(this._prevFrame, frame); |
| 295 | const rows = getRows(this.output); |
| 296 | this.restoreCursor(); |
| 297 | if (diff) { |
| 298 | const diffOffsetAfter = Math.max(0, diff.numLinesAfter - rows); |
| 299 | const diffOffsetBefore = Math.max(0, diff.numLinesBefore - rows); |
| 300 | let diffLine = diff.lines.find((line) => line >= diffOffsetAfter); |
| 301 | |
| 302 | if (diffLine === undefined) { |
| 303 | this._prevFrame = frame; |
| 304 | return; |
| 305 | } |
| 306 | |
| 307 | // If a single line has changed, only update that line |
| 308 | if (diff.lines.length === 1) { |
| 309 | this.output.write(cursor.move(0, diffLine - diffOffsetBefore)); |
| 310 | this.output.write(erase.lines(1)); |
| 311 | const lines = frame.split('\n'); |
| 312 | this.output.write(lines[diffLine]); |
| 313 | this._prevFrame = frame; |
| 314 | this.output.write(cursor.move(0, lines.length - diffLine - 1)); |
| 315 | return; |
| 316 | // If many lines have changed, rerender everything past the first line |
| 317 | } else if (diff.lines.length > 1) { |
| 318 | if (diffOffsetAfter < diffOffsetBefore) { |
| 319 | diffLine = diffOffsetAfter; |
| 320 | } else { |
| 321 | const adjustedDiffLine = diffLine - diffOffsetBefore; |
| 322 | if (adjustedDiffLine > 0) { |
| 323 | this.output.write(cursor.move(0, adjustedDiffLine)); |
| 324 | } |
| 325 | } |
| 326 | this.output.write(erase.down()); |
| 327 | const lines = frame.split('\n'); |
| 328 | const newLines = lines.slice(diffLine); |
| 329 | this.output.write(newLines.join('\n')); |
| 330 | this._prevFrame = frame; |
| 331 | return; |
| 332 | } |
| 333 | } |
| 334 | |
| 335 | this.output.write(erase.down()); |
| 336 | } |
| 337 | |
| 338 | this.output.write(frame); |
| 339 | if (this.state === 'initial') { |
| 340 | this.state = 'active'; |
| 341 | } |
no test coverage detected