patch 9.0.1710: scrolloff options work slightly different

Commit: 
https://github.com/vim/vim/commit/4a8eb6e7a9df10f79bf95301ced012f0d6a13088
Author: Christian Brabandt <[email protected]>
Date:   Sun Aug 13 19:43:42 2023 +0200

    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 <[email protected]>

diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 9292b05a4..ec2b8756b 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -252,6 +252,8 @@ opt+=val" the expansion is done before the adding or 
removing.
 
 Handling of local options                      *local-options*
 
+Note: The following also applies to |global-local| options.
+
 Some of the options only apply to a window or buffer.  Each window or buffer
 has its own copy of this option, thus each can have its own value.  This
 allows you to set 'list' in one window but not in another.  And set
@@ -301,6 +303,30 @@ The options local to a window are remembered for each 
buffer.  This also
 happens when the buffer is not loaded, but they are lost when the buffer is
 wiped out |:bwipe|.
 
+Special local window options                   *special-local-window-option*
+
+The following local window options won't be copied over when new windows are
+created, thus they behave slightly differently:
+
+       Option          Reason  ~
+       'previewwindow' there can only be a single one
+       'scroll'        specific to existing window
+       'winfixheight'  specific to existing window
+       'winfixwidth'   specific to existing window
+
+Special local buffer options                   *special-local-buffer-option*
+
+The following local buffer options won't be copied over when new buffers are
+created, thus they behave slightly differently:
+
+       Option          Reason  ~
+       'filetype'      explicitly set by autocommands
+       'syntax'        explicitly set by autocommands
+       'bufhidden'     denote |special-buffers|
+       'buftype'       denote |special-buffers|
+       'readonly'      will be detected automatically
+       'modified'      will be detected automatically
+
                                                        *:setl* *:setlocal*
 :setl[ocal][!] ...     Like ":set" but set only the value local to the
                        current buffer or window.  Not all options have a
@@ -374,7 +400,6 @@ used.  Thus it does the same as: >
 Note: In the future more global options can be made |global-local|.  Using
 ":setlocal" on a global option might work differently then.
 
-
                                                *option-value-function*
 Some options ('completefunc', 'imactivatefunc', 'imstatusfunc', 'omnifunc',
 'operatorfunc', 'quickfixtextfunc', 'tagfunc' and 'thesaurusfunc') are set to
@@ -1449,7 +1474,7 @@ A jump table for the options with a short description can 
be found at |Q_op|.
 
                                                *'bufhidden'* *'bh'*
 'bufhidden' 'bh'       string (default: "")
-                       local to buffer
+                       local to buffer  |special-local-buffer-option|
        This option specifies what happens when a buffer is no longer
        displayed in a window:
          <empty>       follow the global 'hidden' option
@@ -1481,7 +1506,7 @@ A jump table for the options with a short description can 
be found at |Q_op|.
 
                                                *'buftype'* *'bt'* *E382*
 'buftype' 'bt'         string (default: "")
-                       local to buffer
+                       local to buffer  |special-local-buffer-option|
        The value of this option specifies the type of a buffer:
          <empty>       normal buffer
          nofile        buffer which is not related to a file and will not be
@@ -3408,7 +3433,7 @@ A jump table for the options with a short description can 
be found at |Q_op|.
 
                                        *'filetype'* *'ft'*
 'filetype' 'ft'                string (default: "")
-                       local to buffer
+                       local to buffer  |special-local-buffer-option|
        When this option is set, the FileType autocommand event is triggered.
        All autocommands that match with the value of this option will be
        executed.  Thus the value of 'filetype' is used in place of the file
@@ -5565,7 +5590,7 @@ A jump table for the options with a short description can 
be found at |Q_op|.
 
                                *'modified'* *'mod'* *'nomodified'* *'nomod'*
 'modified' 'mod'       boolean (default off)
-                       local to buffer
+                       local to buffer  |special-local-buffer-option|
        When on, the buffer is considered to be modified.  This option is set
        when:
        1. A change was made to the text since it was last written.  Using the
@@ -6136,7 +6161,7 @@ A jump table for the options with a short description can 
be found at |Q_op|.
                                        *'previewwindow'* *'nopreviewwindow'*
                                        *'pvw'* *'nopvw'* *E590*
 'previewwindow' 'pvw'  boolean (default off)
-                       local to window
+                       local to window  |special-local-window-option|
                        {not available when compiled without the |+quickfix|
                        feature}
        Identifies the preview window.  Only one window can have this option
@@ -6331,7 +6356,7 @@ A jump table for the options with a short description can 
be found at |Q_op|.
 
                                   *'readonly'* *'ro'* *'noreadonly'* *'noro'*
 'readonly' 'ro'                boolean (default off)
-                       local to buffer
+                       local to buffer  |special-local-buffer-option|
        If on, writes fail unless you use a '!'.  Protects you from
        accidentally overwriting a file.  Default on when Vim is started
        in read-only mode ("vim -R") or when the executable is called "view".
@@ -6710,7 +6735,7 @@ A jump table for the options with a short description can 
be found at |Q_op|.
 
                                                *'scroll'* *'scr'*
 'scroll' 'scr'         number  (default: half the window height)
-                       local to window
+                       local to window  |special-local-window-option|
        Number of lines to scroll with CTRL-U and CTRL-D commands.  Will be
        set to half the number of lines in the window when the window size
        changes.  This may happen when enabling the |status-line| or
@@ -7972,7 +7997,7 @@ A jump table for the options with a short description can 
be found at |Q_op|.
 
                                                *'syntax'* *'syn'*
 'syntax' 'syn'         string  (default empty)
-                       local to buffer
+                       local to buffer  |special-local-buffer-option|
                        {not available when compiled without the |+syntax|
                        feature}
        When this option is set, the syntax with this name is loaded, unless
@@ -9420,7 +9445,7 @@ A jump table for the options with a short description can 
be found at |Q_op|.
 
                        *'winfixheight'* *'wfh'* *'nowinfixheight'* *'nowfh'*
 'winfixheight' 'wfh'   boolean (default off)
-                       local to window
+                       local to window  |special-local-window-option|
        Keep the window height when windows are opened or closed and
        'equalalways' is set.  Also for |CTRL-W_=|.  Set by default for the
        |preview-window| and |quickfix-window|.
@@ -9428,7 +9453,7 @@ A jump table for the options with a short description can 
be found at |Q_op|.
 
                        *'winfixwidth'* *'wfw'* *'nowinfixwidth'* *'nowfw'*
 'winfixwidth' 'wfw'    boolean (default off)
-                       local to window
+                       local to window  |special-local-window-option|
        Keep the window width when windows are opened or closed and
        'equalalways' is set.  Also for |CTRL-W_=|.
        The width may be changed anyway when running out of room.
diff --git a/runtime/doc/tags b/runtime/doc/tags
index b34ecd5de..ce1918f26 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -9708,6 +9708,8 @@ spec_chglog_format        pi_spec.txt     
/*spec_chglog_format*
 spec_chglog_prepend    pi_spec.txt     /*spec_chglog_prepend*
 spec_chglog_release_info       pi_spec.txt     /*spec_chglog_release_info*
 special-buffers        windows.txt     /*special-buffers*
+special-local-buffer-option    options.txt     /*special-local-buffer-option*
+special-local-window-option    options.txt     /*special-local-window-option*
 specifies      vim9class.txt   /*specifies*
 speed-up       tips.txt        /*speed-up*
 spell  spell.txt       /*spell*
diff --git a/src/option.c b/src/option.c
index 3050dbc41..a6d73d2f5 100644
--- a/src/option.c
+++ b/src/option.c
@@ -6652,6 +6652,8 @@ copy_winopt(winopt_T *from, winopt_T *to)
     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 ccef53704..1b4308e6b 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -312,6 +312,10 @@ typedef struct
     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 @@ struct window_S
     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 0de5e25f9..5bacebc35 100644
--- a/src/testdir/test_options.vim
+++ b/src/testdir/test_options.vim
@@ -1689,4 +1689,89 @@ func Test_string_option_revert_on_failure()
   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 311bb8c73..100dd95b3 100644
--- a/src/version.c
+++ b/src/version.c
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1710,
 /**/
     1709,
 /**/
diff --git a/src/window.c b/src/window.c
index f02aa9f05..33d19fadb 100644
--- a/src/window.c
+++ b/src/window.c
@@ -5546,8 +5546,8 @@ win_alloc(win_T *after, int hidden)
     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;

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/E1qVFNk-000MDW-BX%40256bit.org.

Raspunde prin e-mail lui