Skip to content

Commit dfdf06c

Browse files
Rohan Ranjan PrasadRohan Ranjan Prasad
authored andcommitted
fix(cli): optimize truncateMessage to O(n) and bypass if not TTY
1 parent 97036fb commit dfdf06c

1 file changed

Lines changed: 42 additions & 5 deletions

File tree

packages/cli-v3/src/utilities/windows.ts

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ function getVisibleLength(str: string): number {
1919
}
2020

2121
function truncateMessage(msg: string, maxLength?: number): string {
22+
// If not a TTY and no explicit length provided, don't truncate
23+
if (!process.stdout.isTTY && maxLength === undefined) {
24+
return msg;
25+
}
26+
2227
const terminalWidth = maxLength ?? process.stdout.columns ?? 80;
2328
const availableWidth = terminalWidth - 5; // Reserve some space for the spinner and padding
2429
const visibleLength = getVisibleLength(msg);
@@ -28,13 +33,45 @@ function truncateMessage(msg: string, maxLength?: number): string {
2833
}
2934

3035
// We need to truncate based on visible characters, but preserve ANSI sequences
31-
// Simple approach: truncate character by character until we fit
32-
let truncated = msg;
33-
while (getVisibleLength(truncated) > availableWidth - 3) {
34-
truncated = truncated.slice(0, -1);
36+
const targetLength = availableWidth - 3;
37+
let visibleCount = 0;
38+
let result = "";
39+
40+
const ansiRegex = /\x1b\]8;;[^\x07]*\x07|\x1b\[[0-9;]*[a-zA-Z]/g;
41+
let lastIndex = 0;
42+
let match;
43+
44+
while ((match = ansiRegex.exec(msg)) !== null) {
45+
const textPart = msg.slice(lastIndex, match.index);
46+
const textPartVisibleLength = textPart.length;
47+
48+
if (visibleCount + textPartVisibleLength > targetLength) {
49+
if (visibleCount <= targetLength) {
50+
result += textPart.slice(0, targetLength - visibleCount) + "...";
51+
visibleCount = targetLength + 1; // Mark as done
52+
}
53+
result += match[0];
54+
} else {
55+
if (visibleCount <= targetLength) {
56+
result += textPart + match[0];
57+
visibleCount += textPartVisibleLength;
58+
} else {
59+
result += match[0];
60+
}
61+
}
62+
lastIndex = ansiRegex.lastIndex;
63+
}
64+
65+
if (visibleCount <= targetLength) {
66+
const remainingText = msg.slice(lastIndex);
67+
if (visibleCount + remainingText.length > targetLength) {
68+
result += remainingText.slice(0, targetLength - visibleCount) + "...";
69+
} else {
70+
result += remainingText;
71+
}
3572
}
3673

37-
return truncated + "...";
74+
return result;
3875
}
3976

4077
const wrappedClackSpinner = () => {

0 commit comments

Comments
 (0)