Compare commits

...

79 Commits

Author SHA1 Message Date
Christopher Jeffrey (JJ)
eab243fc7a Merge pull request #214 from dbkaplun/strict-mode-fixes
strict mode fixes
2016-01-04 00:13:40 -08:00
Dan Kaplun
ba1982d4a9 Replace octal parseInt with hex literal 2016-01-04 02:50:49 -05:00
Dan Kaplun
62b439ef8e strict mode fixes 2016-01-03 18:32:58 -05:00
Christopher Jeffrey
1c20b8b2ee improve listtable. 2015-12-22 02:03:40 -08:00
Christopher Jeffrey
04ffa283ac unicode env vars. 2015-09-07 05:14:10 -07:00
Christopher Jeffrey
10edaa088b use telnet2 for example. 2015-09-02 18:48:05 -07:00
Christopher Jeffrey
a45575fee6 v0.1.81 2015-09-02 18:31:21 -07:00
Christopher Jeffrey
e4900bb037 add "event" for any event. fixes #171. 2015-08-31 20:50:10 -07:00
Christopher Jeffrey
793646955f stop image animation on destroy. improve test. 2015-08-25 20:49:59 -07:00
Christopher Jeffrey
7a1a979632 add test for blessed+term.js. see #168. 2015-08-18 03:30:31 -07:00
Christopher Jeffrey
05dcd84216 minor: reset error on tput. 2015-08-18 02:24:10 -07:00
Christopher Jeffrey
5ccc80d8b8 browserify: use xterm-256color. fix transform on windows. fixes #167. 2015-08-18 02:23:42 -07:00
Christopher Jeffrey
1ae8604964 always reset global instances. 2015-08-14 00:40:25 -07:00
Christopher Jeffrey
1b0d912814 ansi viewer image. 2015-08-11 17:05:47 -07:00
Christopher Jeffrey
5d5fa05d8e fix multiple screen finding. throw errors on edge cases. 2015-08-11 07:16:36 -07:00
Christopher Jeffrey
19f61aba7f clear screen text buffer on term switch. 2015-08-11 03:25:50 -07:00
Christopher Jeffrey
607dc29dbb check for parm_*_cursor terminfo on program.cu[udbf]. 2015-08-11 03:01:01 -07:00
Christopher Jeffrey
a1ddc1443c renderer: check for parm_right_cursor before using it. 2015-08-11 02:57:02 -07:00
Christopher Jeffrey
f1d16950c5 unicode: cleanup combining table. 2015-08-11 00:02:03 -07:00
Christopher Jeffrey
142b5e070d add .jshintrc and .jscsrc. 2015-08-10 22:58:33 -07:00
Christopher Jeffrey
a79e8106ea cleanup and fixes. 2015-08-10 22:57:01 -07:00
Christopher Jeffrey
5e143e7fe5 v0.1.80. see #165. 2015-08-10 10:48:26 -07:00
Christopher Jeffrey
b7c5f0f2f2 add screen.realloc() method. 2015-08-09 17:35:34 -07:00
Christopher Jeffrey
364a56f4dc v0.1.21 2015-08-09 03:25:03 -07:00
Christopher Jeffrey
e317355a5e update readme. 2015-08-09 03:20:53 -07:00
Christopher Jeffrey
2934ac6408 improve forceUnicode. 2015-08-09 03:20:41 -07:00
Christopher Jeffrey
c1670137ae enable full unicode for blessed-telnet example. 2015-08-09 03:14:03 -07:00
Christopher Jeffrey
20636913e5 blessed-telnet improvement. 2015-08-08 17:20:32 -07:00
Christopher Jeffrey
f6a19a57e9 always lowercase terminal name. debug messages for blessed-telnet. 2015-08-08 15:02:53 -07:00
Christopher Jeffrey
524a922880 fix default blessed-telnet test. 2015-08-08 05:04:06 -07:00
Christopher Jeffrey
802e4ddc48 refactor and improve blessed-telnet. 2015-08-07 21:07:55 -07:00
Christopher Jeffrey
29c9d1529a fix terminal element destroy. do not render if screen is destroyed. 2015-08-07 21:02:16 -07:00
Christopher Jeffrey
b54e86d361 call screen.destroy instead of process.exit in tests. 2015-08-07 21:00:31 -07:00
Christopher Jeffrey
7e0104ef42 blessed-telnet: termtype. 2015-08-06 03:33:00 -07:00
Christopher Jeffrey
d7933adfb0 blessed-telnet: handle env variables. 2015-08-06 03:27:18 -07:00
Christopher Jeffrey
a8b1764ec6 padding warning. 2015-08-06 01:50:17 -07:00
Christopher Jeffrey
216aaf1f48 fix NO_PADDING detection. 2015-08-06 00:35:22 -07:00
Christopher Jeffrey
0547509481 add a small Tput.print helper function. 2015-08-06 00:13:03 -07:00
Christopher Jeffrey
45b180174f disable * padding for now. 2015-08-06 00:03:59 -07:00
Christopher Jeffrey
64072411bb fix setTerminal. add termswitch test. 2015-08-05 23:54:48 -07:00
Christopher Jeffrey
9b5673edf7 automatically call setTerminal on terminal setter. 2015-08-05 23:30:07 -07:00
Christopher Jeffrey
3df75398a0 improve screen.setTerminal. 2015-08-05 21:27:08 -07:00
Christopher Jeffrey
210c33d076 add setTerminal(). use terminal option always for consistency. 2015-08-05 20:58:20 -07:00
Christopher Jeffrey
72586faef9 fix bigtext. whitespace. 2015-08-05 18:52:31 -07:00
Christopher Jeffrey (JJ)
41a354c571 Merge pull request #164 from anko/parse-tags-fix
Add failing test for helpers.parseTags
2015-08-05 18:35:09 -07:00
Christopher Jeffrey
e6a5b0cac9 lazily load Screen in helpers.js. fixes #164. 2015-08-05 17:59:18 -07:00
An Ko
ecf08f4ba7 Add failing test for helpers.parseTags
a4d56fb moved the function from here 99f9d622e6/lib/widget.js (L9607-L9610) to its own file, but didn't fill in any reference for the Screen variable.
2015-08-05 18:41:40 +02:00
Christopher Jeffrey
54430504d1 refactor screen finding. 2015-08-05 07:49:17 -07:00
Christopher Jeffrey
730dd59b39 set screen when appending a node. 2015-08-05 07:28:02 -07:00
Christopher Jeffrey
90c441a329 add multiple screen docs and telnet server example. 2015-08-05 07:22:06 -07:00
Christopher Jeffrey
b068a8d036 cleanup. 2015-08-05 05:06:07 -07:00
Christopher Jeffrey
0d86165122 ensure screen and program globals are reset. 2015-08-05 05:02:37 -07:00
Christopher Jeffrey
8007aa8ee7 automatically find screen if we are using multiple. 2015-08-05 05:00:14 -07:00
Christopher Jeffrey
a9fb228f23 add program.index. 2015-08-05 04:39:48 -07:00
Christopher Jeffrey
7351c8a716 set screen.index. 2015-08-05 04:34:18 -07:00
Christopher Jeffrey
86fb0582cc do not default to program.global. 2015-08-05 03:49:41 -07:00
Christopher Jeffrey
ee31799e7f use _owrite instead of output.write. 2015-08-05 03:27:24 -07:00
Christopher Jeffrey
2b26fe9952 minor: readme. 2015-08-02 01:57:00 -07:00
Christopher Jeffrey
aa23f346d9 readme. package. 2015-08-02 01:56:26 -07:00
Christopher Jeffrey
89afe613ad readme: remove blessed changes finally. 2015-07-31 20:49:41 -07:00
Christopher Jeffrey
5cb517e3f8 readme 2015-07-31 20:48:56 -07:00
Christopher Jeffrey
17f7d7bf31 readme: minor. 2015-07-31 02:17:34 -07:00
Christopher Jeffrey
fb2cc6a205 readme: screen options. 2015-07-31 02:14:38 -07:00
Christopher Jeffrey
8b81eb7299 v0.1.20 2015-07-31 00:15:24 -07:00
Christopher Jeffrey
af2a42423b remove backward compat tty helpers. 2015-07-31 00:09:46 -07:00
Christopher Jeffrey
b4fb673943 Revert "support node v0.6.x."
This reverts commit ce59050ded.
2015-07-31 00:09:01 -07:00
Christopher Jeffrey
ce59050ded support node v0.6.x. 2015-07-30 23:54:24 -07:00
Christopher Jeffrey
53f3d002b0 require node >=v0.8.0. 2015-07-30 23:53:37 -07:00
Christopher Jeffrey
be8ad38e6c check for setRawMode on spawn(). 2015-07-30 23:43:47 -07:00
Christopher Jeffrey
bdb3f098ca improve backward compat with node <=0.6.0. 2015-07-30 23:41:20 -07:00
Christopher Jeffrey
29f70f11f9 v0.1.19 2015-07-30 23:08:47 -07:00
Christopher Jeffrey
103ce24787 helpers to potentially support node <=0.6.0. 2015-07-30 23:07:23 -07:00
Christopher Jeffrey
b0d0063b1c support node <=0.8.0. 2015-07-30 22:55:05 -07:00
Christopher Jeffrey
33db6f4a31 v0.1.18 2015-07-30 20:38:00 -07:00
Christopher Jeffrey
3ff6c4e5fb fix property name collision if input/output is a socket. 2015-07-30 18:17:58 -07:00
Christopher Jeffrey
fe1f470995 allow focusing of detached children still. 2015-07-30 17:58:30 -07:00
Christopher Jeffrey
22469380e2 fix focus error. fix table setData error. fixes #160. 2015-07-30 17:55:40 -07:00
Christopher Jeffrey
ad3a5ae7f9 v0.1.17 2015-07-30 05:08:26 -07:00
Christopher Jeffrey
dc95fc6e3c fix terminal element clearing. 2015-07-30 05:08:04 -07:00
90 changed files with 1189 additions and 592 deletions

15
.jscsrc Normal file
View File

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

41
.jshintrc Normal file
View File

@ -0,0 +1,41 @@
{
"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,3 +2,5 @@
test/ test/
img/ img/
node_modules/ node_modules/
.jshintrc
.jscsrc

147
README.md
View File

@ -30,16 +30,6 @@ Blessed has been used to implement other popular libraries and programs.
Examples include: the [slap text editor][slap] and [blessed-contrib][contrib]. Examples include: the [slap text editor][slap] and [blessed-contrib][contrib].
The blessed API itself has gone on to inspire [termui][termui] for Go. 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 ## Install
``` bash ``` bash
@ -52,17 +42,14 @@ This will render a box with line borders containing the text `'Hello world!'`,
perfectly centered horizontally and vertically. perfectly centered horizontally and vertically.
__NOTE__: It is recommend you use either `smartCSR` or `fastCSR` as a __NOTE__: It is recommend you use either `smartCSR` or `fastCSR` as a
`blessed.screen` option. `autoPadding` is also recommended; it will `blessed.screen` option. This will enable CSR when scrolling text in elements
automatically offset box content within borders instead of on top of them when or when manipulating lines.
coords are `0`. Non-`autoPadding` _may_ be deprecated in the future. See the
API documentation for further explanation of these options.
``` js ``` js
var blessed = require('blessed'); var blessed = require('blessed');
// Create a screen object. // Create a screen object.
var screen = blessed.screen({ var screen = blessed.screen({
autoPadding: true,
smartCSR: true smartCSR: true
}); });
@ -201,6 +188,8 @@ screen.render();
- [Poisitioning](#positioning) - [Poisitioning](#positioning)
- [Rendering](#rendering) - [Rendering](#rendering)
- [Artificial Cursors](#artificial-cursors) - [Artificial Cursors](#artificial-cursors)
- [Multiple Screens](#multiple-screens)
- [Server Side Usage](#server-side-usage)
### Notes ### Notes
@ -340,7 +329,14 @@ The screen on which every other node renders.
- __warnings__ - Display warnings (such as the output not being a TTY, similar - __warnings__ - Display warnings (such as the output not being a TTY, similar
to ncurses). to ncurses).
- __forceUnicode__ - Force blessed to use unicode even if it is not detected - __forceUnicode__ - Force blessed to use unicode even if it is not detected
via terminfo, env variables, or windows code page. 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: ##### Properties:
@ -364,6 +360,8 @@ The screen on which every other node renders.
- __grabKeys__ - Whether the focused element grabs all keypresses. - __grabKeys__ - Whether the focused element grabs all keypresses.
- __lockKeys__ - Prevent keypresses from being received by any element. - __lockKeys__ - Prevent keypresses from being received by any element.
- __hover__ - The currently hovered element. Only set if mouse events are bound. - __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. - __title__ - Set or get window title.
##### Events: ##### Events:
@ -392,6 +390,7 @@ The screen on which every other node renders.
`debug` option was set. `debug` option was set.
- __alloc()__ - Allocate a new pending screen buffer and a new output screen - __alloc()__ - Allocate a new pending screen buffer and a new output screen
buffer. buffer.
- __realloc()__ - Reallocate the screen buffers and clear the screen.
- __draw(start, end)__ - Draw the screen based on the contents of the screen - __draw(start, end)__ - Draw the screen based on the contents of the screen
buffer. buffer.
- __render()__ - Render all child elements, writing all data to the screen - __render()__ - Render all child elements, writing all data to the screen
@ -445,9 +444,10 @@ The screen on which every other node renders.
within the region. Returns a string containing only characters and SGR codes. within the region. Returns a string containing only characters and SGR codes.
Can be displayed by simply echoing it in a terminal. Can be displayed by simply echoing it in a terminal.
- __destroy()__ - Destroy the screen object and remove it from the global list. - __destroy()__ - Destroy the screen object and remove it from the global list.
Only useful if using multiple screens. Also remove all global events relevant to the screen object. If all screen
- __program.destroy()__ - Destroy the program object and remove it from the objects are destroyed, the node process is essentially reset to its initial
global list. Only useful if using multiple programs. state.
- __setTerminal(term)__ - Reset the terminal to `term`. Reloads terminfo.
#### Element (from Node) #### Element (from Node)
@ -1382,7 +1382,7 @@ manager. Requires term.js and pty.js to be installed. See
- __shell__ - Name of shell. `$SHELL` by default. - __shell__ - Name of shell. `$SHELL` by default.
- __args__ - Args for shell. - __args__ - Args for shell.
- __cursor__ - Can be `line`, `underline`, and `block`. - __cursor__ - Can be `line`, `underline`, and `block`.
- __term__ - Terminal name (Default: `xterm`). - __terminal__ - Terminal name (Default: `xterm`).
- __env__ - Object for process env. - __env__ - Object for process env.
- Other options similar to term.js'. - Other options similar to term.js'.
@ -2127,6 +2127,111 @@ 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 ### Notes
@ -2139,7 +2244,7 @@ Windows users will need to explicitly set `term` when creating a screen like so
This is now handled automatically): This is now handled automatically):
``` js ``` js
var screen = blessed.screen({ term: 'windows-ansi' }); var screen = blessed.screen({ terminal: 'windows-ansi' });
``` ```

View File

@ -43,7 +43,7 @@ var requireWidgets = widgets.reduce(function(out, name) {
* terminfo or termcap, just use xterm terminfo/cap. * terminfo or termcap, just use xterm terminfo/cap.
*/ */
var infoPath = path.resolve(__dirname, '..', 'usr', 'xterm') var infoPath = path.resolve(__dirname, '..', 'usr', 'xterm-256color')
, capPath = path.resolve(__dirname, '..', 'usr', 'xterm.termcap'); , capPath = path.resolve(__dirname, '..', 'usr', 'xterm.termcap');
var infoPathFake = path.resolve( var infoPathFake = path.resolve(
@ -87,7 +87,7 @@ readMethods = readMethods.toString().slice(24, -2)
*/ */
function end(file, offset) { function end(file, offset) {
return file.split(path.sep).slice(offset).join(path.sep); return file.split(path.sep).slice(-offset).join('/');
} }
/** /**
@ -95,10 +95,10 @@ function end(file, offset) {
*/ */
module.exports = function(file) { module.exports = function(file) {
if (end(file, -2) === 'lib/widget.js') { if (end(file, 2) === 'lib/widget.js') {
return transformer(requireWidgets); return transformer(requireWidgets);
} }
if (end(file, -2) === 'lib/tput.js') { if (end(file, 2) === 'lib/tput.js') {
return transformer(readMethods); return transformer(readMethods);
} }
return transformer(); return transformer();

99
example/blessed-telnet.js Executable file
View File

@ -0,0 +1,99 @@
#!/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,7 +127,11 @@ var bottomright = blessed.terminal({
topleft.focus(); topleft.focus();
screen.key('C-q', function() { screen.key('C-q', function() {
return process.exit(0); topleft.kill();
topright.kill();
bottomleft.kill();
bottomright.kill();
return screen.destroy();
}); });
screen.program.key('S-tab', function() { screen.program.key('S-tab', function() {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -66,11 +66,13 @@ function Program(options) {
this.scrollTop = 0; this.scrollTop = 0;
this.scrollBottom = this.rows - 1; this.scrollBottom = this.rows - 1;
this.terminal = options.term this._terminal = options.terminal
|| options.terminal || options.term
|| process.env.TERM || process.env.TERM
|| (process.platform === 'win32' ? 'windows-ansi' : 'xterm'); || (process.platform === 'win32' ? 'windows-ansi' : 'xterm');
this._terminal = this._terminal.toLowerCase();
// OSX // OSX
this.isOSXTerm = process.env.TERM_PROGRAM === 'Apple_Terminal'; this.isOSXTerm = process.env.TERM_PROGRAM === 'Apple_Terminal';
this.isiTerm2 = process.env.TERM_PROGRAM === 'iTerm.app' this.isiTerm2 = process.env.TERM_PROGRAM === 'iTerm.app'
@ -126,6 +128,7 @@ Program.bind = function(program) {
if (!~Program.instances.indexOf(program)) { if (!~Program.instances.indexOf(program)) {
Program.instances.push(program); Program.instances.push(program);
program.index = Program.total;
Program.total++; Program.total++;
} }
@ -192,7 +195,7 @@ Program.prototype.setupDump = function() {
return data.replace(/[\0\x80\x1b-\x1f\x7f\x01-\x1a]/g, function(ch) { return data.replace(/[\0\x80\x1b-\x1f\x7f\x01-\x1a]/g, function(ch) {
switch (ch) { switch (ch) {
case '\0': case '\0':
case '\200': case '\x80':
ch = '@'; ch = '@';
break; break;
case '\x1b': case '\x1b':
@ -243,10 +246,10 @@ Program.prototype.setupTput = function() {
var self = this var self = this
, options = this.options , options = this.options
, write = this.write.bind(this); , write = this._write.bind(this);
var tput = this.tput = new Tput({ var tput = this.tput = new Tput({
term: this.terminal, terminal: this.terminal,
padding: options.padding, padding: options.padding,
extended: options.extended, extended: options.extended,
printf: options.printf, printf: options.printf,
@ -260,6 +263,12 @@ Program.prototype.setupTput = function() {
}); });
} }
if (tput.padding) {
nextTick(function() {
self.emit('warning', 'Terminfo padding has been enabled.');
});
}
this.put = function() { this.put = function() {
var args = slice.call(arguments) var args = slice.call(arguments)
, cap = args.shift(); , cap = args.shift();
@ -279,7 +288,7 @@ Program.prototype.setupTput = function() {
return; return;
} }
if (options.padding) { if (tput.padding) {
self.put[key] = function() { self.put[key] = function() {
return tput._print(tput[key].apply(tput, arguments), write); return tput._print(tput[key].apply(tput, arguments), write);
}; };
@ -291,6 +300,21 @@ 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) { Program.prototype.has = function(name) {
return this.tput return this.tput
? this.tput.has(name) ? this.tput.has(name)
@ -314,11 +338,11 @@ Program.prototype.listen = function() {
// } // }
// Listen for keys/mouse on input // Listen for keys/mouse on input
if (!this.input._blessedListened) { if (!this.input._blessedInput) {
this.input._blessedListened = 1; this.input._blessedInput = 1;
this._listenInput(); this._listenInput();
} else { } else {
this.input._blessedListened++; this.input._blessedInput++;
} }
this.on('newListener', this._newHandler = function fn(type) { this.on('newListener', this._newHandler = function fn(type) {
@ -339,11 +363,11 @@ Program.prototype.listen = function() {
}); });
// Listen for resize on output // Listen for resize on output
if (!this.output._blessedListened) { if (!this.output._blessedOutput) {
this.output._blessedListened = 1; this.output._blessedOutput = 1;
this._listenOutput(); this._listenOutput();
} else { } else {
this.output._blessedListened++; this.output._blessedOutput++;
} }
}; };
@ -445,6 +469,8 @@ Program.prototype.destroy = function() {
this.flush(); this.flush();
this._exiting = true; this._exiting = true;
Program.global = Program.instances[0];
if (Program.total === 0) { if (Program.total === 0) {
Program.global = null; Program.global = null;
@ -454,10 +480,10 @@ Program.prototype.destroy = function() {
delete Program._bound; delete Program._bound;
} }
this.input._blessedListened--; this.input._blessedInput--;
this.output._blessedListened--; this.output._blessedOutput--;
if (this.input._blessedListened === 0) { if (this.input._blessedInput === 0) {
this.input.removeListener('keypress', this.input._keypressHandler); this.input.removeListener('keypress', this.input._keypressHandler);
this.input.removeListener('data', this.input._dataHandler); this.input.removeListener('data', this.input._dataHandler);
delete this.input._keypressHandler; delete this.input._keypressHandler;
@ -473,7 +499,7 @@ Program.prototype.destroy = function() {
} }
} }
if (this.output._blessedListened === 0) { if (this.output._blessedOutput === 0) {
this.output.removeListener('resize', this.output._resizeHandler); this.output.removeListener('resize', this.output._resizeHandler);
delete this.output._resizeHandler; delete this.output._resizeHandler;
} }
@ -544,7 +570,15 @@ Program.prototype.bindMouse = function() {
Program.prototype._bindMouse = function(s, buf) { Program.prototype._bindMouse = function(s, buf) {
var self = this var self = this
, key , key
, parts; , parts
, b
, x
, y
, mod
, params
, down
, page
, button;
key = { key = {
name: undefined, name: undefined,
@ -588,9 +622,9 @@ Program.prototype._bindMouse = function(s, buf) {
|| (by > 0x00 && by < 0x20) || (by > 0x00 && by < 0x20)
|| (buf[4] > 223 && buf[4] < 248 && buf.length === 6) || (buf[4] > 223 && buf[4] < 248 && buf.length === 6)
|| (buf[5] > 223 && buf[5] < 248 && buf.length === 6))) { || (buf[5] > 223 && buf[5] < 248 && buf.length === 6))) {
var b = buf[3] b = buf[3];
, x = buf[4] x = buf[4];
, y = buf[5]; y = buf[5];
// unsigned char overflow. // unsigned char overflow.
if (x < 0x20) x += 0xff; if (x < 0x20) x += 0xff;
@ -606,10 +640,9 @@ Program.prototype._bindMouse = function(s, buf) {
// XTerm / X10 // XTerm / X10
if (parts = /^\x1b\[M([\x00\u0020-\uffff]{3})/.exec(s)) { if (parts = /^\x1b\[M([\x00\u0020-\uffff]{3})/.exec(s)) {
var b = parts[1].charCodeAt(0) b = parts[1].charCodeAt(0);
, x = parts[1].charCodeAt(1) x = parts[1].charCodeAt(1);
, y = parts[1].charCodeAt(2) y = parts[1].charCodeAt(2);
, mod;
key.name = 'mouse'; key.name = 'mouse';
key.type = 'X10'; key.type = 'X10';
@ -642,7 +675,7 @@ Program.prototype._bindMouse = function(s, buf) {
delete this._lastButton; delete this._lastButton;
} else { } else {
key.action = 'mousedown'; key.action = 'mousedown';
var button = b & 3; button = b & 3;
key.button = key.button =
button === 0 ? 'left' button === 0 ? 'left'
: button === 1 ? 'middle' : button === 1 ? 'middle'
@ -674,10 +707,10 @@ Program.prototype._bindMouse = function(s, buf) {
// URxvt // URxvt
if (parts = /^\x1b\[(\d+;\d+;\d+)M/.exec(s)) { if (parts = /^\x1b\[(\d+;\d+;\d+)M/.exec(s)) {
var params = parts[1].split(';') params = parts[1].split(';');
, b = +params[0] b = +params[0];
, x = +params[1] x = +params[1];
, y = +params[2]; y = +params[2];
key.name = 'mouse'; key.name = 'mouse';
key.type = 'urxvt'; key.type = 'urxvt';
@ -714,7 +747,7 @@ Program.prototype._bindMouse = function(s, buf) {
delete this._lastButton; delete this._lastButton;
} else { } else {
key.action = 'mousedown'; key.action = 'mousedown';
var button = b & 3; button = b & 3;
key.button = key.button =
button === 0 ? 'left' button === 0 ? 'left'
: button === 1 ? 'middle' : button === 1 ? 'middle'
@ -747,11 +780,11 @@ Program.prototype._bindMouse = function(s, buf) {
// SGR // SGR
if (parts = /^\x1b\[<(\d+;\d+;\d+)([mM])/.exec(s)) { if (parts = /^\x1b\[<(\d+;\d+;\d+)([mM])/.exec(s)) {
var down = parts[2] === 'M' down = parts[2] === 'M';
, params = parts[1].split(';') params = parts[1].split(';');
, b = +params[0] b = +params[0];
, x = +params[1] x = +params[1];
, y = +params[2]; y = +params[2];
key.name = 'mouse'; key.name = 'mouse';
key.type = 'sgr'; key.type = 'sgr';
@ -775,7 +808,7 @@ Program.prototype._bindMouse = function(s, buf) {
key.action = down key.action = down
? 'mousedown' ? 'mousedown'
: 'mouseup'; : 'mouseup';
var button = b & 3; button = b & 3;
key.button = key.button =
button === 0 ? 'left' button === 0 ? 'left'
: button === 1 ? 'middle' : button === 1 ? 'middle'
@ -807,11 +840,11 @@ Program.prototype._bindMouse = function(s, buf) {
// The xterm mouse documentation says there is a // The xterm mouse documentation says there is a
// `<` prefix, the DECRQLP says there is no prefix. // `<` prefix, the DECRQLP says there is no prefix.
if (parts = /^\x1b\[<(\d+;\d+;\d+;\d+)&w/.exec(s)) { if (parts = /^\x1b\[<(\d+;\d+;\d+;\d+)&w/.exec(s)) {
var params = parts[1].split(';') params = parts[1].split(';');
, b = +params[0] b = +params[0];
, x = +params[1] x = +params[1];
, y = +params[2] y = +params[2];
, page = +params[3]; page = +params[3];
key.name = 'mouse'; key.name = 'mouse';
key.type = 'dec'; key.type = 'dec';
@ -820,6 +853,7 @@ Program.prototype._bindMouse = function(s, buf) {
key.buf = buf; key.buf = buf;
key.x = x; key.x = x;
key.y = y; key.y = y;
key.page = page;
if (this.zero) key.x--, key.y--; if (this.zero) key.x--, key.y--;
@ -840,9 +874,9 @@ Program.prototype._bindMouse = function(s, buf) {
// vt300 // vt300
if (parts = /^\x1b\[24([0135])~\[(\d+),(\d+)\]\r/.exec(s)) { if (parts = /^\x1b\[24([0135])~\[(\d+),(\d+)\]\r/.exec(s)) {
var b = +parts[1] b = +parts[1];
, x = +parts[2] x = +parts[2];
, y = +parts[3]; y = +parts[3];
key.name = 'mouse'; key.name = 'mouse';
key.type = 'vt300'; key.type = 'vt300';
@ -881,7 +915,7 @@ Program.prototype._bindMouse = function(s, buf) {
// gpm support for linux vc // gpm support for linux vc
Program.prototype.enableGpm = function() { Program.prototype.enableGpm = function() {
var self = this; var self = this;
var gpmclient = require('./gpmclient') var gpmclient = require('./gpmclient');
if (this.gpm) return; if (this.gpm) return;
@ -1004,8 +1038,7 @@ Program.prototype.bindResponse = function() {
}; };
Program.prototype._bindResponse = function(s) { Program.prototype._bindResponse = function(s) {
var self = this var out = {}
, out = {}
, parts; , parts;
if (Buffer.isBuffer(s)) { if (Buffer.isBuffer(s)) {
@ -1291,7 +1324,7 @@ Program.prototype._bindResponse = function(s) {
out.type = 'window-state'; out.type = 'window-state';
out.state = parts[1] === '1' out.state = parts[1] === '1'
? 'non-iconified' ? 'non-iconified'
: 'iconified' : 'iconified';
// LEGACY // LEGACY
out.windowState = out.state; out.windowState = out.state;
@ -1596,10 +1629,16 @@ Program.prototype.response = function(name, text, callback, noBypass) {
: this._twrite(text); : 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) { Program.prototype._buffer = function(text) {
if (this._exiting) { if (this._exiting) {
this.flush(); this.flush();
this.output.write(text); this._owrite(text);
return; return;
} }
@ -1615,9 +1654,9 @@ Program.prototype._buffer = function(text) {
return true; return true;
}; };
Program.prototype.flush = function(text) { Program.prototype.flush = function() {
if (!this._buf) return; if (!this._buf) return;
this.output.write(this._buf); this._owrite(this._buf);
this._buf = ''; this._buf = '';
}; };
@ -1626,7 +1665,7 @@ Program.prototype._write = function(text) {
if (this.useBuffer) { if (this.useBuffer) {
return this._buffer(text); return this._buffer(text);
} }
return this.output.write(text); return this._owrite(text);
}; };
// Example: `DCS tmux; ESC Pt ST` // Example: `DCS tmux; ESC Pt ST`
@ -1650,7 +1689,7 @@ Program.prototype._twrite = function(data) {
if (self.output.bytesWritten > 0 || ++iterations === 50) { if (self.output.bytesWritten > 0 || ++iterations === 50) {
clearInterval(timer); clearInterval(timer);
self.flush(); self.flush();
self.output.write(data); self._owrite(data);
} }
}, 100); }, 100);
return true; return true;
@ -1661,14 +1700,14 @@ Program.prototype._twrite = function(data) {
this.flush(); this.flush();
// Write out raw now that the buffer is flushed. // Write out raw now that the buffer is flushed.
return this.output.write(data); return this._owrite(data);
} }
return this._write(data); return this._write(data);
}; };
Program.prototype.echo = Program.prototype.echo =
Program.prototype.write = function(text, attr) { Program.prototype.print = function(text, attr) {
return attr return attr
? this._write(this.text(text, attr)) ? this._write(this.text(text, attr))
: this._write(text); : this._write(text);
@ -1750,7 +1789,7 @@ Program.prototype.simpleInsert = function(ch, i, attr) {
}; };
Program.prototype.repeat = function(ch, i) { Program.prototype.repeat = function(ch, i) {
if (!(i >= 0)) i = 0; if (!i || i < 0) i = 0;
return Array(i + 1).join(ch); return Array(i + 1).join(ch);
}; };
@ -1872,7 +1911,7 @@ Program.prototype.getCursorColor = function(callback) {
//Program.prototype.pad = //Program.prototype.pad =
Program.prototype.nul = function() { Program.prototype.nul = function() {
//if (this.has('pad')) return this.put.pad(); //if (this.has('pad')) return this.put.pad();
return this._write('\200'); return this._write('\x80');
}; };
Program.prototype.bel = Program.prototype.bel =
@ -2010,7 +2049,7 @@ Program.prototype.restoreCursor = function(key, hide) {
// Save Cursor Locally // Save Cursor Locally
Program.prototype.lsaveCursor = function(key) { Program.prototype.lsaveCursor = function(key) {
var key = key || 'local'; key = key || 'local';
this._saved = this._saved || {}; this._saved = this._saved || {};
this._saved[key] = this._saved[key] || {}; this._saved[key] = this._saved[key] || {};
this._saved[key].x = this.x; this._saved[key].x = this.x;
@ -2020,7 +2059,8 @@ Program.prototype.lsaveCursor = function(key) {
// Restore Cursor Locally // Restore Cursor Locally
Program.prototype.lrestoreCursor = function(key, hide) { Program.prototype.lrestoreCursor = function(key, hide) {
var key = key || 'local', pos; var pos;
key = key || 'local';
if (!this._saved || !this._saved[key]) return; if (!this._saved || !this._saved[key]) return;
pos = this._saved[key]; pos = this._saved[key];
//delete this._saved[key]; //delete this._saved[key];
@ -2241,7 +2281,12 @@ Program.prototype.up =
Program.prototype.cursorUp = function(param) { Program.prototype.cursorUp = function(param) {
this.y -= param || 1; this.y -= param || 1;
this._ncoords(); this._ncoords();
if (this.tput) return this.put.cuu(param); if (this.tput) {
if (!this.tput.strings.parm_up_cursor) {
return this._write(this.repeat(this.tput.cuu1(), param));
}
return this.put.cuu(param);
}
return this._write('\x1b[' + (param || '') + 'A'); return this._write('\x1b[' + (param || '') + 'A');
}; };
@ -2252,7 +2297,12 @@ Program.prototype.down =
Program.prototype.cursorDown = function(param) { Program.prototype.cursorDown = function(param) {
this.y += param || 1; this.y += param || 1;
this._ncoords(); this._ncoords();
if (this.tput) return this.put.cud(param); if (this.tput) {
if (!this.tput.strings.parm_down_cursor) {
return this._write(this.repeat(this.tput.cud1(), param));
}
return this.put.cud(param);
}
return this._write('\x1b[' + (param || '') + 'B'); return this._write('\x1b[' + (param || '') + 'B');
}; };
@ -2264,7 +2314,12 @@ Program.prototype.forward =
Program.prototype.cursorForward = function(param) { Program.prototype.cursorForward = function(param) {
this.x += param || 1; this.x += param || 1;
this._ncoords(); this._ncoords();
if (this.tput) return this.put.cuf(param); if (this.tput) {
if (!this.tput.strings.parm_right_cursor) {
return this._write(this.repeat(this.tput.cuf1(), param));
}
return this.put.cuf(param);
}
return this._write('\x1b[' + (param || '') + 'C'); return this._write('\x1b[' + (param || '') + 'C');
}; };
@ -2276,7 +2331,12 @@ Program.prototype.back =
Program.prototype.cursorBackward = function(param) { Program.prototype.cursorBackward = function(param) {
this.x -= param || 1; this.x -= param || 1;
this._ncoords(); this._ncoords();
if (this.tput) return this.put.cub(param); if (this.tput) {
if (!this.tput.strings.parm_left_cursor) {
return this._write(this.repeat(this.tput.cub1(), param));
}
return this.put.cub(param);
}
return this._write('\x1b[' + (param || '') + 'D'); return this._write('\x1b[' + (param || '') + 'D');
}; };
@ -2463,7 +2523,6 @@ Program.prototype.text = function(text, attr) {
// NOTE: sun-color may not allow multiple params for SGR. // NOTE: sun-color may not allow multiple params for SGR.
Program.prototype._attr = function(param, val) { Program.prototype._attr = function(param, val) {
var self = this var self = this
, param
, parts , parts
, color , color
, m; , m;
@ -2523,7 +2582,6 @@ Program.prototype._attr = function(param, val) {
return val === false return val === false
? '\x1b[27m' ? '\x1b[27m'
: '\x1b[7m'; : '\x1b[7m';
break;
case 'invisible': case 'invisible':
return val === false return val === false
? '\x1b[28m' ? '\x1b[28m'
@ -2918,7 +2976,7 @@ Program.prototype.charPosAbsolute = function(param) {
if (this.tput) { if (this.tput) {
return this.put.hpa.apply(this.put, arguments); return this.put.hpa.apply(this.put, arguments);
} }
var param = slice.call(arguments).join(';'); param = slice.call(arguments).join(';');
return this._write('\x1b[' + (param || '') + '`'); return this._write('\x1b[' + (param || '') + '`');
}; };
@ -2927,11 +2985,11 @@ Program.prototype.charPosAbsolute = function(param) {
// reuse CSI Ps C ? // reuse CSI Ps C ?
Program.prototype.hpr = Program.prototype.hpr =
Program.prototype.HPositionRelative = function(param) { Program.prototype.HPositionRelative = function(param) {
if (this.tput) return this.cuf(param);
this.x += param || 1; this.x += param || 1;
this._ncoords(); this._ncoords();
// Does not exist: // Does not exist:
// if (this.tput) return this.put.hpr(param); // if (this.tput) return this.put.hpr(param);
if (this.tput) return this.put.cuf(param);
return this._write('\x1b[' + (param || '') + 'a'); return this._write('\x1b[' + (param || '') + 'a');
}; };
@ -2986,7 +3044,7 @@ Program.prototype.linePosAbsolute = function(param) {
if (this.tput) { if (this.tput) {
return this.put.vpa.apply(this.put, arguments); return this.put.vpa.apply(this.put, arguments);
} }
var param = slice.call(arguments).join(';'); param = slice.call(arguments).join(';');
return this._write('\x1b[' + (param || '') + 'd'); return this._write('\x1b[' + (param || '') + 'd');
}; };
@ -2994,11 +3052,11 @@ Program.prototype.linePosAbsolute = function(param) {
// reuse CSI Ps B ? // reuse CSI Ps B ?
Program.prototype.vpr = Program.prototype.vpr =
Program.prototype.VPositionRelative = function(param) { Program.prototype.VPositionRelative = function(param) {
if (this.tput) return this.cud(param);
this.y += param || 1; this.y += param || 1;
this._ncoords(); this._ncoords();
// Does not exist: // Does not exist:
// if (this.tput) return this.put.vpr(param); // if (this.tput) return this.put.vpr(param);
if (this.tput) return this.put.cud(param);
return this._write('\x1b[' + (param || '') + 'e'); return this._write('\x1b[' + (param || '') + 'e');
}; };
@ -3852,7 +3910,7 @@ Program.prototype.setAttrInRectangle = function() {
// CSI ? Pm s // CSI ? Pm s
// Save DEC Private Mode Values. Ps values are the same as for // Save DEC Private Mode Values. Ps values are the same as for
// DECSET. // DECSET.
Program.prototype.savePrivateValues = function(params) { Program.prototype.savePrivateValues = function() {
return this._write('\x1b[?' + slice.call(arguments).join(';') + 's'); return this._write('\x1b[?' + slice.call(arguments).join(';') + 's');
}; };
@ -3924,7 +3982,7 @@ Program.prototype.getWindowSize = function(callback) {
// Ps denotes the attributes to reverse, i.e., 1, 4, 5, 7. // Ps denotes the attributes to reverse, i.e., 1, 4, 5, 7.
// NOTE: xterm doesn't enable this code by default. // NOTE: xterm doesn't enable this code by default.
Program.prototype.decrara = Program.prototype.decrara =
Program.prototype.reverseAttrInRectangle = function(params) { Program.prototype.reverseAttrInRectangle = function() {
return this._write('\x1b[' + slice.call(arguments).join(';') + '$t'); return this._write('\x1b[' + slice.call(arguments).join(';') + '$t');
}; };
@ -3937,7 +3995,7 @@ Program.prototype.reverseAttrInRectangle = function(params) {
// Ps = 3 -> Query window/icon labels using UTF-8. (See dis- // Ps = 3 -> Query window/icon labels using UTF-8. (See dis-
// cussion of "Title Modes") // cussion of "Title Modes")
// XXX VTE bizarelly echos this: // XXX VTE bizarelly echos this:
Program.prototype.setTitleModeFeature = function(params) { Program.prototype.setTitleModeFeature = function() {
return this._twrite('\x1b[>' + slice.call(arguments).join(';') + 't'); return this._twrite('\x1b[>' + slice.call(arguments).join(';') + 't');
}; };
@ -3947,7 +4005,7 @@ Program.prototype.setTitleModeFeature = function(params) {
// Ps = 2 , 3 or 4 -> low. // Ps = 2 , 3 or 4 -> low.
// Ps = 5 , 6 , 7 , or 8 -> high. // Ps = 5 , 6 , 7 , or 8 -> high.
Program.prototype.decswbv = Program.prototype.decswbv =
Program.prototype.setWarningBellVolume = function(params) { Program.prototype.setWarningBellVolume = function(param) {
return this._write('\x1b[' + (param || '') + ' t'); return this._write('\x1b[' + (param || '') + ' t');
}; };
@ -3957,7 +4015,7 @@ Program.prototype.setWarningBellVolume = function(params) {
// Ps = 2 , 3 or 4 -> low. // Ps = 2 , 3 or 4 -> low.
// Ps = 0 , 5 , 6 , 7 , or 8 -> high. // Ps = 0 , 5 , 6 , 7 , or 8 -> high.
Program.prototype.decsmbv = Program.prototype.decsmbv =
Program.prototype.setMarginBellVolume = function(params) { Program.prototype.setMarginBellVolume = function(param) {
return this._write('\x1b[' + (param || '') + ' u'); return this._write('\x1b[' + (param || '') + ' u');
}; };
@ -3969,7 +4027,7 @@ Program.prototype.setMarginBellVolume = function(params) {
// Pp denotes the target page. // Pp denotes the target page.
// NOTE: xterm doesn't enable this code by default. // NOTE: xterm doesn't enable this code by default.
Program.prototype.deccra = Program.prototype.deccra =
Program.prototype.copyRectangle = function(params) { Program.prototype.copyRectangle = function() {
return this._write('\x1b[' + slice.call(arguments).join(';') + '$v'); return this._write('\x1b[' + slice.call(arguments).join(';') + '$v');
}; };
@ -3985,7 +4043,7 @@ Program.prototype.copyRectangle = function(params) {
// ted, any locator motion will be reported. DECELR always can- // ted, any locator motion will be reported. DECELR always can-
// cels any prevous rectangle definition. // cels any prevous rectangle definition.
Program.prototype.decefr = Program.prototype.decefr =
Program.prototype.enableFilterRectangle = function(params) { Program.prototype.enableFilterRectangle = function() {
return this._write('\x1b[' + slice.call(arguments).join(';') + '\'w'); return this._write('\x1b[' + slice.call(arguments).join(';') + '\'w');
}; };
@ -4001,7 +4059,7 @@ Program.prototype.enableFilterRectangle = function(params) {
// Pn = 1 <- clock multiplier. // Pn = 1 <- clock multiplier.
// Pn = 0 <- STP flags. // Pn = 0 <- STP flags.
Program.prototype.decreqtparm = Program.prototype.decreqtparm =
Program.prototype.requestParameters = function(params) { Program.prototype.requestParameters = function(param) {
return this._write('\x1b[' + (param || 0) + 'x'); return this._write('\x1b[' + (param || 0) + 'x');
}; };
@ -4010,7 +4068,7 @@ Program.prototype.requestParameters = function(params) {
// Ps = 1 -> from start to end position, wrapped. // Ps = 1 -> from start to end position, wrapped.
// Ps = 2 -> rectangle (exact). // Ps = 2 -> rectangle (exact).
Program.prototype.decsace = Program.prototype.decsace =
Program.prototype.selectChangeExtent = function(params) { Program.prototype.selectChangeExtent = function(param) {
return this._write('\x1b[' + (param || 0) + 'x'); return this._write('\x1b[' + (param || 0) + 'x');
}; };
@ -4020,7 +4078,7 @@ Program.prototype.selectChangeExtent = function(params) {
// Pt; Pl; Pb; Pr denotes the rectangle. // Pt; Pl; Pb; Pr denotes the rectangle.
// NOTE: xterm doesn't enable this code by default. // NOTE: xterm doesn't enable this code by default.
Program.prototype.decfra = Program.prototype.decfra =
Program.prototype.fillRectangle = function(params) { Program.prototype.fillRectangle = function() {
return this._write('\x1b[' + slice.call(arguments).join(';') + '$x'); return this._write('\x1b[' + slice.call(arguments).join(';') + '$x');
}; };
@ -4037,7 +4095,7 @@ Program.prototype.fillRectangle = function(params) {
// Pu = 1 <- device physical pixels. // Pu = 1 <- device physical pixels.
// Pu = 2 <- character cells. // Pu = 2 <- character cells.
Program.prototype.decelr = Program.prototype.decelr =
Program.prototype.enableLocatorReporting = function(params) { Program.prototype.enableLocatorReporting = function() {
return this._write('\x1b[' + slice.call(arguments).join(';') + '\'z'); return this._write('\x1b[' + slice.call(arguments).join(';') + '\'z');
}; };
@ -4046,7 +4104,7 @@ Program.prototype.enableLocatorReporting = function(params) {
// Pt; Pl; Pb; Pr denotes the rectangle. // Pt; Pl; Pb; Pr denotes the rectangle.
// NOTE: xterm doesn't enable this code by default. // NOTE: xterm doesn't enable this code by default.
Program.prototype.decera = Program.prototype.decera =
Program.prototype.eraseRectangle = function(params) { Program.prototype.eraseRectangle = function() {
return this._write('\x1b[' + slice.call(arguments).join(';') + '$z'); return this._write('\x1b[' + slice.call(arguments).join(';') + '$z');
}; };
@ -4062,7 +4120,7 @@ Program.prototype.eraseRectangle = function(params) {
// Ps = 3 -> report button up transitions. // Ps = 3 -> report button up transitions.
// Ps = 4 -> do not report button up transitions. // Ps = 4 -> do not report button up transitions.
Program.prototype.decsle = Program.prototype.decsle =
Program.prototype.setLocatorEvents = function(params) { Program.prototype.setLocatorEvents = function() {
return this._write('\x1b[' + slice.call(arguments).join(';') + '\'{'); return this._write('\x1b[' + slice.call(arguments).join(';') + '\'{');
}; };
@ -4070,7 +4128,7 @@ Program.prototype.setLocatorEvents = function(params) {
// Selective Erase Rectangular Area (DECSERA), VT400 and up. // Selective Erase Rectangular Area (DECSERA), VT400 and up.
// Pt; Pl; Pb; Pr denotes the rectangle. // Pt; Pl; Pb; Pr denotes the rectangle.
Program.prototype.decsera = Program.prototype.decsera =
Program.prototype.selectiveEraseRectangle = function(params) { Program.prototype.selectiveEraseRectangle = function() {
return this._write('\x1b[' + slice.call(arguments).join(';') + '${'); return this._write('\x1b[' + slice.call(arguments).join(';') + '${');
}; };
@ -4117,13 +4175,13 @@ Program.prototype.selectiveEraseRectangle = function(params) {
Program.prototype.decrqlp = Program.prototype.decrqlp =
Program.prototype.req_mouse_pos = Program.prototype.req_mouse_pos =
Program.prototype.reqmp = Program.prototype.reqmp =
Program.prototype.requestLocatorPosition = function(params, callback) { Program.prototype.requestLocatorPosition = function(param, callback) {
// See also: // See also:
// get_mouse / getm / Gm // get_mouse / getm / Gm
// mouse_info / minfo / Mi // mouse_info / minfo / Mi
// Correct for tput? // Correct for tput?
if (this.has('req_mouse_pos')) { if (this.has('req_mouse_pos')) {
var code = this.tput.req_mouse_pos.apply(this.tput, params); var code = this.tput.req_mouse_pos(param);
return this.response('locator-position', code, callback); return this.response('locator-position', code, callback);
} }
return this.response('locator-position', return this.response('locator-position',
@ -4147,6 +4205,7 @@ Program.prototype.deleteColumns = function() {
}; };
Program.prototype.out = function(name) { Program.prototype.out = function(name) {
var args = Array.prototype.slice.call(arguments, 1);
this.ret = true; this.ret = true;
var out = this[name].apply(this, args); var out = this[name].apply(this, args);
this.ret = false; this.ret = false;
@ -4200,7 +4259,7 @@ Program.prototype.pause = function(callback) {
}; };
}; };
Program.prototype.resume = function(callback) { Program.prototype.resume = function() {
if (this._resume) return this._resume(); if (this._resume) return this._resume();
}; };
@ -4218,7 +4277,7 @@ function unshiftEvent(obj, event, listener) {
listeners.forEach(function(listener) { listeners.forEach(function(listener) {
obj.on(event, listener); obj.on(event, listener);
}); });
}; }
function merge(out) { function merge(out) {
slice.call(arguments, 1).forEach(function(obj) { slice.call(arguments, 1).forEach(function(obj) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -10,13 +10,14 @@
var EventEmitter = require('../events').EventEmitter; var EventEmitter = require('../events').EventEmitter;
var helpers = require('../helpers');
/** /**
* Node * Node
*/ */
function Node(options) { function Node(options) {
var self = this;
var Screen = require('./screen');
if (!(this instanceof Node)) { if (!(this instanceof Node)) {
return new Node(options); return new Node(options);
} }
@ -25,15 +26,43 @@ function Node(options) {
options = options || {}; options = options || {};
this.options = options; this.options = options;
this.screen = this.screen
|| options.screen this.screen = this.screen || options.screen;
|| require('./screen').global
|| (function(){throw new Error('No active 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.parent = options.parent || null; this.parent = options.parent || null;
this.children = []; this.children = [];
this.$ = this._ = this.data = {}; this.$ = this._ = this.data = {};
this.uid = Node.uid++; this.uid = Node.uid++;
this.index = -1; this.index = this.index != null ? this.index : -1;
if (this.type !== 'screen') { if (this.type !== 'screen') {
this.detached = true; this.detached = true;
@ -55,8 +84,13 @@ Node.prototype.type = 'node';
Node.prototype.insert = function(element, i) { Node.prototype.insert = function(element, i) {
var self = this; var self = this;
if (element.screen && element.screen !== this.screen) {
throw new Error('Cannot switch a node\'s screen.');
}
element.detach(); element.detach();
element.parent = this; element.parent = this;
element.screen = this.screen;
if (i === 0) { if (i === 0) {
this.children.unshift(element); this.children.unshift(element);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -22,6 +22,7 @@ var helpers = require('../helpers');
var Node = require('./node'); var Node = require('./node');
var Log = require('./log'); var Log = require('./log');
var Element = require('./element');
var Box = require('./box'); var Box = require('./box');
/** /**
@ -42,7 +43,7 @@ function Screen(options) {
options = { program: options }; options = { program: options };
} }
this.program = options.program || program.global; this.program = options.program;
if (!this.program) { if (!this.program) {
this.program = program({ this.program = program({
@ -51,7 +52,7 @@ function Screen(options) {
log: options.log, log: options.log,
debug: options.debug, debug: options.debug,
dump: options.dump, dump: options.dump,
term: options.term, terminal: options.terminal || options.term,
resizeTimeout: options.resizeTimeout, resizeTimeout: options.resizeTimeout,
forceUnicode: options.forceUnicode, forceUnicode: options.forceUnicode,
tput: true, tput: true,
@ -63,9 +64,9 @@ function Screen(options) {
this.program.useBuffer = true; this.program.useBuffer = true;
this.program.zero = true; this.program.zero = true;
this.program.options.resizeTimeout = options.resizeTimeout; this.program.options.resizeTimeout = options.resizeTimeout;
if (options.forceUnicode) { if (options.forceUnicode != null) {
this.program.tput.features.unicode = true; this.program.tput.features.unicode = options.forceUnicode;
this.program.tput.unicode = true; this.program.tput.unicode = options.forceUnicode;
} }
} }
@ -200,6 +201,7 @@ Screen.bind = function(screen) {
if (!~Screen.instances.indexOf(screen)) { if (!~Screen.instances.indexOf(screen)) {
Screen.instances.push(screen); Screen.instances.push(screen);
screen.index = Screen.total;
Screen.total++; Screen.total++;
} }
@ -251,6 +253,29 @@ Screen.prototype.__defineSetter__('title', function(title) {
return this.program.title = 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() { Screen.prototype.enter = function() {
if (this.program.isAlt) return; if (this.program.isAlt) return;
if (!this.cursor._set) { if (!this.cursor._set) {
@ -370,10 +395,13 @@ Screen.prototype.postEnter = function() {
tags: true tags: true
}); });
self.render(); self.render();
setTimeout(function() { var timeout = setTimeout(function() {
warning.destroy(); warning.destroy();
self.render(); self.render();
}, 1500).unref(); }, 1500);
if (timeout.unref) {
timeout.unref();
}
}); });
} }
}; };
@ -387,6 +415,8 @@ Screen.prototype.destroy = function() {
Screen.instances.splice(index, 1); Screen.instances.splice(index, 1);
Screen.total--; Screen.total--;
Screen.global = Screen.instances[0];
if (Screen.total === 0) { if (Screen.total === 0) {
Screen.global = null; Screen.global = null;
@ -413,9 +443,6 @@ Screen.prototype.destroy = function() {
}; };
Screen.prototype.log = function() { Screen.prototype.log = function() {
if (this.debugLog) {
this.debugLog.log.apply(this.debugLog, arguments);
}
return this.program.log.apply(this.program, arguments); return this.program.log.apply(this.program, arguments);
}; };
@ -524,7 +551,7 @@ Screen.prototype._listenMouse = function(el) {
// }); // });
// Autofocus elements with the appropriate option. // Autofocus elements with the appropriate option.
this.on('element click', function(el, data) { this.on('element click', function(el) {
if (el.clickable === true && el.options.autoFocus !== false) { if (el.clickable === true && el.options.autoFocus !== false) {
el.focus(); el.focus();
} }
@ -637,7 +664,7 @@ Screen.prototype._initHover = function() {
// XXX This can cause problems if the // XXX This can cause problems if the
// terminal does not support allMotion. // terminal does not support allMotion.
// Workaround: check to see if content is set. // Workaround: check to see if content is set.
this.on('element mouseup', function(el, data) { this.on('element mouseup', function(el) {
if (!self._hoverText.getContent()) return; if (!self._hoverText.getContent()) return;
if (!el._hoverOptions) return; if (!el._hoverOptions) return;
self.append(self._hoverText); self.append(self._hoverText);
@ -661,7 +688,7 @@ Screen.prototype.__defineGetter__('height', function() {
return this.program.rows; return this.program.rows;
}); });
Screen.prototype.alloc = function() { Screen.prototype.alloc = function(dirty) {
var x, y; var x, y;
this.lines = []; this.lines = [];
@ -670,7 +697,7 @@ Screen.prototype.alloc = function() {
for (x = 0; x < this.cols; x++) { for (x = 0; x < this.cols; x++) {
this.lines[y][x] = [this.dattr, ' ']; this.lines[y][x] = [this.dattr, ' '];
} }
this.lines[y].dirty = false; this.lines[y].dirty = !!dirty;
} }
this.olines = []; this.olines = [];
@ -684,9 +711,15 @@ Screen.prototype.alloc = function() {
this.program.clear(); this.program.clear();
}; };
Screen.prototype.realloc = function() {
return this.alloc(true);
};
Screen.prototype.render = function() { Screen.prototype.render = function() {
var self = this; var self = this;
if (this.destroyed) return;
this.emit('prerender'); this.emit('prerender');
this._borderStops = {}; this._borderStops = {};
@ -1131,7 +1164,11 @@ Screen.prototype.draw = function(start, end) {
// } else { // } else {
// out += this.tput.el(); // out += this.tput.el();
// } // }
// out += this.tput.cuf(xx - x); // if (this.tput.strings.parm_right_cursor) {
// out += this.tput.cuf(xx - x);
// } else {
// out += this.tput.cup(y, xx);
// }
// this.fillRegion(data, ' ', // this.fillRegion(data, ' ',
// x, this.tput.strings.erase_chars ? xx : line.length, // x, this.tput.strings.erase_chars ? xx : line.length,
// y, y + 1); // y, y + 1);
@ -1164,9 +1201,13 @@ Screen.prototype.draw = function(start, end) {
} }
continue; continue;
} else if (lx !== -1) { } else if (lx !== -1) {
out += y === ly if (this.tput.strings.parm_right_cursor) {
? this.tput.cuf(x - lx) out += y === ly
: this.tput.cup(y, x); ? this.tput.cuf(x - lx)
: this.tput.cup(y, x);
} else {
out += this.tput.cup(y, x);
}
lx = -1, ly = -1; lx = -1, ly = -1;
} }
o[x][0] = data; o[x][0] = data;
@ -1348,7 +1389,7 @@ Screen.prototype.draw = function(start, end) {
} }
// this.program.flush(); // this.program.flush();
// this.program.output.write(pre + main + post); // this.program._owrite(pre + main + post);
this.program._write(pre + main + post); this.program._write(pre + main + post);
} }
@ -1625,7 +1666,7 @@ Screen.prototype._focus = function(self, old) {
// If we're in a scrollable element, // If we're in a scrollable element,
// automatically scroll to the focused element. // automatically scroll to the focused element.
if (el) { if (el && !el.detached) {
// NOTE: This is different from the other "visible" values - it needs the // NOTE: This is different from the other "visible" values - it needs the
// visible height of the scrolling element itself, not the element within // visible height of the scrolling element itself, not the element within
// it. // it.
@ -1703,11 +1744,12 @@ Screen.prototype.spawn = function(file, args, options) {
var screen = this var screen = this
, program = screen.program , program = screen.program
, options = options || {}
, spawn = require('child_process').spawn , spawn = require('child_process').spawn
, mouse = program.mouseEnabled , mouse = program.mouseEnabled
, ps; , ps;
options = options || {};
options.stdio = options.stdio || 'inherit'; options.stdio = options.stdio || 'inherit';
program.lsaveCursor('spawn'); program.lsaveCursor('spawn');
@ -1719,13 +1761,17 @@ Screen.prototype.spawn = function(file, args, options) {
var write = program.output.write; var write = program.output.write;
program.output.write = function() {}; program.output.write = function() {};
program.input.pause(); program.input.pause();
program.input.setRawMode(false); if (program.input.setRawMode) {
program.input.setRawMode(false);
}
var resume = function() { var resume = function() {
if (resume.done) return; if (resume.done) return;
resume.done = true; resume.done = true;
program.input.setRawMode(true); if (program.input.setRawMode) {
program.input.setRawMode(true);
}
program.input.resume(); program.input.resume();
program.output.write = write; program.output.write = write;
@ -1733,8 +1779,8 @@ Screen.prototype.spawn = function(file, args, options) {
// program.csr(0, program.rows - 1); // program.csr(0, program.rows - 1);
if (mouse) { if (mouse) {
program.enableMouse(); program.enableMouse();
if (self.options.sendFocus) { if (screen.options.sendFocus) {
self.program.setMouse({ sendFocus: true }, true); screen.program.setMouse({ sendFocus: true }, true);
} }
} }
@ -1754,8 +1800,7 @@ Screen.prototype.spawn = function(file, args, options) {
}; };
Screen.prototype.exec = function(file, args, options, callback) { Screen.prototype.exec = function(file, args, options, callback) {
var callback = arguments[arguments.length - 1] var ps = this.spawn(file, args, options);
, ps = this.spawn(file, args, options);
ps.on('error', function(err) { ps.on('error', function(err) {
if (!callback) return; if (!callback) return;
@ -1787,7 +1832,6 @@ Screen.prototype.readEditor = function(options, callback) {
options = options || {}; options = options || {};
var self = this var self = this
, fs = require('fs')
, editor = options.editor || process.env.EDITOR || 'vi' , editor = options.editor || process.env.EDITOR || 'vi'
, name = options.name || process.title || 'blessed' , name = options.name || process.title || 'blessed'
, rnd = Math.random().toString(36).split('.').pop() , rnd = Math.random().toString(36).split('.').pop()
@ -1822,14 +1866,12 @@ Screen.prototype.readEditor = function(options, callback) {
}; };
Screen.prototype.displayImage = function(file, callback) { Screen.prototype.displayImage = function(file, callback) {
var self = this;
if (!file) { if (!file) {
if (!callback) return; if (!callback) return;
return callback(new Error('No image.')); return callback(new Error('No image.'));
} }
var file = path.resolve(process.cwd(), file); file = path.resolve(process.cwd(), file);
if (!~file.indexOf('://')) { if (!~file.indexOf('://')) {
file = 'file://' + file; file = 'file://' + file;
@ -1962,7 +2004,9 @@ Screen.prototype.cursorShape = function(shape, blink) {
self.cursor._state ^= 1; self.cursor._state ^= 1;
if (self.renders) self.render(); if (self.renders) self.render();
}, 500); }, 500);
this._cursorBlink.unref(); if (this._cursorBlink.unref) {
this._cursorBlink.unref();
}
} }
return true; return true;
} }
@ -2216,9 +2260,9 @@ var dangles = {
'\u2502': true // '│' '\u2502': true // '│'
}; };
var cdangles = { // var cdangles = {
'\u250c': true // '┌' // '\u250c': true // '┌'
}; // };
// Every ACS angle character can be // Every ACS angle character can be
// represented by 4 bits ordered like this: // represented by 4 bits ordered like this:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

5
test/helpers.js Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -32,5 +32,5 @@ box.input('Input: ', '', function(err, data) {
}); });
screen.key('C-q', function(ch, key) { screen.key('C-q', function(ch, key) {
return process.exit(0); return screen.destroy();
}); });

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -94,14 +94,41 @@ var png = blessed.image({
screen.render(); screen.render();
screen.key('q', function() { screen.key('q', function() {
process.exit(0); clearInterval(timeout);
screen.destroy();
}); });
var timeout = setInterval(function() { var timeout = setInterval(function() {
if (png.right <= 0) {
clearInterval(timeout);
return;
}
png.left++; png.left++;
screen.render(); screen.render();
}, 100); }, 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() { png.on('mousedown', function() {
clearInterval(timeout); clearInterval(timeout);
}); });

View File

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

View File

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

View File

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

View File

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

View File

@ -75,7 +75,7 @@ over.key('down', function() {
over.focus(); over.focus();
screen.key('q', function() { screen.key('q', function() {
return process.exit(0); return screen.destroy();
}); });
var lorem = 'Non eram nescius Brute cum quae summis ingeniis exquisitaque' 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)); tab._.data.setContent(require('util').inspect(process, null, 6));
screen.key('q', function() { screen.key('q', function() {
process.exit(0); screen.destroy();
}); });
screen.render(); screen.render();

View File

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

View File

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

View File

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

View File

@ -0,0 +1,62 @@
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();

53
test/widget-termswitch.js Normal file
View File

@ -0,0 +1,53 @@
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.render();
screen.key('q', function() { screen.key('q', function() {
process.exit(0); screen.destroy();
}); });
screen.key('i', function() { screen.key('i', function() {

View File

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

View File

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

View File

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

View File

@ -30,6 +30,11 @@ screen.debugLog.on('show', function() {
screen.render(); 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({ screen.append(blessed.text({
top: 0, top: 0,
left: 2, left: 2,