neovim

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

test_menu.vim (24176B)


      1 " Test that the system menu can be loaded.
      2 
      3 source check.vim
      4 CheckFeature menu
      5 
      6 source screendump.vim
      7 
      8 func Test_load_menu()
      9  try
     10    source $VIMRUNTIME/menu.vim
     11  catch
     12    call assert_report('error while loading menus: ' . v:exception)
     13  endtry
     14  call assert_match('browse confirm w', execute(':menu File.Save'))
     15 
     16  let v:errmsg = ''
     17  doautocmd LoadBufferMenu VimEnter
     18  call assert_equal('', v:errmsg)
     19 
     20  source $VIMRUNTIME/delmenu.vim
     21  call assert_equal('', v:errmsg)
     22 endfunc
     23 
     24 func Test_buffer_menu_special_buffers()
     25  " Load in runtime menus
     26  try
     27    source $VIMRUNTIME/menu.vim
     28  catch
     29    call assert_report('error while loading menus: ' . v:exception)
     30  endtry
     31 
     32  let v:errmsg = ''
     33  doautocmd LoadBufferMenu VimEnter
     34  call assert_equal('', v:errmsg)
     35 
     36  let orig_buffer_menus = execute("nmenu Buffers")
     37 
     38  " Test that regular new buffer results in a new buffer menu item.
     39  new
     40  let new_buffer_menus = execute('nmenu Buffers')
     41  call assert_equal(len(split(orig_buffer_menus, "\n")) + 2, len(split(new_buffer_menus, "\n")))
     42  bwipe!
     43  call assert_equal(orig_buffer_menus, execute("nmenu Buffers"))
     44 
     45  " Make a new command-line window, test that it does not create a new buffer
     46  " menu.
     47  call feedkeys("q::let cmdline_buffer_menus=execute('nmenu Buffers')\<CR>:q\<CR>", 'ntx')
     48  call assert_equal(len(split(orig_buffer_menus, "\n")) + 2, len(split(cmdline_buffer_menus, "\n")))
     49  call assert_equal(orig_buffer_menus, execute("nmenu Buffers"))
     50 
     51  if has('terminal')
     52    " Open a terminal window and test that it does not create a buffer menu
     53    " item.
     54    terminal
     55    let term_buffer_menus = execute('nmenu Buffers')
     56    call assert_equal(len(split(orig_buffer_menus, "\n")) + 2, len(split(term_buffer_menus, "\n")))
     57    bwipe!
     58    call assert_equal(orig_buffer_menus, execute("nmenu Buffers"))
     59  endif
     60 
     61  " Remove menus to clean up
     62  source $VIMRUNTIME/delmenu.vim
     63  call assert_equal('', v:errmsg)
     64 endfunc
     65 
     66 func Test_translate_menu()
     67  if !has('multi_lang')
     68    return
     69  endif
     70  if !filereadable($VIMRUNTIME . '/lang/menu_de_de.latin1.vim')
     71    throw 'Skipped: translated menu not found'
     72  endif
     73 
     74  " First delete any English menus.
     75  source $VIMRUNTIME/delmenu.vim
     76  set langmenu=de_de
     77  source $VIMRUNTIME/menu.vim
     78  call assert_match('browse confirm w', execute(':menu Datei.Speichern'))
     79 
     80  source $VIMRUNTIME/delmenu.vim
     81 endfunc
     82 
     83 func Test_menu_commands()
     84  nmenu 2 Test.FooBar :let g:did_menu = 'normal'<CR>
     85  vmenu 2 Test.FooBar :let g:did_menu = 'visual'<CR>
     86  smenu 2 Test.FooBar :let g:did_menu = 'select'<CR>
     87  omenu 2 Test.FooBar :let g:did_menu = 'op-pending'<CR>
     88  tlmenu 2 Test.FooBar :let g:did_menu = 'terminal'<CR>
     89  imenu 2 Test.FooBar :let g:did_menu = 'insert'<CR>
     90  cmenu 2 Test.FooBar :let g:did_menu = 'cmdline'<CR>
     91  emenu n Test.FooBar
     92 
     93  call feedkeys(":menu Test.FooB\<C-A>\<C-B>\"\<CR>", 'tx')
     94  call assert_equal('"menu Test.FooBar', @:)
     95 
     96  call assert_equal('normal', g:did_menu)
     97  emenu v Test.FooBar
     98  call assert_equal('visual', g:did_menu)
     99  emenu s Test.FooBar
    100  call assert_equal('select', g:did_menu)
    101  emenu o Test.FooBar
    102  call assert_equal('op-pending', g:did_menu)
    103  emenu t Test.FooBar
    104  call assert_equal('terminal', g:did_menu)
    105  emenu i Test.FooBar
    106  call assert_equal('insert', g:did_menu)
    107  emenu c Test.FooBar
    108  call assert_equal('cmdline', g:did_menu)
    109 
    110  nunmenu Test.FooBar
    111  call assert_fails('emenu n Test.FooBar', 'E335: Menu not defined for Normal mode')
    112  vunmenu Test.FooBar
    113  call assert_fails('emenu v Test.FooBar', 'E335: Menu not defined for Visual mode')
    114  vmenu 2 Test.FooBar :let g:did_menu = 'visual'<CR>
    115  sunmenu Test.FooBar
    116  call assert_fails('emenu s Test.FooBar', 'E335: Menu not defined for Select mode')
    117  ounmenu Test.FooBar
    118  call assert_fails('emenu o Test.FooBar', 'E335: Menu not defined for Op-pending mode')
    119  iunmenu Test.FooBar
    120  call assert_fails('emenu i Test.FooBar', 'E335: Menu not defined for Insert mode')
    121  cunmenu Test.FooBar
    122  call assert_fails('emenu c Test.FooBar', 'E335: Menu not defined for Cmdline mode')
    123  tlunmenu Test.FooBar
    124  call assert_fails('emenu t Test.FooBar', 'E335: Menu not defined for Terminal mode')
    125 
    126  aunmenu Test.FooBar
    127  call assert_fails('emenu n Test.FooBar', 'E334:')
    128 
    129  nmenu 2 Test.FooBar.Child :let g:did_menu = 'foobar'<CR>
    130  call assert_fails('emenu n Test.FooBar', 'E333:')
    131  nunmenu Test.FooBar.Child
    132 
    133  unlet g:did_menu
    134 endfun
    135 
    136 " Test various menu related errors
    137 func Test_menu_errors()
    138  menu Test.Foo  :version<CR>
    139 
    140  " Error cases
    141  call assert_fails('menu .Test.Foo :ls<CR>', 'E475:')
    142  call assert_fails('menu Test. :ls<CR>', 'E330:')
    143  call assert_fails('menu Foo. :ls<CR>', 'E331:')
    144  call assert_fails('unmenu Test.Foo abc', 'E488:')
    145  call assert_fails('menu <Tab>:ls  :ls<CR>', 'E792:')
    146  call assert_fails('menu Test.<Tab>:ls  :ls<CR>', 'E792:')
    147  call assert_fails('menu Test.Foo.Bar  :ls<CR>', 'E327:')
    148  call assert_fails('menu Test.-Sep-.Baz  :ls<CR>', 'E332:')
    149  call assert_fails('menu Foo.Bar.--.Baz  :ls<CR>', 'E332:')
    150  call assert_fails('menu disable Test.Foo.Bar', 'E327:')
    151  call assert_fails('menu disable T.Foo', 'E329:')
    152  call assert_fails('unmenu Test.Foo.Bar', 'E327:')
    153  call assert_fails('cunmenu Test.Foo', 'E328:')
    154  call assert_fails('unmenu Test.Bar', 'E329:')
    155  call assert_fails('menu Test.Foo.Bar', 'E327:')
    156  call assert_fails('cmenu Test.Foo', 'E328:')
    157  call assert_fails('emenu x Test.Foo', 'E475:')
    158  call assert_fails('emenu Test.Foo.Bar', 'E327:')
    159  call assert_fails('menutranslate Test', 'E474:')
    160 
    161  silent! unmenu Foo
    162  unmenu Test
    163 endfunc
    164 
    165 func Test_unmenu_range_errors()
    166  for prefix in ['', 'a', 'c', 'i', 'n', 's', 't', 'tl', 'v', 'x']
    167    call assert_fails('42' .. prefix .. 'unmenu', 'E481:')
    168  endfor
    169 endfunc
    170 
    171 " Test for menu item completion in command line
    172 func Test_menu_expand()
    173  " Create the menu items for test
    174  menu Dummy.Nothing lll
    175  for i in range(1, 4)
    176    let m = 'menu Xmenu.A' .. i .. '.A' .. i
    177    for j in range(1, 4)
    178      exe m .. 'B' .. j .. ' :echo "A' .. i .. 'B' .. j .. '"' .. "<CR>"
    179    endfor
    180  endfor
    181  set wildmenu
    182 
    183  " Test for <CR> selecting a submenu
    184  call feedkeys(":emenu Xmenu.A\<Tab>\<CR>\<Right>x\<BS>\<C-B>\"\<CR>", 'xt')
    185  call assert_equal('"emenu Xmenu.A1.A1B2', @:)
    186 
    187  " Test for <Down> selecting a submenu
    188  call feedkeys(":emenu Xmenu.A\<Tab>\<Right>\<Right>\<Down>" ..
    189        \ "\<C-A>\<C-B>\"\<CR>", 'xt')
    190  call assert_equal('"emenu Xmenu.A3.A3B1 A3B2 A3B3 A3B4', @:)
    191 
    192  " Test for <Up> to go up a submenu
    193  call feedkeys(":emenu Xmenu.A\<Tab>\<Down>\<Up>\<Right>\<Right>" ..
    194        \ "\<Left>\<Down>\<C-A>\<C-B>\"\<CR>", 'xt')
    195  call assert_equal('"emenu Xmenu.A2.A2B1 A2B2 A2B3 A2B4', @:)
    196 
    197  " Test for <Up> to go up a menu
    198  call feedkeys(":emenu Xmenu.A\<Tab>\<Down>\<Up>\<Up>\<Up>" ..
    199        \ "\<C-A>\<C-B>\"\<CR>", 'xt')
    200  call assert_equal('"emenu Dummy. Xmenu.', @:)
    201 
    202  " Test for expanding only submenus
    203  call feedkeys(":popup Xmenu.\<C-A>\<C-B>\"\<CR>", 'xt')
    204  call assert_equal('"popup Xmenu.A1 A2 A3 A4', @:)
    205 
    206  " Test for expanding menus after enable/disable
    207  call feedkeys(":menu enable Xmenu.\<C-A>\<C-B>\"\<CR>", 'xt')
    208  call assert_equal('"menu enable Xmenu.A1. A2. A3. A4.', @:)
    209  call feedkeys(":menu disable Xmenu.\<C-A>\<C-B>\"\<CR>", 'xt')
    210  call assert_equal('"menu disable Xmenu.A1. A2. A3. A4.', @:)
    211 
    212  " Test for expanding non-existing menu path
    213  call feedkeys(":menu xyz.\<C-A>\<C-B>\"\<CR>", 'xt')
    214  call assert_equal('"menu xyz.', @:)
    215  call feedkeys(":menu Xmenu.A1.A1B1.xyz.\<C-A>\<C-B>\"\<CR>", 'xt')
    216  call assert_equal('"menu Xmenu.A1.A1B1.xyz.', @:)
    217 
    218  set wildmenu&
    219  unmenu Xmenu
    220  unmenu Dummy
    221 
    222  " Test for expanding popup menus with some hidden items
    223  menu Xmenu.foo.A1 a1
    224  menu Xmenu.]bar bar
    225  menu Xmenu.]baz.B1 b1
    226  menu Xmenu.-sep- :
    227  call feedkeys(":popup Xmenu.\<C-A>\<C-B>\"\<CR>", 'xt')
    228  call assert_equal('"popup Xmenu.foo', @:)
    229  unmenu Xmenu
    230 endfunc
    231 
    232 " Test for the menu_info() function
    233 func Test_menu_info()
    234  " Define menus with various attributes
    235  10nnoremenu 10.10 T&est.F&oo  :echo 'foo'<CR>
    236  10nmenu <silent> 10.20 T&est.B&ar<Tab>:bar  :echo 'bar'<CR>
    237  10nmenu <script> 10.30.5 T&est.Ba&z.Qu&x  :echo 'qux'<CR>
    238 
    239  let d = #{name: "B&ar\t:bar", display: 'Bar', modes: 'n', shortcut: 'a',
    240        \ accel: ':bar', priority: 20, enabled: v:true, silent: v:true,
    241        \ noremenu: v:false, script: v:false, rhs: ":echo 'bar'<CR>"}
    242  call assert_equal(d, menu_info('Test.Bar'))
    243 
    244  let d = #{name: 'Ba&z', display: 'Baz', modes: 'n', shortcut: 'z',
    245        \ priority: 30, submenus: ['Qux']}
    246  call assert_equal(d, menu_info('Test.Baz'))
    247 
    248  let d = #{name: 'T&est', display: 'Test', modes: 'n', shortcut: 'e',
    249        \ priority: 10, submenus: ['Foo', 'Bar', 'Baz']}
    250  call assert_equal(d, menu_info('Test'))
    251  call assert_equal({}, menu_info('Test.Dummy'))
    252  call assert_equal({}, menu_info('Dummy'))
    253 
    254  nmenu disable Test.Foo
    255  call assert_equal(v:false, menu_info('Test.Foo').enabled)
    256  nmenu enable Test.Foo
    257  call assert_equal(v:true, menu_info('Test.Foo').enabled)
    258 
    259  call assert_equal(menu_info('Test.Foo'), menu_info('Test.Foo', ''))
    260  nmenu Test.abc  <Nop>
    261  call assert_equal('<Nop>', menu_info('Test.abc').rhs)
    262  call assert_fails('call menu_info([])', 'E730:')
    263  call assert_fails('call menu_info("", [])', 'E730:')
    264  nunmenu Test
    265 
    266  " Test for defining menus in different modes
    267  menu Test.menu :menu<CR>
    268  menu! Test.menu! :menu!<CR>
    269  amenu Test.amenu  :amenu<CR>
    270  nmenu Test.nmenu  :nmenu<CR>
    271  omenu Test.omenu  :omenu<CR>
    272  vmenu Test.vmenu  :vmenu<CR>
    273  xmenu Test.xmenu  :xmenu<CR>
    274  smenu Test.smenu  :smenu<CR>
    275  imenu <silent> <script> Test.imenu  :imenu<CR>
    276  cmenu Test.cmenu  :cmenu<CR>
    277  tlmenu Test.tlmenu  :tlmenu<CR>
    278  tmenu Test.nmenu Normal mode menu
    279  tmenu Test.omenu Op-pending mode menu
    280  noremenu Test.noremenu :noremenu<CR>
    281  noremenu! Test.noremenu! :noremenu!<CR>
    282  anoremenu Test.anoremenu  :anoremenu<CR>
    283  nnoremenu Test.nnoremenu  :nnoremenu<CR>
    284  onoremenu Test.onoremenu  :onoremenu<CR>
    285  vnoremenu Test.vnoremenu  :vnoremenu<CR>
    286  xnoremenu Test.xnoremenu  :xnoremenu<CR>
    287  snoremenu Test.snoremenu  :snoremenu<CR>
    288  inoremenu <silent> Test.inoremenu  :inoremenu<CR>
    289  cnoremenu Test.cnoremenu  :cnoremenu<CR>
    290  tlnoremenu Test.tlnoremenu  :tlnoremenu<CR>
    291  call assert_equal(#{name: 'menu', priority: 500, shortcut: '',
    292        \ display: 'menu', modes: ' ', enabled: v:true, silent: v:false,
    293        \ rhs: ":menu<CR>", noremenu: v:false, script: v:false},
    294        \ menu_info('Test.menu'))
    295  call assert_equal(#{name: 'menu!', priority: 500, shortcut: '',
    296        \ display: 'menu!', modes: '!', enabled: v:true, silent: v:false,
    297        \ rhs: ":menu!<CR>", noremenu: v:false, script: v:false},
    298        \ menu_info('Test.menu!', '!'))
    299  call assert_equal(#{name: 'amenu', priority: 500, shortcut: '',
    300        \ display: 'amenu', modes: 'a', enabled: v:true, silent: v:false,
    301        \ rhs: ":amenu<CR>", noremenu: v:false, script: v:false},
    302        \ menu_info('Test.amenu', 'a'))
    303  call assert_equal(#{name: 'nmenu', priority: 500, shortcut: '',
    304        \ display: 'nmenu', modes: 'n', enabled: v:true, silent: v:false,
    305        \ rhs: ':nmenu<CR>', noremenu: v:false, script: v:false},
    306        \ menu_info('Test.nmenu', 'n'))
    307  call assert_equal(#{name: 'omenu', priority: 500, shortcut: '',
    308        \ display: 'omenu', modes: 'o', enabled: v:true, silent: v:false,
    309        \ rhs: ':omenu<CR>', noremenu: v:false, script: v:false},
    310        \ menu_info('Test.omenu', 'o'))
    311  call assert_equal(#{name: 'vmenu', priority: 500, shortcut: '',
    312        \ display: 'vmenu', modes: 'v', enabled: v:true, silent: v:false,
    313        \ rhs: ':vmenu<CR>', noremenu: v:false, script: v:false},
    314        \ menu_info('Test.vmenu', 'v'))
    315  call assert_equal(#{name: 'xmenu', priority: 500, shortcut: '',
    316        \ display: 'xmenu', modes: 'x', enabled: v:true, silent: v:false,
    317        \ rhs: ':xmenu<CR>', noremenu: v:false, script: v:false},
    318        \ menu_info('Test.xmenu', 'x'))
    319  call assert_equal(#{name: 'smenu', priority: 500, shortcut: '',
    320        \ display: 'smenu', modes: 's', enabled: v:true, silent: v:false,
    321        \ rhs: ':smenu<CR>', noremenu: v:false, script: v:false},
    322        \ menu_info('Test.smenu', 's'))
    323  call assert_equal(#{name: 'imenu', priority: 500, shortcut: '',
    324        \ display: 'imenu', modes: 'i', enabled: v:true, silent: v:true,
    325        \ rhs: ':imenu<CR>', noremenu: v:false, script: v:true},
    326        \ menu_info('Test.imenu', 'i'))
    327  call assert_equal(#{ name: 'cmenu', priority: 500, shortcut: '',
    328        \ display: 'cmenu', modes: 'c', enabled: v:true, silent: v:false,
    329        \ rhs: ':cmenu<CR>', noremenu: v:false, script: v:false},
    330        \ menu_info('Test.cmenu', 'c'))
    331  call assert_equal(#{name: 'tlmenu', priority: 500, shortcut: '',
    332        \ display: 'tlmenu', modes: 'tl', enabled: v:true, silent: v:false,
    333        \ rhs: ':tlmenu<CR>', noremenu: v:false, script: v:false},
    334        \ menu_info('Test.tlmenu', 'tl'))
    335  call assert_equal(#{name: 'noremenu', priority: 500, shortcut: '',
    336        \ display: 'noremenu', modes: ' ', enabled: v:true, silent: v:false,
    337        \ rhs: ":noremenu<CR>", noremenu: v:true, script: v:false},
    338        \ menu_info('Test.noremenu'))
    339  call assert_equal(#{name: 'noremenu!', priority: 500, shortcut: '',
    340        \ display: 'noremenu!', modes: '!', enabled: v:true, silent: v:false,
    341        \ rhs: ":noremenu!<CR>", noremenu: v:true, script: v:false},
    342        \ menu_info('Test.noremenu!', '!'))
    343  call assert_equal(#{name: 'anoremenu', priority: 500, shortcut: '',
    344        \ display: 'anoremenu', modes: 'a', enabled: v:true, silent: v:false,
    345        \ rhs: ":anoremenu<CR>", noremenu: v:true, script: v:false},
    346        \ menu_info('Test.anoremenu', 'a'))
    347  call assert_equal(#{name: 'nnoremenu', priority: 500, shortcut: '',
    348        \ display: 'nnoremenu', modes: 'n', enabled: v:true, silent: v:false,
    349        \ rhs: ':nnoremenu<CR>', noremenu: v:true, script: v:false},
    350        \ menu_info('Test.nnoremenu', 'n'))
    351  call assert_equal(#{name: 'onoremenu', priority: 500, shortcut: '',
    352        \ display: 'onoremenu', modes: 'o', enabled: v:true, silent: v:false,
    353        \ rhs: ':onoremenu<CR>', noremenu: v:true, script: v:false},
    354        \ menu_info('Test.onoremenu', 'o'))
    355  call assert_equal(#{name: 'vnoremenu', priority: 500, shortcut: '',
    356        \ display: 'vnoremenu', modes: 'v', enabled: v:true, silent: v:false,
    357        \ rhs: ':vnoremenu<CR>', noremenu: v:true, script: v:false},
    358        \ menu_info('Test.vnoremenu', 'v'))
    359  call assert_equal(#{name: 'xnoremenu', priority: 500, shortcut: '',
    360        \ display: 'xnoremenu', modes: 'x', enabled: v:true, silent: v:false,
    361        \ rhs: ':xnoremenu<CR>', noremenu: v:true, script: v:false},
    362        \ menu_info('Test.xnoremenu', 'x'))
    363  call assert_equal(#{name: 'snoremenu', priority: 500, shortcut: '',
    364        \ display: 'snoremenu', modes: 's', enabled: v:true, silent: v:false,
    365        \ rhs: ':snoremenu<CR>', noremenu: v:true, script: v:false},
    366        \ menu_info('Test.snoremenu', 's'))
    367  call assert_equal(#{name: 'inoremenu', priority: 500, shortcut: '',
    368        \ display: 'inoremenu', modes: 'i', enabled: v:true, silent: v:true,
    369        \ rhs: ':inoremenu<CR>', noremenu: v:true, script: v:false},
    370        \ menu_info('Test.inoremenu', 'i'))
    371  call assert_equal(#{ name: 'cnoremenu', priority: 500, shortcut: '',
    372        \ display: 'cnoremenu', modes: 'c', enabled: v:true, silent: v:false,
    373        \ rhs: ':cnoremenu<CR>', noremenu: v:true, script: v:false},
    374        \ menu_info('Test.cnoremenu', 'c'))
    375  call assert_equal(#{name: 'tlnoremenu', priority: 500, shortcut: '',
    376        \ display: 'tlnoremenu', modes: 'tl', enabled: v:true, silent: v:false,
    377        \ rhs: ':tlnoremenu<CR>', noremenu: v:true, script: v:false},
    378        \ menu_info('Test.tlnoremenu', 'tl'))
    379 
    380  " Test for getting all the top-level menu names
    381  call assert_notequal(menu_info('').submenus, [])
    382 
    383  aunmenu Test
    384  tlunmenu Test
    385  call assert_equal({}, menu_info('Test'))
    386  call assert_equal({}, menu_info('Test', '!'))
    387  call assert_equal({}, menu_info('Test', 'a'))
    388  call assert_equal({}, menu_info('Test', 'n'))
    389  call assert_equal({}, menu_info('Test', 'o'))
    390  call assert_equal({}, menu_info('Test', 'v'))
    391  call assert_equal({}, menu_info('Test', 'x'))
    392  call assert_equal({}, menu_info('Test', 's'))
    393  call assert_equal({}, menu_info('Test', 'i'))
    394  call assert_equal({}, menu_info('Test', 'c'))
    395  call assert_equal({}, menu_info('Test', 't'))
    396  call assert_equal({}, menu_info('Test', 'tl'))
    397 
    398  amenu Test.amenu  :amenu<CR>
    399  call assert_equal(':amenu<CR>', menu_info('Test.amenu', '').rhs)
    400  call assert_equal('<C-\><C-O>:amenu<CR>', menu_info('Test.amenu', '!').rhs)
    401  call assert_equal(':amenu<CR>', menu_info('Test.amenu', 'n').rhs)
    402  call assert_equal('<C-C>:amenu<CR><C-\><C-G>',
    403        \ menu_info('Test.amenu', 'o').rhs)
    404  call assert_equal('<C-C>:amenu<CR><C-\><C-G>',
    405        \ menu_info('Test.amenu', 'v').rhs)
    406  call assert_equal('<C-C>:amenu<CR><C-\><C-G>',
    407        \ menu_info('Test.amenu', 'x').rhs)
    408  call assert_equal('<C-C>:amenu<CR><C-\><C-G>',
    409        \ menu_info('Test.amenu', 's').rhs)
    410  call assert_equal('<C-\><C-O>:amenu<CR>', menu_info('Test.amenu', 'i').rhs)
    411  call assert_equal('<C-C>:amenu<CR><C-\><C-G>',
    412        \ menu_info('Test.amenu', 'c').rhs)
    413  aunmenu Test.amenu
    414 
    415  " Test for hidden menus
    416  menu ]Test.menu :menu<CR>
    417  call assert_equal(#{name: ']Test', display: ']Test', priority: 500,
    418        \ shortcut: '', modes: ' ', submenus: ['menu']},
    419        \ menu_info(']Test'))
    420  unmenu ]Test
    421 endfunc
    422 
    423 " Test for <special> keyword in a menu with 'cpo' containing '<'
    424 func Test_menu_special()
    425  throw 'Skipped: Nvim does not support cpoptions flag "<"'
    426  new
    427  set cpo+=<
    428  nmenu Test.Sign  am<Tab>n<Esc>
    429  call feedkeys(":emenu n Test.Sign\<CR>", 'x')
    430  call assert_equal("m<Tab>n<Esc>", getline(1))
    431  nunmenu Test.Sign
    432  nmenu <special> Test.Sign  am<Tab>n<Esc>
    433  call setline(1, '')
    434  call feedkeys(":emenu n Test.Sign\<CR>", 'x')
    435  call assert_equal("m\tn", getline(1))
    436  set cpo-=<
    437  bw!
    438  nunmenu Test.Sign
    439 endfunc
    440 
    441 " Test for "icon=filename" in a toolbar
    442 func Test_menu_icon()
    443  CheckFeature toolbar
    444  nmenu icon=myicon.xpm Toolbar.Foo  :echo "Foo"<CR>
    445  call assert_equal('myicon.xpm', "Toolbar.Foo"->menu_info().icon)
    446  nunmenu Toolbar.Foo
    447 
    448  " Test for using the builtin icon
    449  amenu ToolBar.BuiltIn22 :echo "BuiltIn22"<CR>
    450  call assert_equal(#{name: 'BuiltIn22', display: 'BuiltIn22',
    451        \ enabled: v:true, shortcut: '', modes: 'a', script: v:false,
    452        \ iconidx: 22, priority: 500, silent: v:false,
    453        \ rhs: ':echo "BuiltIn22"<CR>', noremenu: v:false},
    454        \ menu_info("ToolBar.BuiltIn22"))
    455  aunmenu ToolBar.BuiltIn22
    456 endfunc
    457 
    458 " Test for ":emenu" command in different modes
    459 func Test_emenu_cmd()
    460  new
    461  xmenu Test.foo rx
    462  call setline(1, ['aaaa', 'bbbb'])
    463  normal ggVj
    464  %emenu Test.foo
    465  call assert_equal(['xxxx', 'xxxx'], getline(1, 2))
    466  call setline(1, ['aaaa', 'bbbb'])
    467  exe "normal ggVj\<Esc>"
    468  %emenu Test.foo
    469  call assert_equal(['xxxx', 'xxxx'], getline(1, 2))
    470  call setline(1, ['aaaa', 'bbbb'])
    471  exe "normal ggV\<Esc>"
    472  2emenu Test.foo
    473  call assert_equal(['aaaa', 'xxxx'], getline(1, 2))
    474  xunmenu Test.foo
    475  bw!
    476 endfunc
    477 
    478 " Test for PopUp menus
    479 func Test_popup_menu()
    480  20menu PopUp.foo :echo 'foo'<CR>
    481  20menu PopUp.bar :echo 'bar'<CR>
    482  call assert_equal(#{name: 'PopUp', display: 'PopUp', priority: 20,
    483        \ shortcut: '', modes: ' ', submenus: ['foo', 'bar']},
    484        \ menu_info('PopUp'))
    485  menu disable PopUp.bar
    486  call assert_equal(v:true, "PopUp.foo"->menu_info().enabled)
    487  call assert_equal(v:false, "PopUp.bar"->menu_info().enabled)
    488  menu enable PopUp.bar
    489  call assert_equal(v:true, "PopUp.bar"->menu_info().enabled)
    490  unmenu PopUp
    491 endfunc
    492 
    493 func Test_popup_menu_truncated()
    494  CheckNotGui
    495 
    496  set mouse=a mousemodel=popup
    497  aunmenu PopUp
    498  for i in range(2 * &lines)
    499    exe $'menu PopUp.{i} <Cmd>let g:res = {i}<CR>'
    500  endfor
    501 
    502  func LeftClickExpr(row, col)
    503    call Ntest_setmouse(a:row, a:col)
    504    return "\<LeftMouse>"
    505  endfunc
    506 
    507  " Clicking at the bottom should place popup menu above click position.
    508  " <RightRelease> should not select an item immediately.
    509  let g:res = -1
    510  call Ntest_setmouse(&lines, 1)
    511  nnoremap <expr><F2> LeftClickExpr(4, 1)
    512  call feedkeys("\<RightMouse>\<RightRelease>\<F2>", 'tx')
    513  call assert_equal(3, g:res)
    514 
    515  " Clicking at the top should place popup menu below click position.
    516  let g:res = -1
    517  call Ntest_setmouse(1, 1)
    518  nnoremap <expr><F2> LeftClickExpr(5, 1)
    519  call feedkeys("\<RightMouse>\<RightRelease>\<F2>", 'tx')
    520  call assert_equal(3, g:res)
    521 
    522  nunmap <F2>
    523  delfunc LeftClickExpr
    524  unlet g:res
    525  aunmenu PopUp
    526  set mouse& mousemodel&
    527 endfunc
    528 
    529 " Test for MenuPopup autocommand
    530 func Test_autocmd_MenuPopup()
    531  CheckNotGui
    532 
    533  set mouse=a mousemodel=popup
    534  aunmenu PopUp
    535  autocmd MenuPopup * exe printf(
    536    \ 'anoremenu PopUp.Foo <Cmd>let g:res = ["%s", "%s"]<CR>',
    537    \ expand('<afile>'), expand('<amatch>'))
    538 
    539  call feedkeys("\<RightMouse>\<Down>\<CR>", 'tnix')
    540  call assert_equal(['n', 'n'], g:res)
    541 
    542  call feedkeys("v\<RightMouse>\<Down>\<CR>\<Esc>", 'tnix')
    543  call assert_equal(['v', 'v'], g:res)
    544 
    545  call feedkeys("gh\<RightMouse>\<Down>\<CR>\<Esc>", 'tnix')
    546  call assert_equal(['s', 's'], g:res)
    547 
    548  call feedkeys("i\<RightMouse>\<Down>\<CR>\<Esc>", 'tnix')
    549  call assert_equal(['i', 'i'], g:res)
    550 
    551  autocmd! MenuPopup
    552  aunmenu PopUp.Foo
    553  unlet g:res
    554  set mouse& mousemodel&
    555 endfunc
    556 
    557 " Test for listing the menus using the :menu command
    558 func Test_show_menus()
    559  " In the GUI, tear-off menu items are present in the output below
    560  " So skip this test
    561  CheckNotGui
    562  aunmenu *
    563  call assert_equal(['--- Menus ---'], split(execute('menu'), "\n"))
    564  nmenu <script> 200.10 Test.nmenu1 :nmenu1<CR>
    565  nmenu 200.20 Test.nmenu2 :nmenu2<CR>
    566  nnoremenu 200.30 Test.nmenu3 :nmenu3<CR>
    567  nmenu 200.40 Test.nmenu4 :nmenu4<CR>
    568  nmenu 200.50 disable Test.nmenu4
    569  let exp =<< trim [TEXT]
    570  --- Menus ---
    571  200 Test
    572    10 nmenu1
    573        n&   :nmenu1<CR>
    574    20 nmenu2
    575        n    :nmenu2<CR>
    576    30 nmenu3
    577        n*   :nmenu3<CR>
    578    40 nmenu4
    579        n  - :nmenu4<CR>
    580  [TEXT]
    581  call assert_equal(exp, split(execute('nmenu'), "\n"))
    582  nunmenu Test
    583 endfunc
    584 
    585 " Test for menu tips
    586 func Test_tmenu()
    587  tunmenu *
    588  call assert_equal(['--- Menus ---'], split(execute('tmenu'), "\n"))
    589  tmenu Test.nmenu1 nmenu1
    590  tmenu Test.nmenu2.sub1 nmenu2.sub1
    591  let exp =<< trim [TEXT]
    592  --- Menus ---
    593  500 Test
    594    500 nmenu1
    595        t  - nmenu1
    596    500 nmenu2
    597      500 sub1
    598          t  - nmenu2.sub1
    599  [TEXT]
    600  call assert_equal(exp, split(execute('tmenu'), "\n"))
    601  tunmenu Test
    602 endfunc
    603 
    604 func Test_only_modifier()
    605  exe "tmenu a.b \x80\xfc0"
    606  let exp =<< trim [TEXT]
    607  --- Menus ---
    608  500 a
    609    500 b
    610        t  - <T-2-^@>
    611  [TEXT]
    612  call assert_equal(exp, split(execute('tmenu'), "\n"))
    613 
    614  tunmenu a.b
    615 endfunc
    616 
    617 func Test_unmenu_while_listing_menus()
    618  CheckRunVimInTerminal
    619 
    620  let lines =<< trim END
    621      set nocompatible
    622      unmenu *
    623      for i in range(1, 999)
    624        exe 'menu ' .. 'foo.' .. i .. ' bar'
    625      endfor
    626      au CmdlineLeave : call timer_start(0, {-> execute('unmenu *')})
    627  END
    628  call writefile(lines, 'Xmenuclear', 'D')
    629  let buf = RunVimInTerminal('-S Xmenuclear', {'rows': 10})
    630 
    631  " this was using freed memory
    632  call term_sendkeys(buf, ":menu\<CR>")
    633  call TermWait(buf, 50)
    634  call term_sendkeys(buf, "G")
    635  call TermWait(buf, 50)
    636  call term_sendkeys(buf, "\<CR>")
    637 
    638  call StopVimInTerminal(buf)
    639 endfunc
    640 
    641 " Test for opening a menu drawn in the cmdline area
    642 func Test_popupmenu_cmdline()
    643  CheckScreendump
    644  CheckRunVimInTerminal
    645 
    646  let lines =<< trim END
    647    set mousemodel=popup
    648    menu PopUp.Test1 :<CR>
    649    menu PopUp.Test2 :<CR>
    650    menu PopUp.Test3 :<CR>
    651    call setline(1, repeat(['abcde'], 5))
    652  END
    653  call writefile(lines, 'Xpopupcmdline', 'D')
    654  let buf = RunVimInTerminal('-S Xpopupcmdline', {'rows': 4})
    655 
    656  " cmdline area should be cleared when popupmenu that covered it is closed
    657  call term_sendkeys(buf, "\<RightMouse>\<RightRelease>\<Esc>")
    658  call VerifyScreenDump(buf, 'Test_popupmenu_cmdline_1', {})
    659 
    660  call StopVimInTerminal(buf)
    661 endfunc
    662 
    663 " vim: shiftwidth=2 sts=2 expandtab