( content: string, terminalWidth: number, suppressExpandHint = false, )
| 69 | * @returns The rendered content with truncation if needed. |
| 70 | */ |
| 71 | export function renderTruncatedContent( |
| 72 | content: string, |
| 73 | terminalWidth: number, |
| 74 | suppressExpandHint = false, |
| 75 | ): string { |
| 76 | const trimmedContent = content.trimEnd() |
| 77 | if (!trimmedContent) { |
| 78 | return '' |
| 79 | } |
| 80 | |
| 81 | const wrapWidth = Math.max(terminalWidth - PADDING_TO_PREVENT_OVERFLOW, 10) |
| 82 | |
| 83 | // Only process enough content for the visible lines. Avoids O(n) wrapping |
| 84 | // on huge outputs (e.g. 64MB binary dumps that cause 382K-row screens). |
| 85 | const maxChars = MAX_LINES_TO_SHOW * wrapWidth * 4 |
| 86 | const preTruncated = trimmedContent.length > maxChars |
| 87 | const contentForWrapping = preTruncated |
| 88 | ? trimmedContent.slice(0, maxChars) |
| 89 | : trimmedContent |
| 90 | |
| 91 | const { aboveTheFold, remainingLines } = wrapText( |
| 92 | contentForWrapping, |
| 93 | wrapWidth, |
| 94 | ) |
| 95 | |
| 96 | const estimatedRemaining = preTruncated |
| 97 | ? Math.max( |
| 98 | remainingLines, |
| 99 | Math.ceil(trimmedContent.length / wrapWidth) - MAX_LINES_TO_SHOW, |
| 100 | ) |
| 101 | : remainingLines |
| 102 | |
| 103 | return [ |
| 104 | aboveTheFold, |
| 105 | estimatedRemaining > 0 |
| 106 | ? chalk.dim( |
| 107 | `… +${estimatedRemaining} lines${suppressExpandHint ? '' : ` ${ctrlOToExpand()}`}`, |
| 108 | ) |
| 109 | : '', |
| 110 | ] |
| 111 | .filter(Boolean) |
| 112 | .join('\n') |
| 113 | } |
| 114 | |
| 115 | /** Fast check: would OutputLine truncate this content? Counts raw newlines |
| 116 | * only (ignores terminal-width wrapping), so it may return false for a single |
no test coverage detected