diff --git a/package.json b/package.json index 33c5744b1..aa2c75b9b 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,5 @@ "jest": { "coverageDirectory": "./coverage/", "collectCoverage": true - }, - "dependencies": {} + } } diff --git a/packages/core/lib/utils.js b/packages/core/lib/utils.js index 2a744eaaf..06099525d 100644 --- a/packages/core/lib/utils.js +++ b/packages/core/lib/utils.js @@ -1,3 +1,5 @@ +const wrapAnsi = require('wrap-ansi'); + /** * Force line returns at specific width. This function is ANSI code friendly and it'll * ignore invisible codes during width calculation. @@ -5,15 +7,8 @@ * @param {number} width * @return {string} */ -exports.breakLines = (content, width) => { - const regex = new RegExp('(?:(?:\\033[[0-9;]*m)*.?){1,' + width + '}', 'g'); - return content +exports.breakLines = (content, width) => + content .split('\n') - .flatMap((line) => { - const chunk = line.match(regex); - // Remove the last match as it's always empty - chunk.pop(); - return chunk || ''; - }) + .map((line) => wrapAnsi(line, width, { trim: false, hard: true })) .join('\n'); -}; diff --git a/packages/core/package.json b/packages/core/package.json index 71d4cdb5e..9fbeb3301 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -21,7 +21,8 @@ "mute-stream": "^0.0.8", "run-async": "^2.3.0", "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" }, "publishConfig": { "access": "public" diff --git a/packages/inquirer/examples/terminal-link.js b/packages/inquirer/examples/terminal-link.js new file mode 100644 index 000000000..1cd2b59b3 --- /dev/null +++ b/packages/inquirer/examples/terminal-link.js @@ -0,0 +1,36 @@ +/** + * A terminal-link example. We expect no odd line breaks. + * Note: you will need a compatible terminal to see the rendered links. https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda + * For screenshots of the expected behavior, see https://github.com/SBoudrias/Inquirer.js/pull/1106 + */ + +'use strict'; +const inquirer = require('..'); +const terminalLink = require('terminal-link'); + +inquirer + .prompt([ + { + type: 'list', + name: 'size', + message: 'What size do you need?', + choices: [ + 'Jumbo', + 'Large', + 'Standard', + 'Medium', + 'Small', + 'Micro which is truly and surely the ' + + terminalLink( + 'very very very very very very smallest', + 'https://www.google.com/search?q=very+very+very+very+very+very+very+very+very+very+long' + ), + ], + filter(val) { + return val.toLowerCase(); + }, + }, + ]) + .then((answers) => { + console.log(JSON.stringify(answers, null, ' ')); + }); diff --git a/packages/inquirer/lib/utils/screen-manager.js b/packages/inquirer/lib/utils/screen-manager.js index 9fd1c1b71..0be0e8e16 100644 --- a/packages/inquirer/lib/utils/screen-manager.js +++ b/packages/inquirer/lib/utils/screen-manager.js @@ -1,6 +1,7 @@ 'use strict'; const util = require('./readline'); const cliWidth = require('cli-width'); +const wrapAnsi = require('wrap-ansi'); const stripAnsi = require('strip-ansi'); const stringWidth = require('string-width'); const ora = require('ora'); @@ -156,13 +157,10 @@ class ScreenManager { breakLines(lines, width = this.normalizedCliWidth()) { // Break lines who're longer than the cli width so we can normalize the natural line // returns behavior across terminals. - const regex = new RegExp(`(?:(?:\\033[[0-9;]*m)*.?){1,${width}}`, 'g'); - return lines.map((line) => { - const chunk = line.match(regex); - // Last match is always empty - chunk.pop(); - return chunk || ''; - }); + // re: trim: false; by default, `wrap-ansi` trims whitespace, which + // is not what we want. + // re: hard: true; by default', `wrap-ansi` does soft wrapping + return lines.map((line) => wrapAnsi(line, width, { trim: false, hard: true })); } /** diff --git a/packages/inquirer/package.json b/packages/inquirer/package.json index 0e70ab0cb..3d9884ab7 100644 --- a/packages/inquirer/package.json +++ b/packages/inquirer/package.json @@ -26,7 +26,8 @@ "mocha": "^9.2.2", "mockery": "^2.1.0", "nyc": "^15.0.0", - "sinon": "^13.0.1" + "sinon": "^13.0.1", + "terminal-link": "^2.1.1" }, "scripts": { "test": "nyc mocha test/**/* -r ./test/before", @@ -50,6 +51,7 @@ "rxjs": "^7.5.5", "string-width": "^4.1.0", "strip-ansi": "^6.0.0", - "through": "^2.3.6" + "through": "^2.3.6", + "wrap-ansi": "^7.0.0" } }