Compare commits

..

No commits in common. "master" and "v0.1.15" have entirely different histories.

92 changed files with 650 additions and 1469 deletions

15
.jscsrc
View File

@ -1,15 +0,0 @@
{
"preset": "airbnb",
"esnext": false,
"requireTrailingComma": null,
"requireCommaBeforeLineBreak": null,
"requireCamelCaseOrUpperCaseIdentifiers": null,
"requirePaddingNewLinesBeforeLineComments": null,
"requirePaddingNewLinesAfterBlocks": null,
"safeContextKeyword": "self",
"maximumLineLength": 110,
"maxErrors": 1000,
"requireSpaceAfterLineComment": true
}

View File

@ -1,41 +0,0 @@
{
"bitwise": false,
"curly": false,
"eqeqeq": true,
"freeze": true,
"latedef": "nofunc",
"maxparams": 7,
"noarg": true,
"shadow": "inner",
"undef": true,
"unused": true,
"boss": true,
"expr": true,
"eqnull": true,
"evil": true,
"loopfunc": true,
"proto": true,
"supernew": true,
"-W018": true,
"-W064": true,
"-W086": true,
"+W032": true,
"browser": false,
"browserify": false,
"node": true,
"nonstandard": true,
"typed": true,
"worker": false,
"camelcase": false,
"indent": 2,
"maxlen": 110,
"newcap": true,
"quotmark": "single",
"laxbreak": true,
"laxcomma": true
}

View File

@ -2,5 +2,3 @@
test/
img/
node_modules/
.jshintrc
.jscsrc

151
README.md
View File

@ -30,6 +30,16 @@ Blessed has been used to implement other popular libraries and programs.
Examples include: the [slap text editor][slap] and [blessed-contrib][contrib].
The blessed API itself has gone on to inspire [termui][termui] for Go.
## Important Blessed Changes (>0.0.51)
- The absolute `.left` _property_ (not option) has been renamed to `.aleft`.
The `.rleft` property has been renamed to `.left`. This should not have much
effect on most applications. This includes all other coordinate properties.
- `autoPadding` is now enabled by default. To revert to the original behavior,
pass `autoPadding: false` into the screen object. That being said, it would
be wiser to adjust your code to use `autoPadding`. Non-`autoPadding` is now
considered deprecated.
## Install
``` bash
@ -42,14 +52,17 @@ This will render a box with line borders containing the text `'Hello world!'`,
perfectly centered horizontally and vertically.
__NOTE__: It is recommend you use either `smartCSR` or `fastCSR` as a
`blessed.screen` option. This will enable CSR when scrolling text in elements
or when manipulating lines.
`blessed.screen` option. `autoPadding` is also recommended; it will
automatically offset box content within borders instead of on top of them when
coords are `0`. Non-`autoPadding` _may_ be deprecated in the future. See the
API documentation for further explanation of these options.
``` js
var blessed = require('blessed');
// Create a screen object.
var screen = blessed.screen({
autoPadding: true,
smartCSR: true
});
@ -188,8 +201,6 @@ screen.render();
- [Poisitioning](#positioning)
- [Rendering](#rendering)
- [Artificial Cursors](#artificial-cursors)
- [Multiple Screens](#multiple-screens)
- [Server Side Usage](#server-side-usage)
### Notes
@ -298,8 +309,8 @@ The screen on which every other node renders.
debug console which will display when pressing F12. It will display all log
and debug messages.
- __ignoreLocked__ - Array of keys in their full format (e.g. `C-c`) to ignore
when keys are locked or grabbed. Useful for creating a key that will _always_
exit no matter whether the keys are locked.
when keys are locked. Useful for creating a key that will _always_ exit no
matter whether the keys are locked.
- __dockBorders__ - Automatically "dock" borders with other elements instead of
overlapping, depending on position (__experimental__). For example:
These border-overlapped elements:
@ -328,15 +339,6 @@ The screen on which every other node renders.
- __sendFocus__ - Send focus events after mouse is enabled.
- __warnings__ - Display warnings (such as the output not being a TTY, similar
to ncurses).
- __forceUnicode__ - Force blessed to use unicode even if it is not detected
via terminfo, env variables, or windows code page. If value is `true` unicode
is forced. If value is `false` non-unicode is forced (default: `null`).
- __input/output__ - Input and output streams. `process.stdin`/`process.stdout`
by default, however, it could be a `net.Socket` if you want to make a program
that runs over telnet or something of that nature.
- __terminal__ - `TERM` name used for terminfo parsing. The `$TERM` env variable is
used by default.
- __title__ - Set the terminal window title if possible.
##### Properties:
@ -360,8 +362,6 @@ The screen on which every other node renders.
- __grabKeys__ - Whether the focused element grabs all keypresses.
- __lockKeys__ - Prevent keypresses from being received by any element.
- __hover__ - The currently hovered element. Only set if mouse events are bound.
- __terminal__ - Set or get terminal name. `Set` calls `screen.setTerminal()`
internally.
- __title__ - Set or get window title.
##### Events:
@ -390,7 +390,6 @@ The screen on which every other node renders.
`debug` option was set.
- __alloc()__ - Allocate a new pending screen buffer and a new output screen
buffer.
- __realloc()__ - Reallocate the screen buffers and clear the screen.
- __draw(start, end)__ - Draw the screen based on the contents of the screen
buffer.
- __render()__ - Render all child elements, writing all data to the screen
@ -444,10 +443,9 @@ The screen on which every other node renders.
within the region. Returns a string containing only characters and SGR codes.
Can be displayed by simply echoing it in a terminal.
- __destroy()__ - Destroy the screen object and remove it from the global list.
Also remove all global events relevant to the screen object. If all screen
objects are destroyed, the node process is essentially reset to its initial
state.
- __setTerminal(term)__ - Reset the terminal to `term`. Reloads terminfo.
Only useful if using multiple screens.
- __program.destroy()__ - Destroy the program object and remove it from the
global list. Only useful if using multiple programs.
#### Element (from Node)
@ -1382,7 +1380,7 @@ manager. Requires term.js and pty.js to be installed. See
- __shell__ - Name of shell. `$SHELL` by default.
- __args__ - Args for shell.
- __cursor__ - Can be `line`, `underline`, and `block`.
- __terminal__ - Terminal name (Default: `xterm`).
- __term__ - Terminal name (Default: `xterm`).
- __env__ - Object for process env.
- Other options similar to term.js'.
@ -2127,111 +2125,6 @@ var screen = blessed.screen({
```
#### Multiple Screens
Blessed supports the ability to create multiple screens. This may not seem
useful at first, but if you're writing a program that serves terminal
interfaces over http, telnet, or any other protocol, this can be very useful.
##### Server Side Usage
A simple telnet server might look like this (see examples/blessed-telnet.js for
a full example):
``` js
var blessed = require('blessed');
var telnet = require('telnet2');
telnet({ tty: true }, function(client) {
client.on('term', function(terminal) {
screen.terminal = terminal;
screen.render();
});
client.on('size', function(width, height) {
client.columns = width;
client.rows = height;
client.emit('resize');
});
var screen = blessed.screen({
smartCSR: true,
input: client,
output: client,
terminal: 'xterm-256color',
fullUnicode: true
});
client.on('close', function() {
if (!screen.destroyed) {
screen.destroy();
}
});
screen.key(['C-c', 'q'], function(ch, key) {
screen.destroy();
});
screen.on('destroy', function() {
if (client.writable) {
client.destroy();
}
});
screen.data.main = blessed.box({
parent: screen,
left: 'center',
top: 'center',
width: '80%',
height: '90%',
border: 'line',
content: 'Welcome to my server. Here is your own private session.'
});
screen.render();
}).listen(2300);
```
Once you've written something similar and started it, you can simply telnet
into your blessed app:
``` bash
$ telnet localhost 2300
```
Creating a netcat server would also work as long as you disable line buffering
and terminal echo on the commandline via `stty`:
`$ stty -icanon -echo; ncat localhost 2300; stty icanon echo`
Or by using netcat's `-t` option: `$ ncat -t localhost 2300`
Creating a streaming http 1.1 server than runs in the terminal is possible by
curling it with special arguments: `$ curl -sSNT. localhost:8080`.
There are currently no examples of netcat/nc/ncat or http->curl servers yet.
---
The `blessed.screen` constructor can accept `input`, `output`, and `term`
arguments to aid with this. The multiple screens will be managed internally by
blessed. The programmer just has to keep track of the references, however, to
avoid ambiguity, it's possible to explicitly dictate which screen a node is
part of by using the `screen` option when creating an element.
The `screen.destroy()` method is also crucial: this will clean up all event
listeners the screen has bound and make sure it stops listening on the event
loop. Make absolutely certain to remember to clean up your screens once you're
done with them.
A tricky part is making sure to include the ability for the client to send the
TERM which is reset on the serverside, and the terminal size, which is should
also be reset on the serverside. Both of these capabilities are demonstrated
above.
For a working example of a blessed telnet server, see
`examples/blessed-telnet.js`.
### Notes
@ -2244,7 +2137,7 @@ Windows users will need to explicitly set `term` when creating a screen like so
This is now handled automatically):
``` js
var screen = blessed.screen({ terminal: 'windows-ansi' });
var screen = blessed.screen({ term: 'windows-ansi' });
```

View File

@ -7,10 +7,9 @@ var blessed = require('../')
tput = blessed.tput({
terminal: process.env.TERM,
termcap: !!process.env.USE_TERMCAP,
extended: true
});
if (tput[cmd]) {
process.stdout.write(tput[cmd].apply(tput, argv));
process.stdout.write(tput[cmd].apply(tput, argv) + '\n');
}

View File

@ -1,7 +0,0 @@
all:
@cd .. && browserify -e index.js -o browser/blessed.js
clean:
@rm -f blessed.js
.PHONY: clean all

View File

@ -1,105 +0,0 @@
/**
* transform.js - browserify workaround for blessed
* Copyright (c) 2013-2015, Christopher Jeffrey and contributors (MIT License).
* https://github.com/chjj/blessed
*/
var Transform = require('stream').Transform
, path = require('path')
, fs = require('fs');
/**
* Transformer
*/
function transformer(code) {
var stream = new Transform;
stream._transform = function(chunk, encoding, callback) {
return callback(null, chunk);
};
stream._flush = function(callback) {
if (code) {
stream.push(code);
}
return callback();
};
return stream;
}
/**
* Explicitly require all widgets in widget.js
*/
var widgets = fs.readdirSync(__dirname + '/../lib/widgets');
var requireWidgets = widgets.reduce(function(out, name) {
name = path.basename(name, '.js');
out += '\nrequire(\'./widgets/' + name + '\');';
return out;
}, '');
/**
* Do not make filesystem calls in tput.js for
* terminfo or termcap, just use xterm terminfo/cap.
*/
var infoPath = path.resolve(__dirname, '..', 'usr', 'xterm-256color')
, capPath = path.resolve(__dirname, '..', 'usr', 'xterm.termcap');
var infoPathFake = path.resolve(
path.sep, 'usr', 'share', 'terminfo',
path.basename(infoPath)[0],
path.basename(infoPath)
);
function readMethods() {
Tput._infoBuffer = new Buffer(TERMINFO, 'base64');
Tput.prototype.readTerminfo = function() {
this.terminal = TERMINFO_NAME;
return this.parseTerminfo(Tput._infoBuffer, TERMINFO_PATH);
};
Tput.cpaths = [];
Tput.termcap = TERMCAP;
Tput.prototype._readTermcap = Tput.prototype.readTermcap;
Tput.prototype.readTermcap = function() {
this.terminal = TERMCAP_NAME;
return this._readTermcap(this.terminal);
};
Tput.prototype.detectUnicode = function() {
return true;
};
}
readMethods = readMethods.toString().slice(24, -2)
.replace(/^ /gm, '')
.replace('TERMINFO', JSON.stringify(fs.readFileSync(infoPath, 'base64')))
.replace('TERMINFO_NAME', JSON.stringify(path.basename(infoPath)))
.replace('TERMINFO_PATH', JSON.stringify(infoPathFake))
.replace('TERMCAP', JSON.stringify(fs.readFileSync(capPath, 'utf8')))
.replace('TERMCAP_NAME', JSON.stringify(path.basename(capPath, '.termcap')));
/**
* Helpers
*/
function end(file, offset) {
return file.split(path.sep).slice(-offset).join('/');
}
/**
* Expose
*/
module.exports = function(file) {
if (end(file, 2) === 'lib/widget.js') {
return transformer(requireWidgets);
}
if (end(file, 2) === 'lib/tput.js') {
return transformer(readMethods);
}
return transformer();
};

View File

@ -1,99 +0,0 @@
#!/usr/bin/env node
/**
* blessed-telnet.js
* https://github.com/chjj/blessed
* Copyright (c) 2013-2015, Christopher Jeffrey (MIT License)
* A blessed telnet server.
* See: https://github.com/TooTallNate/node-telnet
*/
process.title = 'blessed-telnet';
var fs = require('fs');
var path = require('path');
var blessed = require('blessed');
var telnet = require('telnet2');
var server = telnet({ tty: true }, function(client) {
client.on('debug', function(msg) {
console.error(msg);
});
client.on('term', function(terminal) {
screen.terminal = terminal;
screen.render();
});
client.on('size', function(width, height) {
client.columns = width;
client.rows = height;
client.emit('resize');
});
var screen = blessed.screen({
smartCSR: true,
input: client,
output: client,
terminal: 'xterm-256color',
fullUnicode: true
});
client.on('close', function() {
if (!screen.destroyed) {
screen.destroy();
}
});
screen.on('destroy', function() {
if (client.writable) {
client.destroy();
}
});
if (test === 'widget-simple') {
return simpleTest(screen);
}
loadTest(screen, test);
});
function simpleTest(screen) {
screen.data.main = blessed.box({
parent: screen,
width: '80%',
height: '90%',
border: 'line',
content: 'Welcome to my server. Here is your own private session.',
style: {
bg: 'red'
}
});
screen.key('i', function() {
screen.data.main.style.bg = 'blue';
screen.render();
});
screen.key(['C-c', 'q'], function(ch, key) {
screen.destroy();
});
screen.render();
}
var test = process.argv[2] || path.resolve(__dirname, '../test/widget-shadow.js');
if (~test.indexOf('widget-png.js')) process.argv.length = 2;
test = path.resolve(process.cwd(), test);
function loadTest(screen, name) {
var Screen = blessed.screen;
blessed.screen = function() { return screen; };
var path = require.resolve(name);
delete require.cache[path];
require(name);
blessed.screen = Screen;
}
server.listen(2300);
console.log('Listening on 2300...');

View File

@ -127,11 +127,7 @@ var bottomright = blessed.terminal({
topleft.focus();
screen.key('C-q', function() {
topleft.kill();
topright.kill();
bottomleft.kill();
bottomright.kill();
return screen.destroy();
return process.exit(0);
});
screen.program.key('S-tab', function() {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -4,10 +4,6 @@
* Taken from terminfo(5) man page.
*/
/* jshint maxlen: 300 */
// jscs:disable maximumLineLength
// jscs:disable
var alias = exports;
// These are the boolean capabilities:

View File

@ -122,8 +122,6 @@ exports.mixColors = function(c1, c2, alpha) {
};
exports.blend = function blend(attr, attr2, alpha) {
var name, i, c, nc;
var bg = attr & 0x1ff;
if (attr2 != null) {
var bg2 = attr2 & 0x1ff;
@ -138,12 +136,12 @@ exports.blend = function blend(attr, attr2, alpha) {
} else if (bg >= 8 && bg <= 15) {
bg -= 8;
} else {
name = exports.ncolors[bg];
var name = exports.ncolors[bg];
if (name) {
for (i = 0; i < exports.ncolors.length; i++) {
for (var i = 0; i < exports.ncolors.length; i++) {
if (name === exports.ncolors[i] && i !== bg) {
c = exports.vcolors[bg];
nc = exports.vcolors[i];
var c = exports.vcolors[bg];
var nc = exports.vcolors[i];
if (nc[0] + nc[1] + nc[2] < c[0] + c[1] + c[2]) {
blend._cache[bg] = i;
bg = i;
@ -178,12 +176,12 @@ exports.blend = function blend(attr, attr2, alpha) {
} else if (fg >= 8 && fg <= 15) {
fg -= 8;
} else {
name = exports.ncolors[fg];
var name = exports.ncolors[fg];
if (name) {
for (i = 0; i < exports.ncolors.length; i++) {
for (var i = 0; i < exports.ncolors.length; i++) {
if (name === exports.ncolors[i] && i !== fg) {
c = exports.vcolors[fg];
nc = exports.vcolors[i];
var c = exports.vcolors[fg];
var nc = exports.vcolors[i];
if (nc[0] + nc[1] + nc[2] < c[0] + c[1] + c[2]) {
blend._cache[fg] = i;
fg = i;

View File

@ -79,10 +79,6 @@ EventEmitter.prototype._emit = function(type, args) {
var handler = this._events[type]
, ret;
// if (type !== 'event') {
// this._emit('event', [type.replace(/^element /, '')].concat(args));
// }
if (!handler) {
if (type === 'error') {
throw new args[0];
@ -105,11 +101,8 @@ EventEmitter.prototype._emit = function(type, args) {
EventEmitter.prototype.emit = function(type) {
var args = slice.call(arguments, 1)
, params = slice.call(arguments)
, el = this;
this._emit('event', params);
if (this.type === 'screen') {
return this._emit(type, args);
}
@ -120,13 +113,8 @@ EventEmitter.prototype.emit = function(type) {
type = 'element ' + type;
args.unshift(this);
// `element` prefix
// params = [type].concat(args);
// no `element` prefix
// params.splice(1, 0, this);
do {
// el._emit('event', params);
if (!el._events[type]) continue;
if (el._emit(type, args) === false) {
return false;

View File

@ -7,6 +7,7 @@
var net = require('net');
var fs = require('fs');
var EventEmitter = require('events').EventEmitter;
var util = require('util')
var GPM_USE_MAGIC = false;
@ -32,9 +33,8 @@ var GPM_SOCKET = '/dev/gpmctl';
// } Gpm_Connect;
function send_config(socket, Gpm_Connect, callback) {
var buffer;
if (GPM_USE_MAGIC) {
buffer = new Buffer(20);
var buffer = new Buffer(20);
buffer.writeUInt32LE(GPM_MAGIC, 0);
buffer.writeUInt16LE(Gpm_Connect.eventMask, 4);
buffer.writeUInt16LE(Gpm_Connect.defaultMask, 6);
@ -43,7 +43,7 @@ function send_config(socket, Gpm_Connect, callback) {
buffer.writeInt16LE(process.pid, 12);
buffer.writeInt16LE(Gpm_Connect.vc, 16);
} else {
buffer = new Buffer(16);
var buffer = new Buffer(16);
buffer.writeUInt16LE(Gpm_Connect.eventMask, 0);
buffer.writeUInt16LE(Gpm_Connect.defaultMask, 2);
buffer.writeUInt16LE(Gpm_Connect.minMod, 4);
@ -183,7 +183,7 @@ function GpmClient(options) {
}
});
gpm.on('error', function() {
gpm.on('error', function(err) {
self.stop();
});
});

View File

@ -93,9 +93,9 @@ helpers.escape = function(text) {
});
};
helpers.parseTags = function(text, screen) {
helpers.parseTags = function(text) {
return helpers.Element.prototype._parseTags.call(
{ parseTags: true, screen: screen || helpers.Screen.global }, text);
{ parseTags: true, screen: Screen.global }, text);
};
helpers.generateTags = function(style, text) {
@ -150,13 +150,6 @@ helpers.dropUnicode = function(text) {
.replace(unicode.chars.surrogate, '?');
};
helpers.__defineGetter__('Screen', function() {
if (!helpers._screen) {
helpers._screen = require('./widgets/screen');
}
return helpers._screen;
});
helpers.__defineGetter__('Element', function() {
if (!helpers._element) {
helpers._element = require('./widgets/element');

View File

@ -26,13 +26,7 @@
// IN THE SOFTWARE.
var EventEmitter = require('events').EventEmitter;
// NOTE: node <=v0.8.x has no EventEmitter.listenerCount
function listenerCount(stream, event) {
return EventEmitter.listenerCount
? EventEmitter.listenerCount(stream, event)
: stream.listeners(event).length;
}
var StringDecoder = require('string_decoder').StringDecoder;
/**
* accepts a readable Stream instance and makes it emit "keypress" events
@ -44,7 +38,7 @@ function emitKeypressEvents(stream) {
stream._keypressDecoder = new StringDecoder('utf8');
function onData(b) {
if (listenerCount(stream, 'keypress') > 0) {
if (EventEmitter.listenerCount(stream, 'keypress') > 0) {
var r = stream._keypressDecoder.write(b);
if (r) emitKeys(stream, r);
} else {
@ -55,13 +49,13 @@ function emitKeypressEvents(stream) {
}
function onNewListener(event) {
if (event === 'keypress') {
if (event == 'keypress') {
stream.on('data', onData);
stream.removeListener('newListener', onNewListener);
}
}
if (listenerCount(stream, 'keypress') > 0) {
if (EventEmitter.listenerCount(stream, 'keypress') > 0) {
stream.on('data', onData);
} else {
stream.on('newListener', onNewListener);

View File

@ -66,13 +66,11 @@ function Program(options) {
this.scrollTop = 0;
this.scrollBottom = this.rows - 1;
this._terminal = options.terminal
|| options.term
this.terminal = options.term
|| options.terminal
|| process.env.TERM
|| (process.platform === 'win32' ? 'windows-ansi' : 'xterm');
this._terminal = this._terminal.toLowerCase();
// OSX
this.isOSXTerm = process.env.TERM_PROGRAM === 'Apple_Terminal';
this.isiTerm2 = process.env.TERM_PROGRAM === 'iTerm.app'
@ -128,19 +126,14 @@ Program.bind = function(program) {
if (!~Program.instances.indexOf(program)) {
Program.instances.push(program);
program.index = Program.total;
Program.total++;
}
if (Program._bound) return;
Program._bound = true;
unshiftEvent(process, 'exit', Program._exitHandler = function() {
unshiftEvent(process, 'exit', function() {
Program.instances.forEach(function(program) {
// Potentially reset window title on exit:
// if (program._originalTitle) {
// program.setTitle(program._originalTitle);
// }
// Ensure the buffer is flushed (it should
// always be at this point, but who knows).
program.flush();
@ -149,6 +142,15 @@ Program.bind = function(program) {
program._exiting = true;
});
});
// Potentially reset window title on exit:
// unshiftEvent(process, 'exit', function() {
// Program.instances.forEach(function(program) {
// if (program._originalTitle) {
// program.setTitle(program._originalTitle);
// }
// });
// });
};
Program.prototype.__proto__ = EventEmitter.prototype;
@ -195,7 +197,7 @@ Program.prototype.setupDump = function() {
return data.replace(/[\0\x80\x1b-\x1f\x7f\x01-\x1a]/g, function(ch) {
switch (ch) {
case '\0':
case '\x80':
case '\200':
ch = '@';
break;
case '\x1b':
@ -246,15 +248,14 @@ Program.prototype.setupTput = function() {
var self = this
, options = this.options
, write = this._write.bind(this);
, write = this.write.bind(this);
var tput = this.tput = new Tput({
terminal: this.terminal,
term: this.terminal,
padding: options.padding,
extended: options.extended,
printf: options.printf,
termcap: options.termcap,
forceUnicode: options.forceUnicode
termcap: options.termcap
});
if (tput.error) {
@ -263,12 +264,6 @@ Program.prototype.setupTput = function() {
});
}
if (tput.padding) {
nextTick(function() {
self.emit('warning', 'Terminfo padding has been enabled.');
});
}
this.put = function() {
var args = slice.call(arguments)
, cap = args.shift();
@ -288,7 +283,7 @@ Program.prototype.setupTput = function() {
return;
}
if (tput.padding) {
if (options.padding) {
self.put[key] = function() {
return tput._print(tput[key].apply(tput, arguments), write);
};
@ -300,21 +295,6 @@ Program.prototype.setupTput = function() {
});
};
Program.prototype.__defineGetter__('terminal', function() {
return this._terminal;
});
Program.prototype.__defineSetter__('terminal', function(terminal) {
this.setTerminal(terminal);
return this.terminal;
});
Program.prototype.setTerminal = function(terminal) {
this._terminal = terminal.toLowerCase();
delete this._tputSetup;
this.setupTput();
};
Program.prototype.has = function(name) {
return this.tput
? this.tput.has(name)
@ -326,9 +306,8 @@ Program.prototype.term = function(is) {
};
Program.prototype.listen = function() {
var self = this;
// Potentially reset window title on exit:
// var self = this;
// if (!this.isRxvt) {
// if (!this.isVTE) this.setTitleModeFeature(3);
// this.manipulateWindow(21, function(err, data) {
@ -338,36 +317,15 @@ Program.prototype.listen = function() {
// }
// Listen for keys/mouse on input
if (!this.input._blessedInput) {
this.input._blessedInput = 1;
if (!this.input._blessedListened) {
this.input._blessedListened = true;
this._listenInput();
} else {
this.input._blessedInput++;
}
this.on('newListener', this._newHandler = function fn(type) {
if (type === 'keypress' || type === 'mouse') {
self.removeListener('newListener', fn);
if (self.input.setRawMode && !self.input.isRaw) {
self.input.setRawMode(true);
self.input.resume();
}
}
});
this.on('newListener', function fn(type) {
if (type === 'mouse') {
self.removeListener('newListener', fn);
self.bindMouse();
}
});
// Listen for resize on output
if (!this.output._blessedOutput) {
this.output._blessedOutput = 1;
if (!this.output._blessedListened) {
this.output._blessedListened = true;
this._listenOutput();
} else {
this.output._blessedOutput++;
}
};
@ -376,7 +334,7 @@ Program.prototype._listenInput = function() {
, self = this;
// Input
this.input.on('keypress', this.input._keypressHandler = function(ch, key) {
this.input.on('keypress', function(ch, key) {
key = key || { ch: ch };
if (key.name === 'undefined'
@ -412,7 +370,7 @@ Program.prototype._listenInput = function() {
});
});
this.input.on('data', this.input._dataHandler = function(data) {
this.input.on('data', function(data) {
Program.instances.forEach(function(program) {
if (program.input !== self.input) return;
program.emit('data', data);
@ -420,6 +378,29 @@ Program.prototype._listenInput = function() {
});
keys.emitKeypressEvents(this.input);
this.on('newListener', function fn(type) {
if (type === 'keypress' || type === 'mouse') {
Program.instances.forEach(function(program) {
if (program.input !== self.input) return;
program.removeListener('newListener', fn);
if (program.input.setRawMode && !program.input.isRaw) {
program.input.setRawMode(true);
program.input.resume();
}
});
}
});
this.on('newListener', function fn(type) {
if (type === 'mouse') {
Program.instances.forEach(function(program) {
if (program.input !== self.input) return;
program.removeListener('newListener', fn);
program.bindMouse();
});
}
});
};
Program.prototype._listenOutput = function() {
@ -441,7 +422,7 @@ Program.prototype._listenOutput = function() {
});
}
this.output.on('resize', this.output._resizeHandler = function() {
this.output.on('resize', function() {
Program.instances.forEach(function(program) {
if (program.output !== self.output) return;
if (!program.options.resizeTimeout) {
@ -461,53 +442,12 @@ Program.prototype._listenOutput = function() {
Program.prototype.destroy = function() {
var index = Program.instances.indexOf(this);
if (~index) {
Program.instances.splice(index, 1);
Program.total--;
this.flush();
this._exiting = true;
Program.global = Program.instances[0];
if (Program.total === 0) {
Program.global = null;
process.removeListener('exit', Program._exitHandler);
delete Program._exitHandler;
delete Program._bound;
}
this.input._blessedInput--;
this.output._blessedOutput--;
if (this.input._blessedInput === 0) {
this.input.removeListener('keypress', this.input._keypressHandler);
this.input.removeListener('data', this.input._dataHandler);
delete this.input._keypressHandler;
delete this.input._dataHandler;
if (this.input.setRawMode) {
if (this.input.isRaw) {
this.input.setRawMode(false);
}
if (!this.input.destroyed) {
this.input.pause();
}
}
}
if (this.output._blessedOutput === 0) {
this.output.removeListener('resize', this.output._resizeHandler);
delete this.output._resizeHandler;
}
this.removeListener('newListener', this._newHandler);
delete this._newHandler;
this.destroyed = true;
this.emit('destroy');
}
};
@ -570,15 +510,7 @@ Program.prototype.bindMouse = function() {
Program.prototype._bindMouse = function(s, buf) {
var self = this
, key
, parts
, b
, x
, y
, mod
, params
, down
, page
, button;
, parts;
key = {
name: undefined,
@ -622,9 +554,9 @@ Program.prototype._bindMouse = function(s, buf) {
|| (by > 0x00 && by < 0x20)
|| (buf[4] > 223 && buf[4] < 248 && buf.length === 6)
|| (buf[5] > 223 && buf[5] < 248 && buf.length === 6))) {
b = buf[3];
x = buf[4];
y = buf[5];
var b = buf[3]
, x = buf[4]
, y = buf[5];
// unsigned char overflow.
if (x < 0x20) x += 0xff;
@ -640,9 +572,10 @@ Program.prototype._bindMouse = function(s, buf) {
// XTerm / X10
if (parts = /^\x1b\[M([\x00\u0020-\uffff]{3})/.exec(s)) {
b = parts[1].charCodeAt(0);
x = parts[1].charCodeAt(1);
y = parts[1].charCodeAt(2);
var b = parts[1].charCodeAt(0)
, x = parts[1].charCodeAt(1)
, y = parts[1].charCodeAt(2)
, mod;
key.name = 'mouse';
key.type = 'X10';
@ -675,7 +608,7 @@ Program.prototype._bindMouse = function(s, buf) {
delete this._lastButton;
} else {
key.action = 'mousedown';
button = b & 3;
var button = b & 3;
key.button =
button === 0 ? 'left'
: button === 1 ? 'middle'
@ -707,10 +640,10 @@ Program.prototype._bindMouse = function(s, buf) {
// URxvt
if (parts = /^\x1b\[(\d+;\d+;\d+)M/.exec(s)) {
params = parts[1].split(';');
b = +params[0];
x = +params[1];
y = +params[2];
var params = parts[1].split(';')
, b = +params[0]
, x = +params[1]
, y = +params[2];
key.name = 'mouse';
key.type = 'urxvt';
@ -747,7 +680,7 @@ Program.prototype._bindMouse = function(s, buf) {
delete this._lastButton;
} else {
key.action = 'mousedown';
button = b & 3;
var button = b & 3;
key.button =
button === 0 ? 'left'
: button === 1 ? 'middle'
@ -780,11 +713,11 @@ Program.prototype._bindMouse = function(s, buf) {
// SGR
if (parts = /^\x1b\[<(\d+;\d+;\d+)([mM])/.exec(s)) {
down = parts[2] === 'M';
params = parts[1].split(';');
b = +params[0];
x = +params[1];
y = +params[2];
var down = parts[2] === 'M'
, params = parts[1].split(';')
, b = +params[0]
, x = +params[1]
, y = +params[2];
key.name = 'mouse';
key.type = 'sgr';
@ -808,7 +741,7 @@ Program.prototype._bindMouse = function(s, buf) {
key.action = down
? 'mousedown'
: 'mouseup';
button = b & 3;
var button = b & 3;
key.button =
button === 0 ? 'left'
: button === 1 ? 'middle'
@ -840,11 +773,11 @@ Program.prototype._bindMouse = function(s, buf) {
// The xterm mouse documentation says there is a
// `<` prefix, the DECRQLP says there is no prefix.
if (parts = /^\x1b\[<(\d+;\d+;\d+;\d+)&w/.exec(s)) {
params = parts[1].split(';');
b = +params[0];
x = +params[1];
y = +params[2];
page = +params[3];
var params = parts[1].split(';')
, b = +params[0]
, x = +params[1]
, y = +params[2]
, page = +params[3];
key.name = 'mouse';
key.type = 'dec';
@ -853,7 +786,6 @@ Program.prototype._bindMouse = function(s, buf) {
key.buf = buf;
key.x = x;
key.y = y;
key.page = page;
if (this.zero) key.x--, key.y--;
@ -874,9 +806,9 @@ Program.prototype._bindMouse = function(s, buf) {
// vt300
if (parts = /^\x1b\[24([0135])~\[(\d+),(\d+)\]\r/.exec(s)) {
b = +parts[1];
x = +parts[2];
y = +parts[3];
var b = +parts[1]
, x = +parts[2]
, y = +parts[3];
key.name = 'mouse';
key.type = 'vt300';
@ -915,7 +847,7 @@ Program.prototype._bindMouse = function(s, buf) {
// gpm support for linux vc
Program.prototype.enableGpm = function() {
var self = this;
var gpmclient = require('./gpmclient');
var gpmclient = require('./gpmclient')
if (this.gpm) return;
@ -1038,7 +970,8 @@ Program.prototype.bindResponse = function() {
};
Program.prototype._bindResponse = function(s) {
var out = {}
var self = this
, out = {}
, parts;
if (Buffer.isBuffer(s)) {
@ -1324,7 +1257,7 @@ Program.prototype._bindResponse = function(s) {
out.type = 'window-state';
out.state = parts[1] === '1'
? 'non-iconified'
: 'iconified';
: 'iconified'
// LEGACY
out.windowState = out.state;
@ -1629,16 +1562,10 @@ Program.prototype.response = function(name, text, callback, noBypass) {
: this._twrite(text);
};
Program.prototype._owrite =
Program.prototype.write = function(text) {
if (!this.output.writable) return;
return this.output.write(text);
};
Program.prototype._buffer = function(text) {
if (this._exiting) {
this.flush();
this._owrite(text);
this.output.write(text);
return;
}
@ -1654,9 +1581,9 @@ Program.prototype._buffer = function(text) {
return true;
};
Program.prototype.flush = function() {
Program.prototype.flush = function(text) {
if (!this._buf) return;
this._owrite(this._buf);
this.output.write(this._buf);
this._buf = '';
};
@ -1665,7 +1592,7 @@ Program.prototype._write = function(text) {
if (this.useBuffer) {
return this._buffer(text);
}
return this._owrite(text);
return this.output.write(text);
};
// Example: `DCS tmux; ESC Pt ST`
@ -1689,7 +1616,7 @@ Program.prototype._twrite = function(data) {
if (self.output.bytesWritten > 0 || ++iterations === 50) {
clearInterval(timer);
self.flush();
self._owrite(data);
self.output.write(data);
}
}, 100);
return true;
@ -1700,14 +1627,14 @@ Program.prototype._twrite = function(data) {
this.flush();
// Write out raw now that the buffer is flushed.
return this._owrite(data);
return this.output.write(data);
}
return this._write(data);
};
Program.prototype.echo =
Program.prototype.print = function(text, attr) {
Program.prototype.write = function(text, attr) {
return attr
? this._write(this.text(text, attr))
: this._write(text);
@ -1789,7 +1716,7 @@ Program.prototype.simpleInsert = function(ch, i, attr) {
};
Program.prototype.repeat = function(ch, i) {
if (!i || i < 0) i = 0;
if (!(i >= 0)) i = 0;
return Array(i + 1).join(ch);
};
@ -1911,7 +1838,7 @@ Program.prototype.getCursorColor = function(callback) {
//Program.prototype.pad =
Program.prototype.nul = function() {
//if (this.has('pad')) return this.put.pad();
return this._write('\x80');
return this._write('\200');
};
Program.prototype.bel =
@ -2049,7 +1976,7 @@ Program.prototype.restoreCursor = function(key, hide) {
// Save Cursor Locally
Program.prototype.lsaveCursor = function(key) {
key = key || 'local';
var key = key || 'local';
this._saved = this._saved || {};
this._saved[key] = this._saved[key] || {};
this._saved[key].x = this.x;
@ -2059,8 +1986,7 @@ Program.prototype.lsaveCursor = function(key) {
// Restore Cursor Locally
Program.prototype.lrestoreCursor = function(key, hide) {
var pos;
key = key || 'local';
var key = key || 'local', pos;
if (!this._saved || !this._saved[key]) return;
pos = this._saved[key];
//delete this._saved[key];
@ -2281,12 +2207,7 @@ Program.prototype.up =
Program.prototype.cursorUp = function(param) {
this.y -= param || 1;
this._ncoords();
if (this.tput) {
if (!this.tput.strings.parm_up_cursor) {
return this._write(this.repeat(this.tput.cuu1(), param));
}
return this.put.cuu(param);
}
if (this.tput) return this.put.cuu(param);
return this._write('\x1b[' + (param || '') + 'A');
};
@ -2297,12 +2218,7 @@ Program.prototype.down =
Program.prototype.cursorDown = function(param) {
this.y += param || 1;
this._ncoords();
if (this.tput) {
if (!this.tput.strings.parm_down_cursor) {
return this._write(this.repeat(this.tput.cud1(), param));
}
return this.put.cud(param);
}
if (this.tput) return this.put.cud(param);
return this._write('\x1b[' + (param || '') + 'B');
};
@ -2314,12 +2230,7 @@ Program.prototype.forward =
Program.prototype.cursorForward = function(param) {
this.x += param || 1;
this._ncoords();
if (this.tput) {
if (!this.tput.strings.parm_right_cursor) {
return this._write(this.repeat(this.tput.cuf1(), param));
}
return this.put.cuf(param);
}
if (this.tput) return this.put.cuf(param);
return this._write('\x1b[' + (param || '') + 'C');
};
@ -2331,12 +2242,7 @@ Program.prototype.back =
Program.prototype.cursorBackward = function(param) {
this.x -= param || 1;
this._ncoords();
if (this.tput) {
if (!this.tput.strings.parm_left_cursor) {
return this._write(this.repeat(this.tput.cub1(), param));
}
return this.put.cub(param);
}
if (this.tput) return this.put.cub(param);
return this._write('\x1b[' + (param || '') + 'D');
};
@ -2523,6 +2429,7 @@ Program.prototype.text = function(text, attr) {
// NOTE: sun-color may not allow multiple params for SGR.
Program.prototype._attr = function(param, val) {
var self = this
, param
, parts
, color
, m;
@ -2582,6 +2489,7 @@ Program.prototype._attr = function(param, val) {
return val === false
? '\x1b[27m'
: '\x1b[7m';
break;
case 'invisible':
return val === false
? '\x1b[28m'
@ -2976,7 +2884,7 @@ Program.prototype.charPosAbsolute = function(param) {
if (this.tput) {
return this.put.hpa.apply(this.put, arguments);
}
param = slice.call(arguments).join(';');
var param = slice.call(arguments).join(';');
return this._write('\x1b[' + (param || '') + '`');
};
@ -2985,11 +2893,11 @@ Program.prototype.charPosAbsolute = function(param) {
// reuse CSI Ps C ?
Program.prototype.hpr =
Program.prototype.HPositionRelative = function(param) {
if (this.tput) return this.cuf(param);
this.x += param || 1;
this._ncoords();
// Does not exist:
// if (this.tput) return this.put.hpr(param);
if (this.tput) return this.put.cuf(param);
return this._write('\x1b[' + (param || '') + 'a');
};
@ -3044,7 +2952,7 @@ Program.prototype.linePosAbsolute = function(param) {
if (this.tput) {
return this.put.vpa.apply(this.put, arguments);
}
param = slice.call(arguments).join(';');
var param = slice.call(arguments).join(';');
return this._write('\x1b[' + (param || '') + 'd');
};
@ -3052,11 +2960,11 @@ Program.prototype.linePosAbsolute = function(param) {
// reuse CSI Ps B ?
Program.prototype.vpr =
Program.prototype.VPositionRelative = function(param) {
if (this.tput) return this.cud(param);
this.y += param || 1;
this._ncoords();
// Does not exist:
// if (this.tput) return this.put.vpr(param);
if (this.tput) return this.put.cud(param);
return this._write('\x1b[' + (param || '') + 'e');
};
@ -3910,7 +3818,7 @@ Program.prototype.setAttrInRectangle = function() {
// CSI ? Pm s
// Save DEC Private Mode Values. Ps values are the same as for
// DECSET.
Program.prototype.savePrivateValues = function() {
Program.prototype.savePrivateValues = function(params) {
return this._write('\x1b[?' + slice.call(arguments).join(';') + 's');
};
@ -3982,7 +3890,7 @@ Program.prototype.getWindowSize = function(callback) {
// Ps denotes the attributes to reverse, i.e., 1, 4, 5, 7.
// NOTE: xterm doesn't enable this code by default.
Program.prototype.decrara =
Program.prototype.reverseAttrInRectangle = function() {
Program.prototype.reverseAttrInRectangle = function(params) {
return this._write('\x1b[' + slice.call(arguments).join(';') + '$t');
};
@ -3995,7 +3903,7 @@ Program.prototype.reverseAttrInRectangle = function() {
// Ps = 3 -> Query window/icon labels using UTF-8. (See dis-
// cussion of "Title Modes")
// XXX VTE bizarelly echos this:
Program.prototype.setTitleModeFeature = function() {
Program.prototype.setTitleModeFeature = function(params) {
return this._twrite('\x1b[>' + slice.call(arguments).join(';') + 't');
};
@ -4005,7 +3913,7 @@ Program.prototype.setTitleModeFeature = function() {
// Ps = 2 , 3 or 4 -> low.
// Ps = 5 , 6 , 7 , or 8 -> high.
Program.prototype.decswbv =
Program.prototype.setWarningBellVolume = function(param) {
Program.prototype.setWarningBellVolume = function(params) {
return this._write('\x1b[' + (param || '') + ' t');
};
@ -4015,7 +3923,7 @@ Program.prototype.setWarningBellVolume = function(param) {
// Ps = 2 , 3 or 4 -> low.
// Ps = 0 , 5 , 6 , 7 , or 8 -> high.
Program.prototype.decsmbv =
Program.prototype.setMarginBellVolume = function(param) {
Program.prototype.setMarginBellVolume = function(params) {
return this._write('\x1b[' + (param || '') + ' u');
};
@ -4027,7 +3935,7 @@ Program.prototype.setMarginBellVolume = function(param) {
// Pp denotes the target page.
// NOTE: xterm doesn't enable this code by default.
Program.prototype.deccra =
Program.prototype.copyRectangle = function() {
Program.prototype.copyRectangle = function(params) {
return this._write('\x1b[' + slice.call(arguments).join(';') + '$v');
};
@ -4043,7 +3951,7 @@ Program.prototype.copyRectangle = function() {
// ted, any locator motion will be reported. DECELR always can-
// cels any prevous rectangle definition.
Program.prototype.decefr =
Program.prototype.enableFilterRectangle = function() {
Program.prototype.enableFilterRectangle = function(params) {
return this._write('\x1b[' + slice.call(arguments).join(';') + '\'w');
};
@ -4059,7 +3967,7 @@ Program.prototype.enableFilterRectangle = function() {
// Pn = 1 <- clock multiplier.
// Pn = 0 <- STP flags.
Program.prototype.decreqtparm =
Program.prototype.requestParameters = function(param) {
Program.prototype.requestParameters = function(params) {
return this._write('\x1b[' + (param || 0) + 'x');
};
@ -4068,7 +3976,7 @@ Program.prototype.requestParameters = function(param) {
// Ps = 1 -> from start to end position, wrapped.
// Ps = 2 -> rectangle (exact).
Program.prototype.decsace =
Program.prototype.selectChangeExtent = function(param) {
Program.prototype.selectChangeExtent = function(params) {
return this._write('\x1b[' + (param || 0) + 'x');
};
@ -4078,7 +3986,7 @@ Program.prototype.selectChangeExtent = function(param) {
// Pt; Pl; Pb; Pr denotes the rectangle.
// NOTE: xterm doesn't enable this code by default.
Program.prototype.decfra =
Program.prototype.fillRectangle = function() {
Program.prototype.fillRectangle = function(params) {
return this._write('\x1b[' + slice.call(arguments).join(';') + '$x');
};
@ -4095,7 +4003,7 @@ Program.prototype.fillRectangle = function() {
// Pu = 1 <- device physical pixels.
// Pu = 2 <- character cells.
Program.prototype.decelr =
Program.prototype.enableLocatorReporting = function() {
Program.prototype.enableLocatorReporting = function(params) {
return this._write('\x1b[' + slice.call(arguments).join(';') + '\'z');
};
@ -4104,7 +4012,7 @@ Program.prototype.enableLocatorReporting = function() {
// Pt; Pl; Pb; Pr denotes the rectangle.
// NOTE: xterm doesn't enable this code by default.
Program.prototype.decera =
Program.prototype.eraseRectangle = function() {
Program.prototype.eraseRectangle = function(params) {
return this._write('\x1b[' + slice.call(arguments).join(';') + '$z');
};
@ -4120,7 +4028,7 @@ Program.prototype.eraseRectangle = function() {
// Ps = 3 -> report button up transitions.
// Ps = 4 -> do not report button up transitions.
Program.prototype.decsle =
Program.prototype.setLocatorEvents = function() {
Program.prototype.setLocatorEvents = function(params) {
return this._write('\x1b[' + slice.call(arguments).join(';') + '\'{');
};
@ -4128,7 +4036,7 @@ Program.prototype.setLocatorEvents = function() {
// Selective Erase Rectangular Area (DECSERA), VT400 and up.
// Pt; Pl; Pb; Pr denotes the rectangle.
Program.prototype.decsera =
Program.prototype.selectiveEraseRectangle = function() {
Program.prototype.selectiveEraseRectangle = function(params) {
return this._write('\x1b[' + slice.call(arguments).join(';') + '${');
};
@ -4175,13 +4083,13 @@ Program.prototype.selectiveEraseRectangle = function() {
Program.prototype.decrqlp =
Program.prototype.req_mouse_pos =
Program.prototype.reqmp =
Program.prototype.requestLocatorPosition = function(param, callback) {
Program.prototype.requestLocatorPosition = function(params, callback) {
// See also:
// get_mouse / getm / Gm
// mouse_info / minfo / Mi
// Correct for tput?
if (this.has('req_mouse_pos')) {
var code = this.tput.req_mouse_pos(param);
var code = this.tput.req_mouse_pos.apply(this.tput, params);
return this.response('locator-position', code, callback);
}
return this.response('locator-position',
@ -4205,7 +4113,6 @@ Program.prototype.deleteColumns = function() {
};
Program.prototype.out = function(name) {
var args = Array.prototype.slice.call(arguments, 1);
this.ret = true;
var out = this[name].apply(this, args);
this.ret = false;
@ -4259,7 +4166,7 @@ Program.prototype.pause = function(callback) {
};
};
Program.prototype.resume = function() {
Program.prototype.resume = function(callback) {
if (this._resume) return this._resume();
};
@ -4277,7 +4184,7 @@ function unshiftEvent(obj, event, listener) {
listeners.forEach(function(listener) {
obj.on(event, listener);
});
}
};
function merge(out) {
slice.call(arguments, 1).forEach(function(obj) {

View File

@ -37,35 +37,31 @@ function Tput(options) {
options = options || {};
if (typeof options === 'string') {
options = { terminal: options };
options = { term: options };
}
this.options = options;
this.terminal = options.terminal
|| options.term
this.terminal = options.term
|| options.terminal
|| process.env.TERM
|| (process.platform === 'win32' ? 'windows-ansi' : 'xterm');
this.terminal = this.terminal.toLowerCase();
this.debug = options.debug;
this.padding = options.padding;
this.extended = options.extended;
this.printf = options.printf;
this.termcap = options.termcap;
this.error = null;
this.terminfoPrefix = options.terminfoPrefix;
this.terminfoFile = options.terminfoFile;
this.termcapFile = options.termcapFile;
if (options.terminal || options.term) {
if (options.term || options.terminal) {
this.setup();
}
}
};
Tput.prototype.setup = function() {
this.error = null;
try {
if (this.termcap) {
try {
@ -147,12 +143,11 @@ Tput.ipaths = [
];
Tput.prototype.readTerminfo = function(term) {
var data
var term = term || this.terminal
, data
, file
, info;
term = term || this.terminal;
file = path.normalize(this._prefix(term));
data = fs.readFileSync(file);
info = this.parseTerminfo(data, file);
@ -202,6 +197,7 @@ Tput.prototype._tprefix = function(prefix, term, soft) {
var file
, dir
, ch
, i
, sdiff
, sfile
@ -366,7 +362,7 @@ Tput.prototype.parseTerminfo = function(data, file) {
o = 0;
for (; i < l; i += 2) {
v = Tput.numbers[o++];
if (data[i + 1] === 0xff && data[i] === 0xff) {
if (data[i + 1] === 0377 && data[i] === 0377) {
info.numbers[v] = -1;
} else {
info.numbers[v] = (data[i + 1] << 8) | data[i];
@ -379,7 +375,7 @@ Tput.prototype.parseTerminfo = function(data, file) {
o = 0;
for (; i < l; i += 2) {
v = Tput.strings[o++];
if (data[i + 1] === 0xff && data[i] === 0xff) {
if (data[i + 1] === 0377 && data[i] === 0377) {
info.strings[v] = -1;
} else {
info.strings[v] = (data[i + 1] << 8) | data[i];
@ -533,7 +529,7 @@ Tput.prototype.parseExtended = function(data) {
var _numbers = [];
l = i + h.numCount * 2;
for (; i < l; i += 2) {
if (data[i + 1] === 0xff && data[i] === 0xff) {
if (data[i + 1] === 0377 && data[i] === 0377) {
_numbers.push(-1);
} else {
_numbers.push((data[i + 1] << 8) | data[i]);
@ -544,7 +540,7 @@ Tput.prototype.parseExtended = function(data) {
var _strings = [];
l = i + h.strCount * 2;
for (; i < l; i += 2) {
if (data[i + 1] === 0xff && data[i] === 0xff) {
if (data[i + 1] === 0377 && data[i] === 0377) {
_strings.push(-1);
} else {
_strings.push((data[i + 1] << 8) | data[i]);
@ -706,12 +702,6 @@ Tput.prototype.inject = function(info) {
this.features = info.features;
Object.keys(info.features).forEach(function(key) {
if (key === 'padding') {
if (!info.features.padding && self.options.padding !== true) {
self.padding = false;
}
return;
}
self[key] = info.features[key];
});
};
@ -720,7 +710,8 @@ Tput.prototype.inject = function(info) {
// ~/ncurses/ncurses/tinfo/lib_tparm.c
// ~/ncurses/ncurses/tinfo/comp_scan.c
Tput.prototype._compile = function(info, key, str) {
var v;
var self = this
, v;
this._debug('Compiling %s: %s', key, JSON.stringify(str));
@ -884,7 +875,7 @@ Tput.prototype._compile = function(info, key, str) {
ch = ':';
break;
case '0':
ch = '\x80';
ch = '\200';
break;
case 'a':
ch = '\x07';
@ -1166,10 +1157,9 @@ Tput.prototype._compile = function(info, key, str) {
// See: ~/ncurses/ncurses/tinfo/lib_tputs.c
Tput.prototype._print = function(code, print, done) {
var xon = !this.bools.needs_xon_xoff || this.bools.xon_xoff;
print = print || write;
done = done || noop;
var print = print || write
, done = done || noop
, xon = !this.bools.needs_xon_xoff || this.bools.xon_xoff;
if (!this.padding) {
print(code);
@ -1187,8 +1177,8 @@ Tput.prototype._print = function(code, print, done) {
var part = parts[i++]
, padding = /^\$<([\d.]+)([*\/]{0,2})>/.exec(part)
, amount
, suffix;
// , affect;
, suffix
, affect;
if (!padding) {
print(part);
@ -1214,11 +1204,9 @@ Tput.prototype._print = function(code, print, done) {
// advisory if the device has the xon capability; it is used for cost
// computation but does not trigger delays.
if (~suffix.indexOf('*')) {
// XXX Disable this for now.
amount = amount;
// if (affect = /\x1b\[(\d+)[LM]/.exec(part)) {
// amount *= +affect[1];
// }
if (affect = /\x1b\[(\d+)[LM]/.exec(part)) {
amount *= +affect[1];
}
// The above is a huge workaround. In reality, we need to compile
// `_print` into the string functions and check the cap name and
// params.
@ -1237,16 +1225,6 @@ Tput.prototype._print = function(code, print, done) {
})();
};
// A small helper function if we want
// to easily output text with setTimeouts.
Tput.print = function() {
var fake = {
padding: true,
bools: { needs_xon_xoff: true, xon_xoff: false }
};
return Tput.prototype._print.apply(fake, arguments);
};
/**
* Termcap
*/
@ -1261,12 +1239,12 @@ Tput.cpaths = [
Tput.prototype.readTermcap = function(term) {
var self = this
, term = term || this.terminal
, terms
, term_
, root
, paths;
term = term || this.terminal;
, paths
, i;
// Termcap has a bunch of terminals usually stored in one file/string,
// so we need to find the one containing our desired terminal.
@ -2041,14 +2019,6 @@ Tput.prototype.detectFeatures = function(info) {
};
Tput.prototype.detectUnicode = function() {
if (process.env.NCURSES_FORCE_UNICODE != null) {
return !!+process.env.NCURSES_FORCE_UNICODE;
}
if (this.options.forceUnicode != null) {
return this.options.forceUnicode;
}
var LANG = process.env.LANG
+ ':' + process.env.LANGUAGE
+ ':' + process.env.LC_ALL
@ -2075,8 +2045,8 @@ Tput.prototype.detectBrokenACS = function(info) {
}
// If the terminal supports unicode, we don't need ACS.
if (info.numbers.U8 >= 0) {
return !!info.numbers.U8;
if (info.numbers['U8'] >= 0) {
return !!info.numbers['U8'];
}
// The linux console is just broken for some reason.
@ -2094,14 +2064,14 @@ Tput.prototype.detectBrokenACS = function(info) {
// screen termcap is bugged?
if (this.termcap
&& info.name.indexOf('screen') === 0
&& info.name.indexOf('screen') == 0
&& process.env.TERMCAP
&& ~process.env.TERMCAP.indexOf('screen')
&& ~process.env.TERMCAP.indexOf('hhII00')) {
if (~info.strings.enter_alt_charset_mode.indexOf('\x0e')
|| ~info.strings.enter_alt_charset_mode.indexOf('\x0f')
|| ~info.strings.set_attributes.indexOf('\x0e')
|| ~info.strings.set_attributes.indexOf('\x0f')) {
if (~info.strings.enter_alt_charset_mode.indexOf('\016')
|| ~info.strings.enter_alt_charset_mode.indexOf('\017')
|| ~info.strings.set_attributes.indexOf('\016')
|| ~info.strings.set_attributes.indexOf('\017')) {
return true;
}
}
@ -2122,15 +2092,15 @@ Tput.prototype.detectPCRomSet = function(info) {
return false;
};
Tput.prototype.detectMagicCookie = function() {
Tput.prototype.detectMagicCookie = function(info) {
return process.env.NCURSES_NO_MAGIC_COOKIE == null;
};
Tput.prototype.detectPadding = function() {
Tput.prototype.detectPadding = function(info) {
return process.env.NCURSES_NO_PADDING == null;
};
Tput.prototype.detectSetbuf = function() {
Tput.prototype.detectSetbuf = function(info) {
return process.env.NCURSES_NO_SETBUF == null;
};
@ -2172,7 +2142,7 @@ Tput.prototype.GetConsoleCP = function() {
}
// Allow unicode on all windows consoles for now:
if (+process.env.NCURSES_NO_WINDOWS_UNICODE !== 1) {
if (+process.env.NCURSES_UNICODE !== 0) {
return 65001;
}
@ -2280,7 +2250,7 @@ function sprintf(src) {
break;
case 'c': // char
param = isFinite(param)
? String.fromCharCode(param || 0x80)
? String.fromCharCode(param || 0200)
: '';
break;
}
@ -2394,9 +2364,8 @@ Object.keys(Tput.alias).forEach(function(key) {
});
Tput.prototype.has = function(name) {
name = Tput.aliasMap[name];
var val = this.all[name];
var name = Tput.aliasMap[name]
, val = this.all[name];
if (!name) return false;

View File

@ -142,9 +142,9 @@ exports.charWidth = function(str, i) {
// check for double-wide
// if (point >= 0x1100
// && (point <= 0x115f // Hangul Jamo init. consonants
// || point === 0x2329 || point === 0x232a
// || point == 0x2329 || point == 0x232a
// || (point >= 0x2e80 && point <= 0xa4cf
// && point !== 0x303f) // CJK ... Yi
// && point != 0x303f) // CJK ... Yi
// || (point >= 0xac00 && point <= 0xd7a3) // Hangul Syllables
// || (point >= 0xf900 && point <= 0xfaff) // CJK Compatibility Ideographs
// || (point >= 0xfe10 && point <= 0xfe19) // Vertical forms
@ -157,7 +157,7 @@ exports.charWidth = function(str, i) {
// }
// check for double-wide
if ((0x3000 === point)
if ((0x3000 == point)
|| (0xFF01 <= point && point <= 0xFF60)
|| (0xFFE0 <= point && point <= 0xFFE6)) {
return 2;
@ -208,129 +208,129 @@ exports.charWidth = function(str, i) {
// http://www.unicode.org/reports/tr11/
// http://www.unicode.org/reports/tr11/#Ambiguous
if (process.env.NCURSES_CJK_WIDTH) {
if ((0x00A1 === point)
|| (0x00A4 === point)
if ((0x00A1 == point)
|| (0x00A4 == point)
|| (0x00A7 <= point && point <= 0x00A8)
|| (0x00AA === point)
|| (0x00AA == point)
|| (0x00AD <= point && point <= 0x00AE)
|| (0x00B0 <= point && point <= 0x00B4)
|| (0x00B6 <= point && point <= 0x00BA)
|| (0x00BC <= point && point <= 0x00BF)
|| (0x00C6 === point)
|| (0x00D0 === point)
|| (0x00C6 == point)
|| (0x00D0 == point)
|| (0x00D7 <= point && point <= 0x00D8)
|| (0x00DE <= point && point <= 0x00E1)
|| (0x00E6 === point)
|| (0x00E6 == point)
|| (0x00E8 <= point && point <= 0x00EA)
|| (0x00EC <= point && point <= 0x00ED)
|| (0x00F0 === point)
|| (0x00F0 == point)
|| (0x00F2 <= point && point <= 0x00F3)
|| (0x00F7 <= point && point <= 0x00FA)
|| (0x00FC === point)
|| (0x00FE === point)
|| (0x0101 === point)
|| (0x0111 === point)
|| (0x0113 === point)
|| (0x011B === point)
|| (0x00FC == point)
|| (0x00FE == point)
|| (0x0101 == point)
|| (0x0111 == point)
|| (0x0113 == point)
|| (0x011B == point)
|| (0x0126 <= point && point <= 0x0127)
|| (0x012B === point)
|| (0x012B == point)
|| (0x0131 <= point && point <= 0x0133)
|| (0x0138 === point)
|| (0x0138 == point)
|| (0x013F <= point && point <= 0x0142)
|| (0x0144 === point)
|| (0x0144 == point)
|| (0x0148 <= point && point <= 0x014B)
|| (0x014D === point)
|| (0x014D == point)
|| (0x0152 <= point && point <= 0x0153)
|| (0x0166 <= point && point <= 0x0167)
|| (0x016B === point)
|| (0x01CE === point)
|| (0x01D0 === point)
|| (0x01D2 === point)
|| (0x01D4 === point)
|| (0x01D6 === point)
|| (0x01D8 === point)
|| (0x01DA === point)
|| (0x01DC === point)
|| (0x0251 === point)
|| (0x0261 === point)
|| (0x02C4 === point)
|| (0x02C7 === point)
|| (0x016B == point)
|| (0x01CE == point)
|| (0x01D0 == point)
|| (0x01D2 == point)
|| (0x01D4 == point)
|| (0x01D6 == point)
|| (0x01D8 == point)
|| (0x01DA == point)
|| (0x01DC == point)
|| (0x0251 == point)
|| (0x0261 == point)
|| (0x02C4 == point)
|| (0x02C7 == point)
|| (0x02C9 <= point && point <= 0x02CB)
|| (0x02CD === point)
|| (0x02D0 === point)
|| (0x02CD == point)
|| (0x02D0 == point)
|| (0x02D8 <= point && point <= 0x02DB)
|| (0x02DD === point)
|| (0x02DF === point)
|| (0x02DD == point)
|| (0x02DF == point)
|| (0x0300 <= point && point <= 0x036F)
|| (0x0391 <= point && point <= 0x03A1)
|| (0x03A3 <= point && point <= 0x03A9)
|| (0x03B1 <= point && point <= 0x03C1)
|| (0x03C3 <= point && point <= 0x03C9)
|| (0x0401 === point)
|| (0x0401 == point)
|| (0x0410 <= point && point <= 0x044F)
|| (0x0451 === point)
|| (0x2010 === point)
|| (0x0451 == point)
|| (0x2010 == point)
|| (0x2013 <= point && point <= 0x2016)
|| (0x2018 <= point && point <= 0x2019)
|| (0x201C <= point && point <= 0x201D)
|| (0x2020 <= point && point <= 0x2022)
|| (0x2024 <= point && point <= 0x2027)
|| (0x2030 === point)
|| (0x2030 == point)
|| (0x2032 <= point && point <= 0x2033)
|| (0x2035 === point)
|| (0x203B === point)
|| (0x203E === point)
|| (0x2074 === point)
|| (0x207F === point)
|| (0x2035 == point)
|| (0x203B == point)
|| (0x203E == point)
|| (0x2074 == point)
|| (0x207F == point)
|| (0x2081 <= point && point <= 0x2084)
|| (0x20AC === point)
|| (0x2103 === point)
|| (0x2105 === point)
|| (0x2109 === point)
|| (0x2113 === point)
|| (0x2116 === point)
|| (0x20AC == point)
|| (0x2103 == point)
|| (0x2105 == point)
|| (0x2109 == point)
|| (0x2113 == point)
|| (0x2116 == point)
|| (0x2121 <= point && point <= 0x2122)
|| (0x2126 === point)
|| (0x212B === point)
|| (0x2126 == point)
|| (0x212B == point)
|| (0x2153 <= point && point <= 0x2154)
|| (0x215B <= point && point <= 0x215E)
|| (0x2160 <= point && point <= 0x216B)
|| (0x2170 <= point && point <= 0x2179)
|| (0x2189 === point)
|| (0x2189 == point)
|| (0x2190 <= point && point <= 0x2199)
|| (0x21B8 <= point && point <= 0x21B9)
|| (0x21D2 === point)
|| (0x21D4 === point)
|| (0x21E7 === point)
|| (0x2200 === point)
|| (0x21D2 == point)
|| (0x21D4 == point)
|| (0x21E7 == point)
|| (0x2200 == point)
|| (0x2202 <= point && point <= 0x2203)
|| (0x2207 <= point && point <= 0x2208)
|| (0x220B === point)
|| (0x220F === point)
|| (0x2211 === point)
|| (0x2215 === point)
|| (0x221A === point)
|| (0x220B == point)
|| (0x220F == point)
|| (0x2211 == point)
|| (0x2215 == point)
|| (0x221A == point)
|| (0x221D <= point && point <= 0x2220)
|| (0x2223 === point)
|| (0x2225 === point)
|| (0x2223 == point)
|| (0x2225 == point)
|| (0x2227 <= point && point <= 0x222C)
|| (0x222E === point)
|| (0x222E == point)
|| (0x2234 <= point && point <= 0x2237)
|| (0x223C <= point && point <= 0x223D)
|| (0x2248 === point)
|| (0x224C === point)
|| (0x2252 === point)
|| (0x2248 == point)
|| (0x224C == point)
|| (0x2252 == point)
|| (0x2260 <= point && point <= 0x2261)
|| (0x2264 <= point && point <= 0x2267)
|| (0x226A <= point && point <= 0x226B)
|| (0x226E <= point && point <= 0x226F)
|| (0x2282 <= point && point <= 0x2283)
|| (0x2286 <= point && point <= 0x2287)
|| (0x2295 === point)
|| (0x2299 === point)
|| (0x22A5 === point)
|| (0x22BF === point)
|| (0x2312 === point)
|| (0x2295 == point)
|| (0x2299 == point)
|| (0x22A5 == point)
|| (0x22BF == point)
|| (0x2312 == point)
|| (0x2460 <= point && point <= 0x24E9)
|| (0x24EB <= point && point <= 0x254B)
|| (0x2550 <= point && point <= 0x2573)
@ -343,37 +343,37 @@ exports.charWidth = function(str, i) {
|| (0x25BC <= point && point <= 0x25BD)
|| (0x25C0 <= point && point <= 0x25C1)
|| (0x25C6 <= point && point <= 0x25C8)
|| (0x25CB === point)
|| (0x25CB == point)
|| (0x25CE <= point && point <= 0x25D1)
|| (0x25E2 <= point && point <= 0x25E5)
|| (0x25EF === point)
|| (0x25EF == point)
|| (0x2605 <= point && point <= 0x2606)
|| (0x2609 === point)
|| (0x2609 == point)
|| (0x260E <= point && point <= 0x260F)
|| (0x2614 <= point && point <= 0x2615)
|| (0x261C === point)
|| (0x261E === point)
|| (0x2640 === point)
|| (0x2642 === point)
|| (0x261C == point)
|| (0x261E == point)
|| (0x2640 == point)
|| (0x2642 == point)
|| (0x2660 <= point && point <= 0x2661)
|| (0x2663 <= point && point <= 0x2665)
|| (0x2667 <= point && point <= 0x266A)
|| (0x266C <= point && point <= 0x266D)
|| (0x266F === point)
|| (0x266F == point)
|| (0x269E <= point && point <= 0x269F)
|| (0x26BE <= point && point <= 0x26BF)
|| (0x26C4 <= point && point <= 0x26CD)
|| (0x26CF <= point && point <= 0x26E1)
|| (0x26E3 === point)
|| (0x26E3 == point)
|| (0x26E8 <= point && point <= 0x26FF)
|| (0x273D === point)
|| (0x2757 === point)
|| (0x273D == point)
|| (0x2757 == point)
|| (0x2776 <= point && point <= 0x277F)
|| (0x2B55 <= point && point <= 0x2B59)
|| (0x3248 <= point && point <= 0x324F)
|| (0xE000 <= point && point <= 0xF8FF)
|| (0xFE00 <= point && point <= 0xFE0F)
|| (0xFFFD === point)
|| (0xFFFD == point)
|| (0x1F100 <= point && point <= 0x1F10A)
|| (0x1F110 <= point && point <= 0x1F12D)
|| (0x1F130 <= point && point <= 0x1F169)
@ -405,54 +405,54 @@ exports.isSurrogate = function(str, i) {
};
exports.combiningTable = [
[0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489],
[0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2],
[0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603],
[0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670],
[0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED],
[0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A],
[0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902],
[0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D],
[0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981],
[0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD],
[0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C],
[0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D],
[0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC],
[0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD],
[0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C],
[0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D],
[0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0],
[0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48],
[0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC],
[0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD],
[0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D],
[0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6],
[0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E],
[0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC],
[0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35],
[0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E],
[0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97],
[0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030],
[0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039],
[0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F],
[0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753],
[0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD],
[0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD],
[0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922],
[0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B],
[0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34],
[0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42],
[0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF],
[0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063],
[0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F],
[0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B],
[0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F],
[0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB],
[0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F],
[0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169],
[0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD],
[0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F],
[0xE0100, 0xE01EF]
[ 0x0300, 0x036F ], [ 0x0483, 0x0486 ], [ 0x0488, 0x0489 ],
[ 0x0591, 0x05BD ], [ 0x05BF, 0x05BF ], [ 0x05C1, 0x05C2 ],
[ 0x05C4, 0x05C5 ], [ 0x05C7, 0x05C7 ], [ 0x0600, 0x0603 ],
[ 0x0610, 0x0615 ], [ 0x064B, 0x065E ], [ 0x0670, 0x0670 ],
[ 0x06D6, 0x06E4 ], [ 0x06E7, 0x06E8 ], [ 0x06EA, 0x06ED ],
[ 0x070F, 0x070F ], [ 0x0711, 0x0711 ], [ 0x0730, 0x074A ],
[ 0x07A6, 0x07B0 ], [ 0x07EB, 0x07F3 ], [ 0x0901, 0x0902 ],
[ 0x093C, 0x093C ], [ 0x0941, 0x0948 ], [ 0x094D, 0x094D ],
[ 0x0951, 0x0954 ], [ 0x0962, 0x0963 ], [ 0x0981, 0x0981 ],
[ 0x09BC, 0x09BC ], [ 0x09C1, 0x09C4 ], [ 0x09CD, 0x09CD ],
[ 0x09E2, 0x09E3 ], [ 0x0A01, 0x0A02 ], [ 0x0A3C, 0x0A3C ],
[ 0x0A41, 0x0A42 ], [ 0x0A47, 0x0A48 ], [ 0x0A4B, 0x0A4D ],
[ 0x0A70, 0x0A71 ], [ 0x0A81, 0x0A82 ], [ 0x0ABC, 0x0ABC ],
[ 0x0AC1, 0x0AC5 ], [ 0x0AC7, 0x0AC8 ], [ 0x0ACD, 0x0ACD ],
[ 0x0AE2, 0x0AE3 ], [ 0x0B01, 0x0B01 ], [ 0x0B3C, 0x0B3C ],
[ 0x0B3F, 0x0B3F ], [ 0x0B41, 0x0B43 ], [ 0x0B4D, 0x0B4D ],
[ 0x0B56, 0x0B56 ], [ 0x0B82, 0x0B82 ], [ 0x0BC0, 0x0BC0 ],
[ 0x0BCD, 0x0BCD ], [ 0x0C3E, 0x0C40 ], [ 0x0C46, 0x0C48 ],
[ 0x0C4A, 0x0C4D ], [ 0x0C55, 0x0C56 ], [ 0x0CBC, 0x0CBC ],
[ 0x0CBF, 0x0CBF ], [ 0x0CC6, 0x0CC6 ], [ 0x0CCC, 0x0CCD ],
[ 0x0CE2, 0x0CE3 ], [ 0x0D41, 0x0D43 ], [ 0x0D4D, 0x0D4D ],
[ 0x0DCA, 0x0DCA ], [ 0x0DD2, 0x0DD4 ], [ 0x0DD6, 0x0DD6 ],
[ 0x0E31, 0x0E31 ], [ 0x0E34, 0x0E3A ], [ 0x0E47, 0x0E4E ],
[ 0x0EB1, 0x0EB1 ], [ 0x0EB4, 0x0EB9 ], [ 0x0EBB, 0x0EBC ],
[ 0x0EC8, 0x0ECD ], [ 0x0F18, 0x0F19 ], [ 0x0F35, 0x0F35 ],
[ 0x0F37, 0x0F37 ], [ 0x0F39, 0x0F39 ], [ 0x0F71, 0x0F7E ],
[ 0x0F80, 0x0F84 ], [ 0x0F86, 0x0F87 ], [ 0x0F90, 0x0F97 ],
[ 0x0F99, 0x0FBC ], [ 0x0FC6, 0x0FC6 ], [ 0x102D, 0x1030 ],
[ 0x1032, 0x1032 ], [ 0x1036, 0x1037 ], [ 0x1039, 0x1039 ],
[ 0x1058, 0x1059 ], [ 0x1160, 0x11FF ], [ 0x135F, 0x135F ],
[ 0x1712, 0x1714 ], [ 0x1732, 0x1734 ], [ 0x1752, 0x1753 ],
[ 0x1772, 0x1773 ], [ 0x17B4, 0x17B5 ], [ 0x17B7, 0x17BD ],
[ 0x17C6, 0x17C6 ], [ 0x17C9, 0x17D3 ], [ 0x17DD, 0x17DD ],
[ 0x180B, 0x180D ], [ 0x18A9, 0x18A9 ], [ 0x1920, 0x1922 ],
[ 0x1927, 0x1928 ], [ 0x1932, 0x1932 ], [ 0x1939, 0x193B ],
[ 0x1A17, 0x1A18 ], [ 0x1B00, 0x1B03 ], [ 0x1B34, 0x1B34 ],
[ 0x1B36, 0x1B3A ], [ 0x1B3C, 0x1B3C ], [ 0x1B42, 0x1B42 ],
[ 0x1B6B, 0x1B73 ], [ 0x1DC0, 0x1DCA ], [ 0x1DFE, 0x1DFF ],
[ 0x200B, 0x200F ], [ 0x202A, 0x202E ], [ 0x2060, 0x2063 ],
[ 0x206A, 0x206F ], [ 0x20D0, 0x20EF ], [ 0x302A, 0x302F ],
[ 0x3099, 0x309A ], [ 0xA806, 0xA806 ], [ 0xA80B, 0xA80B ],
[ 0xA825, 0xA826 ], [ 0xFB1E, 0xFB1E ], [ 0xFE00, 0xFE0F ],
[ 0xFE20, 0xFE23 ], [ 0xFEFF, 0xFEFF ], [ 0xFFF9, 0xFFFB ],
[ 0x10A01, 0x10A03 ], [ 0x10A05, 0x10A06 ], [ 0x10A0C, 0x10A0F ],
[ 0x10A38, 0x10A3A ], [ 0x10A3F, 0x10A3F ], [ 0x1D167, 0x1D169 ],
[ 0x1D173, 0x1D182 ], [ 0x1D185, 0x1D18B ], [ 0x1D1AA, 0x1D1AD ],
[ 0x1D242, 0x1D244 ], [ 0xE0001, 0xE0001 ], [ 0xE0020, 0xE007F ],
[ 0xE0100, 0xE01EF ]
];
exports.combining = exports.combiningTable.reduce(function(out, row) {
@ -484,7 +484,7 @@ exports.codePointAt = function(str, position) {
var size = string.length;
// `ToInteger`
var index = position ? Number(position) : 0;
if (index !== index) { // better `isNaN`
if (index != index) { // better `isNaN`
index = 0;
}
// Account for out-of-bounds indices:
@ -541,7 +541,7 @@ exports.fromCodePoint = function() {
!isFinite(codePoint) || // `NaN`, `+Infinity`, or `-Infinity`
codePoint < 0 || // not a valid Unicode code point
codePoint > 0x10FFFF || // not a valid Unicode code point
floor(codePoint) !== codePoint // not an integer
floor(codePoint) != codePoint // not an integer
) {
throw RangeError('Invalid code point: ' + codePoint);
}
@ -554,7 +554,7 @@ exports.fromCodePoint = function() {
lowSurrogate = (codePoint % 0x400) + 0xDC00;
codeUnits.push(highSurrogate, lowSurrogate);
}
if (index + 1 === length || codeUnits.length > MAX_SIZE) {
if (index + 1 == length || codeUnits.length > MAX_SIZE) {
result += stringFromCharCode.apply(null, codeUnits);
codeUnits.length = 0;
}

View File

@ -8,8 +8,11 @@
* Modules
*/
var cp = require('child_process');
var cp = require('child_process')
, path = require('path')
, fs = require('fs');
var helpers = require('../helpers');
var colors = require('../colors');
var Node = require('./node');
@ -47,10 +50,6 @@ function ANSIImage(options) {
// prevent image from blending with itself if there are alpha channels
self.screen.clearRegion(lpos.xi, lpos.xl, lpos.yi, lpos.yl);
});
this.on('destroy', function() {
self.stop();
});
}
ANSIImage.prototype.__proto__ = Box.prototype;
@ -123,37 +122,38 @@ ANSIImage.prototype.setImage = function(file) {
}
};
ANSIImage.prototype.play = function() {
ANSIImage.prototype.play = function(callback) {
var self = this;
if (!this.img) return;
return this.img.play(function(bmp, cellmap) {
return this.img.play(callback || function(bmp, cellmap) {
self.cellmap = cellmap;
self.screen.render();
});
};
ANSIImage.prototype.pause = function() {
if (!this.img) return;
return this.img.pause();
};
ANSIImage.prototype.stop = function() {
if (!this.img) return;
return this.img.stop();
};
ANSIImage.prototype.clearImage = function() {
this.stop();
if (this.img) {
this.stop();
}
this.setContent('');
this.img = null;
this.cellmap = null;
};
ANSIImage.prototype.render = function() {
var self = this;
var coords = this._render();
if (!coords) return;
if (this.img && this.cellmap) {
if (this.img) {
this.img.renderElement(this.cellmap, this);
}

View File

@ -10,6 +10,8 @@
var fs = require('fs');
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
@ -139,10 +141,10 @@ BigText.prototype.render = function() {
if (mcell == null) break;
if (this.fch && this.fch !== ' ') {
lines[y][x + mx][0] = dattr;
lines[y][x + mx][1] = mcell === 1 ? this.fch : this.ch;
lines[y][x + mx][1] = mcell === 1 ? this.fch : ' ';
} else {
lines[y][x + mx][0] = mcell === 1 ? attr : dattr;
lines[y][x + mx][1] = mcell === 1 ? ' ' : this.ch;
lines[y][x + mx][1] = ' ';
}
}
lines[y].dirty = true;

View File

@ -8,6 +8,8 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Element = require('./element');

View File

@ -8,6 +8,8 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Input = require('./input');

View File

@ -8,6 +8,8 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Input = require('./input');
@ -43,7 +45,7 @@ function Checkbox(options) {
});
}
this.on('focus', function() {
this.on('focus', function(old) {
var lpos = self.lpos;
if (!lpos) return;
self.screen.program.lsaveCursor('checkbox');

View File

@ -305,6 +305,12 @@ Element.prototype.free = function() {
delete this._slisteners;
};
Element.prototype.destroy = function() {
this.detach();
this.free();
this.emit('destroy');
};
Element.prototype.hide = function() {
if (this.hidden) return;
this.clearPos();
@ -589,6 +595,7 @@ Element.prototype._wrapContent = function(content, width) {
, margin = 0
, rtof = []
, ftor = []
, fake = []
, out = []
, no = 0
, line
@ -859,16 +866,16 @@ Element.prototype.disableDrag = function() {
return this._draggable = false;
};
Element.prototype.key = function() {
Element.prototype.key = function(key, listener) {
return this.screen.program.key.apply(this, arguments);
};
Element.prototype.onceKey = function() {
Element.prototype.onceKey = function(key, listener) {
return this.screen.program.onceKey.apply(this, arguments);
};
Element.prototype.unkey =
Element.prototype.removeKey = function() {
Element.prototype.removeKey = function(key, listener) {
return this.screen.program.unkey.apply(this, arguments);
};
@ -885,7 +892,7 @@ Element.prototype.setIndex = function(index) {
var i = this.parent.children.indexOf(this);
if (!~i) return;
var item = this.parent.children.splice(i, 1)[0];
var item = this.parent.children.splice(i, 1)[0]
this.parent.children.splice(index, 0, item);
};
@ -961,6 +968,7 @@ Element.prototype.setLabel = function(options) {
}
var reposition = function() {
var visible = self.height - self.iheight;
self._label.rtop = (self.childBase || 0) - self.itop;
if (!self.screen.autoPadding) {
self._label.rtop = (self.childBase || 0);
@ -990,6 +998,8 @@ Element.prototype.removeLabel = function() {
};
Element.prototype.setHover = function(options) {
var self = this;
if (typeof options === 'string') {
options = { text: options };
}
@ -1601,7 +1611,7 @@ Element.prototype._getShrinkBox = function(xi, xl, yi, yl, get) {
return { xi: xi, xl: xl, yi: yi, yl: yl };
};
Element.prototype._getShrinkContent = function(xi, xl, yi, yl) {
Element.prototype._getShrinkContent = function(xi, xl, yi, yl, get) {
var h = this._clines.length
, w = this._clines.mwidth || 1;
@ -2425,16 +2435,12 @@ Element.prototype.deleteLine = function(i, n) {
diff = start - this._clines.length;
// XXX clearPos() without diff statement?
var height = 0;
if (diff > 0) {
var pos = this._getCoords();
if (!pos) return;
height = pos.yl - pos.yi - this.iheight;
var base = this.childBase || 0
var height = pos.yl - pos.yi - this.iheight
, base = this.childBase || 0
, visible = real >= base && real - base < height;
if (pos && visible && this.screen.cleanSides(this)) {
@ -2471,10 +2477,9 @@ Element.prototype.deleteTop = function(n) {
Element.prototype.deleteBottom = function(n) {
var h = (this.childBase || 0) + this.height - 1 - this.iheight
, i = Math.min(h, this._clines.length - 1)
, n = n || 1
, fake = this._clines.rtof[i];
n = n || 1;
return this.deleteLine(fake - (n - 1), n);
};

View File

@ -8,6 +8,8 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
@ -163,7 +165,8 @@ Form.prototype.focusLast = function() {
};
Form.prototype.submit = function() {
var out = {};
var self = this
, out = {};
this.children.forEach(function fn(el) {
if (el.value != null) {

View File

@ -8,6 +8,8 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
@ -16,6 +18,8 @@ var Box = require('./box');
*/
function Image(options) {
var self = this;
if (!(this instanceof Node)) {
return new Image(options);
}

View File

@ -8,6 +8,8 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');

View File

@ -8,6 +8,8 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Element = require('./element');
@ -16,6 +18,8 @@ var Element = require('./element');
*/
function Layout(options) {
var self = this;
if (!(this instanceof Node)) {
return new Layout(options);
}
@ -76,7 +80,9 @@ Layout.prototype.renderer = function(coords) {
var width = coords.xl - coords.xi
, height = coords.yl - coords.yi
, xi = coords.xi
, yi = coords.yi;
, xl = coords.xl
, yi = coords.yi
, yl = coords.yl;
// The current row offset in cells (which row are we on?)
var rowOffset = 0;
@ -169,6 +175,8 @@ Layout.prototype.renderer = function(coords) {
};
Layout.prototype.render = function() {
var self = this;
this._emit('prerender');
var coords = this._renderCoords();

View File

@ -8,6 +8,8 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
@ -16,6 +18,8 @@ var Box = require('./box');
*/
function Line(options) {
var self = this;
if (!(this instanceof Node)) {
return new Line(options);
}

View File

@ -92,11 +92,11 @@ function List(options) {
if (options.mouse) {
this.screen._listenMouse(this);
this.on('element wheeldown', function() {
this.on('element wheeldown', function(el, data) {
self.select(self.selected + 2);
self.screen.render();
});
this.on('element wheelup', function() {
this.on('element wheelup', function(el, data) {
self.select(self.selected - 2);
self.screen.render();
});
@ -274,7 +274,7 @@ List.prototype.createItem = function(content) {
var item = new Box(options);
if (this.mouse) {
item.on('click', function() {
item.on('click', function(data) {
self.focus();
if (self.items[self.selected] === item) {
self.emit('action', item, self.selected);
@ -294,6 +294,8 @@ List.prototype.createItem = function(content) {
List.prototype.add =
List.prototype.addItem =
List.prototype.appendItem = function(content) {
var self = this;
content = typeof content === 'string' ? content : content.getContent();
var item = this.createItem(content);
@ -368,13 +370,12 @@ List.prototype.clearItems = function() {
};
List.prototype.setItems = function(items) {
var original = this.items.slice()
var items = items.slice()
, original = this.items.slice()
, selected = this.selected
, sel = this.ritems[this.selected]
, i = 0;
items = items.slice();
this.select(0);
for (; i < items.length; i++) {
@ -439,8 +440,7 @@ List.prototype.spliceItem = function(child, n) {
List.prototype.find =
List.prototype.fuzzyFind = function(search, back) {
var start = this.selected + (back ? -1 : 1)
, i;
var start = this.selected + (back ? -1 : 1);
if (typeof search === 'number') search += '';
@ -464,17 +464,17 @@ List.prototype.fuzzyFind = function(search, back) {
}
if (!back) {
for (i = start; i < this.ritems.length; i++) {
for (var i = start; i < this.ritems.length; i++){
if (test(helpers.cleanTags(this.ritems[i]))) return i;
}
for (i = 0; i < start; i++) {
for (var i = 0; i < start; i++){
if (test(helpers.cleanTags(this.ritems[i]))) return i;
}
} else {
for (i = start; i >= 0; i--) {
for (var i = start; i >= 0; i--){
if (test(helpers.cleanTags(this.ritems[i]))) return i;
}
for (i = this.ritems.length - 1; i > start; i--) {
for (var i = this.ritems.length - 1; i > start; i--){
if (test(helpers.cleanTags(this.ritems[i]))) return i;
}
}

View File

@ -89,7 +89,7 @@ function Listbar(options) {
}
if (options.autoCommandKeys) {
this.onScreenEvent('keypress', function(ch) {
this.onScreenEvent('keypress', function(ch, key) {
if (/^[0-9]$/.test(ch)) {
var i = +ch - 1;
if (!~i) i = 9;
@ -165,7 +165,7 @@ Listbar.prototype.appendItem = function(item, callback) {
if (!this.parent) {
drawn = 0;
} else {
drawn = prev ? prev.aleft + prev.width : 0;
drawn = prev ? prev.aleft + prev.width : 0
if (!this.screen.autoPadding) {
drawn += this.ileft;
}
@ -246,7 +246,7 @@ Listbar.prototype.appendItem = function(item, callback) {
if (cmd.callback) {
if (cmd.keys) {
this.screen.key(cmd.keys, function() {
this.screen.key(cmd.keys, function(ch, key) {
self.emit('action', el, self.selected);
self.emit('select', el, self.selected);
if (el._.cmd.callback) {
@ -264,7 +264,7 @@ Listbar.prototype.appendItem = function(item, callback) {
// XXX May be affected by new element.options.mouse option.
if (this.mouse) {
el.on('click', function() {
el.on('click', function(data) {
self.emit('action', el, self.selected);
self.emit('select', el, self.selected);
if (el._.cmd.callback) {
@ -311,7 +311,7 @@ Listbar.prototype.select = function(offset) {
}
if (!this.parent) {
this.emit('select item', this.items[offset], offset);
this.emit('select item', el, offset);
return;
}

View File

@ -8,6 +8,8 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
var List = require('./list');
@ -25,8 +27,7 @@ function ListTable(options) {
}
options = options || {};
// options.shrink = true;
options.shrink = true;
options.normalShrink = true;
options.style = options.style || {};
options.style.border = options.style.border || {};
@ -38,19 +39,8 @@ function ListTable(options) {
options.style.selected = options.style.cell.selected;
options.style.item = options.style.cell;
var border = options.border;
if (border
&& border.top === false
&& border.bottom === false
&& border.left === false
&& border.right === false) {
delete options.border;
}
List.call(this, options);
options.border = border;
this._header = new Box({
parent: this,
left: this.screen.autoPadding ? 0 : this.ileft,
@ -75,10 +65,6 @@ function ListTable(options) {
this.setData(options.rows || options.data);
this.on('attach', function() {
self.setData(self.rows);
});
this.on('resize', function() {
var selected = self.selected;
self.setData(self.rows);
@ -96,14 +82,9 @@ ListTable.prototype._calculateMaxes = Table.prototype._calculateMaxes;
ListTable.prototype.setRows =
ListTable.prototype.setData = function(rows) {
var self = this
, align = this.__align
, selected = this.selected
, original = this.items.slice()
, sel = this.ritems[this.selected];
, align = this.__align;
if (this.visible && this.lpos) {
this.clearPos();
}
this.clearPos();
this.clearItems();
@ -111,12 +92,11 @@ ListTable.prototype.setData = function(rows) {
this._calculateMaxes();
if (!this._maxes) return;
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 = self._maxes[i];
@ -163,15 +143,7 @@ ListTable.prototype.setData = function(rows) {
this._header.setFront();
// Try to find our old item if it still exists.
sel = this.ritems.indexOf(sel);
if (~sel) {
this.select(sel);
} else if (this.items.length === original.length) {
this.select(selected);
} else {
this.select(Math.min(selected, this.items.length - 1));
}
this.select(0);
};
ListTable.prototype._select = ListTable.prototype.select;
@ -197,54 +169,48 @@ ListTable.prototype.render = function() {
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);
var height = coords.yl - coords.yi - this.ibottom;
var width = coords.xl - coords.xi - this.iright
, height = coords.yl - coords.yi - this.ibottom;
var border = this.border;
if (!this.border && this.options.border) {
border = this.options.border;
}
if (!border || this.options.noCellBorders) return coords;
if (!this.border || this.options.noCellBorders) return coords;
// Draw border with correct angles.
ry = 0;
for (i = 0; i < height + 1; i++) {
if (!lines[yi + ry]) break;
rx = 0;
self._maxes.slice(0, -1).forEach(function(max) {
self._maxes.slice(0, -1).forEach(function(max, i) {
rx += max;
if (!lines[yi + ry][xi + rx + 1]) return;
// center
if (ry === 0) {
// top
rx++;
lines[yi + ry][xi + rx][0] = battr;
lines[yi + ry][xi + ++rx][0] = battr;
lines[yi + ry][xi + rx][1] = '\u252c'; // '┬'
// XXX If we alter iheight and itop for no borders - nothing should be written here
if (!border.top) {
if (!self.border.top) {
lines[yi + ry][xi + rx][1] = '\u2502'; // '│'
}
lines[yi + ry].dirty = true;
} else if (ry === height) {
// bottom
rx++;
lines[yi + ry][xi + rx][0] = battr;
lines[yi + ry][xi + ++rx][0] = battr;
lines[yi + ry][xi + rx][1] = '\u2534'; // '┴'
// XXX If we alter iheight and ibottom for no borders - nothing should be written here
if (!border.bottom) {
if (!self.border.bottom) {
lines[yi + ry][xi + rx][1] = '\u2502'; // '│'
}
lines[yi + ry].dirty = true;
} else {
// middle
rx++;
++rx;
}
});
ry += 1;
@ -254,19 +220,16 @@ ListTable.prototype.render = function() {
for (ry = 1; ry < height; ry++) {
if (!lines[yi + ry]) break;
rx = 0;
self._maxes.slice(0, -1).forEach(function(max) {
self._maxes.slice(0, -1).forEach(function(max, i) {
rx += max;
if (!lines[yi + ry][xi + rx + 1]) return;
if (self.options.fillCellBorders !== false) {
var lbg = lines[yi + ry][xi + rx][0] & 0x1ff;
rx++;
lines[yi + ry][xi + rx][0] = (battr & ~0x1ff) | lbg;
lines[yi + ry][xi + ++rx][0] = (battr & ~0x1ff) | lbg;
} else {
rx++;
lines[yi + ry][xi + rx][0] = battr;
lines[yi + ry][xi + ++rx][0] = battr;
}
lines[yi + ry][xi + rx][1] = '\u2502'; // '│'
lines[yi + ry].dirty = true;
});
}

View File

@ -8,6 +8,8 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
var Text = require('./text');
@ -17,6 +19,8 @@ var Text = require('./text');
*/
function Loading(options) {
var self = this;
if (!(this instanceof Node)) {
return new Loading(options);
}

View File

@ -12,6 +12,8 @@ var util = require('util');
var nextTick = global.setImmediate || process.nextTick.bind(process);
var helpers = require('../helpers');
var Node = require('./node');
var ScrollableText = require('./scrollabletext');

View File

@ -8,6 +8,8 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
@ -16,6 +18,8 @@ var Box = require('./box');
*/
function Message(options) {
var self = this;
if (!(this instanceof Node)) {
return new Message(options);
}

View File

@ -10,14 +10,13 @@
var EventEmitter = require('../events').EventEmitter;
var helpers = require('../helpers');
/**
* Node
*/
function Node(options) {
var self = this;
var Screen = require('./screen');
if (!(this instanceof Node)) {
return new Node(options);
}
@ -26,43 +25,15 @@ function Node(options) {
options = options || {};
this.options = options;
this.screen = this.screen || options.screen;
if (!this.screen) {
if (this.type === 'screen') {
this.screen = this;
} else if (Screen.total === 1) {
this.screen = Screen.global;
} else if (options.parent) {
this.screen = options.parent;
while (this.screen && this.screen.type !== 'screen') {
this.screen = this.screen.parent;
}
} else if (Screen.total) {
// This _should_ work in most cases as long as the element is appended
// synchronously after the screen's creation. Throw error if not.
this.screen = Screen.instances[Screen.instances.length - 1];
process.nextTick(function() {
if (!self.parent) {
throw new Error('Element (' + self.type + ')'
+ ' was not appended synchronously after the'
+ ' screen\'s creation. Please set a `parent`'
+ ' or `screen` option in the element\'s constructor'
+ ' if you are going to use multiple screens and'
+ ' append the element later.');
}
});
} else {
throw new Error('No active screen.');
}
}
this.screen = this.screen
|| options.screen
|| require('./screen').global
|| (function(){throw new Error('No active screen.')})();
this.parent = options.parent || null;
this.children = [];
this.$ = this._ = this.data = {};
this.uid = Node.uid++;
this.index = this.index != null ? this.index : -1;
this.index = -1;
if (this.type !== 'screen') {
this.detached = true;
@ -84,13 +55,8 @@ Node.prototype.type = 'node';
Node.prototype.insert = function(element, i) {
var self = this;
if (element.screen && element.screen !== this.screen) {
throw new Error('Cannot switch a node\'s screen.');
}
element.detach();
element.parent = this;
element.screen = this.screen;
if (i === 0) {
this.children.unshift(element);
@ -169,19 +135,6 @@ Node.prototype.detach = function() {
if (this.parent) this.parent.remove(this);
};
Node.prototype.free = function() {
return;
};
Node.prototype.destroy = function() {
this.detach();
this.forDescendants(function(el) {
el.free();
el.destroyed = true;
el.emit('destroy');
}, this);
};
Node.prototype.forDescendants = function(iter, s) {
if (s) iter(this);
this.children.forEach(function emit(el) {

View File

@ -123,10 +123,11 @@ OverlayImage.prototype.type = 'overlayimage';
OverlayImage.w3mdisplay = '/usr/lib/w3m/w3mimgdisplay';
OverlayImage.prototype.spawn = function(file, args, opt, callback) {
var spawn = require('child_process').spawn
var screen = this.screen
, opt = opt || {}
, spawn = require('child_process').spawn
, ps;
opt = opt || {};
ps = spawn(file, args, opt);
ps.on('error', function(err) {
@ -153,7 +154,7 @@ OverlayImage.prototype.setImage = function(img, callback) {
}
this._settingImage = true;
var reset = function() {
var reset = function(err, success) {
self._settingImage = false;
self._queue = self._queue || [];
var item = self._queue.shift();
@ -311,6 +312,8 @@ OverlayImage.prototype.renderImage = function(img, ratio, callback) {
};
OverlayImage.prototype.clearImage = function(callback) {
var self = this;
if (cp.execSync) {
callback = callback || function(err, result) { return result; };
try {
@ -371,6 +374,7 @@ OverlayImage.prototype.clearImage = function(callback) {
};
OverlayImage.prototype.imageSize = function(callback) {
var self = this;
var img = this.file;
if (cp.execSync) {
@ -521,6 +525,8 @@ OverlayImage.prototype.getPixelRatio = function(callback) {
};
OverlayImage.prototype.renderImageSync = function(img, ratio) {
var self = this;
if (OverlayImage.hasW3MDisplay === false) {
throw new Error('W3M Image Display not available.');
}
@ -689,6 +695,8 @@ OverlayImage.prototype.termSizeSync = function(_, recurse) {
};
OverlayImage.prototype.getPixelRatioSync = function() {
var self = this;
// XXX We could cache this, but sometimes it's better
// to recalculate to be pixel perfect.
if (this._ratio && !this._needsRatio) {

View File

@ -8,6 +8,8 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Input = require('./input');

View File

@ -8,6 +8,8 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
var Button = require('./button');
@ -18,6 +20,8 @@ var Textbox = require('./textbox');
*/
function Prompt(options) {
var self = this;
if (!(this instanceof Node)) {
return new Prompt(options);
}

View File

@ -8,6 +8,8 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
var Button = require('./button');
@ -17,6 +19,8 @@ var Button = require('./button');
*/
function Question(options) {
var self = this;
if (!(this instanceof Node)) {
return new Question(options);
}

View File

@ -8,6 +8,8 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Checkbox = require('./checkbox');

View File

@ -8,6 +8,8 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');

View File

@ -22,7 +22,6 @@ var helpers = require('../helpers');
var Node = require('./node');
var Log = require('./log');
var Element = require('./element');
var Box = require('./box');
/**
@ -43,7 +42,7 @@ function Screen(options) {
options = { program: options };
}
this.program = options.program;
this.program = options.program || program.global;
if (!this.program) {
this.program = program({
@ -52,9 +51,8 @@ function Screen(options) {
log: options.log,
debug: options.debug,
dump: options.dump,
terminal: options.terminal || options.term,
term: options.term,
resizeTimeout: options.resizeTimeout,
forceUnicode: options.forceUnicode,
tput: true,
buffer: true,
zero: true
@ -64,10 +62,6 @@ function Screen(options) {
this.program.useBuffer = true;
this.program.zero = true;
this.program.options.resizeTimeout = options.resizeTimeout;
if (options.forceUnicode != null) {
this.program.tput.features.unicode = options.forceUnicode;
this.program.tput.unicode = options.forceUnicode;
}
}
this.tput = this.program.tput;
@ -194,6 +188,8 @@ Screen.total = 0;
Screen.instances = [];
Screen.signals = true;
Screen.bind = function(screen) {
if (!Screen.global) {
Screen.global = screen;
@ -201,15 +197,14 @@ Screen.bind = function(screen) {
if (!~Screen.instances.indexOf(screen)) {
Screen.instances.push(screen);
screen.index = Screen.total;
Screen.total++;
}
if (Screen._bound) return;
Screen._bound = true;
process.on('uncaughtException', Screen._exceptionHandler = function(err) {
if (process.listeners('uncaughtException').length > 1) {
process.on('uncaughtException', function(err) {
if (process.listeners('uncaughtException').length > Screen.total) {
return;
}
Screen.instances.slice().forEach(function(screen) {
@ -222,19 +217,22 @@ Screen.bind = function(screen) {
});
});
['SIGTERM', 'SIGINT', 'SIGQUIT'].forEach(function(signal) {
var name = '_' + signal.toLowerCase() + 'Handler';
process.on(signal, Screen[name] = function() {
if (process.listeners(signal).length > 1) {
return;
}
nextTick(function() {
process.exit(0);
// XXX Multiple signal handlers and removal of signal
// handlers does not work, so we have this option instead.
if (Screen.signals) {
['SIGTERM', 'SIGINT', 'SIGQUIT'].forEach(function(signal) {
process.on(signal, function() {
if (process.listeners(signal).length > Screen.total) {
return;
}
nextTick(function() {
process.exit(0);
});
});
});
});
}
process.on('exit', Screen._exitHandler = function() {
process.on('exit', function() {
Screen.instances.slice().forEach(function(screen) {
screen.destroy();
});
@ -253,29 +251,6 @@ Screen.prototype.__defineSetter__('title', function(title) {
return this.program.title = title;
});
Screen.prototype.__defineGetter__('terminal', function() {
return this.program.terminal;
});
Screen.prototype.__defineSetter__('terminal', function(terminal) {
this.setTerminal(terminal);
return this.program.terminal;
});
Screen.prototype.setTerminal = function(terminal) {
var entered = !!this.program.isAlt;
if (entered) {
this._buf = '';
this.program._buf = '';
this.leave();
}
this.program.setTerminal(terminal);
this.tput = this.program.tput;
if (entered) {
this.enter();
}
};
Screen.prototype.enter = function() {
if (this.program.isAlt) return;
if (!this.cursor._set) {
@ -395,18 +370,14 @@ Screen.prototype.postEnter = function() {
tags: true
});
self.render();
var timeout = setTimeout(function() {
setTimeout(function() {
warning.destroy();
self.render();
}, 1500);
if (timeout.unref) {
timeout.unref();
}
}, 1500).unref();
});
}
};
Screen.prototype._destroy = Screen.prototype.destroy;
Screen.prototype.destroy = function() {
this.leave();
@ -414,35 +385,19 @@ Screen.prototype.destroy = function() {
if (~index) {
Screen.instances.splice(index, 1);
Screen.total--;
Screen.global = Screen.instances[0];
if (Screen.total === 0) {
Screen.global = null;
process.removeListener('uncaughtException', Screen._exceptionHandler);
process.removeListener('SIGTERM', Screen._sigtermHandler);
process.removeListener('SIGINT', Screen._sigintHandler);
process.removeListener('SIGQUIT', Screen._sigquitHandler);
process.removeListener('exit', Screen._exitHandler);
delete Screen._exceptionHandler;
delete Screen._sigtermHandler;
delete Screen._sigintHandler;
delete Screen._sigquitHandler;
delete Screen._exitHandler;
delete Screen._bound;
}
this.destroyed = true;
this.emit('destroy');
this._destroy();
}
this.program.destroy();
};
Screen.prototype.log = function() {
if (this.debugLog) {
this.debugLog.log.apply(this.debugLog, arguments);
}
return this.program.log.apply(this.program, arguments);
};
@ -551,7 +506,7 @@ Screen.prototype._listenMouse = function(el) {
// });
// Autofocus elements with the appropriate option.
this.on('element click', function(el) {
this.on('element click', function(el, data) {
if (el.clickable === true && el.options.autoFocus !== false) {
el.focus();
}
@ -588,7 +543,7 @@ Screen.prototype._listenKeys = function(el) {
var focused = self.focused
, grabKeys = self.grabKeys;
if (!grabKeys || ~self.ignoreLocked.indexOf(key.full)) {
if (!grabKeys) {
self.emit('keypress', ch, key);
self.emit('key ' + key.full, ch, key);
}
@ -664,7 +619,7 @@ Screen.prototype._initHover = function() {
// XXX This can cause problems if the
// terminal does not support allMotion.
// Workaround: check to see if content is set.
this.on('element mouseup', function(el) {
this.on('element mouseup', function(el, data) {
if (!self._hoverText.getContent()) return;
if (!el._hoverOptions) return;
self.append(self._hoverText);
@ -688,7 +643,7 @@ Screen.prototype.__defineGetter__('height', function() {
return this.program.rows;
});
Screen.prototype.alloc = function(dirty) {
Screen.prototype.alloc = function() {
var x, y;
this.lines = [];
@ -697,7 +652,7 @@ Screen.prototype.alloc = function(dirty) {
for (x = 0; x < this.cols; x++) {
this.lines[y][x] = [this.dattr, ' '];
}
this.lines[y].dirty = !!dirty;
this.lines[y].dirty = false;
}
this.olines = [];
@ -711,15 +666,9 @@ Screen.prototype.alloc = function(dirty) {
this.program.clear();
};
Screen.prototype.realloc = function() {
return this.alloc(true);
};
Screen.prototype.render = function() {
var self = this;
if (this.destroyed) return;
this.emit('prerender');
this._borderStops = {};
@ -1164,11 +1113,7 @@ Screen.prototype.draw = function(start, end) {
// } else {
// out += this.tput.el();
// }
// if (this.tput.strings.parm_right_cursor) {
// out += this.tput.cuf(xx - x);
// } else {
// out += this.tput.cup(y, xx);
// }
// out += this.tput.cuf(xx - x);
// this.fillRegion(data, ' ',
// x, this.tput.strings.erase_chars ? xx : line.length,
// y, y + 1);
@ -1201,13 +1146,9 @@ Screen.prototype.draw = function(start, end) {
}
continue;
} else if (lx !== -1) {
if (this.tput.strings.parm_right_cursor) {
out += y === ly
? this.tput.cuf(x - lx)
: this.tput.cup(y, x);
} else {
out += this.tput.cup(y, x);
}
out += y === ly
? this.tput.cuf(x - lx)
: this.tput.cup(y, x);
lx = -1, ly = -1;
}
o[x][0] = data;
@ -1389,7 +1330,7 @@ Screen.prototype.draw = function(start, end) {
}
// this.program.flush();
// this.program._owrite(pre + main + post);
// this.program.output.write(pre + main + post);
this.program._write(pre + main + post);
}
@ -1666,7 +1607,7 @@ Screen.prototype._focus = function(self, old) {
// If we're in a scrollable element,
// automatically scroll to the focused element.
if (el && !el.detached) {
if (el) {
// NOTE: This is different from the other "visible" values - it needs the
// visible height of the scrolling element itself, not the element within
// it.
@ -1744,12 +1685,11 @@ Screen.prototype.spawn = function(file, args, options) {
var screen = this
, program = screen.program
, options = options || {}
, spawn = require('child_process').spawn
, mouse = program.mouseEnabled
, ps;
options = options || {};
options.stdio = options.stdio || 'inherit';
program.lsaveCursor('spawn');
@ -1761,17 +1701,13 @@ Screen.prototype.spawn = function(file, args, options) {
var write = program.output.write;
program.output.write = function() {};
program.input.pause();
if (program.input.setRawMode) {
program.input.setRawMode(false);
}
program.input.setRawMode(false);
var resume = function() {
if (resume.done) return;
resume.done = true;
if (program.input.setRawMode) {
program.input.setRawMode(true);
}
program.input.setRawMode(true);
program.input.resume();
program.output.write = write;
@ -1779,8 +1715,8 @@ Screen.prototype.spawn = function(file, args, options) {
// program.csr(0, program.rows - 1);
if (mouse) {
program.enableMouse();
if (screen.options.sendFocus) {
screen.program.setMouse({ sendFocus: true }, true);
if (self.options.sendFocus) {
self.program.setMouse({ sendFocus: true }, true);
}
}
@ -1800,7 +1736,8 @@ Screen.prototype.spawn = function(file, args, options) {
};
Screen.prototype.exec = function(file, args, options, callback) {
var ps = this.spawn(file, args, options);
var callback = arguments[arguments.length - 1]
, ps = this.spawn(file, args, options);
ps.on('error', function(err) {
if (!callback) return;
@ -1832,6 +1769,7 @@ Screen.prototype.readEditor = function(options, callback) {
options = options || {};
var self = this
, fs = require('fs')
, editor = options.editor || process.env.EDITOR || 'vi'
, name = options.name || process.title || 'blessed'
, rnd = Math.random().toString(36).split('.').pop()
@ -1866,12 +1804,14 @@ Screen.prototype.readEditor = function(options, callback) {
};
Screen.prototype.displayImage = function(file, callback) {
var self = this;
if (!file) {
if (!callback) return;
return callback(new Error('No image.'));
}
file = path.resolve(process.cwd(), file);
var file = path.resolve(process.cwd(), file);
if (!~file.indexOf('://')) {
file = 'file://' + file;
@ -2004,9 +1944,7 @@ Screen.prototype.cursorShape = function(shape, blink) {
self.cursor._state ^= 1;
if (self.renders) self.render();
}, 500);
if (this._cursorBlink.unref) {
this._cursorBlink.unref();
}
this._cursorBlink.unref();
}
return true;
}
@ -2260,9 +2198,9 @@ var dangles = {
'\u2502': true // '│'
};
// var cdangles = {
// '\u250c': true // '┌'
// };
var cdangles = {
'\u250c': true // '┌'
};
// Every ACS angle character can be
// represented by 4 bits ordered like this:

View File

@ -8,6 +8,8 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
@ -95,7 +97,7 @@ function ScrollableBox(options) {
// If mouseup occurs out of the window, no mouseup event fires, and
// scrollbar will drag again on mousedown until another mouseup
// occurs.
self.onScreenEvent('mouseup', smu = function() {
self.onScreenEvent('mouseup', smu = function(data) {
self._scrollingBar = false;
self.removeScreenEvent('mousedown', smd);
self.removeScreenEvent('mouseup', smu);
@ -106,11 +108,11 @@ function ScrollableBox(options) {
}
if (options.mouse) {
this.on('wheeldown', function() {
this.on('wheeldown', function(el, data) {
self.scroll(self.height / 2 | 0 || 1);
self.screen.render();
});
this.on('wheelup', function() {
this.on('wheelup', function(el, data) {
self.scroll(-(self.height / 2 | 0) || -1);
self.screen.render();
});

View File

@ -8,6 +8,8 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var ScrollableBox = require('./scrollablebox');

View File

@ -8,6 +8,8 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
@ -42,11 +44,6 @@ function Table(options) {
this.setData(options.rows || options.data);
this.on('attach', function() {
self.setContent('');
self.setData(self.rows);
});
this.on('resize', function() {
self.setContent('');
self.setData(self.rows);
@ -62,10 +59,6 @@ Table.prototype._calculateMaxes = function() {
var self = this;
var maxes = [];
if (this.detached) return;
this.rows = this.rows || [];
this.rows.forEach(function(row) {
row.forEach(function(cell, i) {
var clen = self.strWidth(cell);
@ -110,15 +103,15 @@ Table.prototype.setRows =
Table.prototype.setData = function(rows) {
var self = this
, text = ''
, line = ''
, align = this.align;
this.rows = rows || [];
this._calculateMaxes();
if (!this._maxes) return;
this.rows.forEach(function(row, i) {
var isHeader = i === 0;
var isFooter = i === self.rows.length - 1;
row.forEach(function(cell, i) {
var width = self._maxes[i];
@ -178,7 +171,9 @@ Table.prototype.render = function() {
var lines = this.screen.lines
, xi = coords.xi
, xl = coords.xl
, yi = coords.yi
, yl = coords.yl
, rx
, ry
, i;
@ -203,7 +198,6 @@ Table.prototype.render = function() {
} else {
lines[yi + y][xi + x][0] = cattr;
}
lines[yi + y].dirty = true;
}
}
@ -236,39 +230,33 @@ Table.prototype.render = function() {
lines[yi + ry][xi + 0][1] = '\u2500'; // '─'
}
}
lines[yi + ry].dirty = true;
} else if (i === self._maxes.length - 1) {
if (!lines[yi + ry][xi + rx + 1]) return;
// right side
if (ry === 0) {
// top
rx++;
lines[yi + ry][xi + rx][0] = battr;
lines[yi + ry][xi + ++rx][0] = battr;
// lines[yi + ry][xi + rx][1] = '\u2510'; // '┐'
} else if (ry / 2 === self.rows.length) {
// bottom
rx++;
lines[yi + ry][xi + rx][0] = battr;
lines[yi + ry][xi + ++rx][0] = battr;
// lines[yi + ry][xi + rx][1] = '\u2518'; // '┘'
} else {
// middle
rx++;
lines[yi + ry][xi + rx][0] = battr;
lines[yi + ry][xi + ++rx][0] = battr;
lines[yi + ry][xi + rx][1] = '\u2524'; // '┤'
// XXX If we alter iwidth and iright for no borders - nothing should be written here
if (!self.border.right) {
lines[yi + ry][xi + rx][1] = '\u2500'; // '─'
}
}
lines[yi + ry].dirty = true;
return;
}
if (!lines[yi + ry][xi + rx + 1]) return;
// center
if (ry === 0) {
// top
rx++;
lines[yi + ry][xi + rx][0] = battr;
lines[yi + ry][xi + ++rx][0] = battr;
lines[yi + ry][xi + rx][1] = '\u252c'; // '┬'
// XXX If we alter iheight and itop for no borders - nothing should be written here
if (!self.border.top) {
@ -276,8 +264,7 @@ Table.prototype.render = function() {
}
} else if (ry / 2 === self.rows.length) {
// bottom
rx++;
lines[yi + ry][xi + rx][0] = battr;
lines[yi + ry][xi + ++rx][0] = battr;
lines[yi + ry][xi + rx][1] = '\u2534'; // '┴'
// XXX If we alter iheight and ibottom for no borders - nothing should be written here
if (!self.border.bottom) {
@ -287,16 +274,13 @@ Table.prototype.render = function() {
// middle
if (self.options.fillCellBorders) {
var lbg = (ry <= 2 ? hattr : cattr) & 0x1ff;
rx++;
lines[yi + ry][xi + rx][0] = (battr & ~0x1ff) | lbg;
lines[yi + ry][xi + ++rx][0] = (battr & ~0x1ff) | lbg;
} else {
rx++;
lines[yi + ry][xi + rx][0] = battr;
lines[yi + ry][xi + ++rx][0] = battr;
}
lines[yi + ry][xi + rx][1] = '\u253c'; // '┼'
// rx++;
// ++rx;
}
lines[yi + ry].dirty = true;
});
ry += 2;
}
@ -305,26 +289,23 @@ Table.prototype.render = function() {
for (ry = 1; ry < self.rows.length * 2; ry++) {
if (!lines[yi + ry]) break;
rx = 0;
self._maxes.slice(0, -1).forEach(function(max) {
self._maxes.slice(0, -1).forEach(function(max, i) {
rx += max;
if (!lines[yi + ry][xi + rx + 1]) return;
if (ry % 2 !== 0) {
if (self.options.fillCellBorders) {
var lbg = (ry <= 2 ? hattr : cattr) & 0x1ff;
rx++;
lines[yi + ry][xi + rx][0] = (battr & ~0x1ff) | lbg;
lines[yi + ry][xi + ++rx][0] = (battr & ~0x1ff) | lbg;
} else {
rx++;
lines[yi + ry][xi + rx][0] = battr;
lines[yi + ry][xi + ++rx][0] = battr;
}
lines[yi + ry][xi + rx][1] = '\u2502'; // '│'
lines[yi + ry].dirty = true;
} else {
rx++;
}
});
rx = 1;
self._maxes.forEach(function(max) {
self._maxes.forEach(function(max, i) {
while (max--) {
if (ry % 2 === 0) {
if (!lines[yi + ry]) break;
@ -336,7 +317,6 @@ Table.prototype.render = function() {
lines[yi + ry][xi + rx][0] = battr;
}
lines[yi + ry][xi + rx][1] = '\u2500'; // '─'
lines[yi + ry].dirty = true;
}
rx++;
}

View File

@ -10,6 +10,8 @@
var nextTick = global.setImmediate || process.nextTick.bind(process);
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
@ -18,6 +20,8 @@ var Box = require('./box');
*/
function Terminal(options) {
var self = this;
if (!(this instanceof Node)) {
return new Terminal(options);
}
@ -44,10 +48,7 @@ function Terminal(options) {
this.style.bg = this.style.bg || 'default';
this.style.fg = this.style.fg || 'default';
this.termName = options.terminal
|| options.term
|| process.env.TERM
|| 'xterm';
this.termName = options.term || process.env.TERM || 'xterm';
this.bootstrap();
}
@ -73,7 +74,7 @@ Terminal.prototype.bootstrap = function() {
get ownerDocument() { return element; },
addEventListener: function() {},
removeEventListener: function() {},
getElementsByTagName: function() { return [element]; },
getElementsByTagName: function(name) { return [element]; },
getElementById: function() { return element; },
parentNode: null,
offsetParent: null,
@ -193,7 +194,7 @@ Terminal.prototype.bootstrap = function() {
this.term.on('passthrough', function(data) {
self.screen.program.flush();
self.screen.program._owrite(data);
self.screen.program.output.write(data);
});
this.on('resize', function() {
@ -208,7 +209,6 @@ Terminal.prototype.bootstrap = function() {
this.on('destroy', function() {
self.kill();
self.screen.program.input.removeListener('data', self._onData);
});
if (this.handler) {
@ -252,6 +252,11 @@ Terminal.prototype.bootstrap = function() {
});
this.screen._listenKeys(this);
this.on('destroy', function() {
self.screen.program.removeListener('data', self._onData);
self.pty.destroy();
});
};
Terminal.prototype.write = function(data) {
@ -344,7 +349,7 @@ Terminal.prototype._isMouse = function(buf) {
};
Terminal.prototype.setScroll =
Terminal.prototype.scrollTo = function(offset) {
Terminal.prototype.scrollTo = function(offset, always) {
this.term.ydisp = offset;
return this.emit('scroll');
};
@ -353,7 +358,7 @@ Terminal.prototype.getScroll = function() {
return this.term.ydisp;
};
Terminal.prototype.scroll = function(offset) {
Terminal.prototype.scroll = function(offset, always) {
this.term.scrollDisp(offset);
return this.emit('scroll');
};
@ -368,7 +373,7 @@ Terminal.prototype.getScrollHeight = function() {
return this.term.rows - 1;
};
Terminal.prototype.getScrollPerc = function() {
Terminal.prototype.getScrollPerc = function(s) {
return (this.term.ydisp / this.term.ybase) * 100;
};
@ -397,12 +402,7 @@ Terminal.prototype.kill = function() {
this.pty.destroy();
this.pty.kill();
}
this.term.refresh = function() {};
this.term.write('\x1b[H\x1b[J');
if (this.term._blink) {
clearInterval(this.term._blink);
}
this.term.destroy();
this.term.write('\x1b[H\x1b[2J');
};
/**

View File

@ -8,6 +8,8 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Element = require('./element');

View File

@ -12,6 +12,8 @@ var unicode = require('../unicode');
var nextTick = global.setImmediate || process.nextTick.bind(process);
var helpers = require('../helpers');
var Node = require('./node');
var Input = require('./input');

View File

@ -8,6 +8,8 @@
* Modules
*/
var helpers = require('../helpers');
var Node = require('./node');
var Textarea = require('./textarea');
@ -16,6 +18,8 @@ var Textarea = require('./textarea');
*/
function Textbox(options) {
var self = this;
if (!(this instanceof Node)) {
return new Textbox(options);
}

View File

@ -10,6 +10,10 @@
var cp = require('child_process');
var nextTick = global.setImmediate || process.nextTick.bind(process);
var helpers = require('../helpers');
var Node = require('./node');
var Box = require('./box');
var Terminal = require('./terminal');

View File

@ -2,8 +2,7 @@
"name": "blessed",
"description": "A high-level terminal interface library for node.js.",
"author": "Christopher Jeffrey",
"version": "0.1.81",
"license": "MIT",
"version": "0.1.15",
"main": "./lib/blessed.js",
"bin": "./bin/tput.js",
"preferGlobal": false,
@ -11,11 +10,5 @@
"homepage": "https://github.com/chjj/blessed",
"bugs": { "url": "http://github.com/chjj/blessed/issues" },
"keywords": ["curses", "tui", "tput", "terminfo", "termcap"],
"tags": ["curses", "tui", "tput", "terminfo", "termcap"],
"engines": {
"node": ">= 0.8.0"
},
"browserify": {
"transform": ["./browser/transform.js"]
}
"tags": ["curses", "tui", "tput", "terminfo", "termcap"]
}

View File

@ -1,5 +0,0 @@
var blessed = require('../'),
screen = blessed.screen();
console.log(blessed.helpers.parseTags('{red-fg}This should be red.{/red-fg}'));
console.log(blessed.helpers.parseTags('{green-bg}This should have a green background.{/green-bg}'));

View File

@ -81,7 +81,7 @@ function parseArg() {
var argv = parseArg();
var tput = blessed.tput({
terminal: argv[0] !== 'all' && argv[0] !== 'rand'
term: argv[0] !== 'all' && argv[0] !== 'rand'
? argv[0] || __dirname + '/../usr/xterm'
: null,
extended: true,
@ -107,14 +107,17 @@ if (argv[0] === 'all') {
result = result.trim().toLowerCase();
if (result !== 'y') return process.exit(0);
console.log('\x1b[32m(You bet your ass I wish to proceed.)\x1b[m');
blessed.tput.print(
'$<1000/>.$<1000/>.$<1000/>.$<100/>Let\'s go...',
process.stdout.write.bind(process.stdout),
function() {
tput.compileAll(argv[1]);
process.exit(0);
}
);
// tput._write('$<1000/>.$<1000/>.$<1000/>.$<100/>Let\'s go...',
// process.stdout.write.bind(process.stdout),
// function() {});
setTimeout(function() { process.stdout.write('.'); }, 1000);
setTimeout(function() { process.stdout.write('.'); }, 2000);
setTimeout(function() { process.stdout.write('.'); }, 3000);
setTimeout(function() { console.log('Let\'s go...'); }, 3100);
setTimeout(function() {
tput.compileAll(argv[1]);
process.exit(0);
}, 4000);
});
return;

View File

@ -27,7 +27,7 @@ var box2 = blessed.box({
});
screen.key('q', function() {
return screen.destroy();
return process.exit(0);
});
screen.render();

View File

@ -17,16 +17,14 @@ var box = blessed.bigtext({
// width: 'shrink',
border: 'line',
fch: ' ',
ch: '\u2592',
style: {
fg: 'red',
bg: 'blue',
bold: false
}
});
screen.key('q', function() {
return screen.destroy();
return process.exit(0);
});
screen.render();

View File

@ -84,7 +84,7 @@ text.scroll = function(offset, always) {
text.focus();
screen.key('q', function() {
return screen.destroy();
return process.exit(0);
});
screen.render();

View File

@ -82,7 +82,7 @@ blessed.listtable({
// });
screen.key('q', function() {
return screen.destroy();
return process.exit(0);
});
screen.render();

View File

@ -119,7 +119,7 @@ var over = blessed.box({
});
screen.key('q', function() {
return screen.destroy();
return process.exit(0);
});
screen.render();

View File

@ -1,36 +0,0 @@
var blessed = require('../');
var screen = blessed.screen({
dump: __dirname + '/logs/exit.log',
smartCSR: true,
autoPadding: true,
warnings: true,
ignoreLocked: ['C-q']
});
var box = blessed.prompt({
parent: screen,
left: 'center',
top: 'center',
width: '70%',
height: 'shrink',
border: 'line'
});
screen.render();
box.input('Input: ', '', function(err, data) {
screen.destroy();
if (process.argv[2] === 'resume') {
process.stdin.resume();
} else if (process.argv[2] === 'end') {
process.stdin.setRawMode(false);
process.stdin.end();
}
if (err) throw err;
console.log('Input: ' + data);
});
screen.key('C-q', function(ch, key) {
return screen.destroy();
});

View File

@ -47,7 +47,7 @@ fm.refresh();
screen.render();
screen.key('q', function() {
screen.destroy();
process.exit(0);
});
screen.key(['s', 'p'], function() {

View File

@ -243,7 +243,7 @@ var bottom = blessed.line({
});
screen.key('q', function() {
return screen.destroy();
return process.exit(0);
});
form.focus();

View File

@ -64,7 +64,7 @@ screen.key('i', function() {
});
screen.key('q', function() {
return screen.destroy();
return process.exit(0);
});
screen.render();

View File

@ -33,5 +33,5 @@ setTimeout(function() {
}, 2000);
screen.key('q', function() {
screen.destroy();
process.exit(0);
});

View File

@ -159,7 +159,7 @@ if (process.argv[2] !== 'grid') {
}
screen.key('q', function() {
return screen.destroy();
return process.exit(0);
});
screen.render();

View File

@ -116,7 +116,7 @@ screen.append(bar);
bar.focus();
screen.key('q', function() {
return screen.destroy();
return process.exit(0);
});
screen.render();

View File

@ -30,7 +30,7 @@ var box = blessed.box({
*/
var table = blessed.listtable({
//parent: screen,
parent: screen,
top: 'center',
left: 'center',
data: null,
@ -83,15 +83,12 @@ data2[1][0] = '{red-fg}' + data2[1][0] + '{/red-fg}';
data2[2][0] += ' (' + DU + JUAN + ')';
screen.key('q', function() {
return screen.destroy();
return process.exit(0);
});
table.focus();
table.setData(data2);
screen.append(table);
screen.render();
setTimeout(function() {

View File

@ -42,7 +42,7 @@ setInterval(function() {
}, 1000).unref();
screen.key('q', function() {
return screen.destroy();
return process.exit(0);
});
screen.render();

View File

@ -23,7 +23,7 @@ blessed.box({
});
screen.key('q', function() {
return screen.destroy();
return process.exit(0);
});
screen.render();

View File

@ -38,11 +38,11 @@ list.select(0);
list.on('select', function(item) {
console.log(item.getText());
screen.destroy();
process.exit(0);
});
screen.key('C-c', function() {
screen.destroy();
process.exit(0);
});
list.focus();

View File

@ -23,7 +23,7 @@ var box = blessed.box({
box.focus();
screen.key('q', function() {
return screen.destroy();
return process.exit(0);
});
screen.render();

View File

@ -68,5 +68,5 @@ box.focus();
screen.render();
screen.key('q', function() {
screen.destroy();
process.exit(0);
});

View File

@ -22,7 +22,7 @@ blessed.box({
});
screen.key('q', function() {
return screen.destroy();
return process.exit(0);
});
screen.render();

View File

@ -8,10 +8,7 @@ var screen = blessed.screen({
var frames = require(__dirname + '/frames.json');
var timer = setInterval(function() {
if (!frames.length) {
clearInterval(timer);
return screen.destroy();
}
setInterval(function() {
if (!frames.length) return process.exit(0);
process.stdout.write(frames.shift());
}, 100);

View File

@ -94,41 +94,14 @@ var png = blessed.image({
screen.render();
screen.key('q', function() {
clearInterval(timeout);
screen.destroy();
process.exit(0);
});
var timeout = setInterval(function() {
if (png.right <= 0) {
clearInterval(timeout);
return;
}
png.left++;
screen.render();
}, 100);
if (timeout.unref) timeout.unref();
screen.key(['h', 'left'], function() {
png.left -= 2;
});
screen.key(['k', 'up'], function() {
png.top -= 2;
});
screen.key(['l', 'right'], function() {
png.left += 2;
});
screen.key(['j', 'down'], function() {
png.top += 2;
});
screen.on('keypress', function() {
clearInterval(timeout);
});
png.on('mousedown', function() {
clearInterval(timeout);
});

View File

@ -107,7 +107,7 @@ assert.equal(inner.rtop, 4);
screen.on('keypress', function(ch, key) {
if (key.name === 'escape' || key.name === 'q') {
return screen.destroy();
return process.exit(0);
}
});

View File

@ -69,7 +69,7 @@ prompt.input('Question?', '', function(err, value) {
loader.load('Loading...');
setTimeout(function() {
loader.stop();
screen.destroy();
process.exit(0);
}, 3000);
});
});
@ -77,7 +77,7 @@ prompt.input('Question?', '', function(err, value) {
});
screen.key('q', function() {
screen.destroy();
process.exit(0);
});
screen.render();

View File

@ -36,16 +36,18 @@ var text = blessed.scrollabletext({
text.focus();
var frames = [];
var timer = setInterval(function() {
frames.push(screen.screenshot());
}, 100);
screen.key('C-q', function() {
fs.writeFileSync(__dirname + '/frames.json', JSON.stringify(frames));
clearInterval(timer);
return screen.destroy();
screen.key('q', function() {
return process.exit(0);
});
screen.render();
var frames = [];
setInterval(function() {
frames.push(screen.screenshot());
}, 100);
process.on('exit', function() {
fs.writeFileSync(__dirname + '/frames.json', JSON.stringify(frames));
});

View File

@ -120,7 +120,7 @@ var box3 = blessed.box({
});
screen.key('q', function() {
return screen.destroy();
return process.exit(0);
});
box.focus();

View File

@ -75,7 +75,7 @@ over.key('down', function() {
over.focus();
screen.key('q', function() {
return screen.destroy();
return process.exit(0);
});
var lorem = 'Non eram nescius Brute cum quae summis ingeniis exquisitaque'

View File

@ -37,7 +37,7 @@ tab._.data = blessed.text({
tab._.data.setContent(require('util').inspect(process, null, 6));
screen.key('q', function() {
screen.destroy();
process.exit(0);
});
screen.render();

View File

@ -151,11 +151,11 @@ form._.submit.on('press', function() {
form.on('submit', function(data) {
screen.leave();
console.log(data);
screen.destroy();
process.exit(0);
});
screen.key('q', function() {
screen.destroy();
process.exit(0);
});
screen.render();

View File

@ -37,7 +37,7 @@ var inner = blessed.box({
});
screen.key('q', function() {
return screen.destroy();
return process.exit(0);
});
screen.render();

View File

@ -12,7 +12,7 @@ var DU = '杜';
var JUAN = '鹃';
var table = blessed.table({
//parent: screen,
parent: screen,
top: 'center',
left: 'center',
data: null,
@ -58,11 +58,10 @@ data2[1][0] = '{red-fg}' + data2[1][0] + '{/red-fg}';
data2[2][0] += ' (' + DU + JUAN + ')';
screen.key('q', function() {
return screen.destroy();
return process.exit(0);
});
table.setData(data2);
screen.append(table);
screen.render();
setTimeout(function() {

View File

@ -1,62 +0,0 @@
var blessed = require('../');
var screen = blessed.screen({
dump: __dirname + '/logs/termblessed.log',
smartCSR: true,
warnings: true
});
var terminal = blessed.terminal({
parent: screen,
// cursor: 'line',
cursorBlink: true,
screenKeys: false,
top: 'center',
left: 'center',
width: '90%',
height: '90%',
border: 'line',
handler: function() {},
style: {
fg: 'default',
bg: 'default',
focus: {
border: {
fg: 'green'
}
}
}
});
terminal.focus();
var term = terminal.term;
var screen2 = blessed.screen({
dump: __dirname + '/logs/termblessed2.log',
smartCSR: true,
warnings: true,
input: term,
output: term
});
var box1 = blessed.box({
parent: screen2,
top: 'center',
left: 'center',
width: 20,
height: 10,
border: 'line',
content: 'Hello world'
});
screen.key('C-q', function() {
// NOTE:
// not necessary since screen.destroy causes terminal.term to be destroyed
// (screen2's input and output are no longer readable/writable)
// screen2.destroy();
return screen.destroy();
});
screen2.render();
screen.render();

View File

@ -1,53 +0,0 @@
var blessed = require('../')
, screen;
screen = blessed.screen({
dump: __dirname + '/logs/termswitch.log',
smartCSR: true,
warnings: true
});
var lorem = require('fs').readFileSync(__dirname + '/git.diff', 'utf8');
var btext = blessed.box({
parent: screen,
left: 'center',
top: 'center',
width: '80%',
height: '80%',
style: {
bg: 'green'
},
border: 'line',
content: 'CSR should still work.'
});
var text = blessed.scrollabletext({
parent: screen,
content: lorem,
border: 'line',
left: 'center',
top: 'center',
draggable: true,
width: '50%',
height: '50%',
mouse: true,
keys: true,
vi: true
});
text.focus();
screen.key('q', function() {
return screen.destroy();
});
screen.render();
setTimeout(function() {
// screen.setTerminal('vt100');
screen.terminal = 'vt100';
screen.render();
text.setContent(screen.program._terminal);
screen.render();
}, 1000);

View File

@ -24,7 +24,7 @@ var box = blessed.textarea({
screen.render();
screen.key('q', function() {
screen.destroy();
process.exit(0);
});
screen.key('i', function() {

View File

@ -105,7 +105,7 @@ var main = blessed.box({
main.focus();
screen.key('q', function() {
return screen.destroy();
return process.exit(0);
});
screen.render();

View File

@ -22,7 +22,7 @@ var box = blessed.box({
});
screen.key('q', function() {
return screen.destroy();
return process.exit(0);
});
screen.render();

View File

@ -23,5 +23,5 @@ video.focus();
screen.render();
screen.key(['q', 'C-q', 'C-c'], function() {
screen.destroy();
process.exit(0);
});

View File

@ -30,11 +30,6 @@ screen.debugLog.on('show', function() {
screen.render();
});
screen.on('event', function(event, el) {
var type = (el && el.type) || Object.prototype.toString.call(el).slice(8, -1);
screen.program.log('emit("%s", {%s})', event, type);
});
screen.append(blessed.text({
top: 0,
left: 2,