Preserve scroll position across reflows

Finally! Changing the message visibility threshold doesn't totally
screw up scroll position. Neither do horizontal resizes, but vertical
resizes drift because the value of windowTop() changes before and
after...

The scroll position is anchored to the top of the window. It's
arbitrary whether to anchor the top or the bottom, but other scrolling
commands like M-p and C-r are anchored to the top, so this is
consistent.
master
C. McEnroe 2021-01-26 22:33:16 -05:00
parent 52c58128c8
commit d7d4572220
1 changed files with 15 additions and 5 deletions

20
ui.c
View File

@ -567,10 +567,25 @@ void uiFormat(
uiWrite(id, heat, time, buf);
}
static void scrollTo(struct Window *window, int top) {
window->scroll = 0;
windowScroll(window, top - MAIN_LINES + MarkerLines);
}
static void windowReflow(struct Window *window) {
uint num = 0;
const struct Line *line = bufferHard(window->buffer, windowTop(window));
if (line) num = line->num;
window->unreadHard = bufferReflow(
window->buffer, COLS, window->thresh, window->unreadSoft
);
if (!window->scroll || !num) return;
for (size_t i = 0; i < BufferCap; ++i) {
line = bufferHard(window->buffer, i);
if (!line || line->num != num) continue;
scrollTo(window, BufferCap - i);
break;
}
}
static void resize(void) {
@ -762,11 +777,6 @@ static void scrollPage(struct Window *window, int n) {
windowScroll(window, n * (MAIN_LINES - SplitLines - MarkerLines - 1));
}
static void scrollTo(struct Window *window, int top) {
window->scroll = 0;
windowScroll(window, top - MAIN_LINES + MarkerLines);
}
static void scrollHot(struct Window *window, int dir) {
for (size_t i = windowTop(window) + dir; i < BufferCap; i += dir) {
const struct Line *line = bufferHard(window->buffer, i);