docs. key() fix. wrapContent() fix. box.{insert,delete}Line fix.
This commit is contained in:
parent
bc99d7fc37
commit
12e7eab68d
168
README.md
168
README.md
|
@ -2,113 +2,68 @@
|
||||||
|
|
||||||
A curses-like library for node.js.
|
A curses-like library for node.js.
|
||||||
|
|
||||||
Blessed was originally written to only support the xterm terminfo, but can
|
## Example
|
||||||
now parse and compile any terminfo to be completely portable accross all
|
|
||||||
terminals. See the `tput` example below.
|
|
||||||
|
|
||||||
Blessed also includes an extremely high-level widget library.
|
This will render a box with ascii borders containing the text `'Hello world!'`,
|
||||||
|
|
||||||
|
|
||||||
## Example Usage
|
|
||||||
|
|
||||||
This will actually parse the xterm terminfo and compile every
|
|
||||||
string capability to a javascript function:
|
|
||||||
|
|
||||||
``` js
|
|
||||||
var Tput = require('blessed').Tput
|
|
||||||
, tput = Tput('xterm');
|
|
||||||
|
|
||||||
console.log(tput.setaf(4) + 'hello' + tput.sgr0());
|
|
||||||
```
|
|
||||||
|
|
||||||
To play around with it on the command line, it works just like tput:
|
|
||||||
|
|
||||||
``` bash
|
|
||||||
$ tput.js setaf 2
|
|
||||||
$ tput.js sgr0
|
|
||||||
$ echo "$(tput.js setaf 2)hello world$(tput.js sgr0)"
|
|
||||||
```
|
|
||||||
|
|
||||||
The main functionality is exposed in the main `blessed` module:
|
|
||||||
|
|
||||||
``` js
|
|
||||||
var blessed = require('blessed')
|
|
||||||
, program = blessed();
|
|
||||||
|
|
||||||
program.key('q', function(ch, key) {
|
|
||||||
program.clear();
|
|
||||||
program.disableMouse();
|
|
||||||
program.showCursor();
|
|
||||||
program.normalBuffer();
|
|
||||||
process.exit(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
program.on('mouse', function(data) {
|
|
||||||
if (data.action === 'mousemove') {
|
|
||||||
program.move(data.x, data.y);
|
|
||||||
program.bg('red');
|
|
||||||
program.write('x');
|
|
||||||
program.bg('!red');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
program.alternateBuffer();
|
|
||||||
program.enableMouse();
|
|
||||||
program.hideCursor();
|
|
||||||
program.clear();
|
|
||||||
|
|
||||||
program.move(1, 1);
|
|
||||||
program.bg('black');
|
|
||||||
program.write('Hello world', 'blue fg');
|
|
||||||
program.setx((program.cols / 2 | 0) - 4);
|
|
||||||
program.down(5);
|
|
||||||
program.write('Hi again!');
|
|
||||||
program.bg('!black');
|
|
||||||
program.feed();
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## High-level Documentation
|
|
||||||
|
|
||||||
### Example
|
|
||||||
|
|
||||||
This will render a box with ascii borders containing the text 'Hello world!',
|
|
||||||
perfectly centered horizontally and vertically.
|
perfectly centered horizontally and vertically.
|
||||||
|
|
||||||
``` js
|
``` js
|
||||||
var blessed = require('blessed')
|
var blessed = require('blessed');
|
||||||
, screen = new blessed.Screen;
|
|
||||||
|
|
||||||
var box = new blessed.Box({
|
// Create a screen object.
|
||||||
|
var screen = blessed.screen();
|
||||||
|
|
||||||
|
// Create a box perfectly centered horizontally and vertically.
|
||||||
|
var box = blessed.box({
|
||||||
top: 'center',
|
top: 'center',
|
||||||
left: 'center',
|
left: 'center',
|
||||||
width: '50%',
|
width: '50%',
|
||||||
height: '50%',
|
height: '50%',
|
||||||
border: {
|
border: {
|
||||||
type: 'ascii',
|
type: 'ascii',
|
||||||
fg: 'white'
|
fg: '#ffffff'
|
||||||
},
|
},
|
||||||
fg: 'white',
|
fg: 'white',
|
||||||
bg: 'magenta',
|
bg: 'magenta',
|
||||||
content: 'Hello world!',
|
content: 'Hello {bold}world{/bold}!',
|
||||||
tags: true
|
tags: true,
|
||||||
|
hoverEffects: {
|
||||||
|
bg: 'green'
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Append our box to the screen.
|
||||||
screen.append(box);
|
screen.append(box);
|
||||||
|
|
||||||
|
// If our box is clicked, change the content.
|
||||||
box.on('click', function(data) {
|
box.on('click', function(data) {
|
||||||
box.setContent('{center}Some different {red-fg}content{/red-fg}.{/center}');
|
box.setContent('{center}Some different {red-fg}content{/red-fg}.{/center}');
|
||||||
screen.render();
|
screen.render();
|
||||||
});
|
});
|
||||||
|
|
||||||
screen.key('escape', function(ch, key) {
|
// If box is focused, handle `enter` and give us some more content.
|
||||||
|
box.key('enter', function() {
|
||||||
|
box.setContent('{right}Even different {black-fg}content{/black-fg}.{/right}\n');
|
||||||
|
box.setLine(1, 'bar');
|
||||||
|
box.insertLine(1, 'foo');
|
||||||
|
screen.render();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Quit on Escape, q, or Control-C.
|
||||||
|
screen.key(['escape', 'q', 'C-c'], function(ch, key) {
|
||||||
return process.exit(0);
|
return process.exit(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Focus our element.
|
||||||
|
box.focus();
|
||||||
|
|
||||||
|
// Render the screen.
|
||||||
screen.render();
|
screen.render();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## High-level Documentation
|
||||||
|
|
||||||
### Widgets
|
### Widgets
|
||||||
|
|
||||||
Blessed comes with a number of high-level widgets so you can avoid all the
|
Blessed comes with a number of high-level widgets so you can avoid all the
|
||||||
|
@ -770,6 +725,65 @@ Outputting:
|
||||||
- For a less interactive position testing, see `test/widget-pos.js`.
|
- For a less interactive position testing, see `test/widget-pos.js`.
|
||||||
|
|
||||||
|
|
||||||
|
## Lower-Level Usage
|
||||||
|
|
||||||
|
This will actually parse the xterm terminfo and compile every
|
||||||
|
string capability to a javascript function:
|
||||||
|
|
||||||
|
``` js
|
||||||
|
var Tput = require('blessed').Tput
|
||||||
|
, tput = Tput('xterm');
|
||||||
|
|
||||||
|
console.log(tput.setaf(4) + 'hello' + tput.sgr0());
|
||||||
|
```
|
||||||
|
|
||||||
|
To play around with it on the command line, it works just like tput:
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
$ tput.js setaf 2
|
||||||
|
$ tput.js sgr0
|
||||||
|
$ echo "$(tput.js setaf 2)hello world$(tput.js sgr0)"
|
||||||
|
```
|
||||||
|
|
||||||
|
The main functionality is exposed in the main `blessed` module:
|
||||||
|
|
||||||
|
``` js
|
||||||
|
var blessed = require('blessed')
|
||||||
|
, program = blessed();
|
||||||
|
|
||||||
|
program.key('q', function(ch, key) {
|
||||||
|
program.clear();
|
||||||
|
program.disableMouse();
|
||||||
|
program.showCursor();
|
||||||
|
program.normalBuffer();
|
||||||
|
process.exit(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
program.on('mouse', function(data) {
|
||||||
|
if (data.action === 'mousemove') {
|
||||||
|
program.move(data.x, data.y);
|
||||||
|
program.bg('red');
|
||||||
|
program.write('x');
|
||||||
|
program.bg('!red');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
program.alternateBuffer();
|
||||||
|
program.enableMouse();
|
||||||
|
program.hideCursor();
|
||||||
|
program.clear();
|
||||||
|
|
||||||
|
program.move(1, 1);
|
||||||
|
program.bg('black');
|
||||||
|
program.write('Hello world', 'blue fg');
|
||||||
|
program.setx((program.cols / 2 | 0) - 4);
|
||||||
|
program.down(5);
|
||||||
|
program.write('Hi again!');
|
||||||
|
program.bg('!black');
|
||||||
|
program.feed();
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Copyright (c) 2013, Christopher Jeffrey. (MIT License)
|
Copyright (c) 2013, Christopher Jeffrey. (MIT License)
|
||||||
|
|
|
@ -1535,16 +1535,16 @@ Element.prototype.__defineGetter__('detached', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
Element.prototype.key = function() {
|
Element.prototype.key = function() {
|
||||||
return Screen.prototype.key.apply(this, arguments);
|
return this.screen.program.key.apply(this, arguments);
|
||||||
};
|
};
|
||||||
|
|
||||||
Element.prototype.onceKey = function() {
|
Element.prototype.onceKey = function() {
|
||||||
return Screen.prototype.onceKey.apply(this, arguments);
|
return this.screen.program.onceKey.apply(this, arguments);
|
||||||
};
|
};
|
||||||
|
|
||||||
Element.prototype.unkey =
|
Element.prototype.unkey =
|
||||||
Element.prototype.removeKey = function() {
|
Element.prototype.removeKey = function() {
|
||||||
return Screen.prototype.unkey.apply(this, arguments);
|
return this.screen.program.unkey.apply(this, arguments);
|
||||||
};
|
};
|
||||||
|
|
||||||
Element.prototype.clearPos = function() {
|
Element.prototype.clearPos = function() {
|
||||||
|
@ -2168,75 +2168,99 @@ outer:
|
||||||
// Maybe _lastPos could be updated on .left, .right, etc setters?
|
// Maybe _lastPos could be updated on .left, .right, etc setters?
|
||||||
|
|
||||||
Box.prototype.insertLine = function(i, line) {
|
Box.prototype.insertLine = function(i, line) {
|
||||||
|
var pos = this._lastPos || 0;
|
||||||
|
|
||||||
if (typeof line === 'string') line = [line];
|
if (typeof line === 'string') line = [line];
|
||||||
|
|
||||||
if (this.screen.cleanSides(this)) {
|
if (i > this._clines.length) {
|
||||||
|
for (var j = this._clines.length; j < i; j++) this._clines.push('');
|
||||||
|
}
|
||||||
|
|
||||||
i = Math.max(i, 0);
|
i = Math.max(i, 0);
|
||||||
i = Math.min(i, this._lastPos.yl - this._lastPos.yi - (this.border ? 2 : 0) - this.padding * 2);
|
//i = Math.min(i, this._clines.length);
|
||||||
|
|
||||||
|
var height = pos.yl - pos.yi - (this.border ? 2 : 0) - this.padding * 2
|
||||||
|
, base = this.childBase || 0
|
||||||
|
, visible = i >= base && i - base < height;
|
||||||
|
|
||||||
|
if (pos && visible && this.screen.cleanSides(this)) {
|
||||||
this.screen.insertLine(line.length,
|
this.screen.insertLine(line.length,
|
||||||
this._lastPos.yi + (this.border ? 1 : 0) + this.padding + i,
|
pos.yi + (this.border ? 1 : 0) + this.padding + i - base,
|
||||||
this._lastPos.yi,
|
pos.yi,
|
||||||
this._lastPos.yl - (this.border ? 1 : 0) - this.padding - 1);
|
pos.yl - (this.border ? 1 : 0) - this.padding - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
line.forEach(function(line, j) {
|
line.forEach(function(line, j) {
|
||||||
this._clines.splice((this.childBase || 0) + (this.border ? 1 : 0) + this.padding + i + j, 0, line);
|
this._clines.splice(i + j, 0, line);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
this.setContent(this._clines.join('\n'), true);
|
this.setContent(this._clines.join('\n'), true);
|
||||||
};
|
};
|
||||||
|
|
||||||
Box.prototype.deleteLine = function(i, n) {
|
Box.prototype.deleteLine = function(i, n) {
|
||||||
|
var pos = this._lastPos || 0;
|
||||||
|
|
||||||
var reset = true
|
var reset = true
|
||||||
, n = n || 1;
|
, n = n || 1;
|
||||||
|
|
||||||
if (this.screen.cleanSides(this)) {
|
|
||||||
i = Math.max(i, 0);
|
i = Math.max(i, 0);
|
||||||
i = Math.min(i, this._lastPos.yl - this._lastPos.yi - (this.border ? 2 : 0) - this.padding * 2);
|
i = Math.min(i, this._clines.length - 1);
|
||||||
|
|
||||||
|
var height = pos.yl - pos.yi - (this.border ? 2 : 0) - this.padding * 2
|
||||||
|
, base = this.childBase || 0
|
||||||
|
, visible = i >= base && i - base < height;
|
||||||
|
|
||||||
|
if (pos && visible && this.screen.cleanSides(this)) {
|
||||||
this.screen.deleteLine(n,
|
this.screen.deleteLine(n,
|
||||||
this._lastPos.yi + (this.border ? 1 : 0) + this.padding + i,
|
pos.yi + (this.border ? 1 : 0) + this.padding + i - base,
|
||||||
this._lastPos.yi,
|
pos.yi,
|
||||||
this._lastPos.yl - (this.border ? 1 : 0) - this.padding - 1);
|
pos.yl - (this.border ? 1 : 0) - this.padding - 1);
|
||||||
reset = false;
|
reset = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (n--) {
|
while (n--) {
|
||||||
this._clines.splice((this.childBase || 0) + (this.border ? 1 : 0) + this.padding + i, 1);
|
this._clines.splice(i, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setContent(this._clines.join('\n'), reset);
|
this.setContent(this._clines.join('\n'), reset);
|
||||||
};
|
};
|
||||||
|
|
||||||
Box.prototype.insertTop = function(line) {
|
Box.prototype.insertTop = function(line) {
|
||||||
return this.insertLine(0, line);
|
return this.insertLine((this.childBase || 0) + 0, line);
|
||||||
};
|
};
|
||||||
|
|
||||||
Box.prototype.insertBottom = function(line) {
|
Box.prototype.insertBottom = function(line) {
|
||||||
return this.insertLine(this.height - (this.border ? 2 : 0) - this.padding * 2, line);
|
return this.insertLine((this.childBase || 0)
|
||||||
|
+ this.height - (this.border ? 2 : 0) - this.padding * 2, line);
|
||||||
};
|
};
|
||||||
|
|
||||||
Box.prototype.deleteTop = function() {
|
Box.prototype.deleteTop = function() {
|
||||||
return this.deleteLine(0);
|
return this.deleteLine((this.childBase || 0) + 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
Box.prototype.deleteBottom = function() {
|
Box.prototype.deleteBottom = function() {
|
||||||
return this.deleteLine(this.height - (this.border ? 2 : 0) - this.padding * 2);
|
return this.deleteLine((this.childBase || 0)
|
||||||
|
+ this.height - (this.border ? 2 : 0) - this.padding * 2);
|
||||||
};
|
};
|
||||||
|
|
||||||
Box.prototype.setLine = function(i, line) {
|
Box.prototype.setLine = function(i, line) {
|
||||||
|
if (i > this._clines.length) {
|
||||||
|
for (var j = this._clines.length; j < i; j++) this._clines.push('');
|
||||||
|
}
|
||||||
i = Math.max(i, 0);
|
i = Math.max(i, 0);
|
||||||
i = Math.min(i, this._lastPos.yl - this._lastPos.yi - (this.border ? 2 : 0) - this.padding * 2);
|
//i = Math.min(i, this._clines.length);
|
||||||
this._clines[(this.childBase || 0) + (this.border ? 1 : 0) + this.padding + i] = line;
|
this._clines[(this.childBase || 0) + i] = line;
|
||||||
return this.setContent(this._clines.join('\n'), true);
|
return this.setContent(this._clines.join('\n'), true);
|
||||||
};
|
};
|
||||||
|
|
||||||
Box.prototype.getLine = function(i) {
|
Box.prototype.getLine = function(i) {
|
||||||
i = Math.max(i, 0);
|
i = Math.max(i, 0);
|
||||||
i = Math.min(i, this._lastPos.yl - this._lastPos.yi - (this.border ? 2 : 0) - this.padding * 2);
|
i = Math.min(i, this._clines.length);
|
||||||
return this._clines[(this.childBase || 0) + (this.border ? 1 : 0) + this.padding + i];
|
return this._clines[(this.childBase || 0) + i];
|
||||||
};
|
};
|
||||||
|
|
||||||
Box.prototype.clearLine = function(i) {
|
Box.prototype.clearLine = function(i) {
|
||||||
|
i = Math.min(i, this._clines.length - 1);
|
||||||
return this.setLine(i, '');
|
return this.setLine(i, '');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4095,7 +4119,8 @@ function wrapContent(content, width, tags, state) {
|
||||||
while (line[i] && line[i++] !== 'm');
|
while (line[i] && line[i++] !== 'm');
|
||||||
}
|
}
|
||||||
if (!line[i]) break;
|
if (!line[i]) break;
|
||||||
if (++total === width) {
|
//if (++total === width) {
|
||||||
|
if (++total > width) {
|
||||||
// Try to find a space to break on:
|
// Try to find a space to break on:
|
||||||
if (line[i] !== ' ') {
|
if (line[i] !== ' ') {
|
||||||
var j = i;
|
var j = i;
|
||||||
|
@ -4122,6 +4147,10 @@ function wrapContent(content, width, tags, state) {
|
||||||
line = line.substring(i - 1);
|
line = line.substring(i - 1);
|
||||||
out.push(sp(part, width, align));
|
out.push(sp(part, width, align));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure we didn't wrap the line to the very end, otherwise
|
||||||
|
// we get a pointless empty line after a newline.
|
||||||
|
if (line === '') return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If only an escape code got cut off, at it to `part`.
|
// If only an escape code got cut off, at it to `part`.
|
||||||
|
|
Loading…
Reference in New Issue