Explicit line wraps

This commit is contained in:
Florian Mounier
2015-05-07 15:29:17 +02:00
parent 324b6aa020
commit 78e3050387
4 changed files with 192 additions and 151 deletions

File diff suppressed because one or more lines are too long

View File

@@ -213,12 +213,12 @@
Terminal.prototype.putChar = function(c) {
if (this.insertMode) {
this.screen[this.y + this.shift][0].splice(this.x, 0, this.cloneAttr(this.curAttr, c));
this.screen[this.y + this.shift][0].pop();
this.screen[this.y + this.shift].chars.splice(this.x, 0, this.cloneAttr(this.curAttr, c));
this.screen[this.y + this.shift].chars.pop();
} else {
this.screen[this.y + this.shift][0][this.x] = this.cloneAttr(this.curAttr, c);
this.screen[this.y + this.shift].chars[this.x] = this.cloneAttr(this.curAttr, c);
}
return this.screen[this.y + this.shift][1] = true;
return this.screen[this.y + this.shift].dirty = true;
};
Terminal.prototype.resetVars = function() {
@@ -258,7 +258,7 @@
i = this.rows;
this.shift = 0;
while (i--) {
this.screen.push([this.blankLine(), true]);
this.screen.push(this.blankLine());
}
this.setupStops();
return this.skipNextKey = null;
@@ -294,7 +294,7 @@
Terminal.prototype.blur = function() {
this.cursorState = 1;
this.screen[this.y + this.shift][1] = true;
this.screen[this.y + this.shift].dirty = true;
this.refresh();
if (this.sendFocus) {
this.send('\x1b[O');
@@ -493,7 +493,7 @@
};
Terminal.prototype.refresh = function(force) {
var attr, ch, classes, cursor, data, dirty, fg, group, i, j, k, len, len1, len2, len3, line, lines, m, newOut, o, out, q, ref, ref1, ref2, ref3, ref4, ref5, skipnext, styles, u, x;
var attr, ch, classes, cursor, data, fg, group, i, j, k, len, len1, len2, len3, line, lines, m, newOut, o, out, q, ref, ref1, ref2, ref3, ref4, skipnext, styles, u, x;
if (force == null) {
force = false;
}
@@ -505,8 +505,8 @@
newOut = '';
ref1 = this.screen;
for (j = m = 0, len1 = ref1.length; m < len1; j = ++m) {
ref2 = ref1[j], line = ref2[0], dirty = ref2[1];
if (!(dirty || force)) {
line = ref1[j];
if (!(line.dirty || force)) {
continue;
}
out = "";
@@ -517,8 +517,8 @@
}
attr = this.cloneAttr(this.defAttr);
skipnext = false;
for (i = o = 0, ref3 = this.cols - 1; 0 <= ref3 ? o <= ref3 : o >= ref3; i = 0 <= ref3 ? ++o : --o) {
data = line[i];
for (i = o = 0, ref2 = this.cols - 1; 0 <= ref2 ? o <= ref2 : o >= ref2; i = 0 <= ref2 ? ++o : --o) {
data = line.chars[i];
if (data.html) {
out += data.html;
continue;
@@ -618,12 +618,15 @@
if (j !== this.y + this.shift) {
out = this.linkify(out);
}
if (line.wrap) {
out += '\u23CE';
}
if (this.children[j]) {
this.children[j].innerHTML = out;
} else {
newOut += "<div class=\"line\">" + out + "</div>";
}
this.screen[j][1] = false;
this.screen[j].dirty = false;
}
if (newOut !== '') {
group = this.document.createElement('div');
@@ -634,14 +637,14 @@
this.shift = 0;
lines = document.querySelectorAll('.line');
if (lines.length > this.scrollback) {
ref4 = Array.prototype.slice.call(lines, 0, lines.length - this.scrollback);
for (q = 0, len2 = ref4.length; q < len2; q++) {
line = ref4[q];
ref3 = Array.prototype.slice.call(lines, 0, lines.length - this.scrollback);
for (q = 0, len2 = ref3.length; q < len2; q++) {
line = ref3[q];
line.remove();
}
ref5 = document.querySelectorAll('.group:empty');
for (u = 0, len3 = ref5.length; u < len3; u++) {
group = ref5[u];
ref4 = document.querySelectorAll('.group:empty');
for (u = 0, len3 = ref4.length; u < len3; u++) {
group = ref4[u];
group.remove();
}
lines = document.querySelectorAll('.line');
@@ -670,7 +673,7 @@
Terminal.prototype.showCursor = function() {
if (!this.cursorState) {
this.cursorState = 1;
this.screen[this.y + this.shift][1] = true;
this.screen[this.y + this.shift].dirty = true;
return this.refresh();
}
};
@@ -698,26 +701,26 @@
Terminal.prototype.scroll = function() {
var i, k, ref, ref1, results;
if (this.normal || this.scrollTop !== 0 || this.scrollBottom !== this.rows - 1) {
this.screen.splice(this.shift + this.scrollBottom + 1, 0, [this.blankLine(), true]);
this.screen.splice(this.shift + this.scrollBottom + 1, 0, this.blankLine());
this.screen.splice(this.shift + this.scrollTop, 1);
results = [];
for (i = k = ref = this.scrollTop, ref1 = this.scrollBottom; ref <= ref1 ? k <= ref1 : k >= ref1; i = ref <= ref1 ? ++k : --k) {
results.push(this.screen[i + this.shift][1] = true);
results.push(this.screen[i + this.shift].dirty = true);
}
return results;
} else {
this.screen.push([this.blankLine(), true]);
this.screen.push(this.blankLine());
return this.shift++;
}
};
Terminal.prototype.unscroll = function() {
var i, k, ref, ref1, results;
this.screen.splice(this.shift + this.scrollTop, 0, [this.blankLine(true), true]);
this.screen.splice(this.shift + this.scrollTop, 0, this.blankLine(true));
this.screen.splice(this.shift + this.scrollBottom + 1, 1);
results = [];
for (i = k = ref = this.scrollTop, ref1 = this.scrollBottom; ref <= ref1 ? k <= ref1 : k >= ref1; i = ref <= ref1 ? ++k : --k) {
results.push(this.screen[i + this.shift][1] = true);
results.push(this.screen[i + this.shift].dirty = true);
}
return results;
};
@@ -792,7 +795,7 @@
ch = this.charset[ch];
}
if (this.x >= this.cols) {
this.putChar('\u23CE');
this.screen[this.y + this.shift].wrap = true;
this.x = 0;
this.nextLine();
}
@@ -919,9 +922,9 @@
ref1 = this.screen;
for (k = 0, len = ref1.length; k < len; k++) {
line = ref1[k];
line[1] = true;
for (c = m = 0, ref2 = line[0].length; 0 <= ref2 ? m <= ref2 : m >= ref2; c = 0 <= ref2 ? ++m : --m) {
line[0][c] = this.cloneAttr(this.curAttr, "E");
line.dirty = true;
for (c = m = 0, ref2 = line.chars.length; 0 <= ref2 ? m <= ref2 : m >= ref2; c = 0 <= ref2 ? ++m : --m) {
line.chars[c] = this.cloneAttr(this.curAttr, "E");
}
}
this.x = this.y = 0;
@@ -1192,8 +1195,9 @@
}
attr = this.cloneAttr(this.curAttr);
attr.html = "<div class=\"inline-html\">" + content + "</div>";
this.screen[this.y + this.shift][0][this.x] = attr;
this.screen[this.y + this.shift][1] = true;
this.screen[this.y + this.shift].chars[this.x] = attr;
this.screen[this.y + this.shift].dirty = true;
this.screen[this.y + this.shift].wrap = false;
break;
case "IMAGE":
content = encodeURI(content);
@@ -1206,8 +1210,9 @@
}
attr = this.cloneAttr(this.curAttr);
attr.html = "<img class=\"inline-image\" src=\"data:" + mime + ";base64," + b64 + "\" />";
this.screen[this.y + this.shift][0][this.x] = attr;
this.screen[this.y + this.shift][1] = true;
this.screen[this.y + this.shift].chars[this.x] = attr;
this.screen[this.y + this.shift].dirty = true;
this.screen[this.y + this.shift].wrap = false;
break;
case "PROMPT":
this.send(content);
@@ -1275,7 +1280,7 @@
}
i++;
}
this.screen[this.y + this.shift][1] = true;
this.screen[this.y + this.shift].dirty = true;
return this.refresh();
};
@@ -1589,15 +1594,16 @@
if (oldCols < this.cols) {
i = this.screen.length;
while (i--) {
while (this.screen[i][0].length < this.cols) {
this.screen[i][0].push(this.defAttr);
while (this.screen[i].chars.length < this.cols) {
this.screen[i].chars.push(this.defAttr);
}
this.screen[i].wrap = false;
}
} else if (oldCols > this.cols) {
i = this.screen.length;
while (i--) {
while (this.screen[i][0].length > this.cols) {
this.screen[i][0].pop();
while (this.screen[i].chars.length > this.cols) {
this.screen[i].chars.pop();
}
}
}
@@ -1607,7 +1613,7 @@
el = this.body;
while (j++ < this.rows) {
if (this.screen.length < this.rows) {
this.screen.push([this.blankLine(), true]);
this.screen.push(this.blankLine());
}
if (this.children.length < this.rows) {
line = this.document.createElement("div");
@@ -1700,20 +1706,22 @@
Terminal.prototype.eraseRight = function(x, y) {
var line;
line = this.screen[y + this.shift][0];
line = this.screen[y + this.shift].chars;
while (x < this.cols) {
line[x] = this.eraseAttr();
x++;
}
return this.screen[y + this.shift][1] = true;
this.screen[y + this.shift].dirty = true;
return this.screen[y + this.shift].wrap = false;
};
Terminal.prototype.eraseLeft = function(x, y) {
x++;
while (x--) {
this.screen[y + this.shift][0][x] = this.eraseAttr();
this.screen[y + this.shift].chars[x] = this.eraseAttr();
}
return this.screen[y + this.shift][1] = true;
this.screen[y + this.shift].dirty = true;
return this.screen[y + this.shift].wrap = false;
};
Terminal.prototype.eraseLine = function(y) {
@@ -1725,11 +1733,15 @@
attr = (cur ? this.eraseAttr() : this.defAttr);
line = [];
i = 0;
while (i < this.cols + 1) {
while (i < this.cols) {
line[i] = attr;
i++;
}
return line;
return {
chars: line,
dirty: true,
wrap: false
};
};
Terminal.prototype.ch = function(cur) {
@@ -1991,10 +2003,10 @@
row = this.y;
j = this.x;
while (param-- && j < this.cols) {
this.screen[row + this.shift][0].splice(j++, 0, [this.eraseAttr(), true]);
this.screen[row + this.shift][0].pop();
this.screen[row + this.shift].chars.splice(j++, 0, [this.eraseAttr(), true]);
this.screen[row + this.shift].chars.pop();
}
return this.screen[row + this.shift][1] = true;
return this.screen[row + this.shift].dirty = true;
};
Terminal.prototype.cursorNextLine = function(params) {
@@ -2039,12 +2051,12 @@
param = 1;
}
while (param--) {
this.screen.splice(this.y + this.shift, 0, [this.blankLine(true), true]);
this.screen.splice(this.y + this.shift, 0, this.blankLine(true));
this.screen.splice(this.scrollBottom + 1 + this.shift, 1);
}
results = [];
for (i = k = ref = this.y + this.shift, ref1 = this.screen.length - 1; ref <= ref1 ? k <= ref1 : k >= ref1; i = ref <= ref1 ? ++k : --k) {
results.push(this.screen[i][1] = true);
results.push(this.screen[i].dirty = true);
}
return results;
};
@@ -2056,7 +2068,7 @@
param = 1;
}
while (param--) {
this.screen.splice(this.scrollBottom + this.shift, 0, [this.blankLine(true), true]);
this.screen.splice(this.scrollBottom + this.shift, 0, this.blankLine(true));
this.screen.splice(this.y + this.shift, 1);
if (!(this.normal || this.scrollTop !== 0 || this.scrollBottom !== this.rows - 1)) {
this.children[this.y + this.shift].remove();
@@ -2066,7 +2078,7 @@
if (this.normal || this.scrollTop !== 0 || this.scrollBottom !== this.rows - 1) {
results = [];
for (i = k = ref = this.y + this.shift, ref1 = this.screen.length - 1; ref <= ref1 ? k <= ref1 : k >= ref1; i = ref <= ref1 ? ++k : --k) {
results.push(this.screen[i][1] = true);
results.push(this.screen[i].dirty = true);
}
return results;
}
@@ -2079,10 +2091,11 @@
param = 1;
}
while (param--) {
this.screen[this.y + this.shift][0].splice(this.x, 1);
this.screen[this.y + this.shift][0].push(this.eraseAttr());
this.screen[this.y + this.shift].chars.splice(this.x, 1);
this.screen[this.y + this.shift].chars.push(this.eraseAttr());
}
return this.screen[this.y + this.shift][1] = true;
this.screen[this.y + this.shift].dirty = true;
return this.screen[this.y + this.shift].wrap = false;
};
Terminal.prototype.eraseChars = function(params) {
@@ -2093,9 +2106,10 @@
}
j = this.x;
while (param-- && j < this.cols) {
this.screen[this.y + this.shift][0][j++] = this.eraseAttr();
this.screen[this.y + this.shift].chars[j++] = this.eraseAttr();
}
return this.screen[this.y + this.shift][1] = true;
this.screen[this.y + this.shift].dirty = true;
return this.screen[this.y + this.shift].wrap = false;
};
Terminal.prototype.charPosAbsolute = function(params) {
@@ -2378,11 +2392,11 @@
param = params[0] || 1;
while (param--) {
this.screen.splice(this.scrollTop, 1);
this.screen.splice(this.scrollBottom, 0, [this.blankLine(), true]);
this.screen.splice(this.scrollBottom, 0, this.blankLine());
}
results = [];
for (i = k = ref = this.scrollTop, ref1 = this.scrollBottom; ref <= ref1 ? k <= ref1 : k >= ref1; i = ref <= ref1 ? ++k : --k) {
results.push(this.screen[i + this.shift][1] = true);
results.push(this.screen[i + this.shift].dirty = true);
}
return results;
};
@@ -2392,11 +2406,11 @@
param = params[0] || 1;
while (param--) {
this.screen.splice(this.scrollBottom, 1);
this.screen.splice(this.scrollTop, 0, [this.blankLine(), true]);
this.screen.splice(this.scrollTop, 0, this.blankLine());
}
results = [];
for (i = k = ref = this.scrollTop, ref1 = this.scrollBottom; ref <= ref1 ? k <= ref1 : k >= ref1; i = ref <= ref1 ? ++k : --k) {
results.push(this.screen[i + this.shift][1] = true);
results.push(this.screen[i + this.shift].dirty = true);
}
return results;
};
@@ -2418,12 +2432,12 @@
Terminal.prototype.repeatPrecedingCharacter = function(params) {
var ch, line, param;
param = params[0] || 1;
line = this.screen[this.y + this.shift][0];
line = this.screen[this.y + this.shift].chars;
ch = line[this.x - 1] || this.defAttr;
while (param--) {
line[this.x++] = ch;
}
return this.screen[this.y + this.shift][1] = true;
return this.screen[this.y + this.shift].dirty = true;
};
Terminal.prototype.tabClear = function(params) {
@@ -2485,8 +2499,8 @@
attr = params[4];
results = [];
while (t < b + 1) {
line = this.screen[t + this.shift][0];
this.screen[t + this.shift][1] = true;
line = this.screen[t + this.shift].chars;
this.screen[t + this.shift].dirty = true;
i = l;
while (i < r) {
line[i] = this.cloneAttr(attr, line[i].ch);
@@ -2526,8 +2540,8 @@
r = params[4];
results = [];
while (t < b + 1) {
line = this.screen[t + this.shift][0];
this.screen[t + this.shift][1] = true;
line = this.screen[t + this.shift].chars;
this.screen[t + this.shift].dirty = true;
i = l;
while (i < r) {
line[i] = this.cloneAttr(line[i][0], String.fromCharCode(ch));
@@ -2551,8 +2565,8 @@
r = params[3];
results = [];
while (t < b + 1) {
line = this.screen[t + this.shift][0];
this.screen[t + this.shift][1] = true;
line = this.screen[t + this.shift].chars;
this.screen[t + this.shift].dirty = true;
i = l;
while (i < r) {
line[i] = this.eraseAttr();
@@ -2570,33 +2584,48 @@
Terminal.prototype.requestLocatorPosition = function(params) {};
Terminal.prototype.insertColumns = function() {
var i, l, param;
var i, l, param, results;
param = params[0];
l = this.rows + this.shift;
results = [];
while (param--) {
i = this.shift;
results.push((function() {
var results1;
results1 = [];
while (i < l) {
this.screen[i][0].splice(this.x + 1, 0, this.eraseAttr());
this.screen[i][0].pop();
i++;
this.screen[i].chars.splice(this.x + 1, 0, this.eraseAttr());
this.screen[i].chars.pop();
this.screen[i].dirty = true;
results1.push(i++);
}
return results1;
}).call(this));
}
return this.screen[i][1] = true;
return results;
};
Terminal.prototype.deleteColumns = function() {
var i, l, param;
var i, l, param, results;
param = params[0];
l = this.rows + this.shift;
results = [];
while (param--) {
i = this.shift;
results.push((function() {
var results1;
results1 = [];
while (i < l) {
this.screen[i][0].splice(this.x, 1);
this.screen[i][0].push(this.eraseAttr());
i++;
this.screen[i].chars.splice(this.x, 1);
this.screen[i].chars.push(this.eraseAttr());
this.screen[i].dirty = true;
this.screen[i].wrap = false;
results1.push(i++);
}
return results1;
}).call(this));
}
return this.screen[i][1] = true;
return results;
};
Terminal.prototype.charsets = {

File diff suppressed because one or more lines are too long

View File

@@ -119,12 +119,12 @@ class Terminal
putChar: (c) ->
if @insertMode
@screen[@y + @shift][0].splice(@x, 0, @cloneAttr @curAttr, c)
@screen[@y + @shift][0].pop()
@screen[@y + @shift].chars.splice(@x, 0, @cloneAttr @curAttr, c)
@screen[@y + @shift].chars.pop()
else
@screen[@y + @shift][0][@x] = @cloneAttr @curAttr, c
@screen[@y + @shift].chars[@x] = @cloneAttr @curAttr, c
@screen[@y + @shift][1] = true
@screen[@y + @shift].dirty = true
resetVars: ->
@x = 0
@@ -168,7 +168,7 @@ class Terminal
@screen = []
i = @rows
@shift = 0
@screen.push [@blankLine(), true] while i--
@screen.push @blankLine() while i--
@setupStops()
@skipNextKey = null
@@ -194,7 +194,7 @@ class Terminal
blur: ->
@cursorState = 1
@screen[@y + @shift][1] = true
@screen[@y + @shift].dirty = true
@refresh()
@send('\x1b[O') if @sendFocus
@body.classList.add('blur')
@@ -392,8 +392,8 @@ class Terminal
cursor.parentNode.replaceChild(
@document.createTextNode(cursor.textContent), cursor)
newOut = ''
for [line, dirty], j in @screen
continue unless dirty or force
for line, j in @screen
continue unless line.dirty or force
out = ""
if j is @y + @shift and not @cursorHidden
@@ -404,7 +404,7 @@ class Terminal
attr = @cloneAttr @defAttr
skipnext = false
for i in [0..@cols - 1]
data = line[i]
data = line.chars[i]
if data.html
out += data.html
continue
@@ -487,11 +487,12 @@ class Terminal
attr = data
out += "</span>" unless @equalAttr attr, @defAttr
out = @linkify(out) unless j is @y + @shift
out += '\u23CE' if line.wrap
if @children[j]
@children[j].innerHTML = out
else
newOut += "<div class=\"line\">#{out}</div>"
@screen[j][1] = false
@screen[j].dirty = false
if newOut isnt ''
group = @document.createElement('div')
@@ -527,7 +528,7 @@ class Terminal
showCursor: ->
unless @cursorState
@cursorState = 1
@screen[@y + @shift][1] = true
@screen[@y + @shift].dirty = true
@refresh()
@@ -547,21 +548,21 @@ class Terminal
# Use emulated scroll in alternate buffer or when scroll region is defined
if @normal or @scrollTop isnt 0 or @scrollBottom isnt @rows - 1
# inner scroll
@screen.splice @shift + @scrollBottom + 1, 0, [@blankLine(), true]
@screen.splice @shift + @scrollBottom + 1, 0, @blankLine()
@screen.splice @shift + @scrollTop, 1
for i in [@scrollTop..@scrollBottom]
@screen[i + @shift][1] = true
@screen[i + @shift].dirty = true
else
@screen.push [@blankLine(), true]
@screen.push @blankLine()
@shift++
unscroll: ->
@screen.splice @shift + @scrollTop , 0, [@blankLine(true), true]
@screen.splice @shift + @scrollTop , 0, @blankLine(true)
@screen.splice @shift + @scrollBottom + 1, 1
for i in [@scrollTop..@scrollBottom]
@screen[i + @shift][1] = true
@screen[i + @shift].dirty = true
nativeScrollTo: (scroll=2000000000) -> # ~ Max ff number
@@ -629,7 +630,7 @@ class Terminal
if ch >= " "
ch = @charset[ch] if @charset?[ch]
if @x >= @cols
@putChar '\u23CE'
@screen[@y + @shift].wrap = true
@x = 0
@nextLine()
@@ -769,9 +770,9 @@ class Terminal
break
when "8" # DECALN
for line in @screen
line[1] = true
for c in [0..line[0].length]
line[0][c] = @cloneAttr @curAttr, "E"
line.dirty = true
for c in [0..line.chars.length]
line.chars[c] = @cloneAttr @curAttr, "E"
@x = @y = 0
# ESC H Tab Set (HTS is 0x88).
@@ -1091,8 +1092,9 @@ class Terminal
attr = @cloneAttr @curAttr
attr.html = (
"<div class=\"inline-html\">#{content}</div>")
@screen[@y + @shift][0][@x] = attr
@screen[@y + @shift][1] = true
@screen[@y + @shift].chars[@x] = attr
@screen[@y + @shift].dirty = true
@screen[@y + @shift].wrap = false
when "IMAGE"
# Prevent injection
@@ -1108,8 +1110,9 @@ class Terminal
attr.html = (
"<img class=\"inline-image\" src=\"data:#{mime};base64,#{
b64}\" />")
@screen[@y + @shift][0][@x] = attr
@screen[@y + @shift][1] = true
@screen[@y + @shift].chars[@x] = attr
@screen[@y + @shift].dirty = true
@screen[@y + @shift].wrap = false
when "PROMPT"
@send content
@@ -1178,7 +1181,7 @@ class Terminal
@state = State.normal
i++
@screen[@y + @shift][1] = true
@screen[@y + @shift].dirty = true
@refresh()
writeln: (data) ->
@@ -1496,11 +1499,13 @@ class Terminal
# does xterm use the default attr?
i = @screen.length
while i--
@screen[i][0].push @defAttr while @screen[i][0].length < @cols
@screen[i].chars.push @defAttr while @screen[i].chars.length < @cols
@screen[i].wrap = false
else if oldCols > @cols
i = @screen.length
while i--
@screen[i][0].pop() while @screen[i][0].length > @cols
@screen[i].chars.pop() while @screen[i].chars.length > @cols
@setupStops oldCols
@@ -1509,7 +1514,7 @@ class Terminal
if j < @rows
el = @body
while j++ < @rows
@screen.push [@blankLine(), true] if @screen.length < @rows
@screen.push @blankLine() if @screen.length < @rows
if @children.length < @rows
line = @document.createElement("div")
line.className = 'line'
@@ -1563,18 +1568,20 @@ class Terminal
if x >= @cols then @cols - 1 else (if x < 0 then 0 else x)
eraseRight: (x, y) ->
line = @screen[y + @shift][0]
line = @screen[y + @shift].chars
# xterm
while x < @cols
line[x] = @eraseAttr()
x++
@screen[y + @shift][1] = true
@screen[y + @shift].dirty = true
@screen[y + @shift].wrap = false
eraseLeft: (x, y) ->
x++
@screen[y + @shift][0][x] = @eraseAttr() while x--
@screen[y + @shift][1] = true
@screen[y + @shift].chars[x] = @eraseAttr() while x--
@screen[y + @shift].dirty = true
@screen[y + @shift].wrap = false
eraseLine: (y) ->
@eraseRight 0, y
@@ -1583,10 +1590,13 @@ class Terminal
attr = (if cur then @eraseAttr() else @defAttr)
line = []
i = 0
while i < @cols + 1
while i < @cols
line[i] = attr
i++
line
chars: line
dirty: true
wrap: false
ch: (cur) ->
if cur then @eraseAttr() else @defAttr
@@ -1931,9 +1941,9 @@ class Terminal
j = @x
# xterm
while param-- and j < @cols
@screen[row + @shift][0].splice j++, 0, [@eraseAttr(), true]
@screen[row + @shift][0].pop()
@screen[row + @shift][1] = true
@screen[row + @shift].chars.splice j++, 0, [@eraseAttr(), true]
@screen[row + @shift].chars.pop()
@screen[row + @shift].dirty = true
# CSI Ps E
@@ -1973,12 +1983,12 @@ class Terminal
param = 1 if param < 1
while param--
@screen.splice @y + @shift, 0, [@blankLine(true), true]
@screen.splice @y + @shift, 0, @blankLine(true)
# blankLine(true) - xterm/linux behavior
@screen.splice @scrollBottom + 1 + @shift, 1
for i in [@y + @shift..@screen.length - 1]
@screen[i][1] = true
@screen[i].dirty = true
# CSI Ps M
# Delete Ps Line(s) (default = 1) (DL).
@@ -1989,7 +1999,7 @@ class Terminal
while param--
# test: echo -e '\e[44m\e[1M\e[0m'
# blankLine(true) - xterm/linux behavior
@screen.splice @scrollBottom + @shift, 0, [@blankLine(true), true]
@screen.splice @scrollBottom + @shift, 0, @blankLine(true)
@screen.splice @y + @shift, 1
unless @normal or @scrollTop isnt 0 or @scrollBottom isnt @rows - 1
@children[@y + @shift].remove()
@@ -1997,7 +2007,7 @@ class Terminal
if @normal or @scrollTop isnt 0 or @scrollBottom isnt @rows - 1
for i in [@y + @shift..@screen.length - 1]
@screen[i][1] = true
@screen[i].dirty = true
# CSI Ps P
# Delete Ps Character(s) (default = 1) (DCH).
@@ -2006,10 +2016,10 @@ class Terminal
param = 1 if param < 1
while param--
@screen[@y + @shift][0].splice @x, 1
@screen[@y + @shift][0].push @eraseAttr()
@screen[@y + @shift][1] = true
@screen[@y + @shift].chars.splice @x, 1
@screen[@y + @shift].chars.push @eraseAttr()
@screen[@y + @shift].dirty = true
@screen[@y + @shift].wrap = false
# CSI Ps X
# Erase Ps Character(s) (default = 1) (ECH).
@@ -2018,8 +2028,9 @@ class Terminal
param = 1 if param < 1
j = @x
# xterm
@screen[@y + @shift][0][j++] = @eraseAttr() while param-- and j < @cols
@screen[@y + @shift][1] = true
@screen[@y + @shift].chars[j++] = @eraseAttr() while param-- and j < @cols
@screen[@y + @shift].dirty = true
@screen[@y + @shift].wrap = false
# CSI Pm ` Character Position Absolute
# [column] (default = [row,1]) (HPA).
@@ -2472,10 +2483,10 @@ class Terminal
param = params[0] or 1
while param--
@screen.splice @scrollTop, 1
@screen.splice @scrollBottom, 0, [@blankLine(), true]
@screen.splice @scrollBottom, 0, @blankLine()
for i in [@scrollTop..@scrollBottom]
@screen[i + @shift][1] = true
@screen[i + @shift].dirty = true
# CSI Ps T Scroll down Ps lines (default = 1) (SD).
@@ -2483,10 +2494,10 @@ class Terminal
param = params[0] or 1
while param--
@screen.splice @scrollBottom, 1
@screen.splice @scrollTop, 0, [@blankLine(), true]
@screen.splice @scrollTop, 0, @blankLine()
for i in [@scrollTop..@scrollBottom]
@screen[i + @shift][1] = true
@screen[i + @shift].dirty = true
# CSI Ps ; Ps ; Ps ; Ps ; Ps T
@@ -2520,10 +2531,10 @@ class Terminal
# CSI Ps b Repeat the preceding graphic character Ps times (REP).
repeatPrecedingCharacter: (params) ->
param = params[0] or 1
line = @screen[@y + @shift][0]
line = @screen[@y + @shift].chars
ch = line[@x - 1] or @defAttr
line[@x++] = ch while param--
@screen[@y + @shift][1] = true
@screen[@y + @shift].dirty = true
# CSI Ps g Tab Clear (TBC).
# Ps = 0 -> Clear Current Column (default).
@@ -2694,8 +2705,8 @@ class Terminal
r = params[3]
attr = params[4]
while t < b + 1
line = @screen[t + @shift][0]
@screen[t + @shift][1] = true
line = @screen[t + @shift].chars
@screen[t + @shift].dirty = true
i = l
while i < r
line[i] = @cloneAttr attr, line[i].ch
@@ -2851,8 +2862,8 @@ class Terminal
b = params[3]
r = params[4]
while t < b + 1
line = @screen[t + @shift][0]
@screen[t + @shift][1] = true
line = @screen[t + @shift].chars
@screen[t + @shift].dirty = true
i = l
while i < r
line[i] = @cloneAttr line[i][0], String.fromCharCode(ch)
@@ -2886,8 +2897,8 @@ class Terminal
b = params[2]
r = params[3]
while t < b + 1
line = @screen[t + @shift][0]
@screen[t + @shift][1] = true
line = @screen[t + @shift].chars
@screen[t + @shift].dirty = true
i = l
while i < r
line[i] = @eraseAttr()
@@ -2966,10 +2977,10 @@ class Terminal
while param--
i = @shift
while i < l
@screen[i][0].splice @x + 1, 0, @eraseAttr()
@screen[i][0].pop()
@screen[i].chars.splice @x + 1, 0, @eraseAttr()
@screen[i].chars.pop()
@screen[i].dirty = true
i++
@screen[i][1] = true
# CSI P m SP ~
@@ -2981,10 +2992,11 @@ class Terminal
while param--
i = @shift
while i < l
@screen[i][0].splice @x, 1
@screen[i][0].push @eraseAttr()
@screen[i].chars.splice @x, 1
@screen[i].chars.push @eraseAttr()
@screen[i].dirty = true
@screen[i].wrap = false
i++
@screen[i][1] = true
# DEC Special Character and Line Drawing Set.
# http://vt100.net/docs/vt102-ug/table5-13.html