diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/nvim/ex_cmds.lua | 551 | ||||
| -rw-r--r-- | src/nvim/ex_cmds2.c | 36 | ||||
| -rw-r--r-- | src/nvim/ex_cmds_defs.h | 10 | ||||
| -rw-r--r-- | src/nvim/ex_docmd.c | 681 | ||||
| -rw-r--r-- | src/nvim/ex_getln.c | 1 | ||||
| -rw-r--r-- | src/nvim/testdir/Makefile | 6 | ||||
| -rw-r--r-- | src/nvim/testdir/test62.in | 2 | ||||
| -rw-r--r-- | src/nvim/testdir/test_argument_0count.in | 28 | ||||
| -rw-r--r-- | src/nvim/testdir/test_argument_0count.ok | 5 | ||||
| -rw-r--r-- | src/nvim/testdir/test_argument_count.in | 46 | ||||
| -rw-r--r-- | src/nvim/testdir/test_argument_count.ok | 13 | ||||
| -rw-r--r-- | src/nvim/testdir/test_close_count.in | 156 | ||||
| -rw-r--r-- | src/nvim/testdir/test_close_count.ok | 23 | ||||
| -rw-r--r-- | src/nvim/testdir/test_command_count.in | 157 | ||||
| -rw-r--r-- | src/nvim/testdir/test_command_count.ok | 38 | ||||
| -rw-r--r-- | src/nvim/version.c | 24 | ||||
| -rw-r--r-- | src/nvim/vim.h | 1 | ||||
| -rw-r--r-- | src/nvim/window.c | 24 | 
18 files changed, 1704 insertions, 98 deletions
| diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua index 52dc0d6212..5f60b8cb09 100644 --- a/src/nvim/ex_cmds.lua +++ b/src/nvim/ex_cmds.lua @@ -28,2635 +28,3166 @@ local FILES      = bit.bor(XFILE, EXTRA)  local WORD1      = bit.bor(EXTRA, NOSPC)  local FILE1      = bit.bor(FILES, NOSPC) +local ADDR_LINES            =  0 +local ADDR_WINDOWS          =  1 +local ADDR_ARGUMENTS        =  2 +local ADDR_LOADED_BUFFERS   =  3 +local ADDR_BUFFERS          =  4 +local ADDR_TABS             =  5 +  -- The following table is described in ex_cmds_defs.h file.  return {    {      command='append',      flags=bit.bor(BANG, RANGE, ZEROR, TRLBAR, CMDWIN, MODIFY), +    addr_type=ADDR_LINES,      func='ex_append',    },    {      command='abbreviate',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_abbreviate',    },    {      command='abclear',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_abclear',    },    {      command='aboveleft',      flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), +    addr_type=ADDR_LINES,      func='ex_wrongmodifier',    },    {      command='all',      flags=bit.bor(BANG, RANGE, NOTADR, COUNT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_all',    },    {      command='amenu',      flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='anoremenu',      flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='args',      flags=bit.bor(BANG, FILES, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_args',    },    {      command='argadd',      flags=bit.bor(BANG, NEEDARG, RANGE, NOTADR, ZEROR, FILES, TRLBAR), +    addr_type=ADDR_ARGUMENTS,      func='ex_argadd',    },    {      command='argdelete',      flags=bit.bor(BANG, RANGE, NOTADR, FILES, TRLBAR), +    addr_type=ADDR_ARGUMENTS,      func='ex_argdelete',    },    {      command='argdo', -    flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM), +    flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, NOTADR, DFLALL), +    addr_type=ADDR_ARGUMENTS,      func='ex_listdo',    },    {      command='argedit', -    flags=bit.bor(BANG, NEEDARG, RANGE, NOTADR, FILE1, EDITCMD, ARGOPT, TRLBAR), +    flags=bit.bor(BANG, NEEDARG, RANGE, NOTADR, ZEROR, FILE1, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_ARGUMENTS,      func='ex_argedit',    },    {      command='argglobal',      flags=bit.bor(BANG, FILES, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_args',    },    {      command='arglocal',      flags=bit.bor(BANG, FILES, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_args',    },    {      command='argument',      flags=bit.bor(BANG, RANGE, NOTADR, COUNT, EXTRA, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_ARGUMENTS,      func='ex_argument',    },    {      command='ascii',      flags=bit.bor(TRLBAR, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='do_ascii',    },    {      command='autocmd',      flags=bit.bor(BANG, EXTRA, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_autocmd',    },    {      command='augroup',      flags=bit.bor(BANG, WORD1, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_autocmd',    },    {      command='aunmenu',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='buffer',      flags=bit.bor(BANG, RANGE, NOTADR, BUFNAME, BUFUNL, COUNT, EXTRA, EDITCMD, TRLBAR), +    addr_type=ADDR_BUFFERS,      func='ex_buffer',    },    {      command='bNext',      flags=bit.bor(BANG, RANGE, NOTADR, COUNT, EDITCMD, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_bprevious',    },    {      command='ball',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_buffer_all',    },    {      command='badd',      flags=bit.bor(NEEDARG, FILE1, EDITCMD, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_edit',    },    {      command='bdelete',      flags=bit.bor(BANG, RANGE, NOTADR, BUFNAME, COUNT, EXTRA, TRLBAR), +    addr_type=ADDR_BUFFERS,      func='ex_bunload',    },    {      command='behave',      flags=bit.bor(NEEDARG, WORD1, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_behave',    },    {      command='belowright',      flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), +    addr_type=ADDR_LINES,      func='ex_wrongmodifier',    },    {      command='bfirst',      flags=bit.bor(BANG, RANGE, NOTADR, EDITCMD, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_brewind',    },    {      command='blast',      flags=bit.bor(BANG, RANGE, NOTADR, EDITCMD, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_blast',    },    {      command='bmodified',      flags=bit.bor(BANG, RANGE, NOTADR, COUNT, EDITCMD, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_bmodified',    },    {      command='bnext',      flags=bit.bor(BANG, RANGE, NOTADR, COUNT, EDITCMD, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_bnext',    },    {      command='botright',      flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), +    addr_type=ADDR_LINES,      func='ex_wrongmodifier',    },    {      command='bprevious',      flags=bit.bor(BANG, RANGE, NOTADR, COUNT, EDITCMD, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_bprevious',    },    {      command='brewind',      flags=bit.bor(BANG, RANGE, NOTADR, EDITCMD, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_brewind',    },    {      command='break',      flags=bit.bor(TRLBAR, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_break',    },    {      command='breakadd',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_breakadd',    },    {      command='breakdel',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_breakdel',    },    {      command='breaklist',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_breaklist',    },    {      command='browse',      flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_wrongmodifier',    },    {      command='buffers',      flags=bit.bor(BANG, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='buflist_list',    },    {      command='bufdo', -    flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM), +    flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, NOTADR, DFLALL), +    addr_type=ADDR_BUFFERS,      func='ex_listdo',    },    {      command='bunload',      flags=bit.bor(BANG, RANGE, NOTADR, BUFNAME, COUNT, EXTRA, TRLBAR), +    addr_type=ADDR_LOADED_BUFFERS,      func='ex_bunload',    },    {      command='bwipeout',      flags=bit.bor(BANG, RANGE, NOTADR, BUFNAME, BUFUNL, COUNT, EXTRA, TRLBAR), +    addr_type=ADDR_BUFFERS,      func='ex_bunload',    },    {      command='change',      flags=bit.bor(BANG, WHOLEFOLD, RANGE, COUNT, TRLBAR, CMDWIN, MODIFY), +    addr_type=ADDR_LINES,      func='ex_change',    },    {      command='cNext',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR, BANG), +    addr_type=ADDR_LINES,      func='ex_cnext',    },    {      command='cNfile',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR, BANG), +    addr_type=ADDR_LINES,      func='ex_cnext',    },    {      command='cabbrev',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_abbreviate',    },    {      command='cabclear',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_abclear',    },    {      command='caddbuffer',      flags=bit.bor(RANGE, NOTADR, WORD1, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_cbuffer',    },    {      command='caddexpr',      flags=bit.bor(NEEDARG, WORD1, NOTRLCOM, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_cexpr',    },    {      command='caddfile',      flags=bit.bor(TRLBAR, FILE1), +    addr_type=ADDR_LINES,      func='ex_cfile',    },    {      command='call',      flags=bit.bor(RANGE, NEEDARG, EXTRA, NOTRLCOM, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_call',    },    {      command='catch',      flags=bit.bor(EXTRA, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_catch',    },    {      command='cbuffer',      flags=bit.bor(BANG, RANGE, NOTADR, WORD1, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_cbuffer',    },    {      command='cc',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR, BANG), +    addr_type=ADDR_LINES,      func='ex_cc',    },    {      command='cclose',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_cclose',    },    {      command='cd',      flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_cd',    },    {      command='center',      flags=bit.bor(TRLBAR, RANGE, WHOLEFOLD, EXTRA, CMDWIN, MODIFY), +    addr_type=ADDR_LINES,      func='ex_align',    },    {      command='cexpr',      flags=bit.bor(NEEDARG, WORD1, NOTRLCOM, TRLBAR, BANG), +    addr_type=ADDR_LINES,      func='ex_cexpr',    },    {      command='cfile',      flags=bit.bor(TRLBAR, FILE1, BANG), +    addr_type=ADDR_LINES,      func='ex_cfile',    },    {      command='cfirst',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR, BANG), +    addr_type=ADDR_LINES,      func='ex_cc',    },    {      command='cgetfile',      flags=bit.bor(TRLBAR, FILE1), +    addr_type=ADDR_LINES,      func='ex_cfile',    },    {      command='cgetbuffer',      flags=bit.bor(RANGE, NOTADR, WORD1, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_cbuffer',    },    {      command='cgetexpr',      flags=bit.bor(NEEDARG, WORD1, NOTRLCOM, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_cexpr',    },    {      command='chdir',      flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_cd',    },    {      command='changes',      flags=bit.bor(TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_changes',    },    {      command='checkpath',      flags=bit.bor(TRLBAR, BANG, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_checkpath',    },    {      command='checktime',      flags=bit.bor(RANGE, NOTADR, BUFNAME, COUNT, EXTRA, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_checktime',    },    {      command='clist',      flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='qf_list',    },    {      command='clast',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR, BANG), +    addr_type=ADDR_LINES,      func='ex_cc',    },    {      command='close', -    flags=bit.bor(BANG, TRLBAR, CMDWIN), +    flags=bit.bor(BANG, RANGE, NOTADR, COUNT, TRLBAR, CMDWIN), +    addr_type=ADDR_WINDOWS,      func='ex_close',    },    {      command='cmap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_map',    },    {      command='cmapclear',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_mapclear',    },    {      command='cmenu',      flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='cnext',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR, BANG), +    addr_type=ADDR_LINES,      func='ex_cnext',    },    {      command='cnewer',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), +    addr_type=ADDR_LINES,      func='qf_age',    },    {      command='cnfile',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR, BANG), +    addr_type=ADDR_LINES,      func='ex_cnext',    },    {      command='cnoremap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_map',    },    {      command='cnoreabbrev',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_abbreviate',    },    {      command='cnoremenu',      flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='copy',      flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, TRLBAR, CMDWIN, MODIFY), +    addr_type=ADDR_LINES,      func='ex_copymove',    },    {      command='colder',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), +    addr_type=ADDR_LINES,      func='qf_age',    },    {      command='colorscheme',      flags=bit.bor(WORD1, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_colorscheme',    },    {      command='command',      flags=bit.bor(EXTRA, BANG, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_command',    },    {      command='comclear',      flags=bit.bor(TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_comclear',    },    {      command='compiler',      flags=bit.bor(BANG, TRLBAR, WORD1, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_compiler',    },    {      command='continue',      flags=bit.bor(TRLBAR, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_continue',    },    {      command='confirm',      flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_wrongmodifier',    },    {      command='copen',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_copen',    },    {      command='cprevious',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR, BANG), +    addr_type=ADDR_LINES,      func='ex_cnext',    },    {      command='cpfile',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR, BANG), +    addr_type=ADDR_LINES,      func='ex_cnext',    },    {      command='cquit',      flags=bit.bor(TRLBAR, BANG), +    addr_type=ADDR_LINES,      func='ex_cquit',    },    {      command='crewind',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR, BANG), +    addr_type=ADDR_LINES,      func='ex_cc',    },    {      command='cscope',      flags=bit.bor(EXTRA, NOTRLCOM, XFILE), +    addr_type=ADDR_LINES,      func='do_cscope',    },    {      command='cstag',      flags=bit.bor(BANG, TRLBAR, WORD1), +    addr_type=ADDR_LINES,      func='do_cstag',    },    {      command='cunmap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_unmap',    },    {      command='cunabbrev',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_abbreviate',    },    {      command='cunmenu',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='cwindow',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_cwindow',    },    {      command='delete',      flags=bit.bor(RANGE, WHOLEFOLD, REGSTR, COUNT, TRLBAR, CMDWIN, MODIFY), +    addr_type=ADDR_LINES,      func='ex_operators',    },    {      command='delmarks',      flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_delmarks',    },    {      command='debug',      flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_debug',    },    {      command='debuggreedy',      flags=bit.bor(RANGE, NOTADR, ZEROR, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_debuggreedy',    },    {      command='delcommand',      flags=bit.bor(NEEDARG, WORD1, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_delcommand',    },    {      command='delfunction',      flags=bit.bor(NEEDARG, WORD1, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_delfunction',    },    {      command='display',      flags=bit.bor(EXTRA, NOTRLCOM, TRLBAR, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_display',    },    {      command='diffupdate',      flags=bit.bor(BANG, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_diffupdate',    },    {      command='diffget',      flags=bit.bor(RANGE, EXTRA, TRLBAR, MODIFY), +    addr_type=ADDR_LINES,      func='ex_diffgetput',    },    {      command='diffoff',      flags=bit.bor(BANG, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_diffoff',    },    {      command='diffpatch',      flags=bit.bor(EXTRA, FILE1, TRLBAR, MODIFY), +    addr_type=ADDR_LINES,      func='ex_diffpatch',    },    {      command='diffput',      flags=bit.bor(RANGE, EXTRA, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_diffgetput',    },    {      command='diffsplit',      flags=bit.bor(EXTRA, FILE1, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_diffsplit',    },    {      command='diffthis',      flags=bit.bor(TRLBAR), +    addr_type=ADDR_LINES,      func='ex_diffthis',    },    {      command='digraphs',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_digraphs',    },    {      command='djump',      flags=bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA), +    addr_type=ADDR_LINES,      func='ex_findpat',    },    {      command='dlist',      flags=bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_findpat',    },    {      command='doautocmd',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_doautocmd',    },    {      command='doautoall',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_doautoall',    },    {      command='drop',      flags=bit.bor(FILES, EDITCMD, NEEDARG, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_drop',    },    {      command='dsearch',      flags=bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_findpat',    },    {      command='dsplit',      flags=bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA), +    addr_type=ADDR_LINES,      func='ex_findpat',    },    {      command='edit',      flags=bit.bor(BANG, FILE1, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_edit',    },    {      command='earlier',      flags=bit.bor(TRLBAR, EXTRA, NOSPC, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_later',    },    {      command='echo',      flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_echo',    },    {      command='echoerr',      flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_execute',    },    {      command='echohl',      flags=bit.bor(EXTRA, TRLBAR, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_echohl',    },    {      command='echomsg',      flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_execute',    },    {      command='echon',      flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_echo',    },    {      command='else',      flags=bit.bor(TRLBAR, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_else',    },    {      command='elseif',      flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_else',    },    {      command='emenu',      flags=bit.bor(NEEDARG, EXTRA, TRLBAR, NOTRLCOM, RANGE, NOTADR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_emenu',    },    {      command='endif',      flags=bit.bor(TRLBAR, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_endif',    },    {      command='endfunction',      flags=bit.bor(TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_endfunction',    },    {      command='endfor',      flags=bit.bor(TRLBAR, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_endwhile',    },    {      command='endtry',      flags=bit.bor(TRLBAR, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_endtry',    },    {      command='endwhile',      flags=bit.bor(TRLBAR, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_endwhile',    },    {      command='enew',      flags=bit.bor(BANG, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_edit',    },    {      command='ex',      flags=bit.bor(BANG, FILE1, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_edit',    },    {      command='execute',      flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_execute',    },    {      command='exit',      flags=bit.bor(RANGE, WHOLEFOLD, BANG, FILE1, ARGOPT, DFLALL, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_exit',    },    {      command='exusage',      flags=bit.bor(TRLBAR), +    addr_type=ADDR_LINES,      func='ex_exusage',    },    {      command='file',      flags=bit.bor(RANGE, NOTADR, ZEROR, BANG, FILE1, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_file',    },    {      command='files',      flags=bit.bor(BANG, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='buflist_list',    },    {      command='filetype',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_filetype',    },    {      command='find',      flags=bit.bor(RANGE, NOTADR, BANG, FILE1, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_find',    },    {      command='finally',      flags=bit.bor(TRLBAR, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_finally',    },    {      command='finish',      flags=bit.bor(TRLBAR, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_finish',    },    {      command='first',      flags=bit.bor(EXTRA, BANG, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_rewind',    },    {      command='fold',      flags=bit.bor(RANGE, WHOLEFOLD, TRLBAR, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_fold',    },    {      command='foldclose',      flags=bit.bor(RANGE, BANG, WHOLEFOLD, TRLBAR, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_foldopen',    },    {      command='folddoopen',      flags=bit.bor(RANGE, DFLALL, NEEDARG, EXTRA, NOTRLCOM), +    addr_type=ADDR_LINES,      func='ex_folddo',    },    {      command='folddoclosed',      flags=bit.bor(RANGE, DFLALL, NEEDARG, EXTRA, NOTRLCOM), +    addr_type=ADDR_LINES,      func='ex_folddo',    },    {      command='foldopen',      flags=bit.bor(RANGE, BANG, WHOLEFOLD, TRLBAR, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_foldopen',    },    {      command='for',      flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_while',    },    {      command='function',      flags=bit.bor(EXTRA, BANG, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_function',    },    {      command='global',      flags=bit.bor(RANGE, WHOLEFOLD, BANG, EXTRA, DFLALL, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_global',    },    {      command='goto',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_goto',    },    {      command='grep',      flags=bit.bor(RANGE, NOTADR, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE), +    addr_type=ADDR_LINES,      func='ex_make',    },    {      command='grepadd',      flags=bit.bor(RANGE, NOTADR, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE), +    addr_type=ADDR_LINES,      func='ex_make',    },    {      command='gui',      flags=bit.bor(BANG, FILES, EDITCMD, ARGOPT, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_gui',    },    {      command='gvim',      flags=bit.bor(BANG, FILES, EDITCMD, ARGOPT, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_gui',    },    {      command='help',      flags=bit.bor(BANG, EXTRA, NOTRLCOM), +    addr_type=ADDR_LINES,      func='ex_help',    },    {      command='helpclose',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_helpclose',    },    {      command='helpfind',      flags=bit.bor(EXTRA, NOTRLCOM), +    addr_type=ADDR_LINES,      func='ex_helpfind',    },    {      command='helpgrep',      flags=bit.bor(EXTRA, NOTRLCOM, NEEDARG), +    addr_type=ADDR_LINES,      func='ex_helpgrep',    },    {      command='helptags',      flags=bit.bor(NEEDARG, FILES, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_helptags',    },    {      command='hardcopy',      flags=bit.bor(RANGE, COUNT, EXTRA, TRLBAR, DFLALL, BANG), +    addr_type=ADDR_LINES,      func='ex_hardcopy',    },    {      command='highlight',      flags=bit.bor(BANG, EXTRA, TRLBAR, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_highlight',    },    {      command='hide', -    flags=bit.bor(BANG, EXTRA, NOTRLCOM), +    flags=bit.bor(BANG, RANGE, NOTADR, COUNT, EXTRA, NOTRLCOM), +    addr_type=ADDR_WINDOWS,      func='ex_hide',    },    {      command='history',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_history',    },    {      command='insert',      flags=bit.bor(BANG, RANGE, TRLBAR, CMDWIN, MODIFY), +    addr_type=ADDR_LINES,      func='ex_append',    },    {      command='iabbrev',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_abbreviate',    },    {      command='iabclear',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_abclear',    },    {      command='if',      flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_if',    },    {      command='ijump',      flags=bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA), +    addr_type=ADDR_LINES,      func='ex_findpat',    },    {      command='ilist',      flags=bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_findpat',    },    {      command='imap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_map',    },    {      command='imapclear',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_mapclear',    },    {      command='imenu',      flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='inoremap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_map',    },    {      command='inoreabbrev',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_abbreviate',    },    {      command='inoremenu',      flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='intro',      flags=bit.bor(TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_intro',    },    {      command='isearch',      flags=bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_findpat',    },    {      command='isplit',      flags=bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA), +    addr_type=ADDR_LINES,      func='ex_findpat',    },    {      command='iunmap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_unmap',    },    {      command='iunabbrev',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_abbreviate',    },    {      command='iunmenu',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='join',      flags=bit.bor(BANG, RANGE, WHOLEFOLD, COUNT, EXFLAGS, TRLBAR, CMDWIN, MODIFY), +    addr_type=ADDR_LINES,      func='ex_join',    },    {      command='jumps',      flags=bit.bor(TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_jumps',    },    {      command='k',      flags=bit.bor(RANGE, WORD1, TRLBAR, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_mark',    },    {      command='keepmarks',      flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), +    addr_type=ADDR_LINES,      func='ex_wrongmodifier',    },    {      command='keepjumps',      flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), +    addr_type=ADDR_LINES,      func='ex_wrongmodifier',    },    {      command='keeppatterns',      flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), +    addr_type=ADDR_LINES,      func='ex_wrongmodifier',    },    {      command='keepalt',      flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), +    addr_type=ADDR_LINES,      func='ex_wrongmodifier',    },    {      command='list',      flags=bit.bor(RANGE, WHOLEFOLD, COUNT, EXFLAGS, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_print',    },    {      command='lNext',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR, BANG), +    addr_type=ADDR_LINES,      func='ex_cnext',    },    {      command='lNfile',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR, BANG), +    addr_type=ADDR_LINES,      func='ex_cnext',    },    {      command='last',      flags=bit.bor(EXTRA, BANG, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_last',    },    {      command='language',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_language',    },    {      command='laddexpr',      flags=bit.bor(NEEDARG, WORD1, NOTRLCOM, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_cexpr',    },    {      command='laddbuffer',      flags=bit.bor(RANGE, NOTADR, WORD1, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_cbuffer',    },    {      command='laddfile',      flags=bit.bor(TRLBAR, FILE1), +    addr_type=ADDR_LINES,      func='ex_cfile',    },    {      command='later',      flags=bit.bor(TRLBAR, EXTRA, NOSPC, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_later',    },    {      command='lbuffer',      flags=bit.bor(BANG, RANGE, NOTADR, WORD1, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_cbuffer',    },    {      command='lcd',      flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_cd',    },    {      command='lchdir',      flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_cd',    },    {      command='lclose',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_cclose',    },    {      command='lcscope',      flags=bit.bor(EXTRA, NOTRLCOM, XFILE), +    addr_type=ADDR_LINES,      func='do_cscope',    },    {      command='left',      flags=bit.bor(TRLBAR, RANGE, WHOLEFOLD, EXTRA, CMDWIN, MODIFY), +    addr_type=ADDR_LINES,      func='ex_align',    },    {      command='leftabove',      flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), +    addr_type=ADDR_LINES,      func='ex_wrongmodifier',    },    {      command='let',      flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_let',    },    {      command='lexpr',      flags=bit.bor(NEEDARG, WORD1, NOTRLCOM, TRLBAR, BANG), +    addr_type=ADDR_LINES,      func='ex_cexpr',    },    {      command='lfile',      flags=bit.bor(TRLBAR, FILE1, BANG), +    addr_type=ADDR_LINES,      func='ex_cfile',    },    {      command='lfirst',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR, BANG), +    addr_type=ADDR_LINES,      func='ex_cc',    },    {      command='lgetfile',      flags=bit.bor(TRLBAR, FILE1), +    addr_type=ADDR_LINES,      func='ex_cfile',    },    {      command='lgetbuffer',      flags=bit.bor(RANGE, NOTADR, WORD1, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_cbuffer',    },    {      command='lgetexpr',      flags=bit.bor(NEEDARG, WORD1, NOTRLCOM, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_cexpr',    },    {      command='lgrep',      flags=bit.bor(RANGE, NOTADR, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE), +    addr_type=ADDR_LINES,      func='ex_make',    },    {      command='lgrepadd',      flags=bit.bor(RANGE, NOTADR, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE), +    addr_type=ADDR_LINES,      func='ex_make',    },    {      command='lhelpgrep',      flags=bit.bor(EXTRA, NOTRLCOM, NEEDARG), +    addr_type=ADDR_LINES,      func='ex_helpgrep',    },    {      command='ll',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR, BANG), +    addr_type=ADDR_LINES,      func='ex_cc',    },    {      command='llast',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR, BANG), +    addr_type=ADDR_LINES,      func='ex_cc',    },    {      command='llist',      flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='qf_list',    },    {      command='lmap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_map',    },    {      command='lmapclear',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_mapclear',    },    {      command='lmake',      flags=bit.bor(BANG, EXTRA, NOTRLCOM, TRLBAR, XFILE), +    addr_type=ADDR_LINES,      func='ex_make',    },    {      command='lnoremap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_map',    },    {      command='lnext',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR, BANG), +    addr_type=ADDR_LINES,      func='ex_cnext',    },    {      command='lnewer',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), +    addr_type=ADDR_LINES,      func='qf_age',    },    {      command='lnfile',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR, BANG), +    addr_type=ADDR_LINES,      func='ex_cnext',    },    {      command='loadview',      flags=bit.bor(FILE1, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_loadview',    },    {      command='loadkeymap',      flags=bit.bor(CMDWIN), +    addr_type=ADDR_LINES,      func='ex_loadkeymap',    },    {      command='lockmarks',      flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), +    addr_type=ADDR_LINES,      func='ex_wrongmodifier',    },    {      command='lockvar',      flags=bit.bor(BANG, EXTRA, NEEDARG, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_lockvar',    },    {      command='lolder',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), +    addr_type=ADDR_LINES,      func='qf_age',    },    {      command='lopen',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_copen',    },    {      command='lprevious',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR, BANG), +    addr_type=ADDR_LINES,      func='ex_cnext',    },    {      command='lpfile',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR, BANG), +    addr_type=ADDR_LINES,      func='ex_cnext',    },    {      command='lrewind',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR, BANG), +    addr_type=ADDR_LINES,      func='ex_cc',    },    {      command='ltag',      flags=bit.bor(NOTADR, TRLBAR, BANG, WORD1), +    addr_type=ADDR_LINES,      func='ex_tag',    },    {      command='lunmap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_unmap',    },    {      command='lua',      flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_script_ni',    },    {      command='luado',      flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_ni',    },    {      command='luafile',      flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_ni',    },    {      command='lvimgrep',      flags=bit.bor(RANGE, NOTADR, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE), +    addr_type=ADDR_LINES,      func='ex_vimgrep',    },    {      command='lvimgrepadd',      flags=bit.bor(RANGE, NOTADR, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE), +    addr_type=ADDR_LINES,      func='ex_vimgrep',    },    {      command='lwindow',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_cwindow',    },    {      command='ls',      flags=bit.bor(BANG, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='buflist_list',    },    {      command='move',      flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, TRLBAR, CMDWIN, MODIFY), +    addr_type=ADDR_LINES,      func='ex_copymove',    },    {      command='mark',      flags=bit.bor(RANGE, WORD1, TRLBAR, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_mark',    },    {      command='make',      flags=bit.bor(BANG, EXTRA, NOTRLCOM, TRLBAR, XFILE), +    addr_type=ADDR_LINES,      func='ex_make',    },    {      command='map',      flags=bit.bor(BANG, EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_map',    },    {      command='mapclear',      flags=bit.bor(EXTRA, BANG, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_mapclear',    },    {      command='marks',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='do_marks',    },    {      command='match',      flags=bit.bor(RANGE, NOTADR, EXTRA, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_match',    },    {      command='menu',      flags=bit.bor(RANGE, NOTADR, ZEROR, BANG, EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='menutranslate',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menutranslate',    },    {      command='messages',      flags=bit.bor(TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_messages',    },    {      command='mkexrc',      flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_mkrc',    },    {      command='mksession',      flags=bit.bor(BANG, FILE1, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_mkrc',    },    {      command='mkspell',      flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE), +    addr_type=ADDR_LINES,      func='ex_mkspell',    },    {      command='mkvimrc',      flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_mkrc',    },    {      command='mkview',      flags=bit.bor(BANG, FILE1, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_mkrc',    },    {      command='mode',      flags=bit.bor(WORD1, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_mode',    },    {      command='mzscheme',      flags=bit.bor(RANGE, EXTRA, DFLALL, NEEDARG, CMDWIN, SBOXOK), +    addr_type=ADDR_LINES,      func='ex_script_ni',    },    {      command='mzfile',      flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_ni',    },    {      command='next',      flags=bit.bor(RANGE, NOTADR, BANG, FILES, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_next',    },    {      command='nbkey',      flags=bit.bor(EXTRA, NOTADR, NEEDARG), +    addr_type=ADDR_LINES,      func='ex_nbkey',    },    {      command='nbclose',      flags=bit.bor(TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_nbclose',    },    {      command='nbstart',      flags=bit.bor(WORD1, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_nbstart',    },    {      command='new',      flags=bit.bor(BANG, FILE1, RANGE, NOTADR, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_splitview',    },    {      command='nmap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_map',    },    {      command='nmapclear',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_mapclear',    },    {      command='nmenu',      flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='nnoremap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_map',    },    {      command='nnoremenu',      flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='noremap',      flags=bit.bor(BANG, EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_map',    },    {      command='noautocmd',      flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), +    addr_type=ADDR_LINES,      func='ex_wrongmodifier',    },    {      command='nohlsearch',      flags=bit.bor(TRLBAR, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_nohlsearch',    },    {      command='noreabbrev',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_abbreviate',    },    {      command='noremenu',      flags=bit.bor(RANGE, NOTADR, ZEROR, BANG, EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='noswapfile',      flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), +    addr_type=ADDR_LINES,      func='ex_wrongmodifier',    },    {      command='normal',      flags=bit.bor(RANGE, BANG, EXTRA, NEEDARG, NOTRLCOM, USECTRLV, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_normal',    },    {      command='number',      flags=bit.bor(RANGE, WHOLEFOLD, COUNT, EXFLAGS, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_print',    },    {      command='nunmap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_unmap',    },    {      command='nunmenu',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='open',      flags=bit.bor(RANGE, BANG, EXTRA), +    addr_type=ADDR_LINES,      func='ex_open',    },    {      command='oldfiles',      flags=bit.bor(BANG, TRLBAR, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_oldfiles',    },    {      command='omap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_map',    },    {      command='omapclear',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_mapclear',    },    {      command='omenu',      flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='only', -    flags=bit.bor(BANG, TRLBAR), +    flags=bit.bor(BANG, NOTADR, RANGE, COUNT, TRLBAR), +    addr_type=ADDR_WINDOWS,      func='ex_only',    },    {      command='onoremap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_map',    },    {      command='onoremenu',      flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='options',      flags=bit.bor(TRLBAR), +    addr_type=ADDR_LINES,      func='ex_options',    },    {      command='ounmap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_unmap',    },    {      command='ounmenu',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='ownsyntax',      flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_ownsyntax',    },    {      command='print',      flags=bit.bor(RANGE, WHOLEFOLD, COUNT, EXFLAGS, TRLBAR, CMDWIN, SBOXOK), +    addr_type=ADDR_LINES,      func='ex_print',    },    {      command='pclose',      flags=bit.bor(BANG, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_pclose',    },    {      command='perl',      flags=bit.bor(RANGE, EXTRA, DFLALL, NEEDARG, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_script_ni',    },    {      command='perldo',      flags=bit.bor(RANGE, EXTRA, DFLALL, NEEDARG, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_ni',    },    {      command='pedit',      flags=bit.bor(BANG, FILE1, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_pedit',    },    {      command='pop',      flags=bit.bor(RANGE, NOTADR, BANG, COUNT, TRLBAR, ZEROR), +    addr_type=ADDR_LINES,      func='ex_tag',    },    {      command='popup',      flags=bit.bor(NEEDARG, EXTRA, BANG, TRLBAR, NOTRLCOM, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_popup',    },    {      command='ppop',      flags=bit.bor(RANGE, NOTADR, BANG, COUNT, TRLBAR, ZEROR), +    addr_type=ADDR_LINES,      func='ex_ptag',    },    {      command='preserve',      flags=bit.bor(TRLBAR), +    addr_type=ADDR_LINES,      func='ex_preserve',    },    {      command='previous',      flags=bit.bor(EXTRA, RANGE, NOTADR, COUNT, BANG, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_previous',    },    {      command='promptfind',      flags=bit.bor(EXTRA, NOTRLCOM, CMDWIN), +    addr_type=ADDR_LINES,      func='gui_mch_find_dialog',    },    {      command='promptrepl',      flags=bit.bor(EXTRA, NOTRLCOM, CMDWIN), +    addr_type=ADDR_LINES,      func='gui_mch_replace_dialog',    },    {      command='profile',      flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_profile',    },    {      command='profdel',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_breakdel',    },    {      command='psearch',      flags=bit.bor(BANG, RANGE, WHOLEFOLD, DFLALL, EXTRA), +    addr_type=ADDR_LINES,      func='ex_psearch',    },    {      command='ptag',      flags=bit.bor(RANGE, NOTADR, BANG, WORD1, TRLBAR, ZEROR), +    addr_type=ADDR_LINES,      func='ex_ptag',    },    {      command='ptNext',      flags=bit.bor(RANGE, NOTADR, BANG, TRLBAR, ZEROR), +    addr_type=ADDR_LINES,      func='ex_ptag',    },    {      command='ptfirst',      flags=bit.bor(RANGE, NOTADR, BANG, TRLBAR, ZEROR), +    addr_type=ADDR_LINES,      func='ex_ptag',    },    {      command='ptjump',      flags=bit.bor(BANG, TRLBAR, WORD1), +    addr_type=ADDR_LINES,      func='ex_ptag',    },    {      command='ptlast',      flags=bit.bor(BANG, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_ptag',    },    {      command='ptnext',      flags=bit.bor(RANGE, NOTADR, BANG, TRLBAR, ZEROR), +    addr_type=ADDR_LINES,      func='ex_ptag',    },    {      command='ptprevious',      flags=bit.bor(RANGE, NOTADR, BANG, TRLBAR, ZEROR), +    addr_type=ADDR_LINES,      func='ex_ptag',    },    {      command='ptrewind',      flags=bit.bor(RANGE, NOTADR, BANG, TRLBAR, ZEROR), +    addr_type=ADDR_LINES,      func='ex_ptag',    },    {      command='ptselect',      flags=bit.bor(BANG, TRLBAR, WORD1), +    addr_type=ADDR_LINES,      func='ex_ptag',    },    {      command='put',      flags=bit.bor(RANGE, WHOLEFOLD, BANG, REGSTR, TRLBAR, ZEROR, CMDWIN, MODIFY), +    addr_type=ADDR_LINES,      func='ex_put',    },    {      command='pwd',      flags=bit.bor(TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_pwd',    },    {      command='python',      flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_python',    },    {      command='pydo',      flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_pydo',    },    {      command='pyfile',      flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_pyfile',    },    {      command='py3',      flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_python3',    },    {      command='py3do',      flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_pydo3',    },    {      command='python3',      flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_python3',    },    {      command='py3file',      flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_py3file',    },    {      command='quit', -    flags=bit.bor(BANG, TRLBAR, CMDWIN), +    flags=bit.bor(BANG, RANGE, COUNT, NOTADR, TRLBAR, CMDWIN), +    addr_type=ADDR_WINDOWS,      func='ex_quit',    },    {      command='quitall',      flags=bit.bor(BANG, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_quit_all',    },    {      command='qall',      flags=bit.bor(BANG, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_quit_all',    },    {      command='read',      flags=bit.bor(BANG, RANGE, WHOLEFOLD, FILE1, ARGOPT, TRLBAR, ZEROR, CMDWIN, MODIFY), +    addr_type=ADDR_LINES,      func='ex_read',    },    {      command='recover',      flags=bit.bor(BANG, FILE1, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_recover',    },    {      command='redo',      flags=bit.bor(TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_redo',    },    {      command='redir',      flags=bit.bor(BANG, FILES, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_redir',    },    {      command='redraw',      flags=bit.bor(BANG, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_redraw',    },    {      command='redrawstatus',      flags=bit.bor(BANG, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_redrawstatus',    },    {      command='registers',      flags=bit.bor(EXTRA, NOTRLCOM, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_display',    },    {      command='resize',      flags=bit.bor(RANGE, NOTADR, TRLBAR, WORD1), +    addr_type=ADDR_LINES,      func='ex_resize',    },    {      command='retab',      flags=bit.bor(TRLBAR, RANGE, WHOLEFOLD, DFLALL, BANG, WORD1, CMDWIN, MODIFY), +    addr_type=ADDR_LINES,      func='ex_retab',    },    {      command='return',      flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_return',    },    {      command='rewind',      flags=bit.bor(EXTRA, BANG, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_rewind',    },    {      command='right',      flags=bit.bor(TRLBAR, RANGE, WHOLEFOLD, EXTRA, CMDWIN, MODIFY), +    addr_type=ADDR_LINES,      func='ex_align',    },    {      command='rightbelow',      flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), +    addr_type=ADDR_LINES,      func='ex_wrongmodifier',    },    {      command='runtime',      flags=bit.bor(BANG, NEEDARG, FILES, TRLBAR, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_runtime',    },    {      command='rundo',      flags=bit.bor(NEEDARG, FILE1), +    addr_type=ADDR_LINES,      func='ex_rundo',    },    {      command='ruby',      flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_script_ni',    },    {      command='rubydo',      flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_ni',    },    {      command='rubyfile',      flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_ni',    },    {      command='rviminfo',      flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_viminfo',    },    {      command='substitute',      flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN), +    addr_type=ADDR_LINES,      func='do_sub',    },    {      command='sNext',      flags=bit.bor(EXTRA, RANGE, NOTADR, COUNT, BANG, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_previous',    },    {      command='sargument',      flags=bit.bor(BANG, RANGE, NOTADR, COUNT, EXTRA, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_ARGUMENTS,      func='ex_argument',    },    {      command='sall',      flags=bit.bor(BANG, RANGE, NOTADR, COUNT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_all',    },    {      command='sandbox',      flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), +    addr_type=ADDR_LINES,      func='ex_wrongmodifier',    },    {      command='saveas',      flags=bit.bor(BANG, DFLALL, FILE1, ARGOPT, CMDWIN, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_write',    },    {      command='sbuffer',      flags=bit.bor(BANG, RANGE, NOTADR, BUFNAME, BUFUNL, COUNT, EXTRA, EDITCMD, TRLBAR), +    addr_type=ADDR_BUFFERS,      func='ex_buffer',    },    {      command='sbNext',      flags=bit.bor(RANGE, NOTADR, COUNT, EDITCMD, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_bprevious',    },    {      command='sball',      flags=bit.bor(RANGE, NOTADR, COUNT, EDITCMD, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_buffer_all',    },    {      command='sbfirst',      flags=bit.bor(EDITCMD, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_brewind',    },    {      command='sblast',      flags=bit.bor(EDITCMD, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_blast',    },    {      command='sbmodified',      flags=bit.bor(RANGE, NOTADR, COUNT, EDITCMD, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_bmodified',    },    {      command='sbnext',      flags=bit.bor(RANGE, NOTADR, COUNT, EDITCMD, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_bnext',    },    {      command='sbprevious',      flags=bit.bor(RANGE, NOTADR, COUNT, EDITCMD, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_bprevious',    },    {      command='sbrewind',      flags=bit.bor(EDITCMD, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_brewind',    },    {      command='scriptnames',      flags=bit.bor(TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_scriptnames',    },    {      command='scriptencoding',      flags=bit.bor(WORD1, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_scriptencoding',    },    {      command='scscope',      flags=bit.bor(EXTRA, NOTRLCOM), +    addr_type=ADDR_LINES,      func='do_scscope',    },    {      command='set',      flags=bit.bor(TRLBAR, EXTRA, CMDWIN, SBOXOK), +    addr_type=ADDR_LINES,      func='ex_set',    },    {      command='setfiletype',      flags=bit.bor(TRLBAR, EXTRA, NEEDARG, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_setfiletype',    },    {      command='setglobal',      flags=bit.bor(TRLBAR, EXTRA, CMDWIN, SBOXOK), +    addr_type=ADDR_LINES,      func='ex_set',    },    {      command='setlocal',      flags=bit.bor(TRLBAR, EXTRA, CMDWIN, SBOXOK), +    addr_type=ADDR_LINES,      func='ex_set',    },    {      command='sfind',      flags=bit.bor(BANG, FILE1, RANGE, NOTADR, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_splitview',    },    {      command='sfirst',      flags=bit.bor(EXTRA, BANG, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_rewind',    },    {      command='simalt',      flags=bit.bor(NEEDARG, WORD1, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_simalt',    },    {      command='sign',      flags=bit.bor(NEEDARG, RANGE, NOTADR, EXTRA, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_sign',    },    {      command='silent',      flags=bit.bor(NEEDARG, EXTRA, BANG, NOTRLCOM, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_wrongmodifier',    },    {      command='sleep',      flags=bit.bor(RANGE, NOTADR, COUNT, EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_sleep',    },    {      command='slast',      flags=bit.bor(EXTRA, BANG, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_last',    },    {      command='smagic',      flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_submagic',    },    {      command='smap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_map',    },    {      command='smapclear',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_mapclear',    },    {      command='smenu',      flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='snext',      flags=bit.bor(RANGE, NOTADR, BANG, FILES, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_next',    },    {      command='snomagic',      flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_submagic',    },    {      command='snoremap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_map',    },    {      command='snoremenu',      flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='source',      flags=bit.bor(BANG, FILE1, TRLBAR, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_source',    },    {      command='sort',      flags=bit.bor(RANGE, DFLALL, WHOLEFOLD, BANG, EXTRA, NOTRLCOM, MODIFY), +    addr_type=ADDR_LINES,      func='ex_sort',    },    {      command='split',      flags=bit.bor(BANG, FILE1, RANGE, NOTADR, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_splitview',    },    {      command='spellgood',      flags=bit.bor(BANG, RANGE, NOTADR, NEEDARG, EXTRA, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_spell',    },    {      command='spelldump',      flags=bit.bor(BANG, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_spelldump',    },    {      command='spellinfo',      flags=bit.bor(TRLBAR), +    addr_type=ADDR_LINES,      func='ex_spellinfo',    },    {      command='spellrepall',      flags=bit.bor(TRLBAR), +    addr_type=ADDR_LINES,      func='ex_spellrepall',    },    {      command='spellundo',      flags=bit.bor(BANG, RANGE, NOTADR, NEEDARG, EXTRA, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_spell',    },    {      command='spellwrong',      flags=bit.bor(BANG, RANGE, NOTADR, NEEDARG, EXTRA, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_spell',    },    {      command='sprevious',      flags=bit.bor(EXTRA, RANGE, NOTADR, COUNT, BANG, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_previous',    },    {      command='srewind',      flags=bit.bor(EXTRA, BANG, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_rewind',    },    {      command='stop',      flags=bit.bor(TRLBAR, BANG, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_stop',    },    {      command='stag',      flags=bit.bor(RANGE, NOTADR, BANG, WORD1, TRLBAR, ZEROR), +    addr_type=ADDR_LINES,      func='ex_stag',    },    {      command='startinsert',      flags=bit.bor(BANG, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_startinsert',    },    {      command='startgreplace',      flags=bit.bor(BANG, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_startinsert',    },    {      command='startreplace',      flags=bit.bor(BANG, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_startinsert',    },    {      command='stopinsert',      flags=bit.bor(BANG, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_stopinsert',    },    {      command='stjump',      flags=bit.bor(BANG, TRLBAR, WORD1), +    addr_type=ADDR_LINES,      func='ex_stag',    },    {      command='stselect',      flags=bit.bor(BANG, TRLBAR, WORD1), +    addr_type=ADDR_LINES,      func='ex_stag',    },    {      command='sunhide',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_buffer_all',    },    {      command='sunmap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_unmap',    },    {      command='sunmenu',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='suspend',      flags=bit.bor(TRLBAR, BANG, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_stop',    },    {      command='sview',      flags=bit.bor(BANG, FILE1, RANGE, NOTADR, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_splitview',    },    {      command='swapname',      flags=bit.bor(TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_swapname',    },    {      command='syntax',      flags=bit.bor(EXTRA, NOTRLCOM, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_syntax',    },    {      command='syntime',      flags=bit.bor(NEEDARG, WORD1, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_syntime',    },    {      command='syncbind',      flags=bit.bor(TRLBAR), +    addr_type=ADDR_LINES,      func='ex_syncbind',    },    {      command='t',      flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, TRLBAR, CMDWIN, MODIFY), +    addr_type=ADDR_LINES,      func='ex_copymove',    },    {      command='tNext',      flags=bit.bor(RANGE, NOTADR, BANG, TRLBAR, ZEROR), +    addr_type=ADDR_LINES,      func='ex_tag',    },    {      command='tag',      flags=bit.bor(RANGE, NOTADR, BANG, WORD1, TRLBAR, ZEROR), +    addr_type=ADDR_LINES,      func='ex_tag',    },    {      command='tags',      flags=bit.bor(TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='do_tags',    },    {      command='tab',      flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), +    addr_type=ADDR_LINES,      func='ex_wrongmodifier',    },    {      command='tabclose',      flags=bit.bor(RANGE, NOTADR, COUNT, BANG, TRLBAR, CMDWIN), +    addr_type=ADDR_TABS,      func='ex_tabclose',    },    {      command='tabdo', -    flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), +    flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM, RANGE, NOTADR, DFLALL), +    addr_type=ADDR_TABS,      func='ex_listdo',    },    {      command='tabedit',      flags=bit.bor(BANG, FILE1, RANGE, NOTADR, ZEROR, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_TABS,      func='ex_splitview',    },    {      command='tabfind',      flags=bit.bor(BANG, FILE1, RANGE, NOTADR, ZEROR, EDITCMD, ARGOPT, NEEDARG, TRLBAR), +    addr_type=ADDR_TABS,      func='ex_splitview',    },    {      command='tabfirst',      flags=bit.bor(TRLBAR), +    addr_type=ADDR_LINES,      func='ex_tabnext',    },    {      command='tabmove',      flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, NOSPC, TRLBAR), +    addr_type=ADDR_TABS,      func='ex_tabmove',    },    {      command='tablast',      flags=bit.bor(TRLBAR), +    addr_type=ADDR_LINES,      func='ex_tabnext',    },    {      command='tabnext',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_tabnext',    },    {      command='tabnew',      flags=bit.bor(BANG, FILE1, RANGE, NOTADR, ZEROR, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_TABS,      func='ex_splitview',    },    {      command='tabonly', -    flags=bit.bor(BANG, TRLBAR, CMDWIN), +    flags=bit.bor(BANG, RANGE, NOTADR, TRLBAR, CMDWIN), +    addr_type=ADDR_TABS,      func='ex_tabonly',    },    {      command='tabprevious',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_tabnext',    },    {      command='tabNext',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_tabnext',    },    {      command='tabrewind',      flags=bit.bor(TRLBAR), +    addr_type=ADDR_LINES,      func='ex_tabnext',    },    {      command='tabs',      flags=bit.bor(TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_tabs',    },    {      command='tcl',      flags=bit.bor(RANGE,EXTRA,NEEDARG,CMDWIN), +    addr_type=ADDR_LINES,      func='ex_script_ni',    },    {      command='tcldo',      flags=bit.bor(RANGE,DFLALL,EXTRA,NEEDARG,CMDWIN), +    addr_type=ADDR_LINES,      func='ex_ni',    },    {      command='tclfile',      flags=bit.bor(RANGE,FILE1,NEEDARG,CMDWIN), +    addr_type=ADDR_LINES,      func='ex_ni',    },    {      command='tearoff',      flags=bit.bor(NEEDARG, EXTRA, TRLBAR, NOTRLCOM, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_tearoff',    },    {      command='terminal',      flags=bit.bor(BANG, FILES, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_terminal',    },    {      command='tfirst',      flags=bit.bor(RANGE, NOTADR, BANG, TRLBAR, ZEROR), +    addr_type=ADDR_LINES,      func='ex_tag',    },    {      command='throw',      flags=bit.bor(EXTRA, NEEDARG, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_throw',    },    {      command='tjump',      flags=bit.bor(BANG, TRLBAR, WORD1), +    addr_type=ADDR_LINES,      func='ex_tag',    },    {      command='tlast',      flags=bit.bor(BANG, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_tag',    },    {      command='tmap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_map',    },    {      command='tmapclear',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_mapclear',    },    {      command='tmenu',      flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='tnext',      flags=bit.bor(RANGE, NOTADR, BANG, TRLBAR, ZEROR), +    addr_type=ADDR_LINES,      func='ex_tag',    },    {      command='tnoremap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_map',    },    {      command='topleft',      flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), +    addr_type=ADDR_LINES,      func='ex_wrongmodifier',    },    {      command='tprevious',      flags=bit.bor(RANGE, NOTADR, BANG, TRLBAR, ZEROR), +    addr_type=ADDR_LINES,      func='ex_tag',    },    {      command='trewind',      flags=bit.bor(RANGE, NOTADR, BANG, TRLBAR, ZEROR), +    addr_type=ADDR_LINES,      func='ex_tag',    },    {      command='try',      flags=bit.bor(TRLBAR, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_try',    },    {      command='tselect',      flags=bit.bor(BANG, TRLBAR, WORD1), +    addr_type=ADDR_LINES,      func='ex_tag',    },    {      command='tunmap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_unmap',    },    {      command='tunmenu',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='undo',      flags=bit.bor(RANGE, NOTADR, COUNT, ZEROR, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_undo',    },    {      command='undojoin',      flags=bit.bor(TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_undojoin',    },    {      command='undolist',      flags=bit.bor(TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_undolist',    },    {      command='unabbreviate',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_abbreviate',    },    {      command='unhide',      flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_buffer_all',    },    {      command='unlet',      flags=bit.bor(BANG, EXTRA, NEEDARG, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_unlet',    },    {      command='unlockvar',      flags=bit.bor(BANG, EXTRA, NEEDARG, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_lockvar',    },    {      command='unmap',      flags=bit.bor(BANG, EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_unmap',    },    {      command='unmenu',      flags=bit.bor(BANG, EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='unsilent',      flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_wrongmodifier',    },    {      command='update',      flags=bit.bor(RANGE, WHOLEFOLD, BANG, FILE1, ARGOPT, DFLALL, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_update',    },    {      command='vglobal',      flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, DFLALL, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_global',    },    {      command='version',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_version',    },    {      command='verbose',      flags=bit.bor(NEEDARG, RANGE, NOTADR, EXTRA, NOTRLCOM, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_wrongmodifier',    },    {      command='vertical',      flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), +    addr_type=ADDR_LINES,      func='ex_wrongmodifier',    },    {      command='visual',      flags=bit.bor(BANG, FILE1, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_edit',    },    {      command='view',      flags=bit.bor(BANG, FILE1, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_edit',    },    {      command='vimgrep',      flags=bit.bor(RANGE, NOTADR, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE), +    addr_type=ADDR_LINES,      func='ex_vimgrep',    },    {      command='vimgrepadd',      flags=bit.bor(RANGE, NOTADR, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE), +    addr_type=ADDR_LINES,      func='ex_vimgrep',    },    {      command='viusage',      flags=bit.bor(TRLBAR), +    addr_type=ADDR_LINES,      func='ex_viusage',    },    {      command='vmap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_map',    },    {      command='vmapclear',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_mapclear',    },    {      command='vmenu',      flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='vnoremap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_map',    },    {      command='vnew',      flags=bit.bor(BANG, FILE1, RANGE, NOTADR, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_splitview',    },    {      command='vnoremenu',      flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='vsplit',      flags=bit.bor(BANG, FILE1, RANGE, NOTADR, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_splitview',    },    {      command='vunmap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_unmap',    },    {      command='vunmenu',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='write',      flags=bit.bor(RANGE, WHOLEFOLD, BANG, FILE1, ARGOPT, DFLALL, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_write',    },    {      command='wNext',      flags=bit.bor(RANGE, WHOLEFOLD, NOTADR, BANG, FILE1, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_wnext',    },    {      command='wall',      flags=bit.bor(BANG, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='do_wqall',    },    {      command='while',      flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_while',    },    {      command='winsize',      flags=bit.bor(EXTRA, NEEDARG, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_winsize',    },    {      command='wincmd',      flags=bit.bor(NEEDARG, WORD1, RANGE, NOTADR), +    addr_type=ADDR_WINDOWS,      func='ex_wincmd',    },    {      command='windo', -    flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM), +    flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, NOTADR, DFLALL), +    addr_type=ADDR_WINDOWS,      func='ex_listdo',    },    {      command='winpos',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_ni',    },    {      command='wnext',      flags=bit.bor(RANGE, NOTADR, BANG, FILE1, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_wnext',    },    {      command='wprevious',      flags=bit.bor(RANGE, NOTADR, BANG, FILE1, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_wnext',    },    {      command='wq',      flags=bit.bor(RANGE, WHOLEFOLD, BANG, FILE1, ARGOPT, DFLALL, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_exit',    },    {      command='wqall',      flags=bit.bor(BANG, FILE1, ARGOPT, DFLALL, TRLBAR), +    addr_type=ADDR_LINES,      func='do_wqall',    },    {      command='wsverb',      flags=bit.bor(EXTRA, NOTADR, NEEDARG), +    addr_type=ADDR_LINES,      func='ex_wsverb',    },    {      command='wundo',      flags=bit.bor(BANG, NEEDARG, FILE1), +    addr_type=ADDR_LINES,      func='ex_wundo',    },    {      command='wviminfo',      flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_viminfo',    },    {      command='xit',      flags=bit.bor(RANGE, WHOLEFOLD, BANG, FILE1, ARGOPT, DFLALL, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_exit',    },    {      command='xall',      flags=bit.bor(BANG, TRLBAR), +    addr_type=ADDR_LINES,      func='do_wqall',    },    {      command='xmap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_map',    },    {      command='xmapclear',      flags=bit.bor(EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_mapclear',    },    {      command='xmenu',      flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='xnoremap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_map',    },    {      command='xnoremenu',      flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='xunmap',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_unmap',    },    {      command='xunmenu',      flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_menu',    },    {      command='yank',      flags=bit.bor(RANGE, WHOLEFOLD, REGSTR, COUNT, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_operators',    },    {      command='z',      flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, EXFLAGS, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_z',    },    {      command='!',      enum='CMD_bang',      flags=bit.bor(RANGE, WHOLEFOLD, BANG, FILES, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_bang',    },    {      command='#',      enum='CMD_pound',      flags=bit.bor(RANGE, WHOLEFOLD, COUNT, EXFLAGS, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_print',    },    {      command='&',      enum='CMD_and',      flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, MODIFY), +    addr_type=ADDR_LINES,      func='do_sub',    },    {      command='*',      enum='CMD_star',      flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_at',    },    {      command='<',      enum='CMD_lshift',      flags=bit.bor(RANGE, WHOLEFOLD, COUNT, EXFLAGS, TRLBAR, CMDWIN, MODIFY), +    addr_type=ADDR_LINES,      func='ex_operators',    },    {      command='=',      enum='CMD_equal',      flags=bit.bor(RANGE, TRLBAR, DFLALL, EXFLAGS, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_equal',    },    {      command='>',      enum='CMD_rshift',      flags=bit.bor(RANGE, WHOLEFOLD, COUNT, EXFLAGS, TRLBAR, CMDWIN, MODIFY), +    addr_type=ADDR_LINES,      func='ex_operators',    },    {      command='@',      enum='CMD_at',      flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_at',    },    {      command='Next',      flags=bit.bor(EXTRA, RANGE, NOTADR, COUNT, BANG, EDITCMD, ARGOPT, TRLBAR), +    addr_type=ADDR_LINES,      func='ex_previous',    },    {      command='Print',      flags=bit.bor(RANGE, WHOLEFOLD, COUNT, EXFLAGS, TRLBAR, CMDWIN), +    addr_type=ADDR_LINES,      func='ex_print',    },    {      command='~',      enum='CMD_tilde',      flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, MODIFY), +    addr_type=ADDR_LINES,      func='do_sub',    },  } diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 98e6d87196..e453d68247 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -1844,13 +1844,33 @@ void ex_listdo(exarg_T *eap)        || !check_changed(curbuf, CCGD_AW            | (eap->forceit ? CCGD_FORCEIT : 0)            | CCGD_EXCMD)) { -    /* start at the first argument/window/buffer */      i = 0; +    /* start at the eap->line1 argument/window/buffer */      wp = firstwin;      tp = first_tabpage; +    switch (eap->cmdidx) { +      case CMD_windo: +        for (; wp != NULL && i + 1 < eap->line1; wp = wp->w_next) { +          i++; +        } +        break; +      case CMD_tabdo: +        for (; tp != NULL && i + 1 < eap->line1; tp = tp->tp_next) { +          i++; +        } +        break; +      case CMD_argdo: +        i = eap->line1 - 1; +        break; +      case CMD_bufdo: +        i = eap->line1; +        break; +      default: +        break; +    }      /* set pcmark now */      if (eap->cmdidx == CMD_bufdo) -      goto_buffer(eap, DOBUF_FIRST, FORWARD, 0); +      goto_buffer(eap, DOBUF_FIRST, FORWARD, i);      else        setpcmark();      listcmd_busy = TRUE;            /* avoids setting pcmark below */ @@ -1873,7 +1893,6 @@ void ex_listdo(exarg_T *eap)          }          if (curwin->w_arg_idx != i)            break; -        ++i;        } else if (eap->cmdidx == CMD_windo) {          /* go to window "wp" */          if (!win_valid(wp)) @@ -1899,13 +1918,14 @@ void ex_listdo(exarg_T *eap)            }        } +      ++i;        /* execute the command */        do_cmdline(eap->arg, eap->getline, eap->cookie,            DOCMD_VERBOSE + DOCMD_NOWAIT);        if (eap->cmdidx == CMD_bufdo) {          /* Done? */ -        if (next_fnum < 0) +        if (next_fnum < 0 || next_fnum > eap->line2)            break;          /* Check if the buffer still exists. */ @@ -1939,6 +1959,14 @@ void ex_listdo(exarg_T *eap)          if (curwin->w_p_scb)            do_check_scrollbind(TRUE);        } +      if (eap->cmdidx == CMD_windo || eap->cmdidx == CMD_tabdo) { +        if (i + 1 > eap->line2) { +          break; +        } +      } +      if (eap->cmdidx == CMD_argdo && i >= eap->line2) { +        break; +      }      }      listcmd_busy = FALSE;    } diff --git a/src/nvim/ex_cmds_defs.h b/src/nvim/ex_cmds_defs.h index 1b920511b6..4065cc2fdc 100644 --- a/src/nvim/ex_cmds_defs.h +++ b/src/nvim/ex_cmds_defs.h @@ -71,6 +71,14 @@  #define WORD1   (EXTRA | NOSPC) /* one extra word allowed */  #define FILE1   (FILES | NOSPC) /* 1 file allowed, defaults to current file */ +// values for cmd_addr_type +#define ADDR_LINES              0 +#define ADDR_WINDOWS            1 +#define ADDR_ARGUMENTS          2 +#define ADDR_LOADED_BUFFERS     3 +#define ADDR_BUFFERS            4 +#define ADDR_TABS               5 +  typedef struct exarg exarg_T;  /* behavior for bad character, "++bad=" argument */ @@ -87,6 +95,7 @@ typedef struct cmdname {    char_u *cmd_name;    ///< Name of the command.    ex_func_T cmd_func;  ///< Function with implementation of this command.    uint32_t cmd_argt;     ///< Relevant flags from the declared above. +  int cmd_addr_type;     ///< Flag for address type  } CommandDefinition;  /// Arguments used for Ex commands. @@ -102,6 +111,7 @@ struct exarg {    int addr_count;               ///< the number of addresses given    linenr_T line1;               ///< the first line number    linenr_T line2;               ///< the second line number or count +  int addr_type;                ///< type of the count/range    int flags;                    ///< extra flags after count: EXFLAG_    char_u      *do_ecmd_cmd;     ///< +command arg to be used in edited file    linenr_T do_ecmd_lnum;        ///< the line number in an edited file diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 51010983bb..646d64f9f8 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -85,6 +85,7 @@ typedef struct ucmd {    char_u      *uc_rep;          /* The command's replacement string */    long uc_def;                  /* The default value for a range/count */    int uc_compl;                 /* completion type */ +  int uc_addr_type;             /* The command's address type */    scid_T uc_scriptID;           /* SID where the command was defined */    char_u      *uc_compl_arg;    /* completion argument if any */  } ucmd_T; @@ -1066,16 +1067,178 @@ void * getline_cookie(LineGetter fgetline,  }  /* + * Helper function to apply an offset for buffer commands, i.e. ":bdelete", + * ":bwipeout", etc. + * Returns the buffer number. + */ +static int compute_buffer_local_count(int addr_type, int lnum, int offset) +{ +  buf_T *buf; +  buf_T *nextbuf; +  int count = offset; + +  buf = firstbuf; +  while (buf->b_next != NULL && buf->b_fnum < lnum) +    buf = buf->b_next; +  while (count != 0) { +    count += (count < 0) ? 1 : -1; +    nextbuf = (offset < 0) ? buf->b_prev : buf->b_next; +    if (nextbuf == NULL) +      break; +    buf = nextbuf; +    if (addr_type == ADDR_LOADED_BUFFERS) +      /* skip over unloaded buffers */ +      while (buf->b_ml.ml_mfp == NULL) { +        nextbuf = (offset < 0) ? buf->b_prev : buf->b_next; +        if (nextbuf == NULL) { +          break; +        } +        buf = nextbuf; +      } +  } +  // we might have gone too far, last buffer is not loaded +  if (addr_type == ADDR_LOADED_BUFFERS) { +    while (buf->b_ml.ml_mfp == NULL) { +      nextbuf = (offset >= 0) ? buf->b_prev : buf->b_next; +      if (nextbuf == NULL) +        break; +      buf = nextbuf; +    } +  } +  return buf->b_fnum; +} + +static int current_win_nr(win_T *win) +{ +  int nr = 0; + +  FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { +    ++nr; +    if (wp == win) +      break; +  } +  return nr; +} + +static int current_tab_nr(tabpage_T *tab) +{ +  int nr = 0; + +  FOR_ALL_TABS(tp) { +    ++nr; +    if (tp == tab) +      break; +  } +  return nr; +} + +#define CURRENT_WIN_NR current_win_nr(curwin) +#define LAST_WIN_NR current_win_nr(NULL) +#define CURRENT_TAB_NR current_tab_nr(curtab) +#define LAST_TAB_NR current_tab_nr(NULL) + +/* +* Figure out the address type for ":wincmd". +*/ +static void get_wincmd_addr_type(char_u *arg, exarg_T *eap) +{ +  switch (*arg) { +    case 'S': +    case Ctrl_S: +    case 's': +    case Ctrl_N: +    case 'n': +    case 'j': +    case Ctrl_J: +    case 'k': +    case Ctrl_K: +    case 'T': +    case Ctrl_R: +    case 'r': +    case 'R': +    case 'K': +    case 'J': +    case '+': +    case '-': +    case Ctrl__: +    case '_': +    case '|': +    case ']': +    case Ctrl_RSB: +    case 'g': +    case Ctrl_G: +    case Ctrl_V: +    case 'v': +    case 'h': +    case Ctrl_H: +    case 'l': +    case Ctrl_L: +    case 'H': +    case 'L': +    case '>': +    case '<': +    case '}': +    case 'f': +    case 'F': +    case Ctrl_F: +    case 'i': +    case Ctrl_I: +    case 'd': +    case Ctrl_D: +      /* window size or any count */ +      eap->addr_type = ADDR_LINES; +      break; + +    case Ctrl_HAT: +    case '^': +      /* buffer number */ +      eap->addr_type = ADDR_BUFFERS; +      break; + +    case Ctrl_Q: +    case 'q': +    case Ctrl_C: +    case 'c': +    case Ctrl_O: +    case 'o': +    case Ctrl_W: +    case 'w': +    case 'W': +    case 'x': +    case Ctrl_X: +      /* window number */ +      eap->addr_type = ADDR_WINDOWS; +      break; + +    case Ctrl_Z: +    case 'z': +    case 'P': +    case 't': +    case Ctrl_T: +    case 'b': +    case Ctrl_B: +    case 'p': +    case Ctrl_P: +    case '=': +    case CAR: +      /* no count */ +      eap->addr_type = 0; +      break; +  } +} + +/*   * Execute one Ex command.   *   * If 'sourcing' is TRUE, the command will be included in the error message.   *   * 1. skip comment lines and leading space   * 2. handle command modifiers - * 3. parse range - * 4. parse command - * 5. parse arguments - * 6. switch on command name + * 3. skip over the range to find the command + * 4. parse the range + * 5. parse the command + * 6. parse arguments + * 7. switch on command name   *   * Note: "fgetline" can be NULL.   * @@ -1100,6 +1263,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,    int did_sandbox = FALSE;    cmdmod_T save_cmdmod;    int ni;                                       /* set when Not Implemented */ +  char_u *cmd;    memset(&ea, 0, sizeof(ea));    ea.line1 = 1; @@ -1132,7 +1296,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,    ea.cmd = *cmdlinep;    for (;; ) {      /* -     * 1. skip comment lines and leading white space and colons +     * 1. Skip comment lines and leading white space and colons.       */      while (*ea.cmd == ' ' || *ea.cmd == '\t' || *ea.cmd == ':')        ++ea.cmd; @@ -1155,7 +1319,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,      }      /* -     * 2. handle command modifiers. +     * 2. Handle command modifiers.       */      p = ea.cmd;      if (ascii_isdigit(*ea.cmd)) @@ -1319,8 +1483,18 @@ static char_u * do_one_cmd(char_u **cmdlinep,      (void)do_intthrow(cstack);    } +  // 3. Skip over the range to find the command. Let "p" point to after it. +  // +  // We need the command to know what kind of range it uses. + +  cmd = ea.cmd; +  ea.cmd = skip_range(ea.cmd, NULL); +  if (*ea.cmd == '*' && vim_strchr(p_cpo, CPO_STAR) == NULL) +    ea.cmd = skipwhite(ea.cmd + 1); +  p = find_command(&ea, NULL); +    /* -   * 3. parse a range specifier of the form: addr [,addr] [;addr] .. +   * 4. Parse a range specifier of the form: addr [,addr] [;addr] ..     *     * where 'addr' is:     * @@ -1336,25 +1510,109 @@ static char_u * do_one_cmd(char_u **cmdlinep,     * is equal to the lower.     */ +  // ea.addr_type for user commands is set by find_ucmd +  if (!IS_USER_CMDIDX(ea.cmdidx)) { +    if (ea.cmdidx != CMD_SIZE) { +      ea.addr_type = cmdnames[(int)ea.cmdidx].cmd_addr_type; +    } else { +      ea.addr_type = ADDR_LINES; +    } +    // :wincmd range depends on the argument +    if (ea.cmdidx == CMD_wincmd && p != NULL) { +      get_wincmd_addr_type(skipwhite(p), &ea); +    } +  } +    /* repeat for all ',' or ';' separated addresses */ +  ea.cmd = cmd;    for (;; ) {      ea.line1 = ea.line2; -    ea.line2 = curwin->w_cursor.lnum;       /* default is current line number */ +    switch (ea.addr_type) { +      case ADDR_LINES: +        // default is current line number +        ea.line2 = curwin->w_cursor.lnum; +        break; +      case ADDR_WINDOWS: +        lnum = CURRENT_WIN_NR; +        ea.line2 = lnum; +        break; +      case ADDR_ARGUMENTS: +        ea.line2 = curwin->w_arg_idx + 1; +        if (ea.line2 > ARGCOUNT) { +          ea.line2 = ARGCOUNT; +        } +        break; +      case ADDR_LOADED_BUFFERS: +      case ADDR_BUFFERS: +        ea.line2 = curbuf->b_fnum; +        break; +      case ADDR_TABS: +        lnum = CURRENT_TAB_NR; +        ea.line2 = lnum; +        break; +    }      ea.cmd = skipwhite(ea.cmd); -    lnum = get_address(&ea.cmd, ea.skip, ea.addr_count == 0); +    lnum = get_address(&ea.cmd, ea.addr_type, ea.skip, ea.addr_count == 0);      if (ea.cmd == NULL)                     /* error detected */        goto doend;      if (lnum == MAXLNUM) {        if (*ea.cmd == '%') {                 /* '%' - all lines */          ++ea.cmd; -        ea.line1 = 1; -        ea.line2 = curbuf->b_ml.ml_line_count; +        switch (ea.addr_type) { +          case ADDR_LINES: +            ea.line1 = 1; +            ea.line2 = curbuf->b_ml.ml_line_count; +            break; +          case ADDR_LOADED_BUFFERS: { +            buf_T *buf = firstbuf; +            while (buf->b_next != NULL && buf->b_ml.ml_mfp == NULL) { +              buf = buf->b_next; +            } +            ea.line1 = buf->b_fnum; +            buf = lastbuf; +            while (buf->b_prev != NULL && buf->b_ml.ml_mfp == NULL) { +              buf = buf->b_prev; +            } +            ea.line2 = buf->b_fnum; +            break; +          } +          case ADDR_BUFFERS: +            ea.line1 = firstbuf->b_fnum; +            ea.line2 = lastbuf->b_fnum; +            break; +          case ADDR_WINDOWS: +          case ADDR_TABS: +            if (IS_USER_CMDIDX(ea.cmdidx)) { +              ea.line1 = 1; +              ea.line2 = +                  ea.addr_type == ADDR_WINDOWS ? LAST_WIN_NR : LAST_TAB_NR; +            } else { +              // there is no Vim command which uses '%' and +              // ADDR_WINDOWS or ADDR_TABS +              errormsg = (char_u *)_(e_invrange); +              goto doend; +            } +            break; +          case ADDR_ARGUMENTS: +            if (ARGCOUNT == 0) { +              ea.line1 = ea.line2 = 0; +            } else { +              ea.line1 = 1; +              ea.line2 = ARGCOUNT; +            } +            break; +        }          ++ea.addr_count;        }        /* '*' - visual area */        else if (*ea.cmd == '*' && vim_strchr(p_cpo, CPO_STAR) == NULL) {          pos_T       *fp; +        if (ea.addr_type != ADDR_LINES) { +          errormsg = (char_u *)_(e_invrange); +          goto doend; +        } +          ++ea.cmd;          if (!ea.skip) {            fp = getmark('<', FALSE); @@ -1392,7 +1650,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,    check_cursor_lnum();    /* -   * 4. parse command +   * 5. Parse the command.     */    /* @@ -1446,9 +1704,6 @@ static char_u * do_one_cmd(char_u **cmdlinep,      goto doend;    } -  /* Find the command and let "p" point to after it. */ -  p = find_command(&ea, NULL); -    // If this looks like an undefined user command and there are CmdUndefined    // autocommands defined, trigger the matching autocommands.    if (p != NULL && ea.cmdidx == CMD_SIZE && !ea.skip @@ -1502,7 +1757,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,      ea.forceit = FALSE;    /* -   * 5. parse arguments +   * 6. Parse arguments.     */    if (!IS_USER_CMDIDX(ea.cmdidx)) {      ea.argt = cmdnames[(int)ea.cmdidx].cmd_argt; @@ -1695,8 +1950,43 @@ static char_u * do_one_cmd(char_u **cmdlinep,    }    if ((ea.argt & DFLALL) && ea.addr_count == 0) { +    buf_T *buf; +      ea.line1 = 1; -    ea.line2 = curbuf->b_ml.ml_line_count; +    switch (ea.addr_type) { +      case ADDR_LINES: +        ea.line2 = curbuf->b_ml.ml_line_count; +        break; +      case ADDR_LOADED_BUFFERS: +        buf = firstbuf; +        while (buf->b_next != NULL && buf->b_ml.ml_mfp == NULL) { +          buf = buf->b_next; +        } +        ea.line1 = buf->b_fnum; +        buf = lastbuf; +        while (buf->b_prev != NULL && buf->b_ml.ml_mfp == NULL) { +          buf = buf->b_prev; +        } +        ea.line2 = buf->b_fnum; +        break; +      case ADDR_BUFFERS: +        ea.line1 = firstbuf->b_fnum; +        ea.line2 = lastbuf->b_fnum; +        break; +      case ADDR_WINDOWS: +        ea.line2 = LAST_WIN_NR; +        break; +      case ADDR_TABS: +        ea.line2 = LAST_TAB_NR; +        break; +      case ADDR_ARGUMENTS: +        if (ARGCOUNT == 0) { +          ea.line1 = ea.line2 = 0; +        } else { +          ea.line2 = ARGCOUNT; +        } +        break; +    }    }    /* accept numbered register only when no count allowed (:put) */ @@ -1888,7 +2178,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,    }    /* -   * 6. switch on command name +   * 7. Switch on command name.     *     * The "ea" structure holds the arguments that can be used.     */ @@ -2057,7 +2347,7 @@ static char_u *find_command(exarg_T *eap, int *full)     * Exceptions:     * - the 'k' command can directly be followed by any character.     * - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r' -   *	    but :sre[wind] is another command, as are :scrip[tnames], +   *	    but :sre[wind] is another command, as are :scr[iptnames],     *	    :scs[cope], :sim[alt], :sig[ns] and :sil[ent].     * - the "d" command can directly be followed by 'l' or 'p' flag.     */ @@ -2195,6 +2485,7 @@ find_ucmd (              eap->cmdidx = CMD_USER_BUF;            eap->argt = uc->uc_argt;            eap->useridx = j; +          eap->addr_type = uc->uc_addr_type;            if (compl != NULL)              *compl = uc->uc_compl; @@ -2734,9 +3025,8 @@ set_one_cmd_context (            return NULL;          } -        /* For the -complete and -nargs attributes, we complete -         * their arguments as well. -         */ +        // For the -complete, -nargs and -addr attributes, we complete +        // their arguments as well.          if (STRNICMP(arg, "complete", p - arg) == 0) {            xp->xp_context = EXPAND_USER_COMPLETE;            xp->xp_pattern = p + 1; @@ -2745,6 +3035,10 @@ set_one_cmd_context (            xp->xp_context = EXPAND_USER_NARGS;            xp->xp_pattern = p + 1;            return NULL; +        } else if (STRNICMP(arg, "addr", p - arg) == 0) { +          xp->xp_context = EXPAND_USER_ADDR_TYPE; +          xp->xp_pattern = p + 1; +          return NULL;          }          return NULL;        } @@ -3098,12 +3392,11 @@ skip_range (   *   * Return MAXLNUM when no Ex address was found.   */ -static linenr_T  -get_address ( -    char_u **ptr, -    int skip,                   /* only skip the address, don't use it */ -    int to_other_file              /* flag: may jump to other file */ -) +static linenr_T get_address(char_u **ptr, +                            int addr_type,  // flag: one of ADDR_LINES, ... +                            int skip,  // only skip the address, don't use it +                            int to_other_file  // flag: may jump to other file +                            )  {    int c;    int i; @@ -3112,6 +3405,7 @@ get_address (    pos_T pos;    pos_T       *fp;    linenr_T lnum; +  buf_T *buf;    cmd = skipwhite(*ptr);    lnum = MAXLNUM; @@ -3119,12 +3413,55 @@ get_address (      switch (*cmd) {      case '.':                               /* '.' - Cursor position */        ++cmd; -      lnum = curwin->w_cursor.lnum; +      switch (addr_type) { +        case ADDR_LINES: +          lnum = curwin->w_cursor.lnum; +          break; +        case ADDR_WINDOWS: +          lnum = CURRENT_WIN_NR; +          break; +        case ADDR_ARGUMENTS: +          lnum = curwin->w_arg_idx + 1; +          break; +        case ADDR_LOADED_BUFFERS: +        case ADDR_BUFFERS: +          lnum = curbuf->b_fnum; +          break; +        case ADDR_TABS: +          lnum = CURRENT_TAB_NR; +          break; +      }        break;      case '$':                               /* '$' - last line */        ++cmd; -      lnum = curbuf->b_ml.ml_line_count; +      switch (addr_type) { +        case ADDR_LINES: +          lnum = curbuf->b_ml.ml_line_count; +          break; +        case ADDR_WINDOWS: +          lnum = LAST_WIN_NR; +          break; +        case ADDR_ARGUMENTS: +          lnum = ARGCOUNT; +          break; +        case ADDR_LOADED_BUFFERS: +          buf = lastbuf; +          while (buf->b_ml.ml_mfp == NULL) { +            if (buf->b_prev == NULL) { +              break; +            } +            buf = buf->b_prev; +          } +          lnum = buf->b_fnum; +          break; +        case ADDR_BUFFERS: +          lnum = lastbuf->b_fnum; +          break; +        case ADDR_TABS: +          lnum = LAST_TAB_NR; +          break; +      }        break;      case '\'':                              /* ''' - mark */ @@ -3132,6 +3469,10 @@ get_address (          cmd = NULL;          goto error;        } +      if (addr_type != ADDR_LINES) { +        EMSG(_(e_invaddr)); +        goto error; +      }        if (skip)          ++cmd;        else { @@ -3155,6 +3496,10 @@ get_address (      case '/':      case '?':                           /* '/' or '?' - search */        c = *cmd++; +      if (addr_type != ADDR_LINES) { +        EMSG(_(e_invaddr)); +        goto error; +      }        if (skip) {                       /* skip "/pat/" */          cmd = skip_regexp(cmd, c, p_magic, NULL);          if (*cmd == c) @@ -3194,6 +3539,10 @@ get_address (      case '\\':                      /* "\?", "\/" or "\&", repeat search */        ++cmd; +      if (addr_type != ADDR_LINES) { +        EMSG(_(e_invaddr)); +        goto error; +      }        if (*cmd == '&')          i = RE_SUBST;        else if (*cmd == '?' || *cmd == '/') @@ -3233,8 +3582,27 @@ get_address (        if (*cmd != '-' && *cmd != '+' && !ascii_isdigit(*cmd))          break; -      if (lnum == MAXLNUM) -        lnum = curwin->w_cursor.lnum;           /* "+1" is same as ".+1" */ +      if (lnum == MAXLNUM) { +        switch (addr_type) { +          case ADDR_LINES: +            lnum = curwin->w_cursor.lnum; /* "+1" is same as ".+1" */ +            break; +          case ADDR_WINDOWS: +            lnum = CURRENT_WIN_NR; +            break; +          case ADDR_ARGUMENTS: +            lnum = curwin->w_arg_idx + 1; +            break; +          case ADDR_LOADED_BUFFERS: +          case ADDR_BUFFERS: +            lnum = curbuf->b_fnum; +            break; +          case ADDR_TABS: +            lnum = CURRENT_TAB_NR; +            break; +        } +      } +        if (ascii_isdigit(*cmd))          i = '+';                        /* "number" is same as "+number" */        else @@ -3242,8 +3610,10 @@ get_address (        if (!ascii_isdigit(*cmd))           /* '+' is '+1', but '+0' is not '+1' */          n = 1;        else -        n = getdigits_long(&cmd); -      if (i == '-') +        n = getdigits(&cmd); +      if (addr_type == ADDR_LOADED_BUFFERS || addr_type == ADDR_BUFFERS) +        lnum = compute_buffer_local_count(addr_type, lnum, (i == '-') ? -1 * n : n); +      else if (i == '-')          lnum -= n;        else          lnum += n; @@ -3295,15 +3665,65 @@ static void ex_script_ni(exarg_T *eap)   */  static char_u *invalid_range(exarg_T *eap)  { -  if (       eap->line1 < 0 -             || eap->line2 < 0 -             || eap->line1 > eap->line2 -             || ((eap->argt & RANGE) -                 && !(eap->argt & NOTADR) -                 && eap->line2 > curbuf->b_ml.ml_line_count -                 + (eap->cmdidx == CMD_diffget) -                 )) +  buf_T *buf; +  if (eap->line1 < 0 || eap->line2 < 0 || eap->line1 > eap->line2) {      return (char_u *)_(e_invrange); +  } + +  if (eap->argt & RANGE) { +    switch(eap->addr_type) { +      case ADDR_LINES: +        if (!(eap->argt & NOTADR) +            && eap->line2 > curbuf->b_ml.ml_line_count +               + (eap->cmdidx == CMD_diffget)) { +          return (char_u *)_(e_invrange); +        } +        break; +      case ADDR_ARGUMENTS: +        if (eap->line2 > ARGCOUNT + (!ARGCOUNT)) {  // add 1 if ARGCOUNT is 0 +          return (char_u *)_(e_invrange); +        } +        break; +      case ADDR_BUFFERS: +        if (eap->line1 < firstbuf->b_fnum +            || eap->line2 > lastbuf->b_fnum) { +          return (char_u *)_(e_invrange); +        } +        break; +     case ADDR_LOADED_BUFFERS: +        buf = firstbuf; +        while (buf->b_ml.ml_mfp == NULL) { +          if (buf->b_next == NULL) { +            return (char_u *)_(e_invrange); +          } +          buf = buf->b_next; +        } +        if (eap->line1 < buf->b_fnum) { +          return (char_u *)_(e_invrange); +        } +        buf = lastbuf; +        while (buf->b_ml.ml_mfp == NULL) { +          if (buf->b_prev == NULL) { +            return (char_u *)_(e_invrange); +          } +          buf = buf->b_prev; +        } +        if (eap->line2 > buf->b_fnum) { +          return (char_u *)_(e_invrange); +        } +        break; +      case ADDR_WINDOWS: +        if (eap->line2 > LAST_WIN_NR) { +          return (char_u *)_(e_invrange); +        } +        break; +      case ADDR_TABS: +        if (eap->line2 > LAST_TAB_NR) { +          return (char_u *)_(e_invrange); +        } +        break; +    } +  }    return NULL;  } @@ -4091,10 +4511,9 @@ char_u *get_command_name(expand_T *xp, int idx)    return cmdnames[idx].cmd_name;  } -  static int uc_add_command(char_u *name, size_t name_len, char_u *rep,                            uint32_t argt, long def, int flags, int compl, -                          char_u *compl_arg, int force) +                          char_u *compl_arg, int addr_type, int force)  {    ucmd_T      *cmd = NULL;    char_u      *p; @@ -4169,6 +4588,7 @@ static int uc_add_command(char_u *name, size_t name_len, char_u *rep,    cmd->uc_compl = compl;    cmd->uc_scriptID = current_SID;    cmd->uc_compl_arg = compl_arg; +  cmd->uc_addr_type = addr_type;    return OK; @@ -4178,6 +4598,21 @@ fail:    return FAIL;  } + +static struct { +  int expand; +  char *name; +} addr_type_complete[] = +{ +  {ADDR_ARGUMENTS, "arguments"}, +  {ADDR_LINES, "lines"}, +  {ADDR_LOADED_BUFFERS, "loaded_buffers"}, +  {ADDR_TABS, "tabs"}, +  {ADDR_BUFFERS, "buffers"}, +  {ADDR_WINDOWS, "windows"}, +  {-1, NULL} +}; +  /*   * List of names for completion for ":command" with the EXPAND_ flag.   * Must be alphabetical for completion. @@ -4226,6 +4661,7 @@ static struct {  static void uc_list(char_u *name, size_t name_len)  { +  int i, j;    int found = FALSE;    ucmd_T      *cmd;    int len; @@ -4234,7 +4670,6 @@ static void uc_list(char_u *name, size_t name_len)    gap = &curbuf->b_ucmds;    for (;; ) { -    int i;      for (i = 0; i < gap->ga_len; ++i) {        cmd = USER_CMD_GA(gap, i);        a = cmd->uc_argt; @@ -4245,7 +4680,7 @@ static void uc_list(char_u *name, size_t name_len)        /* Put out the title first time */        if (!found) -        MSG_PUTS_TITLE(_("\n    Name        Args Range Complete  Definition")); +        MSG_PUTS_TITLE(_("\n    Name        Args       Address   Complete  Definition"));        found = TRUE;        msg_putchar('\n');        if (got_int) @@ -4300,8 +4735,21 @@ static void uc_list(char_u *name, size_t name_len)          IObuff[len++] = ' ';        } while (len < 11); +      /* Address Type */ +      for (j = 0; addr_type_complete[j].expand != -1; ++j) +        if (addr_type_complete[j].expand != ADDR_LINES && +            addr_type_complete[j].expand == cmd->uc_addr_type) { +          STRCPY(IObuff + len, addr_type_complete[j].name); +          len += (int)STRLEN(IObuff + len); +          break; +        } + +      do { +        IObuff[len++] = ' '; +      } while (len < 21); +        /* Completion */ -      for (int j = 0; command_complete[j].expand != 0; ++j) +      for (j = 0; command_complete[j].expand != 0; ++j)          if (command_complete[j].expand == cmd->uc_compl) {            STRCPY(IObuff + len, command_complete[j].name);            len += (int)STRLEN(IObuff + len); @@ -4310,7 +4758,7 @@ static void uc_list(char_u *name, size_t name_len)        do {          IObuff[len++] = ' '; -      } while (len < 21); +      } while (len < 35);        IObuff[len] = '\0';        msg_outtrans(IObuff); @@ -4346,7 +4794,9 @@ static char_u *uc_fun_cmd(void)    return IObuff;  } -static int uc_scan_attr(char_u *attr, size_t len, uint32_t *argt, long *def, int *flags, int *compl, char_u **compl_arg) +static int uc_scan_attr(char_u *attr, size_t len, uint32_t *argt, long *def, +                        int *flags, int * compl, char_u **compl_arg, +                        int *addr_type_arg)  {    char_u      *p; @@ -4445,6 +4895,18 @@ invalid_count:        if (parse_compl_arg(val, (int)vallen, compl, argt, compl_arg)            == FAIL)          return FAIL; +    } else if (STRNICMP(attr, "addr", attrlen) == 0) { +      *argt |= RANGE; +      if (val == NULL) { +        EMSG(_("E179: argument required for -addr")); +        return FAIL; +      } +      if (parse_addr_type_arg(val, (int)vallen, argt, addr_type_arg) == FAIL) { +        return FAIL; +      } +      if (addr_type_arg != ADDR_LINES) { +        *argt |= (ZEROR | NOTADR); +      }      } else {        char_u ch = attr[len];        attr[len] = '\0'; @@ -4470,6 +4932,7 @@ static void ex_command(exarg_T *eap)    int flags = 0;    int     compl = EXPAND_NOTHING;    char_u  *compl_arg = NULL; +  int addr_type_arg = ADDR_LINES;    int has_attr = (eap->arg[0] == '-');    int name_len; @@ -4479,7 +4942,7 @@ static void ex_command(exarg_T *eap)    while (*p == '-') {      ++p;      end = skiptowhite(p); -    if (uc_scan_attr(p, end - p, &argt, &def, &flags, &compl, &compl_arg) +    if (uc_scan_attr(p, end - p, &argt, &def, &flags, &compl, &compl_arg, &addr_type_arg)          == FAIL)        return;      p = skipwhite(end); @@ -4513,7 +4976,7 @@ static void ex_command(exarg_T *eap)      return;    } else      uc_add_command(name, end - name, p, argt, def, flags, compl, compl_arg, -        eap->forceit); +                   addr_type_arg, eap->forceit);  }  /* @@ -4941,6 +5404,13 @@ static char_u *get_user_command_name(int idx)  {    return get_user_commands(NULL, idx - (int)CMD_SIZE);  } +/* + * Function given to ExpandGeneric() to obtain the list of user address type names. + */ +char_u *get_user_cmd_addr_type(expand_T *xp, int idx) +{ +  return (char_u *)addr_type_complete[idx].name; +}  /*   * Function given to ExpandGeneric() to obtain the list of user command names. @@ -4961,9 +5431,9 @@ char_u *get_user_commands(expand_T *xp, int idx)   */  char_u *get_user_cmd_flags(expand_T *xp, int idx)  { -  static char *user_cmd_flags[] = -  {"bang", "bar", "buffer", "complete", "count", -   "nargs", "range", "register"}; +  static char *user_cmd_flags[] = {"addr",   "bang",     "bar", +                                   "buffer", "complete", "count", +                                   "nargs",  "range",    "register"};    if (idx >= (int)ARRAY_SIZE(user_cmd_flags))      return NULL; @@ -4990,6 +5460,36 @@ char_u *get_user_cmd_complete(expand_T *xp, int idx)    return (char_u *)command_complete[idx].name;  } +/* + * Parse address type argument + */ +int parse_addr_type_arg(char_u *value, int vallen, uint32_t *argt, +                        int *addr_type_arg) +{ +  int i, a, b; +  for (i = 0; addr_type_complete[i].expand != -1; ++i) { +    a = (int)STRLEN(addr_type_complete[i].name) == vallen; +    b = STRNCMP(value, addr_type_complete[i].name, vallen) == 0; +    if (a && b) { +      *addr_type_arg = addr_type_complete[i].expand; +      break; +    } +  } + +  if (addr_type_complete[i].expand == -1) { +    char_u *err = value; +    for (i = 0; err[i] == NUL || !ascii_iswhite(err[i]); i++) +      ; +    err[i] = NUL; +    EMSG2(_("E180: Invalid address type value: %s"), err); +    return FAIL; +  } + +  if (*addr_type_arg != ADDR_LINES) +    *argt |= NOTADR; + +  return OK; +}  /*   * Parse a completion argument "value[vallen]". @@ -5089,7 +5589,7 @@ void not_exiting(void)  }  /* - * ":quit": quit current window, quit Vim if closed the last window. + * ":quit": quit current window, quit Vim if the last window is closed.   */  static void ex_quit(exarg_T *eap)  { @@ -5102,10 +5602,25 @@ static void ex_quit(exarg_T *eap)      text_locked_msg();      return;    } + +  win_T *wp; + +  if (eap->addr_count > 0) { +    int wnr = eap->line2; + +    for (wp = firstwin; wp->w_next != NULL; wp = wp->w_next) { +      if (--wnr <= 0) +        break; +    } +  } else { +    wp = curwin; +  } +    apply_autocmds(EVENT_QUITPRE, NULL, NULL, FALSE, curbuf);    /* Refuse to quit when locked or when the buffer in the last window is     * being closed (can only happen in autocommands). */ -  if (curbuf_locked() || (curbuf->b_nwindows == 1 && curbuf->b_closing)) +  if (curbuf_locked() || +      (wp->w_buffer->b_nwindows == 1 && wp->w_buffer->b_closing))      return; @@ -5127,7 +5642,7 @@ static void ex_quit(exarg_T *eap)        getout(0);      }      /* close window; may free buffer */ -    win_close(curwin, !P_HID(curwin->w_buffer) || eap->forceit); +    win_close(wp, !P_HID(wp->w_buffer) || eap->forceit);    }  } @@ -5174,12 +5689,24 @@ static void ex_quit_all(exarg_T *eap)   */  static void ex_close(exarg_T *eap)  { +  win_T *win; +  int winnr = 0;    if (cmdwin_type != 0)      cmdwin_result = Ctrl_C; -  else if (!text_locked() -           && !curbuf_locked() -           ) -    ex_win_close(eap->forceit, curwin, NULL); +  else if (!text_locked() && !curbuf_locked()) { +    if (eap->addr_count == 0) +      ex_win_close(eap->forceit, curwin, NULL); +    else { +      for (win = firstwin; win != NULL; win = win->w_next) { +        winnr++; +        if (winnr == eap->line2) +          break; +      } +      if (win == NULL) +        win = lastwin; +      ex_win_close(eap->forceit, win, NULL); +    } +  }  }  /* @@ -5271,6 +5798,8 @@ static void ex_tabonly(exarg_T *eap)    else if (first_tabpage->tp_next == NULL)      MSG(_("Already only one tab page"));    else { +    if (eap->addr_count > 0) +      goto_tabpage(eap->line2);      /* Repeat this up to a 1000 times, because autocommands may mess       * up the lists. */      for (int done = 0; done < 1000; ++done) { @@ -5341,6 +5870,18 @@ void tabpage_close_other(tabpage_T *tp, int forceit)   */  static void ex_only(exarg_T *eap)  { +  win_T *wp; +  int wnr; +  if (eap->addr_count > 0) { +    wnr = eap->line2; +    for (wp = firstwin; --wnr > 0;) { +      if (wp->w_next == NULL) +        break; +      else +        wp = wp->w_next; +    } +    win_goto(wp); +  }    close_others(TRUE, eap->forceit);  } @@ -5363,7 +5904,21 @@ static void ex_hide(exarg_T *eap)      /* ":hide" or ":hide | cmd": hide current window */      eap->nextcmd = check_nextcmd(eap->arg);      if (!eap->skip) { -      win_close(curwin, FALSE);         /* don't free buffer */ +      if (eap->addr_count == 0) +        win_close(curwin, FALSE); /* don't free buffer */ +      else { +        int winnr = 0; +        win_T *win; + +        for (win = firstwin; win != NULL; win = win->w_next) { +          winnr++; +          if (winnr == eap->line2) +            break; +        } +        if (win == NULL) +          win = lastwin; +        win_close(win, FALSE); +      }      }    }  } @@ -6518,7 +7073,7 @@ static void ex_copymove(exarg_T *eap)  {    long n; -  n = get_address(&eap->arg, FALSE, FALSE); +  n = get_address(&eap->arg, eap->addr_type, FALSE, FALSE);    if (eap->arg == NULL) {           /* error detected */      eap->nextcmd = NULL;      return; diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index b54ae5fe11..1a04f1bd91 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -3701,6 +3701,7 @@ ExpandFromContext (        {EXPAND_BEHAVE, get_behave_arg, TRUE, TRUE},        {EXPAND_HISTORY, get_history_arg, TRUE, TRUE},        {EXPAND_USER_COMMANDS, get_user_commands, FALSE, TRUE}, +      {EXPAND_USER_ADDR_TYPE, get_user_cmd_addr_type, FALSE, TRUE},        {EXPAND_USER_CMD_FLAGS, get_user_cmd_flags, FALSE, TRUE},        {EXPAND_USER_NARGS, get_user_cmd_nargs, FALSE, TRUE},        {EXPAND_USER_COMPLETE, get_user_cmd_complete, FALSE, TRUE}, diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile index 0a7c16e2cb..2dedc3db12 100644 --- a/src/nvim/testdir/Makefile +++ b/src/nvim/testdir/Makefile @@ -29,7 +29,11 @@ SCRIPTS := test_autoformat_join.out                                    \             test86.out  test87.out  test88.out                          \             test96.out                                                  \             test_listlbr.out                                            \ -           test_breakindent.out +           test_breakindent.out                                        \ +           test_argument_count.out                                     \ +           test_close_count.out                                        \ +           test_command_count.out                                      \ +           test_argument_0count.out  SCRIPTS_GUI := test16.out diff --git a/src/nvim/testdir/test62.in b/src/nvim/testdir/test62.in index 93d968b33e..c201fe7137 100644 --- a/src/nvim/testdir/test62.in +++ b/src/nvim/testdir/test62.in @@ -13,7 +13,7 @@ STARTTEST  :" Open three tab pages and use ":tabdo"  :0tabnew  :1tabnew -:888tabnew +:$tabnew  :tabdo call append(line('$'), 'this is tab page ' . tabpagenr())  :tabclose! 2  :tabrewind diff --git a/src/nvim/testdir/test_argument_0count.in b/src/nvim/testdir/test_argument_0count.in new file mode 100644 index 0000000000..88317fa1fc --- /dev/null +++ b/src/nvim/testdir/test_argument_0count.in @@ -0,0 +1,28 @@ +Tests for :0argadd and :0argedit     vim: set ft=vim : + +STARTTEST +:so small.vim +:let arglists = [] +:%argd +:arga a b c d +:2argu +:0arga added +:call add(arglists, argv()) +:2argu +:arga third +:call add(arglists, argv()) +:%argd +:arga a b c d +:2argu +:0arge edited +:call add(arglists, argv()) +:2argu +:arga third +:call add(arglists, argv()) +:e! test.out +:call append(0, map(copy(arglists), 'join(v:val, " ")')) +:w +:qa! +ENDTEST + + diff --git a/src/nvim/testdir/test_argument_0count.ok b/src/nvim/testdir/test_argument_0count.ok new file mode 100644 index 0000000000..ee5daea812 --- /dev/null +++ b/src/nvim/testdir/test_argument_0count.ok @@ -0,0 +1,5 @@ +added a b c d +added a third b c d +edited a b c d +edited a third b c d + diff --git a/src/nvim/testdir/test_argument_count.in b/src/nvim/testdir/test_argument_count.in new file mode 100644 index 0000000000..af91f38375 --- /dev/null +++ b/src/nvim/testdir/test_argument_count.in @@ -0,0 +1,46 @@ +Tests for :[count]argument! and :[count]argdelete     vim: set ft=vim : + +STARTTEST +:%argd +:argadd a b c d +:set hidden +:let buffers = [] +:augroup TEST +:au BufEnter * call add(buffers, expand('%:t')) +:augroup END +:$argu +:$-argu +:-argu +:1argu +:+2argu +:augroup TEST +:au! +:augroup END +:let arglists = [] +:.argd +:call add(arglists, argv()) +:-argd +:call add(arglists, argv()) +:$argd +:call add(arglists, argv()) +:1arga c +:1arga b +:$argu +:$arga x +:call add(arglists, argv()) +:0arga Y +:call add(arglists, argv()) +:%argd +:call add(arglists, argv()) +:arga a b c d e f +:2,$-argd +:call add(arglists, argv()) +:e! test.out +:call append(0, buffers) +:let lnr = line('$') +:call append(lnr, map(copy(arglists), 'join(v:val, " ")')) +:w +:qa! +ENDTEST + + diff --git a/src/nvim/testdir/test_argument_count.ok b/src/nvim/testdir/test_argument_count.ok new file mode 100644 index 0000000000..f51562620d --- /dev/null +++ b/src/nvim/testdir/test_argument_count.ok @@ -0,0 +1,13 @@ +d +c +b +a +c + +a b d +a d +a +a b c x +Y a b c x + +a f diff --git a/src/nvim/testdir/test_close_count.in b/src/nvim/testdir/test_close_count.in new file mode 100644 index 0000000000..58dfb425ce --- /dev/null +++ b/src/nvim/testdir/test_close_count.in @@ -0,0 +1,156 @@ +Tests for :[count]close! and :[count]hide     vim: set ft=vim : + +STARTTEST +:let tests = [] +:so tiny.vim +:for i in range(5) +:new +:endfor +:4wincmd w +:close! +:let buffers = [] +:windo call add(buffers, bufnr('%')) +:call add(tests, buffers) +:1close! +:let buffers = [] +:windo call add(buffers, bufnr('%')) +:call add(tests, buffers) +:$close! +:let buffers = [] +:windo call add(buffers, bufnr('%')) +:call add(tests, buffers) +:1wincmd w +:2close! +:let buffers = [] +:windo call add(buffers, bufnr('%')) +:call add(tests, buffers) +:1wincmd w +:new +:new +:2wincmd w +:-1close! +:let buffers = [] +:windo call add(buffers, bufnr('%')) +:call add(tests, buffers) +:2wincmd w +:+1close! +:let buffers = [] +:windo call add(buffers, bufnr('%')) +:call add(tests, buffers) +:e! test.out +:call append(0, map(copy(tests), 'join(v:val, " ")')) +:w +:only! +:b1 +ENDTEST + +STARTTEST +:let tests = [] +:so tiny.vim +:for i in range(5) +:new +:endfor +:let buffers = [] +:windo call add(buffers, bufnr('%')) +:call add(tests, buffers) +:4wincmd w +:.hide +:let buffers = [] +:windo call add(buffers, bufnr('%')) +:call add(tests, buffers) +:1hide +:let buffers = [] +:windo call add(buffers, bufnr('%')) +:call add(tests, buffers) +:$hide +:let buffers = [] +:windo call add(buffers, bufnr('%')) +:call add(tests, buffers) +:1wincmd w +:2hide +:let buffers = [] +:windo call add(buffers, bufnr('%')) +:call add(tests, buffers) +:1wincmd w +:new +:new +:3wincmd w +:-hide +:let buffers = [] +:windo call add(buffers, bufnr('%')) +:call add(tests, buffers) +:2wincmd w +:+hide +:let buffers = [] +:windo call add(buffers, bufnr('%')) +:call add(tests, buffers) +:e! test.out +:call append(line('$'), map(copy(tests), 'join(v:val, " ")')) +Go +:w +:only! +:b1 +ENDTEST + +STARTTEST +:let tests = [] +:so tiny.vim +:set hidden +:for i in range(5) +:new +:endfor +:1wincmd w +:$ hide +:let buffers = [] +:windo call add(buffers, bufnr('%')) +:call add(tests, buffers) +:$-1 close! +:let buffers = [] +:windo call add(buffers, bufnr('%')) +:call add(tests, buffers) +:1wincmd w +:.+close! +:let buffers = [] +:windo call add(buffers, bufnr('%')) +:call add(tests, buffers) +:e! test.out +:call append(line('$'), map(copy(tests), 'join(v:val, " ")')) +Go +:w +:only! +:b1 +ENDTEST + +STARTTEST +:let tests = [] +:so tiny.vim +:set hidden +:for i in range(5) +:new +:endfor +:4wincmd w +c +:let buffers = [] +:windo call add(buffers, bufnr('%')) +:call add(tests, buffers) +1c +:let buffers = [] +:windo call add(buffers, bufnr('%')) +:call add(tests, buffers) +9c +:let buffers = [] +:windo call add(buffers, bufnr('%')) +:call add(tests, buffers) +:1wincmd w +2c +:let buffers = [] +:windo call add(buffers, bufnr('%')) +:call add(tests, buffers) +:only! +:e! test.out +:call append(line('$'), map(copy(tests), 'join(v:val, " ")')) +:w +:qa! +ENDTEST + + diff --git a/src/nvim/testdir/test_close_count.ok b/src/nvim/testdir/test_close_count.ok new file mode 100644 index 0000000000..1cee870487 --- /dev/null +++ b/src/nvim/testdir/test_close_count.ok @@ -0,0 +1,23 @@ +6 5 4 2 1 +5 4 2 1 +5 4 2 +5 2 +7 5 2 +7 5 + +13 12 11 10 9 1 +13 12 11 9 1 +12 11 9 1 +12 11 9 +12 9 +15 12 9 +15 12 + +20 19 18 17 16 +20 19 18 16 +20 18 16 + +25 24 23 21 1 +24 23 21 1 +24 23 21 +24 21 diff --git a/src/nvim/testdir/test_command_count.in b/src/nvim/testdir/test_command_count.in new file mode 100644 index 0000000000..dd3c108360 --- /dev/null +++ b/src/nvim/testdir/test_command_count.in @@ -0,0 +1,157 @@ +Test for user command counts	    vim: set ft=vim : + +STARTTEST +:so tiny.vim +:lang C +:let g:lines = [] +:com -range=% RangeLines :call add(g:lines, 'RangeLines '.<line1>.' '.<line2>) +:com -range -addr=arguments RangeArguments :call add(g:lines, 'RangeArguments '.<line1>.' '.<line2>) +:com -range=% -addr=arguments RangeArgumentsAll :call add(g:lines, 'RangeArgumentsAll '.<line1>.' '.<line2>) +:com -range -addr=loaded_buffers RangeLoadedBuffers :call add(g:lines, 'RangeLoadedBuffers '.<line1>.' '.<line2>) +:com -range=% -addr=loaded_buffers RangeLoadedBuffersAll :call add(g:lines, 'RangeLoadedBuffersAll '.<line1>.' '.<line2>) +:com -range -addr=buffers RangeBuffers :call add(g:lines, 'RangeBuffers '.<line1>.' '.<line2>) +:com -range=% -addr=buffers RangeBuffersAll :call add(g:lines, 'RangeBuffersAll '.<line1>.' '.<line2>) +:com -range -addr=windows RangeWindows :call add(g:lines, 'RangeWindows '.<line1>.' '.<line2>) +:com -range=% -addr=windows RangeWindowsAll :call add(g:lines, 'RangeWindowsAll '.<line1>.' '.<line2>) +:com -range -addr=tabs RangeTabs :call add(g:lines, 'RangeTabs '.<line1>.' '.<line2>) +:com -range=% -addr=tabs RangeTabsAll :call add(g:lines, 'RangeTabsAll '.<line1>.' '.<line2>) +:set hidden +:arga a b c d +:argdo echo "loading buffers" +:argu 3 +:.-,$-RangeArguments +:%RangeArguments +:RangeArgumentsAll +:N +:.RangeArguments +:split|split|split|split +:3wincmd w +:.,$RangeWindows +:%RangeWindows +:RangeWindowsAll +:only +:blast|bd +:.,$RangeLoadedBuffers +:%RangeLoadedBuffers +:RangeLoadedBuffersAll +:.,$RangeBuffers +:%RangeBuffers +:RangeBuffersAll +:tabe|tabe|tabe|tabe +:normal 2gt +:.,$RangeTabs +:%RangeTabs +:RangeTabsAll +:1tabonly +:s/\n/\r\r\r\r\r/ +:2ma< +:$-ma> +:'<,'>RangeLines +:com -range=% -buffer LocalRangeLines :call add(g:lines, 'LocalRangeLines '.<line1>.' '.<line2>) +:'<,'>LocalRangeLines +:b1 +ENDTEST + +STARTTEST +:call add(g:lines, '') +:%argd +:arga a b c d +:let v:errmsg = '' +:5argu +:call add(g:lines, '5argu ' . v:errmsg) +:$argu +:call add(g:lines, '4argu ' . expand('%:t')) +:let v:errmsg = '' +:1argu +:call add(g:lines, '1argu ' . expand('%:t')) +:let v:errmsg = '' +:100b +:call add(g:lines, '100b ' . v:errmsg) +:split|split|split|split +:let v:errmsg = '' +:0close +:call add(g:lines, '0close ' . v:errmsg) +:$wincmd w +:$close +:call add(g:lines, '$close ' . winnr()) +:let v:errmsg = '' +:$+close +:call add(g:lines, '$+close ' . v:errmsg) +:$tabe +:call add(g:lines, '$tabe ' . tabpagenr()) +:let v:errmsg = '' +:$+tabe +:call add(g:lines, '$+tabe ' . v:errmsg) +:only! +:e x +:0tabm +:normal 1gt +:call add(g:lines, '0tabm ' . expand('%:t')) +:tabonly! +:only! +:e! test.out +:call append(0, g:lines) +:unlet g:lines +:w|bd +:b1 +ENDTEST + +STARTTEST +:let g:lines = [] +:func BufStatus() +:  call add(g:lines, 'aaa: ' . buflisted(g:buf_aaa) . ' bbb: ' . buflisted(g:buf_bbb) . ' ccc: ' . buflisted(g:buf_ccc)) +:endfunc +:se nohidden +:e aaa +:let buf_aaa = bufnr('%') +:e bbb +:let buf_bbb = bufnr('%') +:e ccc +:let buf_ccc = bufnr('%') +:b1 +:call BufStatus() +:exe buf_bbb . "," . buf_ccc . "bdelete" +:call BufStatus() +:exe buf_aaa . "bdelete" +:call BufStatus() +:e! test.out +:call append('$', g:lines) +:unlet g:lines +:delfunc BufStatus +:w|bd +:b1 +ENDTEST + +STARTTEST +:se hidden +:only! +:let g:lines = [] +:%argd +:arga a b c d e f +:3argu +:let args = '' +:.,$-argdo let args .= ' '.expand('%') +:call add(g:lines, 'argdo:' . args) +:split|split|split|split +:2wincmd w +:let windows = '' +:.,$-windo let windows .= ' '.winnr() +:call add(g:lines, 'windo:'. windows) +:b2 +:let buffers = '' +:.,$-bufdo let buffers .= ' '.bufnr('%') +:call add(g:lines, 'bufdo:' . buffers) +:let buffers = '' +:3,7bufdo let buffers .= ' '.bufnr('%') +:call add(g:lines, 'bufdo:' . buffers) +:tabe|tabe|tabe|tabe +:normal! 2gt +:let tabpages = '' +:.,$-tabdo let tabpages .= ' '.tabpagenr() +:call add(g:lines, 'tabdo:' . tabpages) +:e! test.out +:call append('$', g:lines) +:w|qa! +ENDTEST + + diff --git a/src/nvim/testdir/test_command_count.ok b/src/nvim/testdir/test_command_count.ok new file mode 100644 index 0000000000..8fdbc7748d --- /dev/null +++ b/src/nvim/testdir/test_command_count.ok @@ -0,0 +1,38 @@ +RangeArguments 2 4 +RangeArguments 1 5 +RangeArgumentsAll 1 5 +RangeArguments 2 2 +RangeWindows 3 5 +RangeWindows 1 5 +RangeWindowsAll 1 5 +RangeLoadedBuffers 2 4 +RangeLoadedBuffers 1 4 +RangeLoadedBuffersAll 1 4 +RangeBuffers 2 5 +RangeBuffers 1 5 +RangeBuffersAll 1 5 +RangeTabs 2 5 +RangeTabs 1 5 +RangeTabsAll 1 5 +RangeLines 2 5 +LocalRangeLines 2 5 + +5argu E16: Invalid range +4argu d +1argu a +100b E16: Invalid range +0close  +$close 3 +$+close E16: Invalid range +$tabe 2 +$+tabe E16: Invalid range +0tabm x + +aaa: 1 bbb: 1 ccc: 1 +aaa: 1 bbb: 0 ccc: 0 +aaa: 0 bbb: 0 ccc: 0 +argdo: c d e +windo: 2 3 4 +bufdo: 2 3 4 5 6 7 8 9 10 15 +bufdo: 3 4 5 6 7 +tabdo: 2 3 4 diff --git a/src/nvim/version.c b/src/nvim/version.c index 8622f9fe8a..3ca0b254f4 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -184,22 +184,22 @@ static int included_patches[] = {    //598,    //597,    //596, -  //595, +  595,    //594,    //593,    //592,    //591 NA    //590,    //589 NA -  //588, +  588,    //587,    //586 NA -  //585, +  585,    //584 NA    //583 NA    //582,    //581, -  //580, +  580,    //579,    578,    //577, @@ -207,18 +207,18 @@ static int included_patches[] = {    //575,    //574,    //573, -  //572, +  572,    //571 NA    //570 NA    //569, -  //568, +  568,    567, -  //566, -  //565, +  566, +  565,    //564,    563,    //562, -  //561, +  561,    //560 NA    559,    //558 NA @@ -233,14 +233,14 @@ static int included_patches[] = {    549,    //548 NA    547, -  //546, +  546,    545,    //544 NA    543, -  //542, +  542,    541,    //540 NA -  //539, +  539,    538,    537,    536, diff --git a/src/nvim/vim.h b/src/nvim/vim.h index 41fcff129c..127e385619 100644 --- a/src/nvim/vim.h +++ b/src/nvim/vim.h @@ -182,6 +182,7 @@ enum {    EXPAND_HISTORY,    EXPAND_USER,    EXPAND_SYNTIME, +  EXPAND_USER_ADDR_TYPE,  }; diff --git a/src/nvim/window.c b/src/nvim/window.c index 4f31c09eeb..f93e88deb2 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -124,10 +124,7 @@ do_window (    case Ctrl_HAT:    case '^':      CHECK_CMDWIN reset_VIsual_and_resel();      /* stop Visual mode */ -    STRCPY(cbuf, "split #"); -    if (Prenum) -      vim_snprintf((char *)cbuf + 7, sizeof(cbuf) - 7, -          "%" PRId64, (int64_t)Prenum); +    cmd_with_count("split #", cbuf, sizeof(cbuf), Prenum);      do_cmdline_cmd(cbuf);      break; @@ -151,14 +148,16 @@ newwindow:    case Ctrl_Q:    case 'q':      reset_VIsual_and_resel();                   /* stop Visual mode */ -    do_cmdline_cmd((char_u *)"quit"); +    cmd_with_count("quit", cbuf, sizeof(cbuf), Prenum); +    do_cmdline_cmd(cbuf);      break;    /* close current window */    case Ctrl_C:    case 'c':      reset_VIsual_and_resel();                   /* stop Visual mode */ -    do_cmdline_cmd((char_u *)"close"); +    cmd_with_count("close", cbuf, sizeof(cbuf), Prenum); +    do_cmdline_cmd(cbuf);      break;    /* close preview window */ @@ -183,7 +182,8 @@ newwindow:    case Ctrl_O:    case 'o':      CHECK_CMDWIN reset_VIsual_and_resel();      /* stop Visual mode */ -    do_cmdline_cmd((char_u *)"only"); +    cmd_with_count("only", cbuf, sizeof(cbuf), Prenum); +    do_cmdline_cmd(cbuf);      break;    /* cursor to next window with wrap around */ @@ -487,6 +487,16 @@ wingotofile:    }  } +static void cmd_with_count(char *cmd, char_u *bufp, size_t bufsize, +                           long Prenum) +{ +  size_t len = xstrlcpy((char *)bufp, cmd, bufsize); + +  if (Prenum > 0 && len < bufsize) { +    vim_snprintf((char *)bufp + len, bufsize - len, "%" PRId64, Prenum); +  } +} +  /*   * split the current window, implements CTRL-W s and :split   * | 
