patch 9.0.1710: scrolloff options work slightly different
Problem: sidescrolloff and scrolloff options work slightly
different than other global-local options
Solution: Make it behave consistent for all global-local options
It was noticed, that sidescrolloff and scrolloff options behave
differently in comparison to other global-local window options like
'listchars'
So make those two behave like other global-local options. Also add some
extra documentation for a few special local-window options.
Add a few tests to make sure all global-local window options behave
similar
closes: #12956
closes: #12643
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/option.c b/src/option.c
index 3050dbc..a6d73d2 100644
--- a/src/option.c
+++ b/src/option.c
@@ -6652,6 +6652,8 @@
to->wo_sms = from->wo_sms;
to->wo_crb = from->wo_crb;
to->wo_crb_save = from->wo_crb_save;
+ to->wo_siso = from->wo_siso;
+ to->wo_so = from->wo_so;
#ifdef FEAT_SPELL
to->wo_spell = from->wo_spell;
#endif
diff --git a/src/structs.h b/src/structs.h
index ccef537..1b4308e 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -312,6 +312,10 @@
char_u *wo_scl;
# define w_p_scl w_onebuf_opt.wo_scl // 'signcolumn'
#endif
+ long wo_siso;
+# define w_p_siso w_onebuf_opt.wo_siso // 'sidescrolloff' local value
+ long wo_so;
+# define w_p_so w_onebuf_opt.wo_so // 'scrolloff' local value
#ifdef FEAT_TERMINAL
char_u *wo_twk;
# define w_p_twk w_onebuf_opt.wo_twk // 'termwinkey'
@@ -3977,8 +3981,6 @@
int *w_p_cc_cols; // array of columns to highlight or NULL
char_u w_p_culopt_flags; // flags for cursorline highlighting
#endif
- long w_p_siso; // 'sidescrolloff' local value
- long w_p_so; // 'scrolloff' local value
#ifdef FEAT_LINEBREAK
int w_briopt_min; // minimum width for breakindent
diff --git a/src/testdir/test_options.vim b/src/testdir/test_options.vim
index 0de5e25..5bacebc 100644
--- a/src/testdir/test_options.vim
+++ b/src/testdir/test_options.vim
@@ -1689,4 +1689,89 @@
bw!
endfunc
+func Test_set_option_window_global_local()
+ new Xbuffer1
+ let [ _gso, _lso ] = [ &g:scrolloff, &l:scrolloff ]
+ setlocal scrolloff=2
+ setglobal scrolloff=3
+ setl modified
+ " A new buffer has its own window-local options
+ hide enew
+ call assert_equal(-1, &l:scrolloff)
+ call assert_equal(3, &g:scrolloff)
+ " A new window opened with its own buffer-local options
+ new
+ call assert_equal(-1, &l:scrolloff)
+ call assert_equal(3, &g:scrolloff)
+ " Re-open Xbuffer1 and it should use
+ " the previous set window-local options
+ b Xbuffer1
+ call assert_equal(2, &l:scrolloff)
+ call assert_equal(3, &g:scrolloff)
+ bw!
+ bw!
+ let &g:scrolloff = _gso
+endfunc
+
+func GetGlobalLocalWindowOptions()
+ new
+ sil! r $VIMRUNTIME/doc/options.txt
+ " Filter for global or local to window
+ v/^'.*'.*\n.*global or local to window |global-local/d
+ " get option value and type
+ sil %s/^'\([^']*\)'.*'\s\+\(\w\+\)\s\+(default \%(\(".*"\|\d\+\|empty\)\).*/\1 \2 \3/g
+ sil %s/empty/""/g
+ " split the result
+ let result=getline(1,'$')->map({_, val -> split(val, ' ')})
+ bw!
+ return result
+endfunc
+
+func Test_set_option_window_global_local_all()
+ new Xbuffer2
+
+ let optionlist = GetGlobalLocalWindowOptions()
+ for [opt, type, default] in optionlist
+ let _old = eval('&g:' .. opt)
+ if type == 'string'
+ if opt == 'fillchars'
+ exe 'setl ' .. opt .. '=vert:+'
+ exe 'setg ' .. opt .. '=vert:+,fold:+'
+ elseif opt == 'listchars'
+ exe 'setl ' .. opt .. '=tab:>>'
+ exe 'setg ' .. opt .. '=tab:++'
+ elseif opt == 'virtualedit'
+ exe 'setl ' .. opt .. '=all'
+ exe 'setg ' .. opt .. '=block'
+ else
+ exe 'setl ' .. opt .. '=Local'
+ exe 'setg ' .. opt .. '=Global'
+ endif
+ elseif type == 'number'
+ exe 'setl ' .. opt .. '=5'
+ exe 'setg ' .. opt .. '=10'
+ endif
+ setl modified
+ hide enew
+ if type == 'string'
+ call assert_equal('', eval('&l:' .. opt))
+ if opt == 'fillchars'
+ call assert_equal('vert:+,fold:+', eval('&g:' .. opt), 'option:' .. opt)
+ elseif opt == 'listchars'
+ call assert_equal('tab:++', eval('&g:' .. opt), 'option:' .. opt)
+ elseif opt == 'virtualedit'
+ call assert_equal('block', eval('&g:' .. opt), 'option:' .. opt)
+ else
+ call assert_equal('Global', eval('&g:' .. opt), 'option:' .. opt)
+ endif
+ elseif type == 'number'
+ call assert_equal(-1, eval('&l:' .. opt), 'option:' .. opt)
+ call assert_equal(10, eval('&g:' .. opt), 'option:' .. opt)
+ endif
+ bw!
+ exe 'let &g:' .. opt .. '=' .. default
+ endfor
+ bw!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 311bb8c..100dd95 100644
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1710,
+/**/
1709,
/**/
1708,
diff --git a/src/window.c b/src/window.c
index f02aa9f..33d19fa 100644
--- a/src/window.c
+++ b/src/window.c
@@ -5546,8 +5546,8 @@
new_wp->w_scbind_pos = 1;
// use global option value for global-local options
- new_wp->w_p_so = -1;
- new_wp->w_p_siso = -1;
+ new_wp->w_allbuf_opt.wo_so = new_wp->w_p_so = -1;
+ new_wp->w_allbuf_opt.wo_siso = new_wp->w_p_siso = -1;
// We won't calculate w_fraction until resizing the window
new_wp->w_fraction = 0;