diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-07-04 16:48:53 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-04 16:48:53 +0800 |
commit | a76b689b479e89d6feae687443d13ec38602a1a6 (patch) | |
tree | fdec2d49f42789f6a158d2495126bf8b33db548c /src/nvim/window.c | |
parent | e8b3ed74bca4bd6ececcc240f816451bef7fd58c (diff) | |
download | rneovim-a76b689b479e89d6feae687443d13ec38602a1a6.tar.gz rneovim-a76b689b479e89d6feae687443d13ec38602a1a6.tar.bz2 rneovim-a76b689b479e89d6feae687443d13ec38602a1a6.zip |
perf(ui-ext): approximate scroll_delta when scrolling too much (#24234)
Diffstat (limited to 'src/nvim/window.c')
-rw-r--r-- | src/nvim/window.c | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/src/nvim/window.c b/src/nvim/window.c index f5533db385..187115a4d6 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -1030,15 +1030,13 @@ void ui_ext_win_position(win_T *wp, bool validate) void ui_ext_win_viewport(win_T *wp) { if ((wp == curwin || ui_has(kUIMultigrid)) && wp->w_viewport_invalid) { - int botline = wp->w_botline; - int line_count = wp->w_buffer->b_ml.ml_line_count; - if (botline == line_count + 1 && wp->w_empty_rows == 0) { - // TODO(bfredl): The might be more cases to consider, like how does this - // interact with incomplete final line? Diff filler lines? - botline = wp->w_buffer->b_ml.ml_line_count; - } + const linenr_T line_count = wp->w_buffer->b_ml.ml_line_count; + // Avoid ml_get errors when producing "scroll_delta". + const linenr_T cur_topline = MIN(wp->w_topline, line_count); + const linenr_T cur_botline = MIN(wp->w_botline, line_count); int64_t delta = 0; linenr_T last_topline = wp->w_viewport_last_topline; + linenr_T last_botline = wp->w_viewport_last_botline; int last_topfill = wp->w_viewport_last_topfill; int64_t last_skipcol = wp->w_viewport_last_skipcol; if (last_topline > line_count) { @@ -1047,19 +1045,39 @@ void ui_ext_win_viewport(win_T *wp) last_topfill = 0; last_skipcol = MAXCOL; } - if (wp->w_topline < last_topline - || (wp->w_topline == last_topline && wp->w_skipcol < last_skipcol)) { - delta -= win_get_text_height(wp, wp->w_topline, last_topline, wp->w_skipcol, last_skipcol); - } else if ((wp->w_topline > last_topline && wp->w_topline <= line_count) - || (wp->w_topline == last_topline && wp->w_skipcol > last_skipcol)) { - delta += win_get_text_height(wp, last_topline, wp->w_topline, last_skipcol, wp->w_skipcol); + last_botline = MIN(last_botline, line_count); + if (cur_topline < last_topline + || (cur_topline == last_topline && wp->w_skipcol < last_skipcol)) { + if (last_topline > 0 && cur_botline < last_topline) { + // Scrolling too many lines: only give an approximate "scroll_delta". + delta -= win_get_text_height(wp, cur_topline, cur_botline, wp->w_skipcol, 0); + delta -= last_topline - cur_botline; + } else { + delta -= win_get_text_height(wp, cur_topline, last_topline, wp->w_skipcol, last_skipcol); + } + } else if (cur_topline > last_topline + || (cur_topline == last_topline && wp->w_skipcol > last_skipcol)) { + if (last_botline > 0 && cur_topline > last_botline) { + // Scrolling too many lines: only give an approximate "scroll_delta". + delta += win_get_text_height(wp, last_topline, last_botline, last_skipcol, 0); + delta += cur_topline - last_botline; + } else { + delta += win_get_text_height(wp, last_topline, cur_topline, last_skipcol, wp->w_skipcol); + } } delta += last_topfill; delta -= wp->w_topfill; - ui_call_win_viewport(wp->w_grid_alloc.handle, wp->handle, wp->w_topline - 1, botline, + linenr_T ev_botline = wp->w_botline; + if (ev_botline == line_count + 1 && wp->w_empty_rows == 0) { + // TODO(bfredl): The might be more cases to consider, like how does this + // interact with incomplete final line? Diff filler lines? + ev_botline = line_count; + } + ui_call_win_viewport(wp->w_grid_alloc.handle, wp->handle, wp->w_topline - 1, ev_botline, wp->w_cursor.lnum - 1, wp->w_cursor.col, line_count, delta); wp->w_viewport_invalid = false; wp->w_viewport_last_topline = wp->w_topline; + wp->w_viewport_last_botline = wp->w_botline; wp->w_viewport_last_topfill = wp->w_topfill; wp->w_viewport_last_skipcol = wp->w_skipcol; } |