assume screen.tput is present.

This commit is contained in:
Christopher Jeffrey 2013-08-27 08:58:53 -05:00
parent e563155b0e
commit f8c2ebef1d

View File

@ -12,8 +12,10 @@
var EventEmitter = require('./events').EventEmitter var EventEmitter = require('./events').EventEmitter
, assert = require('assert') , assert = require('assert')
, path = require('path') , path = require('path')
, fs = require('fs') , fs = require('fs');
, colors = require('./colors')
var colors = require('./colors')
, program = require('./program')
, widget = exports; , widget = exports;
/** /**
@ -248,8 +250,6 @@ function Screen(options) {
options = { program: options }; options = { program: options };
} }
var program = require('./program');
this.program = options.program || program.global; this.program = options.program || program.global;
if (!this.program) { if (!this.program) {
@ -604,6 +604,7 @@ Screen.prototype.render = function() {
this.emit('prerender'); this.emit('prerender');
// TODO: Possibly get rid of .dirty altogether.
// TODO: Could possibly drop .dirty and just clear the `lines` buffer every // TODO: Could possibly drop .dirty and just clear the `lines` buffer every
// time before a screen.render. This way clearRegion doesn't have to be // time before a screen.render. This way clearRegion doesn't have to be
// called in arbitrary places for the sake of clearing a spot where an // called in arbitrary places for the sake of clearing a spot where an
@ -636,8 +637,7 @@ Screen.prototype.blankLine = function(ch, dirty) {
Screen.prototype.insertLine = function(n, y, top, bottom) { Screen.prototype.insertLine = function(n, y, top, bottom) {
// if (y === top) return this.insertLineNC(n, y, top, bottom); // if (y === top) return this.insertLineNC(n, y, top, bottom);
if (!this.tput if (!this.tput.strings.change_scroll_region
|| !this.tput.strings.change_scroll_region
|| !this.tput.strings.delete_line || !this.tput.strings.delete_line
|| !this.tput.strings.insert_line) return; || !this.tput.strings.insert_line) return;
@ -659,8 +659,7 @@ Screen.prototype.insertLine = function(n, y, top, bottom) {
Screen.prototype.deleteLine = function(n, y, top, bottom) { Screen.prototype.deleteLine = function(n, y, top, bottom) {
// if (y === top) return this.deleteLineNC(n, y, top, bottom); // if (y === top) return this.deleteLineNC(n, y, top, bottom);
if (!this.tput if (!this.tput.strings.change_scroll_region
|| !this.tput.strings.change_scroll_region
|| !this.tput.strings.delete_line || !this.tput.strings.delete_line
|| !this.tput.strings.insert_line) return; || !this.tput.strings.insert_line) return;
@ -683,8 +682,7 @@ Screen.prototype.deleteLine = function(n, y, top, bottom) {
// Scroll down (up cursor-wise). // Scroll down (up cursor-wise).
// This will only work for top line deletion as opposed to arbitrary lines. // This will only work for top line deletion as opposed to arbitrary lines.
Screen.prototype.insertLineNC = function(n, y, top, bottom) { Screen.prototype.insertLineNC = function(n, y, top, bottom) {
if (!this.tput if (!this.tput.strings.change_scroll_region
|| !this.tput.strings.change_scroll_region
|| !this.tput.strings.delete_line) return; || !this.tput.strings.delete_line) return;
this._buf += this.tput.csr(top, bottom); this._buf += this.tput.csr(top, bottom);
@ -706,8 +704,7 @@ Screen.prototype.insertLineNC = function(n, y, top, bottom) {
// Scroll up (down cursor-wise). // Scroll up (down cursor-wise).
// This will only work for bottom line deletion as opposed to arbitrary lines. // This will only work for bottom line deletion as opposed to arbitrary lines.
Screen.prototype.deleteLineNC = function(n, y, top, bottom) { Screen.prototype.deleteLineNC = function(n, y, top, bottom) {
if (!this.tput if (!this.tput.strings.change_scroll_region
|| !this.tput.strings.change_scroll_region
|| !this.tput.strings.delete_line) return; || !this.tput.strings.delete_line) return;
this._buf += this.tput.csr(top, bottom); this._buf += this.tput.csr(top, bottom);
@ -754,11 +751,6 @@ Screen.prototype.deleteTop = function(top, bottom) {
Screen.prototype.cleanSides = function(el) { Screen.prototype.cleanSides = function(el) {
var pos = el.lpos; var pos = el.lpos;
// If we don't have tput, we can't use CSR anyway.
// if (!this.tput) {
// return false;
// }
if (!pos) { if (!pos) {
return false; return false;
} }
@ -860,7 +852,6 @@ Screen.prototype.draw = function(start, end) {
line = this.lines[y]; line = this.lines[y];
o = this.olines[y]; o = this.olines[y];
// TODO: Possibly get rid of .dirty altogether.
if (!line.dirty) continue; if (!line.dirty) continue;
line.dirty = false; line.dirty = false;
@ -876,7 +867,7 @@ Screen.prototype.draw = function(start, end) {
// the bg for non BCE terminals worth the overhead? // the bg for non BCE terminals worth the overhead?
if (this.options.useBCE if (this.options.useBCE
&& ch === ' ' && ch === ' '
&& ((this.tput && this.tput.bools.back_color_erase) && (this.tput.bools.back_color_erase
|| (data & 0x1ff) === (this.dattr & 0x1ff)) || (data & 0x1ff) === (this.dattr & 0x1ff))
&& ((data >> 18) & 8) === ((this.dattr >> 18) & 8)) { && ((data >> 18) & 8) === ((this.dattr >> 18) & 8)) {
clr = true; clr = true;
@ -898,12 +889,8 @@ Screen.prototype.draw = function(start, end) {
out += this.codeAttr(data); out += this.codeAttr(data);
attr = data; attr = data;
} }
out += this.tput out += this.tput.cup(y, x);
? this.tput.cup(y, x) out += this.tput.el();
: '\x1b[' + (y + 1) + ';' + (x + 1) + 'H';
out += this.tput
? this.tput.el(0)
: '\x1b[K';
for (xx = x; xx < this.cols; xx++) { for (xx = x; xx < this.cols; xx++) {
o[xx][0] = data; o[xx][0] = data;
o[xx][1] = ' '; o[xx][1] = ' ';
@ -915,31 +902,23 @@ Screen.prototype.draw = function(start, end) {
// and start over drawing the rest of line. Might // and start over drawing the rest of line. Might
// not be worth it. Try to use ECH if the terminal // not be worth it. Try to use ECH if the terminal
// supports it. Maybe only try to use ECH here. // supports it. Maybe only try to use ECH here.
// //if (this.tput && this.tput.strings.erase_chars) // //if (this.tput.strings.erase_chars)
// if (!clr && neq && (xx - x) > 10) { // if (!clr && neq && (xx - x) > 10) {
// lx = -1, ly = -1; // lx = -1, ly = -1;
// if (data !== attr) { // if (data !== attr) {
// out += this.codeAttr(data); // out += this.codeAttr(data);
// attr = data; // attr = data;
// } // }
// out += this.tput // out += this.tput.cup(y, x);
// ? this.tput.cup(y, x) // if (this.tput.strings.erase_chars) {
// : '\x1b[' + (y + 1) + ';' + (x + 1) + 'H';
// if (this.tput && this.tput.strings.erase_chars) {
// // Use erase_chars to avoid erasing the whole line. // // Use erase_chars to avoid erasing the whole line.
// out += this.tput // out += this.tput.ech(xx - x);
// ? this.tput.ech(xx - x)
// : '\x1b[' + (xx - x) + 'X';
// } else { // } else {
// out += this.tput // out += this.tput.el();
// ? this.tput.el(0)
// : '\x1b[K';
// } // }
// out += this.tput // out += this.tput.cuf(xx - x);
// ? this.tput.cuf(xx - x)
// : '\x1b[' + (xx - x) + 'C';
// this.fillRegion(data, ' ', // this.fillRegion(data, ' ',
// x, this.tput && this.tput.strings.erase_chars ? xx : this.cols, // x, this.tput.strings.erase_chars ? xx : this.cols,
// y, y + 1); // y, y + 1);
// x = xx - 1; // x = xx - 1;
// continue; // continue;
@ -970,15 +949,9 @@ Screen.prototype.draw = function(start, end) {
} }
continue; continue;
} else if (lx !== -1) { } else if (lx !== -1) {
if (this.tput) { out += y === ly
out += y === ly ? this.tput.cuf(x - lx)
? this.tput.cuf(x - lx) : this.tput.cup(y, x);
: this.tput.cup(y, x);
} else {
out += y === ly
? '\x1b[' + (x - lx) + 'C'
: '\x1b[' + (y + 1) + ';' + (x + 1) + 'H';
}
lx = -1, ly = -1; lx = -1, ly = -1;
} }
o[x][0] = data; o[x][0] = data;
@ -1069,36 +1042,34 @@ Screen.prototype.draw = function(start, end) {
// supports UTF8, but I imagine it's unlikely. // supports UTF8, but I imagine it's unlikely.
// Maybe remove !this.tput.unicode check, however, // Maybe remove !this.tput.unicode check, however,
// this seems to be the way ncurses does it. // this seems to be the way ncurses does it.
if (this.tput) { if (this.tput.strings.enter_alt_charset_mode) {
if (this.tput.strings.enter_alt_charset_mode) { //if (!this.tput.brokenACS || !this.tput.unicode) {
//if (!this.tput.brokenACS || !this.tput.unicode) { if (!this.tput.brokenACS) {
if (!this.tput.brokenACS) { if (this.tput.acscr[ch]) {
if (this.tput.acscr[ch]) { if (acs) {
if (acs) { ch = this.tput.acscr[ch];
ch = this.tput.acscr[ch]; } else {
} else { ch = this.tput.smacs()
ch = this.tput.smacs() + this.tput.acscr[ch];
+ this.tput.acscr[ch]; acs = true;
acs = true;
}
} else if (acs) {
ch = this.tput.rmacs() + ch;
acs = false;
} }
} else if (acs) {
ch = this.tput.rmacs() + ch;
acs = false;
} }
} else { }
// U8 is not consistently correct. Some terminfo's } else {
// terminals that do not declare it may actually // U8 is not consistently correct. Some terminfo's
// support utf8 (e.g. urxvt), but if the terminal // terminals that do not declare it may actually
// does not declare support for ACS (and U8), chances // support utf8 (e.g. urxvt), but if the terminal
// are it does not support UTF8. This is probably // does not declare support for ACS (and U8), chances
// the "safest" way to do this. Should fix things // are it does not support UTF8. This is probably
// like sun-color. // the "safest" way to do this. Should fix things
// if (this.tput.numbers.U8 !== 1 && ch > '~') { // like sun-color.
// if ((!this.unicode || this.tput.numbers.U8 !== 1) && this.tput.utoa[ch]) { // if (this.tput.numbers.U8 !== 1 && ch > '~') {
if (this.tput.numbers.U8 !== 1 && this.tput.utoa[ch]) { // if ((!this.unicode || this.tput.numbers.U8 !== 1) && this.tput.utoa[ch]) {
ch = this.tput.utoa[ch] || '?'; if (this.tput.numbers.U8 !== 1 && this.tput.utoa[ch]) {
} ch = this.tput.utoa[ch] || '?';
} }
} }
@ -1113,9 +1084,7 @@ Screen.prototype.draw = function(start, end) {
} }
if (out) { if (out) {
main += this.tput main += this.tput.cup(y, 0) + out;
? this.tput.cup(y, 0) + out
: '\x1b[' + (y + 1) + ';1H' + out;
} }
} }
@ -1128,20 +1097,12 @@ Screen.prototype.draw = function(start, end) {
pre = ''; pre = '';
post = ''; post = '';
pre += this.tput pre += this.tput.sc();
? this.tput.sc() post += this.tput.rc();
: '\x1b7';
post += this.tput
? this.tput.rc()
: '\x1b8';
if (!this.program.cursorHidden) { if (!this.program.cursorHidden) {
pre += this.tput pre += this.tput.civis();
? this.tput.civis() post += this.tput.cnorm();
: '\x1b[?25l';
post += this.tput
? this.tput.cnorm()
: '\x1b[?25h';
} }
// this.program.flush(); // this.program.flush();
@ -1151,14 +1112,12 @@ Screen.prototype.draw = function(start, end) {
}; };
Screen.prototype._reduceColor = function(col) { Screen.prototype._reduceColor = function(col) {
if (this.tput) { if (col >= 16 && this.tput.colors <= 16) {
if (col >= 16 && this.tput.colors <= 16) { col = colors.ccolors[col];
col = colors.ccolors[col]; } else if (col >= 8 && this.tput.colors <= 8) {
} else if (col >= 8 && this.tput.colors <= 8) { col -= 8;
col -= 8; } else if (col >= 2 && this.tput.colors <= 2) {
} else if (col >= 2 && this.tput.colors <= 2) { col %= 2;
col %= 2;
}
} }
return col; return col;
}; };