commit 2bfa414d2b6906e3d9bb44b26eaa402cc6b76f2e from: Omar Polo date: Thu Jul 01 14:01:44 2021 UTC handle the resize better Try to preserve as much as possible the current_line and top_line during wrap_page. In redraw_window recompute the correct y position. commit - 94ec38e85dbc4ec718934b3bcc765398e2b8ccd4 commit + 2bfa414d2b6906e3d9bb44b26eaa402cc6b76f2e blob - 2b0cc30aa67a7e932f2f09f29e4896693dd2c3dc blob + a11eeb4cec444a86fd3de58f06e50ef1415f938a --- ui.c +++ ui.c @@ -563,11 +563,12 @@ static int wrap_page(struct buffer *buffer, int width) { struct line *l; - const struct line *orig; + const struct line *top_orig, *orig; struct vline *vl; int pre_width; const char *prfx; + top_orig = buffer->top_line == NULL ? NULL : buffer->top_line->parent; orig = buffer->current_line == NULL ? NULL : buffer->current_line->parent; buffer->top_line = NULL; @@ -602,8 +603,20 @@ wrap_page(struct buffer *buffer, int width) break; } - if (orig == l && buffer->current_line == NULL) { + if (top_orig == l && buffer->top_line == NULL) { buffer->line_off = buffer->line_max-1; + buffer->top_line = TAILQ_LAST(&buffer->head, vhead); + + while (1) { + vl = TAILQ_PREV(buffer->top_line, vhead, vlines); + if (vl == NULL || vl->parent != orig) + break; + buffer->top_line = vl; + buffer->line_off--; + } + } + + if (orig == l && buffer->current_line == NULL) { buffer->current_line = TAILQ_LAST(&buffer->head, vhead); while (1) { @@ -611,7 +624,6 @@ wrap_page(struct buffer *buffer, int width) if (vl == NULL || vl->parent != orig) break; buffer->current_line = vl; - buffer->line_off--; } } } @@ -619,7 +631,8 @@ wrap_page(struct buffer *buffer, int width) if (buffer->current_line == NULL) buffer->current_line = TAILQ_FIRST(&buffer->head); - buffer->top_line = buffer->current_line; + if (buffer->top_line == NULL) + buffer->top_line = buffer->current_line; return 1; } @@ -772,8 +785,8 @@ redraw_tabline(void) static void redraw_window(WINDOW *win, int height, int width, struct buffer *buffer) { - struct vline *vl; - int l; + struct vline *vl; + int l, onscreen; /* * Don't bother redraw the body if nothing changed. Cursor @@ -784,24 +797,44 @@ redraw_window(WINDOW *win, int height, int width, stru buffer->last_line_off == buffer->line_off) goto end; +again: werase(win); - - buffer->line_off = MIN(buffer->line_max-1, buffer->line_off); - buffer->force_redraw = 0; - buffer->last_line_off = buffer->line_off; + buffer->curs_y = 0; if (TAILQ_EMPTY(&buffer->head)) goto end; l = 0; + onscreen = 0; for (vl = buffer->top_line; vl != NULL; vl = TAILQ_NEXT(vl, vlines)) { wmove(win, l, 0); print_vline(x_offset, width, win, vl); + + if (vl == buffer->current_line) + onscreen = 1; + + if (!onscreen) + buffer->curs_y++; + l++; if (l == height) break; + } + + if (!onscreen) { + for (; vl != NULL; vl = TAILQ_NEXT(vl, vlines)) { + if (vl == buffer->current_line) + break; + buffer->line_off++; + buffer->top_line = TAILQ_NEXT(buffer->top_line, vlines); + } + + goto again; } + buffer->last_line_off = buffer->line_off; + restore_cursor(buffer); + buffer->force_redraw = 0; end: wmove(win, buffer->curs_y, buffer->curs_x); }