aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/ui_events.in.h2
-rw-r--r--src/nvim/buffer_defs.h1
-rw-r--r--src/nvim/window.c15
3 files changed, 16 insertions, 2 deletions
diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h
index a08e8dbfeb..b93f521ca3 100644
--- a/src/nvim/api/ui_events.in.h
+++ b/src/nvim/api/ui_events.in.h
@@ -114,7 +114,7 @@ void msg_set_pos(Integer grid, Integer row, Boolean scrolled, String sep_char)
FUNC_API_SINCE(6) FUNC_API_COMPOSITOR_IMPL FUNC_API_CLIENT_IGNORE;
void win_viewport(Integer grid, Window win, Integer topline, Integer botline, Integer curline,
- Integer curcol, Integer line_count)
+ Integer curcol, Integer line_count, Integer scroll_delta)
FUNC_API_SINCE(7) FUNC_API_CLIENT_IGNORE;
void win_extmark(Integer grid, Window win, Integer ns_id, Integer mark_id, Integer row, Integer col)
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index 6122136a75..4bdf5aac64 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -1222,6 +1222,7 @@ struct window_S {
colnr_T w_valid_leftcol; // last known w_leftcol
bool w_viewport_invalid;
+ linenr_T w_viewport_last_topline; // topline when the viewport was last updated
// w_cline_height is the number of physical lines taken by the buffer line
// that the cursor is on. We use this to avoid extra calls to plines_win().
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 38b7326363..39e9efbabb 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -993,10 +993,22 @@ void ui_ext_win_viewport(win_T *wp)
// interact with incomplete final line? Diff filler lines?
botline = wp->w_buffer->b_ml.ml_line_count;
}
+ int scroll_delta = 0;
+ if (wp->w_viewport_last_topline > line_count) {
+ scroll_delta -= wp->w_viewport_last_topline - line_count;
+ wp->w_viewport_last_topline = line_count;
+ }
+ if (wp->w_topline < wp->w_viewport_last_topline) {
+ scroll_delta -= plines_m_win(wp, wp->w_topline, wp->w_viewport_last_topline - 1);
+ } else if (wp->w_topline > wp->w_viewport_last_topline
+ && wp->w_topline <= line_count) {
+ scroll_delta += plines_m_win(wp, wp->w_viewport_last_topline, wp->w_topline - 1);
+ }
ui_call_win_viewport(wp->w_grid_alloc.handle, wp->handle, wp->w_topline - 1,
botline, wp->w_cursor.lnum - 1, wp->w_cursor.col,
- line_count);
+ line_count, scroll_delta);
wp->w_viewport_invalid = false;
+ wp->w_viewport_last_topline = wp->w_topline;
}
}
@@ -5038,6 +5050,7 @@ static win_T *win_alloc(win_T *after, bool hidden)
new_wp->w_floating = 0;
new_wp->w_float_config = FLOAT_CONFIG_INIT;
new_wp->w_viewport_invalid = true;
+ new_wp->w_viewport_last_topline = 1;
new_wp->w_ns_hl = -1;