mirror of
https://github.com/embarklabs/neo-blessed.git
synced 2025-01-22 16:59:28 +00:00
work on adding back_color_erase handling, acs optimization, and other stuff ncurses usually handles.
This commit is contained in:
parent
de79656b04
commit
00e680d413
@ -1105,6 +1105,63 @@ Program.prototype.response = function(name, text, callback) {
|
||||
return this.write(text);
|
||||
};
|
||||
|
||||
Program.prototype._wrapCursor = function(nl) {
|
||||
if (this.tput) {
|
||||
//if (this.tput.bools.eat_newline_glitch) {
|
||||
// return;
|
||||
//}
|
||||
if (this.tput.bools.auto_right_margin) {
|
||||
this.x = 0;
|
||||
this.y++;
|
||||
return;
|
||||
}
|
||||
this.x--;
|
||||
return;
|
||||
}
|
||||
this.x = 0;
|
||||
this.y++;
|
||||
};
|
||||
|
||||
// TODO: Make a private write for all of the methods here
|
||||
// which does not call _parseChar. Make public write call
|
||||
// _parseChar.
|
||||
Program.prototype._parseChar = function(text, attr) {
|
||||
for (var i = 0; i < text.length; i++) {
|
||||
var cs = false;
|
||||
while (text[i] === '\x1b') {
|
||||
i++;
|
||||
if (text[i] === '[' || text === ']') {
|
||||
cs = true;
|
||||
continue;
|
||||
}
|
||||
if (cs && (text[i] === ';' || (text[i] >= '0' && text[i] <= '9'))) {
|
||||
continue;
|
||||
}
|
||||
if (text[i] === '\\' && text[i + 1] === '\x1b') i++;
|
||||
i++;
|
||||
cs = false;
|
||||
break;
|
||||
}
|
||||
if (text[i] === '\n') {
|
||||
if (this.tput
|
||||
&& this.tput.bools.eat_newline_glitch
|
||||
&& this.x >= this.cols) {
|
||||
;
|
||||
} else {
|
||||
this.x = 0;
|
||||
this.y++;
|
||||
}
|
||||
} else if (text[i] === '\r') {
|
||||
this.x = 0;
|
||||
} else {
|
||||
this.x++;
|
||||
if (this.x >= this.width) {
|
||||
this._wrapCursor();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Program.prototype.write =
|
||||
Program.prototype.echo = function(text, attr) {
|
||||
// if (this.output === process.stdout) {
|
||||
@ -1261,6 +1318,9 @@ Program.prototype.return = function() {
|
||||
Program.prototype.nel =
|
||||
Program.prototype.newline =
|
||||
Program.prototype.feed = function() {
|
||||
if (this.tput && this.tput.bools.eat_newline_glitch && this.x >= this.width) {
|
||||
return;
|
||||
}
|
||||
this.x = 0;
|
||||
this.y++;
|
||||
this._ncoords();
|
||||
|
184
lib/widget.js
184
lib/widget.js
@ -677,6 +677,64 @@ Screen.prototype.deleteLine = function(n, y, top, bottom) {
|
||||
}
|
||||
};
|
||||
|
||||
// This is how ncurses does it.
|
||||
// Scroll down (up cursor-wise).
|
||||
// This will only work for top line deletion as opposed to arbitrary lines.
|
||||
Screen.prototype.insertLineNC = function(n, y, top, bottom) {
|
||||
if (!this.tput
|
||||
|| !this.tput.strings.change_scroll_region
|
||||
|| !this.tput.strings.delete_line
|
||||
|| !this.tput.strings.insert_line) return;
|
||||
|
||||
if (y !== top) return this.insertLine.apply(this, arguments);
|
||||
|
||||
this.program.sc();
|
||||
this.program.csr(top, bottom);
|
||||
this.program.cup(top, 0);
|
||||
this.program.dl(n);
|
||||
this.program.csr(0, this.height - 1);
|
||||
// this.program.cup(top, 0);
|
||||
this.program.rc();
|
||||
|
||||
var j = bottom + 1;
|
||||
|
||||
while (n--) {
|
||||
this.lines.splice(j, 0, this.blankLine());
|
||||
this.lines.splice(y, 1);
|
||||
this.olines.splice(j, 0, this.blankLine());
|
||||
this.olines.splice(y, 1);
|
||||
}
|
||||
};
|
||||
|
||||
// This is how ncurses does it.
|
||||
// Scroll up (down cursor-wise).
|
||||
// This will only work for bottom line deletion as opposed to arbitrary lines.
|
||||
Screen.prototype.deleteLineNC = function(n, y, top, bottom) {
|
||||
if (!this.tput
|
||||
|| !this.tput.strings.change_scroll_region
|
||||
|| !this.tput.strings.delete_line
|
||||
|| !this.tput.strings.insert_line) return;
|
||||
|
||||
if (y !== bottom) return this.deleteLine.apply(this, arguments);
|
||||
|
||||
this.program.sc();
|
||||
this.program.csr(top, bottom);
|
||||
this.program.cup(bottom, 0);
|
||||
this.program.write(Array(n + 1).join('\n'));
|
||||
this.program.csr(0, this.height - 1);
|
||||
// this.program.cup(bottom - 1, 0);
|
||||
this.program.rc();
|
||||
|
||||
var j = bottom + 1;
|
||||
|
||||
while (n--) {
|
||||
this.lines.splice(j, 0, this.blankLine());
|
||||
this.lines.splice(y, 1);
|
||||
this.olines.splice(j, 0, this.blankLine());
|
||||
this.olines.splice(y, 1);
|
||||
}
|
||||
};
|
||||
|
||||
Screen.prototype.insertBottom = function(top, bottom) {
|
||||
return this.deleteLine(1, top, top, bottom);
|
||||
};
|
||||
@ -768,12 +826,18 @@ Screen.prototype.draw = function(start, end) {
|
||||
, attr
|
||||
, fg
|
||||
, bg
|
||||
, flags;
|
||||
, flags
|
||||
, acs
|
||||
, bc;
|
||||
|
||||
var lx = -1
|
||||
, ly = -1
|
||||
, o;
|
||||
|
||||
var bcx = -1
|
||||
, bcy = -1
|
||||
, bca = -1;
|
||||
|
||||
// var cx = this.program.x
|
||||
// , cy = this.program.y
|
||||
// , ch = this.program.cursorHidden;
|
||||
@ -797,6 +861,65 @@ Screen.prototype.draw = function(start, end) {
|
||||
data = line[x][0];
|
||||
ch = line[x][1];
|
||||
|
||||
// Take advantage of xterm's back_color_erase
|
||||
// feature by using a lookahead.
|
||||
if (this.tput.bools.back_color_erase && ch === ' ' && line[x + 1]) {
|
||||
var ne = false
|
||||
, cl = true;
|
||||
|
||||
for (var xi = x; xi < this.cols; xi++) {
|
||||
if (line[xi][0] !== data || line[xi][1] !== ' ') {
|
||||
cl = false;
|
||||
break;
|
||||
}
|
||||
if (line[xi][0] !== o[xi][0] || line[xi][1] !== o[xi][1]) {
|
||||
ne = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (cl && ne) {
|
||||
if (data !== attr) {
|
||||
out += this.codeAttr(data);
|
||||
attr = data;
|
||||
}
|
||||
out += this.tput.el(0);
|
||||
for (var xi = x; xi < this.cols; xi++) {
|
||||
o[xi][0] = data;
|
||||
o[xi][1] = ' ';
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// comment the break in the first xi loop above for this to work.
|
||||
// if (!ne) {
|
||||
// attr = data;
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
|
||||
// Take advantage of xterm's back_color_erase feature.
|
||||
// Stop spitting out so many damn spaces.
|
||||
if (0) if (this.tput.bools.back_color_erase) {
|
||||
if (ch === ' ' && (bca === -1 || bca === data)) {
|
||||
if (bcy === -1) {
|
||||
bcx = x;
|
||||
bcy = y;
|
||||
bca = data;
|
||||
}
|
||||
//ch = '';
|
||||
} else if (bcy !== -1) {
|
||||
// If it's more than ten spaces, just EL and jump forward.
|
||||
// Might break things since it could alter the output buffer.
|
||||
// out += x - bcx > 10
|
||||
// ? this.tput.el(0) + this.tput.cuf(x - bcx)
|
||||
// : Array((x - bcx) + 1).join(' ');
|
||||
out += Array((x - bcx) + 1).join(' ');
|
||||
bcx = -1, bcy = -1, bca = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Optimize by comparing the real output
|
||||
// buffer to the pending output buffer.
|
||||
if (data === o[x][0] && ch === o[x][1]) {
|
||||
if (lx === -1) {
|
||||
lx = x;
|
||||
@ -890,6 +1013,7 @@ Screen.prototype.draw = function(start, end) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// Attempt to use ACS for supported characters.
|
||||
// This is not ideal, but it's how ncurses works.
|
||||
// There are a lot of terminals that support ACS
|
||||
@ -929,15 +1053,50 @@ Screen.prototype.draw = function(start, end) {
|
||||
// ch = this.tput.utoa[ch] || '?';
|
||||
// }
|
||||
}
|
||||
*/
|
||||
|
||||
if (this.tput.strings.enter_alt_charset_mode) {
|
||||
if (!this.tput.brokenACS || !this.tput.unicode) {
|
||||
if (this.tput.acscr[ch]) {
|
||||
if (acs) {
|
||||
ch = this.tput.acscr[ch];
|
||||
} else {
|
||||
ch = this.tput.smacs()
|
||||
+ this.tput.acscr[ch]
|
||||
acs = true;
|
||||
}
|
||||
} else if (acs) {
|
||||
ch = this.tput.rmacs() + ch;
|
||||
acs = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// if (this.program.term('sun') && ch > '~') {
|
||||
// if (this.tput.numbers.U8 !== 1 && ch > '~') {
|
||||
if (this.tput.numbers.U8 !== 1 && this.utoa[ch]) {
|
||||
ch = this.tput.utoa[ch] || '?';
|
||||
}
|
||||
}
|
||||
|
||||
if (0) if (bcy !== -1) ch = '';
|
||||
|
||||
out += ch;
|
||||
attr = data;
|
||||
}
|
||||
|
||||
if (0) if (bcy !== -1) {
|
||||
out += this.tput.el(0);
|
||||
bcx = -1, bcy = -1, bca = -1;
|
||||
}
|
||||
|
||||
if (attr !== this.dattr) {
|
||||
out += '\x1b[m';
|
||||
}
|
||||
|
||||
//if (this.tput.bools.back_color_erase && out && lx === -1) {
|
||||
// out = this._replaceSpaces(out);
|
||||
//}
|
||||
|
||||
if (this.tput) {
|
||||
if (out) this.program.write(this.tput.cup(y, 0) + out);
|
||||
} else {
|
||||
@ -951,6 +1110,27 @@ Screen.prototype.draw = function(start, end) {
|
||||
this.program.restoreCursor();
|
||||
};
|
||||
|
||||
Screen.prototype._replaceSpaces = function(out) {
|
||||
if (!this._sr) this._sr = this._spaceReplacer.bind(this);
|
||||
return out.replace(/ {5,}/g, this._sr);
|
||||
};
|
||||
|
||||
Screen.prototype._spaceReplacer = function(ch) {
|
||||
return this.tput.el(0) + this.tput.cuf(ch.length);
|
||||
};
|
||||
|
||||
Screen.prototype._replaceSpaces = function(out) {
|
||||
if (!this._sr) this._sr = this._spaceReplacer.bind(this);
|
||||
// / +(?=(?:\x1b\[m)?(?:\x1b\[[\d;]*H|$))/g,
|
||||
return out.replace(
|
||||
/ {5,}(?=(?:\x1b\[[\d;]*m)*(?:\x1b\[[\d;]*H|$))/g,
|
||||
this._sr);
|
||||
};
|
||||
|
||||
Screen.prototype._spaceReplacer = function(ch) {
|
||||
return this.tput.el(0);
|
||||
};
|
||||
|
||||
Screen.prototype._reduceColor = function(col) {
|
||||
if (this.tput) {
|
||||
if (col >= 16 && this.tput.colors <= 16) {
|
||||
@ -1633,7 +1813,7 @@ Element.prototype._focus = function() {
|
||||
, visible = el.height - el.iheight;
|
||||
|
||||
if (ryi < el.childBase) {
|
||||
el.scrollTo(ryi - 0);
|
||||
el.scrollTo(ryi);
|
||||
this.screen.render();
|
||||
} else if (ryi >= el.childBase + visible) {
|
||||
el.scrollTo(ryi);
|
||||
|
@ -12,7 +12,7 @@ var form = blessed.form({
|
||||
height: 12,
|
||||
bg: 'green',
|
||||
content: 'foobar',
|
||||
border: {
|
||||
border_: {
|
||||
type: 'ch',
|
||||
ch: ' ',
|
||||
style: { inverse: true }
|
||||
|
Loading…
x
Reference in New Issue
Block a user