diff options
author | Lewis Russell <lewis6991@gmail.com> | 2024-07-17 12:23:15 +0100 |
---|---|---|
committer | Lewis Russell <me@lewisr.dev> | 2024-07-31 11:33:32 +0100 |
commit | 573a71469d37cc35f72bfc929f4ce1156833df9f (patch) | |
tree | a00230976aa453aabb2c9de073e08ccde343e400 /src/nvim/ex_docmd.c | |
parent | c9b129a02ab46fc80c81f3f9cabed4040a7462c0 (diff) | |
download | rneovim-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.c | 21 |
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(); |