From f3df07a2378d74d47a02741c239cf80c803b177f Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Wed, 31 Jul 2013 17:09:41 -0500 Subject: [PATCH] buffer everything. cancel acs at the end of draw() if necessary. --- lib/program.js | 56 ++++++++++++++++++++++++++++++++++++++++++++++++-- lib/widget.js | 11 ++++++++-- 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/lib/program.js b/lib/program.js index 987c79b..d06c324 100644 --- a/lib/program.js +++ b/lib/program.js @@ -66,6 +66,10 @@ function Program(options) { || process.env.TERM || 'xterm'; + this._buf = ''; + this.__flush = this._flush.bind(this); + process.on('exit', this.__flush); + if (!Program.global) { Program.global = this; } @@ -1233,16 +1237,42 @@ Program.prototype._parseChar = function(text, attr) { } }; +Program.prototype._buffer = function(text) { + if (process._exiting) { + this._flush(); + this.output.write(text); + return; + } + + if (this._buf) { + this._buf += text; + return; + } + + this._buf = text; + + process.nextTick(this.__flush); +}; + +Program.prototype._flush = function(text) { + if (!this._buf) return; + this.output.write(this._buf); + this._buf = ''; +}; + Program.prototype._write = function(text) { if (this.ret) return text; + if (this.options.buffer) { + return this._buffer(text); + } return this.output.write(text); }; Program.prototype.echo = Program.prototype.write = function(text, attr) { return attr - ? this.output.write(this.text(text, attr)) - : this.output.write(text); + ? this._write(this.text(text, attr)) + : this._write(text); }; Program.prototype._ncoords = function() { @@ -3480,6 +3510,28 @@ Program.prototype.resume = function(callback) { if (this._resume) return this._resume(); }; +/** + * Helpers + */ + +// We could do this easier by just manipulating the _events object, or for +// older versions of node, manipulating the array returned by listeners(), but +// neither of these methods are guaranteed to work in future versions of node. +function unshiftEvent(obj, event, listener) { + var listeners = obj.listeners(event); + obj.removeAllListeners(event); + obj.on(event, listener); + listeners.forEach(function(listener) { + obj.on(event, listener); + }); +}; + +// Ensure _exiting is set for future versions of node that may remove it. +// We need this to be the first listener executed. +unshiftEvent(process, 'exit', function() { + process._exiting = true; +}); + /** * Expose */ diff --git a/lib/widget.js b/lib/widget.js index 26727fd..31cdca6 100644 --- a/lib/widget.js +++ b/lib/widget.js @@ -267,6 +267,7 @@ function Screen(options) { options = { program: options }; } + options.buffer = true; options.program = options.program || require('./program').global || new (require('./program'))(options); @@ -280,7 +281,6 @@ function Screen(options) { this.program = options.program; this.program.zero = true; this.tput = this.program.tput; - this.output = this.program.output; this.autoPadding = options.autoPadding; @@ -1122,6 +1122,11 @@ Screen.prototype.draw = function(start, end) { } } + if (acs) { + main += this.tput.rmacs(); + acs = false; + } + if (main) { var pre = '' , post = ''; @@ -1142,7 +1147,9 @@ Screen.prototype.draw = function(start, end) { : '\x1b[?25h'; } - this.output.write(pre + main + post); + // this.program._flush(); + // this.program.output.write(pre + main + post); + this.program._write(pre + main + post); } };