diff --git a/lib/string/ansi.ts b/lib/string/ansi.ts index b3882d22686c0f9d6b15c61f698f93026feaa758..ac87c2301c6a728f00b0f49dace8055dea221e45 100644 --- a/lib/string/ansi.ts +++ b/lib/string/ansi.ts @@ -226,6 +226,7 @@ export function debugAnsi(text: string): string { /** Measure the visible length of a string, ignoring ansi codes. */ export function widthInTerminal(str: string): number { + segmenter ??= new Intl.Segmenter(); let width = 0; if (str.includes("\x1b")) str = str.replace(ansiEscapes, ""); for (let i = 0, { length } = str; i < length; i += 1) { @@ -256,6 +257,7 @@ export function widthInTerminal(str: string): number { */ // TODO: rename to trimForTerminal export function trimToWidth(str: string, columns: number): string { + segmenter ??= new Intl.Segmenter(); let width = 0; let ansi = false; for (let i = 0, { length } = str; i < length; i += 1) { @@ -310,7 +312,7 @@ export function trimToWidth(str: string, columns: number): string { // https://github.com/sindresorhus/string-width/blob/42e7b697393a9b9ff732f9bd3ab1db87c3c208b2/index.js // https://github.com/sindresorhus/get-east-asian-width/blob/6aee3824b5e2ade910a38ed93cf9d89b7b5a8e5b/index.js // MIT license -const segmenter = /* @__PURE__ */ new Intl.Segmenter(); +let segmenter: Intl.Segmenter | null = null; const ansiEscapes = /[\u001B\u009B][[\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\d\/\#&.:=?%@~_]+)*|[a-zA-Z\d]+(?:;[-a-zA-Z\d\/\#&.:=?%@~_]*)*)?(?:\u0007|\u001B\u005C|\u009C))|(?:(?:\d{1,4}(?:;\d{0,4})*)?[\dA-PR-TZcf-nq-uy=><~]))/g; const zeroWidthClusterRegex =