Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
shannonmoeller committed Feb 13, 2016
0 parents commit 01984d3
Show file tree
Hide file tree
Showing 7 changed files with 212 additions and 0 deletions.
16 changes: 16 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = tab
insert_final_newline = true
trim_trailing_whitespace = true

[*.json]
indent_size = 2
indent_style = space

[*.md]
indent_style = space
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.nyc_output/
coverage/
node_modules/

*.log
.*.swp
.npmignore
16 changes: 16 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
sudo: false
language: node_js
node_js:
- node
- '5.5'
- '5.4'
- '5.3'
- '5.2'
- '5.1'
- '5.0'
- '4.2'
- '4.1'
- '4.0'
- '0.12'
after_script:
- npm run coveralls
47 changes: 47 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"name": "cli-columns",
"version": "1.0.0",
"description": "Columnated lists for the CLI.",
"main": "src/cli-columns.js",
"scripts": {
"coveralls": "nyc report -r text-lcov | coveralls",
"pretest": "xo src/*.js test/*.js",
"test": "nyc ava -v test/*.js",
"watch": "watch 'npm test' src test -du"
},
"repository": {
"type": "git",
"url": "https://github.com/shannonmoeller/colonel"
},
"keywords": [
"ansi",
"cli",
"column",
"columns",
"list",
"log",
"ls",
"row",
"rows",
"unicode",
"unix"
],
"author": "Shannon Moeller <me@shannonmoeller> (http://shannonmoeller.com)",
"license": "MIT",
"bugs": {
"url": "https://github.com/shannonmoeller/colonel/issues"
},
"homepage": "https://github.com/shannonmoeller/colonel",
"dependencies": {
"object-assign": "^4.0.1",
"string-width": "^1.0.1"
},
"devDependencies": {
"ava": "^0.11.0",
"chalk": "^1.1.1",
"nyc": "^5.6.0",
"strip-ansi": "^3.0.0",
"watch": "^0.17.1",
"xo": "^0.12.1"
}
}
67 changes: 67 additions & 0 deletions src/cli-columns.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
var assign = require('object-assign');
var stringWidth = require('string-width');
var stripAnsi = require('strip-ansi');
var concat = Array.prototype.concat;

var defaults = {
character: ' ',
newline: '\n',
padding: 2,
width: 0
};

function byPlainText(a, b) {
return stripAnsi(a) > stripAnsi(b) ? 1 : -1;
}

function makeArray() {
return [];
}

function makeList(count) {
return Array.apply(null, Array(count));
}

function padCell(fullWidth, character, value) {
var valueWidth = stringWidth(value);
var filler = makeList(fullWidth - valueWidth + 1);

return value + filler.join(character);
}

function toRows(rows, cell, i) {
rows[i % rows.length].push(cell);

return rows;
}

function toString(arr) {
return arr.join('');
}

function columns(values, options) {
values = concat.apply([], values);
options = assign({}, defaults, options);

var cells = values
.filter(Boolean)
.map(String)
.sort(byPlainText);

var termWidth = options.width || process.stdout.columns;
var cellWidth = Math.max.apply(null, cells.map(stringWidth)) + options.padding;
var columnCount = Math.floor(termWidth / cellWidth) || 1;
var rowCount = Math.ceil(cells.length / columnCount) || 1;

if (columnCount === 1) {
return cells.join(options.newline);
}

return cells
.map(padCell.bind(null, cellWidth, options.character))
.reduce(toRows, makeList(rowCount).map(makeArray))
.map(toString)
.join(options.newline);
}

module.exports = columns;
58 changes: 58 additions & 0 deletions test/cli-columns.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import columns from '../src/cli-columns';
import chalk from 'chalk';
import stripAnsi from 'strip-ansi';
import test from 'ava';

test('should print one column list', async assert => {
var cols = columns(['foo', ['bar', 'baz'], ['bat', 'qux']], {
width: 2
});

console.log(cols);

var expected =
'bar\n' +
'bat\n' +
'baz\n' +
'foo\n' +
'qux';

assert.is(cols, expected);
});

test('should print three column list', async assert => {
var cols = columns(['foo', ['bar', 'baz'], ['bat', 'qux']], {
width: 16
});

console.log(cols);

var expected =
'bar baz qux \n' +
'bat foo ';

assert.is(cols, expected);
});

test('should print complex list', async assert => {
var cols = columns(
[
'foo', 'bar', 'baz', chalk.blue('berry'),
chalk.red('apple'), 'pomegranate',
'durian', chalk.green('star fruit'),
'apricot', 'pear', 'banana pinapple'
],
{
width: 80
}
);

console.log(cols);

var expected =
'apple bar durian pomegranate \n' +
'apricot baz foo star fruit \n' +
'banana pinapple berry pear ';

assert.is(stripAnsi(cols), expected);
});

0 comments on commit 01984d3

Please sign in to comment.