1
0
forked from aniani/vim

patch 9.0.0647: the 'splitscroll' option is not a good name

Problem:    The 'splitscroll' option is not a good name.
Solution:   Rename 'splitscroll' to 'splitkeep' and make it a string option,
            also supporting "topline". (Luuk van Baal, closes #11258)
This commit is contained in:
Luuk van Baal 2022-10-03 15:28:08 +01:00 committed by Bram Moolenaar
parent 6b2d4ff714
commit 13ece2ae1d
21 changed files with 141 additions and 129 deletions

View File

@ -7518,24 +7518,28 @@ A jump table for the options with a short description can be found at |Q_op|.
When on, splitting a window will put the new window below the current
one. |:split|
*'splitkeep'* *'spk'
'splitkeep' 'spk' string (default "cursor")
global
The value of this option determines the scroll behavior when opening,
closing or resizing horizontal splits.
Possible values are:
cursor Keep the same relative cursor position.
screen Keep the text on the same screen line.
topline Keep the topline the same.
For the "screen" and "topline" values, the cursor position will be
changed when necessary. In this case, the jumplist will be populated
with the previous cursor position. For "screen", the text cannot always
be kept on the same screen line when 'wrap' is enabled.
*'splitright'* *'spr'* *'nosplitright'* *'nospr'*
'splitright' 'spr' boolean (default off)
global
When on, splitting a window will put the new window right of the
current one. |:vsplit|
*'splitscroll'* *'spsc'* *'nosplitscroll'* *'nospsc'*
'splitscroll' 'spsc' boolean (default on)
global
The value of this option determines the scroll behavior when opening,
closing or resizing horizontal splits. When "on", splitting a window
horizontally will keep the same relative cursor position in the old and
new window, as well windows that are resized. When "off", scrolling
will be avoided to stabilize the window content. Instead, the cursor
position will be changed when necessary. In this case, the jumplist
will be populated with the previous cursor position. Scrolling cannot
be guaranteed to be avoided when 'wrap' is enabled.
*'startofline'* *'sol'* *'nostartofline'* *'nosol'*
'startofline' 'sol' boolean (default on)
global

View File

@ -919,8 +919,8 @@ Short explanation of each option: *option-list*
'spelloptions' 'spo' options for spell checking
'spellsuggest' 'sps' method(s) used to suggest spelling corrections
'splitbelow' 'sb' new window from split is below the current one
'splitkeep' 'spk' determines scroll behavior for split windows
'splitright' 'spr' new window is put right of the current one
'splitscroll' 'spsc' determines scroll behavior for split windows
'startofline' 'sol' commands move cursor to first non-blank in line
'statusline' 'stl' custom format for the status line
'suffixes' 'su' suffixes that are ignored with multiple match

View File

@ -516,10 +516,10 @@ call <SID>AddOption("switchbuf", gettext("\"useopen\" and/or \"split\"; which wi
call <SID>OptionG("swb", &swb)
call <SID>AddOption("splitbelow", gettext("a new window is put below the current one"))
call <SID>BinOptionG("sb", &sb)
call <SID>AddOption("splitkeep", gettext("determines scroll behavior for split windows"))
call <SID>BinOptionG("spk", &spk)
call <SID>AddOption("splitright", gettext("a new window is put right of the current one"))
call <SID>BinOptionG("spr", &spr)
call <SID>AddOption("splitscroll", gettext("determines scroll behavior for split windows"))
call <SID>BinOptionG("spsc", &spsc)
call <SID>AddOption("scrollbind", gettext("this window scrolls together with other bound windows"))
call append("$", "\t" .. s:local_to_window)
call <SID>BinOptionL("scb")

View File

@ -1975,10 +1975,10 @@ EXTERN int channel_need_redraw INIT(= FALSE);
EXTERN optmagic_T magic_overruled INIT(= OPTION_MAGIC_NOT_SET);
#ifdef FEAT_CMDWIN
// Skip win_fix_cursor() call for 'nosplitscroll' when cmdwin is closed.
// Skip win_fix_cursor() call for 'splitkeep' when cmdwin is closed.
EXTERN int skip_win_fix_cursor INIT(= FALSE);
#endif
// Skip win_fix_scroll() call for 'nosplitscroll' when closing tab page.
// Skip win_fix_scroll() call for 'splitkeep' when closing tab page.
EXTERN int skip_win_fix_scroll INIT(= FALSE);
// Skip update_topline() call while executing win_fix_scroll().
EXTERN int skip_update_topline INIT(= FALSE);

View File

@ -219,6 +219,10 @@ update_topline(void)
long *so_ptr = curwin->w_p_so >= 0 ? &curwin->w_p_so : &p_so;
int save_so = *so_ptr;
// Cursor is updated instead when this is TRUE for 'splitkeep'.
if (skip_update_topline)
return;
// If there is no valid screen and when the window height is zero just use
// the cursor line.
if (!screen_valid(TRUE) || curwin->w_height == 0)
@ -1027,7 +1031,6 @@ curs_columns(
/*
* First make sure that w_topline is valid (after moving the cursor).
*/
if (!skip_update_topline)
update_topline();
/*

View File

@ -924,11 +924,11 @@ EXTERN char_u *p_spo; // 'spelloptions'
EXTERN char_u *p_sps; // 'spellsuggest'
#endif
EXTERN int p_spr; // 'splitright'
EXTERN int p_spsc; // 'splitscroll'
EXTERN int p_sol; // 'startofline'
EXTERN char_u *p_su; // 'suffixes'
EXTERN char_u *p_sws; // 'swapsync'
EXTERN char_u *p_swb; // 'switchbuf'
EXTERN char_u *p_spk; // 'splitkeep'
EXTERN unsigned swb_flags;
// Keep in sync with p_swb_values in optionstr.c
#define SWB_USEOPEN 0x001

View File

@ -2350,12 +2350,12 @@ static struct vimoption options[] =
{"splitbelow", "sb", P_BOOL|P_VI_DEF,
(char_u *)&p_sb, PV_NONE,
{(char_u *)FALSE, (char_u *)0L} SCTX_INIT},
{"splitkeep", "spk", P_STRING,
(char_u *)&p_spk, PV_NONE,
{(char_u *)"cursor", (char_u *)"cursor"} SCTX_INIT},
{"splitright", "spr", P_BOOL|P_VI_DEF,
(char_u *)&p_spr, PV_NONE,
{(char_u *)FALSE, (char_u *)0L} SCTX_INIT},
{"splitscroll", "spsc", P_BOOL,
(char_u *)&p_spsc, PV_NONE,
{(char_u *)TRUE, (char_u *)TRUE} SCTX_INIT},
{"startofline", "sol", P_BOOL|P_VI_DEF|P_VIM,
(char_u *)&p_sol, PV_NONE,
{(char_u *)TRUE, (char_u *)0L} SCTX_INIT},

View File

@ -46,6 +46,7 @@ static char *(p_ssop_values[]) = {"buffers", "winpos", "resize", "winsize",
#endif
// Keep in sync with SWB_ flags in option.h
static char *(p_swb_values[]) = {"useopen", "usetab", "split", "newtab", "vsplit", "uselast", NULL};
static char *(p_spk_values[]) = {"cursor", "screen", "topline", NULL};
static char *(p_tc_values[]) = {"followic", "ignore", "match", "followscs", "smart", NULL};
#if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_MSWIN)
static char *(p_toolbar_values[]) = {"text", "icons", "tooltips", "horiz", NULL};
@ -1683,6 +1684,13 @@ did_set_string_option(
errmsg = e_invalid_argument;
}
// 'splitkeep'
else if (varp == &p_spk)
{
if (check_opt_strings(p_spk, p_spk_values, FALSE) != OK)
errmsg = e_invalid_argument;
}
// 'debug'
else if (varp == &p_debug)
{

View File

@ -3621,8 +3621,8 @@ struct window_S
int w_winrow; // first row of window in screen
int w_height; // number of rows in window, excluding
// status/command/winbar line(s)
int w_prev_winrow; // previous winrow used for 'splitscroll'
int w_prev_height; // previous height used for 'splitscroll'
int w_prev_winrow; // previous winrow used for 'splitkeep'
int w_prev_height; // previous height used for 'splitkeep'
int w_status_height; // number of status lines (0 or 1)
int w_wincol; // Leftmost column of window in screen.

View File

@ -134,6 +134,7 @@ let test_values = {
\ 'spelllang': [['', 'xxx', 'sr@latin'], ['not&lang', "that\\\rthere"]],
\ 'spelloptions': [['', 'camel'], ['xxx']],
\ 'spellsuggest': [['', 'best', 'double,33'], ['xxx']],
\ 'splitkeep': [['cursor', 'screen', 'topline'], ['xxx']],
\ 'switchbuf': [['', 'useopen', 'split,newtab'], ['xxx']],
\ 'tagcase': [['smart', 'match'], ['', 'xxx', 'smart,match']],
\ 'term': [[], []],

View File

@ -1632,31 +1632,29 @@ func Test_win_equal_last_status()
set laststatus&
endfunc
" Ensure no scrolling happens with 'nosplitscroll' for a sequence of
" Test "screen" and "cursor" values for 'splitkeep' with a sequence of
" split operations for various options: with and without a winbar,
" tabline, for each possible value of 'laststatus', 'scrolloff',
" 'equalalways', and regardless of the cursor position.
func Test_nosplitscroll_options()
set nowrap
set nosplitscroll
" 'equalalways', and with the cursor at the top, middle and bottom.
func Test_splitkeep_options()
" disallow window resizing
let save_WS = &t_WS
set t_WS=
let gui = has("gui_running")
inoremap <expr> c "<cmd>copen<bar>wincmd k<CR>"
for run in range(0, 10)
for run in range(0, 20)
let &splitkeep = run > 10 ? 'topline' : 'screen'
let &scrolloff = (!(run % 4) ? 0 : run)
let &laststatus = (run % 3)
let &splitbelow = (run % 3)
let &equalalways = (run % 2)
let wsb = (run % 2) && &splitbelow
let tl = (gui ? 0 : ((run % 5) ? 1 : 0))
let pos = !(run % 3) ? 'H' : ((run % 2) ? 'M' : 'L')
tabnew | tabonly! | redraw
let tabline = (gui ? 0 : ((run % 5) ? 1 : 0))
let winbar_sb = (run % 2) && (run % 3)
execute 'set scrolloff=' . (!(run % 4) ? 0 : run)
execute 'set laststatus=' . (run % 3)
execute 'set ' . ((run % 2) ? 'equalalways' : 'noequalalways')
execute 'set ' . ((run % 3) ? 'splitbelow' : 'nosplitbelow')
execute (run % 5) ? 'tabnew' : ''
execute (run % 2) ? 'nnoremenu 1.10 WinBar.Test :echo' : ''
let pos = !(run % 3) ? 'H' : ((run % 2) ? 'M' : 'L')
call setline(1, range(1, 256))
" No scroll for restore_snapshot
norm G
@ -1672,17 +1670,17 @@ func Test_nosplitscroll_options()
call assert_equal(1, line("w0"))
call assert_equal(&scroll, winheight(0) / 2)
wincmd j
call assert_equal(win_screenpos(0)[0] - tabline - winbar_sb, line("w0"))
call assert_equal(&spk == 'topline' ? 1 : win_screenpos(0)[0] - tl - wsb, line("w0"))
" No scroll when resizing windows
wincmd k | resize +2
wincmd k | resize +2 | redraw
call assert_equal(1, line("w0"))
wincmd j
call assert_equal(win_screenpos(0)[0] - tabline - winbar_sb, line("w0"))
call assert_equal(&spk == 'topline' ? 1 : win_screenpos(0)[0] - tl - wsb, line("w0"))
" No scroll when dragging statusline
call win_move_statusline(1, -3)
call assert_equal(win_screenpos(0)[0] - tabline - winbar_sb, line("w0"))
call assert_equal(&spk == 'topline' ? 1 : win_screenpos(0)[0] - tl - wsb, line("w0"))
wincmd k
call assert_equal(1, line("w0"))
@ -1690,9 +1688,9 @@ func Test_nosplitscroll_options()
set lines+=2
call assert_equal(1, line("w0"))
wincmd j
call assert_equal(win_screenpos(0)[0] - tabline - winbar_sb, line("w0"))
call assert_equal(&spk == 'topline' ? 1 : win_screenpos(0)[0] - tl - wsb, line("w0"))
set lines-=2
call assert_equal(win_screenpos(0)[0] - tabline - winbar_sb, line("w0"))
call assert_equal(&spk == 'topline' ? 1 : win_screenpos(0)[0] - tl - wsb, line("w0"))
wincmd k
call assert_equal(1, line("w0"))
@ -1700,23 +1698,23 @@ func Test_nosplitscroll_options()
wincmd =
call assert_equal(1, line("w0"))
wincmd j
call assert_equal(win_screenpos(0)[0] - tabline - winbar_sb, line("w0"))
call assert_equal(&spk == 'topline' ? 1 : win_screenpos(0)[0] - tl - wsb, line("w0"))
wincmd k
call assert_equal(1, line("w0"))
" No scroll in windows split multiple times
vsplit | split | 4wincmd w
call assert_equal(win_screenpos(0)[0] - tabline - winbar_sb, line("w0"))
call assert_equal(&spk == 'topline' ? 1 : win_screenpos(0)[0] - tl - wsb, line("w0"))
1wincmd w | quit | wincmd l | split
call assert_equal(win_screenpos(0)[0] - tabline - winbar_sb, line("w0"))
call assert_equal(&spk == 'topline' ? 1 : win_screenpos(0)[0] - tl - wsb, line("w0"))
wincmd j
call assert_equal(win_screenpos(0)[0] - tabline - winbar_sb, line("w0"))
call assert_equal(&spk == 'topline' ? 1 : win_screenpos(0)[0] - tl - wsb, line("w0"))
" No scroll in small window
2wincmd w | only | 5split | wincmd k
call assert_equal(1, line("w0"))
wincmd j
call assert_equal(win_screenpos(0)[0] - tabline - winbar_sb, line("w0"))
call assert_equal(&spk == 'topline' ? 1 : win_screenpos(0)[0] - tl - wsb, line("w0"))
" No scroll for vertical split
quit | vsplit | wincmd l
@ -1725,8 +1723,8 @@ func Test_nosplitscroll_options()
call assert_equal(1, line("w0"))
" No scroll in windows split and quit multiple times
quit | redraw | split | redraw | split | redraw | quit | redraw
call assert_equal(win_screenpos(0)[0] - tabline - winbar_sb, line("w0"))
quit | redraw | split | split | quit | redraw
call assert_equal(&spk == 'topline' ? 1 : win_screenpos(0)[0] - tl - wsb, line("w0"))
" No scroll for new buffer
1wincmd w | only | copen | wincmd k
@ -1734,7 +1732,7 @@ func Test_nosplitscroll_options()
only
call assert_equal(1, line("w0"))
above copen | wincmd j
call assert_equal(win_screenpos(0)[0] - tabline, line("w0"))
call assert_equal(&spk == 'topline' ? 1 : win_screenpos(0)[0] - tl, line("w0"))
" No scroll when opening cmdwin, and no cursor move when closing cmdwin.
only | norm ggL
@ -1751,22 +1749,21 @@ func Test_nosplitscroll_options()
only | execute "norm gg5\<C-e>" | split | wincmd k
call assert_equal(6, line("w0"))
wincmd j
call assert_equal(5 + win_screenpos(0)[0] - tabline - winbar_sb, line("w0"))
call assert_equal(&spk == 'topline' ? 6 : 5 + win_screenpos(0)[0] - tl - wsb, line("w0"))
endfor
tabnew | tabonly! | %bwipeout!
iunmap c
set wrap&
set scrolloff&
set splitbelow&
set laststatus&
set equalalways&
set splitscroll&
set splitkeep&
let &t_WS = save_WS
endfunc
function Test_nosplitscroll_cmdwin_cursor_position()
set nosplitscroll
function Test_splitkeep_cmdwin_cursor_position()
set splitkeep=screen
call setline(1, range(&lines))
" No scroll when cursor is at near bottom of window and cusor position
@ -1789,11 +1786,11 @@ function Test_nosplitscroll_cmdwin_cursor_position()
call assert_equal(1, col('.'))
%bwipeout!
set splitscroll&
set splitkeep&
endfunction
function Test_nosplitscroll_misc()
set nosplitscroll
function Test_splitkeep_misc()
set splitkeep=screen
set splitbelow
call setline(1, range(1, &lines))
@ -1815,44 +1812,45 @@ function Test_nosplitscroll_misc()
%bwipeout!
set splitbelow&
set splitscroll&
set splitkeep&
endfunc
function Test_nosplitscroll_callback()
function Test_splitkeep_callback()
CheckScreendump
let lines =<< trim END
set nosplitscroll
set splitkeep=screen
call setline(1, range(&lines))
function WincmdCb(a, b)
function C1(a, b)
split | wincmd p
endfunction
function TermCb(a, b)
function C2(a, b)
close | split
endfunction
nnoremap t <cmd>call popup_create(term_start(&shell, { 'hidden': 1, 'exit_cb': 'TermCb' }), {})<CR>
nnoremap j <cmd>call job_start([&shell, &shellcmdflag, "echo"], { 'exit_cb': 'WincmdCb' })<CR>
nn j <cmd>call job_start([&sh, &shcf, "true"], { 'exit_cb': 'C1' })<CR>
nn t <cmd>call popup_create(term_start([&sh, &shcf, "true"],
\ { 'hidden': 1, 'exit_cb': 'C2' }), {})<CR>
END
call writefile(lines, 'XTestNosplitscrollCallback', 'D')
let buf = RunVimInTerminal('-S XTestNosplitscrollCallback', #{rows: 8})
call writefile(lines, 'XTestSplitkeepCallback', 'D')
let buf = RunVimInTerminal('-S XTestSplitkeepCallback', #{rows: 8})
call term_sendkeys(buf, "j")
call VerifyScreenDump(buf, 'Test_nosplitscroll_callback_1', {})
call VerifyScreenDump(buf, 'Test_splitkeep_callback_1', {})
call term_sendkeys(buf, ":quit\<CR>Htexit\<CR>")
call VerifyScreenDump(buf, 'Test_nosplitscroll_callback_2', {})
call term_sendkeys(buf, ":quit\<CR>Ht")
call VerifyScreenDump(buf, 'Test_splitkeep_callback_2', {})
call term_sendkeys(buf, ":set sb\<CR>:quit\<CR>Gj")
call VerifyScreenDump(buf, 'Test_nosplitscroll_callback_3', {})
call VerifyScreenDump(buf, 'Test_splitkeep_callback_3', {})
call term_sendkeys(buf, ":quit\<CR>Gtexit\<CR>")
call VerifyScreenDump(buf, 'Test_nosplitscroll_callback_4', {})
call term_sendkeys(buf, ":quit\<CR>Gt")
call VerifyScreenDump(buf, 'Test_splitkeep_callback_4', {})
endfunc
function Test_nosplitscroll_fold()
function Test_splitkeep_fold()
CheckScreendump
let lines =<< trim END
set nosplitscroll
set splitkeep=screen
set foldmethod=marker
set number
let line = 1
@ -1862,20 +1860,20 @@ let lines =<< trim END
let line += 8
endfor
END
call writefile(lines, 'XTestNosplitscrollFold', 'D')
let buf = RunVimInTerminal('-S XTestNosplitscrollFold', #{rows: 10})
call writefile(lines, 'XTestSplitkeepFold', 'D')
let buf = RunVimInTerminal('-S XTestSplitkeepFold', #{rows: 10})
call term_sendkeys(buf, "L:wincmd s\<CR>")
call VerifyScreenDump(buf, 'Test_nosplitscroll_fold_1', {})
call VerifyScreenDump(buf, 'Test_splitkeep_fold_1', {})
call term_sendkeys(buf, ":quit\<CR>")
call VerifyScreenDump(buf, 'Test_nosplitscroll_fold_2', {})
call VerifyScreenDump(buf, 'Test_splitkeep_fold_2', {})
call term_sendkeys(buf, "H:below split\<CR>")
call VerifyScreenDump(buf, 'Test_nosplitscroll_fold_3', {})
call VerifyScreenDump(buf, 'Test_splitkeep_fold_3', {})
call term_sendkeys(buf, ":wincmd k\<CR>:quit\<CR>")
call VerifyScreenDump(buf, 'Test_nosplitscroll_fold_4', {})
call VerifyScreenDump(buf, 'Test_splitkeep_fold_4', {})
endfunction
" vim: shiftwidth=2 sts=2 expandtab

View File

@ -699,6 +699,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
647,
/**/
646,
/**/

View File

@ -1325,7 +1325,7 @@ win_split_ins(
win_equal(wp, TRUE,
(flags & WSP_VERT) ? (dir == 'v' ? 'b' : 'h')
: dir == 'h' ? 'b' : 'v');
else if (!p_spsc && wp != aucmd_win)
else if (*p_spk != 'c' && wp != aucmd_win)
win_fix_scroll(FALSE);
// Don't change the window height/width to 'winheight' / 'winwidth' if a
@ -1411,7 +1411,7 @@ win_init(win_T *newp, win_T *oldp, int flags UNUSED)
newp->w_prevdir = (oldp->w_prevdir == NULL)
? NULL : vim_strsave(oldp->w_prevdir);
if (!p_spsc)
if (*p_spk != 'c')
{
newp->w_botline = oldp->w_botline;
newp->w_prev_height = oldp->w_height - WINBAR_HEIGHT(oldp);
@ -1925,7 +1925,7 @@ win_equal(
win_equal_rec(next_curwin == NULL ? curwin : next_curwin, current,
topframe, dir, 0, tabline_height(),
(int)Columns, topframe->fr_height);
if (!p_spsc && next_curwin != aucmd_win)
if (*p_spk != 'c' && next_curwin != aucmd_win)
win_fix_scroll(TRUE);
}
@ -2733,7 +2733,7 @@ win_close(win_T *win, int free_buf)
else
{
win_comp_pos();
if (!p_spsc)
if (*p_spk != 'c')
win_fix_scroll(FALSE);
}
if (close_curwin)
@ -4931,7 +4931,7 @@ win_enter_ext(win_T *wp, int flags)
// Might need to scroll the old window before switching, e.g., when the
// cursor was moved.
if (p_spsc)
if (*p_spk == 'c')
update_topline();
// may have to copy the buffer options when 'cpo' contains 'S'
@ -4947,7 +4947,7 @@ win_enter_ext(win_T *wp, int flags)
check_cursor();
if (!virtual_active())
curwin->w_cursor.coladd = 0;
if (p_spsc) // assume cursor position needs updating.
if (*p_spk == 'c') // assume cursor position needs updating
changed_line_abv_curs();
else
win_fix_cursor(TRUE);
@ -5068,7 +5068,7 @@ static int last_win_id = LOWEST_WIN_ID - 1;
* FALSE.
*/
static win_T *
win_alloc(win_T *after UNUSED, int hidden UNUSED)
win_alloc(win_T *after, int hidden)
{
win_T *new_wp;
@ -5480,7 +5480,7 @@ shell_new_rows(void)
compute_cmdrow();
curtab->tp_ch_used = p_ch;
if (!p_spsc && !skip_win_fix_scroll)
if (*p_spk != 'c' && !skip_win_fix_scroll)
win_fix_scroll(TRUE);
#if 0
@ -5687,7 +5687,7 @@ win_setheight_win(int height, win_T *win)
msg_row = row;
msg_col = 0;
if (!p_spsc)
if (*p_spk != 'c')
win_fix_scroll(TRUE);
redraw_all_later(UPD_NOT_VALID);
@ -6218,7 +6218,7 @@ win_drag_status_line(win_T *dragwin, int offset)
p_ch = MAX(Rows - cmdline_row, 1);
curtab->tp_ch_used = p_ch;
if (!p_spsc)
if (*p_spk != 'c')
win_fix_scroll(TRUE);
redraw_all_later(UPD_SOME_VALID);
@ -6348,7 +6348,7 @@ set_fraction(win_T *wp)
}
/*
* Handle scroll position for 'nosplitscroll'. Replaces scroll_to_fraction()
* Handle scroll position for 'splitkeep'. Replaces scroll_to_fraction()
* call from win_new_height(). Instead we iterate over all windows in a
* tabpage and calculate the new scroll position.
* TODO: Ensure this also works with wrapped lines.
@ -6362,14 +6362,14 @@ win_fix_scroll(int resize)
win_T *wp;
linenr_T lnum;
skip_update_topline = TRUE; // avoid scrolling in curs_columns()
skip_update_topline = TRUE;
FOR_ALL_WINDOWS(wp)
{
// Skip when window height has not changed.
if (wp->w_height != wp->w_prev_height)
{
// If window has moved update botline to keep the same screenlines.
if (wp->w_winrow != wp->w_prev_winrow)
if (*p_spk == 's' && wp->w_winrow != wp->w_prev_winrow)
{
lnum = wp->w_cursor.lnum;
diff = (wp->w_winrow - wp->w_prev_winrow)
@ -6403,7 +6403,7 @@ win_fix_scroll(int resize)
}
/*
* Make sure the cursor position is valid for 'nosplitscroll'.
* Make sure the cursor position is valid for 'splitkeep'.
* If it is not, put the cursor position in the jumplist and move it.
* If we are not in normal mode, scroll to make valid instead.
*/
@ -6429,25 +6429,23 @@ win_fix_cursor(int normal)
top = cursor_down_inner(wp, so);
wp->w_cursor.lnum = wp->w_botline - 1;
bot = cursor_up_inner(wp, so);
wp->w_cursor.lnum = lnum;
// Check if cursor position is above or below valid cursor range.
if (lnum > bot && (wp->w_botline - wp->w_buffer->b_ml.ml_line_count) != 1)
nlnum = bot;
else if (lnum < top && wp->w_topline != 1)
nlnum = (so == wp->w_height / 2) ? bot : top;
wp->w_cursor.lnum = lnum;
if (nlnum) // Cursor is invalid for current scroll position.
{
if (normal) // Save to jumplist and set cursor to avoid scrolling.
{
setmark('\'');
wp->w_cursor.lnum = nlnum;
curs_columns(TRUE); // validate w_wrow
}
else // Scroll instead when not in normal mode.
{
wp->w_fraction = 0.5 * FRACTION_MULT;
wp->w_fraction = (nlnum == bot) ? FRACTION_MULT : 0;
scroll_to_fraction(wp, wp->w_prev_height);
validate_botline_win(curwin);
}
@ -6474,7 +6472,7 @@ win_new_height(win_T *wp, int height)
if (wp->w_height > 0)
{
if (wp == curwin && p_spsc)
if (wp == curwin && *p_spk == 'c')
// w_wrow needs to be valid. When setting 'laststatus' this may
// call win_new_height() recursively.
validate_cursor();
@ -6490,7 +6488,7 @@ win_new_height(win_T *wp, int height)
// There is no point in adjusting the scroll position when exiting. Some
// values might be invalid.
if (!exiting && p_spsc)
if (!exiting && *p_spk == 'c')
scroll_to_fraction(wp, prev_height);
}
@ -6604,7 +6602,7 @@ scroll_to_fraction(win_T *wp, int prev_height)
if (wp == curwin)
{
if (p_spsc && get_scrolloff_value())
if (get_scrolloff_value())
update_topline();
curs_columns(FALSE); // validate w_wrow
}
@ -6627,15 +6625,13 @@ win_new_width(win_T *wp, int width)
wp->w_width = width < 0 ? 0 : width;
wp->w_lines_valid = 0;
changed_line_abv_curs_win(wp);
// Handled in win_fix_scroll()
if (p_spsc)
{
invalidate_botline_win(wp);
if (wp == curwin)
{
skip_update_topline = (*p_spk != 'c');
update_topline();
curs_columns(TRUE); // validate w_wrow
}
skip_update_topline = FALSE;
}
redraw_win_later(wp, UPD_NOT_VALID);
wp->w_redr_status = TRUE;