neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

test_options.vim (96360B)


      1 " Test for options
      2 
      3 source shared.vim
      4 source check.vim
      5 source view_util.vim
      6 
      7 scriptencoding utf-8
      8 
      9 func Test_whichwrap()
     10  set whichwrap=b,s
     11  call assert_equal('b,s', &whichwrap)
     12 
     13  set whichwrap+=h,l
     14  call assert_equal('b,s,h,l', &whichwrap)
     15 
     16  set whichwrap+=h,l
     17  call assert_equal('b,s,h,l', &whichwrap)
     18 
     19  set whichwrap+=h,l
     20  call assert_equal('b,s,h,l', &whichwrap)
     21 
     22  set whichwrap=h,h
     23  call assert_equal('h', &whichwrap)
     24 
     25  set whichwrap=h,h,h
     26  call assert_equal('h', &whichwrap)
     27 
     28  " " For compatibility with Vim 3.0 and before, number values are also
     29  " " supported for 'whichwrap'
     30  " set whichwrap=1
     31  " call assert_equal('b', &whichwrap)
     32  " set whichwrap=2
     33  " call assert_equal('s', &whichwrap)
     34  " set whichwrap=4
     35  " call assert_equal('h,l', &whichwrap)
     36  " set whichwrap=8
     37  " call assert_equal('<,>', &whichwrap)
     38  " set whichwrap=16
     39  " call assert_equal('[,]', &whichwrap)
     40  " set whichwrap=31
     41  " call assert_equal('b,s,h,l,<,>,[,]', &whichwrap)
     42 
     43  set whichwrap&
     44 endfunc
     45 
     46 func Test_isfname()
     47  " This used to cause Vim to access uninitialized memory.
     48  set isfname=
     49  call assert_equal("~X", expand("~X"))
     50  set isfname&
     51  " Test for setting 'isfname' to an unsupported character
     52  let save_isfname = &isfname
     53  call assert_fails('exe $"set isfname+={"\u1234"}"', 'E474:')
     54  call assert_equal(save_isfname, &isfname)
     55 endfunc
     56 
     57 " Test for getting the value of 'pastetoggle'
     58 func Test_pastetoggle()
     59  throw "Skipped: 'pastetoggle' is removed from Nvim"
     60  " character with K_SPECIAL byte
     61  let &pastetoggle = '…'
     62  call assert_equal('…', &pastetoggle)
     63  call assert_equal("\n  pastetoggle=…", execute('set pastetoggle?'))
     64 
     65  " modified character with K_SPECIAL byte
     66  let &pastetoggle = '<M-…>'
     67  call assert_equal('<M-…>', &pastetoggle)
     68  call assert_equal("\n  pastetoggle=<M-…>", execute('set pastetoggle?'))
     69 
     70  " illegal bytes
     71  let str = ":\x7f:\x80:\x90:\xd0:"
     72  let &pastetoggle = str
     73  call assert_equal(str, &pastetoggle)
     74  call assert_equal("\n  pastetoggle=" .. strtrans(str), execute('set pastetoggle?'))
     75 
     76  unlet str
     77  set pastetoggle&
     78 endfunc
     79 
     80 func Test_wildchar()
     81  " Empty 'wildchar' used to access invalid memory.
     82  call assert_fails('set wildchar=', 'E521:')
     83  call assert_fails('set wildchar=abc', 'E521:')
     84  set wildchar=<Esc>
     85  let a=execute('set wildchar?')
     86  call assert_equal("\n  wildchar=<Esc>", a)
     87  set wildchar=27
     88  let a=execute('set wildchar?')
     89  call assert_equal("\n  wildchar=<Esc>", a)
     90  set wildchar&
     91 endfunc
     92 
     93 func Test_wildoptions()
     94  set wildoptions=
     95  set wildoptions+=tagfile
     96  set wildoptions+=tagfile
     97  call assert_equal('tagfile', &wildoptions)
     98 endfunc
     99 
    100 func Test_options_command()
    101  let caught = 'ok'
    102  try
    103    options
    104  catch
    105    let caught = v:throwpoint . "\n" . v:exception
    106  endtry
    107  call assert_equal('ok', caught)
    108 
    109  " Check if the option-window is opened horizontally.
    110  wincmd j
    111  call assert_notequal('nvim-optwin://optwin', bufname(''))
    112  wincmd k
    113  call assert_equal('nvim-optwin://optwin', bufname(''))
    114  " close option-window
    115  close
    116 
    117  " Open the option-window vertically.
    118  vert options
    119  " Check if the option-window is opened vertically.
    120  wincmd l
    121  call assert_notequal('nvim-optwin://optwin', bufname(''))
    122  wincmd h
    123  call assert_equal('nvim-optwin://optwin', bufname(''))
    124  " close option-window
    125  close
    126 
    127  " Open the option-window at the top.
    128  set splitbelow
    129  topleft options
    130  call assert_equal(1, winnr())
    131  close
    132 
    133  " Open the option-window at the bottom.
    134  set nosplitbelow
    135  botright options
    136  call assert_equal(winnr('$'), winnr())
    137  close
    138  set splitbelow&
    139 
    140  " Open the option-window in a new tab.
    141  tab options
    142  " Check if the option-window is opened in a tab.
    143  normal gT
    144  call assert_notequal('nvim-optwin://optwin', bufname(''))
    145  normal gt
    146  call assert_equal('nvim-optwin://optwin', bufname(''))
    147  " close option-window
    148  close
    149 
    150  " Open the options window browse
    151  if has('browse')
    152    browse set
    153    call assert_equal('nvim-optwin://optwin', bufname(''))
    154    close
    155  endif
    156 endfunc
    157 
    158 func Test_path_keep_commas()
    159  " Test that changing 'path' keeps two commas.
    160  set path=foo,,bar
    161  set path-=bar
    162  set path+=bar
    163  call assert_equal('foo,,bar', &path)
    164 
    165  set path&
    166 endfunc
    167 
    168 func Test_path_too_long()
    169  exe 'set path=' .. repeat('x', 10000)
    170  call assert_fails('find x', 'E854:')
    171  set path&
    172 endfunc
    173 
    174 func Test_signcolumn()
    175  CheckFeature signs
    176  call assert_equal("auto", &signcolumn)
    177  set signcolumn=yes
    178  set signcolumn=no
    179  call assert_fails('set signcolumn=nope', 'E474: Invalid argument: signcolumn=nope')
    180 endfunc
    181 
    182 func Test_filetype_valid()
    183  set ft=valid_name
    184  call assert_equal("valid_name", &filetype)
    185  set ft=valid-name
    186  call assert_equal("valid-name", &filetype)
    187 
    188  call assert_fails(":set ft=wrong;name", "E474:")
    189  call assert_fails(":set ft=wrong\\\\name", "E474:")
    190  call assert_fails(":set ft=wrong\\|name", "E474:")
    191  call assert_fails(":set ft=wrong/name", "E474:")
    192  call assert_fails(":set ft=wrong\\\nname", "E474:")
    193  call assert_equal("valid-name", &filetype)
    194 
    195  exe "set ft=trunc\x00name"
    196  call assert_equal("trunc", &filetype)
    197 endfunc
    198 
    199 func Test_syntax_valid()
    200  if !has('syntax')
    201    return
    202  endif
    203  set syn=valid_name
    204  call assert_equal("valid_name", &syntax)
    205  set syn=valid-name
    206  call assert_equal("valid-name", &syntax)
    207 
    208  call assert_fails(":set syn=wrong;name", "E474:")
    209  call assert_fails(":set syn=wrong\\\\name", "E474:")
    210  call assert_fails(":set syn=wrong\\|name", "E474:")
    211  call assert_fails(":set syn=wrong/name", "E474:")
    212  call assert_fails(":set syn=wrong\\\nname", "E474:")
    213  call assert_equal("valid-name", &syntax)
    214 
    215  exe "set syn=trunc\x00name"
    216  call assert_equal("trunc", &syntax)
    217 endfunc
    218 
    219 func Test_keymap_valid()
    220  if !has('keymap')
    221    return
    222  endif
    223  call assert_fails(":set kmp=valid_name", "E544:")
    224  call assert_fails(":set kmp=valid_name", "valid_name")
    225  call assert_fails(":set kmp=valid-name", "E544:")
    226  call assert_fails(":set kmp=valid-name", "valid-name")
    227 
    228  call assert_fails(":set kmp=wrong;name", "E474:")
    229  call assert_fails(":set kmp=wrong\\\\name", "E474:")
    230  call assert_fails(":set kmp=wrong\\|name", "E474:")
    231  call assert_fails(":set kmp=wrong/name", "E474:")
    232  call assert_fails(":set kmp=wrong\\\nname", "E474:")
    233 
    234  call assert_fails(":set kmp=trunc\x00name", "E544:")
    235  call assert_fails(":set kmp=trunc\x00name", "trunc")
    236 endfunc
    237 
    238 func Test_wildchar_valid()
    239  call assert_fails("set wildchar=<CR>", "E474:")
    240  call assert_fails("set wildcharm=<C-C>", "E474:")
    241 endfunc
    242 
    243 func Check_dir_option(name)
    244  " Check that it's possible to set the option.
    245  exe 'set ' . a:name . '=/usr/share/dict/words'
    246  call assert_equal('/usr/share/dict/words', eval('&' . a:name))
    247  exe 'set ' . a:name . '=/usr/share/dict/words,/and/there'
    248  call assert_equal('/usr/share/dict/words,/and/there', eval('&' . a:name))
    249  exe 'set ' . a:name . '=/usr/share/dict\ words'
    250  call assert_equal('/usr/share/dict words', eval('&' . a:name))
    251 
    252  " Check rejecting weird characters.
    253  call assert_fails("set " . a:name . "=/not&there", "E474:")
    254  call assert_fails("set " . a:name . "=/not>there", "E474:")
    255  call assert_fails("set " . a:name . "=/not.*there", "E474:")
    256 endfunc
    257 
    258 func Test_cinkeys()
    259  " This used to cause invalid memory access
    260  set cindent cinkeys=0
    261  norm a
    262  set cindent& cinkeys&
    263 endfunc
    264 
    265 func Test_dictionary()
    266  call Check_dir_option('dictionary')
    267 endfunc
    268 
    269 func Test_thesaurus()
    270  call Check_dir_option('thesaurus')
    271 endfun
    272 
    273 func Test_complete()
    274  " Trailing single backslash used to cause invalid memory access.
    275  set complete=s\
    276  new
    277  call feedkeys("i\<C-N>\<Esc>", 'xt')
    278  bwipe!
    279  call assert_fails('set complete=ix', 'E535: Illegal character after <i>')
    280  call assert_fails('set complete=x', 'E539: Illegal character <x>')
    281  call assert_fails('set complete=..', 'E535: Illegal character after <.>')
    282  set complete=.,w,b,u,k,\ s,i,d,],t,U,F,o
    283  call assert_fails('set complete=i^-10', 'E535: Illegal character after <^>')
    284  call assert_fails('set complete=i^x', 'E535: Illegal character after <^>')
    285  call assert_fails('set complete=k^2,t^-1,s^', 'E535: Illegal character after <^>')
    286  call assert_fails('set complete=t^-1', 'E535: Illegal character after <^>')
    287  call assert_fails('set complete=kfoo^foo2', 'E535: Illegal character after <^>')
    288  call assert_fails('set complete=kfoo^', 'E535: Illegal character after <^>')
    289  call assert_fails('set complete=.^', 'E535: Illegal character after <^>')
    290  set complete=.,w,b,u,k,s,i,d,],t,U,F,o
    291  set complete=.
    292  set complete=.^10,t^0
    293 
    294  func Foo(a, b)
    295    return ''
    296  endfunc
    297 
    298  set complete+=Ffuncref('Foo'\\,\ [10])
    299  set complete=Ffuncref('Foo'\\,\ [10])^10
    300  set complete&
    301  set complete+=Ffunction('g:Foo'\\,\ [10\\,\ 20])
    302  set complete&
    303  delfunc Foo
    304 endfun
    305 
    306 func Test_set_completion()
    307  call feedkeys(":set di\<C-A>\<C-B>\"\<CR>", 'tx')
    308  call assert_equal('"set dictionary diff diffanchors diffexpr diffopt digraph directory display', @:)
    309 
    310  call feedkeys(":setlocal di\<C-A>\<C-B>\"\<CR>", 'tx')
    311  call assert_equal('"setlocal dictionary diff diffanchors diffexpr diffopt digraph directory display', @:)
    312 
    313  call feedkeys(":setglobal di\<C-A>\<C-B>\"\<CR>", 'tx')
    314  call assert_equal('"setglobal dictionary diff diffanchors diffexpr diffopt digraph directory display', @:)
    315 
    316  " Expand boolean options. When doing :set no<Tab> Vim prefixes the option
    317  " names with "no".
    318  call feedkeys(":set nodi\<C-A>\<C-B>\"\<CR>", 'tx')
    319  call assert_equal('"set nodiff nodigraph', @:)
    320 
    321  call feedkeys(":set invdi\<C-A>\<C-B>\"\<CR>", 'tx')
    322  call assert_equal('"set invdiff invdigraph', @:)
    323 
    324  " Expanding "set noinv" does nothing.
    325  call feedkeys(":set noinv\<C-A>\<C-B>\"\<CR>", 'tx')
    326  call assert_equal('"set noinv', @:)
    327 
    328  " Expand abbreviation of options.
    329  call feedkeys(":set ts\<C-A>\<C-B>\"\<CR>", 'tx')
    330  call assert_equal('"set tabstop thesaurus thesaurusfunc', @:)
    331 
    332  " Expand current value
    333  call feedkeys(":set suffixes=\<C-A>\<C-B>\"\<CR>", 'tx')
    334  call assert_equal('"set suffixes=.bak,~,.o,.h,.info,.swp,.obj', @:)
    335 
    336  call feedkeys(":set suffixes:\<C-A>\<C-B>\"\<CR>", 'tx')
    337  call assert_equal('"set suffixes:.bak,~,.o,.h,.info,.swp,.obj', @:)
    338 
    339  " " Expand key codes.
    340  " call feedkeys(":set <H\<C-A>\<C-B>\"\<CR>", 'tx')
    341  " call assert_equal('"set <Help> <Home>', @:)
    342  " " <BackSpace> (alt name) and <BS> should both show up in auto-complete
    343  " call feedkeys(":set <B\<C-A>\<C-B>\"\<CR>", 'tx')
    344  " call assert_equal('"set <BackSpace> <Bar> <BS> <Bslash>', @:)
    345  " " <ScrollWheelDown> has alt name <MouseUp> but it should not show up here
    346  " " nor show up as duplicates
    347  " call feedkeys(":set <ScrollWheel\<C-A>\<C-B>\"\<CR>", 'tx')
    348  " call assert_equal('"set <ScrollWheelDown> <ScrollWheelLeft> <ScrollWheelRight> <ScrollWheelUp>', @:)
    349  "
    350  " " Expand terminal options.
    351  " call feedkeys(":set t_A\<C-A>\<C-B>\"\<CR>", 'tx')
    352  " call assert_equal('"set t_AB t_AF t_AU t_AL', @:)
    353  " call assert_fails('call feedkeys(":set <t_afoo>=\<C-A>\<CR>", "xt")', 'E474:')
    354 
    355  " Expand directories.
    356  call feedkeys(":set cdpath=./\<C-A>\<C-B>\"\<CR>", 'tx')
    357  call assert_match(' ./samples/ ', @:)
    358  call assert_notmatch(' ./summarize.vim ', @:)
    359  set cdpath&
    360 
    361  " Expand files and directories.
    362  call feedkeys(":set tags=./\<C-A>\<C-B>\"\<CR>", 'tx')
    363  call assert_match(' ./samples/.* ./summarize.vim', @:)
    364 
    365  call feedkeys(":set tags=./\\\\ dif\<C-A>\<C-B>\"\<CR>", 'tx')
    366  call assert_equal('"set tags=./\\ diff diffanchors diffexpr diffopt', @:)
    367 
    368  " Expand files with spaces/commas in them. Make sure we delimit correctly.
    369  "
    370  " 'tags' allow for for spaces/commas to both act as delimiters, with actual
    371  " spaces requiring double escape, and commas need a single escape.
    372  " 'dictionary' is a normal comma-separated option where only commas act as
    373  " delimiters, and both space/comma need one single escape.
    374  " 'makeprg' is a non-comma-separated option. Commas don't need escape.
    375  defer delete('Xfoo Xspace.txt')
    376  defer delete('Xsp_dummy')
    377  defer delete('Xbar,Xcomma.txt')
    378  defer delete('Xcom_dummy')
    379  call writefile([], 'Xfoo Xspace.txt')
    380  call writefile([], 'Xsp_dummy')
    381  call writefile([], 'Xbar,Xcomma.txt')
    382  call writefile([], 'Xcom_dummy')
    383 
    384  call feedkeys(':set tags=./Xfoo\ Xsp' .. "\<C-A>\<C-B>\"\<CR>", 'tx')
    385  call assert_equal('"set tags=./Xfoo\ Xsp_dummy', @:)
    386  call feedkeys(':set tags=./Xfoo\\\ Xsp' .. "\<C-A>\<C-B>\"\<CR>", 'tx')
    387  call assert_equal('"set tags=./Xfoo\\\ Xspace.txt', @:)
    388  call feedkeys(':set dictionary=./Xfoo\ Xsp' .. "\<C-A>\<C-B>\"\<CR>", 'tx')
    389  call assert_equal('"set dictionary=./Xfoo\ Xspace.txt', @:)
    390 
    391  call feedkeys(':set dictionary=./Xbar,Xcom' .. "\<C-A>\<C-B>\"\<CR>", 'tx')
    392  call assert_equal('"set dictionary=./Xbar,Xcom_dummy', @:)
    393  if has('win32')
    394    " In Windows, '\,' is literal, see `:help filename-backslash`, so this
    395    " means we treat it as one file name.
    396    call feedkeys(':set dictionary=Xbar\,Xcom' .. "\<C-A>\<C-B>\"\<CR>", 'tx')
    397    call assert_equal('"set dictionary=Xbar\,Xcomma.txt', @:)
    398  else
    399    " In other platforms, '\,' simply escape to ',', and indicate a delimiter
    400    " to split into a separate file name. You need '\\,' to escape the comma
    401    " as part of the file name.
    402    call feedkeys(':set dictionary=Xbar\,Xcom' .. "\<C-A>\<C-B>\"\<CR>", 'tx')
    403    call assert_equal('"set dictionary=Xbar\,Xcom_dummy', @:)
    404 
    405    call feedkeys(':set dictionary=Xbar\\,Xcom' .. "\<C-A>\<C-B>\"\<CR>", 'tx')
    406    call assert_equal('"set dictionary=Xbar\\,Xcomma.txt', @:)
    407  endif
    408  call feedkeys(":set makeprg=./Xbar,Xcom\<C-A>\<C-B>\"\<CR>", 'tx')
    409  call assert_equal('"set makeprg=./Xbar,Xcomma.txt', @:)
    410  set tags& dictionary& makeprg&
    411 
    412  " Expanding the option names
    413  call feedkeys(":set \<Tab>\<C-B>\"\<CR>", 'xt')
    414  call assert_equal('"set all', @:)
    415 
    416  " Expanding a second set of option names
    417  call feedkeys(":set wrapscan \<Tab>\<C-B>\"\<CR>", 'xt')
    418  call assert_equal('"set wrapscan all', @:)
    419 
    420  " Expanding a special keycode
    421  " call feedkeys(":set <Home>\<Tab>\<C-B>\"\<CR>", 'xt')
    422  " call assert_equal('"set <Home>', @:)
    423 
    424  " Expanding an invalid special keycode
    425  call feedkeys(":set <abcd>\<Tab>\<C-B>\"\<CR>", 'xt')
    426  call assert_equal("\"set <abcd>\<Tab>", @:)
    427 
    428  " Expanding a terminal keycode
    429  " call feedkeys(":set t_AB\<Tab>\<C-B>\"\<CR>", 'xt')
    430  " call assert_equal("\"set t_AB", @:)
    431 
    432  " Expanding an invalid option name
    433  call feedkeys(":set abcde=\<Tab>\<C-B>\"\<CR>", 'xt')
    434  call assert_equal("\"set abcde=\<Tab>", @:)
    435 
    436  " Expanding after a = for a boolean option
    437  call feedkeys(":set wrapscan=\<Tab>\<C-B>\"\<CR>", 'xt')
    438  call assert_equal("\"set wrapscan=\<Tab>", @:)
    439 
    440  " Expanding a numeric option
    441  call feedkeys(":set tabstop+=\<Tab>\<C-B>\"\<CR>", 'xt')
    442  call assert_equal("\"set tabstop+=" .. &tabstop, @:)
    443 
    444  " Expanding a non-boolean option
    445  call feedkeys(":set invtabstop=\<Tab>\<C-B>\"\<CR>", 'xt')
    446  call assert_equal("\"set invtabstop=", @:)
    447 
    448  " Expand options for 'spellsuggest'
    449  call feedkeys(":set spellsuggest=file:test_options.v\<Tab>\<C-B>\"\<CR>", 'xt')
    450  call assert_equal("\"set spellsuggest=file:test_options.vim", @:)
    451  call feedkeys(":set spellsuggest=best,file:test_options.v\<Tab>\<C-B>\"\<CR>", 'xt')
    452  call assert_equal("\"set spellsuggest=best,file:test_options.vim", @:)
    453 
    454  " Expanding value for 'key' is disallowed
    455  if exists('+key')
    456    set key=abcd
    457    call feedkeys(":set key=\<Tab>\<C-B>\"\<CR>", 'xt')
    458    call assert_equal('"set key=', @:)
    459    call feedkeys(":set key-=\<Tab>\<C-B>\"\<CR>", 'xt')
    460    call assert_equal('"set key-=', @:)
    461    set key=
    462  endif
    463 
    464  " Expand values for 'filetype'
    465  call feedkeys(":set filetype=sshdconfi\<Tab>\<C-B>\"\<CR>", 'xt')
    466  call assert_equal('"set filetype=sshdconfig', @:)
    467  call feedkeys(":set filetype=a\<C-A>\<C-B>\"\<CR>", 'xt')
    468  call assert_equal('"set filetype=' .. getcompletion('a*', 'filetype')->join(), @:)
    469 
    470  " Expand values for 'syntax'
    471  call feedkeys(":set syntax=sshdconfi\<Tab>\<C-B>\"\<CR>", 'xt')
    472  call assert_equal('"set syntax=sshdconfig', @:)
    473  call feedkeys(":set syntax=a\<C-A>\<C-B>\"\<CR>", 'xt')
    474  call assert_equal('"set syntax=' .. getcompletion('a*', 'syntax')->join(), @:)
    475 
    476  if has('keymap')
    477    " Expand values for 'keymap'
    478    call feedkeys(":set keymap=acc\<Tab>\<C-B>\"\<CR>", 'xt')
    479    call assert_equal('"set keymap=accents', @:)
    480    call feedkeys(":set keymap=a\<C-A>\<C-B>\"\<CR>", 'xt')
    481    call assert_equal('"set keymap=' .. getcompletion('a*', 'keymap')->join(), @:)
    482  endif
    483 endfunc
    484 
    485 " Test handling of expanding individual string option values
    486 func Test_set_completion_string_values()
    487  "
    488  " Test basic enum string options that have well-defined enum names
    489  "
    490 
    491  " call assert_equal(['lastline', 'truncate', 'uhex'], getcompletion('set display=', 'cmdline'))
    492  call assert_equal(['lastline', 'truncate', 'uhex', 'msgsep'], getcompletion('set display=', 'cmdline'))
    493  call assert_equal(['truncate'], getcompletion('set display=t', 'cmdline'))
    494  call assert_equal(['uhex'], getcompletion('set display=*ex*', 'cmdline'))
    495 
    496  " Test that if a value is set, it will populate the results, but only if
    497  " typed value is empty.
    498  set display=uhex,lastline
    499  " call assert_equal(['uhex,lastline', 'lastline', 'truncate', 'uhex'], getcompletion('set display=', 'cmdline'))
    500  call assert_equal(['uhex,lastline', 'lastline', 'truncate', 'uhex', 'msgsep'], getcompletion('set display=', 'cmdline'))
    501  call assert_equal(['uhex'], getcompletion('set display=u', 'cmdline'))
    502  " If the set value is part of the enum list, it will show as the first
    503  " result with no duplicate.
    504  set display=uhex
    505  " call assert_equal(['uhex', 'lastline', 'truncate'], getcompletion('set display=', 'cmdline'))
    506  call assert_equal(['uhex', 'lastline', 'truncate', 'msgsep'], getcompletion('set display=', 'cmdline'))
    507  " If empty value, will just show the normal list without an empty item
    508  set display=
    509  " call assert_equal(['lastline', 'truncate', 'uhex'], getcompletion('set display=', 'cmdline'))
    510  call assert_equal(['lastline', 'truncate', 'uhex', 'msgsep'], getcompletion('set display=', 'cmdline'))
    511  " Test escaping of the values
    512  " call assert_equal('vert:\|,fold:-,eob:~,lastline:@', getcompletion('set fillchars=', 'cmdline')[0])
    513  call assert_equal('vert:\|,foldsep:\|,fold:-', getcompletion('set fillchars=', 'cmdline')[0])
    514 
    515  " Test comma-separated lists will expand after a comma.
    516  call assert_equal(['uhex'], getcompletion('set display=truncate,*ex*', 'cmdline'))
    517  " Also test the positioning of the expansion is correct
    518  call feedkeys(":set display=truncate,l\<Tab>\<C-B>\"\<CR>", 'xt')
    519  call assert_equal('"set display=truncate,lastline', @:)
    520  set display&
    521 
    522  " Test single-value options will not expand after a comma
    523  call assert_equal([], getcompletion('set ambw=single,', 'cmdline'))
    524 
    525  " Test the other simple options to make sure they have basic auto-complete,
    526  " but don't exhaustively validate their results.
    527  call assert_equal('single', getcompletion('set ambw=', 'cmdline')[0])
    528  call assert_match('light\|dark', getcompletion('set bg=', 'cmdline')[1])
    529  call assert_equal('indent,eol,start', getcompletion('set backspace=', 'cmdline')[0])
    530  call assert_equal('yes', getcompletion('set backupcopy=', 'cmdline')[1])
    531  call assert_equal('backspace', getcompletion('set belloff=', 'cmdline')[1])
    532  call assert_equal('min:', getcompletion('set briopt=', 'cmdline')[1])
    533  if exists('+browsedir')
    534    call assert_equal('current', getcompletion('set browsedir=', 'cmdline')[1])
    535  endif
    536  call assert_equal('unload', getcompletion('set bufhidden=', 'cmdline')[1])
    537  "call assert_equal('nowrite', getcompletion('set buftype=', 'cmdline')[1])
    538  call assert_equal('help', getcompletion('set buftype=', 'cmdline')[1])
    539  call assert_equal('internal', getcompletion('set casemap=', 'cmdline')[1])
    540  if exists('+clipboard')
    541    " call assert_match('unnamed', getcompletion('set clipboard=', 'cmdline')[1])
    542    call assert_match('unnamed', getcompletion('set clipboard=', 'cmdline')[0])
    543  endif
    544  call assert_equal('.', getcompletion('set complete=', 'cmdline')[1])
    545  call assert_equal('menu', getcompletion('set completeopt=', 'cmdline')[1])
    546  " call assert_equal('keyword', getcompletion('set completefuzzycollect=', 'cmdline')[0])
    547  if exists('+completeslash')
    548    call assert_equal('backslash', getcompletion('set completeslash=', 'cmdline')[1])
    549  endif
    550  if exists('+cryptmethod')
    551    call assert_equal('zip', getcompletion('set cryptmethod=', 'cmdline')[1])
    552  endif
    553  if exists('+cursorlineopt')
    554    call assert_equal('line', getcompletion('set cursorlineopt=', 'cmdline')[1])
    555  endif
    556  call assert_equal('throw', getcompletion('set debug=', 'cmdline')[1])
    557  call assert_equal('ver', getcompletion('set eadirection=', 'cmdline')[1])
    558  call assert_equal('mac', getcompletion('set fileformat=', 'cmdline')[2])
    559  if exists('+foldclose')
    560    call assert_equal('all', getcompletion('set foldclose=', 'cmdline')[0])
    561  endif
    562  if exists('+foldmethod')
    563    call assert_equal('expr', getcompletion('set foldmethod=', 'cmdline')[1])
    564  endif
    565  if exists('+foldopen')
    566    call assert_equal('all', getcompletion('set foldopen=', 'cmdline')[1])
    567  endif
    568  call assert_equal('stack', getcompletion('set jumpoptions=', 'cmdline')[0])
    569  call assert_equal('stopsel', getcompletion('set keymodel=', 'cmdline')[1])
    570  call assert_equal('expr:1', getcompletion('set lispoptions=', 'cmdline')[1])
    571  call assert_match('popup', getcompletion('set mousemodel=', 'cmdline')[2])
    572  call assert_equal('bin', getcompletion('set nrformats=', 'cmdline')[1])
    573  if exists('+rightleftcmd')
    574    call assert_equal('search', getcompletion('set rightleftcmd=', 'cmdline')[0])
    575  endif
    576  call assert_equal('ver', getcompletion('set scrollopt=', 'cmdline')[1])
    577  call assert_equal('exclusive', getcompletion('set selection=', 'cmdline')[1])
    578  call assert_equal('key', getcompletion('set selectmode=', 'cmdline')[1])
    579  if exists('+ssop')
    580    call assert_equal('buffers', getcompletion('set ssop=', 'cmdline')[1])
    581  endif
    582  call assert_equal('statusline', getcompletion('set showcmdloc=', 'cmdline')[1])
    583  if exists('+signcolumn')
    584    call assert_equal('yes', getcompletion('set signcolumn=', 'cmdline')[1])
    585  endif
    586  if exists('+spelloptions')
    587    call assert_equal('camel', getcompletion('set spelloptions=', 'cmdline')[0])
    588  endif
    589  if exists('+spellsuggest')
    590    call assert_equal('best', getcompletion('set spellsuggest+=', 'cmdline')[0])
    591  endif
    592  call assert_equal('screen', getcompletion('set splitkeep=', 'cmdline')[1])
    593  " call assert_equal('sync', getcompletion('set swapsync=', 'cmdline')[1])
    594  call assert_equal('usetab', getcompletion('set switchbuf=', 'cmdline')[1])
    595  call assert_equal('ignore', getcompletion('set tagcase=', 'cmdline')[1])
    596  if exists('+tabclose')
    597    call assert_equal('left uselast', join(sort(getcompletion('set tabclose=', 'cmdline'))), ' ')
    598  endif
    599  if exists('+termwintype')
    600    call assert_equal('conpty', getcompletion('set termwintype=', 'cmdline')[1])
    601  endif
    602  if exists('+toolbar')
    603    call assert_equal('text', getcompletion('set toolbar=', 'cmdline')[1])
    604  endif
    605  if exists('+tbis')
    606    call assert_equal('medium', getcompletion('set tbis=', 'cmdline')[2])
    607  endif
    608  if exists('+ttymouse')
    609    set ttymouse=
    610    call assert_equal('xterm2', getcompletion('set ttymouse=', 'cmdline')[1])
    611    set ttymouse&
    612  endif
    613  call assert_equal('insert', getcompletion('set virtualedit=', 'cmdline')[1])
    614  call assert_equal('longest', getcompletion('set wildmode=', 'cmdline')[1])
    615  call assert_equal('full', getcompletion('set wildmode=list,longest:', 'cmdline')[0])
    616  call assert_equal('tagfile', getcompletion('set wildoptions=', 'cmdline')[1])
    617  if exists('+winaltkeys')
    618    call assert_equal('yes', getcompletion('set winaltkeys=', 'cmdline')[1])
    619  endif
    620 
    621  " Other string options that queries the system rather than fixed enum names
    622  call assert_equal(['all', 'BufAdd'], getcompletion('set eventignore=', 'cmdline')[0:1])
    623  call assert_equal(['-BufAdd', '-BufCreate'], getcompletion('set eventignore=all,-', 'cmdline')[0:1])
    624  call assert_equal(['WinLeave', 'WinResized', 'WinScrolled'], getcompletion('set eiw=', 'cmdline')[-3:-1])
    625  call assert_equal('latin1', getcompletion('set fileencodings=', 'cmdline')[1])
    626  " call assert_equal('top', getcompletion('set printoptions=', 'cmdline')[0])
    627  " call assert_equal('SpecialKey', getcompletion('set wincolor=', 'cmdline')[0])
    628 
    629  call assert_equal('eol', getcompletion('set listchars+=', 'cmdline')[0])
    630  call assert_equal(['multispace', 'leadmultispace'], getcompletion('set listchars+=', 'cmdline')[-2:])
    631  call assert_equal(['tab', 'leadtab'], getcompletion('set listchars+=', 'cmdline')[5:6])
    632  call assert_equal('eol', getcompletion('setl listchars+=', 'cmdline')[0])
    633  call assert_equal(['tab', 'leadtab'], getcompletion('setl listchars+=', 'cmdline')[5:6])
    634  call assert_equal(['multispace', 'leadmultispace'], getcompletion('setl listchars+=', 'cmdline')[-2:])
    635  call assert_equal('stl', getcompletion('set fillchars+=', 'cmdline')[0])
    636  call assert_equal('stl', getcompletion('setl fillchars+=', 'cmdline')[0])
    637 
    638  "
    639  " Unique string options below
    640  "
    641 
    642  " keyprotocol: only auto-complete when after ':' with known protocol types
    643  " call assert_equal([&keyprotocol], getcompletion('set keyprotocol=', 'cmdline'))
    644  " call feedkeys(":set keyprotocol+=someterm:m\<Tab>\<C-B>\"\<CR>", 'xt')
    645  " call assert_equal('"set keyprotocol+=someterm:mok2', @:)
    646  " set keyprotocol&
    647 
    648  " previewpopup / completepopup
    649  " call assert_equal('height:', getcompletion('set previewpopup=', 'cmdline')[0])
    650  " call assert_equal('EndOfBuffer', getcompletion('set previewpopup=highlight:End*Buffer', 'cmdline')[0])
    651  " call feedkeys(":set previewpopup+=border:\<Tab>\<C-B>\"\<CR>", 'xt')
    652  " call assert_equal('"set previewpopup+=border:on', @:)
    653  " call feedkeys(":set completepopup=height:10,align:\<Tab>\<C-B>\"\<CR>", 'xt')
    654  " call assert_equal('"set completepopup=height:10,align:item', @:)
    655  " call assert_equal([], getcompletion('set completepopup=bogusname:', 'cmdline'))
    656  " set previewpopup& completepopup&
    657 
    658  " diffopt: special handling of algorithm:<alg_list> and inline:<inline_type>
    659  call assert_equal('filler', getcompletion('set diffopt+=', 'cmdline')[0])
    660  call assert_equal([], getcompletion('set diffopt+=iblank,foldcolumn:', 'cmdline'))
    661  call assert_equal('patience', getcompletion('set diffopt+=iblank,algorithm:pat*', 'cmdline')[0])
    662  call assert_equal('char', getcompletion('set diffopt+=iwhite,inline:ch*', 'cmdline')[0])
    663 
    664  " highlight: special parsing, including auto-completing highlight groups
    665  " after ':'
    666  " call assert_equal([&hl, '8'], getcompletion('set hl=', 'cmdline')[0:1])
    667  " call assert_equal('8', getcompletion('set hl+=', 'cmdline')[0])
    668  " call assert_equal(['8:', '8b', '8i'], getcompletion('set hl+=8', 'cmdline')[0:2])
    669  " call assert_equal('8bi', getcompletion('set hl+=8b', 'cmdline')[0])
    670  " call assert_equal('NonText', getcompletion('set hl+=8:No*ext', 'cmdline')[0])
    671  " If all the display modes are used up we should be suggesting nothing. Make
    672  " a hl typed option with all the modes which will look like '8bi-nrsuc2d=t',
    673  " and make sure nothing is suggested from that.
    674  " let hl_display_modes = join(
    675  "       \ filter(map(getcompletion('set hl+=8', 'cmdline'),
    676  "       \            {idx, val -> val[1]}),
    677  "       \        {idx, val -> val != ':'}),
    678  "       \ '')
    679  " call assert_equal([], getcompletion('set hl+=8'..hl_display_modes, 'cmdline'))
    680  " Test completion in middle of the line
    681  " call feedkeys(":set hl=8b i\<Left>\<Left>\<Tab>\<C-B>\"\<CR>", 'xt')
    682  " call assert_equal("\"set hl=8bi i", @:)
    683 
    684  " messagesopt
    685  call assert_equal(['history:', 'hit-enter', 'wait:'],
    686        \ getcompletion('set messagesopt+=', 'cmdline')->sort())
    687 
    688  "
    689  " Test flag lists
    690  "
    691 
    692  " Test set=. Show the original value if nothing is typed after '='.
    693  " Otherwise, the list should avoid showing what's already typed.
    694  set mouse=v
    695  call assert_equal(['v','a','n','i','c','h','r'], getcompletion('set mouse=', 'cmdline'))
    696  set mouse=nvi
    697  call assert_equal(['nvi','a','n','v','i','c','h','r'], getcompletion('set mouse=', 'cmdline'))
    698  call assert_equal(['a','v','i','c','r'], getcompletion('set mouse=hn', 'cmdline'))
    699 
    700  " Test set+=. Never show original value, and it also tries to avoid listing
    701  " flags that's already in the option value.
    702  call assert_equal(['a','c','h','r'], getcompletion('set mouse+=', 'cmdline'))
    703  call assert_equal(['a','c','r'], getcompletion('set mouse+=hn', 'cmdline'))
    704  call assert_equal([], getcompletion('set mouse+=acrhn', 'cmdline'))
    705 
    706  " Test that the position of the expansion is correct (even if there are
    707  " additional values after the current cursor)
    708  call feedkeys(":set mouse=hn\<Left>\<Tab>\<C-B>\"\<CR>", 'xt')
    709  call assert_equal('"set mouse=han', @:)
    710  set mouse&
    711 
    712  " Test that other flag list options have auto-complete, but don't
    713  " exhaustively validate their results.
    714  if exists('+concealcursor')
    715    call assert_equal('n', getcompletion('set cocu=', 'cmdline')[0])
    716  endif
    717  call assert_equal('a', getcompletion('set cpo=', 'cmdline')[1])
    718  call assert_equal('t', getcompletion('set fo=', 'cmdline')[1])
    719  if exists('+guioptions')
    720    call assert_equal('!', getcompletion('set go=', 'cmdline')[1])
    721  endif
    722  call assert_equal('r', getcompletion('set shortmess=', 'cmdline')[1])
    723  call assert_equal('b', getcompletion('set whichwrap=', 'cmdline')[1])
    724 
    725  "
    726  "Test set-=
    727  "
    728 
    729  " Normal single-value option just shows the existing value
    730  set ambiwidth=double
    731  call assert_equal(['double'], getcompletion('set ambw-=', 'cmdline'))
    732  set ambiwidth&
    733 
    734  " Works on numbers and term options as well
    735  call assert_equal([string(&laststatus)], getcompletion('set laststatus-=', 'cmdline'))
    736  set t_Ce=testCe
    737  " call assert_equal(['testCe'], getcompletion('set t_Ce-=', 'cmdline'))
    738  set t_Ce&
    739 
    740  " Comma-separated lists should present each option
    741  set diffopt=context:123,,,,,iblank,iwhiteall
    742  call assert_equal(['context:123', 'iblank', 'iwhiteall'], getcompletion('set diffopt-=', 'cmdline'))
    743  call assert_equal(['context:123', 'iblank'], getcompletion('set diffopt-=*n*', 'cmdline'))
    744  call assert_equal(['iblank', 'iwhiteall'], getcompletion('set diffopt-=i', 'cmdline'))
    745  " Don't present more than one option as it doesn't make sense in set-=
    746  call assert_equal([], getcompletion('set diffopt-=iblank,', 'cmdline'))
    747  " Test empty option
    748  set diffopt=
    749  call assert_equal([], getcompletion('set diffopt-=', 'cmdline'))
    750  " Test all possible values
    751  call assert_equal(['filler', 'anchor', 'context:', 'iblank', 'icase', 'iwhite', 'iwhiteall', 'iwhiteeol', 'horizontal',
    752        \ 'vertical', 'closeoff', 'hiddenoff', 'foldcolumn:', 'followwrap', 'internal', 'indent-heuristic', 'algorithm:', 'inline:', 'linematch:'],
    753        \ getcompletion('set diffopt=', 'cmdline'))
    754  set diffopt&
    755 
    756  " Test escaping output
    757  call assert_equal('vert:\|', getcompletion('set fillchars-=', 'cmdline')[0])
    758 
    759  " Test files with commas in name are being parsed and escaped properly
    760  set path=has\\\ space,file\\,with\\,comma,normal_file
    761  if exists('+completeslash')
    762    call assert_equal(['has\\\ space', 'file\,with\,comma', 'normal_file'], getcompletion('set path-=', 'cmdline'))
    763  else
    764    call assert_equal(['has\\\ space', 'file\\,with\\,comma', 'normal_file'], getcompletion('set path-=', 'cmdline'))
    765  endif
    766  set path&
    767 
    768  " Flag list should present orig value, then individual flags
    769  set mouse=v
    770  call assert_equal(['v'], getcompletion('set mouse-=', 'cmdline'))
    771  set mouse=avn
    772  call assert_equal(['avn','a','v','n'], getcompletion('set mouse-=', 'cmdline'))
    773  " Don't auto-complete when we have at least one flags already
    774  call assert_equal([], getcompletion('set mouse-=n', 'cmdline'))
    775  " Test empty option
    776  set mouse=
    777  call assert_equal([], getcompletion('set mouse-=', 'cmdline'))
    778  set mouse&
    779 
    780  " 'whichwrap' is an odd case where it's both flag list and comma-separated
    781  set ww=b,h
    782  call assert_equal(['b','h'], getcompletion('set ww-=', 'cmdline'))
    783  set ww&
    784 endfunc
    785 
    786 func Test_set_option_errors()
    787  call assert_fails('set scroll=-1', 'E49:')
    788  call assert_fails('set backupcopy=', 'E474:')
    789  call assert_fails('set regexpengine=3', 'E474:')
    790  call assert_fails('set history=10001', 'E474:')
    791  call assert_fails('set numberwidth=21', 'E474:')
    792  call assert_fails('set colorcolumn=-a', 'E474:')
    793  call assert_fails('set colorcolumn=a', 'E474:')
    794  call assert_fails('set colorcolumn=1,', 'E474:')
    795  call assert_fails('set colorcolumn=1;', 'E474:')
    796  call assert_fails('set cmdheight=-1', 'E487:')
    797  call assert_fails('set cmdwinheight=-1', 'E487:')
    798  if has('conceal')
    799    call assert_fails('set conceallevel=-1', 'E487:')
    800    call assert_fails('set conceallevel=4', 'E474:')
    801  endif
    802  call assert_fails('set helpheight=-1', 'E487:')
    803  call assert_fails('set history=-1', 'E487:')
    804  call assert_fails('set report=-1', 'E487:')
    805  call assert_fails('set shiftwidth=-1', 'E487:')
    806  call assert_fails('set sidescroll=-1', 'E487:')
    807  call assert_fails('set tabstop=-1', 'E487:')
    808  call assert_fails('set tabstop=10000', 'E474:')
    809  call assert_fails('let &tabstop = 10000', 'E474:')
    810  call assert_fails('set tabstop=5500000000', 'E474:')
    811  call assert_fails('set textwidth=-1', 'E487:')
    812  call assert_fails('set timeoutlen=-1', 'E487:')
    813  call assert_fails('set updatecount=-1', 'E487:')
    814  call assert_fails('set updatetime=-1', 'E487:')
    815  call assert_fails('set winheight=-1', 'E487:')
    816  call assert_fails('set tabstop!', 'E488:')
    817 
    818  " Test for setting unknown option errors
    819  call assert_fails('set xxx', 'E518:')
    820  call assert_fails('setlocal xxx', 'E518:')
    821  call assert_fails('setglobal xxx', 'E518:')
    822  call assert_fails('set xxx=', 'E518:')
    823  call assert_fails('setlocal xxx=', 'E518:')
    824  call assert_fails('setglobal xxx=', 'E518:')
    825  call assert_fails('set xxx:', 'E518:')
    826  call assert_fails('setlocal xxx:', 'E518:')
    827  call assert_fails('setglobal xxx:', 'E518:')
    828  call assert_fails('set xxx!', 'E518:')
    829  call assert_fails('setlocal xxx!', 'E518:')
    830  call assert_fails('setglobal xxx!', 'E518:')
    831  call assert_fails('set xxx?', 'E518:')
    832  call assert_fails('setlocal xxx?', 'E518:')
    833  call assert_fails('setglobal xxx?', 'E518:')
    834  call assert_fails('set xxx&', 'E518:')
    835  call assert_fails('setlocal xxx&', 'E518:')
    836  call assert_fails('setglobal xxx&', 'E518:')
    837  call assert_fails('set xxx<', 'E518:')
    838  call assert_fails('setlocal xxx<', 'E518:')
    839  call assert_fails('setglobal xxx<', 'E518:')
    840 
    841  " Test for missing-options errors.
    842  " call assert_fails('set autoprint?', 'E519:')
    843  " call assert_fails('set beautify?', 'E519:')
    844  " call assert_fails('set flash?', 'E519:')
    845  " call assert_fails('set graphic?', 'E519:')
    846  " call assert_fails('set hardtabs?', 'E519:')
    847  " call assert_fails('set mesg?', 'E519:')
    848  " call assert_fails('set novice?', 'E519:')
    849  " call assert_fails('set open?', 'E519:')
    850  " call assert_fails('set optimize?', 'E519:')
    851  " call assert_fails('set redraw?', 'E519:')
    852  " call assert_fails('set slowopen?', 'E519:')
    853  " call assert_fails('set sourceany?', 'E519:')
    854  " call assert_fails('set w300?', 'E519:')
    855  " call assert_fails('set w1200?', 'E519:')
    856  " call assert_fails('set w9600?', 'E519:')
    857 
    858  call assert_fails('set undolevels=x', 'E521:')
    859  call assert_fails('set tabstop=', 'E521:')
    860  call assert_fails('set comments=-', 'E524:')
    861  call assert_fails('set comments=a', 'E525:')
    862  call assert_fails('set foldmarker=x', 'E536:')
    863  call assert_fails('set commentstring=x', 'E537:')
    864  call assert_fails('let &commentstring = "x"', 'E537:')
    865  call assert_fails('set complete=x', 'E539:')
    866  call assert_fails('set rulerformat=%-', 'E539:')
    867  call assert_fails('set rulerformat=%(', 'E542:')
    868  call assert_fails('set rulerformat=%15(%%', 'E542:')
    869 
    870  " Test for 'statusline' errors
    871  call assert_fails('set statusline=%^', 'E539:')  " Nvim: supports %$
    872  call assert_fails('set statusline=%{', 'E540:')
    873  call assert_fails('set statusline=%{%', 'E540:')
    874  call assert_fails('set statusline=%{%}', 'E539:')
    875  call assert_fails('set statusline=%(', 'E542:')
    876  call assert_fails('set statusline=%)', 'E542:')
    877 
    878  " Test for 'tabline' errors
    879  call assert_fails('set tabline=%^', 'E539:')  " Nvim: supports %$
    880  call assert_fails('set tabline=%{', 'E540:')
    881  call assert_fails('set tabline=%{%', 'E540:')
    882  call assert_fails('set tabline=%{%}', 'E539:')
    883  call assert_fails('set tabline=%(', 'E542:')
    884  call assert_fails('set tabline=%)', 'E542:')
    885 
    886  if has('cursorshape')
    887    " This invalid value for 'guicursor' used to cause Vim to crash.
    888    call assert_fails('set guicursor=i-ci,r-cr:h', 'E545:')
    889    call assert_fails('set guicursor=i-ci', 'E545:')
    890    call assert_fails('set guicursor=x', 'E545:')
    891    call assert_fails('set guicursor=x:', 'E546:')
    892    call assert_fails('set guicursor=r-cr:horx', 'E548:')
    893    call assert_fails('set guicursor=r-cr:hor0', 'E549:')
    894  endif
    895 
    896  if has('mouseshape')
    897    call assert_fails('se mouseshape=i-r:x', 'E547:')
    898  endif
    899 
    900  " Test for 'backupext' and 'patchmode' set to the same value
    901  set backupext=.bak
    902  set patchmode=.patch
    903  call assert_fails('set patchmode=.bak', 'E589:')
    904  call assert_equal('.patch', &patchmode)
    905  call assert_fails('set backupext=.patch', 'E589:')
    906  call assert_equal('.bak', &backupext)
    907  set backupext& patchmode&
    908 
    909  " 'winheight' cannot be smaller than 'winminheight'
    910  call assert_fails('set winminheight=10 winheight=9', 'E591:')
    911  set winminheight& winheight&
    912  set winheight=10 winminheight=10
    913  call assert_fails('set winheight=9', 'E591:')
    914  set winminheight& winheight&
    915 
    916  " 'winwidth' cannot be smaller than 'winminwidth'
    917  call assert_fails('set winminwidth=10 winwidth=9', 'E592:')
    918  set winminwidth& winwidth&
    919  call assert_fails('set winwidth=9 winminwidth=10', 'E592:')
    920  set winwidth& winminwidth&
    921 
    922  call assert_fails("set showbreak=\x01", 'E595:')
    923  " call assert_fails('set t_foo=', 'E846:')
    924  call assert_fails('set tabstop??', 'E488:')
    925  call assert_fails('set wrapscan!!', 'E488:')
    926  call assert_fails('set tabstop&&', 'E488:')
    927  call assert_fails('set wrapscan<<', 'E488:')
    928  call assert_fails('set wrapscan=1', 'E474:')
    929  call assert_fails('set autoindent@', 'E488:')
    930  call assert_fails('set wildchar=<abc>', 'E474:')
    931  call assert_fails('set cmdheight=1a', 'E521:')
    932  call assert_fails('set invcmdheight', 'E474:')
    933  if has('python') || has('python3')
    934    call assert_fails('set pyxversion=6', 'E474:')
    935  endif
    936  call assert_fails("let &tabstop='ab'", ['E521:', 'E521:'])
    937  call assert_fails('set spellcapcheck=%\\(', 'E54:')
    938  call assert_fails('set sessionoptions=curdir,sesdir', 'E474:')
    939  call assert_fails('set foldmarker={{{,', 'E474:')
    940  call assert_fails('set sessionoptions=sesdir,curdir', 'E474:')
    941 
    942  " 'ambiwidth' conflict 'listchars'
    943  setlocal listchars=trail:·
    944  call assert_fails('set ambiwidth=double', 'E834:')
    945  setlocal listchars=trail:-
    946  setglobal listchars=trail:·
    947  call assert_fails('set ambiwidth=double', 'E834:')
    948  set listchars&
    949 
    950  " 'ambiwidth' conflict 'fillchars'
    951  setlocal fillchars=stl    952  call assert_fails('set ambiwidth=double', 'E835:')
    953  setlocal fillchars=stl:-
    954  setglobal fillchars=stl    955  call assert_fails('set ambiwidth=double', 'E835:')
    956  set fillchars&
    957 
    958  call assert_fails('set fileencoding=latin1,utf-8', 'E474:')
    959  set nomodifiable
    960  call assert_fails('set fileencoding=latin1', 'E21:')
    961  set modifiable&
    962  " call assert_fails('set t_#-&', 'E522:')
    963  call assert_fails('let &formatoptions = "?"', 'E539:')
    964  call assert_fails('call setbufvar("", "&formatoptions", "?")', 'E539:')
    965 
    966  " Should raises only one error if passing a wrong variable type.
    967  call assert_fails('call setwinvar(0, "&scrolloff", [])', ['E745:', 'E745:'])
    968  call assert_fails('call setwinvar(0, "&list", [])', ['E745:', 'E745:'])
    969  call assert_fails('call setwinvar(0, "&listchars", [])', ['E730:', 'E730:'])
    970  call assert_fails('call setwinvar(0, "&nosuchoption", 0)', ['E355:', 'E355:'])
    971  call assert_fails('call setwinvar(0, "&nosuchoption", "")', ['E355:', 'E355:'])
    972  call assert_fails('call setwinvar(0, "&nosuchoption", [])', ['E355:', 'E355:'])
    973 endfunc
    974 
    975 func CheckWasSet(name)
    976  let verb_cm = execute('verbose set ' .. a:name .. '?')
    977  call assert_match('Last set from.*test_options.vim', verb_cm)
    978 endfunc
    979 func CheckWasNotSet(name)
    980  let verb_cm = execute('verbose set ' .. a:name .. '?')
    981  call assert_notmatch('Last set from', verb_cm)
    982 endfunc
    983 
    984 " Must be executed before other tests that set 'term'.
    985 func Test_000_term_option_verbose()
    986  throw "Skipped: Nvim does not support setting 'term'"
    987  CheckNotGui
    988 
    989  call CheckWasNotSet('t_cm')
    990 
    991  let term_save = &term
    992  set term=ansi
    993  call CheckWasSet('t_cm')
    994  let &term = term_save
    995 endfunc
    996 
    997 func Test_copy_context()
    998  setlocal list
    999  call CheckWasSet('list')
   1000  split
   1001  call CheckWasSet('list')
   1002  quit
   1003  setlocal nolist
   1004 
   1005  set ai
   1006  call CheckWasSet('ai')
   1007  set filetype=perl
   1008  call CheckWasSet('filetype')
   1009  set fo=tcroq
   1010  call CheckWasSet('fo')
   1011 
   1012  split Xsomebuf
   1013  call CheckWasSet('ai')
   1014  call CheckWasNotSet('filetype')
   1015  call CheckWasSet('fo')
   1016 endfunc
   1017 
   1018 func Test_set_ttytype()
   1019  throw "Skipped: Nvim does not support 'ttytype'"
   1020  CheckUnix
   1021  CheckNotGui
   1022 
   1023  " Setting 'ttytype' used to cause a double-free when exiting vim and
   1024  " when vim is compiled with -DEXITFREE.
   1025  set ttytype=ansi
   1026  call assert_equal('ansi', &ttytype)
   1027  call assert_equal(&ttytype, &term)
   1028  set ttytype=xterm
   1029  call assert_equal('xterm', &ttytype)
   1030  call assert_equal(&ttytype, &term)
   1031  try
   1032    set ttytype=
   1033    call assert_report('set ttytype= did not fail')
   1034  catch /E529/
   1035  endtry
   1036 
   1037  " Some systems accept any terminal name and return dumb settings,
   1038  " check for failure of finding the entry and for missing 'cm' entry.
   1039  try
   1040    set ttytype=xxx
   1041    call assert_report('set ttytype=xxx did not fail')
   1042  catch /E522\|E437/
   1043  endtry
   1044 
   1045  set ttytype&
   1046  call assert_equal(&ttytype, &term)
   1047 
   1048  if has('gui') && !has('gui_running')
   1049    call assert_fails('set term=gui', 'E531:')
   1050  endif
   1051 endfunc
   1052 
   1053 " Test for :set all
   1054 func Test_set_all()
   1055  set tw=75
   1056  set iskeyword=a-z,A-Z
   1057  set nosplitbelow
   1058  let out = execute('set all')
   1059  call assert_match('textwidth=75', out)
   1060  call assert_match('iskeyword=a-z,A-Z', out)
   1061  call assert_match('nosplitbelow', out)
   1062  set tw& iskeyword& splitbelow&
   1063 endfunc
   1064 
   1065 " Test for :set! all
   1066 func Test_set_all_one_column()
   1067  let out_mult = execute('set all')->split("\n")
   1068  let out_one = execute('set! all')->split("\n")
   1069  call assert_true(len(out_mult) < len(out_one))
   1070  call assert_equal(out_one[0], '--- Options ---')
   1071  let options = out_one[1:]->mapnew({_, line -> line[2:]})
   1072  call assert_equal(sort(copy(options)), options)
   1073 endfunc
   1074 
   1075 func Test_renderoptions()
   1076  throw 'skipped: Nvim does not support renderoptions'
   1077  " Only do this for Windows Vista and later, fails on Windows XP and earlier.
   1078  " Doesn't hurt to do this on a non-Windows system.
   1079  if windowsversion() !~ '^[345]\.'
   1080    set renderoptions=type:directx
   1081    set rop=type:directx
   1082  endif
   1083 endfunc
   1084 
   1085 func ResetIndentexpr()
   1086  set indentexpr=
   1087 endfunc
   1088 
   1089 func Test_set_indentexpr()
   1090  " this was causing usage of freed memory
   1091  set indentexpr=ResetIndentexpr()
   1092  new
   1093  call feedkeys("i\<c-f>", 'x')
   1094  call assert_equal('', &indentexpr)
   1095  bwipe!
   1096 endfunc
   1097 
   1098 func Test_backupskip()
   1099  " Option 'backupskip' may contain several comma-separated path
   1100  " specifications if one or more of the environment variables TMPDIR, TMP,
   1101  " or TEMP is defined.  To simplify testing, convert the string value into a
   1102  " list.
   1103  let bsklist = split(&bsk, ',')
   1104 
   1105  if has("mac")
   1106    let found = (index(bsklist, '/private/tmp/*') >= 0)
   1107    call assert_true(found, '/private/tmp not in option bsk: ' . &bsk)
   1108  elseif has("unix")
   1109    let found = (index(bsklist, '/tmp/*') >= 0)
   1110    call assert_true(found, '/tmp not in option bsk: ' . &bsk)
   1111  endif
   1112 
   1113  " If our test platform is Windows, the path(s) in option bsk will use
   1114  " backslash for the path separator and the components could be in short
   1115  " (8.3) format.  As such, we need to replace the backslashes with forward
   1116  " slashes and convert the path components to long format.  The expand()
   1117  " function will do this but it cannot handle comma-separated paths.  This is
   1118  " why bsk was converted from a string into a list of strings above.
   1119  "
   1120  " One final complication is that the wildcard "/*" is at the end of each
   1121  " path and so expand() might return a list of matching files.  To prevent
   1122  " this, we need to remove the wildcard before calling expand() and then
   1123  " append it afterwards.
   1124  if has('win32')
   1125    let item_nbr = 0
   1126    while item_nbr < len(bsklist)
   1127      let path_spec = bsklist[item_nbr]
   1128      let path_spec = strcharpart(path_spec, 0, strlen(path_spec)-2)
   1129      let path_spec = substitute(expand(path_spec), '\\', '/', 'g')
   1130      let bsklist[item_nbr] = path_spec . '/*'
   1131      let item_nbr += 1
   1132    endwhile
   1133  endif
   1134 
   1135  " Option bsk will also include these environment variables if defined.
   1136  " If they're defined, verify they appear in the option value.
   1137  for var in  ['$TMPDIR', '$TMP', '$TEMP']
   1138    if exists(var)
   1139      let varvalue = substitute(expand(var), '\\', '/', 'g')
   1140      let varvalue = substitute(varvalue, '/$', '', '')
   1141      let varvalue .= '/*'
   1142      let found = (index(bsklist, varvalue) >= 0)
   1143      call assert_true(found, var . ' (' . varvalue . ') not in option bsk: ' . &bsk)
   1144    endif
   1145  endfor
   1146 
   1147  " Duplicates from environment variables should be filtered out (option has
   1148  " P_NODUP).  Run this in a separate instance and write v:errors in a file,
   1149  " so that we see what happens on startup.
   1150  let after =<< trim [CODE]
   1151      let bsklist = split(&backupskip, ',')
   1152      call assert_equal(uniq(copy(bsklist)), bsklist)
   1153      call writefile(['errors:'] + v:errors, 'Xtestout')
   1154      qall
   1155  [CODE]
   1156  call writefile(after, 'Xafter')
   1157  " let cmd = GetVimProg() . ' --not-a-term -S Xafter --cmd "set enc=utf8"'
   1158  let cmd = GetVimProg() . ' -S Xafter --cmd "set enc=utf8"'
   1159 
   1160  let saveenv = {}
   1161  for var in ['TMPDIR', 'TMP', 'TEMP']
   1162    let saveenv[var] = getenv(var)
   1163    call setenv(var, '/duplicate/path')
   1164  endfor
   1165 
   1166  " unset $HOME, so that it won't try to read init files
   1167  let saveenv['HOME'] = getenv("HOME")
   1168  call setenv('HOME', v:null)
   1169  exe 'silent !' . cmd
   1170  call assert_equal(['errors:'], readfile('Xtestout'))
   1171 
   1172  " restore environment variables
   1173  for var in ['TMPDIR', 'TMP', 'TEMP', 'HOME']
   1174    call setenv(var, saveenv[var])
   1175  endfor
   1176 
   1177  call delete('Xtestout')
   1178  call delete('Xafter')
   1179 
   1180  " Duplicates should be filtered out (option has P_NODUP)
   1181  let backupskip = &backupskip
   1182  set backupskip=
   1183  set backupskip+=/test/dir
   1184  set backupskip+=/other/dir
   1185  set backupskip+=/test/dir
   1186  call assert_equal('/test/dir,/other/dir', &backupskip)
   1187  let &backupskip = backupskip
   1188 endfunc
   1189 
   1190 func Test_buf_copy_winopt()
   1191  set hidden
   1192 
   1193  " Test copy option from current buffer in window
   1194  split
   1195  enew
   1196  setlocal numberwidth=5
   1197  wincmd w
   1198  call assert_equal(4,&numberwidth)
   1199  bnext
   1200  call assert_equal(5,&numberwidth)
   1201  bw!
   1202  call assert_equal(4,&numberwidth)
   1203 
   1204  " Test copy value from window that used to be display the buffer
   1205  split
   1206  enew
   1207  setlocal numberwidth=6
   1208  bnext
   1209  wincmd w
   1210  call assert_equal(4,&numberwidth)
   1211  bnext
   1212  call assert_equal(6,&numberwidth)
   1213  bw!
   1214 
   1215  " Test that if buffer is current, don't use the stale cached value
   1216  " from the last time the buffer was displayed.
   1217  split
   1218  enew
   1219  setlocal numberwidth=7
   1220  bnext
   1221  bnext
   1222  setlocal numberwidth=8
   1223  wincmd w
   1224  call assert_equal(4,&numberwidth)
   1225  bnext
   1226  call assert_equal(8,&numberwidth)
   1227  bw!
   1228 
   1229  " Test value is not copied if window already has seen the buffer
   1230  enew
   1231  split
   1232  setlocal numberwidth=9
   1233  bnext
   1234  setlocal numberwidth=10
   1235  wincmd w
   1236  call assert_equal(4,&numberwidth)
   1237  bnext
   1238  call assert_equal(4,&numberwidth)
   1239  bw!
   1240 
   1241  set hidden&
   1242 endfunc
   1243 
   1244 func Test_split_copy_options()
   1245  let values = [
   1246    \['cursorbind', 1, 0],
   1247    \['fillchars', '"vert:-"', '"' .. &fillchars .. '"'],
   1248    \['list', 1, 0],
   1249    \['listchars', '"space:-"', '"' .. &listchars .. '"'],
   1250    \['number', 1, 0],
   1251    \['relativenumber', 1, 0],
   1252    \['scrollbind', 1, 0],
   1253    \['smoothscroll', 1, 0],
   1254    \['virtualedit', '"block"', '"' .. &virtualedit .. '"'],
   1255    "\ ['wincolor', '"Search"', '"' .. &wincolor .. '"'],
   1256    \['wrap', 0, 1],
   1257  \]
   1258  if has('linebreak')
   1259    let values += [
   1260      \['breakindent', 1, 0],
   1261      \['breakindentopt', '"min:5"', '"' .. &breakindentopt .. '"'],
   1262      \['linebreak', 1, 0],
   1263      \['numberwidth', 7, 4],
   1264      \['showbreak', '"++"', '"' .. &showbreak .. '"'],
   1265    \]
   1266  endif
   1267  if has('rightleft')
   1268    let values += [
   1269      \['rightleft', 1, 0],
   1270      \['rightleftcmd', '"search"', '"' .. &rightleftcmd .. '"'],
   1271    \]
   1272  endif
   1273  if has('statusline')
   1274    let values += [
   1275      \['statusline', '"---%f---"', '"' .. &statusline .. '"'],
   1276    \]
   1277  endif
   1278  if has('spell')
   1279    let values += [
   1280      \['spell', 1, 0],
   1281    \]
   1282  endif
   1283  if has('syntax')
   1284    let values += [
   1285      \['cursorcolumn', 1, 0],
   1286      \['cursorline', 1, 0],
   1287      \['cursorlineopt', '"screenline"', '"' .. &cursorlineopt .. '"'],
   1288      \['colorcolumn', '"+1"', '"' .. &colorcolumn .. '"'],
   1289    \]
   1290  endif
   1291  if has('diff')
   1292    let values += [
   1293      \['diff', 1, 0],
   1294    \]
   1295  endif
   1296  if has('conceal')
   1297    let values += [
   1298      \['concealcursor', '"nv"', '"' .. &concealcursor .. '"'],
   1299      \['conceallevel', '3', &conceallevel],
   1300    \]
   1301  endif
   1302  if has('terminal')
   1303    let values += [
   1304      \['termwinkey', '"<C-X>"', '"' .. &termwinkey .. '"'],
   1305      \['termwinsize', '"10x20"', '"' .. &termwinsize .. '"'],
   1306    \]
   1307  endif
   1308  if has('folding')
   1309    let values += [
   1310      \['foldcolumn', '"5"',  &foldcolumn],
   1311      \['foldenable', 0, 1],
   1312      \['foldexpr', '"2 + 3"', '"' .. &foldexpr .. '"'],
   1313      \['foldignore', '"+="', '"' .. &foldignore .. '"'],
   1314      \['foldlevel', 4,  &foldlevel],
   1315      \['foldmarker', '">>,<<"', '"' .. &foldmarker .. '"'],
   1316      \['foldmethod', '"marker"', '"' .. &foldmethod .. '"'],
   1317      \['foldminlines', 3,  &foldminlines],
   1318      \['foldnestmax', 17,  &foldnestmax],
   1319      \['foldtext', '"closed"', '"' .. &foldtext .. '"'],
   1320    \]
   1321  endif
   1322  if has('signs')
   1323    let values += [
   1324      \['signcolumn', '"number"', '"' .. &signcolumn .. '"'],
   1325    \]
   1326  endif
   1327 
   1328  " set options to non-default value
   1329  for item in values
   1330    exe $"let &{item[0]} = {item[1]}"
   1331  endfor
   1332 
   1333  " check values are set in new window
   1334  split
   1335  for item in values
   1336    exe $'call assert_equal({item[1]}, &{item[0]}, "{item[0]}")'
   1337  endfor
   1338 
   1339  " restore
   1340  close
   1341  for item in values
   1342    exe $"let &{item[0]} = {item[1]}"
   1343  endfor
   1344 endfunc
   1345 
   1346 func Test_shortmess_F()
   1347  new
   1348  call assert_match('\[No Name\]', execute('file'))
   1349  set shortmess+=F
   1350  call assert_match('\[No Name\]', execute('file'))
   1351  call assert_match('^\s*$', execute('file foo'))
   1352  call assert_match('foo', execute('file'))
   1353  set shortmess-=F
   1354  call assert_match('bar', execute('file bar'))
   1355  call assert_match('bar', execute('file'))
   1356  set shortmess&
   1357  bwipe
   1358 endfunc
   1359 
   1360 func Test_shortmess_F2()
   1361  e file1
   1362  e file2
   1363  call assert_match('file1', execute('bn', ''))
   1364  call assert_match('file2', execute('bn', ''))
   1365  set shortmess+=F
   1366  call assert_true(empty(execute('bn', '')))
   1367  " call assert_false(test_getvalue('need_fileinfo'))
   1368  call assert_true(empty(execute('bn', '')))
   1369  " call assert_false(test_getvalue('need_fileinfo'))
   1370  set hidden
   1371  call assert_true(empty(execute('bn', '')))
   1372  " call assert_false(test_getvalue('need_fileinfo'))
   1373  call assert_true(empty(execute('bn', '')))
   1374  " call assert_false(test_getvalue('need_fileinfo'))
   1375  set nohidden
   1376  call assert_true(empty(execute('bn', '')))
   1377  " call assert_false(test_getvalue('need_fileinfo'))
   1378  call assert_true(empty(execute('bn', '')))
   1379  " call assert_false(test_getvalue('need_fileinfo'))
   1380  set shortmess-=F  " Accommodate Nvim default.
   1381  call assert_match('file1', execute('bn', ''))
   1382  call assert_match('file2', execute('bn', ''))
   1383  bwipe
   1384  bwipe
   1385  " call assert_fails('call test_getvalue("abc")', 'E475:')
   1386 endfunc
   1387 
   1388 func Test_shortmess_F3()
   1389  call writefile(['foo'], 'X_dummy', 'D')
   1390 
   1391  set hidden
   1392  set autoread
   1393  e X_dummy
   1394  e Xotherfile
   1395  call assert_equal(['foo'], getbufline('X_dummy', 1, '$'))
   1396  set shortmess+=F
   1397  echo ''
   1398 
   1399  if has('nanotime')
   1400    sleep 10m
   1401  else
   1402    sleep 2
   1403  endif
   1404  call writefile(['bar'], 'X_dummy')
   1405  bprev
   1406  call assert_equal('', Screenline(&lines))
   1407  call assert_equal(['bar'], getbufline('X_dummy', 1, '$'))
   1408 
   1409  if has('nanotime')
   1410    sleep 10m
   1411  else
   1412    sleep 2
   1413  endif
   1414  call writefile(['baz'], 'X_dummy')
   1415  checktime
   1416  call assert_equal('', Screenline(&lines))
   1417  call assert_equal(['baz'], getbufline('X_dummy', 1, '$'))
   1418 
   1419  set shortmess&
   1420  set autoread&
   1421  set hidden&
   1422  bwipe X_dummy
   1423  bwipe Xotherfile
   1424 endfunc
   1425 
   1426 func Test_local_scrolloff()
   1427  set so=5
   1428  set siso=7
   1429  split
   1430  call assert_equal(5, &so)
   1431  setlocal so=3
   1432  call assert_equal(3, &so)
   1433  wincmd w
   1434  call assert_equal(5, &so)
   1435  wincmd w
   1436  call assert_equal(3, &so)
   1437  "setlocal so<
   1438  set so<
   1439  call assert_equal(5, &so)
   1440  setglob so=8
   1441  call assert_equal(8, &so)
   1442  call assert_equal(-1, &l:so)
   1443  setlocal so=0
   1444  call assert_equal(0, &so)
   1445  setlocal so=-1
   1446  call assert_equal(8, &so)
   1447 
   1448  call assert_equal(7, &siso)
   1449  setlocal siso=3
   1450  call assert_equal(3, &siso)
   1451  wincmd w
   1452  call assert_equal(7, &siso)
   1453  wincmd w
   1454  call assert_equal(3, &siso)
   1455  "setlocal siso<
   1456  set siso<
   1457  call assert_equal(7, &siso)
   1458  setglob siso=4
   1459  call assert_equal(4, &siso)
   1460  call assert_equal(-1, &l:siso)
   1461  setlocal siso=0
   1462  call assert_equal(0, &siso)
   1463  setlocal siso=-1
   1464  call assert_equal(4, &siso)
   1465 
   1466  close
   1467  set so&
   1468  set siso&
   1469 endfunc
   1470 
   1471 func Test_writedelay()
   1472  CheckFunction reltimefloat
   1473 
   1474  new
   1475  call setline(1, 'empty')
   1476  " Nvim: 'writedelay' is applied per screen line.
   1477  " Create 7 vertical splits first.
   1478  vs | vs | vs | vs | vs | vs
   1479  redraw
   1480  set writedelay=10
   1481  let start = reltime()
   1482  " call setline(1, repeat('x', 70))
   1483  " Nvim: enable 'writedelay' per screen line.
   1484  " In each of the 7 vertical splits, 10 screen lines need to be drawn.
   1485  set redrawdebug+=line
   1486  call setline(1, repeat(['x'], 10))
   1487  redraw
   1488  let elapsed = reltimefloat(reltime(start))
   1489  set writedelay=0
   1490  " With 'writedelay' set should take at least 30 * 10 msec
   1491  call assert_inrange(30 * 0.01, 999.0, elapsed)
   1492 
   1493  bwipe!
   1494 endfunc
   1495 
   1496 func Test_visualbell()
   1497  set belloff=
   1498  set visualbell
   1499  call assert_beeps('normal 0h')
   1500  set novisualbell
   1501  set belloff=all
   1502 endfunc
   1503 
   1504 " Test for the 'write' option
   1505 func Test_write()
   1506  new
   1507  call setline(1, ['L1'])
   1508  set nowrite
   1509  call assert_fails('write Xwrfile', 'E142:')
   1510  set write
   1511  " close swapfile
   1512  bw!
   1513 endfunc
   1514 
   1515 " Test for 'buftype' option
   1516 func Test_buftype()
   1517  new
   1518  call setline(1, ['L1'])
   1519  set buftype=nowrite
   1520  call assert_fails('write', 'E382:')
   1521 
   1522  " for val in ['', 'nofile', 'nowrite', 'acwrite', 'quickfix', 'help', 'terminal', 'prompt', 'popup']
   1523  for val in ['', 'nofile', 'nowrite', 'acwrite', 'quickfix', 'help', 'prompt']
   1524    exe 'set buftype=' .. val
   1525    call writefile(['something'], 'XBuftype')
   1526    call assert_fails('write XBuftype', 'E13:', 'with buftype=' .. val)
   1527  endfor
   1528 
   1529  call delete('XBuftype')
   1530  bwipe!
   1531 endfunc
   1532 
   1533 " Test for the 'rightleftcmd' option
   1534 func Test_rightleftcmd()
   1535  CheckFeature rightleft
   1536  set rightleft
   1537 
   1538  let g:l = []
   1539  func AddPos()
   1540    call add(g:l, screencol())
   1541    return ''
   1542  endfunc
   1543  cmap <expr> <F2> AddPos()
   1544 
   1545  set rightleftcmd=
   1546  call feedkeys("/\<F2>abc\<Right>\<F2>\<Left>\<Left>\<F2>" ..
   1547        \ "\<Right>\<F2>\<Esc>", 'xt')
   1548  call assert_equal([2, 5, 3, 4], g:l)
   1549 
   1550  let g:l = []
   1551  set rightleftcmd=search
   1552  call feedkeys("/\<F2>abc\<Left>\<F2>\<Right>\<Right>\<F2>" ..
   1553        \ "\<Left>\<F2>\<Esc>", 'xt')
   1554  call assert_equal([&co - 1, &co - 4, &co - 2, &co - 3], g:l)
   1555 
   1556  cunmap <F2>
   1557  unlet g:l
   1558  set rightleftcmd&
   1559  set rightleft&
   1560 endfunc
   1561 
   1562 " Test for the 'debug' option
   1563 func Test_debug_option()
   1564  " redraw to avoid matching previous messages
   1565  redraw
   1566  set debug=beep
   1567  exe "normal \<C-c>"
   1568  call assert_equal('Beep!', Screenline(&lines))
   1569  call assert_equal('line    4:', Screenline(&lines - 1))
   1570  " also check a line above, with a certain window width the colon is there
   1571  call assert_match('Test_debug_option:$',
   1572        \ Screenline(&lines - 3) .. Screenline(&lines - 2))
   1573  set debug&
   1574 endfunc
   1575 
   1576 " Test for the default CDPATH option
   1577 func Test_opt_default_cdpath()
   1578  let after =<< trim [CODE]
   1579    call assert_equal(',/path/to/dir1,/path/to/dir2', &cdpath)
   1580    call writefile(v:errors, 'Xtestout')
   1581    qall
   1582  [CODE]
   1583  if has('unix')
   1584    let $CDPATH='/path/to/dir1:/path/to/dir2'
   1585  else
   1586    let $CDPATH='/path/to/dir1;/path/to/dir2'
   1587  endif
   1588  if RunVim([], after, '')
   1589    call assert_equal([], readfile('Xtestout'))
   1590    call delete('Xtestout')
   1591  endif
   1592 endfunc
   1593 
   1594 " Test for setting keycodes using set
   1595 func Test_opt_set_keycode()
   1596  " call assert_fails('set <t_k1=l', 'E474:')
   1597  " call assert_fails('set <Home=l', 'E474:')
   1598  call assert_fails('set <t_k1=l', 'E518:')
   1599  call assert_fails('set <Home=l', 'E518:')
   1600  set <t_k9>=abcd
   1601  " call assert_equal('abcd', &t_k9)
   1602  set <t_k9>&
   1603  set <F9>=xyz
   1604  " call assert_equal('xyz', &t_k9)
   1605  set <t_k9>&
   1606 endfunc
   1607 
   1608 " Test for changing options in a sandbox
   1609 func Test_opt_sandbox()
   1610  for opt in ['backupdir', 'cdpath', 'exrc', 'findfunc']
   1611    call assert_fails('sandbox set ' .. opt .. '?', 'E48:')
   1612    call assert_fails('sandbox let &' .. opt .. ' = 1', 'E48:')
   1613  endfor
   1614  call assert_fails('sandbox let &modelineexpr = 1', 'E48:')
   1615 endfunc
   1616 
   1617 " Test for setting string global-local option value
   1618 func Test_set_string_global_local_option()
   1619  setglobal equalprg=gprg
   1620  setlocal equalprg=lprg
   1621  call assert_equal('gprg', &g:equalprg)
   1622  call assert_equal('lprg', &l:equalprg)
   1623  call assert_equal('lprg', &equalprg)
   1624 
   1625  " :set {option}< removes the local value, so that the global value will be used.
   1626  set equalprg<
   1627  call assert_equal('', &l:equalprg)
   1628  call assert_equal('gprg', &equalprg)
   1629 
   1630  " :setlocal {option}< set the effective value of {option} to its global value.
   1631  setglobal equalprg=gnewprg
   1632  setlocal equalprg=lnewprg
   1633  setlocal equalprg<
   1634  call assert_equal('gnewprg', &l:equalprg)
   1635  call assert_equal('gnewprg', &equalprg)
   1636 
   1637  set equalprg&
   1638 endfunc
   1639 
   1640 " Test for setting number global-local option value
   1641 func Test_set_number_global_local_option()
   1642  setglobal scrolloff=10
   1643  setlocal scrolloff=12
   1644  call assert_equal(10, &g:scrolloff)
   1645  call assert_equal(12, &l:scrolloff)
   1646  call assert_equal(12, &scrolloff)
   1647 
   1648  " :setlocal {option}< set the effective value of {option} to its global value.
   1649  "set scrolloff<
   1650  setlocal scrolloff<
   1651  call assert_equal(10, &l:scrolloff)
   1652  call assert_equal(10, &scrolloff)
   1653 
   1654  " :set {option}< removes the local value, so that the global value will be used.
   1655  setglobal scrolloff=15
   1656  setlocal scrolloff=18
   1657  "setlocal scrolloff<
   1658  set scrolloff<
   1659  call assert_equal(-1, &l:scrolloff)
   1660  call assert_equal(15, &scrolloff)
   1661 
   1662  set scrolloff&
   1663 endfunc
   1664 
   1665 " Test for setting boolean global-local option value
   1666 func Test_set_boolean_global_local_option()
   1667  CheckUnix
   1668 
   1669  setglobal autoread fsync
   1670  setlocal noautoread nofsync
   1671  call assert_equal(1, &g:autoread)
   1672  call assert_equal(0, &l:autoread)
   1673  call assert_equal(0, &autoread)
   1674  call assert_equal(1, &g:fsync)
   1675  call assert_equal(0, &l:fsync)
   1676  call assert_equal(0, &fsync)
   1677 
   1678  " :setlocal {option}< set the effective value of {option} to its global value.
   1679  "set autoread< fsync<
   1680  setlocal autoread< fsync<
   1681  call assert_equal(1, &l:autoread)
   1682  call assert_equal(1, &autoread)
   1683  call assert_equal(1, &l:fsync)
   1684  call assert_equal(1, &fsync)
   1685 
   1686  " :set {option}< removes the local value, so that the global value will be used.
   1687  setglobal noautoread nofsync
   1688  setlocal autoread fsync
   1689  "setlocal autoread< fsync<
   1690  set autoread< fsync<
   1691  call assert_equal(-1, &l:autoread)
   1692  call assert_equal(0, &autoread)
   1693  call assert_equal(-1, &l:fsync)
   1694  call assert_equal(0, &fsync)
   1695 
   1696  set autoread& fsync&
   1697 endfunc
   1698 
   1699 func Test_set_in_sandbox()
   1700  " Some boolean options cannot be set in sandbox, some can.
   1701  call assert_fails('sandbox set modelineexpr', 'E48:')
   1702  sandbox set number
   1703  call assert_true(&number)
   1704  set number&
   1705 
   1706  " Some boolean options cannot be set in sandbox, some can.
   1707  if has('python') || has('python3')
   1708    call assert_fails('sandbox set pyxversion=3', 'E48:')
   1709  endif
   1710  sandbox set tabstop=4
   1711  call assert_equal(4, &tabstop)
   1712  set tabstop&
   1713 
   1714  " Some string options cannot be set in sandbox, some can.
   1715  call assert_fails('sandbox set backupdir=/tmp', 'E48:')
   1716  sandbox set filetype=perl
   1717  call assert_equal('perl', &filetype)
   1718  set filetype&
   1719 endfunc
   1720 
   1721 " Test for setting string option value
   1722 func Test_set_string_option()
   1723  " :set {option}=
   1724  set makeprg=
   1725  call assert_equal('', &mp)
   1726  set makeprg=abc
   1727  call assert_equal('abc', &mp)
   1728 
   1729  " :set {option}:
   1730  set makeprg:
   1731  call assert_equal('', &mp)
   1732  set makeprg:abc
   1733  call assert_equal('abc', &mp)
   1734 
   1735  " Let string
   1736  let &makeprg = ''
   1737  call assert_equal('', &mp)
   1738  let &makeprg = 'abc'
   1739  call assert_equal('abc', &mp)
   1740 
   1741  " Let number converts to string
   1742  let &makeprg = 42
   1743  call assert_equal('42', &mp)
   1744 
   1745  " Appending
   1746  set makeprg=abc
   1747  set makeprg+=def
   1748  call assert_equal('abcdef', &mp)
   1749  set makeprg+=def
   1750  call assert_equal('abcdefdef', &mp, ':set+= appends a value even if it already contained')
   1751  let &makeprg .= 'gh'
   1752  call assert_equal('abcdefdefgh', &mp)
   1753  let &makeprg ..= 'ij'
   1754  call assert_equal('abcdefdefghij', &mp)
   1755 
   1756  " Removing
   1757  set makeprg=abcdefghi
   1758  set makeprg-=def
   1759  call assert_equal('abcghi', &mp)
   1760  set makeprg-=def
   1761  call assert_equal('abcghi', &mp, ':set-= does not remove a value if it is not contained')
   1762 
   1763  " Prepending
   1764  set makeprg=abc
   1765  set makeprg^=def
   1766  call assert_equal('defabc', &mp)
   1767  set makeprg^=def
   1768  call assert_equal('defdefabc', &mp, ':set+= prepends a value even if it already contained')
   1769 
   1770  set makeprg&
   1771 endfunc
   1772 
   1773 " Test for setting string comma-separated list option value
   1774 func Test_set_string_comma_list_option()
   1775  " :set {option}=
   1776  set wildignore=
   1777  call assert_equal('', &wildignore)
   1778  set wildignore=*.png
   1779  call assert_equal('*.png', &wildignore)
   1780 
   1781  " :set {option}:
   1782  set wildignore:
   1783  call assert_equal('', &wildignore)
   1784  set wildignore:*.png
   1785  call assert_equal('*.png', &wildignore)
   1786 
   1787  " Let string
   1788  let &wildignore = ''
   1789  call assert_equal('', &wildignore)
   1790  let &wildignore = '*.png'
   1791  call assert_equal('*.png', &wildignore)
   1792 
   1793  " Let number converts to string
   1794  let &wildignore = 42
   1795  call assert_equal('42', &wildignore)
   1796 
   1797  " Appending
   1798  set wildignore=*.png
   1799  set wildignore+=*.jpg
   1800  call assert_equal('*.png,*.jpg', &wildignore, ':set+= prepends a comma to append a value')
   1801  set wildignore+=*.jpg
   1802  call assert_equal('*.png,*.jpg', &wildignore, ':set+= does not append a value if it already contained')
   1803  set wildignore+=jpg
   1804  call assert_equal('*.png,*.jpg,jpg', &wildignore, ':set+= prepends a comma to append a value if it is not exactly match to item')
   1805  let &wildignore .= 'foo'
   1806  call assert_equal('*.png,*.jpg,jpgfoo', &wildignore, ':let-& .= appends a value without a comma')
   1807  let &wildignore ..= 'bar'
   1808  call assert_equal('*.png,*.jpg,jpgfoobar', &wildignore, ':let-& ..= appends a value without a comma')
   1809 
   1810  " Removing
   1811  set wildignore=*.png,*.jpg,*.obj
   1812  set wildignore-=*.jpg
   1813  call assert_equal('*.png,*.obj', &wildignore)
   1814  set wildignore-=*.jpg
   1815  call assert_equal('*.png,*.obj', &wildignore, ':set-= does not remove a value if it is not contained')
   1816  set wildignore-=jpg
   1817  call assert_equal('*.png,*.obj', &wildignore, ':set-= does not remove a value if it is not exactly match to item')
   1818 
   1819  " Prepending
   1820  set wildignore=*.png
   1821  set wildignore^=*.jpg
   1822  call assert_equal('*.jpg,*.png', &wildignore)
   1823  set wildignore^=*.jpg
   1824  call assert_equal('*.jpg,*.png', &wildignore, ':set+= does not prepend a value if it already contained')
   1825  set wildignore^=jpg
   1826  call assert_equal('jpg,*.jpg,*.png', &wildignore, ':set+= prepend a value if it is not exactly match to item')
   1827 
   1828  set wildignore&
   1829 endfunc
   1830 
   1831 " Test for setting string flags option value
   1832 func Test_set_string_flags_option()
   1833  " :set {option}=
   1834  set formatoptions=
   1835  call assert_equal('', &fo)
   1836  set formatoptions=abc
   1837  call assert_equal('abc', &fo)
   1838 
   1839  " :set {option}:
   1840  set formatoptions:
   1841  call assert_equal('', &fo)
   1842  set formatoptions:abc
   1843  call assert_equal('abc', &fo)
   1844 
   1845  " Let string
   1846  let &formatoptions = ''
   1847  call assert_equal('', &fo)
   1848  let &formatoptions = 'abc'
   1849  call assert_equal('abc', &fo)
   1850 
   1851  " Let number converts to string
   1852  let &formatoptions = 12
   1853  call assert_equal('12', &fo)
   1854 
   1855  " Appending
   1856  set formatoptions=abc
   1857  set formatoptions+=pqr
   1858  call assert_equal('abcpqr', &fo)
   1859  set formatoptions+=pqr
   1860  call assert_equal('abcpqr', &fo, ':set+= does not append a value if it already contained')
   1861  let &formatoptions .= 'r'
   1862  call assert_equal('abcpqrr', &fo, ':let-& .= appends a value even if it already contained')
   1863  let &formatoptions ..= 'r'
   1864  call assert_equal('abcpqrrr', &fo, ':let-& ..= appends a value even if it already contained')
   1865 
   1866  " Removing
   1867  set formatoptions=abcpqr
   1868  set formatoptions-=cp
   1869  call assert_equal('abqr', &fo)
   1870  set formatoptions-=cp
   1871  call assert_equal('abqr', &fo, ':set-= does not remove a value if it is not contained')
   1872  set formatoptions-=ar
   1873  call assert_equal('abqr', &fo, ':set-= does not remove a value if it is not exactly match')
   1874 
   1875  " Prepending
   1876  set formatoptions=abc
   1877  set formatoptions^=pqr
   1878  call assert_equal('pqrabc', &fo)
   1879  set formatoptions^=qr
   1880  call assert_equal('pqrabc', &fo, ':set+= does not prepend a value if it already contained')
   1881 
   1882  set formatoptions&
   1883 endfunc
   1884 
   1885 " Test for setting number option value
   1886 func Test_set_number_option()
   1887  " :set {option}=
   1888  set scrolljump=5
   1889  call assert_equal(5, &sj)
   1890  set scrolljump=-3
   1891  call assert_equal(-3, &sj)
   1892 
   1893  " :set {option}:
   1894  set scrolljump:7
   1895  call assert_equal(7, &sj)
   1896  set scrolljump:-5
   1897  call assert_equal(-5, &sj)
   1898 
   1899  " Set hex
   1900  set scrolljump=0x10
   1901  call assert_equal(16, &sj)
   1902  set scrolljump=-0x10
   1903  call assert_equal(-16, &sj)
   1904  set scrolljump=0X12
   1905  call assert_equal(18, &sj)
   1906  set scrolljump=-0X12
   1907  call assert_equal(-18, &sj)
   1908 
   1909  " Set octal
   1910  set scrolljump=010
   1911  call assert_equal(8, &sj)
   1912  set scrolljump=-010
   1913  call assert_equal(-8, &sj)
   1914  set scrolljump=0o12
   1915  call assert_equal(10, &sj)
   1916  set scrolljump=-0o12
   1917  call assert_equal(-10, &sj)
   1918  set scrolljump=0O15
   1919  call assert_equal(13, &sj)
   1920  set scrolljump=-0O15
   1921  call assert_equal(-13, &sj)
   1922 
   1923  " Let number
   1924  let &scrolljump = 4
   1925  call assert_equal(4, &sj)
   1926  let &scrolljump = -6
   1927  call assert_equal(-6, &sj)
   1928 
   1929  " Let numeric string converts to number
   1930  let &scrolljump = '7'
   1931  call assert_equal(7, &sj)
   1932  let &scrolljump = '-9'
   1933  call assert_equal(-9, &sj)
   1934 
   1935  " Incrementing
   1936  set shiftwidth=4
   1937  set sw+=2
   1938  call assert_equal(6, &sw)
   1939  let &shiftwidth += 2
   1940  call assert_equal(8, &sw)
   1941 
   1942  " Decrementing
   1943  set shiftwidth=6
   1944  set sw-=2
   1945  call assert_equal(4, &sw)
   1946  let &shiftwidth -= 2
   1947  call assert_equal(2, &sw)
   1948 
   1949  " Multiplying
   1950  set shiftwidth=4
   1951  set sw^=2
   1952  call assert_equal(8, &sw)
   1953  let &shiftwidth *= 2
   1954  call assert_equal(16, &sw)
   1955 
   1956  set scrolljump&
   1957  set shiftwidth&
   1958 endfunc
   1959 
   1960 " Test for setting boolean option value
   1961 func Test_set_boolean_option()
   1962  set number&
   1963 
   1964  " :set {option}
   1965  set number
   1966  call assert_equal(1, &nu)
   1967 
   1968  " :set no{option}
   1969  set nonu
   1970  call assert_equal(0, &nu)
   1971 
   1972  " :set {option}!
   1973  set number!
   1974  call assert_equal(1, &nu)
   1975  set number!
   1976  call assert_equal(0, &nu)
   1977 
   1978  " :set inv{option}
   1979  set invnumber
   1980  call assert_equal(1, &nu)
   1981  set invnumber
   1982  call assert_equal(0, &nu)
   1983 
   1984  " Let number
   1985  let &number = 1
   1986  call assert_equal(1, &nu)
   1987  let &number = 0
   1988  call assert_equal(0, &nu)
   1989 
   1990  " Let numeric string converts to number
   1991  let &number = '1'
   1992  call assert_equal(1, &nu)
   1993  let &number = '0'
   1994  call assert_equal(0, &nu)
   1995 
   1996  " Let v:true and v:false
   1997  let &nu = v:true
   1998  call assert_equal(1, &nu)
   1999  let &nu = v:false
   2000  call assert_equal(0, &nu)
   2001 
   2002  set number&
   2003 endfunc
   2004 
   2005 " Test for setting string option errors
   2006 func Test_set_string_option_errors()
   2007  " :set no{option}
   2008  call assert_fails('set nomakeprg', 'E474:')
   2009  call assert_fails('setlocal nomakeprg', 'E474:')
   2010  call assert_fails('setglobal nomakeprg', 'E474:')
   2011 
   2012  " :set inv{option}
   2013  call assert_fails('set invmakeprg', 'E474:')
   2014  call assert_fails('setlocal invmakeprg', 'E474:')
   2015  call assert_fails('setglobal invmakeprg', 'E474:')
   2016 
   2017  " :set {option}!
   2018  call assert_fails('set makeprg!', 'E488:')
   2019  call assert_fails('setlocal makeprg!', 'E488:')
   2020  call assert_fails('setglobal makeprg!', 'E488:')
   2021 
   2022  " Invalid trailing chars
   2023  call assert_fails('set makeprg??', 'E488:')
   2024  call assert_fails('setlocal makeprg??', 'E488:')
   2025  call assert_fails('setglobal makeprg??', 'E488:')
   2026  call assert_fails('set makeprg&&', 'E488:')
   2027  call assert_fails('setlocal makeprg&&', 'E488:')
   2028  call assert_fails('setglobal makeprg&&', 'E488:')
   2029  call assert_fails('set makeprg<<', 'E488:')
   2030  call assert_fails('setlocal makeprg<<', 'E488:')
   2031  call assert_fails('setglobal makeprg<<', 'E488:')
   2032  call assert_fails('set makeprg@', 'E488:')
   2033  call assert_fails('setlocal makeprg@', 'E488:')
   2034  call assert_fails('setglobal makeprg@', 'E488:')
   2035 
   2036  " Invalid type
   2037  call assert_fails("let &makeprg = ['xxx']", 'E730:')
   2038 endfunc
   2039 
   2040 " Test for setting number option errors
   2041 func Test_set_number_option_errors()
   2042  " :set no{option}
   2043  call assert_fails('set notabstop', 'E474:')
   2044  call assert_fails('setlocal notabstop', 'E474:')
   2045  call assert_fails('setglobal notabstop', 'E474:')
   2046 
   2047  " :set inv{option}
   2048  call assert_fails('set invtabstop', 'E474:')
   2049  call assert_fails('setlocal invtabstop', 'E474:')
   2050  call assert_fails('setglobal invtabstop', 'E474:')
   2051 
   2052  " :set {option}!
   2053  call assert_fails('set tabstop!', 'E488:')
   2054  call assert_fails('setlocal tabstop!', 'E488:')
   2055  call assert_fails('setglobal tabstop!', 'E488:')
   2056 
   2057  " Invalid trailing chars
   2058  call assert_fails('set tabstop??', 'E488:')
   2059  call assert_fails('setlocal tabstop??', 'E488:')
   2060  call assert_fails('setglobal tabstop??', 'E488:')
   2061  call assert_fails('set tabstop&&', 'E488:')
   2062  call assert_fails('setlocal tabstop&&', 'E488:')
   2063  call assert_fails('setglobal tabstop&&', 'E488:')
   2064  call assert_fails('set tabstop<<', 'E488:')
   2065  call assert_fails('setlocal tabstop<<', 'E488:')
   2066  call assert_fails('setglobal tabstop<<', 'E488:')
   2067  call assert_fails('set tabstop@', 'E488:')
   2068  call assert_fails('setlocal tabstop@', 'E488:')
   2069  call assert_fails('setglobal tabstop@', 'E488:')
   2070 
   2071  " Not a number
   2072  call assert_fails('set tabstop=', 'E521:')
   2073  call assert_fails('setlocal tabstop=', 'E521:')
   2074  call assert_fails('setglobal tabstop=', 'E521:')
   2075  call assert_fails('set tabstop=x', 'E521:')
   2076  call assert_fails('setlocal tabstop=x', 'E521:')
   2077  call assert_fails('setglobal tabstop=x', 'E521:')
   2078  call assert_fails('set tabstop=1x', 'E521:')
   2079  call assert_fails('setlocal tabstop=1x', 'E521:')
   2080  call assert_fails('setglobal tabstop=1x', 'E521:')
   2081  call assert_fails('set tabstop=-x', 'E521:')
   2082  call assert_fails('setlocal tabstop=-x', 'E521:')
   2083  call assert_fails('setglobal tabstop=-x', 'E521:')
   2084  call assert_fails('set tabstop=0x', 'E521:')
   2085  call assert_fails('setlocal tabstop=0x', 'E521:')
   2086  call assert_fails('setglobal tabstop=0x', 'E521:')
   2087  call assert_fails('set tabstop=0o', 'E521:')
   2088  call assert_fails('setlocal tabstop=0o', 'E521:')
   2089  call assert_fails('setglobal tabstop=0o', 'E521:')
   2090  call assert_fails("let &tabstop = 'x'", 'E521:')
   2091  call assert_fails("let &g:tabstop = 'x'", 'E521:')
   2092  call assert_fails("let &l:tabstop = 'x'", 'E521:')
   2093 
   2094  " Invalid type
   2095  call assert_fails("let &tabstop = 'xxx'", 'E521:')
   2096 endfunc
   2097 
   2098 " Test for setting boolean option errors
   2099 func Test_set_boolean_option_errors()
   2100  " :set {option}=
   2101  call assert_fails('set number=', 'E474:')
   2102  call assert_fails('setlocal number=', 'E474:')
   2103  call assert_fails('setglobal number=', 'E474:')
   2104  call assert_fails('set number=1', 'E474:')
   2105  call assert_fails('setlocal number=1', 'E474:')
   2106  call assert_fails('setglobal number=1', 'E474:')
   2107 
   2108  " :set {option}:
   2109  call assert_fails('set number:', 'E474:')
   2110  call assert_fails('setlocal number:', 'E474:')
   2111  call assert_fails('setglobal number:', 'E474:')
   2112  call assert_fails('set number:1', 'E474:')
   2113  call assert_fails('setlocal number:1', 'E474:')
   2114  call assert_fails('setglobal number:1', 'E474:')
   2115 
   2116  " :set {option}+=
   2117  call assert_fails('set number+=1', 'E474:')
   2118  call assert_fails('setlocal number+=1', 'E474:')
   2119  call assert_fails('setglobal number+=1', 'E474:')
   2120 
   2121  " :set {option}^=
   2122  call assert_fails('set number^=1', 'E474:')
   2123  call assert_fails('setlocal number^=1', 'E474:')
   2124  call assert_fails('setglobal number^=1', 'E474:')
   2125 
   2126  " :set {option}-=
   2127  call assert_fails('set number-=1', 'E474:')
   2128  call assert_fails('setlocal number-=1', 'E474:')
   2129  call assert_fails('setglobal number-=1', 'E474:')
   2130 
   2131  " Invalid trailing chars
   2132  call assert_fails('set number!!', 'E488:')
   2133  call assert_fails('setlocal number!!', 'E488:')
   2134  call assert_fails('setglobal number!!', 'E488:')
   2135  call assert_fails('set number??', 'E488:')
   2136  call assert_fails('setlocal number??', 'E488:')
   2137  call assert_fails('setglobal number??', 'E488:')
   2138  call assert_fails('set number&&', 'E488:')
   2139  call assert_fails('setlocal number&&', 'E488:')
   2140  call assert_fails('setglobal number&&', 'E488:')
   2141  call assert_fails('set number<<', 'E488:')
   2142  call assert_fails('setlocal number<<', 'E488:')
   2143  call assert_fails('setglobal number<<', 'E488:')
   2144  call assert_fails('set number@', 'E488:')
   2145  call assert_fails('setlocal number@', 'E488:')
   2146  call assert_fails('setglobal number@', 'E488:')
   2147 
   2148  " Invalid type
   2149  call assert_fails("let &number = 'xxx'", 'E521:')
   2150 endfunc
   2151 
   2152 " Test for the 'window' option
   2153 func Test_window_opt()
   2154  " Needs only one open widow
   2155  %bw!
   2156  call setline(1, range(1, 8))
   2157  set window=5
   2158  exe "normal \<C-F>"
   2159  call assert_equal(4, line('w0'))
   2160  exe "normal \<C-F>"
   2161  call assert_equal(7, line('w0'))
   2162  exe "normal \<C-F>"
   2163  call assert_equal(8, line('w0'))
   2164  exe "normal \<C-B>"
   2165  call assert_equal(5, line('w0'))
   2166  exe "normal \<C-B>"
   2167  call assert_equal(2, line('w0'))
   2168  exe "normal \<C-B>"
   2169  call assert_equal(1, line('w0'))
   2170  set window=1
   2171  exe "normal gg\<C-F>"
   2172  call assert_equal(2, line('w0'))
   2173  exe "normal \<C-F>"
   2174  call assert_equal(3, line('w0'))
   2175  exe "normal \<C-B>"
   2176  call assert_equal(2, line('w0'))
   2177  exe "normal \<C-B>"
   2178  call assert_equal(1, line('w0'))
   2179  enew!
   2180  set window&
   2181 endfunc
   2182 
   2183 " Test for the 'winminheight' option
   2184 func Test_opt_winminheight()
   2185  only!
   2186  let &winheight = &lines + 4
   2187  call assert_fails('let &winminheight = &lines + 2', 'E36:')
   2188  call assert_true(&winminheight <= &lines)
   2189  set winminheight&
   2190  set winheight&
   2191 endfunc
   2192 
   2193 func Test_opt_winminheight_term()
   2194  " See test/functional/legacy/options_spec.lua
   2195  CheckRunVimInTerminal
   2196 
   2197  " The tabline should be taken into account.
   2198  let lines =<< trim END
   2199    set wmh=0 stal=2
   2200    below sp | wincmd _
   2201    below sp | wincmd _
   2202    below sp | wincmd _
   2203    below sp
   2204  END
   2205  call writefile(lines, 'Xwinminheight')
   2206  let buf = RunVimInTerminal('-S Xwinminheight', #{rows: 11})
   2207  call term_sendkeys(buf, ":set wmh=1\n")
   2208  call WaitForAssert({-> assert_match('E36: Not enough room', term_getline(buf, 11))})
   2209 
   2210  call StopVimInTerminal(buf)
   2211  call delete('Xwinminheight')
   2212 endfunc
   2213 
   2214 func Test_opt_winminheight_term_tabs()
   2215  " See test/functional/legacy/options_spec.lua
   2216  CheckRunVimInTerminal
   2217 
   2218  " The tabline should be taken into account.
   2219  let lines =<< trim END
   2220    set wmh=0 stal=2
   2221    split
   2222    split
   2223    split
   2224    split
   2225    tabnew
   2226  END
   2227  call writefile(lines, 'Xwinminheight')
   2228  let buf = RunVimInTerminal('-S Xwinminheight', #{rows: 11})
   2229  call term_sendkeys(buf, ":set wmh=1\n")
   2230  call WaitForAssert({-> assert_match('E36: Not enough room', term_getline(buf, 11))})
   2231 
   2232  call StopVimInTerminal(buf)
   2233  call delete('Xwinminheight')
   2234 endfunc
   2235 
   2236 " Test for the 'winminwidth' option
   2237 func Test_opt_winminwidth()
   2238  only!
   2239  let &winwidth = &columns + 4
   2240  call assert_fails('let &winminwidth = &columns + 2', 'E36:')
   2241  call assert_true(&winminwidth <= &columns)
   2242  set winminwidth&
   2243  set winwidth&
   2244 endfunc
   2245 
   2246 " Test for setting option value containing spaces with isfname+=32
   2247 func Test_isfname_with_options()
   2248  set isfname+=32
   2249  setlocal keywordprg=:term\ help.exe
   2250  call assert_equal(':term help.exe', &keywordprg)
   2251  set isfname&
   2252  setlocal keywordprg&
   2253 endfunc
   2254 
   2255 " Test that resetting laststatus does change scroll option
   2256 func Test_opt_reset_scroll()
   2257  " See test/functional/legacy/options_spec.lua
   2258  CheckRunVimInTerminal
   2259  let vimrc =<< trim [CODE]
   2260    set scroll=2
   2261    set laststatus=2
   2262  [CODE]
   2263  call writefile(vimrc, 'Xscroll')
   2264  let buf = RunVimInTerminal('-S Xscroll', {'rows': 16, 'cols': 45})
   2265  call term_sendkeys(buf, ":verbose set scroll?\n")
   2266  call WaitForAssert({-> assert_match('Last set.*window size', term_getline(buf, 15))})
   2267  call assert_match('^\s*scroll=7$', term_getline(buf, 14))
   2268  call StopVimInTerminal(buf)
   2269 
   2270  " clean up
   2271  call delete('Xscroll')
   2272 endfunc
   2273 
   2274 " Check that VIM_POSIX env variable influences default value of 'cpo' and 'shm'
   2275 func Test_VIM_POSIX()
   2276  throw 'Skipped: Nvim does not support $VIM_POSIX'
   2277  let saved_VIM_POSIX = getenv("VIM_POSIX")
   2278 
   2279  call setenv('VIM_POSIX', "1")
   2280  let after =<< trim [CODE]
   2281    call writefile([&cpo, &shm], 'X_VIM_POSIX')
   2282    qall
   2283  [CODE]
   2284  if RunVim([], after, '')
   2285    call assert_equal(['aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>#{|&/\.;~',
   2286          \            'AS'], readfile('X_VIM_POSIX'))
   2287  endif
   2288 
   2289  call setenv('VIM_POSIX', v:null)
   2290  let after =<< trim [CODE]
   2291    call writefile([&cpo, &shm], 'X_VIM_POSIX')
   2292    qall
   2293  [CODE]
   2294  if RunVim([], after, '')
   2295    call assert_equal(['aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>;',
   2296          \            'S'], readfile('X_VIM_POSIX'))
   2297  endif
   2298 
   2299  call delete('X_VIM_POSIX')
   2300  call setenv('VIM_POSIX', saved_VIM_POSIX)
   2301 endfunc
   2302 
   2303 " Test for setting an option to a Vi or Vim default
   2304 func Test_opt_default()
   2305  throw 'Skipped: Nvim has different defaults'
   2306  set formatoptions&vi
   2307  call assert_equal('vt', &formatoptions)
   2308  set formatoptions&vim
   2309  call assert_equal('tcq', &formatoptions)
   2310 
   2311  call assert_equal('ucs-bom,utf-8,default,latin1', &fencs)
   2312  set fencs=latin1
   2313  set fencs&
   2314  call assert_equal('ucs-bom,utf-8,default,latin1', &fencs)
   2315  set fencs=latin1
   2316  set all&
   2317  call assert_equal('ucs-bom,utf-8,default,latin1', &fencs)
   2318 endfunc
   2319 
   2320 " Test for the 'cmdheight' option
   2321 func Test_opt_cmdheight()
   2322  %bw!
   2323  let ht = &lines
   2324  set cmdheight=9999
   2325  call assert_equal(1, winheight(0))
   2326  call assert_equal(ht - 1, &cmdheight)
   2327  set cmdheight&
   2328 
   2329  " The status line should be taken into account.
   2330  set laststatus=2
   2331  set cmdheight=9999
   2332  call assert_equal(ht - 2, &cmdheight)
   2333  set cmdheight& laststatus=1  " Accommodate Nvim default
   2334 
   2335  " The tabline should be taken into account only non-GUI.
   2336  set showtabline=2
   2337  set cmdheight=9999
   2338  if has('gui_running')
   2339    call assert_equal(ht - 1, &cmdheight)
   2340  else
   2341    call assert_equal(ht - 2, &cmdheight)
   2342  endif
   2343  set cmdheight& showtabline&
   2344 
   2345  " The 'winminheight' should be taken into account.
   2346  set winheight=3 winminheight=3
   2347  split
   2348  set cmdheight=9999
   2349  call assert_equal(ht - 8, &cmdheight)
   2350  %bw!
   2351  set cmdheight& winminheight& winheight&
   2352 
   2353  " Only the windows in the current tabpage are taken into account.
   2354  set winheight=3 winminheight=3 showtabline=0
   2355  split
   2356  tabnew
   2357  set cmdheight=9999
   2358  call assert_equal(ht - 3, &cmdheight)
   2359  %bw!
   2360  set cmdheight& winminheight& winheight& showtabline&
   2361 endfunc
   2362 
   2363 " To specify a control character as an option value, '^' can be used
   2364 func Test_opt_control_char()
   2365  set wildchar=^v
   2366  call assert_equal("\<C-V>", nr2char(&wildchar))
   2367  set wildcharm=^r
   2368  call assert_equal("\<C-R>", nr2char(&wildcharm))
   2369  " Bug: This doesn't work for the 'cedit' and 'termwinkey' options
   2370  set wildchar& wildcharm&
   2371 endfunc
   2372 
   2373 " Test for the 'errorbells' option
   2374 func Test_opt_errorbells()
   2375  set errorbells
   2376  call assert_beeps('s/a1b2/x1y2/')
   2377  set noerrorbells
   2378 endfunc
   2379 
   2380 func Test_opt_scrolljump()
   2381  help
   2382  resize 10
   2383 
   2384  " Test with positive 'scrolljump'.
   2385  set scrolljump=2
   2386  norm! Lj
   2387  call assert_equal({'lnum':11, 'leftcol':0, 'col':0, 'topfill':0,
   2388        \            'topline':3, 'coladd':0, 'skipcol':0, 'curswant':0},
   2389        \           winsaveview())
   2390 
   2391  " Test with negative 'scrolljump' (percentage of window height).
   2392  set scrolljump=-40
   2393  norm! ggLj
   2394  call assert_equal({'lnum':11, 'leftcol':0, 'col':0, 'topfill':0,
   2395         \            'topline':5, 'coladd':0, 'skipcol':0, 'curswant':0},
   2396         \           winsaveview())
   2397 
   2398  set scrolljump&
   2399  bw
   2400 endfunc
   2401 
   2402 " Test for the 'cdhome' option
   2403 func Test_opt_cdhome()
   2404  if has('unix') || has('vms')
   2405    throw 'Skipped: only works on non-Unix'
   2406  endif
   2407 
   2408  set cdhome&
   2409  call assert_equal(0, &cdhome)
   2410  set cdhome
   2411 
   2412  " This paragraph is copied from Test_cd_no_arg().
   2413  let path = getcwd()
   2414  cd
   2415  call assert_equal($HOME, getcwd())
   2416  call assert_notequal(path, getcwd())
   2417  exe 'cd ' .. fnameescape(path)
   2418  call assert_equal(path, getcwd())
   2419 
   2420  set cdhome&
   2421 endfunc
   2422 
   2423 func Test_set_completion_fuzzy()
   2424  CheckOption termguicolors
   2425 
   2426  " Test default option completion
   2427  set wildoptions=
   2428  call feedkeys(":set termg\<C-A>\<C-B>\"\<CR>", 'tx')
   2429  call assert_equal('"set termguicolors', @:)
   2430 
   2431  call feedkeys(":set notermg\<C-A>\<C-B>\"\<CR>", 'tx')
   2432  call assert_equal('"set notermguicolors', @:)
   2433 
   2434  " Test fuzzy option completion
   2435  set wildoptions=fuzzy
   2436  call feedkeys(":set termg\<C-A>\<C-B>\"\<CR>", 'tx')
   2437  " Nvim doesn't have 'termencoding'
   2438  " call assert_equal('"set termguicolors termencoding', @:)
   2439  call assert_equal('"set termguicolors', @:)
   2440 
   2441  call feedkeys(":set notermg\<C-A>\<C-B>\"\<CR>", 'tx')
   2442  call assert_equal('"set notermguicolors', @:)
   2443 
   2444  set wildoptions=
   2445 endfunc
   2446 
   2447 func Test_switchbuf_reset()
   2448  set switchbuf=useopen
   2449  sblast
   2450  call assert_equal(1, winnr('$'))
   2451  set all&
   2452  " Nvim has a different default for 'switchbuf'
   2453  " call assert_equal('', &switchbuf)
   2454  call assert_equal('uselast', &switchbuf)
   2455  sblast
   2456  call assert_equal(2, winnr('$'))
   2457  only!
   2458 endfunc
   2459 
   2460 " :set empty string for global 'keywordprg' falls back to ":help"
   2461 func Test_keywordprg_empty()
   2462  let k = &keywordprg
   2463  set keywordprg=man
   2464  call assert_equal('man', &keywordprg)
   2465  set keywordprg=
   2466  call assert_equal(':help', &keywordprg)
   2467  set keywordprg=man
   2468  call assert_equal('man', &keywordprg)
   2469  call assert_equal("\n  keywordprg=:help", execute('set kp= kp?'))
   2470  let &keywordprg = k
   2471 endfunc
   2472 
   2473 " check that the very first buffer created does not have 'endoffile' set
   2474 func Test_endoffile_default()
   2475  let after =<< trim [CODE]
   2476    call writefile([execute('set eof?')], 'Xtestout')
   2477    qall!
   2478  [CODE]
   2479  if RunVim([], after, '')
   2480    call assert_equal(["\nnoendoffile"], readfile('Xtestout'))
   2481  endif
   2482  call delete('Xtestout')
   2483 endfunc
   2484 
   2485 " Test for setting the 'lines' and 'columns' options to a minimum value
   2486 func Test_set_min_lines_columns()
   2487  let save_lines = &lines
   2488  let save_columns = &columns
   2489 
   2490  let after =<< trim END
   2491    set laststatus=1
   2492    set nomore
   2493    let msg = []
   2494    let v:errmsg = ''
   2495    silent! let &columns=0
   2496    call add(msg, v:errmsg)
   2497    silent! set columns=0
   2498    call add(msg, v:errmsg)
   2499    silent! call setbufvar('', '&columns', 0)
   2500    call add(msg, v:errmsg)
   2501    "call writefile(msg, 'XResultsetminlines')
   2502    silent! let &lines=0
   2503    call add(msg, v:errmsg)
   2504    silent! set lines=0
   2505    call add(msg, v:errmsg)
   2506    silent! call setbufvar('', '&lines', 0)
   2507    call add(msg, v:errmsg)
   2508    call writefile(msg, 'XResultsetminlines')
   2509    qall!
   2510  END
   2511  if RunVim([], after, '')
   2512    call assert_equal(['E594: Need at least 12 columns',
   2513          \ 'E594: Need at least 12 columns: columns=0',
   2514          \ 'E594: Need at least 12 columns',
   2515          \ 'E593: Need at least 2 lines',
   2516          \ 'E593: Need at least 2 lines: lines=0',
   2517          \ 'E593: Need at least 2 lines',], readfile('XResultsetminlines'))
   2518  endif
   2519 
   2520  call delete('XResultsetminlines')
   2521  let &lines = save_lines
   2522  let &columns = save_columns
   2523 endfunc
   2524 
   2525 " Test for reverting a string option value if the new value is invalid.
   2526 func Test_string_option_revert_on_failure()
   2527  new
   2528  let optlist = [
   2529        \ ['ambiwidth', 'double', 'a123'],
   2530        \ ['background', 'dark', 'a123'],
   2531        \ ['backspace', 'eol', 'a123'],
   2532        \ ['backupcopy', 'no', 'a123'],
   2533        \ ['belloff', 'showmatch', 'a123'],
   2534        \ ['breakindentopt', 'min:10', 'list'],
   2535        \ ['bufhidden', 'wipe', 'a123'],
   2536        \ ['buftype', 'nowrite', 'a123'],
   2537        \ ['casemap', 'keepascii', 'a123'],
   2538        \ ['cedit', "\<C-Y>", 'z'],
   2539        \ ['colorcolumn', '10', 'z'],
   2540        \ ['commentstring', '#%s', 'a123'],
   2541        \ ['complete', '.,t', 'a'],
   2542        \ ['completefunc', 'MyCmplFunc', '1a-'],
   2543        "\ ['completeopt', 'popup', 'a123'],
   2544        \ ['completeopt', 'preview', 'a123'],
   2545        "\ ['completepopup', 'width:20', 'border'],
   2546        \ ['concealcursor', 'v', 'xyz'],
   2547        "\ ['cpoptions', 'HJ', 'Q'],
   2548        \ ['cpoptions', 'J', 'Q'],
   2549        "\ ['cryptmethod', 'zip', 'a123'],
   2550        \ ['cursorlineopt', 'screenline', 'a123'],
   2551        \ ['debug', 'throw', 'a123'],
   2552        \ ['diffopt', 'iwhite', 'a123'],
   2553        \ ['display', 'uhex', 'a123'],
   2554        \ ['eadirection', 'hor', 'a123'],
   2555        \ ['encoding', 'utf-8', 'a123'],
   2556        \ ['eventignore', 'TextYankPost', 'a123'],
   2557        \ ['eventignorewin', 'WinScrolled', 'a123'],
   2558        \ ['fileencoding', 'utf-8', 'a123,'],
   2559        \ ['fileformat', 'mac', 'a123'],
   2560        \ ['fileformats', 'mac', 'a123'],
   2561        \ ['filetype', 'abc', 'a^b'],
   2562        \ ['fillchars', 'diff:~', 'a123'],
   2563        \ ['foldclose', 'all', 'a123'],
   2564        \ ['foldmarker', '[[[,]]]', '[[['],
   2565        \ ['foldmethod', 'marker', 'a123'],
   2566        \ ['foldopen', 'percent', 'a123'],
   2567        \ ['formatoptions', 'an', '*'],
   2568        \ ['guicursor', 'n-v-c:block-Cursor/lCursor', 'n-v-c'],
   2569        \ ['helplang', 'en', 'a'],
   2570        "\ ['highlight', '!:CursorColumn', '8:'],
   2571        \ ['keymodel', 'stopsel', 'a123'],
   2572        "\ ['keyprotocol', 'kitty:kitty', 'kitty:'],
   2573        \ ['lispoptions', 'expr:1', 'a123'],
   2574        \ ['listchars', 'tab:->', 'tab:'],
   2575        \ ['matchpairs', '<:>', '<:'],
   2576        \ ['messagesopt', 'hit-enter,history:100', 'a123'],
   2577        \ ['mkspellmem', '100000,1000,100', '100000'],
   2578        \ ['mouse', 'nvi', 'z'],
   2579        \ ['mousemodel', 'extend', 'a123'],
   2580        \ ['nrformats', 'alpha', 'a123'],
   2581        \ ['omnifunc', 'MyOmniFunc', '1a-'],
   2582        \ ['operatorfunc', 'MyOpFunc', '1a-'],
   2583        "\ ['previewpopup', 'width:20', 'a123'],
   2584        "\ ['printoptions', 'paper:A4', 'a123:'],
   2585        \ ['quickfixtextfunc', 'MyQfFunc', '1a-'],
   2586        \ ['rulerformat', '%l', '%['],
   2587        \ ['scrollopt', 'hor,jump', 'a123'],
   2588        \ ['selection', 'exclusive', 'a123'],
   2589        \ ['selectmode', 'cmd', 'a123'],
   2590        \ ['sessionoptions', 'options', 'a123'],
   2591        \ ['shortmess', 'w', '2'],
   2592        \ ['showbreak', '>>', "\x01"],
   2593        \ ['showcmdloc', 'statusline', 'a123'],
   2594        \ ['signcolumn', 'no', 'a123'],
   2595        \ ['spellcapcheck', '[.?!]\+', '%\{'],
   2596        \ ['spellfile', 'MySpell.en.add', "\x01"],
   2597        \ ['spelllang', 'en', "#"],
   2598        \ ['spelloptions', 'camel', 'a123'],
   2599        \ ['spellsuggest', 'double', 'a123'],
   2600        \ ['splitkeep', 'topline', 'a123'],
   2601        \ ['statusline', '%f', '%['],
   2602        "\ ['swapsync', 'sync', 'a123'],
   2603        \ ['switchbuf', 'usetab', 'a123'],
   2604        \ ['syntax', 'abc', 'a^b'],
   2605        \ ['tabline', '%f', '%['],
   2606        \ ['tagcase', 'ignore', 'a123'],
   2607        \ ['tagfunc', 'MyTagFunc', '1a-'],
   2608        \ ['thesaurusfunc', 'MyThesaurusFunc', '1a-'],
   2609        \ ['viewoptions', 'options', 'a123'],
   2610        \ ['virtualedit', 'onemore', 'a123'],
   2611        \ ['whichwrap', '<,>', '{,}'],
   2612        \ ['wildmode', 'list', 'a123'],
   2613        \ ['wildoptions', 'pum', 'a123']
   2614        \ ]
   2615  if has('gui')
   2616    call add(optlist, ['browsedir', 'buffer', 'a123'])
   2617  endif
   2618  if has('clipboard_working')
   2619    call add(optlist, ['clipboard', 'unnamed', 'a123'])
   2620  endif
   2621  if has('win32')
   2622    call add(optlist, ['completeslash', 'slash', 'a123'])
   2623  endif
   2624  if has('cscope')
   2625    call add(optlist, ['cscopequickfix', 't-', 'z-'])
   2626  endif
   2627  if !has('win32') && !has('nvim')
   2628    call add(optlist, ['imactivatefunc', 'MyActFunc', '1a-'])
   2629    call add(optlist, ['imstatusfunc', 'MyStatusFunc', '1a-'])
   2630  endif
   2631  if has('keymap')
   2632    call add(optlist, ['keymap', 'greek', '[]'])
   2633  endif
   2634  if has('mouseshape')
   2635    call add(optlist, ['mouseshape', 'm:no', 'a123:'])
   2636  endif
   2637  if has('win32') && has('gui')
   2638    call add(optlist, ['renderoptions', 'type:directx', 'type:directx,a123'])
   2639  endif
   2640  if has('rightleft')
   2641    call add(optlist, ['rightleftcmd', 'search', 'a123'])
   2642  endif
   2643  if has('terminal')
   2644    call add(optlist, ['termwinkey', '<C-L>', '<C'])
   2645    call add(optlist, ['termwinsize', '24x80', '100'])
   2646  endif
   2647  if has('win32') && has('terminal')
   2648    call add(optlist, ['termwintype', 'winpty', 'a123'])
   2649  endif
   2650  if exists('+toolbar')
   2651    call add(optlist, ['toolbar', 'text', 'a123'])
   2652  endif
   2653  if exists('+toolbariconsize')
   2654    call add(optlist, ['toolbariconsize', 'medium', 'a123'])
   2655  endif
   2656  if exists('+ttymouse') && !has('gui')
   2657    call add(optlist, ['ttymouse', 'xterm', 'a123'])
   2658  endif
   2659  if exists('+vartabs')
   2660    call add(optlist, ['varsofttabstop', '12', 'a123'])
   2661    call add(optlist, ['vartabstop', '4,20', '4,'])
   2662  endif
   2663  if exists('+winaltkeys')
   2664    call add(optlist, ['winaltkeys', 'no', 'a123'])
   2665  endif
   2666  for opt in optlist
   2667    exe $"let save_opt = &{opt[0]}"
   2668    try
   2669      exe $"let &{opt[0]} = '{opt[1]}'"
   2670    catch
   2671      call assert_report($"Caught {v:exception} with {opt->string()}")
   2672    endtry
   2673    call assert_fails($"let &{opt[0]} = '{opt[2]}'", '', opt[0])
   2674    call assert_equal(opt[1], eval($"&{opt[0]}"), opt[0])
   2675    exe $"let &{opt[0]} = save_opt"
   2676  endfor
   2677  bw!
   2678 endfunc
   2679 
   2680 func Test_set_option_window_global_local()
   2681  new Xbuffer1
   2682  let [ _gso, _lso ] = [ &g:scrolloff, &l:scrolloff ]
   2683  setlocal scrolloff=2
   2684  setglobal scrolloff=3
   2685  setl modified
   2686  " A new buffer has its own window-local options
   2687  hide enew
   2688  call assert_equal(-1, &l:scrolloff)
   2689  call assert_equal(3, &g:scrolloff)
   2690  " A new window opened with its own buffer-local options
   2691  new
   2692  call assert_equal(-1, &l:scrolloff)
   2693  call assert_equal(3, &g:scrolloff)
   2694  " Re-open Xbuffer1 and it should use
   2695  " the previous set window-local options
   2696  b Xbuffer1
   2697  call assert_equal(2, &l:scrolloff)
   2698  call assert_equal(3, &g:scrolloff)
   2699  bw!
   2700  bw!
   2701  let &g:scrolloff =  _gso
   2702 endfunc
   2703 
   2704 func GetGlobalLocalWindowOptions()
   2705  new
   2706  sil! r $VIMRUNTIME/doc/options.txt
   2707  " Filter for global or local to window
   2708  v/^'.*'.*\n.*global or local to window |global-local/d
   2709  " get option value and type
   2710  sil %s/^'\([^']*\)'.*'\s\+\(\w\+\)\s\+(default \%(\(".*"\|\d\+\|empty\|is very long\)\).*/\1 \2 \3/g
   2711  " sil %s/empty/""/g
   2712  " split the result
   2713  " let result=getline(1,'$')->map({_, val -> split(val, ' ')})
   2714  let result = getline(1, '$')->map({_, val -> matchlist(val, '\([^ ]\+\) \+\([^ ]\+\) \+\(.*\)')[1:3]})
   2715  bw!
   2716  return result
   2717 endfunc
   2718 
   2719 func Test_set_option_window_global_local_all()
   2720  new Xbuffer2
   2721 
   2722  let optionlist = GetGlobalLocalWindowOptions()
   2723  for [opt, type, default] in optionlist
   2724    let _old = eval('&g:' .. opt)
   2725    if opt == 'statusline'
   2726      " parsed default value is "is very long" as it is a doc string, not actual value
   2727      let default = "\"" . _old . "\""
   2728    endif
   2729    if type == 'string'
   2730      if opt == 'fillchars'
   2731        exe 'setl ' .. opt .. '=vert:+'
   2732        exe 'setg ' .. opt .. '=vert:+,fold:+'
   2733      elseif opt == 'listchars'
   2734        exe 'setl ' .. opt .. '=tab:>>'
   2735        exe 'setg ' .. opt .. '=tab:++'
   2736      elseif opt == 'virtualedit'
   2737        exe 'setl ' .. opt .. '=all'
   2738        exe 'setg ' .. opt .. '=block'
   2739      else
   2740        exe 'setl ' .. opt .. '=Local'
   2741        exe 'setg ' .. opt .. '=Global'
   2742      endif
   2743    elseif type == 'number'
   2744      exe 'setl ' .. opt .. '=5'
   2745      exe 'setg ' .. opt .. '=10'
   2746    endif
   2747    setl modified
   2748    hide enew
   2749    if type == 'string'
   2750      call assert_equal('', eval('&l:' .. opt))
   2751      if opt == 'fillchars'
   2752        call assert_equal('vert:+,fold:+', eval('&g:' .. opt), 'option:' .. opt)
   2753      elseif opt == 'listchars'
   2754        call assert_equal('tab:++', eval('&g:' .. opt), 'option:' .. opt)
   2755      elseif opt == 'virtualedit'
   2756        call assert_equal('block', eval('&g:' .. opt), 'option:' .. opt)
   2757      else
   2758        call assert_equal('Global', eval('&g:' .. opt), 'option:' .. opt)
   2759      endif
   2760    elseif type == 'number'
   2761      call assert_equal(-1, eval('&l:' .. opt), 'option:' .. opt)
   2762      call assert_equal(10, eval('&g:' .. opt), 'option:' .. opt)
   2763    endif
   2764    bw!
   2765    exe 'let &g:' .. opt .. '=' .. default
   2766  endfor
   2767  bw!
   2768 endfunc
   2769 
   2770 func Test_paste_depending_options()
   2771  " setting the paste option, resets all dependent options
   2772  " and will be reported correctly using :verbose set <option>?
   2773  let lines =<< trim [CODE]
   2774    " set paste test
   2775    set autoindent
   2776    set expandtab
   2777    " disabled, because depends on compiled feature set
   2778    " set hkmap
   2779    " set revins
   2780    " set varsofttabstop=8,32,8
   2781    set ruler
   2782    set showmatch
   2783    set smarttab
   2784    set softtabstop=4
   2785    set textwidth=80
   2786    set wrapmargin=10
   2787 
   2788    source Xvimrc_paste2
   2789 
   2790    redir > Xoutput_paste
   2791    verbose set expandtab?
   2792    verbose setg expandtab?
   2793    verbose setl expandtab?
   2794    redir END
   2795 
   2796    qall!
   2797  [CODE]
   2798 
   2799  call writefile(lines, 'Xvimrc_paste', 'D')
   2800  call writefile(['set paste'], 'Xvimrc_paste2', 'D')
   2801  if !RunVim([], lines, '--clean')
   2802    return
   2803  endif
   2804 
   2805  let result = readfile('Xoutput_paste')->filter('!empty(v:val)')
   2806  call assert_equal('noexpandtab', result[0])
   2807  call assert_match("^\tLast set from .*Xvimrc_paste2 line 1$", result[1])
   2808  call assert_equal('noexpandtab', result[2])
   2809  call assert_match("^\tLast set from .*Xvimrc_paste2 line 1$", result[3])
   2810  call assert_equal('noexpandtab', result[4])
   2811  call assert_match("^\tLast set from .*Xvimrc_paste2 line 1$", result[5])
   2812 
   2813  call delete('Xoutput_paste')
   2814 endfunc
   2815 
   2816 func Test_binary_depending_options()
   2817  " setting the paste option, resets all dependent options
   2818  " and will be reported correctly using :verbose set <option>?
   2819  let lines =<< trim [CODE]
   2820    " set binary test
   2821    set expandtab
   2822 
   2823    source Xvimrc_bin2
   2824 
   2825    redir > Xoutput_bin
   2826    verbose set expandtab?
   2827    verbose setg expandtab?
   2828    verbose setl expandtab?
   2829    redir END
   2830 
   2831    qall!
   2832  [CODE]
   2833 
   2834  call writefile(lines, 'Xvimrc_bin', 'D')
   2835  call writefile(['set binary'], 'Xvimrc_bin2', 'D')
   2836  if !RunVim([], lines, '--clean')
   2837    return
   2838  endif
   2839 
   2840  let result = readfile('Xoutput_bin')->filter('!empty(v:val)')
   2841  call assert_equal('noexpandtab', result[0])
   2842  call assert_match("^\tLast set from .*Xvimrc_bin2 line 1$", result[1])
   2843  call assert_equal('noexpandtab', result[2])
   2844  call assert_match("^\tLast set from .*Xvimrc_bin2 line 1$", result[3])
   2845  call assert_equal('noexpandtab', result[4])
   2846  call assert_match("^\tLast set from .*Xvimrc_bin2 line 1$", result[5])
   2847 
   2848  call delete('Xoutput_bin')
   2849 endfunc
   2850 
   2851 func Test_set_wrap()
   2852  " Unsetting 'wrap' when 'smoothscroll' is set does not result in incorrect
   2853  " cursor position.
   2854  set wrap smoothscroll scrolloff=5
   2855 
   2856  call setline(1, ['', 'aaaa'->repeat(500)])
   2857  20 split
   2858  20 vsplit
   2859  norm 2G$
   2860  redraw
   2861  set nowrap
   2862  call assert_equal(2, winline())
   2863 
   2864  set wrap& smoothscroll& scrolloff&
   2865 endfunc
   2866 
   2867 func Test_delcombine()
   2868  new
   2869  set backspace=indent,eol,start
   2870 
   2871  set delcombine
   2872  call setline(1, 'β̳̈:β̳̈')
   2873  normal! 0x
   2874  call assert_equal('β̈:β̳̈', getline(1))
   2875  exe "normal! A\<BS>"
   2876  call assert_equal('β̈:β̈', getline(1))
   2877  normal! 0x
   2878  call assert_equal('β:β̈', getline(1))
   2879  exe "normal! A\<BS>"
   2880  call assert_equal('β:β', getline(1))
   2881  normal! 0x
   2882  call assert_equal(':β', getline(1))
   2883  exe "normal! A\<BS>"
   2884  call assert_equal(':', getline(1))
   2885 
   2886  set nodelcombine
   2887  call setline(1, 'β̳̈:β̳̈')
   2888  normal! 0x
   2889  call assert_equal(':β̳̈', getline(1))
   2890  exe "normal! A\<BS>"
   2891  call assert_equal(':', getline(1))
   2892 
   2893  set backspace& delcombine&
   2894  bwipe!
   2895 endfunc
   2896 
   2897 " Should not raise errors when set missing-options.
   2898 func Test_set_missing_options()
   2899  throw 'Skipped: N/A'
   2900  set autoprint
   2901  set beautify
   2902  set flash
   2903  set graphic
   2904  set hardtabs=8
   2905  set mesg
   2906  set novice
   2907  set open
   2908  set optimize
   2909  set redraw
   2910  set slowopen
   2911  set sourceany
   2912  set w300=23
   2913  set w1200=23
   2914  set w9600=23
   2915 endfunc
   2916 
   2917 func Test_showcmd()
   2918  throw 'Skipped: Nvim does not support support Vi-compatible mode'
   2919  " in no-cp mode, 'showcmd' is enabled
   2920  let _cp=&cp
   2921  call assert_equal(1, &showcmd)
   2922  set cp
   2923  call assert_equal(0, &showcmd)
   2924  set nocp
   2925  call assert_equal(1, &showcmd)
   2926  let &cp = _cp
   2927 endfunc
   2928 
   2929 " vim: shiftwidth=2 sts=2 expandtab