mirror of
https://github.com/embarklabs/neo-blessed.git
synced 2025-02-02 14:14:41 +00:00
readme. example. fixes. response codes.
This commit is contained in:
parent
0b62eabfce
commit
f03d84bb7b
74
README.md
74
README.md
@ -3,7 +3,9 @@
|
||||
A curses-like library for node.js.
|
||||
|
||||
As of right now, it does not read all terminfo. It was designed for one
|
||||
terminal's terminfo: **xterm**.
|
||||
terminal's terminfo: **xterm**, but if you understand the differences between
|
||||
the three popular vt100-based terminals (xterm, screen, rxvt), you should be
|
||||
able to use it for any terminal.
|
||||
|
||||
I want this library to eventually become a high-level library for terminal
|
||||
widgets.
|
||||
@ -11,52 +13,74 @@ widgets.
|
||||
## Example Usage
|
||||
|
||||
``` js
|
||||
var Program = require('blessed')
|
||||
, program = new Program;
|
||||
var blessed = require('blessed')
|
||||
, program = blessed();
|
||||
|
||||
program.on('key', function(ch, key) {
|
||||
if (key.ctrl && key.name === 'c') {
|
||||
console.log('This would have been SIGINT!');
|
||||
program.on('keypress', function(ch, key) {
|
||||
if (key.name === 'q') {
|
||||
program.clear();
|
||||
program.disableMouse();
|
||||
program.showCursor();
|
||||
program.normalBuffer();
|
||||
process.exit(0);
|
||||
}
|
||||
});
|
||||
|
||||
program.setMouse({ normalMouse: true });
|
||||
|
||||
program.on('mouse', function(data) {
|
||||
console.log('Mouse event received:');
|
||||
console.log(data.button, data.x, data.y);
|
||||
if (data.action === 'mouseup') return;
|
||||
program.move(1, program.rows);
|
||||
program.eraseInLine('right');
|
||||
if (data.action === 'wheelup') {
|
||||
program.write('Mouse wheel up at: ' + data.x + ', ' + data.y);
|
||||
} else if (data.action === 'wheeldown') {
|
||||
program.write('Mouse wheel down at: ' + data.x + ', ' + data.y);
|
||||
} else if (data.action === 'mousedown' && data.button === 'left') {
|
||||
program.write('Left button down at: ' + data.x + ', ' + data.y);
|
||||
} else if (data.action === 'mousedown' && data.button === 'right') {
|
||||
program.write('Right button down at: ' + data.x + ', ' + data.y);
|
||||
} else {
|
||||
program.write('Mouse at: ' + data.x + ', ' + data.y);
|
||||
}
|
||||
program.move(data.x, data.y);
|
||||
program.bg('red');
|
||||
program.write(' ');
|
||||
program.bg('!red');
|
||||
});
|
||||
|
||||
program.on('focus', function() {
|
||||
program.move(1, program.rows);
|
||||
program.write('Gained focus.');
|
||||
});
|
||||
|
||||
program.on('blur', function() {
|
||||
program.move(1, program.rows);
|
||||
program.write('Lost focus.');
|
||||
});
|
||||
|
||||
program.alternateBuffer();
|
||||
|
||||
program.enableMouse();
|
||||
program.hideCursor();
|
||||
program.clear();
|
||||
|
||||
program.bg('white');
|
||||
program.move(1, 1);
|
||||
program.bg('black');
|
||||
program.write('Hello world', 'blue fg');
|
||||
program.setx(1);
|
||||
program.setx((program.cols / 2 | 0) - 4);
|
||||
program.down(5);
|
||||
program.write('Hi again!');
|
||||
program.bg('!white');
|
||||
program.bg('!black');
|
||||
program.feed();
|
||||
|
||||
program.getCursor(function(err, data) {
|
||||
if (!err) {
|
||||
console.log('Cursor is at: %s, %s.', data.x, data.y);
|
||||
program.write('Cursor is at: ' + data.x + ', ' + data.y + '.');
|
||||
program.feed();
|
||||
}
|
||||
|
||||
program.charset('SCLD');
|
||||
program.write('abcdefghijklmnopqrstuvwxyz0123456789');
|
||||
program.charset('US');
|
||||
program.setx(0);
|
||||
|
||||
setTimeout(function() {
|
||||
program.eraseInLine('right');
|
||||
setTimeout(function() {
|
||||
program.clear();
|
||||
program.normalBuffer();
|
||||
program.setMouse({ normalMouse: false });
|
||||
}, 2000);
|
||||
}, 2000);
|
||||
program.setx(1);
|
||||
});
|
||||
```
|
||||
|
||||
|
77
example/index.js
Normal file
77
example/index.js
Normal file
@ -0,0 +1,77 @@
|
||||
/**
|
||||
* Example Program for Blessed
|
||||
* Copyright (c) 2013, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/chjj/blessed
|
||||
*/
|
||||
|
||||
var blessed = require('blessed')
|
||||
, program = blessed();
|
||||
|
||||
process.title = 'blessed';
|
||||
|
||||
program.on('keypress', function(ch, key) {
|
||||
if (key.name === 'q') {
|
||||
program.clear();
|
||||
program.disableMouse();
|
||||
program.showCursor();
|
||||
program.normalBuffer();
|
||||
process.exit(0);
|
||||
}
|
||||
});
|
||||
|
||||
program.on('mouse', function(data) {
|
||||
if (data.action === 'mouseup') return;
|
||||
program.move(1, program.rows);
|
||||
program.eraseInLine('right');
|
||||
if (data.action === 'wheelup') {
|
||||
program.write('Mouse wheel up at: ' + data.x + ', ' + data.y);
|
||||
} else if (data.action === 'wheeldown') {
|
||||
program.write('Mouse wheel down at: ' + data.x + ', ' + data.y);
|
||||
} else if (data.action === 'mousedown' && data.button === 'left') {
|
||||
program.write('Left button down at: ' + data.x + ', ' + data.y);
|
||||
} else if (data.action === 'mousedown' && data.button === 'right') {
|
||||
program.write('Right button down at: ' + data.x + ', ' + data.y);
|
||||
} else {
|
||||
program.write('Mouse at: ' + data.x + ', ' + data.y);
|
||||
}
|
||||
program.move(data.x, data.y);
|
||||
program.bg('red');
|
||||
program.write(' ');
|
||||
program.bg('!red');
|
||||
});
|
||||
|
||||
program.on('focus', function() {
|
||||
program.move(1, program.rows);
|
||||
program.write('Gained focus.');
|
||||
});
|
||||
|
||||
program.on('blur', function() {
|
||||
program.move(1, program.rows);
|
||||
program.write('Lost focus.');
|
||||
});
|
||||
|
||||
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();
|
||||
|
||||
program.getCursor(function(err, data) {
|
||||
if (!err) {
|
||||
program.write('Cursor is at: ' + data.x + ', ' + data.y + '.');
|
||||
program.feed();
|
||||
}
|
||||
|
||||
program.charset('SCLD');
|
||||
program.write('abcdefghijklmnopqrstuvwxyz0123456789');
|
||||
program.charset('US');
|
||||
program.setx(1);
|
||||
});
|
220
lib/program.js
220
lib/program.js
@ -15,6 +15,10 @@ var EventEmitter = require('events').EventEmitter;
|
||||
*/
|
||||
|
||||
function Program(input, output) {
|
||||
if (!(this instanceof Program)) {
|
||||
return new Program(input, output);
|
||||
}
|
||||
|
||||
var self = this;
|
||||
|
||||
EventEmitter.call(this);
|
||||
@ -348,6 +352,214 @@ Program.prototype._bindMouse = function(s) {
|
||||
}
|
||||
};
|
||||
|
||||
Program.prototype.bindResponse = function() {
|
||||
this.on('data', this._bindResponse.bind(this));
|
||||
this.bindResponse = function() {};
|
||||
};
|
||||
|
||||
Program.prototype._bindResponse = function(s) {
|
||||
var self = this;
|
||||
|
||||
// FROM: node/lib/readline.js
|
||||
var ch
|
||||
, key = {
|
||||
name: undefined,
|
||||
ctrl: false,
|
||||
meta: false,
|
||||
shift: false
|
||||
}
|
||||
, parts;
|
||||
|
||||
if (Buffer.isBuffer(s)) {
|
||||
if (s[0] > 127 && s[1] === undefined) {
|
||||
s[0] -= 128;
|
||||
s = '\x1b' + s.toString('utf-8');
|
||||
} else {
|
||||
s = s.toString('utf-8');
|
||||
}
|
||||
}
|
||||
|
||||
// CSI Ps n Device Status Report (DSR).
|
||||
// Ps = 5 -> Status Report. Result (``OK'') is
|
||||
// CSI 0 n
|
||||
// CSI ? Ps n
|
||||
// Device Status Report (DSR, DEC-specific).
|
||||
// Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready).
|
||||
// or CSI ? 1 1 n (not ready).
|
||||
// Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked)
|
||||
// or CSI ? 2 1 n (locked).
|
||||
// Ps = 2 6 -> Report Keyboard status as
|
||||
// CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).
|
||||
// The last two parameters apply to VT400 & up, and denote key-
|
||||
// board ready and LK01 respectively.
|
||||
// Ps = 5 3 -> Report Locator status as
|
||||
// CSI ? 5 3 n Locator available, if compiled-in, or
|
||||
// CSI ? 5 0 n No Locator, if not.
|
||||
if (parts = /^\x1b\[(\?)?(\d+)(?:;(\d+);(\d+);(\d+))?n/.exec(s)) {
|
||||
if (!parts[1] && parts[2] === '0' && !parts[3]) {
|
||||
return this.emit('response', {
|
||||
deviceStatus: 'OK'
|
||||
});
|
||||
}
|
||||
|
||||
if (parts[1] && (parts[2] === '10' || parts[2] === '11') && !parts[3]) {
|
||||
return this.emit('response', {
|
||||
printerStatus: parts[2] === '10'
|
||||
? 'ready'
|
||||
: 'not ready'
|
||||
});
|
||||
}
|
||||
|
||||
if (parts[1] && (parts[2] === '20' || parts[2] === '21') && !parts[3]) {
|
||||
return this.emit('response', {
|
||||
UDKStatus: parts[2] === '20'
|
||||
? 'unlocked'
|
||||
: 'locked'
|
||||
});
|
||||
}
|
||||
|
||||
if (parts[1]
|
||||
&& parts[2] === '27'
|
||||
&& parts[3] === '1'
|
||||
&& parts[4] === '0'
|
||||
&& parts[5] === '0') {
|
||||
return this.emit('response', {
|
||||
keyboardStatus: 'OK'
|
||||
});
|
||||
}
|
||||
|
||||
if (parts[1] && (parts[2] === '53' || parts[2] === '50') && !parts[3]) {
|
||||
return this.emit('response', {
|
||||
locator: parts[2] === '53'
|
||||
? 'available'
|
||||
: 'unavailable'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// CSI Ps n Device Status Report (DSR).
|
||||
// Ps = 5 -> Status Report. Result (``OK'') is
|
||||
// CSI 0 n
|
||||
// Ps = 6 -> Report Cursor Position (CPR) [row;column].
|
||||
// Result is
|
||||
// CSI r ; c R
|
||||
// CSI ? Ps n
|
||||
// Device Status Report (DSR, DEC-specific).
|
||||
// Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI
|
||||
// ? r ; c R (assumes page is zero).
|
||||
// Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready).
|
||||
// or CSI ? 1 1 n (not ready).
|
||||
// Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked)
|
||||
// or CSI ? 2 1 n (locked).
|
||||
// Ps = 2 6 -> Report Keyboard status as
|
||||
// CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).
|
||||
// The last two parameters apply to VT400 & up, and denote key-
|
||||
// board ready and LK01 respectively.
|
||||
// Ps = 5 3 -> Report Locator status as
|
||||
// CSI ? 5 3 n Locator available, if compiled-in, or
|
||||
// CSI ? 5 0 n No Locator, if not.
|
||||
|
||||
// Ps = 6 -> Report Cursor Position (CPR) [row;column].
|
||||
// Result is
|
||||
// CSI r ; c R
|
||||
// Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI
|
||||
// ? r ; c R (assumes page is zero).
|
||||
if (parts = /^\x1b\[(\?)?(\d+);(\d+)R/.exec(s)) {
|
||||
return this.emit('response', {
|
||||
cursor: {
|
||||
x: +parts[3],
|
||||
y: +parts[2],
|
||||
page: !parts[1] ? undefined : 0
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// CSI Ps ; Ps ; Ps t
|
||||
// Window manipulation (from dtterm, as well as extensions).
|
||||
// These controls may be disabled using the allowWindowOps
|
||||
// resource. Valid values for the first (and any additional
|
||||
// parameters) are:
|
||||
// Ps = 1 1 -> Report xterm window state. If the xterm window
|
||||
// is open (non-iconified), it returns CSI 1 t . If the xterm
|
||||
// window is iconified, it returns CSI 2 t .
|
||||
// Ps = 1 3 -> Report xterm window position. Result is CSI 3
|
||||
// ; x ; y t
|
||||
// Ps = 1 4 -> Report xterm window in pixels. Result is CSI
|
||||
// 4 ; height ; width t
|
||||
// Ps = 1 8 -> Report the size of the text area in characters.
|
||||
// Result is CSI 8 ; height ; width t
|
||||
// Ps = 1 9 -> Report the size of the screen in characters.
|
||||
// Result is CSI 9 ; height ; width t
|
||||
if (parts = /^\x1b\[(\d+)(?:;(\d+);(\d+))?t/.exec(s)) {
|
||||
if ((parts[1] === '1' || parts[1] === '2') && !parts[2]) {
|
||||
return this.emit('response', {
|
||||
windowState: parts[1] === '1'
|
||||
? 'non-iconified'
|
||||
: 'iconified'
|
||||
});
|
||||
}
|
||||
|
||||
if (parts[1] === '3' && parts[2]) {
|
||||
return this.emit('response', {
|
||||
windowPosition: {
|
||||
x: +parts[2],
|
||||
y: +parts[3]
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (parts[1] === '4' && parts[2]) {
|
||||
return this.emit('response', {
|
||||
windowSizePixels: {
|
||||
height: +parts[2],
|
||||
width: +parts[3]
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (parts[1] === '8' && parts[2]) {
|
||||
return this.emit('response', {
|
||||
textAreaSizeCharacters: {
|
||||
height: +parts[2],
|
||||
width: +parts[3]
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (parts[1] === '9' && parts[2]) {
|
||||
return this.emit('response', {
|
||||
screenSizeCharacters: {
|
||||
height: +parts[2],
|
||||
width: +parts[3]
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// CSI Ps ; Ps ; Ps t
|
||||
// Window manipulation (from dtterm, as well as extensions).
|
||||
// These controls may be disabled using the allowWindowOps
|
||||
// resource. Valid values for the first (and any additional
|
||||
// parameters) are:
|
||||
// Ps = 2 0 -> Report xterm window's icon label. Result is
|
||||
// OSC L label ST
|
||||
// Ps = 2 1 -> Report xterm window's title. Result is OSC l
|
||||
// label ST
|
||||
if (parts = /^\x1b\](l|L)([^\x07\x1b]*)(?:\x07|\\\x1b)/.exec(s)) {
|
||||
if (parts[1] === 'L') {
|
||||
return this.emit('response', {
|
||||
windowIconLabel: parts[2]
|
||||
});
|
||||
}
|
||||
|
||||
if (parts[1] === 'l') {
|
||||
return this.emit('response', {
|
||||
windowTitle: parts[2]
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Program.prototype.receive = function(text, callback) {
|
||||
var listeners = this.listeners('keypress')
|
||||
, bak = listeners.slice();
|
||||
@ -386,8 +598,8 @@ Program.prototype.echo = function(text, attr) {
|
||||
};
|
||||
|
||||
Program.prototype.setx = function(x) {
|
||||
// return this.cursorCharAbsolute(x);
|
||||
return this.charPosAbsolute(x);
|
||||
return this.cursorCharAbsolute(x);
|
||||
// return this.charPosAbsolute(x);
|
||||
};
|
||||
|
||||
Program.prototype.sety = function(y) {
|
||||
@ -2058,4 +2270,6 @@ Program.prototype.deleteColumns = function() {
|
||||
* Expose
|
||||
*/
|
||||
|
||||
module.exports = Program;
|
||||
exports = Program;
|
||||
exports.Program = Program;
|
||||
module.exports = exports;
|
||||
|
Loading…
x
Reference in New Issue
Block a user