mirror of
https://github.com/neovim/neovim.git
synced 2024-12-20 03:05:11 -07:00
vim-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: vim/vim#12956
closes: vim/vim#12643
4a8eb6e7a9
Co-authored-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
parent
99265d099c
commit
0ba27bb51d
@ -189,6 +189,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
|
||||
@ -238,6 +240,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
|
||||
@ -311,7 +337,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', 'omnifunc', 'operatorfunc', 'quickfixtextfunc',
|
||||
'tagfunc' and 'thesaurusfunc') are set to a function name or a function
|
||||
@ -1070,7 +1095,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
|
||||
@ -1102,7 +1127,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
|
||||
acwrite buffer will always be written with |BufWriteCmd|s
|
||||
@ -2408,7 +2433,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
|
||||
@ -4084,7 +4109,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
|
||||
@ -4532,7 +4557,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
|
||||
*'previewwindow'* *'pvw'* *'nopreviewwindow'* *'nopvw'* *E590*
|
||||
'previewwindow' 'pvw' boolean (default off)
|
||||
local to window
|
||||
local to window |special-local-window-option|
|
||||
Identifies the preview window. Only one window can have this option
|
||||
set. It's normally not set directly, but by using one of the commands
|
||||
|:ptag|, |:pedit|, etc.
|
||||
@ -4602,7 +4627,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".
|
||||
@ -4864,7 +4889,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
|
||||
@ -6214,7 +6239,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
|
||||
*'syntax'* *'syn'*
|
||||
'syntax' 'syn' string (default "")
|
||||
local to buffer
|
||||
local to buffer |special-local-buffer-option|
|
||||
When this option is set, the syntax with this name is loaded, unless
|
||||
syntax highlighting has been switched off with ":syntax off".
|
||||
Otherwise this option does not always reflect the current syntax (the
|
||||
@ -7081,7 +7106,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|.
|
||||
@ -7089,7 +7114,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.
|
||||
|
@ -542,6 +542,36 @@ local function scope_to_doc(s)
|
||||
return 'global or '..m[s[2]]..' |global-local|'
|
||||
end
|
||||
|
||||
-- @param o vim.option_meta
|
||||
-- @return string
|
||||
local function scope_more_doc(o)
|
||||
if
|
||||
vim.list_contains({
|
||||
'previewwindow',
|
||||
'scroll',
|
||||
'winfixheight',
|
||||
'winfixwidth',
|
||||
}, o.full_name)
|
||||
then
|
||||
return ' |special-local-window-option|'
|
||||
end
|
||||
|
||||
if
|
||||
vim.list_contains({
|
||||
'bufhidden',
|
||||
'buftype',
|
||||
'filetype',
|
||||
'modified',
|
||||
'readonly',
|
||||
'syntax',
|
||||
}, o.full_name)
|
||||
then
|
||||
return ' |special-local-buffer-option|'
|
||||
end
|
||||
|
||||
return ''
|
||||
end
|
||||
|
||||
--- @return table<string,vim.option_meta>
|
||||
local function get_option_meta()
|
||||
local opts = require('src/nvim/options').options
|
||||
@ -624,7 +654,7 @@ local function render_option_doc(_f, opt, write)
|
||||
write(string.format('%s\t%s', name_str, otype))
|
||||
end
|
||||
|
||||
write('\t\t\t'..scope_to_doc(opt.scope))
|
||||
write('\t\t\t'..scope_to_doc(opt.scope)..scope_more_doc(opt))
|
||||
for _, l in ipairs(split(opt.desc)) do
|
||||
if l == '<' or l:match('^<%s') then
|
||||
write(l)
|
||||
|
@ -230,6 +230,10 @@ typedef struct {
|
||||
#define w_p_crb_save w_onebuf_opt.wo_crb_save
|
||||
char *wo_scl;
|
||||
#define w_p_scl w_onebuf_opt.wo_scl // 'signcolumn'
|
||||
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
|
||||
char *wo_winhl;
|
||||
#define w_p_winhl w_onebuf_opt.wo_winhl // 'winhighlight'
|
||||
char *wo_lcs;
|
||||
@ -1321,8 +1325,6 @@ struct window_S {
|
||||
uint32_t w_p_fdt_flags; // flags for 'foldtext'
|
||||
int *w_p_cc_cols; // array of columns to highlight or NULL
|
||||
uint8_t w_p_culopt_flags; // flags for cursorline highlighting
|
||||
long w_p_siso; // 'sidescrolloff' local value
|
||||
long w_p_so; // 'scrolloff' local value
|
||||
|
||||
int w_briopt_min; // minimum width for breakindent
|
||||
int w_briopt_shift; // additional shift for breakindent
|
||||
|
@ -4702,6 +4702,8 @@ void 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;
|
||||
to->wo_spell = from->wo_spell;
|
||||
to->wo_cuc = from->wo_cuc;
|
||||
to->wo_cul = from->wo_cul;
|
||||
|
@ -5132,8 +5132,8 @@ static win_T *win_alloc(win_T *after, bool hidden)
|
||||
new_wp->w_ns_hl = -1;
|
||||
|
||||
// use global option 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;
|
||||
|
@ -1548,7 +1548,7 @@ describe('lua stdlib', function()
|
||||
eq(100, funcs.luaeval "vim.wo.scrolloff")
|
||||
exec_lua [[
|
||||
vim.wo[0][0].scrolloff = 200
|
||||
vim.cmd "split"
|
||||
vim.cmd "enew"
|
||||
]]
|
||||
eq(100, funcs.luaeval "vim.wo.scrolloff")
|
||||
end)
|
||||
|
@ -1682,4 +1682,90 @@ 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, ' ')})
|
||||
let result = getline(1, '$')->map({_, val -> matchlist(val, '\([^ ]\+\) \+\([^ ]\+\) \+\(.*\)')[1:3]})
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user