From 1b5155cfae2a388925814b3b489618c26a663278 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Wed, 24 Jul 2013 14:17:52 -0500 Subject: [PATCH] refactor and clean up program.js. --- lib/program.js | 348 +++++++++++++++++++++---------------------------- lib/widget.js | 5 +- 2 files changed, 153 insertions(+), 200 deletions(-) diff --git a/lib/program.js b/lib/program.js index 03442a9..6d9aafc 100644 --- a/lib/program.js +++ b/lib/program.js @@ -63,13 +63,6 @@ function Program(options) { || process.env.TERM || 'xterm'; - // if (!Program.global) { - // Program._write = process.stdout.write; - // process.stdout.write = function() {}; - // process.stderr.write = function() {}; - // Program.global = this; - // } - if (!Program.global) { Program.global = this; } @@ -78,8 +71,6 @@ function Program(options) { this.setupTput(); } - this.__flush = this._flush.bind(this); - this.listen(); } @@ -116,7 +107,7 @@ Program.prototype.setupTput = function() { , cap = args.shift(); if (tput[cap]) { - return this.write(tput[cap].apply(tput, args)); + return this._write(tput[cap].apply(tput, args)); } }; @@ -136,7 +127,7 @@ Program.prototype.setupTput = function() { }; } else { self.put[key] = function() { - return self.write(tput[key].apply(tput, arguments)); + return self._write(tput[key].apply(tput, arguments)); }; } }); @@ -209,9 +200,6 @@ Program.prototype.listen = function() { } }); - // self.bindMouse(); - // self.bindResponse(); - // Output this.output.on('resize', function() { self.cols = self.output.columns; @@ -1071,17 +1059,17 @@ Program.prototype.receive = function(text, callback) { text = null; } - return process.nextTick(function() { - self.input.once('data', function(data) { - listeners.push.apply(listeners, bak); - if (typeof data !== 'string') { - data = data.toString('utf8'); - } - return callback(null, data); - }); - - if (text) self.write(text); + this.input.once('data', function(data) { + listeners.push.apply(listeners, bak); + if (typeof data !== 'string') { + data = data.toString('utf8'); + } + return callback(null, data); }); + + if (text != null) { + return this._write(text); + } }; Program.prototype.response = function(name, text, callback) { @@ -1097,14 +1085,18 @@ Program.prototype.response = function(name, text, callback) { this.bindResponse(); - this.once('response' + (name ? ' ' + name : ''), function(event) { + name = name + ? 'response ' + name + : 'response'; + + this.once(name, function(event) { if (event.type === 'error') { return callback(new Error(event.event + ': ' + event.text)); } return callback(null, event); }); - return this.write(text); + return this._write(text); }; Program.prototype._wrapCursor = function(nl) { @@ -1164,33 +1156,9 @@ Program.prototype._parseChar = function(text, attr) { } }; -Program.prototype.echo_ = -Program.prototype.write_ = function(text, attr) { - if (!text) return; - - if (attr) { - text = this.text(text, attr); - } - - if (this._buf) { - this._buf += text; - return true; - } - - this._buf = text; - - //if (!this.__flush) { - // this.__flush = this._flush.bind(this); - //} - - process.nextTick(this.__flush); - - return true; -}; - -Program.prototype._flush = function() { - this.output.write(this._buf); - this._buf = ''; +Program.prototype._write = function(text) { + if (this.ret) return text; + return this.output.write(text); }; Program.prototype.echo = @@ -1272,7 +1240,7 @@ Program.prototype.rmove = function(x, y) { }; Program.prototype.simpleInsert = function(ch, i, attr) { - return this.write(this.repeat(ch, i), attr); + return this._write(this.repeat(ch, i), attr); }; Program.prototype.repeat = function(ch, i) { @@ -1287,25 +1255,25 @@ Program.prototype.repeat = function(ch, i) { //Program.prototype.pad = Program.prototype.nul = function() { //if (this.has('pad')) return this.put.pad(); - return this.write('\200'); + return this._write('\200'); }; Program.prototype.bel = Program.prototype.bell = function() { if (this.has('bel')) return this.put.bel(); - return this.write('\x07'); + return this._write('\x07'); }; Program.prototype.vtab = function() { this.y++; this._ncoords(); - return this.write('\x0b'); + return this._write('\x0b'); }; Program.prototype.ff = Program.prototype.form = function() { if (this.has('ff')) return this.put.ff(); - return this.write('\x0c'); + return this._write('\x0c'); }; Program.prototype.kbs = @@ -1313,7 +1281,7 @@ Program.prototype.backspace = function() { this.x--; this._ncoords(); if (this.has('kbs')) return this.put.kbs(); - return this.write('\x08'); + return this._write('\x08'); }; Program.prototype.ht = @@ -1321,24 +1289,24 @@ Program.prototype.tab = function() { this.x += 8; this._ncoords(); if (this.has('ht')) return this.put.ht(); - return this.write('\t'); + return this._write('\t'); }; Program.prototype.shiftOut = function() { // if (this.has('S2')) return this.put.S2(); - return this.write('\x0e'); + return this._write('\x0e'); }; Program.prototype.shiftIn = function() { // if (this.has('S3')) return this.put.S3(); - return this.write('\x0f'); + return this._write('\x0f'); }; Program.prototype.cr = Program.prototype.return = function() { this.x = 0; if (this.has('cr')) return this.put.cr(); - return this.write('\r'); + return this._write('\r'); }; Program.prototype.nel = @@ -1351,24 +1319,20 @@ Program.prototype.feed = function() { this.y++; this._ncoords(); if (this.has('nel')) return this.put.nel(); - return this.write('\n'); + return this._write('\n'); }; /** * Esc */ -Program.prototype.esc = function(code) { - return this.write('\x1b' + code); -}; - // ESC D Index (IND is 0x84). Program.prototype.ind = Program.prototype.index = function() { this.y++; this._ncoords(); if (this.tput) return this.put.ind(); - return this.write('\x1bD'); + return this._write('\x1bD'); }; // ESC M Reverse Index (RI is 0x8d). @@ -1378,7 +1342,7 @@ Program.prototype.reverseIndex = function() { this.y--; this._ncoords(); if (this.tput) return this.put.ri(); - return this.write('\x1bM'); + return this._write('\x1bM'); }; // ESC E Next Line (NEL is 0x85). @@ -1387,7 +1351,7 @@ Program.prototype.nextLine = function() { this.x = 0; this._ncoords(); if (this.has('nel')) return this.put.nel(); - return this.write('\x1bE'); + return this._write('\x1bE'); }; // ESC c Full Reset (RIS). @@ -1398,13 +1362,13 @@ Program.prototype.reset = function() { ? this.put.rs1() : this.put.ris(); } - return this.write('\x1bc'); + return this._write('\x1bc'); }; // ESC H Tab Set (HTS is 0x88). Program.prototype.tabSet = function() { if (this.tput) return this.put.hts(); - return this.write('\x1bH'); + return this._write('\x1bH'); }; // ESC 7 Save Cursor (DECSC). @@ -1414,7 +1378,7 @@ Program.prototype.saveCursor = function(key) { this.savedX = this.x || 0; this.savedY = this.y || 0; if (this.tput) return this.put.sc(); - return this.esc('7'); + return this._write('\x1b7'); }; // ESC 8 Restore Cursor (DECRC). @@ -1424,7 +1388,7 @@ Program.prototype.restoreCursor = function(key, hide) { this.x = this.savedX || 0; this.y = this.savedY || 0; if (this.tput) return this.put.rc(); - return this.esc('8'); + return this._write('\x1b8'); }; // Save Cursor Locally @@ -1455,7 +1419,7 @@ Program.prototype.lrestoreCursor = function(key, hide) { // ESC # 3 DEC line height/width Program.prototype.lineHeight = function() { - return this.esc('#'); + return this._write('\x1b#'); }; // ESC (,),*,+,-,. Designate G0-G2 Character Set. @@ -1545,7 +1509,7 @@ Program.prototype.charset = function(val, level) { break; } - return this.write('\x1b(' + val); + return this._write('\x1b(' + val); }; Program.prototype.enter_alt_charset_mode = @@ -1594,17 +1558,13 @@ Program.prototype.setG = function(val) { val = 'O'; // Next Char Only break; } - return this.esc(val); + return this._write('\x1b' + val); }; /** * OSC */ -Program.prototype.osc = function(code) { - return this.esc(']' + code); -}; - // OSC Ps ; Pt ST // OSC Ps ; Pt BEL // Set Text Parameters. @@ -1612,11 +1572,11 @@ Program.prototype.setTitle = function(title) { if (this.term('screen')) { // Tmux pane // if (process.env.TMUX) { - // return this.osc('2;' + title + '\x1b\\'); + // return this._write('\x1b]2;' + title + '\x1b\\'); // } - return this.esc('k' + title + '\x1b\\'); + return this._write('\x1bk' + title + '\x1b\\'); } - return this.osc('0;' + title + '\x07'); + return this._write('\x1b]0;' + title + '\x07'); }; // OSC Ps ; Pt ST @@ -1626,7 +1586,7 @@ Program.prototype.resetColors = function(param) { if (this.has('Cr')) { return this.put.Cr(param); } - return this.osc('112;' + param + '\x07'); + return this._write('\x1b]112;' + param + '\x07'); }; // OSC Ps ; Pt ST @@ -1636,7 +1596,7 @@ Program.prototype.dynamicColors = function(param) { if (this.has('Cs')) { return this.put.Cs(param); } - return this.osc('12;' + param + '\x07'); + return this._write('\x1b]12;' + param + '\x07'); }; // OSC Ps ; Pt ST @@ -1646,17 +1606,13 @@ Program.prototype.selData = function(a, b) { if (this.has('Ms')) { return this.put.Ms(a, b); } - return this.osc('52;' + a + ';' + b + '\x07'); + return this._write('\x1b]52;' + a + ';' + b + '\x07'); }; /** * CSI */ -Program.prototype.csi = function(code) { - return this.esc('[' + code); -}; - // CSI Ps A // Cursor Up Ps Times (default = 1) (CUU). Program.prototype.cuu = @@ -1665,7 +1621,7 @@ Program.prototype.cursorUp = function(param) { this.y -= param || 1; this._ncoords(); if (this.tput) return this.put.cuu(param); - return this.write('\x1b[' + (param || '') + 'A'); + return this._write('\x1b[' + (param || '') + 'A'); }; // CSI Ps B @@ -1676,7 +1632,7 @@ Program.prototype.cursorDown = function(param) { this.y += param || 1; this._ncoords(); if (this.tput) return this.put.cud(param); - return this.write('\x1b[' + (param || '') + 'B'); + return this._write('\x1b[' + (param || '') + 'B'); }; // CSI Ps C @@ -1688,7 +1644,7 @@ Program.prototype.cursorForward = function(param) { this.x += param || 1; this._ncoords(); if (this.tput) return this.put.cuf(param); - return this.write('\x1b[' + (param || '') + 'C'); + return this._write('\x1b[' + (param || '') + 'C'); }; // CSI Ps D @@ -1700,7 +1656,7 @@ Program.prototype.cursorBackward = function(param) { this.x -= param || 1; this._ncoords(); if (this.tput) return this.put.cub(param); - return this.write('\x1b[' + (param || '') + 'D'); + return this._write('\x1b[' + (param || '') + 'D'); }; // CSI Ps ; Ps H @@ -1719,7 +1675,7 @@ Program.prototype.cursorPos = function(row, col) { this.y = row; this._ncoords(); if (this.tput) return this.put.cup(row, col); - return this.write('\x1b[' + (row + 1) + ';' + (col + 1) + 'H'); + return this._write('\x1b[' + (row + 1) + ';' + (col + 1) + 'H'); }; // CSI Ps J Erase in Display (ED). @@ -1755,25 +1711,21 @@ Program.prototype.eraseInDisplay = function(param) { } switch (param) { case 'above': - this.write('\x1b[1J'); - break; + return this._write('\X1b[1J'); case 'all': - this.write('\x1b[2J'); - break; + return this._write('\x1b[2J'); case 'saved': - this.write('\x1b[3J'); - break; + return this._write('\x1b[3J'); case 'below': default: - this.write('\x1b[J'); - break; + return this._write('\x1b[J'); } }; Program.prototype.clear = function() { this.x = this.y = 0; if (this.tput) return this.put.clear(); - return this.write('\x1b[H\x1b[J'); + return this._write('\x1b[H\x1b[J'); // return this.ed('all'); }; @@ -1806,15 +1758,12 @@ Program.prototype.eraseInLine = function(param) { } switch (param) { case 'left': - this.write('\x1b[1K'); - break; + return this._write('\x1b[1K'); case 'all': - this.write('\x1b[2K'); - break; + return this._write('\x1b[2K'); case 'right': default: - this.write('\x1b[K'); - break; + return this._write('\x1b[K'); } }; @@ -1883,7 +1832,7 @@ Program.prototype.eraseInLine = function(param) { Program.prototype.sgr = Program.prototype.attr = Program.prototype.charAttributes = function(param, val) { - return this.write(this._attr(param, val)); + return this._write(this._attr(param, val)); }; Program.prototype.text = function(text, attr) { @@ -2193,7 +2142,7 @@ Program.prototype.insertChars = function(param) { this.x += param || 1; this._ncoords(); if (this.tput) return this.put.ich(param); - return this.write('\x1b[' + (param || 1) + '@'); + return this._write('\x1b[' + (param || 1) + '@'); }; // CSI Ps E @@ -2203,7 +2152,7 @@ Program.prototype.cnl = Program.prototype.cursorNextLine = function(param) { this.y += param || 1; this._ncoords(); - return this.write('\x1b[' + (param || '') + 'E'); + return this._write('\x1b[' + (param || '') + 'E'); }; // CSI Ps F @@ -2213,7 +2162,7 @@ Program.prototype.cpl = Program.prototype.cursorPrecedingLine = function(param) { this.y -= param || 1; this._ncoords(); - return this.write('\x1b[' + (param || '') + 'F'); + return this._write('\x1b[' + (param || '') + 'F'); }; // CSI Ps G @@ -2229,7 +2178,7 @@ Program.prototype.cursorCharAbsolute = function(param) { this.y = 0; this._ncoords(); if (this.tput) return this.put.hpa(param); - return this.write('\x1b[' + (param + 1) + 'G'); + return this._write('\x1b[' + (param + 1) + 'G'); }; // CSI Ps L @@ -2237,7 +2186,7 @@ Program.prototype.cursorCharAbsolute = function(param) { Program.prototype.il = Program.prototype.insertLines = function(param) { if (this.tput) return this.put.il(param); - return this.write('\x1b[' + (param || '') + 'L'); + return this._write('\x1b[' + (param || '') + 'L'); }; // CSI Ps M @@ -2245,7 +2194,7 @@ Program.prototype.insertLines = function(param) { Program.prototype.dl = Program.prototype.deleteLines = function(param) { if (this.tput) return this.put.dl(param); - return this.write('\x1b[' + (param || '') + 'M'); + return this._write('\x1b[' + (param || '') + 'M'); }; // CSI Ps P @@ -2253,7 +2202,7 @@ Program.prototype.deleteLines = function(param) { Program.prototype.dch = Program.prototype.deleteChars = function(param) { if (this.tput) return this.put.dch(param); - return this.write('\x1b[' + (param || '') + 'P'); + return this._write('\x1b[' + (param || '') + 'P'); }; // CSI Ps X @@ -2261,7 +2210,7 @@ Program.prototype.deleteChars = function(param) { Program.prototype.ech = Program.prototype.eraseChars = function(param) { if (this.tput) return this.put.ech(param); - return this.write('\x1b[' + (param || '') + 'X'); + return this._write('\x1b[' + (param || '') + 'X'); }; // CSI Pm ` Character Position Absolute @@ -2274,7 +2223,7 @@ Program.prototype.charPosAbsolute = function(param) { return this.put.hpa.apply(this.put, arguments); } var param = slice.call(arguments).join(';'); - return this.write('\x1b[' + (param || '') + '`'); + return this._write('\x1b[' + (param || '') + '`'); }; // 141 61 a * HPR - @@ -2287,7 +2236,7 @@ Program.prototype.HPositionRelative = function(param) { // Does not exist: // if (this.tput) return this.put.hpr(param); if (this.tput) return this.put.cuf(param); - return this.write('\x1b[' + (param || '') + 'a'); + return this._write('\x1b[' + (param || '') + 'a'); }; // CSI Ps c Send Device Attributes (Primary DA). @@ -2342,7 +2291,7 @@ Program.prototype.linePosAbsolute = function(param) { return this.put.vpa.apply(this.put, arguments); } var param = slice.call(arguments).join(';'); - return this.write('\x1b[' + (param || '') + 'd'); + return this._write('\x1b[' + (param || '') + 'd'); }; // 145 65 e * VPR - Vertical Position Relative @@ -2354,7 +2303,7 @@ Program.prototype.VPositionRelative = function(param) { // Does not exist: // if (this.tput) return this.put.vpr(param); if (this.tput) return this.put.cud(param); - return this.write('\x1b[' + (param || '') + 'e'); + return this._write('\x1b[' + (param || '') + 'e'); }; // CSI Ps ; Ps f @@ -2375,7 +2324,7 @@ Program.prototype.HVPosition = function(row, col) { // Does not exist (?): // if (this.tput) return this.put.hvp(row, col); if (this.tput) return this.put.cup(row, col); - return this.write('\x1b[' + (row + 1) + ';' + (col + 1) + 'f'); + return this._write('\x1b[' + (row + 1) + ';' + (col + 1) + 'f'); }; // CSI Pm h Set Mode (SM). @@ -2465,7 +2414,7 @@ Program.prototype.HVPosition = function(row, col) { Program.prototype.sm = Program.prototype.setMode = function() { var param = slice.call(arguments).join(';'); - return this.write('\x1b[' + (param || '') + 'h'); + return this._write('\x1b[' + (param || '') + 'h'); }; Program.prototype.decset = function() { @@ -2483,8 +2432,8 @@ Program.prototype.showCursor = function() { // cvvis starts blinking cursor if (this.tput) return this.put.cnorm(); //if (this.tput) return this.put.cvvis(); - // return this.write('\x1b[?12l\x1b[?25h'); // cursor_normal - // return this.write('\x1b[?12;25h'); // cursor_visible + // return this._write('\x1b[?12l\x1b[?25h'); // cursor_normal + // return this._write('\x1b[?12;25h'); // cursor_visible return this.setMode('?25'); }; @@ -2580,7 +2529,7 @@ Program.prototype.alternateBuffer = function() { Program.prototype.rm = Program.prototype.resetMode = function() { var param = slice.call(arguments).join(';'); - return this.write('\x1b[' + (param || '') + 'l'); + return this._write('\x1b[' + (param || '') + 'l'); }; Program.prototype.decrst = function() { @@ -2648,8 +2597,10 @@ Program.prototype.setMouse = function(opt, enable) { if (enable) { this._currentMouse = opt; + this.mouseEnabled = true; } else { delete this._currentMouse; + this.mouseEnabled = false; } // Make sure we're not a vtNNN @@ -2748,7 +2699,7 @@ Program.prototype.setScrollRegion = function(top, bottom) { this.y = 0; this._ncoords(); if (this.tput) return this.put.csr(top, bottom); - return this.write('\x1b[' + (top + 1) + ';' + (bottom + 1) + 'r'); + return this._write('\x1b[' + (top + 1) + ';' + (bottom + 1) + 'r'); }; // CSI s @@ -2758,7 +2709,7 @@ Program.prototype.saveCursorA = function() { this.savedX = this.x; this.savedY = this.y; if (this.tput) return this.put.sc(); - return this.write('\x1b[s'); + return this._write('\x1b[s'); }; // CSI u @@ -2768,7 +2719,7 @@ Program.prototype.restoreCursorA = function() { this.x = this.savedX || 0; this.y = this.savedY || 0; if (this.tput) return this.put.rc(); - return this.write('\x1b[u'); + return this._write('\x1b[u'); }; /** @@ -2782,7 +2733,7 @@ Program.prototype.cursorForwardTab = function(param) { this.x += 8; this._ncoords(); if (this.tput) return this.put.tab(param); - return this.write('\x1b[' + (param || 1) + 'I'); + return this._write('\x1b[' + (param || 1) + 'I'); }; // CSI Ps S Scroll up Ps lines (default = 1) (SU). @@ -2791,7 +2742,7 @@ Program.prototype.scrollUp = function(param) { this.y -= param || 1; this._ncoords(); if (this.tput) return this.put.parm_index(param); - return this.write('\x1b[' + (param || 1) + 'S'); + return this._write('\x1b[' + (param || 1) + 'S'); }; // CSI Ps T Scroll down Ps lines (default = 1) (SD). @@ -2800,7 +2751,7 @@ Program.prototype.scrollDown = function(param) { this.y += param || 1; this._ncoords(); if (this.tput) return this.put.parm_rindex(param); - return this.write('\x1b[' + (param || 1) + 'T'); + return this._write('\x1b[' + (param || 1) + 'T'); }; // CSI Ps ; Ps ; Ps ; Ps ; Ps T @@ -2808,7 +2759,7 @@ Program.prototype.scrollDown = function(param) { // [func;startx;starty;firstrow;lastrow]. See the section Mouse // Tracking. Program.prototype.initMouseTracking = function() { - return this.write('\x1b[' + slice.call(arguments).join(';') + 'T'); + return this._write('\x1b[' + slice.call(arguments).join(';') + 'T'); }; // CSI > Ps; Ps T @@ -2823,7 +2774,7 @@ Program.prototype.initMouseTracking = function() { // Ps = 3 -> Do not query window/icon labels using UTF-8. // (See discussion of "Title Modes"). Program.prototype.resetTitleModes = function() { - return this.write('\x1b[>' + slice.call(arguments).join(';') + 'T'); + return this._write('\x1b[>' + slice.call(arguments).join(';') + 'T'); }; // CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT). @@ -2832,7 +2783,7 @@ Program.prototype.cursorBackwardTab = function(param) { this.x -= 8; this._ncoords(); if (this.tput) return this.put.cbt(param); - return this.write('\x1b[' + (param || 1) + 'Z'); + return this._write('\x1b[' + (param || 1) + 'Z'); }; // CSI Ps b Repeat the preceding graphic character Ps times (REP). @@ -2841,7 +2792,7 @@ Program.prototype.repeatPrecedingCharacter = function(param) { this.x += param || 1; this._ncoords(); if (this.tput) return this.put.rep(param); - return this.write('\x1b[' + (param || 1) + 'b'); + return this._write('\x1b[' + (param || 1) + 'b'); }; // CSI Ps g Tab Clear (TBC). @@ -2853,7 +2804,7 @@ Program.prototype.repeatPrecedingCharacter = function(param) { Program.prototype.tbc = Program.prototype.tabClear = function(param) { if (this.tput) return this.put.tbc(param); - return this.write('\x1b[' + (param || 0) + 'g'); + return this._write('\x1b[' + (param || 0) + 'g'); }; // CSI Pm i Media Copy (MC). @@ -2869,7 +2820,7 @@ Program.prototype.tabClear = function(param) { // Ps = 1 1 -> Print all pages. Program.prototype.mc = Program.prototype.mediaCopy = function() { - return this.write('\x1b[' + slice.call(arguments).join(';') + 'i'); + return this._write('\x1b[' + slice.call(arguments).join(';') + 'i'); }; Program.prototype.print_screen = @@ -2913,7 +2864,7 @@ Program.prototype.mc5p = function() { // If no parameters are given, all resources are reset to their // initial values. Program.prototype.setResources = function() { - return this.write('\x1b[>' + slice.call(arguments).join(';') + 'm'); + return this._write('\x1b[>' + slice.call(arguments).join(';') + 'm'); }; // CSI > Ps n @@ -2930,7 +2881,7 @@ Program.prototype.setResources = function() { // adding a parameter to each function key to denote the modi- // fiers. Program.prototype.disableModifiers = function(param) { - return this.write('\x1b[>' + (param || '') + 'n'); + return this._write('\x1b[>' + (param || '') + 'n'); }; // CSI > Ps p @@ -2942,7 +2893,7 @@ Program.prototype.disableModifiers = function(param) { // Ps = 2 -> always hide the pointer. If no parameter is // given, xterm uses the default, which is 1 . Program.prototype.setPointerMode = function(param) { - return this.write('\x1b[>' + (param || '') + 'p'); + return this._write('\x1b[>' + (param || '') + 'p'); }; // CSI ! p Soft terminal reset (DECSTR). @@ -2953,9 +2904,9 @@ Program.prototype.softReset = function() { //if (this.tput) return this.put.init_2string(); //if (this.tput) return this.put.reset_2string(); if (this.tput) return this.put.rs2(); - //return this.write('\x1b[!p'); - //return this.write('\x1b[!p\x1b[?3;4l\x1b[4l\x1b>'); // init - return this.write('\x1b[!p\x1b[?3;4l\x1b[4l\x1b>'); // reset + //return this._write('\x1b[!p'); + //return this._write('\x1b[!p\x1b[?3;4l\x1b[4l\x1b>'); // init + return this._write('\x1b[!p\x1b[?3;4l\x1b[4l\x1b>'); // reset }; // CSI Ps$ p @@ -2970,7 +2921,7 @@ Program.prototype.softReset = function() { // 4 - permanently reset Program.prototype.decrqm = Program.prototype.requestAnsiMode = function(param) { - return this.write('\x1b[' + (param || '') + '$p'); + return this._write('\x1b[' + (param || '') + '$p'); }; // CSI ? Ps$ p @@ -2980,7 +2931,7 @@ Program.prototype.requestAnsiMode = function(param) { // as in the ANSI DECRQM. Program.prototype.decrqmp = Program.prototype.requestPrivateMode = function(param) { - return this.write('\x1b[?' + (param || '') + '$p'); + return this._write('\x1b[?' + (param || '') + '$p'); }; // CSI Ps ; Ps " p @@ -2995,7 +2946,7 @@ Program.prototype.requestPrivateMode = function(param) { // Ps = 2 -> 8-bit controls. Program.prototype.decscl = Program.prototype.setConformanceLevel = function() { - return this.write('\x1b[' + slice.call(arguments).join(';') + '"p'); + return this._write('\x1b[' + slice.call(arguments).join(';') + '"p'); }; // CSI Ps q Load LEDs (DECLL). @@ -3008,7 +2959,7 @@ Program.prototype.setConformanceLevel = function() { // Ps = 2 3 -> Extinguish Scroll Lock. Program.prototype.decll = Program.prototype.loadLEDs = function(param) { - return this.write('\x1b[' + (param || '') + 'q'); + return this._write('\x1b[' + (param || '') + 'q'); }; // CSI Ps SP q @@ -3048,7 +2999,7 @@ Program.prototype.setCursorStyle = function(param) { if (this.has('Ss')) { return this.put.Ss(param); } - return this.write('\x1b[' + (param || 1) + ' q'); + return this._write('\x1b[' + (param || 1) + ' q'); }; // CSI Ps " q @@ -3059,14 +3010,14 @@ Program.prototype.setCursorStyle = function(param) { // Ps = 2 -> DECSED and DECSEL can erase. Program.prototype.decsca = Program.prototype.setCharProtectionAttr = function(param) { - return this.write('\x1b[' + (param || 0) + '"q'); + return this._write('\x1b[' + (param || 0) + '"q'); }; // CSI ? Pm r // Restore DEC Private Mode Values. The value of Ps previously // saved is restored. Ps values are the same as for DECSET. Program.prototype.restorePrivateValues = function() { - return this.write('\x1b[?' + slice.call(arguments).join(';') + 'r'); + return this._write('\x1b[?' + slice.call(arguments).join(';') + 'r'); }; // CSI Pt; Pl; Pb; Pr; Ps$ r @@ -3076,14 +3027,14 @@ Program.prototype.restorePrivateValues = function() { // NOTE: xterm doesn't enable this code by default. Program.prototype.deccara = Program.prototype.setAttrInRectangle = function() { - return this.write('\x1b[' + slice.call(arguments).join(';') + '$r'); + return this._write('\x1b[' + slice.call(arguments).join(';') + '$r'); }; // CSI ? Pm s // Save DEC Private Mode Values. Ps values are the same as for // DECSET. Program.prototype.savePrivateValues = function(params) { - return this.write('\x1b[?' + slice.call(arguments).join(';') + 's'); + return this._write('\x1b[?' + slice.call(arguments).join(';') + 's'); }; // CSI Ps ; Ps ; Ps t @@ -3155,7 +3106,7 @@ Program.prototype.getWindowSize = function(callback) { // NOTE: xterm doesn't enable this code by default. Program.prototype.decrara = Program.prototype.reverseAttrInRectangle = function(params) { - return this.write('\x1b[' + slice.call(arguments).join(';') + '$t'); + return this._write('\x1b[' + slice.call(arguments).join(';') + '$t'); }; // CSI > Ps; Ps t @@ -3167,7 +3118,7 @@ Program.prototype.reverseAttrInRectangle = function(params) { // Ps = 3 -> Query window/icon labels using UTF-8. (See dis- // cussion of "Title Modes") Program.prototype.setTitleModeFeature = function(params) { - return this.write('\x1b[>' + slice.call(arguments).join(';') + 't'); + return this._write('\x1b[>' + slice.call(arguments).join(';') + 't'); }; // CSI Ps SP t @@ -3177,7 +3128,7 @@ Program.prototype.setTitleModeFeature = function(params) { // Ps = 5 , 6 , 7 , or 8 -> high. Program.prototype.decswbv = Program.prototype.setWarningBellVolume = function(params) { - return this.write('\x1b[' + (param || '') + ' t'); + return this._write('\x1b[' + (param || '') + ' t'); }; // CSI Ps SP u @@ -3187,7 +3138,7 @@ Program.prototype.setWarningBellVolume = function(params) { // Ps = 0 , 5 , 6 , 7 , or 8 -> high. Program.prototype.decsmbv = Program.prototype.setMarginBellVolume = function(params) { - return this.write('\x1b[' + (param || '') + ' u'); + return this._write('\x1b[' + (param || '') + ' u'); }; // CSI Pt; Pl; Pb; Pr; Pp; Pt; Pl; Pp$ v @@ -3199,7 +3150,7 @@ Program.prototype.setMarginBellVolume = function(params) { // NOTE: xterm doesn't enable this code by default. Program.prototype.deccra = Program.prototype.copyRectangle = function(params) { - return this.write('\x1b[' + slice.call(arguments).join(';') + '$v'); + return this._write('\x1b[' + slice.call(arguments).join(';') + '$v'); }; // CSI Pt ; Pl ; Pb ; Pr ' w @@ -3215,7 +3166,7 @@ Program.prototype.copyRectangle = function(params) { // cels any prevous rectangle definition. Program.prototype.decefr = Program.prototype.enableFilterRectangle = function(params) { - return this.write('\x1b[' + slice.call(arguments).join(';') + '\'w'); + return this._write('\x1b[' + slice.call(arguments).join(';') + '\'w'); }; // CSI Ps x Request Terminal Parameters (DECREQTPARM). @@ -3231,7 +3182,7 @@ Program.prototype.enableFilterRectangle = function(params) { // Pn = 0 <- STP flags. Program.prototype.decreqtparm = Program.prototype.requestParameters = function(params) { - return this.write('\x1b[' + (param || 0) + 'x'); + return this._write('\x1b[' + (param || 0) + 'x'); }; // CSI Ps x Select Attribute Change Extent (DECSACE). @@ -3240,7 +3191,7 @@ Program.prototype.requestParameters = function(params) { // Ps = 2 -> rectangle (exact). Program.prototype.decsace = Program.prototype.selectChangeExtent = function(params) { - return this.write('\x1b[' + (param || 0) + 'x'); + return this._write('\x1b[' + (param || 0) + 'x'); }; // CSI Pc; Pt; Pl; Pb; Pr$ x @@ -3250,7 +3201,7 @@ Program.prototype.selectChangeExtent = function(params) { // NOTE: xterm doesn't enable this code by default. Program.prototype.decfra = Program.prototype.fillRectangle = function(params) { - return this.write('\x1b[' + slice.call(arguments).join(';') + '$x'); + return this._write('\x1b[' + slice.call(arguments).join(';') + '$x'); }; // CSI Ps ; Pu ' z @@ -3267,7 +3218,7 @@ Program.prototype.fillRectangle = function(params) { // Pu = 2 <- character cells. Program.prototype.decelr = Program.prototype.enableLocatorReporting = function(params) { - return this.write('\x1b[' + slice.call(arguments).join(';') + '\'z'); + return this._write('\x1b[' + slice.call(arguments).join(';') + '\'z'); }; // CSI Pt; Pl; Pb; Pr$ z @@ -3276,7 +3227,7 @@ Program.prototype.enableLocatorReporting = function(params) { // NOTE: xterm doesn't enable this code by default. Program.prototype.decera = Program.prototype.eraseRectangle = function(params) { - return this.write('\x1b[' + slice.call(arguments).join(';') + '$z'); + return this._write('\x1b[' + slice.call(arguments).join(';') + '$z'); }; // CSI Pm ' { @@ -3292,7 +3243,7 @@ Program.prototype.eraseRectangle = function(params) { // Ps = 4 -> do not report button up transitions. Program.prototype.decsle = Program.prototype.setLocatorEvents = function(params) { - return this.write('\x1b[' + slice.call(arguments).join(';') + '\'{'); + return this._write('\x1b[' + slice.call(arguments).join(';') + '\'{'); }; // CSI Pt; Pl; Pb; Pr$ { @@ -3300,7 +3251,7 @@ Program.prototype.setLocatorEvents = function(params) { // Pt; Pl; Pb; Pr denotes the rectangle. Program.prototype.decsera = Program.prototype.selectiveEraseRectangle = function(params) { - return this.write('\x1b[' + slice.call(arguments).join(';') + '${'); + return this._write('\x1b[' + slice.call(arguments).join(';') + '${'); }; // CSI Ps ' | @@ -3364,7 +3315,7 @@ Program.prototype.requestLocatorPosition = function(params, callback) { // NOTE: xterm doesn't enable this code by default. Program.prototype.decic = Program.prototype.insertColumns = function() { - return this.write('\x1b[' + slice.call(arguments).join(';') + ' }'); + return this._write('\x1b[' + slice.call(arguments).join(';') + ' }'); }; // CSI P m SP ~ @@ -3372,60 +3323,61 @@ Program.prototype.insertColumns = function() { // NOTE: xterm doesn't enable this code by default. Program.prototype.decdc = Program.prototype.deleteColumns = function() { - return this.write('\x1b[' + slice.call(arguments).join(';') + ' ~'); -}; - -/** - * A workaround to output sequences without writing to a stream. - */ - -Program.prototype._owrite = function(data) { - this._odata = data; + return this._write('\x1b[' + slice.call(arguments).join(';') + ' ~'); }; Program.prototype.out = function(name) { - var args = slice.call(arguments, 1); - var write = this.write; - this.write = this._owrite; - var receive = this.receive; - this.receive = this._owrite; - this._odata = ''; - this[name].apply(this, args); - this.write = write; - this.receive = receive; - return this._odata; + this.ret = true; + var out = this[name].apply(this, args); + this.ret = false; + return out; }; Program.prototype.sigtstp = function(callback) { + var resume = this.pause(); + + process.once('SIGCONT', function() { + resume(); + if (callback) callback(); + }); + + process.kill(process.pid, 'SIGTSTP'); +}; + +Program.prototype.pause = function(callback) { var self = this , isAlt = this.isAlt - , currentMouse = this._currentMouse; + , mouseEnabled = this.mouseEnabled; - this.lsaveCursor('sigtstp'); + this.lsaveCursor('pause'); //this.csr(0, screen.height - 1); if (isAlt) this.normalBuffer(); this.showCursor(); - if (currentMouse) this.disableMouse(); + if (mouseEnabled) this.disableMouse(); var write = this.output.write; this.output.write = function() {}; this.input.setRawMode(false); this.input.pause(); - process.once('SIGCONT', function() { + return this._resume = function() { + delete self._resume; + self.input.setRawMode(true); self.input.resume(); self.output.write = write; if (isAlt) self.alternateBuffer(); //self.csr(0, screen.height - 1); - if (currentMouse) self.enableMouse(); - self.lrestoreCursor('sigtstp', true); + if (mouseEnabled) self.enableMouse(); + self.lrestoreCursor('pause', true); if (callback) callback(); - }); + }; +}; - process.kill(process.pid, 'SIGTSTP'); +Program.prototype.resume = function(callback) { + if (this._resume) return this._resume(); }; /** diff --git a/lib/widget.js b/lib/widget.js index 8622443..823416f 100644 --- a/lib/widget.js +++ b/lib/widget.js @@ -288,6 +288,7 @@ function Screen(options) { this.program = options.program; this.program.zero = true; this.tput = this.program.tput; + this.output = this.program.output; this.dattr = ((0 << 18) | (0x1ff << 9)) | 0x1ff; @@ -1398,7 +1399,7 @@ Screen.prototype.spawn = function(file, args, options) { , program = screen.program , options = options || {} , spawn = require('child_process').spawn - , mouse = program._currentMouse + , mouse = program.mouseEnabled , ps; options.stdio = 'inherit'; @@ -1555,7 +1556,7 @@ Screen.prototype.sigtstp = function(callback) { this.program.sigtstp(function() { self.alloc(); self.render(); - self.program.lrestoreCursor('sigtstp', true); + self.program.lrestoreCursor('pause', true); if (callback) callback(); }); };