diff --git a/.changeset/cruel-hairs-swim.md b/.changeset/cruel-hairs-swim.md new file mode 100644 index 00000000..d3292200 --- /dev/null +++ b/.changeset/cruel-hairs-swim.md @@ -0,0 +1,5 @@ +--- +"@clack/prompts": patch +--- + +Fix spinner clearing too many lines upwards when non-wrapping. diff --git a/packages/prompts/src/spinner.ts b/packages/prompts/src/spinner.ts index 3ff9d70c..2a9cfd63 100644 --- a/packages/prompts/src/spinner.ts +++ b/packages/prompts/src/spinner.ts @@ -101,7 +101,9 @@ export const spinner = ({ trim: false, }); const prevLines = wrapped.split('\n'); - output.write(cursor.up(prevLines.length - 1)); + if (prevLines.length > 1) { + output.write(cursor.up(prevLines.length - 1)); + } output.write(cursor.to(0)); output.write(erase.down()); }; diff --git a/packages/prompts/test/__snapshots__/progress-bar.test.ts.snap b/packages/prompts/test/__snapshots__/progress-bar.test.ts.snap index 86593d50..72508fbc 100644 --- a/packages/prompts/test/__snapshots__/progress-bar.test.ts.snap +++ b/packages/prompts/test/__snapshots__/progress-bar.test.ts.snap @@ -6,7 +6,6 @@ exports[`prompts - progress (isCI = false) > message > sets message for next fra "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ", - "", "", "", "◐ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ foo", @@ -96,15 +95,12 @@ exports[`prompts - progress (isCI = false) > start > renders frames at interval "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ", - "", "", "", "◐ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ", - "", "", "", "◓ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ", - "", "", "", "◑ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ", @@ -135,7 +131,6 @@ exports[`prompts - progress (isCI = false) > stop > renders cancel symbol if cod "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ", - "", "", "", "■ @@ -150,7 +145,6 @@ exports[`prompts - progress (isCI = false) > stop > renders error symbol if code "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ", - "", "", "", "▲ @@ -165,7 +159,6 @@ exports[`prompts - progress (isCI = false) > stop > renders message 1`] = ` "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ", - "", "", "", "◇ foo @@ -180,7 +173,6 @@ exports[`prompts - progress (isCI = false) > stop > renders message without remo "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ", - "", "", "", "◇ foo. @@ -195,7 +187,6 @@ exports[`prompts - progress (isCI = false) > stop > renders submit symbol and st "│ ", "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ", - "", "", "", "◇ @@ -210,19 +201,15 @@ exports[`prompts - progress (isCI = false) > style > renders block progressbar 1 "│ ", "◒ ██████████ ", - "", "", "", "◐ ██████████ ", - "", "", "", "◓ ██████████ ", - "", "", "", "◑ ██████████ ", - "", "", "", "◇ @@ -237,19 +224,15 @@ exports[`prompts - progress (isCI = false) > style > renders heavy progressbar 1 "│ ", "◒ ━━━━━━━━━━ ", - "", "", "", "◐ ━━━━━━━━━━ ", - "", "", "", "◓ ━━━━━━━━━━ ", - "", "", "", "◑ ━━━━━━━━━━ ", - "", "", "", "◇ @@ -264,19 +247,15 @@ exports[`prompts - progress (isCI = false) > style > renders light progressbar 1 "│ ", "◒ ────────── ", - "", "", "", "◐ ────────── ", - "", "", "", "◓ ────────── ", - "", "", "", "◑ ────────── ", - "", "", "", "◇ @@ -293,7 +272,6 @@ exports[`prompts - progress (isCI = true) > message > sets message for next fram "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ...", " ", - "", "", "", "◐ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ foo...", @@ -412,7 +390,6 @@ exports[`prompts - progress (isCI = true) > stop > renders cancel symbol if code "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ...", " ", - "", "", "", "■ @@ -429,7 +406,6 @@ exports[`prompts - progress (isCI = true) > stop > renders error symbol if code "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ...", " ", - "", "", "", "▲ @@ -446,7 +422,6 @@ exports[`prompts - progress (isCI = true) > stop > renders message 1`] = ` "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ...", " ", - "", "", "", "◇ foo @@ -463,7 +438,6 @@ exports[`prompts - progress (isCI = true) > stop > renders message without remov "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ...", " ", - "", "", "", "◇ foo. @@ -480,7 +454,6 @@ exports[`prompts - progress (isCI = true) > stop > renders submit symbol and sto "◒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ...", " ", - "", "", "", "◇ @@ -497,13 +470,11 @@ exports[`prompts - progress (isCI = true) > style > renders block progressbar 1` "◒ ██████████ ...", " ", - "", "", "", "◐ ██████████ ...", " ", - "", "", "", "◇ @@ -520,13 +491,11 @@ exports[`prompts - progress (isCI = true) > style > renders heavy progressbar 1` "◒ ━━━━━━━━━━ ...", " ", - "", "", "", "◐ ━━━━━━━━━━ ...", " ", - "", "", "", "◇ @@ -543,13 +512,11 @@ exports[`prompts - progress (isCI = true) > style > renders light progressbar 1` "◒ ────────── ...", " ", - "", "", "", "◐ ────────── ...", " ", - "", "", "", "◇ diff --git a/packages/prompts/test/__snapshots__/spinner.test.ts.snap b/packages/prompts/test/__snapshots__/spinner.test.ts.snap index 0d2c987e..5bc4a650 100644 --- a/packages/prompts/test/__snapshots__/spinner.test.ts.snap +++ b/packages/prompts/test/__snapshots__/spinner.test.ts.snap @@ -17,19 +17,15 @@ exports[`spinner (isCI = false) > indicator customization > custom delay 1`] = ` "│ ", "◒ ", - "", "", "", "◐ ", - "", "", "", "◓ ", - "", "", "", "◑ ", - "", "", "", "◇ @@ -44,19 +40,15 @@ exports[`spinner (isCI = false) > indicator customization > custom frames 1`] = "│ ", "🐴 ", - "", "", "", "🦋 ", - "", "", "", "🐙 ", - "", "", "", "🐶 ", - "", "", "", "◇ @@ -71,259 +63,195 @@ exports[`spinner (isCI = false) > indicator customization > custom frames with l "│ ", "0 ", - "", "", "", "1 ", - "", "", "", "2 ", - "", "", "", "3 ", - "", "", "", "4 ", - "", "", "", "5 ", - "", "", "", "6 ", - "", "", "", "7 ", - "", "", "", "8 .", - "", "", "", "9 .", - "", "", "", "0 .", - "", "", "", "1 .", - "", "", "", "2 .", - "", "", "", "3 .", - "", "", "", "4 .", - "", "", "", "5 .", - "", "", "", "6 ..", - "", "", "", "7 ..", - "", "", "", "8 ..", - "", "", "", "9 ..", - "", "", "", "0 ..", - "", "", "", "1 ..", - "", "", "", "2 ..", - "", "", "", "3 ..", - "", "", "", "4 ...", - "", "", "", "5 ...", - "", "", "", "6 ...", - "", "", "", "7 ...", - "", "", "", "8 ...", - "", "", "", "9 ...", - "", "", "", "0 ...", - "", "", "", "1 ...", - "", "", "", "2 ...", - "", "", "", "3 ", - "", "", "", "4 ", - "", "", "", "5 ", - "", "", "", "6 ", - "", "", "", "7 ", - "", "", "", "8 ", - "", "", "", "9 ", - "", "", "", "0 ", - "", "", "", "1 .", - "", "", "", "2 .", - "", "", "", "3 .", - "", "", "", "4 .", - "", "", "", "5 .", - "", "", "", "6 .", - "", "", "", "7 .", - "", "", "", "8 .", - "", "", "", "9 ..", - "", "", "", "0 ..", - "", "", "", "1 ..", - "", "", "", "2 ..", - "", "", "", "3 ..", - "", "", "", "4 ..", - "", "", "", "5 ..", - "", "", "", "6 ..", - "", "", "", "7 ...", - "", "", "", "8 ...", - "", "", "", "9 ...", - "", "", "", "0 ...", - "", "", "", "1 ...", - "", "", "", "2 ...", - "", "", "", "3 ...", - "", "", "", "◇ @@ -338,11 +266,9 @@ exports[`spinner (isCI = false) > message > sets message for next frame 1`] = ` "│ ", "◒ ", - "", "", "", "◐ foo", - "", "", "", "◇ @@ -428,6 +354,23 @@ exports[`spinner (isCI = false) > process exit handling > uses global custom err ] `; +exports[`spinner (isCI = false) > start > handles multi-line messages 1`] = ` +[ + "", + "│ +", + "◒ foo +bar +baz", + "", + "", + "", + "◇ +", + "", +] +`; + exports[`spinner (isCI = false) > start > handles wrapping 1`] = ` [ "", @@ -450,19 +393,15 @@ exports[`spinner (isCI = false) > start > renders frames at interval 1`] = ` "│ ", "◒ ", - "", "", "", "◐ ", - "", "", "", "◓ ", - "", "", "", "◑ ", - "", "", "", "◇ @@ -477,7 +416,6 @@ exports[`spinner (isCI = false) > start > renders message 1`] = ` "│ ", "◒ foo", - "", "", "", "◇ @@ -492,7 +430,6 @@ exports[`spinner (isCI = false) > start > renders timer when indicator is "timer "│ ", "◒ [0s]", - "", "", "", "◇ [0s] @@ -507,7 +444,6 @@ exports[`spinner (isCI = false) > stop > renders cancel symbol if code = 1 1`] = "│ ", "◒ ", - "", "", "", "■ @@ -522,7 +458,6 @@ exports[`spinner (isCI = false) > stop > renders error symbol if code > 1 1`] = "│ ", "◒ ", - "", "", "", "▲ @@ -537,7 +472,6 @@ exports[`spinner (isCI = false) > stop > renders message 1`] = ` "│ ", "◒ ", - "", "", "", "◇ foo @@ -552,7 +486,6 @@ exports[`spinner (isCI = false) > stop > renders message without removing dots 1 "│ ", "◒ ", - "", "", "", "◇ foo. @@ -567,7 +500,6 @@ exports[`spinner (isCI = false) > stop > renders submit symbol and stops spinner "│ ", "◒ ", - "", "", "", "◇ @@ -595,7 +527,6 @@ exports[`spinner (isCI = true) > indicator customization > custom delay 1`] = ` "◒ ...", " ", - "", "", "", "◇ @@ -612,7 +543,6 @@ exports[`spinner (isCI = true) > indicator customization > custom frames 1`] = ` "🐴 ...", " ", - "", "", "", "◇ @@ -629,7 +559,6 @@ exports[`spinner (isCI = true) > indicator customization > custom frames with lo "0 ...", " ", - "", "", "", "◇ @@ -646,13 +575,11 @@ exports[`spinner (isCI = true) > message > sets message for next frame 1`] = ` "◒ ...", " ", - "", "", "", "◐ foo...", " ", - "", "", "", "◇ @@ -738,6 +665,25 @@ exports[`spinner (isCI = true) > process exit handling > uses global custom erro ] `; +exports[`spinner (isCI = true) > start > handles multi-line messages 1`] = ` +[ + "", + "│ +", + "◒ foo +bar +baz...", + " +", + "", + "", + "", + "◇ +", + "", +] +`; + exports[`spinner (isCI = true) > start > handles wrapping 1`] = ` [ "", @@ -764,7 +710,6 @@ exports[`spinner (isCI = true) > start > renders frames at interval 1`] = ` "◒ ...", " ", - "", "", "", "◇ @@ -781,7 +726,6 @@ exports[`spinner (isCI = true) > start > renders message 1`] = ` "◒ foo...", " ", - "", "", "", "◇ @@ -798,7 +742,6 @@ exports[`spinner (isCI = true) > start > renders timer when indicator is "timer" "◒ ...", " ", - "", "", "", "◇ [0s] @@ -815,7 +758,6 @@ exports[`spinner (isCI = true) > stop > renders cancel symbol if code = 1 1`] = "◒ ...", " ", - "", "", "", "■ @@ -832,7 +774,6 @@ exports[`spinner (isCI = true) > stop > renders error symbol if code > 1 1`] = ` "◒ ...", " ", - "", "", "", "▲ @@ -849,7 +790,6 @@ exports[`spinner (isCI = true) > stop > renders message 1`] = ` "◒ ...", " ", - "", "", "", "◇ foo @@ -866,7 +806,6 @@ exports[`spinner (isCI = true) > stop > renders message without removing dots 1` "◒ ...", " ", - "", "", "", "◇ foo. @@ -883,7 +822,6 @@ exports[`spinner (isCI = true) > stop > renders submit symbol and stops spinner "◒ ...", " ", - "", "", "", "◇ diff --git a/packages/prompts/test/spinner.test.ts b/packages/prompts/test/spinner.test.ts index 346aaee5..b3ba9f06 100644 --- a/packages/prompts/test/spinner.test.ts +++ b/packages/prompts/test/spinner.test.ts @@ -87,6 +87,18 @@ describe.each(['true', 'false'])('spinner (isCI = %s)', (isCI) => { expect(output.buffer).toMatchSnapshot(); }); + + test('handles multi-line messages', () => { + const result = prompts.spinner({ output }); + + result.start('foo\nbar\nbaz'); + + vi.advanceTimersByTime(80); + + result.stop(); + + expect(output.buffer).toMatchSnapshot(); + }); }); describe('stop', () => {