diff --git a/README.md b/README.md index 3453441..4b14e1d 100644 --- a/README.md +++ b/README.md @@ -254,24 +254,24 @@ The base element. - **fg, bg, bold, underline** - attributes. - **style** - may contain attributes in the format of: - ``` js - { - fg: 'blue', - bg: 'black', - border: { - fg: 'blue' - }, - scrollbar: { - bg: 'blue' - }, - focus: { - bg: 'red' - }, - hover: { - bg: 'red' - } +``` js + { + fg: 'blue', + bg: 'black', + border: { + fg: 'blue' + }, + scrollbar: { + bg: 'blue' + }, + focus: { + bg: 'red' + }, + hover: { + bg: 'red' } - ``` + } +``` - **border** - border object, see below. - **content** - element's text content. - **clickable** - element is clickable. diff --git a/lib/tput.js b/lib/tput.js index 3d61038..ead7c5b 100644 --- a/lib/tput.js +++ b/lib/tput.js @@ -1049,17 +1049,17 @@ Tput.prototype._compile = function(info, key, str) { }; // See: ~/ncurses/ncurses/tinfo/lib_tputs.c -Tput.prototype._print = -Tput.prototype._parsePadding = function(code, print, done) { +Tput.prototype._print = function(code, print, done) { var print = print || write - , done = done || noop; + , done = done || noop + , xon = !this.bools.needs_xon_xoff || this.bools.xon_xoff; if (!this.padding) { print(code); return done(); } - var parts = code.split(/(?=\$<\d+[*\/]{0,2}>)/) + var parts = code.split(/(?=\$<[\d.]+[*\/]{0,2}>)/) , i = 0; (function next() { @@ -1068,7 +1068,10 @@ Tput.prototype._parsePadding = function(code, print, done) { } var part = parts[i++] - , padding = /^\$<(\d+)([*\/]{0,2})>/.exec(part); + , padding = /^\$<([\d.]+)([*\/]{0,2})>/.exec(part) + , amount + , suffix + , affect; if (!padding) { print(part); @@ -1076,6 +1079,16 @@ Tput.prototype._parsePadding = function(code, print, done) { } part = part.substring(padding[0].length); + amount = +padding[1]; + suffix = padding[2]; + + // A `/' suffix indicates that the padding is mandatory and forces a + // delay of the given number of milliseconds even on devices for which xon + // is present to indicate flow control. + if (xon && !~suffix.indexOf('/')) { + print(part); + return next(); + } // A `*' indicates that the padding required is proportional to the number // of lines affected by the operation, and the amount given is the @@ -1083,21 +1096,25 @@ Tput.prototype._parsePadding = function(code, print, done) { // the factor is still the number of lines affected.) Normally, padding is // advisory if the device has the xon capability; it is used for cost // computation but does not trigger delays. - if (~padding[2].indexOf('*')) { - ; - } - - // A `/' suffix indicates that the padding is mandatory and forces a - // delay of the given number of milliseconds even on devices for which xon - // is present to indicate flow control. - if (~padding[2].indexOf('/')) { - ; + if (~suffix.indexOf('*')) { + if (affect = /\x1b\[(\d+)[LM]/.exec(part)) { + amount *= +affect[1]; + } + // The above is a huge workaround. In reality, we need to compile + // `_print` into the string functions and check the cap name and + // params. + // if (cap === 'insert_line' || cap === 'delete_line') { + // amount *= params[0]; + // } + // if (cap === 'clear_screen') { + // amount *= process.stdout.rows; + // } } return setTimeout(function() { print(part); return next(); - }, +padding[1]); + }, amount); })(); }; diff --git a/test/tput.js b/test/tput.js index f2b4e8d..6f02c54 100644 --- a/test/tput.js +++ b/test/tput.js @@ -81,7 +81,9 @@ function parseArg() { var argv = parseArg(); var tput = blessed.tput({ - term: argv[0] && argv[0] !== 'all' && argv[0] !== 'rand' ? argv[0] : 'xterm', + term: argv[0] !== 'all' && argv[0] !== 'rand' + ? argv[0] || __dirname + '/../usr/xterm' + : null, extended: true, debug: true, termcap: argv.termcap, @@ -90,9 +92,7 @@ var tput = blessed.tput({ termcapFile: argv.c || argv.cfile }); -if (!argv[0] || argv[0] === 'all') { - console.log(''); - +if (argv[0] === 'all') { var rl = require('readline').createInterface({ input: process.stdin, output: process.stdout @@ -107,12 +107,14 @@ if (!argv[0] || argv[0] === 'all') { result = result.trim().toLowerCase(); if (result !== 'y') return process.exit(0); console.log('\x1b[32m(You bet your ass I wish to proceed.)\x1b[m'); + tput._write('$<1000/>.$<1000/>.$<1000/>.$<100/>Let\'s go...', process.stdout.write.bind(process.stdout), function() { + }); setTimeout(function() { process.stdout.write('.'); }, 1000); setTimeout(function() { process.stdout.write('.'); }, 2000); setTimeout(function() { process.stdout.write('.'); }, 3000); setTimeout(function() { console.log('Let\'s go...'); - }, 3000); + }, 3100); setTimeout(function() { tput.compileAll(argv[1]); process.exit(0); @@ -123,10 +125,15 @@ if (!argv[0] || argv[0] === 'all') { } if (argv[0] === 'rand') { - var terms = tput.getAll(); - var term = terms[(terms.length - 1) * Math.random() | 0]; + var terms = tput.getAll() + , term; + + term = terms[(terms.length - 1) * Math.random() | 0]; + console.log('Compiling ' + term + '...'); tput.compileTerminfo(term); + console.log('Compiled ' + term + '.'); + return; } @@ -137,12 +144,13 @@ if (argv[0] === 'rand') { // process.stdout.write(blessed.tput.sprintf('%-10s\n', 'hello')); -// tput._compile('%?%p9%t\u001b(0%e\u001b(B%;\u001b[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m'); +// tput._compile({ name: 'xterm' }, 'set_attributes', +// '%?%p9%t\u001b(0%e\u001b(B%;\u001b[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m'); // console.log(tput.setaf(4) + 'foo' + tput.sgr0()); // console.log(tput.setaf(4) + 'foo' + tput.sgr(0)); // tput.padding = true; // tput._print('hello$<1000/>world', console.log, function() { -// tput._print('$<1000*>foo$<1000/>bar', console.log, process.exit); +// tput._print('$<1000/>foo$<1000/>bar', console.log, process.exit); // });