From 3cdb7989d1b1602a0b187882043e964ab49a550b Mon Sep 17 00:00:00 2001 From: James Garbutt <43081j@users.noreply.github.com> Date: Thu, 29 Oct 2026 10:34:58 +0000 Subject: [PATCH] fix: account for escape sequences in prefixes This is a known bug we've had for quite some time. Basically, we were checking `prefix.length` to calculate how much space the prefix (e.g. the guide) takes up. This is incorrect since the prefix usually contains escape sequences, so it can be off by several characters. Using fast-string-width instead means we get the actual width. Note that fast-string-width is already a deep dependency, so this just declares it at the root. --- .changeset/eight-lights-hug.md | 6 + packages/core/package.json | 1 + packages/core/src/utils/index.ts | 4 +- packages/prompts/src/common.ts | 9 +- packages/prompts/src/group-multi-select.ts | 2 +- packages/prompts/src/multi-select.ts | 2 +- packages/prompts/src/select.ts | 2 +- .../__snapshots__/multi-select.test.ts.snap | 64 ++-- .../__snapshots__/select-key.test.ts.snap | 276 ++++++++---------- .../test/__snapshots__/select.test.ts.snap | 136 ++++----- pnpm-lock.yaml | 3 + 11 files changed, 243 insertions(+), 262 deletions(-) create mode 100644 .changeset/eight-lights-hug.md diff --git a/.changeset/eight-lights-hug.md b/.changeset/eight-lights-hug.md new file mode 100644 index 00000000..b06fa8b7 --- /dev/null +++ b/.changeset/eight-lights-hug.md @@ -0,0 +1,6 @@ +--- +"@clack/prompts": patch +"@clack/core": patch +--- + +Account for escape sequences in prefixes during line wrapping. Very narrow outputs will now render correctly. diff --git a/packages/core/package.json b/packages/core/package.json index c84fb4cd..371a6ae0 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -55,6 +55,7 @@ "test": "vitest run" }, "dependencies": { + "fast-string-width": "^3.0.2", "fast-wrap-ansi": "^0.2.0", "sisteransi": "^2.0.0" }, diff --git a/packages/core/src/utils/index.ts b/packages/core/src/utils/index.ts index 96199a8b..9c688be0 100644 --- a/packages/core/src/utils/index.ts +++ b/packages/core/src/utils/index.ts @@ -3,6 +3,7 @@ import type { Key } from 'node:readline'; import * as readline from 'node:readline'; import type { Readable, Writable } from 'node:stream'; import { ReadStream } from 'node:tty'; +import stringWidth from 'fast-string-width'; import { wrapAnsi } from 'fast-wrap-ansi'; import { cursor } from 'sisteransi'; import { isActionKey } from './settings.js'; @@ -107,7 +108,8 @@ export function wrapTextWithPrefix( lineFormatter?: (line: string, index: number) => string ): string { const columns = getColumns(output ?? stdout); - const wrapped = wrapAnsi(text, columns - prefix.length, { + const prefixWidth = stringWidth(prefix); + const wrapped = wrapAnsi(text, columns - prefixWidth, { hard: true, trim: false, }); diff --git a/packages/prompts/src/common.ts b/packages/prompts/src/common.ts index 88037f0b..730c448d 100644 --- a/packages/prompts/src/common.ts +++ b/packages/prompts/src/common.ts @@ -1,6 +1,7 @@ import type { Readable, Writable } from 'node:stream'; import { styleText } from 'node:util'; import type { State } from '@clack/core'; +import { wrapTextWithPrefix } from '@clack/core'; import isUnicodeSupported from 'is-unicode-supported'; export const unicode = isUnicodeSupported(); @@ -77,9 +78,13 @@ export interface CommonOptions { accessible?: boolean; } -export function formatInstructionFooter(instructions: string[], hasGuide: boolean): string[] { +export function formatInstructionFooter( + output: Writable | undefined, + instructions: string[], + hasGuide: boolean +): string[] { const guidePrefix = hasGuide ? `${styleText('cyan', S_BAR)} ` : ''; - const footerLines = [`${guidePrefix}${instructions.join(' • ')}`]; + const footerLines = wrapTextWithPrefix(output, instructions.join(' • '), guidePrefix).split('\n'); if (hasGuide) { footerLines.push(styleText('cyan', S_BAR_END)); } diff --git a/packages/prompts/src/group-multi-select.ts b/packages/prompts/src/group-multi-select.ts index 2cfd26aa..e53bc97f 100644 --- a/packages/prompts/src/group-multi-select.ts +++ b/packages/prompts/src/group-multi-select.ts @@ -297,7 +297,7 @@ export const groupMultiselect = (opts: GroupMultiSelectOptions) => const guidePrefix = hasGuide ? `${styleText('cyan', S_BAR)} ` : ''; const titleLineCount = title.split('\n').length; const footerLines = showInstructions - ? formatInstructionFooter(MULTISELECT_INSTRUCTIONS, hasGuide) + ? formatInstructionFooter(opts.output, MULTISELECT_INSTRUCTIONS, hasGuide) : hasGuide ? [styleText('cyan', S_BAR_END)] : []; diff --git a/packages/prompts/src/multi-select.ts b/packages/prompts/src/multi-select.ts index 8b28c915..b20209af 100644 --- a/packages/prompts/src/multi-select.ts +++ b/packages/prompts/src/multi-select.ts @@ -187,7 +187,7 @@ export const multiselect = (opts: MultiSelectOptions) => { const prefix = hasGuide ? `${styleText('cyan', S_BAR)} ` : ''; const titleLineCount = title.split('\n').length; const footerLines = showInstructions - ? formatInstructionFooter(MULTISELECT_INSTRUCTIONS, hasGuide) + ? formatInstructionFooter(opts.output, MULTISELECT_INSTRUCTIONS, hasGuide) : hasGuide ? [styleText('cyan', S_BAR_END)] : []; diff --git a/packages/prompts/src/select.ts b/packages/prompts/src/select.ts index fc87a58a..804e5817 100644 --- a/packages/prompts/src/select.ts +++ b/packages/prompts/src/select.ts @@ -164,7 +164,7 @@ export const select = (opts: SelectOptions) => { const prefix = hasGuide ? `${styleText('cyan', S_BAR)} ` : ''; const titleLineCount = title.split('\n').length; const footerLines = showInstructions - ? formatInstructionFooter(SELECT_INSTRUCTIONS, hasGuide) + ? formatInstructionFooter(opts.output, SELECT_INSTRUCTIONS, hasGuide) : hasGuide ? [styleText('cyan', S_BAR_END)] : []; diff --git a/packages/prompts/test/__snapshots__/multi-select.test.ts.snap b/packages/prompts/test/__snapshots__/multi-select.test.ts.snap index 950cfbfd..7ef18c23 100644 --- a/packages/prompts/test/__snapshots__/multi-select.test.ts.snap +++ b/packages/prompts/test/__snapshots__/multi-select.test.ts.snap @@ -872,7 +872,7 @@ exports[`multiselect (isCI = false) > wraps cancelled state with long options 1` │ 1 Option 1 Option 1 Option  │ 1 Option 1 │ ↑/↓ to navigate • Space: select • -Enter: confirm +│ Enter: confirm └ ", "", @@ -884,10 +884,9 @@ exports[`multiselect (isCI = false) > wraps cancelled state with long options 1` "", "", "■ foo -│ Option 0 Option 0 Option 0  -│ Option 0 Option 0 Option 0  -│ Option 0 Option 0 Option 0  -│ Option 0 +│ Option 0 Option 0 Option 0 Option 0  +│ Option 0 Option 0 Option 0 Option 0  +│ Option 0 Option 0 │", " ", @@ -899,13 +898,13 @@ exports[`multiselect (isCI = false) > wraps long messages 1`] = ` [ "", "│ -◆ foo foo foo foo foo foo foo -│ foo foo foo foo foo foo -│ foo foo foo foo foo foo foo +◆ foo foo foo foo foo foo foo foo foo +│ foo foo foo foo foo foo foo foo foo +│ foo foo │ ◻ opt0 │ ◻ opt1 │ ↑/↓ to navigate • Space: select • -Enter: confirm +│ Enter: confirm └ ", "", @@ -916,9 +915,9 @@ exports[`multiselect (isCI = false) > wraps long messages 1`] = ` "", "", "", - "◇ foo foo foo foo foo foo foo -│ foo foo foo foo foo foo -│ foo foo foo foo foo foo foo + "◇ foo foo foo foo foo foo foo foo foo +│ foo foo foo foo foo foo foo foo foo +│ foo foo │ opt0", " ", @@ -940,7 +939,7 @@ exports[`multiselect (isCI = false) > wraps success state with long options 1`] │ 1 Option 1 Option 1 Option  │ 1 Option 1 │ ↑/↓ to navigate • Space: select • -Enter: confirm +│ Enter: confirm └ ", "", @@ -952,10 +951,9 @@ exports[`multiselect (isCI = false) > wraps success state with long options 1`] "", "", "◇ foo -│ Option 0 Option 0 Option 0  -│ Option 0 Option 0 Option 0  -│ Option 0 Option 0 Option 0  -│ Option 0", +│ Option 0 Option 0 Option 0 Option 0  +│ Option 0 Option 0 Option 0 Option 0  +│ Option 0 Option 0", " ", "", @@ -1834,7 +1832,7 @@ exports[`multiselect (isCI = true) > wraps cancelled state with long options 1`] │ 1 Option 1 Option 1 Option  │ 1 Option 1 │ ↑/↓ to navigate • Space: select • -Enter: confirm +│ Enter: confirm └ ", "", @@ -1846,10 +1844,9 @@ exports[`multiselect (isCI = true) > wraps cancelled state with long options 1`] "", "", "■ foo -│ Option 0 Option 0 Option 0  -│ Option 0 Option 0 Option 0  -│ Option 0 Option 0 Option 0  -│ Option 0 +│ Option 0 Option 0 Option 0 Option 0  +│ Option 0 Option 0 Option 0 Option 0  +│ Option 0 Option 0 │", " ", @@ -1861,13 +1858,13 @@ exports[`multiselect (isCI = true) > wraps long messages 1`] = ` [ "", "│ -◆ foo foo foo foo foo foo foo -│ foo foo foo foo foo foo -│ foo foo foo foo foo foo foo +◆ foo foo foo foo foo foo foo foo foo +│ foo foo foo foo foo foo foo foo foo +│ foo foo │ ◻ opt0 │ ◻ opt1 │ ↑/↓ to navigate • Space: select • -Enter: confirm +│ Enter: confirm └ ", "", @@ -1878,9 +1875,9 @@ exports[`multiselect (isCI = true) > wraps long messages 1`] = ` "", "", "", - "◇ foo foo foo foo foo foo foo -│ foo foo foo foo foo foo -│ foo foo foo foo foo foo foo + "◇ foo foo foo foo foo foo foo foo foo +│ foo foo foo foo foo foo foo foo foo +│ foo foo │ opt0", " ", @@ -1902,7 +1899,7 @@ exports[`multiselect (isCI = true) > wraps success state with long options 1`] = │ 1 Option 1 Option 1 Option  │ 1 Option 1 │ ↑/↓ to navigate • Space: select • -Enter: confirm +│ Enter: confirm └ ", "", @@ -1914,10 +1911,9 @@ exports[`multiselect (isCI = true) > wraps success state with long options 1`] = "", "", "◇ foo -│ Option 0 Option 0 Option 0  -│ Option 0 Option 0 Option 0  -│ Option 0 Option 0 Option 0  -│ Option 0", +│ Option 0 Option 0 Option 0 Option 0  +│ Option 0 Option 0 Option 0 Option 0  +│ Option 0 Option 0", " ", "", diff --git a/packages/prompts/test/__snapshots__/select-key.test.ts.snap b/packages/prompts/test/__snapshots__/select-key.test.ts.snap index 5fd7cb99..7c99151e 100644 --- a/packages/prompts/test/__snapshots__/select-key.test.ts.snap +++ b/packages/prompts/test/__snapshots__/select-key.test.ts.snap @@ -126,37 +126,33 @@ exports[`text (isCI = false) > long cancelled labels are wrapped correctly 1`] = "", "│ ◆ Select an option: -│  a  This is a somewhat long -│ label This is a somewhat -│ long label This is a -│ somewhat long label This is -│ a somewhat long label This -│ is a somewhat long label -│ This is a somewhat long -│ label This is a somewhat -│ long label This is a -│ somewhat long label This is -│ a somewhat long label This -│ is a somewhat long label +│  a  This is a somewhat long label +│ This is a somewhat long label This is +│ a somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label │  b  Short label └ ", - "", + "", "", "", "■ Select an option: -│ This is a somewhat long  -│ label This is a somewhat  -│ long label This is a  -│ somewhat long label This is -│  a somewhat long label This -│  is a somewhat long label  -│ This is a somewhat long  -│ label This is a somewhat  -│ long label This is a  -│ somewhat long label This is -│  a somewhat long label This -│  is a somewhat long label +│ This is a somewhat long label This is +│  a somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label │", " ", @@ -169,38 +165,34 @@ exports[`text (isCI = false) > long option labels are wrapped correctly 1`] = ` "", "│ ◆ Select an option: -│  a  This is a somewhat long -│ label This is a somewhat -│ long label This is a -│ somewhat long label This is -│ a somewhat long label This -│ is a somewhat long label -│ This is a somewhat long -│ label This is a somewhat -│ long label This is a -│ somewhat long label This is -│ a somewhat long label This -│ is a somewhat long label +│  a  This is a somewhat long label +│ This is a somewhat long label This is +│ a somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label │  b  Short label └ ", "", - "", + "", "", "", "◇ Select an option: -│ This is a somewhat long  -│ label This is a somewhat  -│ long label This is a  -│ somewhat long label This is -│  a somewhat long label This -│  is a somewhat long label  -│ This is a somewhat long  -│ label This is a somewhat  -│ long label This is a  -│ somewhat long label This is -│  a somewhat long label This -│  is a somewhat long label", +│ This is a somewhat long label This is +│  a somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label", " ", ] @@ -211,38 +203,34 @@ exports[`text (isCI = false) > long submitted labels are wrapped correctly 1`] = "", "│ ◆ Select an option: -│  a  This is a somewhat long -│ label This is a somewhat -│ long label This is a -│ somewhat long label This is -│ a somewhat long label This -│ is a somewhat long label -│ This is a somewhat long -│ label This is a somewhat -│ long label This is a -│ somewhat long label This is -│ a somewhat long label This -│ is a somewhat long label +│  a  This is a somewhat long label +│ This is a somewhat long label This is +│ a somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label │  b  Short label └ ", "", - "", + "", "", "", "◇ Select an option: -│ This is a somewhat long  -│ label This is a somewhat  -│ long label This is a  -│ somewhat long label This is -│  a somewhat long label This -│  is a somewhat long label  -│ This is a somewhat long  -│ label This is a somewhat  -│ long label This is a  -│ somewhat long label This is -│  a somewhat long label This -│  is a somewhat long label", +│ This is a somewhat long label This is +│  a somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label", " ", ] @@ -472,37 +460,33 @@ exports[`text (isCI = true) > long cancelled labels are wrapped correctly 1`] = "", "│ ◆ Select an option: -│  a  This is a somewhat long -│ label This is a somewhat -│ long label This is a -│ somewhat long label This is -│ a somewhat long label This -│ is a somewhat long label -│ This is a somewhat long -│ label This is a somewhat -│ long label This is a -│ somewhat long label This is -│ a somewhat long label This -│ is a somewhat long label +│  a  This is a somewhat long label +│ This is a somewhat long label This is +│ a somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label │  b  Short label └ ", - "", + "", "", "", "■ Select an option: -│ This is a somewhat long  -│ label This is a somewhat  -│ long label This is a  -│ somewhat long label This is -│  a somewhat long label This -│  is a somewhat long label  -│ This is a somewhat long  -│ label This is a somewhat  -│ long label This is a  -│ somewhat long label This is -│  a somewhat long label This -│  is a somewhat long label +│ This is a somewhat long label This is +│  a somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label │", " ", @@ -515,38 +499,34 @@ exports[`text (isCI = true) > long option labels are wrapped correctly 1`] = ` "", "│ ◆ Select an option: -│  a  This is a somewhat long -│ label This is a somewhat -│ long label This is a -│ somewhat long label This is -│ a somewhat long label This -│ is a somewhat long label -│ This is a somewhat long -│ label This is a somewhat -│ long label This is a -│ somewhat long label This is -│ a somewhat long label This -│ is a somewhat long label +│  a  This is a somewhat long label +│ This is a somewhat long label This is +│ a somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label │  b  Short label └ ", "", - "", + "", "", "", "◇ Select an option: -│ This is a somewhat long  -│ label This is a somewhat  -│ long label This is a  -│ somewhat long label This is -│  a somewhat long label This -│  is a somewhat long label  -│ This is a somewhat long  -│ label This is a somewhat  -│ long label This is a  -│ somewhat long label This is -│  a somewhat long label This -│  is a somewhat long label", +│ This is a somewhat long label This is +│  a somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label", " ", ] @@ -557,38 +537,34 @@ exports[`text (isCI = true) > long submitted labels are wrapped correctly 1`] = "", "│ ◆ Select an option: -│  a  This is a somewhat long -│ label This is a somewhat -│ long label This is a -│ somewhat long label This is -│ a somewhat long label This -│ is a somewhat long label -│ This is a somewhat long -│ label This is a somewhat -│ long label This is a -│ somewhat long label This is -│ a somewhat long label This -│ is a somewhat long label +│  a  This is a somewhat long label +│ This is a somewhat long label This is +│ a somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label This is a +│ somewhat long label │  b  Short label └ ", "", - "", + "", "", "", "◇ Select an option: -│ This is a somewhat long  -│ label This is a somewhat  -│ long label This is a  -│ somewhat long label This is -│  a somewhat long label This -│  is a somewhat long label  -│ This is a somewhat long  -│ label This is a somewhat  -│ long label This is a  -│ somewhat long label This is -│  a somewhat long label This -│  is a somewhat long label", +│ This is a somewhat long label This is +│  a somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label This is a  +│ somewhat long label", " ", ] diff --git a/packages/prompts/test/__snapshots__/select.test.ts.snap b/packages/prompts/test/__snapshots__/select.test.ts.snap index f7ceb1c1..6506b973 100644 --- a/packages/prompts/test/__snapshots__/select.test.ts.snap +++ b/packages/prompts/test/__snapshots__/select.test.ts.snap @@ -42,54 +42,52 @@ exports[`select (isCI = false) > correctly limits options when message wraps to [ "", "│ -◆ This is a very -│ long message that -│ will wrap to -│ multiple lines +◆ This is a very long message +│ that will wrap to multiple +│ lines │ ● Option 0 │ ○ Option 1 │ ... │ ↑/↓ to navigate • Enter: -confirm +│ confirm └ ", - "", - "", + "", + "", "", "│ ○ Option 0 │ ● Option 1 │ ... │ ↑/↓ to navigate • Enter: -confirm +│ confirm └ ", - "", - "", + "", + "", "", "│ ... │ ● Option 2 │ ... │ ↑/↓ to navigate • Enter: -confirm +│ confirm └ ", - "", - "", + "", + "", "", "│ ● Option 3", "", - "", - "", + "", + "", "", "│ ● Option 4", "", - "", + "", "", "", - "◇ This is a very -│ long message that -│ will wrap to -│ multiple lines + "◇ This is a very long message +│ that will wrap to multiple +│ lines │ Option 4", " ", @@ -557,11 +555,10 @@ exports[`select (isCI = false) > wraps long cancelled message 1`] = ` "", "", "■ foo -│ foo foo foo foo foo foo foo -│  foo foo foo foo foo foo  -│ foo foo foo foo foo foo foo -│  foo foo foo foo foo foo  -│ foo foo foo foo +│ foo foo foo foo foo foo foo foo foo  +│ foo foo foo foo foo foo foo foo foo  +│ foo foo foo foo foo foo foo foo foo  +│ foo foo foo │", " ", @@ -573,9 +570,9 @@ exports[`select (isCI = false) > wraps long messages 1`] = ` [ "", "│ -◆ foo foo foo foo foo foo foo -│ foo foo foo foo foo foo -│ foo foo foo foo foo foo foo +◆ foo foo foo foo foo foo foo foo foo +│ foo foo foo foo foo foo foo foo foo +│ foo foo │ ● opt0 │ ○ opt1 │ ↑/↓ to navigate • Enter: confirm @@ -584,9 +581,9 @@ exports[`select (isCI = false) > wraps long messages 1`] = ` "", "", "", - "◇ foo foo foo foo foo foo foo -│ foo foo foo foo foo foo -│ foo foo foo foo foo foo foo + "◇ foo foo foo foo foo foo foo foo foo +│ foo foo foo foo foo foo foo foo foo +│ foo foo │ opt0", " ", @@ -612,11 +609,10 @@ exports[`select (isCI = false) > wraps long results 1`] = ` "", "", "◇ foo -│ foo foo foo foo foo foo foo -│  foo foo foo foo foo foo  -│ foo foo foo foo foo foo foo -│  foo foo foo foo foo foo  -│ foo foo foo foo", +│ foo foo foo foo foo foo foo foo foo  +│ foo foo foo foo foo foo foo foo foo  +│ foo foo foo foo foo foo foo foo foo  +│ foo foo foo", " ", "", @@ -665,54 +661,52 @@ exports[`select (isCI = true) > correctly limits options when message wraps to m [ "", "│ -◆ This is a very -│ long message that -│ will wrap to -│ multiple lines +◆ This is a very long message +│ that will wrap to multiple +│ lines │ ● Option 0 │ ○ Option 1 │ ... │ ↑/↓ to navigate • Enter: -confirm +│ confirm └ ", - "", - "", + "", + "", "", "│ ○ Option 0 │ ● Option 1 │ ... │ ↑/↓ to navigate • Enter: -confirm +│ confirm └ ", - "", - "", + "", + "", "", "│ ... │ ● Option 2 │ ... │ ↑/↓ to navigate • Enter: -confirm +│ confirm └ ", - "", - "", + "", + "", "", "│ ● Option 3", "", - "", - "", + "", + "", "", "│ ● Option 4", "", - "", + "", "", "", - "◇ This is a very -│ long message that -│ will wrap to -│ multiple lines + "◇ This is a very long message +│ that will wrap to multiple +│ lines │ Option 4", " ", @@ -1180,11 +1174,10 @@ exports[`select (isCI = true) > wraps long cancelled message 1`] = ` "", "", "■ foo -│ foo foo foo foo foo foo foo -│  foo foo foo foo foo foo  -│ foo foo foo foo foo foo foo -│  foo foo foo foo foo foo  -│ foo foo foo foo +│ foo foo foo foo foo foo foo foo foo  +│ foo foo foo foo foo foo foo foo foo  +│ foo foo foo foo foo foo foo foo foo  +│ foo foo foo │", " ", @@ -1196,9 +1189,9 @@ exports[`select (isCI = true) > wraps long messages 1`] = ` [ "", "│ -◆ foo foo foo foo foo foo foo -│ foo foo foo foo foo foo -│ foo foo foo foo foo foo foo +◆ foo foo foo foo foo foo foo foo foo +│ foo foo foo foo foo foo foo foo foo +│ foo foo │ ● opt0 │ ○ opt1 │ ↑/↓ to navigate • Enter: confirm @@ -1207,9 +1200,9 @@ exports[`select (isCI = true) > wraps long messages 1`] = ` "", "", "", - "◇ foo foo foo foo foo foo foo -│ foo foo foo foo foo foo -│ foo foo foo foo foo foo foo + "◇ foo foo foo foo foo foo foo foo foo +│ foo foo foo foo foo foo foo foo foo +│ foo foo │ opt0", " ", @@ -1235,11 +1228,10 @@ exports[`select (isCI = true) > wraps long results 1`] = ` "", "", "◇ foo -│ foo foo foo foo foo foo foo -│  foo foo foo foo foo foo  -│ foo foo foo foo foo foo foo -│  foo foo foo foo foo foo  -│ foo foo foo foo", +│ foo foo foo foo foo foo foo foo foo  +│ foo foo foo foo foo foo foo foo foo  +│ foo foo foo foo foo foo foo foo foo  +│ foo foo foo", " ", "", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b0eb3a9b..f6be00ff 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -66,6 +66,9 @@ importers: packages/core: dependencies: + fast-string-width: + specifier: ^3.0.2 + version: 3.0.2 fast-wrap-ansi: specifier: ^0.2.0 version: 0.2.0