aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/ex_docmd.c
diff options
context:
space:
mode:
authorLewis Russell <lewis6991@gmail.com>2024-07-17 12:23:15 +0100
committerLewis Russell <me@lewisr.dev>2024-07-31 11:33:32 +0100
commit573a71469d37cc35f72bfc929f4ce1156833df9f (patch)
treea00230976aa453aabb2c9de073e08ccde343e400 /src/nvim/ex_docmd.c
parentc9b129a02ab46fc80c81f3f9cabed4040a7462c0 (diff)
downloadrneovim-573a71469d37cc35f72bfc929f4ce1156833df9f.tar.gz
rneovim-573a71469d37cc35f72bfc929f4ce1156833df9f.tar.bz2
rneovim-573a71469d37cc35f72bfc929f4ce1156833df9f.zip
fix(scrollbind): properly take filler/virtual lines into account
Problem: `'scrollbind'` does not work properly if the window being scrolled automatically contains any filler/virtual lines (except for diff filler lines). This is because when the scrollbind check is done, the logic only considers changes to topline which are represented as line numbers. Solution: Write the logic for determine the scroll amount to take into account filler/virtual lines. Fixes #29751
Diffstat (limited to 'src/nvim/ex_docmd.c')
-rw-r--r--src/nvim/ex_docmd.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 2defd580fc..e384627fec 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -81,6 +81,7 @@
#include "nvim/os/os_defs.h"
#include "nvim/os/shell.h"
#include "nvim/path.h"
+#include "nvim/plines.h"
#include "nvim/popupmenu.h"
#include "nvim/pos_defs.h"
#include "nvim/profile.h"
@@ -5580,39 +5581,43 @@ static void ex_swapname(exarg_T *eap)
/// (1998-11-02 16:21:01 R. Edward Ralston <eralston@computer.org>)
static void ex_syncbind(exarg_T *eap)
{
- linenr_T topline;
+ linenr_T vtopline; // Target topline (including fill)
+
linenr_T old_linenr = curwin->w_cursor.lnum;
setpcmark();
- // determine max topline
+ // determine max (virtual) topline
if (curwin->w_p_scb) {
- topline = curwin->w_topline;
+ vtopline = get_vtopline(curwin);
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp->w_p_scb && wp->w_buffer) {
- topline = MIN(topline, wp->w_buffer->b_ml.ml_line_count - get_scrolloff_value(curwin));
+ linenr_T y = plines_m_win_fill(wp, 1, wp->w_buffer->b_ml.ml_line_count)
+ - get_scrolloff_value(curwin);
+ vtopline = MIN(vtopline, y);
}
}
- topline = MAX(topline, 1);
+ vtopline = MAX(vtopline, 1);
} else {
- topline = 1;
+ vtopline = 1;
}
// Set all scrollbind windows to the same topline.
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp->w_p_scb) {
- int y = topline - wp->w_topline;
+ int y = vtopline - get_vtopline(wp);
if (y > 0) {
scrollup(wp, y, true);
} else {
scrolldown(wp, -y, true);
}
- wp->w_scbind_pos = topline;
+ wp->w_scbind_pos = vtopline;
redraw_later(wp, UPD_VALID);
cursor_correct(wp);
wp->w_redr_status = true;
}
}
+
if (curwin->w_p_scb) {
did_syncbind = true;
checkpcmark();