Skip to content

Commit

Permalink
calculate row lengths appropriately when they contain ansi colors
Browse files Browse the repository at this point in the history
  • Loading branch information
bcoe committed Oct 16, 2015
1 parent 5eac0ae commit 0aa60a3
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 7 deletions.
15 changes: 9 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
var stringWidth = require('string-width')
var wrap = require('wrap-ansi')
var align = {
right: require('right-align'),
Expand Down Expand Up @@ -52,10 +53,10 @@ UI.prototype._applyLayoutDSL = function (str) {
// than 50% of the screen.
rows.forEach(function (row) {
var columns = row.split('\t')
if (columns.length > 1 && columns[0].length > leftColumnWidth) {
if (columns.length > 1 && stringWidth(columns[0]) > leftColumnWidth) {
leftColumnWidth = Math.min(
Math.floor(_this.width * 0.5),
columns[0].length
stringWidth(columns[0])
)
}
})
Expand Down Expand Up @@ -118,15 +119,17 @@ UI.prototype.rowToString = function (row, lines) {
width = row[c].width // the width with padding.
wrapWidth = _this._negatePadding(row[c]) // the width without padding.

for (var i = 0; i < Math.max(wrapWidth, col.length); i++) {
ts += col.charAt(i) || ' '
ts += col

for (var i = 0; i < wrapWidth - stringWidth(col); i++) {
ts += ' '
}

// align the string within its column.
if (row[c].align && row[c].align !== 'left' && _this.wrap) {
ts = align[row[c].align](ts.trim() + '\n' + new Array(wrapWidth + 1).join(' '))
.split('\n')[0]
if (ts.length < wrapWidth) ts += new Array(width - ts.length).join(' ')
if (stringWidth(ts) < wrapWidth) ts += new Array(width - stringWidth(ts)).join(' ')
}

// add left/right padding and print string.
Expand Down Expand Up @@ -248,7 +251,7 @@ UI.prototype._columnWidths = function (row) {
// any unset widths should be calculated.
if (unset) unsetWidth = Math.floor(remainingWidth / unset)
widths.forEach(function (w, i) {
if (!_this.wrap) widths[i] = row[i].width || row[i].text.length
if (!_this.wrap) widths[i] = row[i].width || stringWidth(row[i].text)
else if (w === undefined) widths[i] = Math.max(unsetWidth, _minWidth(row[i]))
})

Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,16 @@
"dependencies": {
"center-align": "^0.1.1",
"right-align": "^0.1.1",
"string-width": "^1.0.1",
"wrap-ansi": "^1.0.0"
},
"devDependencies": {
"chai": "^3.3.0",
"chalk": "^1.1.1",
"coveralls": "^2.11.4",
"mocha": "^2.3.3",
"nyc": "^3.2.2",
"standard": "^5.3.1"
"standard": "^5.3.1",
"strip-ansi": "^3.0.0"
}
}
24 changes: 24 additions & 0 deletions test/cliui.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

require('chai').should()

var chalk = require('chalk')
var cliui = require('../')
var stripAnsi = require('strip-ansi')

describe('cliui', function () {
describe('div', function () {
Expand Down Expand Up @@ -332,6 +334,28 @@ describe('cliui', function () {
ui.toString().split('\n').should.eql(expected)
})

it('aligns rows appropriately when they contain ansi escape codes', function () {
var ui = cliui({
width: 40
})

ui.div(
' <regex>\t ' + chalk.red('my awesome regex') + '\t [regex]\n ' + chalk.blue('<glob>') + '\t my awesome glob\t [required]'
)

chalk
var expected = [
' <regex> my awesome [regex]',
' regex',
' <glob> my awesome [required]',
' glob'
]

ui.toString().split('\n').map(function (l) {
return stripAnsi(l)
}).should.eql(expected)
})

it('does not apply DSL if wrap is false', function () {
var ui = cliui({
width: 40,
Expand Down

0 comments on commit 0aa60a3

Please sign in to comment.