mirror of https://github.com/adamdruppe/arsd.git
scrollback fixes
This commit is contained in:
parent
40b737eb9d
commit
3559760d3b
97
terminal.d
97
terminal.d
|
@ -3171,25 +3171,57 @@ 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)
|
||||||
remaining--;
|
lineBreaks ~= idx;
|
||||||
if(remaining <= 0)
|
else
|
||||||
break;
|
lineBreaks[brokenLineCount] = idx;
|
||||||
|
|
||||||
|
brokenLineCount++;
|
||||||
|
|
||||||
|
written = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ch == '\t')
|
||||||
|
written += 8; // FIXME
|
||||||
|
else
|
||||||
|
written++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
remaining--;
|
lineBreaks = lineBreaks[0 .. brokenLineCount];
|
||||||
|
|
||||||
|
foreach_reverse(lineBreak; lineBreaks) {
|
||||||
|
if(remaining == 1) {
|
||||||
|
firstPartial = true;
|
||||||
|
firstPartialStartIndex = lineBreak;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
remaining--;
|
||||||
|
}
|
||||||
|
if(remaining <= 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
remaining--;
|
||||||
|
|
||||||
start--;
|
start--;
|
||||||
howMany++;
|
howMany++;
|
||||||
|
@ -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++;
|
|
||||||
|
if(linePos >= height)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(firstPartial) {
|
||||||
|
towrite = towrite[firstPartialStartIndex .. $];
|
||||||
|
firstPartial = false;
|
||||||
}
|
}
|
||||||
terminal.write(towrite);
|
|
||||||
written += towrite.length;
|
foreach(idx, dchar ch; towrite) {
|
||||||
while(written > width) {
|
if(written >= width) {
|
||||||
written -= width;
|
terminal.write(towrite[0 .. idx]);
|
||||||
linePos++;
|
towrite = towrite[idx .. $];
|
||||||
if(linePos >= height)
|
linePos++;
|
||||||
break;
|
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) {
|
||||||
|
|
Loading…
Reference in New Issue