(error?: Error | number | null)
| 1587 | } |
| 1588 | |
| 1589 | unmount(error?: Error | number | null): void { |
| 1590 | if (this.isUnmounted) { |
| 1591 | return; |
| 1592 | } |
| 1593 | |
| 1594 | this.onRender(); |
| 1595 | this.unsubscribeExit(); |
| 1596 | |
| 1597 | if (typeof this.restoreConsole === 'function') { |
| 1598 | this.restoreConsole(); |
| 1599 | } |
| 1600 | this.restoreStderr?.(); |
| 1601 | |
| 1602 | this.unsubscribeTTYHandlers?.(); |
| 1603 | |
| 1604 | // Non-TTY environments don't handle erasing ansi escapes well, so it's better to |
| 1605 | // only render last frame of non-static output |
| 1606 | const diff = this.log.renderPreviousOutput_DEPRECATED(this.frontFrame); |
| 1607 | writeDiffToTerminal(this.terminal, optimize(diff)); |
| 1608 | |
| 1609 | // Clean up terminal modes synchronously before process exit. |
| 1610 | // React's componentWillUnmount won't run in time when process.exit() is called, |
| 1611 | // so we must reset terminal modes here to prevent escape sequence leakage. |
| 1612 | // Use writeSync to stdout (fd 1) to ensure writes complete before exit. |
| 1613 | // We unconditionally send all disable sequences because terminal detection |
| 1614 | // may not work correctly (e.g., in tmux, screen) and these are no-ops on |
| 1615 | // terminals that don't support them. |
| 1616 | /* eslint-disable custom-rules/no-sync-fs -- process exiting; async writes would be dropped */ |
| 1617 | if (this.options.stdout.isTTY) { |
| 1618 | if (this.altScreenActive) { |
| 1619 | // <AlternateScreen>'s unmount effect won't run during signal-exit. |
| 1620 | // Exit alt screen FIRST so other cleanup sequences go to the main screen. |
| 1621 | writeSync(1, EXIT_ALT_SCREEN); |
| 1622 | } |
| 1623 | // Disable mouse tracking — unconditional because altScreenActive can be |
| 1624 | // stale if AlternateScreen's unmount (which flips the flag) raced a |
| 1625 | // blocked event loop + SIGINT. No-op if tracking was never enabled. |
| 1626 | writeSync(1, DISABLE_MOUSE_TRACKING); |
| 1627 | // Drain stdin so in-flight mouse events don't leak to the shell |
| 1628 | this.drainStdin(); |
| 1629 | // Disable extended key reporting (both kitty and modifyOtherKeys) |
| 1630 | writeSync(1, DISABLE_MODIFY_OTHER_KEYS); |
| 1631 | writeSync(1, DISABLE_KITTY_KEYBOARD); |
| 1632 | // Disable focus events (DECSET 1004) |
| 1633 | writeSync(1, DFE); |
| 1634 | // Disable bracketed paste mode |
| 1635 | writeSync(1, DBP); |
| 1636 | // Show cursor |
| 1637 | writeSync(1, SHOW_CURSOR); |
| 1638 | // Clear iTerm2 progress bar |
| 1639 | writeSync(1, CLEAR_ITERM2_PROGRESS); |
| 1640 | // Clear tab status (OSC 21337) so a stale dot doesn't linger |
| 1641 | if (supportsTabStatus()) writeSync(1, wrapForMultiplexer(CLEAR_TAB_STATUS)); |
| 1642 | } |
| 1643 | /* eslint-enable custom-rules/no-sync-fs */ |
| 1644 | |
| 1645 | this.isUnmounted = true; |
| 1646 |
no test coverage detected