optimize Table element. first pass at ListTable.
This commit is contained in:
parent
cbc94254b4
commit
8793be5562
35
README.md
35
README.md
|
@ -1076,6 +1076,41 @@ A stylized table of text elements.
|
|||
]);
|
||||
```
|
||||
|
||||
|
||||
#### ListTable (from Box)
|
||||
|
||||
A stylized table of text elements with a list.
|
||||
|
||||
##### Options:
|
||||
|
||||
- inherits all from Box.
|
||||
- __rows/data__ - array of array of strings representing rows.
|
||||
- __pad__ - spaces to attempt to pad on the sides of each cell. `2` by default:
|
||||
one space on each side.
|
||||
- __style.header__ - header style.
|
||||
- __style.cell__ - cell style.
|
||||
|
||||
##### Properties:
|
||||
|
||||
- inherits all from Box.
|
||||
|
||||
##### Events:
|
||||
|
||||
- inherits all from Box.
|
||||
|
||||
##### Methods:
|
||||
|
||||
- inherits all from Box.
|
||||
- __setRows/setData(rows)__ - set rows in table. array of arrays of strings.
|
||||
```
|
||||
table.setData([
|
||||
[ 'Animals', 'Foods' ],
|
||||
[ 'Elephant', 'Apple' ],
|
||||
[ 'Bird', 'Orange' ]
|
||||
]);
|
||||
```
|
||||
|
||||
|
||||
#### Terminal (from Box)
|
||||
|
||||
A box which spins up a pseudo terminal and renders the output. Useful for
|
||||
|
|
452
lib/widget.js
452
lib/widget.js
|
@ -4658,6 +4658,12 @@ List.prototype.appendItem = function(item) {
|
|||
options.right = this.iright + (this.scrollbar ? 1 : 0);
|
||||
}
|
||||
|
||||
// if (this.shrink) {
|
||||
if (this.shrink && this.options.normalShrink) {
|
||||
delete options.right;
|
||||
options.width = 'shrink';
|
||||
}
|
||||
|
||||
['bg', 'fg', 'bold', 'underline',
|
||||
'blink', 'inverse', 'invisible'].forEach(function(name) {
|
||||
options[name] = function() {
|
||||
|
@ -6783,7 +6789,6 @@ Log.prototype.add = function(text) {
|
|||
|
||||
/**
|
||||
* Table
|
||||
* TODO: Draw custom border with proper angles.
|
||||
*/
|
||||
|
||||
function Table(options) {
|
||||
|
@ -6795,6 +6800,11 @@ function Table(options) {
|
|||
|
||||
options = options || {};
|
||||
options.shrink = true;
|
||||
options.style = options.style || {};
|
||||
options.style.border = options.style.border || {};
|
||||
options.style.header = options.style.header || {};
|
||||
options.style.cell = options.style.cell || {};
|
||||
options.align = options.align || 'center';
|
||||
|
||||
Box.call(this, options);
|
||||
|
||||
|
@ -6804,10 +6814,16 @@ function Table(options) {
|
|||
? options.pad
|
||||
: 2;
|
||||
|
||||
this.__align = options.align || 'center';
|
||||
delete this.align;
|
||||
|
||||
this.setData(options.rows || options.data);
|
||||
|
||||
this.screen.on('resize', function() {
|
||||
var rows = self.rows;
|
||||
// XXX Need to clear previous box.
|
||||
self.setData([]);
|
||||
self.screen.render();
|
||||
self.setData(rows);
|
||||
self.screen.render();
|
||||
});
|
||||
}
|
||||
|
||||
Table.prototype.__proto__ = Box.prototype;
|
||||
|
@ -6820,16 +6836,20 @@ Table.prototype.setData = function(rows) {
|
|||
, text = ''
|
||||
, maxes = []
|
||||
, total = 0
|
||||
, line = '';
|
||||
, line = ''
|
||||
, align = this.align;
|
||||
|
||||
// TODO Pregenerate `generateTags` calls here!
|
||||
var sborder = generateTags(this.style.border)
|
||||
, sheader = generateTags(this.style.header)
|
||||
, scell = generateTags(this.style.cell);
|
||||
|
||||
this.rows = rows || [];
|
||||
|
||||
this.rows.forEach(function(row) {
|
||||
row.forEach(function(cell, i) {
|
||||
if (!maxes[i] || maxes[i] < self._cellLength(cell) + self.pad) {
|
||||
maxes[i] = self._cellLength(cell) + self.pad;
|
||||
var clen = self._cellLength(cell);
|
||||
if (!maxes[i] || maxes[i] < clen + self.pad) {
|
||||
maxes[i] = clen + self.pad;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -6838,48 +6858,54 @@ Table.prototype.setData = function(rows) {
|
|||
total += cell + 1 + self.pad;
|
||||
});
|
||||
|
||||
// TODO Use these values to render the border
|
||||
// elsewhere, in the usual border rendering.
|
||||
this._maxes = maxes;
|
||||
|
||||
maxes.forEach(function(width, i) {
|
||||
if (i !== 0) {
|
||||
line += '\u253c'; // '┼'
|
||||
}
|
||||
for (var i = 0; i < width; i++) {
|
||||
line += '\u2500'; // '─'
|
||||
}
|
||||
});
|
||||
line = generateTags(self.style.border, line);
|
||||
// maxes.forEach(function(width, i) {
|
||||
// if (i !== 0) {
|
||||
// line += '\u253c'; // '┼'
|
||||
// }
|
||||
// for (var i = 0; i < width; i++) {
|
||||
// line += '\u2500'; // '─'
|
||||
// }
|
||||
// });
|
||||
// line = sborder.open + line + sborder.close;
|
||||
|
||||
this.rows.forEach(function(row, i) {
|
||||
var isHeader = i === 0;
|
||||
var isFooter = i === self.rows.length - 1;
|
||||
row.forEach(function(cell, i) {
|
||||
var width = maxes[i];
|
||||
var clen = self._cellLength(cell);
|
||||
|
||||
if (i !== 0) {
|
||||
text += generateTags(self.style.border, '\u2502'); // '│'
|
||||
// text += sborder.open + '\u2502' + sborder.close; // '│'
|
||||
text += ' ';
|
||||
}
|
||||
|
||||
while (self._cellLength(cell) < width) {
|
||||
if (self.__align === 'center') {
|
||||
while (clen < width) {
|
||||
if (align === 'center') {
|
||||
cell = ' ' + cell + ' ';
|
||||
} else if (self.__align === 'left') {
|
||||
clen += 2;
|
||||
} else if (align === 'left') {
|
||||
cell = cell + ' ';
|
||||
} else if (self.__align === 'right') {
|
||||
clen += 1;
|
||||
} else if (align === 'right') {
|
||||
cell = ' ' + cell;
|
||||
clen += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (self._cellLength(cell) > width) {
|
||||
if (self.__align === 'center') {
|
||||
if (clen > width) {
|
||||
if (align === 'center') {
|
||||
// cell = cell.slice(0, -1);
|
||||
cell = cell.substring(1);
|
||||
} else if (self.__align === 'left') {
|
||||
clen--;
|
||||
} else if (align === 'left') {
|
||||
cell = cell.slice(0, -1);
|
||||
} else if (self.__align === 'right') {
|
||||
clen--;
|
||||
} else if (align === 'right') {
|
||||
cell = cell.substring(1);
|
||||
clen--;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6889,16 +6915,17 @@ Table.prototype.setData = function(rows) {
|
|||
}
|
||||
|
||||
if (isHeader) {
|
||||
cell = generateTags(self.style.header, cell);
|
||||
cell = sheader.open + cell + sheader.close;
|
||||
} else {
|
||||
cell = generateTags(self.style.cell, cell);
|
||||
cell = scell.open + cell + scell.close;
|
||||
}
|
||||
|
||||
text += cell;
|
||||
});
|
||||
text += '\n';
|
||||
if (!isFooter) {
|
||||
text += line + '\n';
|
||||
// text += line + '\n';
|
||||
text += '\n';
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -6906,7 +6933,9 @@ Table.prototype.setData = function(rows) {
|
|||
text = text.slice(0, -1);
|
||||
}
|
||||
|
||||
return this.setContent(text);
|
||||
delete this.align;
|
||||
this.setContent(text);
|
||||
this.align = align;
|
||||
};
|
||||
|
||||
Table.prototype._cellLength = function(text) {
|
||||
|
@ -6916,6 +6945,362 @@ Table.prototype._cellLength = function(text) {
|
|||
return text.replace(/{(\/?)([\w\-,;!#]*)}/g, '').length;
|
||||
};
|
||||
|
||||
Table.prototype.render = function() {
|
||||
var self = this;
|
||||
|
||||
var coords = this._render();
|
||||
if (!coords) return;
|
||||
|
||||
if (!this._maxes) return coords;
|
||||
|
||||
var lines = this.screen.lines
|
||||
, xi = coords.xi
|
||||
, xl = coords.xl
|
||||
, yi = coords.yi
|
||||
, yl = coords.yl
|
||||
, rx
|
||||
, ry
|
||||
, i;
|
||||
|
||||
var header = this.sattr(
|
||||
this.style.header,
|
||||
this.style.header.fg,
|
||||
this.style.header.bg);
|
||||
|
||||
var cell = this.sattr(
|
||||
this.style.cell,
|
||||
this.style.cell.fg,
|
||||
this.style.cell.bg);
|
||||
|
||||
var battr = this.sattr(
|
||||
this.style.border,
|
||||
this.style.border.fg,
|
||||
this.style.border.bg);
|
||||
|
||||
var width = coords.xl - coords.xi - this.iwidth / 2
|
||||
, height = coords.yl - coords.yi - this.iheight / 2;
|
||||
|
||||
// Apply attributes to header cells and cells.
|
||||
// Problem: Does not allow for tags in cells.
|
||||
// for (var y = this.iheight / 2; y < height; y++) {
|
||||
// for (var x = this.iwidth / 2; x < width; x++) {
|
||||
// if (y === this.iheight / 2) {
|
||||
// lines[yi + y][xi + x][0] = header;
|
||||
// } else {
|
||||
// lines[yi + y][xi + x][0] = cell;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
if (!this.border) return coords;
|
||||
|
||||
// Draw border with correct angles.
|
||||
ry = 0;
|
||||
for (i = 0; i < self.rows.length + 1; i++) {
|
||||
rx = 0;
|
||||
self._maxes.forEach(function(max, i) {
|
||||
rx += max;
|
||||
if (i === 0) {
|
||||
// left side
|
||||
if (ry === 0) {
|
||||
// top
|
||||
lines[yi + ry][xi + 0][0] = battr;
|
||||
lines[yi + ry][xi + 0][1] = '\u250c'; // '┌'
|
||||
} else if (ry / 2 === self.rows.length) {
|
||||
// bottom
|
||||
lines[yi + ry][xi + 0][0] = battr;
|
||||
lines[yi + ry][xi + 0][1] = '\u2514'; // '└'
|
||||
} else {
|
||||
// middle
|
||||
lines[yi + ry][xi + 0][0] = battr;
|
||||
lines[yi + ry][xi + 0][1] = '\u251c'; // '├'
|
||||
}
|
||||
} else if (i === self.rows.length - 1) {
|
||||
// right side
|
||||
if (ry === 0) {
|
||||
// top
|
||||
lines[yi + ry][xi + ++rx][0] = battr;
|
||||
lines[yi + ry][xi + rx][1] = '\u2510'; // '┐'
|
||||
} else if (ry / 2 === self.rows.length) {
|
||||
// bottom
|
||||
lines[yi + ry][xi + ++rx][0] = battr;
|
||||
lines[yi + ry][xi + rx][1] = '\u2518'; // '┘'
|
||||
} else {
|
||||
// middle
|
||||
lines[yi + ry][xi + ++rx][0] = battr;
|
||||
lines[yi + ry][xi + rx][1] = '\u2524'; // '┤'
|
||||
}
|
||||
return;
|
||||
}
|
||||
// center
|
||||
if (ry === 0) {
|
||||
// top
|
||||
lines[yi + ry][xi + ++rx][0] = battr;
|
||||
lines[yi + ry][xi + rx][1] = '\u252c'; // '┬'
|
||||
} else if (ry / 2 === self.rows.length) {
|
||||
// bottom
|
||||
lines[yi + ry][xi + ++rx][0] = battr;
|
||||
lines[yi + ry][xi + rx][1] = '\u2534'; // '┴'
|
||||
} else {
|
||||
// middle
|
||||
lines[yi + ry][xi + ++rx][0] = battr;
|
||||
lines[yi + ry][xi + rx][1] = '\u253c'; // '┼'
|
||||
// ++rx;
|
||||
}
|
||||
});
|
||||
ry += 2;
|
||||
}
|
||||
|
||||
// Draw internal borders.
|
||||
for (ry = 1; ry < self.rows.length * 2; ry++) {
|
||||
rx = 0;
|
||||
self._maxes.slice(0, -1).forEach(function(max, i) {
|
||||
rx += max;
|
||||
if (ry % 2 !== 0) {
|
||||
lines[yi + ry][xi + ++rx][0] = battr;
|
||||
lines[yi + ry][xi + rx][1] = '\u2502'; // '│'
|
||||
} else {
|
||||
rx++;
|
||||
}
|
||||
});
|
||||
rx = 1;
|
||||
self._maxes.forEach(function(max, i) {
|
||||
while (max--) {
|
||||
if (ry % 2 === 0) {
|
||||
lines[yi + ry][xi + rx][0] = battr;
|
||||
lines[yi + ry][xi + rx][1] = '\u2500'; // '─'
|
||||
}
|
||||
rx++;
|
||||
}
|
||||
// if (ry % 2 === 0 && i !== self._maxes.length - 1) {
|
||||
// lines[yi + ry][xi + rx][0] = battr;
|
||||
// lines[yi + ry][xi + rx][1] = '\u253c'; // '┼'
|
||||
// }
|
||||
rx++;
|
||||
});
|
||||
}
|
||||
|
||||
return coords;
|
||||
};
|
||||
|
||||
/**
|
||||
* ListTable
|
||||
*/
|
||||
|
||||
function ListTable(options) {
|
||||
var self = this;
|
||||
|
||||
if (!(this instanceof Node)) {
|
||||
return new ListTable(options);
|
||||
}
|
||||
|
||||
options = options || {};
|
||||
options.width = 'shrink';
|
||||
options.normalShrink = true;
|
||||
options.style = options.style || {};
|
||||
options.style.border = options.style.border || {};
|
||||
options.style.header = options.style.header || {};
|
||||
options.style.cell = options.style.cell || {};
|
||||
this.__align = options.align || 'center';
|
||||
delete options.align;
|
||||
|
||||
options.style.selected = options.style.cell.selected;
|
||||
options.style.item = options.style.cell;
|
||||
|
||||
List.call(this, options);
|
||||
|
||||
this._header = new Box({
|
||||
parent: this,
|
||||
left: this.screen.autoPadding ? 0 : this.ileft,
|
||||
top: 0,
|
||||
width: 'shrink',
|
||||
height: 1,
|
||||
style: options.style.header,
|
||||
tags: options.parseTags || options.tags
|
||||
});
|
||||
|
||||
this.on('scroll', function() {
|
||||
self._header.setFront();
|
||||
var visible = self.height - self.iheight;
|
||||
self._header.rtop = 1 + self.childBase - (self.border ? 1 : 0);
|
||||
if (!self.screen.autoPadding) {
|
||||
self._header.rtop = 1 + self.childBase;
|
||||
}
|
||||
// self.screen.render();
|
||||
});
|
||||
|
||||
this.pad = options.pad != null
|
||||
? options.pad
|
||||
: 2;
|
||||
|
||||
this.setData(options.rows || options.data);
|
||||
}
|
||||
|
||||
ListTable.prototype.__proto__ = List.prototype;
|
||||
|
||||
ListTable.prototype.type = 'list-table';
|
||||
|
||||
ListTable.prototype.setRows =
|
||||
ListTable.prototype.setData = function(rows) {
|
||||
var self = this
|
||||
, maxes = []
|
||||
, total = 0
|
||||
, align = this.__align;
|
||||
|
||||
this.clearItems();
|
||||
|
||||
this.rows = rows || [];
|
||||
|
||||
this.rows.forEach(function(row) {
|
||||
row.forEach(function(cell, i) {
|
||||
var clen = self._cellLength(cell);
|
||||
if (!maxes[i] || maxes[i] < clen + self.pad) {
|
||||
maxes[i] = clen + self.pad;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
maxes.forEach(function(cell) {
|
||||
total += cell + 1 + self.pad;
|
||||
});
|
||||
|
||||
this._maxes = maxes;
|
||||
|
||||
this.addItem('');
|
||||
|
||||
this.rows.forEach(function(row, i) {
|
||||
var isHeader = i === 0;
|
||||
var isFooter = i === self.rows.length - 1;
|
||||
var text = '';
|
||||
row.forEach(function(cell, i) {
|
||||
var width = maxes[i];
|
||||
var clen = self._cellLength(cell);
|
||||
|
||||
if (i !== 0) {
|
||||
text += ' ';
|
||||
}
|
||||
|
||||
while (clen < width) {
|
||||
if (align === 'center') {
|
||||
cell = ' ' + cell + ' ';
|
||||
clen += 2;
|
||||
} else if (align === 'left') {
|
||||
cell = cell + ' ';
|
||||
clen += 1;
|
||||
} else if (align === 'right') {
|
||||
cell = ' ' + cell;
|
||||
clen += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (clen > width) {
|
||||
if (align === 'center') {
|
||||
cell = cell.substring(1);
|
||||
clen--;
|
||||
} else if (align === 'left') {
|
||||
cell = cell.slice(0, -1);
|
||||
clen--;
|
||||
} else if (align === 'right') {
|
||||
cell = cell.substring(1);
|
||||
clen--;
|
||||
}
|
||||
}
|
||||
|
||||
text += cell;
|
||||
});
|
||||
if (isHeader) {
|
||||
self._header.setContent(text);
|
||||
} else {
|
||||
self.addItem(text);
|
||||
}
|
||||
});
|
||||
|
||||
this._header.setFront();
|
||||
|
||||
this.select(0);
|
||||
};
|
||||
|
||||
ListTable.prototype._select = ListTable.prototype.select;
|
||||
ListTable.prototype.select = function(i) {
|
||||
if (i === 0) {
|
||||
i = 1;
|
||||
}
|
||||
if (i <= 1) {
|
||||
this.setScroll(0);
|
||||
}
|
||||
return this._select(i);
|
||||
};
|
||||
|
||||
ListTable.prototype._cellLength = function(text) {
|
||||
if (!this.options.tags && !this.options.parseTags) {
|
||||
return text.length;
|
||||
}
|
||||
return text.replace(/{(\/?)([\w\-,;!#]*)}/g, '').length;
|
||||
};
|
||||
|
||||
ListTable.prototype.render = function() {
|
||||
var self = this;
|
||||
|
||||
var coords = this._render();
|
||||
if (!coords) return;
|
||||
|
||||
if (!this._maxes) return coords;
|
||||
|
||||
var lines = this.screen.lines
|
||||
, xi = coords.xi
|
||||
, xl = coords.xl
|
||||
, yi = coords.yi
|
||||
, yl = coords.yl
|
||||
, rx
|
||||
, ry
|
||||
, i;
|
||||
|
||||
var battr = this.sattr(
|
||||
this.style.border,
|
||||
this.style.border.fg,
|
||||
this.style.border.bg);
|
||||
|
||||
var width = coords.xl - coords.xi - this.iwidth / 2
|
||||
, height = coords.yl - coords.yi - this.iheight / 2;
|
||||
|
||||
if (!this.border) return coords;
|
||||
|
||||
// Draw border with correct angles.
|
||||
ry = 0;
|
||||
for (i = 0; i < height + 1; i++) {
|
||||
rx = 0;
|
||||
self._maxes.slice(0, -1).forEach(function(max, i) {
|
||||
rx += max;
|
||||
// center
|
||||
if (ry === 0) {
|
||||
// top
|
||||
lines[yi + ry][xi + ++rx][0] = battr;
|
||||
lines[yi + ry][xi + rx][1] = '\u252c'; // '┬'
|
||||
} else if (ry === height) {
|
||||
// bottom
|
||||
lines[yi + ry][xi + ++rx][0] = battr;
|
||||
lines[yi + ry][xi + rx][1] = '\u2534'; // '┴'
|
||||
} else {
|
||||
// middle
|
||||
++rx;
|
||||
}
|
||||
});
|
||||
ry += 1;
|
||||
}
|
||||
|
||||
// Draw internal borders.
|
||||
for (ry = 1; ry < height; ry++) {
|
||||
rx = 0;
|
||||
self._maxes.slice(0, -1).forEach(function(max, i) {
|
||||
rx += max;
|
||||
lines[yi + ry][xi + ++rx][0] = battr;
|
||||
lines[yi + ry][xi + rx][1] = '\u2502'; // '│'
|
||||
});
|
||||
}
|
||||
|
||||
return coords;
|
||||
};
|
||||
|
||||
/**
|
||||
* Terminal
|
||||
*/
|
||||
|
@ -7658,7 +8043,7 @@ function generateTags(style, text) {
|
|||
open = '{' + val + '-' + key + '}' + open;
|
||||
close += '{/' + val + '-' + key + '}';
|
||||
} else {
|
||||
if (val) {
|
||||
if (val === true) {
|
||||
open = '{' + key + '}' + open;
|
||||
close += '{/' + key + '}';
|
||||
}
|
||||
|
@ -7798,6 +8183,7 @@ exports.Listbar = exports.listbar = Listbar;
|
|||
|
||||
exports.Log = exports.log = Log;
|
||||
exports.Table = exports.table = Table;
|
||||
exports.ListTable = exports.listtable = ListTable;
|
||||
|
||||
exports.Terminal = exports.terminal = Terminal;
|
||||
exports.Image = exports.image = Image;
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
var blessed = require('../')
|
||||
, screen;
|
||||
|
||||
screen = blessed.screen({
|
||||
dump: __dirname + '/logs/listtable.log',
|
||||
autoPadding: false
|
||||
});
|
||||
|
||||
var table = blessed.listtable({
|
||||
parent: screen,
|
||||
top: 'center',
|
||||
left: 'center',
|
||||
data: null,
|
||||
border: 'line',
|
||||
align: 'center',
|
||||
tags: true,
|
||||
keys: true,
|
||||
height: 4,
|
||||
vi: true,
|
||||
mouse: true,
|
||||
style: {
|
||||
border: {
|
||||
fg: 'red'
|
||||
},
|
||||
header: {
|
||||
fg: 'blue',
|
||||
bold: true
|
||||
},
|
||||
cell: {
|
||||
fg: 'magenta',
|
||||
selected: {
|
||||
bg: 'blue'
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var data = [
|
||||
[ 'Animals', 'Foods', 'Times' ],
|
||||
[ 'Elephant', 'Apple', '1:00am' ],
|
||||
[ 'Bird', 'Orange', '2:15pm' ]
|
||||
];
|
||||
|
||||
data[1][0] = '{red-fg}' + data[1][0] + '{/red-fg}';
|
||||
|
||||
table.setData(data);
|
||||
|
||||
table.focus();
|
||||
|
||||
screen.key('q', function() {
|
||||
return process.exit(0);
|
||||
});
|
||||
|
||||
screen.render();
|
|
@ -3,7 +3,7 @@ var blessed = require('../')
|
|||
|
||||
screen = blessed.screen({
|
||||
dump: __dirname + '/logs/table.log',
|
||||
autoPadding: true
|
||||
autoPadding: false
|
||||
});
|
||||
|
||||
var table = blessed.table({
|
||||
|
@ -13,6 +13,7 @@ var table = blessed.table({
|
|||
data: null,
|
||||
border: 'line',
|
||||
align: 'center',
|
||||
tags: true,
|
||||
style: {
|
||||
border: {
|
||||
fg: 'red'
|
||||
|
@ -27,11 +28,15 @@ var table = blessed.table({
|
|||
}
|
||||
});
|
||||
|
||||
table.setData([
|
||||
var data = [
|
||||
[ 'Animals', 'Foods', 'Times' ],
|
||||
[ 'Elephant', 'Apple', '1:00am' ],
|
||||
[ 'Bird', 'Orange', '2:15pm' ]
|
||||
]);
|
||||
];
|
||||
|
||||
data[1][0] = '{red-fg}' + data[1][0] + '{/red-fg}';
|
||||
|
||||
table.setData(data);
|
||||
|
||||
screen.key('q', function() {
|
||||
return process.exit(0);
|
||||
|
|
Loading…
Reference in New Issue