From cc863af2cfe1dcbefd139114a5b6c345dd396419 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Fri, 12 Jul 2013 00:00:11 -0500 Subject: [PATCH] zero indexed program to mirror tput. --- lib/program.js | 149 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 106 insertions(+), 43 deletions(-) diff --git a/lib/program.js b/lib/program.js index 1be5b8a..d671bb3 100644 --- a/lib/program.js +++ b/lib/program.js @@ -35,12 +35,17 @@ function Program(options) { this.input = options.input || process.stdin; this.output = options.output || process.stdout; - this.x = 1; - this.y = 1; + this.zero = options.zero; + + this.x = 0; + this.y = 0; this.cols = this.output.columns || 1; this.rows = this.output.rows || 1; + this.scrollTop = 0; + this.scrollBottom = this.rows - 1; + this.terminal = options.terminal || process.env.TERM || 'xterm'; if (options.tput) { @@ -49,14 +54,6 @@ function Program(options) { this.listen(); - if (options.zero) { - this.ti = 0; - this.ni = 1; - } else { - this.ti = -1; - this.ni = 0; - } - //if (!Program.global) { // Program._write = process.stdout.write; // process.stdout.write = function() {}; @@ -711,6 +708,13 @@ Program.prototype.echo = function(text, attr) { : this.output.write(text); }; +Program.prototype._ncoords = function() { + if (this.x < 0) this.x = 0; + else if (this.x >= this.cols) this.x = this.cols - 1; + if (this.y < 0) this.y = 0; + else if (this.y >= this.rows) this.y = this.rows - 1; +}; + Program.prototype.setx = function(x) { return this.cursorCharAbsolute(x); // return this.charPosAbsolute(x); @@ -772,6 +776,7 @@ Program.prototype.bell = function() { Program.prototype.vtab = function() { this.y++; + this._ncoords(); return this.write('\x0b'); }; @@ -782,6 +787,7 @@ Program.prototype.form = function() { Program.prototype.kbs = Program.prototype.backspace = function() { this.x--; + this._ncoords(); if (this.tput) return this.put.kbs(); return this.write('\x08'); }; @@ -789,6 +795,7 @@ Program.prototype.backspace = function() { Program.prototype.ht = Program.prototype.tab = function() { this.x += 8; + this._ncoords(); if (this.tput) return this.put.ht(); // or `tab` return this.write('\t'); }; @@ -803,7 +810,7 @@ Program.prototype.shiftIn = function() { Program.prototype.cr = Program.prototype.return = function() { - this.x = 1; + this.x = 0; if (this.tput) return this.put.cr(); return this.write('\r'); }; @@ -811,8 +818,9 @@ Program.prototype.return = function() { Program.prototype.nel = Program.prototype.newline = Program.prototype.feed = function() { - this.x = 1; + this.x = 0; this.y++; + this._ncoords(); if (this.tput) return this.put.nel(); return this.write('\n'); }; @@ -829,6 +837,7 @@ Program.prototype.esc = function(code) { Program.prototype.ind = Program.prototype.index = function() { this.y++; + this._ncoords(); if (this.tput) return this.put.ind(); return this.write('\x1bD'); }; @@ -838,6 +847,7 @@ Program.prototype.ri = Program.prototype.reverse = Program.prototype.reverseIndex = function() { this.y--; + this._ncoords(); if (this.tput) return this.put.ri(); return this.write('\x1bM'); }; @@ -845,14 +855,15 @@ Program.prototype.reverseIndex = function() { // ESC E Next Line (NEL is 0x85). Program.prototype.nextLine = function() { this.y++; - this.x = 1; + this.x = 0; + this._ncoords(); if (this.tput) return this.put.nel(); return this.write('\x1bE'); }; // ESC c Full Reset (RIS). Program.prototype.reset = function() { - //this.x = this.y = 1; + //this.x = this.y = 0; if (this.tput) return this.put.rs1 ? this.put.rs1() : this.put.ris(); return this.write('\x1bc'); }; @@ -866,8 +877,8 @@ Program.prototype.tabSet = function() { // ESC 7 Save Cursor (DECSC). Program.prototype.sc = Program.prototype.saveCursor = function() { - this.savedX = this.x || 1; - this.savedY = this.y || 1; + this.savedX = this.x || 0; + this.savedY = this.y || 0; if (this.tput) return this.put.sc(); return this.esc('7'); }; @@ -875,8 +886,8 @@ Program.prototype.saveCursor = function() { // ESC 8 Restore Cursor (DECRC). Program.prototype.rc = Program.prototype.restoreCursor = function() { - this.x = this.savedX || 1; - this.y = this.savedY || 1; + this.x = this.savedX || 0; + this.y = this.savedY || 0; if (this.tput) return this.put.rc(); return this.esc('8'); }; @@ -1089,6 +1100,7 @@ Program.prototype.cuu = Program.prototype.up = 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'); }; @@ -1099,6 +1111,7 @@ Program.prototype.cud = Program.prototype.down = 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'); }; @@ -1110,6 +1123,7 @@ Program.prototype.right = Program.prototype.forward = 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'); }; @@ -1121,6 +1135,7 @@ Program.prototype.left = Program.prototype.back = 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'); }; @@ -1130,10 +1145,18 @@ Program.prototype.cursorBackward = function(param) { Program.prototype.cup = Program.prototype.pos = Program.prototype.cursorPos = function(row, col) { - this.x = col || 1; - this.y = row || 1; - if (this.tput) return this.put.cup((row || 1) - 1, (col || 1) - 1); - return this.write('\x1b[' + (row || '1') + ';' + (col || '1') + 'H'); + if (!this.zero) { + row = (row || 1) - 1; + col = (col || 1) - 1; + } else { + row = row || 0; + col = col || 0; + } + this.x = col; + this.y = row; + this._ncoords(); + if (this.tput) return this.put.cup(row, col); + return this.write('\x1b[' + (row + 1) + ';' + (col + 1) + 'H'); }; // CSI Ps J Erase in Display (ED). @@ -1604,6 +1627,7 @@ Program.prototype.getCursor = function(callback) { Program.prototype.ich = 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) + '@'); }; @@ -1614,6 +1638,7 @@ Program.prototype.insertChars = function(param) { Program.prototype.cnl = Program.prototype.cursorNextLine = function(param) { this.y += param || 1; + this._ncoords(); return this.write('\x1b[' + (param || '') + 'E'); }; @@ -1623,6 +1648,7 @@ Program.prototype.cursorNextLine = function(param) { Program.prototype.cpl = Program.prototype.cursorPrecedingLine = function(param) { this.y -= param || 1; + this._ncoords(); return this.write('\x1b[' + (param || '') + 'F'); }; @@ -1630,10 +1656,16 @@ Program.prototype.cursorPrecedingLine = function(param) { // Cursor Character Absolute [column] (default = [row,1]) (CHA). Program.prototype.cha = Program.prototype.cursorCharAbsolute = function(param) { - this.x = param || 1; - this.y = 1; + if (!this.zero) { + param = (param || 1) - 1; + } else { + param = param || 0; + } + this.x = param; + this.y = 0; + this._ncoords(); if (this.tput) return this.put.cha(param); - return this.write('\x1b[' + (param || '') + 'G'); + return this.write('\x1b[' + (param + 1) + 'G'); }; // CSI Ps L @@ -1670,10 +1702,14 @@ Program.prototype.eraseChars = function(param) { // CSI Pm ` Character Position Absolute // [column] (default = [row,1]) (HPA). +// NOTE: Can't find in terminfo, no idea why it has multiple params. Program.prototype.hpa = -Program.prototype.charPosAbsolute = function() { - this.x = arguments[0] || 1; - if (this.tput) return this.put.hpa.apply(this.put, arguments); +Program.prototype.charPosAbsolute = function(param) { + this.x = param || 0; + this._ncoords(); + if (this.tput) { + return this.put.hpa.apply(this.put, arguments); + } var param = Array.prototype.slice.call(arguments).join(';'); return this.write('\x1b[' + (param || '') + '`'); }; @@ -1684,6 +1720,7 @@ Program.prototype.charPosAbsolute = function() { Program.prototype.hpr = Program.prototype.HPositionRelative = function(param) { this.x += param || 1; + this._ncoords(); // Does not exist: // if (this.tput) return this.put.hpr(param); if (this.tput) return this.put.cuf(param); @@ -1738,10 +1775,14 @@ Program.prototype.sendDeviceAttributes = function(param, callback) { // CSI Pm d // Line Position Absolute [row] (default = [1,column]) (VPA). +// NOTE: Can't find in terminfo, no idea why it has multiple params. Program.prototype.vpa = -Program.prototype.linePosAbsolute = function() { - this.y = arguments[0] || 1; - if (this.tput) return this.put.vpa.apply(this.put, arguments); +Program.prototype.linePosAbsolute = function(param) { + this.y = param || 1; + this._ncoords(); + if (this.tput) { + return this.put.vpa.apply(this.put, arguments); + } var param = Array.prototype.slice.call(arguments).join(';'); return this.write('\x1b[' + (param || '') + 'd'); }; @@ -1751,6 +1792,7 @@ Program.prototype.linePosAbsolute = function() { Program.prototype.vpr = Program.prototype.VPositionRelative = function(param) { this.y += param || 1; + this._ncoords(); // Does not exist: // if (this.tput) return this.put.vpr(param); if (this.tput) return this.put.cud(param); @@ -1762,12 +1804,20 @@ Program.prototype.VPositionRelative = function(param) { // [1,1]) (HVP). Program.prototype.hvp = Program.prototype.HVPosition = function(row, col) { - this.y += row || 1; - this.x += col || 1; + if (!this.zero) { + row = (row || 1) - 1; + col = (col || 1) - 1; + } else { + row = row || 0; + col = col || 0; + } + this.y = row; + this.x = col; + this._ncoords(); // Does not exist (?): // if (this.tput) return this.put.hvp(row, col); - if (this.tput) return this.put.cup((row || 1) - 1, (col || 1) - 1); - return this.write('\x1b[' + (row || '1') + ';' + (col || '1') + 'f'); + if (this.tput) return this.put.cup(row, col); + return this.write('\x1b[' + (row + 1) + ';' + (col + 1) + 'f'); }; // CSI Pm h Set Mode (SM). @@ -2145,12 +2195,20 @@ Program.prototype.setMouse = function(opt, enable) { Program.prototype.decstbm = Program.prototype.csr = Program.prototype.setScrollRegion = function(top, bottom) { - this.scrollTop = (top || 1) - 1; - this.scrollBottom = (bottom || this.rows) - 1; - this.x = 1; - this.y = 1; - if (this.tput) return this.put.csr((top || 1) - 1, (bottom || 1) - 1); - return this.write('\x1b[' + (top || 1) + ';' + (bottom || this.rows) + 'r'); + if (!this.zero) { + top = (top || 1) - 1; + bottom = (bottom || this.rows) - 1; + } else { + top = top || 0; + bottom = bottom || (this.rows - 1); + } + this.scrollTop = top; + this.scrollBottom = bottom; + this.x = 0; + this.y = 0; + this._ncoords(); + if (this.tput) return this.put.csr(top, bottom); + return this.write('\x1b[' + (top + 1) + ';' + (bottom + 1) + 'r'); }; // CSI s @@ -2167,8 +2225,8 @@ Program.prototype.saveCursorA = function() { // Restore cursor (ANSI.SYS). Program.prototype.rcA = Program.prototype.restoreCursorA = function() { - this.x = this.savedX || 1; - this.y = this.savedY || 1; + this.x = this.savedX || 0; + this.y = this.savedY || 0; if (this.tput) return this.put.rc(); return this.write('\x1b[u'); }; @@ -2182,6 +2240,7 @@ Program.prototype.restoreCursorA = function() { Program.prototype.cht = Program.prototype.cursorForwardTab = function(param) { this.x += 8; + this._ncoords(); // Does not exit (?): // if (this.tput) return this.put.cht(param); if (this.tput) return this.put.tab(param); // or this.put.ht @@ -2192,6 +2251,7 @@ Program.prototype.cursorForwardTab = function(param) { Program.prototype.su = Program.prototype.scrollUp = function(param) { this.y -= param || 1; + this._ncoords(); // Does not exit: // if (this.tput) return this.put.su(param); if (this.tput) return this.put.rin(param); @@ -2202,6 +2262,7 @@ Program.prototype.scrollUp = function(param) { Program.prototype.sd = Program.prototype.scrollDown = function(param) { this.y += param || 1; + this._ncoords(); // Does not exit: // if (this.tput) return this.put.sd(param); if (this.tput) return this.put.indn(param); @@ -2235,6 +2296,7 @@ Program.prototype.resetTitleModes = function() { Program.prototype.cbt = 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'); }; @@ -2243,6 +2305,7 @@ Program.prototype.cursorBackwardTab = function(param) { Program.prototype.rep = 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'); };