Skip to content

Commit c084e3e

Browse files
stronciumsindresorhus
authored andcommittedMar 3, 2019
Fix a bunch of issues (#30)
Fixes #23 Fixes #24 Fixes #25 Fixes #26 Fixes #27
1 parent 8640dc3 commit c084e3e

File tree

2 files changed

+42
-8
lines changed

2 files changed

+42
-8
lines changed
 

‎index.js

+12-7
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ const wrapWord = (rows, word, columns) => {
6868
//
6969
// 'soft' allows long words to expand past the column length
7070
const exec = (string, columns, options = {}) => {
71-
if (string.trim() === '') {
72-
return options.trim === false ? string : string.trim();
71+
if (options.trim !== false && string.trim() === '') {
72+
return '';
7373
}
7474

7575
let pre = '';
@@ -80,11 +80,13 @@ const exec = (string, columns, options = {}) => {
8080
const rows = [''];
8181

8282
for (const [index, word] of string.split(' ').entries()) {
83-
rows[rows.length - 1] = options.trim === false ? rows[rows.length - 1] : rows[rows.length - 1].trim();
83+
if (options.trim !== false) {
84+
rows[rows.length - 1] = rows[rows.length - 1].trimLeft();
85+
}
8486
let rowLength = stringWidth(rows[rows.length - 1]);
8587

86-
if (rowLength || word === '') {
87-
if (rowLength === columns && options.wordWrap === false) {
88+
if (index !== 0) {
89+
if (rowLength === columns && (options.wordWrap === false || options.trim === false)) {
8890
// If we start with a new word but the current row length equals the length of the columns, add a new row
8991
rows.push('');
9092
rowLength = 0;
@@ -96,8 +98,11 @@ const exec = (string, columns, options = {}) => {
9698

9799
// In 'hard' wrap mode, the length of a line is
98100
// never allowed to extend past 'columns'
99-
if (lengths[index] > columns && options.hard) {
100-
if (rowLength) {
101+
if (options.hard && lengths[index] > columns) {
102+
const remainingColumns = (columns - rowLength);
103+
const breaksStartingThisLine = 1 + Math.floor((lengths[index] - remainingColumns - 1) / columns);
104+
const breaksStartingNextLine = Math.floor((lengths[index] - 1) / columns);
105+
if (breaksStartingNextLine < breaksStartingThisLine) {
101106
rows.push('');
102107
}
103108
wrapWord(rows, word, columns);

‎test.js

+30-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ test('does not prepend newline if first string is greater than "cols"', t => {
5353
test('breaks strings longer than "cols" characters', t => {
5454
const res5 = m(fixture, 5, {hard: true});
5555

56-
t.is(res5, 'The\nquick\nbrown\n\u001B[31mfox\u001B[39m\n\u001B[31mjumpe\u001B[39m\n\u001B[31md\u001B[39m\n\u001B[31mover\u001B[39m\n\u001B[31m\u001B[39mthe\nlazy\n\u001B[32mdog\u001B[39m\n\u001B[32mand\u001B[39m\n\u001B[32mthen\u001B[39m\n\u001B[32mran\u001B[39m\n\u001B[32maway\u001B[39m\n\u001B[32mwith\u001B[39m\n\u001B[32mthe\u001B[39m\n\u001B[32munico\u001B[39m\n\u001B[32mrn.\u001B[39m');
56+
t.is(res5, 'The\nquick\nbrown\n\u001B[31mfox j\u001B[39m\n\u001B[31mumped\u001B[39m\n\u001B[31mover\u001B[39m\n\u001B[31m\u001B[39mthe\nlazy\n\u001B[32mdog\u001B[39m\n\u001B[32mand\u001B[39m\n\u001B[32mthen\u001B[39m\n\u001B[32mran\u001B[39m\n\u001B[32maway\u001B[39m\n\u001B[32mwith\u001B[39m\n\u001B[32mthe\u001B[39m\n\u001B[32munico\u001B[39m\n\u001B[32mrn.\u001B[39m');
5757
t.true(stripAnsi(res5).split('\n').every(x => x.length <= 5));
5858
});
5959

@@ -113,3 +113,32 @@ test('supports unicode surrogate pairs', t => {
113113
t.is(m('a\uD83C\uDE00bc', 2, {hard: true}), 'a\n\uD83C\uDE00\nbc');
114114
t.is(m('a\uD83C\uDE00bc\uD83C\uDE00d\uD83C\uDE00', 2, {hard: true}), 'a\n\uD83C\uDE00\nbc\n\uD83C\uDE00\nd\n\uD83C\uDE00');
115115
});
116+
117+
test('#23, properly wraps whitespace with no trimming', t => {
118+
t.is(m(' ', 2, {trim: false}), ' \n ');
119+
t.is(m(' ', 2, {trim: false, hard: true}), ' \n ');
120+
});
121+
122+
test('#24, trims leading and trailing whitespace only on actual wrapped lines and only with trimming', t => {
123+
t.is(m(' foo bar ', 6), 'foo\nbar');
124+
t.is(m(' foo bar ', 42), 'foo bar');
125+
t.is(m(' foo bar ', 42, {trim: false}), ' foo bar ');
126+
});
127+
128+
test('#25, properly wraps whitespace between words with no trimming', t => {
129+
t.is(m('foo bar', 3), 'foo\nbar');
130+
t.is(m('foo bar', 3, {hard: true}), 'foo\nbar');
131+
t.is(m('foo bar', 3, {trim: false}), 'foo\n \nbar');
132+
t.is(m('foo bar', 3, {trim: false, hard: true}), 'foo\n \nbar');
133+
});
134+
135+
test('#26, does not multiplicate leading spaces with no trimming', t => {
136+
t.is(m(' a ', 10, {trim: false}), ' a ');
137+
t.is(m(' a ', 10, {trim: false}), ' a ');
138+
});
139+
140+
test('#27, does not remove spaces in line with ansi escapes when no trimming', t => {
141+
t.is(m(chalk.bgGreen(` ${chalk.black('OK')} `), 100, {trim: false}), chalk.bgGreen(` ${chalk.black('OK')} `));
142+
t.is(m(chalk.bgGreen(` ${chalk.black('OK')} `), 100, {trim: false}), chalk.bgGreen(` ${chalk.black('OK')} `));
143+
t.is(m(chalk.bgGreen(' hello '), 10, {hard: true, trim: false}), chalk.bgGreen(' hello '));
144+
});

0 commit comments

Comments
 (0)
Please sign in to comment.