scrollback fixes

This commit is contained in:
Adam D. Ruppe 2015-10-30 14:58:50 -04:00
parent 40b737eb9d
commit 3559760d3b
1 changed files with 77 additions and 20 deletions

View File

@ -3171,26 +3171,58 @@ struct ScrollbackBuffer {
int start = cast(int) lines.length; int start = cast(int) lines.length;
int howMany = 0; int howMany = 0;
bool firstPartial = false;
size_t firstPartialStartIndex;
// we'll work backwards to figure out how much will fit... // we'll work backwards to figure out how much will fit...
// this will give accurate per-line things even with changing width and wrapping // this will give accurate per-line things even with changing width and wrapping
// while being generally efficient - we usually want to show the end of the list // while being generally efficient - we usually want to show the end of the list
// anyway; actually using the scrollback is a bit of an exceptional case. // anyway; actually using the scrollback is a bit of an exceptional case.
// It could probably do this instead of on each redraw, on each resize or insertion.
// or at least cache between redraws until one of those invalidates it.
foreach_reverse(line; lines) { foreach_reverse(line; lines) {
int written = 0; int written = 0;
foreach(component; line.components) { int brokenLineCount;
size_t[16] lineBreaksBuffer;
size_t[] lineBreaks = lineBreaksBuffer[];
comp_loop: foreach(component; line.components) {
auto towrite = component.text; auto towrite = component.text;
written += towrite.length; foreach(idx, dchar ch; towrite) {
while(written > width) { if(written >= width) {
written -= width; if(brokenLineCount == lineBreaks.length)
lineBreaks ~= idx;
else
lineBreaks[brokenLineCount] = idx;
brokenLineCount++;
written = 0;
}
if(ch == '\t')
written += 8; // FIXME
else
written++;
}
}
lineBreaks = lineBreaks[0 .. brokenLineCount];
foreach_reverse(lineBreak; lineBreaks) {
if(remaining == 1) {
firstPartial = true;
firstPartialStartIndex = lineBreak;
break;
} else {
remaining--; remaining--;
}
if(remaining <= 0) if(remaining <= 0)
break; break;
} }
}
remaining--; remaining--;
start--; start--;
howMany++; howMany++;
if(remaining <= 0) if(remaining <= 0)
@ -3203,22 +3235,44 @@ struct ScrollbackBuffer {
foreach(idx, line; lines[start .. start + howMany]) { foreach(idx, line; lines[start .. start + howMany]) {
int written = 0; int written = 0;
if(linePos < 0) {
linePos++;
continue;
}
terminal.moveTo(x, y + ((linePos >= 0) ? linePos : 0)); terminal.moveTo(x, y + ((linePos >= 0) ? linePos : 0));
foreach(component; line.components) { foreach(component; line.components) {
terminal.color(component.color, component.background); terminal.color(component.color, component.background);
auto towrite = component.text; auto towrite = component.text;
while(linePos < 0 && width < towrite.length) {
towrite = towrite[width .. $]; again:
linePos++;
}
terminal.write(towrite);
written += towrite.length;
while(written > width) {
written -= width;
linePos++;
if(linePos >= height) if(linePos >= height)
break; break;
if(firstPartial) {
towrite = towrite[firstPartialStartIndex .. $];
firstPartial = false;
} }
foreach(idx, dchar ch; towrite) {
if(written >= width) {
terminal.write(towrite[0 .. idx]);
towrite = towrite[idx .. $];
linePos++;
written = 0;
terminal.moveTo(x, y + linePos);
goto again;
}
if(ch == '\t')
written += 8; // FIXME
else
written++;
}
if(towrite.length)
terminal.write(towrite);
} }
if(written < width) if(written < width)
@ -3231,6 +3285,7 @@ struct ScrollbackBuffer {
break; break;
} }
if(linePos < height)
foreach(i; linePos .. height) { foreach(i; linePos .. height) {
if(i >= 0 && i < height) { if(i >= 0 && i < height) {
terminal.moveTo(x, y + i); terminal.moveTo(x, y + i);
@ -3242,12 +3297,14 @@ struct ScrollbackBuffer {
void addLine(string line) { void addLine(string line) {
lines ~= Line([LineComponent(line)]); lines ~= Line([LineComponent(line)]);
if(scrollbackPosition) // if the user is scrolling back, we want to keep them basically centered where they are
scrollbackPosition++;
} }
void scrollUp(int lines = 1) { void scrollUp(int lines = 1) {
scrollbackPosition += lines; scrollbackPosition += lines;
if(scrollbackPosition >= this.lines.length) //if(scrollbackPosition >= this.lines.length)
scrollbackPosition = cast(int) this.lines.length - 1; // scrollbackPosition = cast(int) this.lines.length - 1;
} }
void scrollDown(int lines = 1) { void scrollDown(int lines = 1) {