diff options
author | C. McEnroe | 2021-01-26 22:33:16 -0500 |
---|---|---|
committer | C. McEnroe | 2021-01-26 22:33:16 -0500 |
commit | d7d4572220b234e6774d53b8e893c20e4ff55591 (patch) | |
tree | d9fb8e7aad05ba240d74e2628a7d552d5ae4667b | |
parent | 52c58128c83a4e6207afd75318446793fd0110ff (diff) |
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.
-rw-r--r-- | ui.c | 20 |
1 files changed, 15 insertions, 5 deletions
@@ -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); |