Skip to content

Instantly share code, notes, and snippets.

@tyru
Created Aug 1, 2019
Embed
What would you like to do?
Add readable name to numbered-function (and vim-jp/vim-vimlparser profiling result)
SCRIPT /Users/tyru/config/home/volt/repos/github.com/vim-jp/vim-vimlparser/autoload/vimlparser.vim
Sourced 1 time
Total time: 0.011356
Self time: 0.011356
count total (s) self (s)
" vim:set ts=8 sts=2 sw=2 tw=0 et:
"
" VimL parser - Vim Script Parser
"
" License: This file is placed in the public domain.
1 0.000004 function! vimlparser#import() abort
return s:
endfunction
" @brief Read input as VimScript and return stringified AST.
" @param input Input filename or string of VimScript.
" @return Stringified AST.
1 0.000003 function! vimlparser#test(input, ...) abort
try
if a:0 > 0
let l:neovim = a:1
else
let l:neovim = 0
endif
let i = type(a:input) == 1 && filereadable(a:input) ? readfile(a:input) : split(a:input, "\n")
let r = s:StringReader.new(i)
let p = s:VimLParser.new(l:neovim)
let c = s:Compiler.new()
echo join(c.compile(p.parse(r)), "\n")
catch
echoerr substitute(v:throwpoint, '\.\.\zs\d\+', '\=s:numtoname(submatch(0))', 'g') . "\n" . v:exception
endtry
endfunction
1 0.000004 function! s:numtoname(num) abort
let sig = printf("function('%s')", a:num)
for k in keys(s:)
if type(s:[k]) == type({})
for name in keys(s:[k])
if type(s:[k][name]) == type(function('tr')) && string(s:[k][name]) == sig
return printf('%s.%s', k, name)
endif
endfor
endif
endfor
return a:num
endfunction
1 0.000005 let s:NIL = []
1 0.000003 let s:TRUE = 1
1 0.000020 let s:FALSE = 0
1 0.000008 let s:NODE_TOPLEVEL = 1
1 0.000006 let s:NODE_COMMENT = 2
1 0.000005 let s:NODE_EXCMD = 3
1 0.000005 let s:NODE_FUNCTION = 4
1 0.000006 let s:NODE_ENDFUNCTION = 5
1 0.000006 let s:NODE_DELFUNCTION = 6
1 0.000005 let s:NODE_RETURN = 7
1 0.000005 let s:NODE_EXCALL = 8
1 0.000005 let s:NODE_LET = 9
1 0.000006 let s:NODE_UNLET = 10
1 0.000006 let s:NODE_LOCKVAR = 11
1 0.000008 let s:NODE_UNLOCKVAR = 12
1 0.000005 let s:NODE_IF = 13
1 0.000006 let s:NODE_ELSEIF = 14
1 0.000005 let s:NODE_ELSE = 15
1 0.000005 let s:NODE_ENDIF = 16
1 0.000006 let s:NODE_WHILE = 17
1 0.000005 let s:NODE_ENDWHILE = 18
1 0.000004 let s:NODE_FOR = 19
1 0.000005 let s:NODE_ENDFOR = 20
1 0.000006 let s:NODE_CONTINUE = 21
1 0.000005 let s:NODE_BREAK = 22
1 0.000005 let s:NODE_TRY = 23
1 0.000005 let s:NODE_CATCH = 24
1 0.000005 let s:NODE_FINALLY = 25
1 0.000005 let s:NODE_ENDTRY = 26
1 0.000005 let s:NODE_THROW = 27
1 0.000005 let s:NODE_ECHO = 28
1 0.000005 let s:NODE_ECHON = 29
1 0.000005 let s:NODE_ECHOHL = 30
1 0.000005 let s:NODE_ECHOMSG = 31
1 0.000025 let s:NODE_ECHOERR = 32
1 0.000006 let s:NODE_EXECUTE = 33
1 0.000005 let s:NODE_TERNARY = 34
1 0.000005 let s:NODE_OR = 35
1 0.000004 let s:NODE_AND = 36
1 0.000006 let s:NODE_EQUAL = 37
1 0.000005 let s:NODE_EQUALCI = 38
1 0.000006 let s:NODE_EQUALCS = 39
1 0.000009 let s:NODE_NEQUAL = 40
1 0.000011 let s:NODE_NEQUALCI = 41
1 0.000009 let s:NODE_NEQUALCS = 42
1 0.000008 let s:NODE_GREATER = 43
1 0.000009 let s:NODE_GREATERCI = 44
1 0.000008 let s:NODE_GREATERCS = 45
1 0.000007 let s:NODE_GEQUAL = 46
1 0.000008 let s:NODE_GEQUALCI = 47
1 0.000007 let s:NODE_GEQUALCS = 48
1 0.000005 let s:NODE_SMALLER = 49
1 0.000006 let s:NODE_SMALLERCI = 50
1 0.000006 let s:NODE_SMALLERCS = 51
1 0.000005 let s:NODE_SEQUAL = 52
1 0.000005 let s:NODE_SEQUALCI = 53
1 0.000006 let s:NODE_SEQUALCS = 54
1 0.000005 let s:NODE_MATCH = 55
1 0.000005 let s:NODE_MATCHCI = 56
1 0.000006 let s:NODE_MATCHCS = 57
1 0.000005 let s:NODE_NOMATCH = 58
1 0.000006 let s:NODE_NOMATCHCI = 59
1 0.000005 let s:NODE_NOMATCHCS = 60
1 0.000005 let s:NODE_IS = 61
1 0.000005 let s:NODE_ISCI = 62
1 0.000005 let s:NODE_ISCS = 63
1 0.000024 let s:NODE_ISNOT = 64
1 0.000005 let s:NODE_ISNOTCI = 65
1 0.000006 let s:NODE_ISNOTCS = 66
1 0.000005 let s:NODE_ADD = 67
1 0.000006 let s:NODE_SUBTRACT = 68
1 0.000005 let s:NODE_CONCAT = 69
1 0.000005 let s:NODE_MULTIPLY = 70
1 0.000005 let s:NODE_DIVIDE = 71
1 0.000005 let s:NODE_REMAINDER = 72
1 0.000005 let s:NODE_NOT = 73
1 0.000005 let s:NODE_MINUS = 74
1 0.000005 let s:NODE_PLUS = 75
1 0.000006 let s:NODE_SUBSCRIPT = 76
1 0.000005 let s:NODE_SLICE = 77
1 0.000005 let s:NODE_CALL = 78
1 0.000005 let s:NODE_DOT = 79
1 0.000014 let s:NODE_NUMBER = 80
1 0.000005 let s:NODE_STRING = 81
1 0.000023 let s:NODE_LIST = 82
1 0.000003 let s:NODE_DICT = 83
1 0.000003 let s:NODE_OPTION = 85
1 0.000004 let s:NODE_IDENTIFIER = 86
1 0.000003 let s:NODE_CURLYNAME = 87
1 0.000003 let s:NODE_ENV = 88
1 0.000003 let s:NODE_REG = 89
1 0.000004 let s:NODE_CURLYNAMEPART = 90
1 0.000004 let s:NODE_CURLYNAMEEXPR = 91
1 0.000003 let s:NODE_LAMBDA = 92
1 0.000004 let s:NODE_BLOB = 93
1 0.000003 let s:NODE_CONST = 94
1 0.000003 let s:TOKEN_EOF = 1
1 0.000015 let s:TOKEN_EOL = 2
1 0.000004 let s:TOKEN_SPACE = 3
1 0.000003 let s:TOKEN_OROR = 4
1 0.000004 let s:TOKEN_ANDAND = 5
1 0.000003 let s:TOKEN_EQEQ = 6
1 0.000003 let s:TOKEN_EQEQCI = 7
1 0.000004 let s:TOKEN_EQEQCS = 8
1 0.000003 let s:TOKEN_NEQ = 9
1 0.000003 let s:TOKEN_NEQCI = 10
1 0.000003 let s:TOKEN_NEQCS = 11
1 0.000003 let s:TOKEN_GT = 12
1 0.000003 let s:TOKEN_GTCI = 13
1 0.000003 let s:TOKEN_GTCS = 14
1 0.000004 let s:TOKEN_GTEQ = 15
1 0.000003 let s:TOKEN_GTEQCI = 16
1 0.000004 let s:TOKEN_GTEQCS = 17
1 0.000003 let s:TOKEN_LT = 18
1 0.000004 let s:TOKEN_LTCI = 19
1 0.000003 let s:TOKEN_LTCS = 20
1 0.000003 let s:TOKEN_LTEQ = 21
1 0.000004 let s:TOKEN_LTEQCI = 22
1 0.000003 let s:TOKEN_LTEQCS = 23
1 0.000003 let s:TOKEN_MATCH = 24
1 0.000004 let s:TOKEN_MATCHCI = 25
1 0.000003 let s:TOKEN_MATCHCS = 26
1 0.000003 let s:TOKEN_NOMATCH = 27
1 0.000004 let s:TOKEN_NOMATCHCI = 28
1 0.000004 let s:TOKEN_NOMATCHCS = 29
1 0.000287 let s:TOKEN_IS = 30
1 0.000006 let s:TOKEN_ISCI = 31
1 0.000004 let s:TOKEN_ISCS = 32
1 0.000003 let s:TOKEN_ISNOT = 33
1 0.000022 let s:TOKEN_ISNOTCI = 34
1 0.000003 let s:TOKEN_ISNOTCS = 35
1 0.000007 let s:TOKEN_PLUS = 36
1 0.000004 let s:TOKEN_MINUS = 37
1 0.000003 let s:TOKEN_DOT = 38
1 0.000003 let s:TOKEN_STAR = 39
1 0.000003 let s:TOKEN_SLASH = 40
1 0.000004 let s:TOKEN_PERCENT = 41
1 0.000003 let s:TOKEN_NOT = 42
1 0.000004 let s:TOKEN_QUESTION = 43
1 0.000004 let s:TOKEN_COLON = 44
1 0.000003 let s:TOKEN_POPEN = 45
1 0.000004 let s:TOKEN_PCLOSE = 46
1 0.000004 let s:TOKEN_SQOPEN = 47
1 0.000003 let s:TOKEN_SQCLOSE = 48
1 0.000004 let s:TOKEN_COPEN = 49
1 0.000003 let s:TOKEN_CCLOSE = 50
1 0.000004 let s:TOKEN_COMMA = 51
1 0.000003 let s:TOKEN_NUMBER = 52
1 0.000004 let s:TOKEN_SQUOTE = 53
1 0.000017 let s:TOKEN_DQUOTE = 54
1 0.000002 let s:TOKEN_OPTION = 55
1 0.000002 let s:TOKEN_IDENTIFIER = 56
1 0.000002 let s:TOKEN_ENV = 57
1 0.000001 let s:TOKEN_REG = 58
1 0.000002 let s:TOKEN_EQ = 59
1 0.000002 let s:TOKEN_OR = 60
1 0.000003 let s:TOKEN_SEMICOLON = 61
1 0.000002 let s:TOKEN_BACKTICK = 62
1 0.000002 let s:TOKEN_DOTDOTDOT = 63
1 0.000002 let s:TOKEN_SHARP = 64
1 0.000002 let s:TOKEN_ARROW = 65
1 0.000010 let s:TOKEN_BLOB = 66
1 0.000002 let s:TOKEN_LITCOPEN = 67
1 0.000002 let s:TOKEN_DOTDOT = 68
1 0.000002 let s:MAX_FUNC_ARGS = 20
1 0.000005 function! s:isalpha(c) abort
return a:c =~# '^[A-Za-z]$'
endfunction
1 0.000003 function! s:isalnum(c) abort
return a:c =~# '^[0-9A-Za-z]$'
endfunction
1 0.000002 function! s:isdigit(c) abort
return a:c =~# '^[0-9]$'
endfunction
1 0.000002 function! s:isodigit(c) abort
return a:c =~# '^[0-7]$'
endfunction
1 0.000002 function! s:isxdigit(c) abort
return a:c =~# '^[0-9A-Fa-f]$'
endfunction
1 0.000002 function! s:iswordc(c) abort
return a:c =~# '^[0-9A-Za-z_]$'
endfunction
1 0.000001 function! s:iswordc1(c) abort
return a:c =~# '^[A-Za-z_]$'
endfunction
1 0.000002 function! s:iswhite(c) abort
return a:c =~# '^[ \t]$'
endfunction
1 0.000002 function! s:isnamec(c) abort
return a:c =~# '^[0-9A-Za-z_:#]$'
endfunction
1 0.000002 function! s:isnamec1(c) abort
return a:c =~# '^[A-Za-z_]$'
endfunction
1 0.000002 function! s:isargname(s) abort
return a:s =~# '^[A-Za-z_][0-9A-Za-z_]*$'
endfunction
1 0.000002 function! s:isvarname(s) abort
return a:s =~# '^[vgslabwt]:$\|^\([vgslabwt]:\)\?[A-Za-z_][0-9A-Za-z_#]*$'
endfunction
" FIXME:
1 0.000001 function! s:isidc(c) abort
return a:c =~# '^[0-9A-Za-z_]$'
endfunction
1 0.000002 function! s:isupper(c) abort
return a:c =~# '^[A-Z]$'
endfunction
1 0.000002 function! s:islower(c) abort
return a:c =~# '^[a-z]$'
endfunction
1 0.000002 function! s:ExArg() abort
let ea = {}
let ea.forceit = s:FALSE
let ea.addr_count = 0
let ea.line1 = 0
let ea.line2 = 0
let ea.flags = 0
let ea.do_ecmd_cmd = ''
let ea.do_ecmd_lnum = 0
let ea.append = 0
let ea.usefilter = s:FALSE
let ea.amount = 0
let ea.regname = 0
let ea.force_bin = 0
let ea.read_edit = 0
let ea.force_ff = 0
let ea.force_enc = 0
let ea.bad_char = 0
let ea.linepos = {}
let ea.cmdpos = []
let ea.argpos = []
let ea.cmd = {}
let ea.modifiers = []
let ea.range = []
let ea.argopt = {}
let ea.argcmd = {}
return ea
endfunction
" struct node {
" int type
" pos pos
" node left
" node right
" node cond
" node rest
" node[] list
" node[] rlist
" node[] body
" string op
" string str
" int depth
" variant value
" }
" TOPLEVEL .body
" COMMENT .str
" EXCMD .ea .str
" FUNCTION .ea .body .left .rlist .attr .endfunction
" ENDFUNCTION .ea
" DELFUNCTION .ea .left
" RETURN .ea .left
" EXCALL .ea .left
" LET .ea .op .left .list .rest .right
" CONST .ea .op .left .list .rest .right
" UNLET .ea .list
" LOCKVAR .ea .depth .list
" UNLOCKVAR .ea .depth .list
" IF .ea .body .cond .elseif .else .endif
" ELSEIF .ea .body .cond
" ELSE .ea .body
" ENDIF .ea
" WHILE .ea .body .cond .endwhile
" ENDWHILE .ea
" FOR .ea .body .left .list .rest .right .endfor
" ENDFOR .ea
" CONTINUE .ea
" BREAK .ea
" TRY .ea .body .catch .finally .endtry
" CATCH .ea .body .pattern
" FINALLY .ea .body
" ENDTRY .ea
" THROW .ea .left
" ECHO .ea .list
" ECHON .ea .list
" ECHOHL .ea .str
" ECHOMSG .ea .list
" ECHOERR .ea .list
" EXECUTE .ea .list
" TERNARY .cond .left .right
" OR .left .right
" AND .left .right
" EQUAL .left .right
" EQUALCI .left .right
" EQUALCS .left .right
" NEQUAL .left .right
" NEQUALCI .left .right
" NEQUALCS .left .right
" GREATER .left .right
" GREATERCI .left .right
" GREATERCS .left .right
" GEQUAL .left .right
" GEQUALCI .left .right
" GEQUALCS .left .right
" SMALLER .left .right
" SMALLERCI .left .right
" SMALLERCS .left .right
" SEQUAL .left .right
" SEQUALCI .left .right
" SEQUALCS .left .right
" MATCH .left .right
" MATCHCI .left .right
" MATCHCS .left .right
" NOMATCH .left .right
" NOMATCHCI .left .right
" NOMATCHCS .left .right
" IS .left .right
" ISCI .left .right
" ISCS .left .right
" ISNOT .left .right
" ISNOTCI .left .right
" ISNOTCS .left .right
" ADD .left .right
" SUBTRACT .left .right
" CONCAT .left .right
" MULTIPLY .left .right
" DIVIDE .left .right
" REMAINDER .left .right
" NOT .left
" MINUS .left
" PLUS .left
" SUBSCRIPT .left .right
" SLICE .left .rlist
" CALL .left .rlist
" DOT .left .right
" NUMBER .value
" STRING .value
" LIST .value
" DICT .value
" NESTING .left
" OPTION .value
" IDENTIFIER .value
" CURLYNAME .value
" ENV .value
" REG .value
" CURLYNAMEPART .value
" CURLYNAMEEXPR .value
" LAMBDA .rlist .left
1 0.000004 function! s:Node(type) abort
return {'type': a:type}
endfunction
1 0.000002 function! s:Err(msg, pos) abort
return printf('vimlparser: %s: line %d col %d', a:msg, a:pos.lnum, a:pos.col)
endfunction
1 0.000004 let s:VimLParser = {}
1 0.000002 function! s:VimLParser.new(...) abort
let obj = copy(self)
call call(obj.__init__, a:000, obj)
return obj
endfunction
1 0.000002 function! s:VimLParser.__init__(...) abort
if len(a:000) > 0
let self.neovim = a:000[0]
else
let self.neovim = 0
endif
let self.find_command_cache = {}
endfunction
1 0.000003 function! s:VimLParser.push_context(node) abort
call insert(self.context, a:node)
endfunction
1 0.000002 function! s:VimLParser.pop_context() abort
call remove(self.context, 0)
endfunction
1 0.000003 function! s:VimLParser.find_context(type) abort
let i = 0
for node in self.context
if node.type == a:type
return i
endif
let i += 1
endfor
return -1
endfunction
1 0.000030 function! s:VimLParser.add_node(node) abort
call add(self.context[0].body, a:node)
endfunction
1 0.000005 function! s:VimLParser.check_missing_endfunction(ends, pos) abort
if self.context[0].type == s:NODE_FUNCTION
throw s:Err(printf('E126: Missing :endfunction: %s', a:ends), a:pos)
endif
endfunction
1 0.000005 function! s:VimLParser.check_missing_endif(ends, pos) abort
if self.context[0].type == s:NODE_IF || self.context[0].type == s:NODE_ELSEIF || self.context[0].type == s:NODE_ELSE
throw s:Err(printf('E171: Missing :endif: %s', a:ends), a:pos)
endif
endfunction
1 0.000002 function! s:VimLParser.check_missing_endtry(ends, pos) abort
if self.context[0].type == s:NODE_TRY || self.context[0].type == s:NODE_CATCH || self.context[0].type == s:NODE_FINALLY
throw s:Err(printf('E600: Missing :endtry: %s', a:ends), a:pos)
endif
endfunction
1 0.000002 function! s:VimLParser.check_missing_endwhile(ends, pos) abort
if self.context[0].type == s:NODE_WHILE
throw s:Err(printf('E170: Missing :endwhile: %s', a:ends), a:pos)
endif
endfunction
1 0.000003 function! s:VimLParser.check_missing_endfor(ends, pos) abort
if self.context[0].type == s:NODE_FOR
throw s:Err(printf('E170: Missing :endfor: %s', a:ends), a:pos)
endif
endfunction
1 0.000003 function! s:VimLParser.parse(reader) abort
let self.reader = a:reader
let self.context = []
let toplevel = s:Node(s:NODE_TOPLEVEL)
let toplevel.pos = self.reader.getpos()
let toplevel.body = []
call self.push_context(toplevel)
while self.reader.peek() !=# '<EOF>'
call self.parse_one_cmd()
endwhile
call self.check_missing_endfunction('TOPLEVEL', self.reader.getpos())
call self.check_missing_endif('TOPLEVEL', self.reader.getpos())
call self.check_missing_endtry('TOPLEVEL', self.reader.getpos())
call self.check_missing_endwhile('TOPLEVEL', self.reader.getpos())
call self.check_missing_endfor('TOPLEVEL', self.reader.getpos())
call self.pop_context()
return toplevel
endfunction
1 0.000002 function! s:VimLParser.parse_one_cmd() abort
let self.ea = s:ExArg()
if self.reader.peekn(2) ==# '#!'
call self.parse_hashbang()
call self.reader.get()
return
endif
call self.reader.skip_white_and_colon()
if self.reader.peekn(1) ==# ''
call self.reader.get()
return
endif
if self.reader.peekn(1) ==# '"'
call self.parse_comment()
call self.reader.get()
return
endif
let self.ea.linepos = self.reader.getpos()
call self.parse_command_modifiers()
call self.parse_range()
call self.parse_command()
call self.parse_trail()
endfunction
" FIXME:
1 0.000002 function! s:VimLParser.parse_command_modifiers() abort
let modifiers = []
while s:TRUE
let pos = self.reader.tell()
let d = ''
if s:isdigit(self.reader.peekn(1))
let d = self.reader.read_digit()
call self.reader.skip_white()
endif
let k = self.reader.read_alpha()
let c = self.reader.peekn(1)
call self.reader.skip_white()
if stridx('aboveleft', k) == 0 && len(k) >= 3 " abo\%[veleft]
call add(modifiers, {'name': 'aboveleft'})
elseif stridx('belowright', k) == 0 && len(k) >= 3 " bel\%[owright]
call add(modifiers, {'name': 'belowright'})
elseif stridx('browse', k) == 0 && len(k) >= 3 " bro\%[wse]
call add(modifiers, {'name': 'browse'})
elseif stridx('botright', k) == 0 && len(k) >= 2 " bo\%[tright]
call add(modifiers, {'name': 'botright'})
elseif stridx('confirm', k) == 0 && len(k) >= 4 " conf\%[irm]
call add(modifiers, {'name': 'confirm'})
elseif stridx('keepmarks', k) == 0 && len(k) >= 3 " kee\%[pmarks]
call add(modifiers, {'name': 'keepmarks'})
elseif stridx('keepalt', k) == 0 && len(k) >= 5 " keepa\%[lt]
call add(modifiers, {'name': 'keepalt'})
elseif stridx('keepjumps', k) == 0 && len(k) >= 5 " keepj\%[umps]
call add(modifiers, {'name': 'keepjumps'})
elseif stridx('keeppatterns', k) == 0 && len(k) >= 5 " keepp\%[atterns]
call add(modifiers, {'name': 'keeppatterns'})
elseif stridx('hide', k) == 0 && len(k) >= 3 " hid\%[e]
if self.ends_excmds(c)
break
endif
call add(modifiers, {'name': 'hide'})
elseif stridx('lockmarks', k) == 0 && len(k) >= 3 " loc\%[kmarks]
call add(modifiers, {'name': 'lockmarks'})
elseif stridx('leftabove', k) == 0 && len(k) >= 5 " lefta\%[bove]
call add(modifiers, {'name': 'leftabove'})
elseif stridx('noautocmd', k) == 0 && len(k) >= 3 " noa\%[utocmd]
call add(modifiers, {'name': 'noautocmd'})
elseif stridx('noswapfile', k) == 0 && len(k) >= 3 " :nos\%[wapfile]
call add(modifiers, {'name': 'noswapfile'})
elseif stridx('rightbelow', k) == 0 && len(k) >= 6 " rightb\%[elow]
call add(modifiers, {'name': 'rightbelow'})
elseif stridx('sandbox', k) == 0 && len(k) >= 3 " san\%[dbox]
call add(modifiers, {'name': 'sandbox'})
elseif stridx('silent', k) == 0 && len(k) >= 3 " sil\%[ent]
if c ==# '!'
call self.reader.get()
call add(modifiers, {'name': 'silent', 'bang': 1})
else
call add(modifiers, {'name': 'silent', 'bang': 0})
endif
elseif k ==# 'tab' " tab
if d !=# ''
call add(modifiers, {'name': 'tab', 'count': str2nr(d, 10)})
else
call add(modifiers, {'name': 'tab'})
endif
elseif stridx('topleft', k) == 0 && len(k) >= 2 " to\%[pleft]
call add(modifiers, {'name': 'topleft'})
elseif stridx('unsilent', k) == 0 && len(k) >= 3 " uns\%[ilent]
call add(modifiers, {'name': 'unsilent'})
elseif stridx('vertical', k) == 0 && len(k) >= 4 " vert\%[ical]
call add(modifiers, {'name': 'vertical'})
elseif stridx('verbose', k) == 0 && len(k) >= 4 " verb\%[ose]
if d !=# ''
call add(modifiers, {'name': 'verbose', 'count': str2nr(d, 10)})
else
call add(modifiers, {'name': 'verbose', 'count': 1})
endif
else
call self.reader.seek_set(pos)
break
endif
endwhile
let self.ea.modifiers = modifiers
endfunction
" FIXME:
1 0.000002 function! s:VimLParser.parse_range() abort
let tokens = []
while s:TRUE
while s:TRUE
call self.reader.skip_white()
let c = self.reader.peekn(1)
if c ==# ''
break
endif
if c ==# '.'
call add(tokens, self.reader.getn(1))
elseif c ==# '$'
call add(tokens, self.reader.getn(1))
elseif c ==# "'"
call self.reader.getn(1)
let m = self.reader.getn(1)
if m ==# ''
break
endif
call add(tokens, "'" . m)
elseif c ==# '/'
call self.reader.getn(1)
let [pattern, _] = self.parse_pattern(c)
call add(tokens, pattern)
elseif c ==# '?'
call self.reader.getn(1)
let [pattern, _] = self.parse_pattern(c)
call add(tokens, pattern)
elseif c ==# '\'
let m = self.reader.p(1)
if m ==# '&' || m ==# '?' || m ==# '/'
call self.reader.seek_cur(2)
call add(tokens, '\' . m)
else
throw s:Err('E10: \\ should be followed by /, ? or &', self.reader.getpos())
endif
elseif s:isdigit(c)
call add(tokens, self.reader.read_digit())
endif
while s:TRUE
call self.reader.skip_white()
if self.reader.peekn(1) ==# ''
break
endif
let n = self.reader.read_integer()
if n ==# ''
break
endif
call add(tokens, n)
endwhile
if self.reader.p(0) !=# '/' && self.reader.p(0) !=# '?'
break
endif
endwhile
if self.reader.peekn(1) ==# '%'
call add(tokens, self.reader.getn(1))
elseif self.reader.peekn(1) ==# '*' " && &cpoptions !~ '\*'
call add(tokens, self.reader.getn(1))
endif
if self.reader.peekn(1) ==# ';'
call add(tokens, self.reader.getn(1))
continue
elseif self.reader.peekn(1) ==# ','
call add(tokens, self.reader.getn(1))
continue
endif
break
endwhile
let self.ea.range = tokens
endfunction
" FIXME:
1 0.000003 function! s:VimLParser.parse_pattern(delimiter) abort
let pattern = ''
let endc = ''
let inbracket = 0
while s:TRUE
let c = self.reader.getn(1)
if c ==# ''
break
endif
if c ==# a:delimiter && inbracket == 0
let endc = c
break
endif
let pattern .= c
if c ==# '\'
let c = self.reader.peekn(1)
if c ==# ''
throw s:Err('E682: Invalid search pattern or delimiter', self.reader.getpos())
endif
call self.reader.getn(1)
let pattern .= c
elseif c ==# '['
let inbracket += 1
elseif c ==# ']'
let inbracket -= 1
endif
endwhile
return [pattern, endc]
endfunction
1 0.000002 function! s:VimLParser.parse_command() abort
call self.reader.skip_white_and_colon()
let self.ea.cmdpos = self.reader.getpos()
if self.reader.peekn(1) ==# '' || self.reader.peekn(1) ==# '"'
if !empty(self.ea.modifiers) || !empty(self.ea.range)
call self.parse_cmd_modifier_range()
endif
return
endif
let self.ea.cmd = self.find_command()
if self.ea.cmd is# s:NIL
call self.reader.setpos(self.ea.cmdpos)
throw s:Err(printf('E492: Not an editor command: %s', self.reader.peekline()), self.ea.cmdpos)
endif
if self.reader.peekn(1) ==# '!' && self.ea.cmd.name !=# 'substitute' && self.ea.cmd.name !=# 'smagic' && self.ea.cmd.name !=# 'snomagic'
call self.reader.getn(1)
let self.ea.forceit = s:TRUE
else
let self.ea.forceit = s:FALSE
endif
if self.ea.cmd.flags !~# '\<BANG\>' && self.ea.forceit && self.ea.cmd.flags !~# '\<USERCMD\>'
throw s:Err('E477: No ! allowed', self.ea.cmdpos)
endif
if self.ea.cmd.name !=# '!'
call self.reader.skip_white()
endif
let self.ea.argpos = self.reader.getpos()
if self.ea.cmd.flags =~# '\<ARGOPT\>'
call self.parse_argopt()
endif
if self.ea.cmd.name ==# 'write' || self.ea.cmd.name ==# 'update'
if self.reader.p(0) ==# '>'
if self.reader.p(1) !=# '>'
throw s:Err('E494: Use w or w>>', self.ea.cmdpos)
endif
call self.reader.seek_cur(2)
call self.reader.skip_white()
let self.ea.append = 1
elseif self.reader.peekn(1) ==# '!' && self.ea.cmd.name ==# 'write'
call self.reader.getn(1)
let self.ea.usefilter = s:TRUE
endif
endif
if self.ea.cmd.name ==# 'read'
if self.ea.forceit
let self.ea.usefilter = s:TRUE
let self.ea.forceit = s:FALSE
elseif self.reader.peekn(1) ==# '!'
call self.reader.getn(1)
let self.ea.usefilter = s:TRUE
endif
endif
if self.ea.cmd.name ==# '<' || self.ea.cmd.name ==# '>'
let self.ea.amount = 1
while self.reader.peekn(1) ==# self.ea.cmd.name
call self.reader.getn(1)
let self.ea.amount += 1
endwhile
call self.reader.skip_white()
endif
if self.ea.cmd.flags =~# '\<EDITCMD\>' && !self.ea.usefilter
call self.parse_argcmd()
endif
call self._parse_command(self.ea.cmd.parser)
endfunction
" TODO: self[a:parser]
1 0.000003 function! s:VimLParser._parse_command(parser) abort
if a:parser ==# 'parse_cmd_append'
call self.parse_cmd_append()
elseif a:parser ==# 'parse_cmd_break'
call self.parse_cmd_break()
elseif a:parser ==# 'parse_cmd_call'
call self.parse_cmd_call()
elseif a:parser ==# 'parse_cmd_catch'
call self.parse_cmd_catch()
elseif a:parser ==# 'parse_cmd_common'
call self.parse_cmd_common()
elseif a:parser ==# 'parse_cmd_continue'
call self.parse_cmd_continue()
elseif a:parser ==# 'parse_cmd_delfunction'
call self.parse_cmd_delfunction()
elseif a:parser ==# 'parse_cmd_echo'
call self.parse_cmd_echo()
elseif a:parser ==# 'parse_cmd_echoerr'
call self.parse_cmd_echoerr()
elseif a:parser ==# 'parse_cmd_echohl'
call self.parse_cmd_echohl()
elseif a:parser ==# 'parse_cmd_echomsg'
call self.parse_cmd_echomsg()
elseif a:parser ==# 'parse_cmd_echon'
call self.parse_cmd_echon()
elseif a:parser ==# 'parse_cmd_else'
call self.parse_cmd_else()
elseif a:parser ==# 'parse_cmd_elseif'
call self.parse_cmd_elseif()
elseif a:parser ==# 'parse_cmd_endfor'
call self.parse_cmd_endfor()
elseif a:parser ==# 'parse_cmd_endfunction'
call self.parse_cmd_endfunction()
elseif a:parser ==# 'parse_cmd_endif'
call self.parse_cmd_endif()
elseif a:parser ==# 'parse_cmd_endtry'
call self.parse_cmd_endtry()
elseif a:parser ==# 'parse_cmd_endwhile'
call self.parse_cmd_endwhile()
elseif a:parser ==# 'parse_cmd_execute'
call self.parse_cmd_execute()
elseif a:parser ==# 'parse_cmd_finally'
call self.parse_cmd_finally()
elseif a:parser ==# 'parse_cmd_finish'
call self.parse_cmd_finish()
elseif a:parser ==# 'parse_cmd_for'
call self.parse_cmd_for()
elseif a:parser ==# 'parse_cmd_function'
call self.parse_cmd_function()
elseif a:parser ==# 'parse_cmd_if'
call self.parse_cmd_if()
elseif a:parser ==# 'parse_cmd_insert'
call self.parse_cmd_insert()
elseif a:parser ==# 'parse_cmd_let'
call self.parse_cmd_let()
elseif a:parser ==# 'parse_cmd_const'
call self.parse_cmd_const()
elseif a:parser ==# 'parse_cmd_loadkeymap'
call self.parse_cmd_loadkeymap()
elseif a:parser ==# 'parse_cmd_lockvar'
call self.parse_cmd_lockvar()
elseif a:parser ==# 'parse_cmd_lua'
call self.parse_cmd_lua()
elseif a:parser ==# 'parse_cmd_modifier_range'
call self.parse_cmd_modifier_range()
elseif a:parser ==# 'parse_cmd_mzscheme'
call self.parse_cmd_mzscheme()
elseif a:parser ==# 'parse_cmd_perl'
call self.parse_cmd_perl()
elseif a:parser ==# 'parse_cmd_python'
call self.parse_cmd_python()
elseif a:parser ==# 'parse_cmd_python3'
call self.parse_cmd_python3()
elseif a:parser ==# 'parse_cmd_return'
call self.parse_cmd_return()
elseif a:parser ==# 'parse_cmd_ruby'
call self.parse_cmd_ruby()
elseif a:parser ==# 'parse_cmd_tcl'
call self.parse_cmd_tcl()
elseif a:parser ==# 'parse_cmd_throw'
call self.parse_cmd_throw()
elseif a:parser ==# 'parse_cmd_try'
call self.parse_cmd_try()
elseif a:parser ==# 'parse_cmd_unlet'
call self.parse_cmd_unlet()
elseif a:parser ==# 'parse_cmd_unlockvar'
call self.parse_cmd_unlockvar()
elseif a:parser ==# 'parse_cmd_usercmd'
call self.parse_cmd_usercmd()
elseif a:parser ==# 'parse_cmd_while'
call self.parse_cmd_while()
elseif a:parser ==# 'parse_wincmd'
call self.parse_wincmd()
elseif a:parser ==# 'parse_cmd_syntax'
call self.parse_cmd_syntax()
else
throw printf('unknown parser: %s', string(a:parser))
endif
endfunction
1 0.000002 function! s:VimLParser.find_command() abort
let c = self.reader.peekn(1)
let name = ''
if c ==# 'k'
call self.reader.getn(1)
let name = 'k'
elseif c ==# 's' && self.reader.peekn(5) =~# '\v^s%(c[^sr][^i][^p]|g|i[^mlg]|I|r[^e])'
call self.reader.getn(1)
let name = 'substitute'
elseif c =~# '[@*!=><&~#]'
call self.reader.getn(1)
let name = c
elseif self.reader.peekn(2) ==# 'py'
let name = self.reader.read_alnum()
else
let pos = self.reader.tell()
let name = self.reader.read_alpha()
if name !=# 'del' && name =~# '\v^d%[elete][lp]$'
call self.reader.seek_set(pos)
let name = self.reader.getn(len(name) - 1)
endif
endif
if name ==# ''
return s:NIL
endif
if has_key(self.find_command_cache, name)
return self.find_command_cache[name]
endif
let cmd = s:NIL
for x in self.builtin_commands
if stridx(x.name, name) == 0 && len(name) >= x.minlen
unlet cmd
let cmd = x
break
endif
endfor
if self.neovim
for x in self.neovim_additional_commands
if stridx(x.name, name) == 0 && len(name) >= x.minlen
unlet cmd
let cmd = x
break
endif
endfor
for x in self.neovim_removed_commands
if stridx(x.name, name) == 0 && len(name) >= x.minlen
unlet cmd
let cmd = s:NIL
break
endif
endfor
endif
" FIXME: user defined command
if (cmd is# s:NIL || cmd.name ==# 'Print') && name =~# '^[A-Z]'
let name .= self.reader.read_alnum()
unlet cmd
let cmd = {'name': name, 'flags': 'USERCMD', 'parser': 'parse_cmd_usercmd'}
endif
let self.find_command_cache[name] = cmd
return cmd
endfunction
" TODO:
1 0.000002 function! s:VimLParser.parse_hashbang() abort
call self.reader.getn(-1)
endfunction
" TODO:
" ++opt=val
1 0.000002 function! s:VimLParser.parse_argopt() abort
while self.reader.p(0) ==# '+' && self.reader.p(1) ==# '+'
let s = self.reader.peekn(20)
if s =~# '^++bin\>'
call self.reader.getn(5)
let self.ea.force_bin = 1
elseif s =~# '^++nobin\>'
call self.reader.getn(7)
let self.ea.force_bin = 2
elseif s =~# '^++edit\>'
call self.reader.getn(6)
let self.ea.read_edit = 1
elseif s =~# '^++ff=\(dos\|unix\|mac\)\>'
call self.reader.getn(5)
let self.ea.force_ff = self.reader.read_alpha()
elseif s =~# '^++fileformat=\(dos\|unix\|mac\)\>'
call self.reader.getn(13)
let self.ea.force_ff = self.reader.read_alpha()
elseif s =~# '^++enc=\S'
call self.reader.getn(6)
let self.ea.force_enc = self.reader.read_nonwhite()
elseif s =~# '^++encoding=\S'
call self.reader.getn(11)
let self.ea.force_enc = self.reader.read_nonwhite()
elseif s =~# '^++bad=\(keep\|drop\|.\)\>'
call self.reader.getn(6)
if s =~# '^++bad=keep'
let self.ea.bad_char = self.reader.getn(4)
elseif s =~# '^++bad=drop'
let self.ea.bad_char = self.reader.getn(4)
else
let self.ea.bad_char = self.reader.getn(1)
endif
elseif s =~# '^++'
throw s:Err('E474: Invalid Argument', self.reader.getpos())
else
break
endif
call self.reader.skip_white()
endwhile
endfunction
" TODO:
" +command
1 0.000002 function! s:VimLParser.parse_argcmd() abort
if self.reader.peekn(1) ==# '+'
call self.reader.getn(1)
if self.reader.peekn(1) ==# ' '
let self.ea.do_ecmd_cmd = '$'
else
let self.ea.do_ecmd_cmd = self.read_cmdarg()
endif
endif
endfunction
1 0.000002 function! s:VimLParser.read_cmdarg() abort
let r = ''
while s:TRUE
let c = self.reader.peekn(1)
if c ==# '' || s:iswhite(c)
break
endif
call self.reader.getn(1)
if c ==# '\'
let c = self.reader.getn(1)
endif
let r .= c
endwhile
return r
endfunction
1 0.000002 function! s:VimLParser.parse_comment() abort
let npos = self.reader.getpos()
let c = self.reader.get()
if c !=# '"'
throw s:Err(printf('unexpected character: %s', c), npos)
endif
let node = s:Node(s:NODE_COMMENT)
let node.pos = npos
let node.str = self.reader.getn(-1)
call self.add_node(node)
endfunction
1 0.000009 function! s:VimLParser.parse_trail() abort
call self.reader.skip_white()
let c = self.reader.peek()
if c ==# '<EOF>'
" pass
elseif c ==# '<EOL>'
call self.reader.get()
elseif c ==# '|'
call self.reader.get()
elseif c ==# '"'
call self.parse_comment()
call self.reader.get()
else
throw s:Err(printf('E488: Trailing characters: %s', c), self.reader.getpos())
endif
endfunction
" modifier or range only command line
1 0.000002 function! s:VimLParser.parse_cmd_modifier_range() abort
let node = s:Node(s:NODE_EXCMD)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let node.str = self.reader.getstr(self.ea.linepos, self.reader.getpos())
call self.add_node(node)
endfunction
" TODO:
1 0.000002 function! s:VimLParser.parse_cmd_common() abort
let end = self.reader.getpos()
if self.ea.cmd.flags =~# '\<TRLBAR\>' && !self.ea.usefilter
let end = self.separate_nextcmd()
elseif self.ea.cmd.name ==# '!' || self.ea.cmd.name ==# 'global' || self.ea.cmd.name ==# 'vglobal' || self.ea.usefilter
while s:TRUE
let end = self.reader.getpos()
if self.reader.getn(1) ==# ''
break
endif
endwhile
else
while s:TRUE
let end = self.reader.getpos()
if self.reader.getn(1) ==# ''
break
endif
endwhile
endif
let node = s:Node(s:NODE_EXCMD)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let node.str = self.reader.getstr(self.ea.linepos, end)
call self.add_node(node)
endfunction
1 0.000002 function! s:VimLParser.separate_nextcmd() abort
if self.ea.cmd.name ==# 'vimgrep' || self.ea.cmd.name ==# 'vimgrepadd' || self.ea.cmd.name ==# 'lvimgrep' || self.ea.cmd.name ==# 'lvimgrepadd'
call self.skip_vimgrep_pat()
endif
let pc = ''
let end = self.reader.getpos()
let nospend = end
while s:TRUE
let end = self.reader.getpos()
if !s:iswhite(pc)
let nospend = end
endif
let c = self.reader.peek()
if c ==# '<EOF>' || c ==# '<EOL>'
break
elseif c ==# "\x16" " <C-V>
call self.reader.get()
let end = self.reader.getpos()
let nospend = self.reader.getpos()
let c = self.reader.peek()
if c ==# '<EOF>' || c ==# '<EOL>'
break
endif
call self.reader.get()
elseif self.reader.peekn(2) ==# '`=' && self.ea.cmd.flags =~# '\<\(XFILE\|FILES\|FILE1\)\>'
call self.reader.getn(2)
call self.parse_expr()
let c = self.reader.peekn(1)
if c !=# '`'
throw s:Err(printf('unexpected character: %s', c), self.reader.getpos())
endif
call self.reader.getn(1)
elseif c ==# '|' || c ==# "\n" ||
\ (c ==# '"' && self.ea.cmd.flags !~# '\<NOTRLCOM\>'
\ && ((self.ea.cmd.name !=# '@' && self.ea.cmd.name !=# '*')
\ || self.reader.getpos() !=# self.ea.argpos)
\ && (self.ea.cmd.name !=# 'redir'
\ || self.reader.getpos().i !=# self.ea.argpos.i + 1 || pc !=# '@'))
let has_cpo_bar = s:FALSE " &cpoptions =~ 'b'
if (!has_cpo_bar || self.ea.cmd.flags !~# '\<USECTRLV\>') && pc ==# '\'
call self.reader.get()
else
break
endif
else
call self.reader.get()
endif
let pc = c
endwhile
if self.ea.cmd.flags !~# '\<NOTRLCOM\>'
let end = nospend
endif
return end
endfunction
" FIXME
1 0.000002 function! s:VimLParser.skip_vimgrep_pat() abort
if self.reader.peekn(1) ==# ''
" pass
elseif s:isidc(self.reader.peekn(1))
" :vimgrep pattern fname
call self.reader.read_nonwhite()
else
" :vimgrep /pattern/[g][j] fname
let c = self.reader.getn(1)
let [_, endc] = self.parse_pattern(c)
if c !=# endc
return
endif
while self.reader.p(0) ==# 'g' || self.reader.p(0) ==# 'j'
call self.reader.getn(1)
endwhile
endif
endfunction
1 0.000008 function! s:VimLParser.parse_cmd_append() abort
call self.reader.setpos(self.ea.linepos)
let cmdline = self.reader.readline()
let lines = [cmdline]
let m = '.'
while s:TRUE
if self.reader.peek() ==# '<EOF>'
break
endif
let line = self.reader.getn(-1)
call add(lines, line)
if line ==# m
break
endif
call self.reader.get()
endwhile
let node = s:Node(s:NODE_EXCMD)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let node.str = join(lines, "\n")
call self.add_node(node)
endfunction
1 0.000001 function! s:VimLParser.parse_cmd_insert() abort
call self.parse_cmd_append()
endfunction
1 0.000002 function! s:VimLParser.parse_cmd_loadkeymap() abort
call self.reader.setpos(self.ea.linepos)
let cmdline = self.reader.readline()
let lines = [cmdline]
while s:TRUE
if self.reader.peek() ==# '<EOF>'
break
endif
let line = self.reader.readline()
call add(lines, line)
endwhile
let node = s:Node(s:NODE_EXCMD)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let node.str = join(lines, "\n")
call self.add_node(node)
endfunction
1 0.000003 function! s:VimLParser.parse_cmd_lua() abort
let lines = []
call self.reader.skip_white()
if self.reader.peekn(2) ==# '<<'
call self.reader.getn(2)
call self.reader.skip_white()
let m = self.reader.readline()
if m ==# ''
let m = '.'
endif
call self.reader.setpos(self.ea.linepos)
let cmdline = self.reader.getn(-1)
let lines = [cmdline]
call self.reader.get()
while s:TRUE
if self.reader.peek() ==# '<EOF>'
break
endif
let line = self.reader.getn(-1)
call add(lines, line)
if line ==# m
break
endif
call self.reader.get()
endwhile
else
call self.reader.setpos(self.ea.linepos)
let cmdline = self.reader.getn(-1)
let lines = [cmdline]
endif
let node = s:Node(s:NODE_EXCMD)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let node.str = join(lines, "\n")
call self.add_node(node)
endfunction
1 0.000002 function! s:VimLParser.parse_cmd_mzscheme() abort
call self.parse_cmd_lua()
endfunction
1 0.000002 function! s:VimLParser.parse_cmd_perl() abort
call self.parse_cmd_lua()
endfunction
1 0.000001 function! s:VimLParser.parse_cmd_python() abort
call self.parse_cmd_lua()
endfunction
1 0.000002 function! s:VimLParser.parse_cmd_python3() abort
call self.parse_cmd_lua()
endfunction
1 0.000002 function! s:VimLParser.parse_cmd_ruby() abort
call self.parse_cmd_lua()
endfunction
1 0.000002 function! s:VimLParser.parse_cmd_tcl() abort
call self.parse_cmd_lua()
endfunction
1 0.000001 function! s:VimLParser.parse_cmd_finish() abort
call self.parse_cmd_common()
if self.context[0].type == s:NODE_TOPLEVEL
call self.reader.seek_end(0)
endif
endfunction
" FIXME
1 0.000002 function! s:VimLParser.parse_cmd_usercmd() abort
call self.parse_cmd_common()
endfunction
1 0.000002 function! s:VimLParser.parse_cmd_function() abort
let pos = self.reader.tell()
call self.reader.skip_white()
" :function
if self.ends_excmds(self.reader.peek())
call self.reader.seek_set(pos)
call self.parse_cmd_common()
return
endif
" :function /pattern
if self.reader.peekn(1) ==# '/'
call self.reader.seek_set(pos)
call self.parse_cmd_common()
return
endif
let left = self.parse_lvalue_func()
call self.reader.skip_white()
if left.type == s:NODE_IDENTIFIER
let s = left.value
let ss = split(s, '\zs')
if ss[0] !=# '<' && !s:isupper(ss[0]) && stridx(s, ':') == -1 && stridx(s, '#') == -1
throw s:Err(printf('E128: Function name must start with a capital or contain a colon: %s', s), left.pos)
endif
endif
" :function {name}
if self.reader.peekn(1) !=# '('
call self.reader.seek_set(pos)
call self.parse_cmd_common()
return
endif
" :function[!] {name}([arguments]) [range] [abort] [dict] [closure]
let node = s:Node(s:NODE_FUNCTION)
let node.pos = self.ea.cmdpos
let node.body = []
let node.ea = self.ea
let node.left = left
let node.rlist = []
let node.attr = {'range': 0, 'abort': 0, 'dict': 0, 'closure': 0}
let node.endfunction = s:NIL
call self.reader.getn(1)
let tokenizer = s:ExprTokenizer.new(self.reader)
if tokenizer.peek().type == s:TOKEN_PCLOSE
call tokenizer.get()
else
let named = {}
while s:TRUE
let varnode = s:Node(s:NODE_IDENTIFIER)
let token = tokenizer.get()
if token.type == s:TOKEN_IDENTIFIER
if !s:isargname(token.value) || token.value ==# 'firstline' || token.value ==# 'lastline'
throw s:Err(printf('E125: Illegal argument: %s', token.value), token.pos)
elseif has_key(named, token.value)
throw s:Err(printf('E853: Duplicate argument name: %s', token.value), token.pos)
endif
let named[token.value] = 1
let varnode.pos = token.pos
let varnode.value = token.value
call add(node.rlist, varnode)
" XXX: Vim doesn't skip white space before comma. F(a ,b) => E475
if s:iswhite(self.reader.p(0)) && tokenizer.peek().type == s:TOKEN_COMMA
throw s:Err('E475: Invalid argument: White space is not allowed before comma', self.reader.getpos())
endif
let token = tokenizer.get()
if token.type == s:TOKEN_COMMA
" XXX: Vim allows last comma. F(a, b, ) => OK
if tokenizer.peek().type == s:TOKEN_PCLOSE
call tokenizer.get()
break
endif
elseif token.type == s:TOKEN_PCLOSE
break
else
throw s:Err(printf('unexpected token: %s', token.value), token.pos)
endif
elseif token.type == s:TOKEN_DOTDOTDOT
let varnode.pos = token.pos
let varnode.value = token.value
call add(node.rlist, varnode)
let token = tokenizer.get()
if token.type == s:TOKEN_PCLOSE
break
else
throw s:Err(printf('unexpected token: %s', token.value), token.pos)
endif
else
throw s:Err(printf('unexpected token: %s', token.value), token.pos)
endif
endwhile
endif
while s:TRUE
call self.reader.skip_white()
let epos = self.reader.getpos()
let key = self.reader.read_alpha()
if key ==# ''
break
elseif key ==# 'range'
let node.attr.range = s:TRUE
elseif key ==# 'abort'
let node.attr.abort = s:TRUE
elseif key ==# 'dict'
let node.attr.dict = s:TRUE
elseif key ==# 'closure'
let node.attr.closure = s:TRUE
else
throw s:Err(printf('unexpected token: %s', key), epos)
endif
endwhile
call self.add_node(node)
call self.push_context(node)
endfunction
1 0.000003 function! s:VimLParser.parse_cmd_endfunction() abort
call self.check_missing_endif('ENDFUNCTION', self.ea.cmdpos)
call self.check_missing_endtry('ENDFUNCTION', self.ea.cmdpos)
call self.check_missing_endwhile('ENDFUNCTION', self.ea.cmdpos)
call self.check_missing_endfor('ENDFUNCTION', self.ea.cmdpos)
if self.context[0].type !=# s:NODE_FUNCTION
throw s:Err('E193: :endfunction not inside a function', self.ea.cmdpos)
endif
call self.reader.getn(-1)
let node = s:Node(s:NODE_ENDFUNCTION)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let self.context[0].endfunction = node
call self.pop_context()
endfunction
1 0.000002 function! s:VimLParser.parse_cmd_delfunction() abort
let node = s:Node(s:NODE_DELFUNCTION)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let node.left = self.parse_lvalue_func()
call self.add_node(node)
endfunction
1 0.000002 function! s:VimLParser.parse_cmd_return() abort
if self.find_context(s:NODE_FUNCTION) == -1
throw s:Err('E133: :return not inside a function', self.ea.cmdpos)
endif
let node = s:Node(s:NODE_RETURN)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let node.left = s:NIL
call self.reader.skip_white()
let c = self.reader.peek()
if c ==# '"' || !self.ends_excmds(c)
let node.left = self.parse_expr()
endif
call self.add_node(node)
endfunction
1 0.000002 function! s:VimLParser.parse_cmd_call() abort
let node = s:Node(s:NODE_EXCALL)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
call self.reader.skip_white()
let c = self.reader.peek()
if self.ends_excmds(c)
throw s:Err('E471: Argument required', self.reader.getpos())
endif
let node.left = self.parse_expr()
if node.left.type !=# s:NODE_CALL
throw s:Err('Not an function call', node.left.pos)
endif
call self.add_node(node)
endfunction
1 0.000002 function! s:VimLParser.parse_cmd_let() abort
let pos = self.reader.tell()
call self.reader.skip_white()
" :let
if self.ends_excmds(self.reader.peek())
call self.reader.seek_set(pos)
call self.parse_cmd_common()
return
endif
let lhs = self.parse_letlhs()
call self.reader.skip_white()
let s1 = self.reader.peekn(1)
let s2 = self.reader.peekn(2)
" TODO check scriptversion?
if s2 ==# '..'
let s2 = self.reader.peekn(3)
endif
" :let {var-name} ..
if self.ends_excmds(s1) || (s2 !=# '+=' && s2 !=# '-=' && s2 !=# '.=' && s2 !=# '..=' && s2 !=# '*=' && s2 !=# '/=' && s2 !=# '%=' && s1 !=# '=')
call self.reader.seek_set(pos)
call self.parse_cmd_common()
return
endif
" :let left op right
let node = s:Node(s:NODE_LET)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let node.op = ''
let node.left = lhs.left
let node.list = lhs.list
let node.rest = lhs.rest
let node.right = s:NIL
if s2 ==# '+=' || s2 ==# '-=' || s2 ==# '.=' || s2 ==# '..=' || s2 ==# '*=' || s2 ==# '/=' || s2 ==# '%='
call self.reader.getn(len(s2))
let node.op = s2
elseif s1 ==# '='
call self.reader.getn(1)
let node.op = s1
else
throw 'NOT REACHED'
endif
let node.right = self.parse_expr()
call self.add_node(node)
endfunction
1 0.000002 function! s:VimLParser.parse_cmd_const() abort
let pos = self.reader.tell()
call self.reader.skip_white()
" :const
if self.ends_excmds(self.reader.peek())
call self.reader.seek_set(pos)
call self.parse_cmd_common()
return
endif
let lhs = self.parse_constlhs()
call self.reader.skip_white()
let s1 = self.reader.peekn(1)
" :const {var-name}
if self.ends_excmds(s1) || s1 !=# '='
call self.reader.seek_set(pos)
call self.parse_cmd_common()
return
endif
" :const left op right
let node = s:Node(s:NODE_CONST)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
call self.reader.getn(1)
let node.op = s1
let node.left = lhs.left
let node.list = lhs.list
let node.rest = lhs.rest
let node.right = self.parse_expr()
call self.add_node(node)
endfunction
1 0.000002 function! s:VimLParser.parse_cmd_unlet() abort
let node = s:Node(s:NODE_UNLET)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let node.list = self.parse_lvaluelist()
call self.add_node(node)
endfunction
1 0.000002 function! s:VimLParser.parse_cmd_lockvar() abort
let node = s:Node(s:NODE_LOCKVAR)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let node.depth = s:NIL
let node.list = []
call self.reader.skip_white()
if s:isdigit(self.reader.peekn(1))
let node.depth = str2nr(self.reader.read_digit(), 10)
endif
let node.list = self.parse_lvaluelist()
call self.add_node(node)
endfunction
1 0.000002 function! s:VimLParser.parse_cmd_unlockvar() abort
let node = s:Node(s:NODE_UNLOCKVAR)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let node.depth = s:NIL
let node.list = []
call self.reader.skip_white()
if s:isdigit(self.reader.peekn(1))
let node.depth = str2nr(self.reader.read_digit(), 10)
endif
let node.list = self.parse_lvaluelist()
call self.add_node(node)
endfunction
1 0.000002 function! s:VimLParser.parse_cmd_if() abort
let node = s:Node(s:NODE_IF)
let node.pos = self.ea.cmdpos
let node.body = []
let node.ea = self.ea
let node.cond = self.parse_expr()
let node.elseif = []
let node.else = s:NIL
let node.endif = s:NIL
call self.add_node(node)
call self.push_context(node)
endfunction
1 0.000003 function! s:VimLParser.parse_cmd_elseif() abort
if self.context[0].type !=# s:NODE_IF && self.context[0].type !=# s:NODE_ELSEIF
throw s:Err('E582: :elseif without :if', self.ea.cmdpos)
endif
if self.context[0].type !=# s:NODE_IF
call self.pop_context()
endif
let node = s:Node(s:NODE_ELSEIF)
let node.pos = self.ea.cmdpos
let node.body = []
let node.ea = self.ea
let node.cond = self.parse_expr()
call add(self.context[0].elseif, node)
call self.push_context(node)
endfunction
1 0.000008 function! s:VimLParser.parse_cmd_else() abort
if self.context[0].type !=# s:NODE_IF && self.context[0].type !=# s:NODE_ELSEIF
throw s:Err('E581: :else without :if', self.ea.cmdpos)
endif
if self.context[0].type !=# s:NODE_IF
call self.pop_context()
endif
let node = s:Node(s:NODE_ELSE)
let node.pos = self.ea.cmdpos
let node.body = []
let node.ea = self.ea
let self.context[0].else = node
call self.push_context(node)
endfunction
1 0.000002 function! s:VimLParser.parse_cmd_endif() abort
if self.context[0].type !=# s:NODE_IF && self.context[0].type !=# s:NODE_ELSEIF && self.context[0].type !=# s:NODE_ELSE
throw s:Err('E580: :endif without :if', self.ea.cmdpos)
endif
if self.context[0].type !=# s:NODE_IF
call self.pop_context()
endif
let node = s:Node(s:NODE_ENDIF)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let self.context[0].endif = node
call self.pop_context()
endfunction
1 0.000002 function! s:VimLParser.parse_cmd_while() abort
let node = s:Node(s:NODE_WHILE)
let node.pos = self.ea.cmdpos
let node.body = []
let node.ea = self.ea
let node.cond = self.parse_expr()
let node.endwhile = s:NIL
call self.add_node(node)
call self.push_context(node)
endfunction
1 0.000013 function! s:VimLParser.parse_cmd_endwhile() abort
if self.context[0].type !=# s:NODE_WHILE
throw s:Err('E588: :endwhile without :while', self.ea.cmdpos)
endif
let node = s:Node(s:NODE_ENDWHILE)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let self.context[0].endwhile = node
call self.pop_context()
endfunction
1 0.000003 function! s:VimLParser.parse_cmd_for() abort
let node = s:Node(s:NODE_FOR)
let node.pos = self.ea.cmdpos
let node.body = []
let node.ea = self.ea
let node.left = s:NIL
let node.right = s:NIL
let node.endfor = s:NIL
let lhs = self.parse_letlhs()
let node.left = lhs.left
let node.list = lhs.list
let node.rest = lhs.rest
call self.reader.skip_white()
let epos = self.reader.getpos()
if self.reader.read_alpha() !=# 'in'
throw s:Err('Missing "in" after :for', epos)
endif
let node.right = self.parse_expr()
call self.add_node(node)
call self.push_context(node)
endfunction
1 0.000003 function! s:VimLParser.parse_cmd_endfor() abort
if self.context[0].type !=# s:NODE_FOR
throw s:Err('E588: :endfor without :for', self.ea.cmdpos)
endif
let node = s:Node(s:NODE_ENDFOR)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let self.context[0].endfor = node
call self.pop_context()
endfunction
1 0.000003 function! s:VimLParser.parse_cmd_continue() abort
if self.find_context(s:NODE_WHILE) == -1 && self.find_context(s:NODE_FOR) == -1
throw s:Err('E586: :continue without :while or :for', self.ea.cmdpos)
endif
let node = s:Node(s:NODE_CONTINUE)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
call self.add_node(node)
endfunction
1 0.000003 function! s:VimLParser.parse_cmd_break() abort
if self.find_context(s:NODE_WHILE) == -1 && self.find_context(s:NODE_FOR) == -1
throw s:Err('E587: :break without :while or :for', self.ea.cmdpos)
endif
let node = s:Node(s:NODE_BREAK)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
call self.add_node(node)
endfunction
1 0.000012 function! s:VimLParser.parse_cmd_try() abort
let node = s:Node(s:NODE_TRY)
let node.pos = self.ea.cmdpos
let node.body = []
let node.ea = self.ea
let node.catch = []
let node.finally = s:NIL
let node.endtry = s:NIL
call self.add_node(node)
call self.push_context(node)
endfunction
1 0.000002 function! s:VimLParser.parse_cmd_catch() abort
if self.context[0].type == s:NODE_FINALLY
throw s:Err('E604: :catch after :finally', self.ea.cmdpos)
elseif self.context[0].type !=# s:NODE_TRY && self.context[0].type !=# s:NODE_CATCH
throw s:Err('E603: :catch without :try', self.ea.cmdpos)
endif
if self.context[0].type !=# s:NODE_TRY
call self.pop_context()
endif
let node = s:Node(s:NODE_CATCH)
let node.pos = self.ea.cmdpos
let node.body = []
let node.ea = self.ea
let node.pattern = s:NIL
call self.reader.skip_white()
if !self.ends_excmds(self.reader.peek())
let [node.pattern, _] = self.parse_pattern(self.reader.get())
endif
call add(self.context[0].catch, node)
call self.push_context(node)
endfunction
1 0.000004 function! s:VimLParser.parse_cmd_finally() abort
if self.context[0].type !=# s:NODE_TRY && self.context[0].type !=# s:NODE_CATCH
throw s:Err('E606: :finally without :try', self.ea.cmdpos)
endif
if self.context[0].type !=# s:NODE_TRY
call self.pop_context()
endif
let node = s:Node(s:NODE_FINALLY)
let node.pos = self.ea.cmdpos
let node.body = []
let node.ea = self.ea
let self.context[0].finally = node
call self.push_context(node)
endfunction
1 0.000003 function! s:VimLParser.parse_cmd_endtry() abort
if self.context[0].type !=# s:NODE_TRY && self.context[0].type !=# s:NODE_CATCH && self.context[0].type !=# s:NODE_FINALLY
throw s:Err('E602: :endtry without :try', self.ea.cmdpos)
endif
if self.context[0].type !=# s:NODE_TRY
call self.pop_context()
endif
let node = s:Node(s:NODE_ENDTRY)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let self.context[0].endtry = node
call self.pop_context()
endfunction
1 0.000003 function! s:VimLParser.parse_cmd_throw() abort
let node = s:Node(s:NODE_THROW)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let node.left = self.parse_expr()
call self.add_node(node)
endfunction
1 0.000003 function! s:VimLParser.parse_cmd_echo() abort
let node = s:Node(s:NODE_ECHO)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let node.list = self.parse_exprlist()
call self.add_node(node)
endfunction
1 0.000002 function! s:VimLParser.parse_cmd_echon() abort
let node = s:Node(s:NODE_ECHON)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let node.list = self.parse_exprlist()
call self.add_node(node)
endfunction
1 0.000002 function! s:VimLParser.parse_cmd_echohl() abort
let node = s:Node(s:NODE_ECHOHL)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let node.str = ''
while !self.ends_excmds(self.reader.peek())
let node.str .= self.reader.get()
endwhile
call self.add_node(node)
endfunction
1 0.000003 function! s:VimLParser.parse_cmd_echomsg() abort
let node = s:Node(s:NODE_ECHOMSG)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let node.list = self.parse_exprlist()
call self.add_node(node)
endfunction
1 0.000002 function! s:VimLParser.parse_cmd_echoerr() abort
let node = s:Node(s:NODE_ECHOERR)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let node.list = self.parse_exprlist()
call self.add_node(node)
endfunction
1 0.000003 function! s:VimLParser.parse_cmd_execute() abort
let node = s:Node(s:NODE_EXECUTE)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let node.list = self.parse_exprlist()
call self.add_node(node)
endfunction
1 0.000003 function! s:VimLParser.parse_expr() abort
return s:ExprParser.new(self.reader).parse()
endfunction
1 0.000002 function! s:VimLParser.parse_exprlist() abort
let list = []
while s:TRUE
call self.reader.skip_white()
let c = self.reader.peek()
if c !=# '"' && self.ends_excmds(c)
break
endif
let node = self.parse_expr()
call add(list, node)
endwhile
return list
endfunction
1 0.000003 function! s:VimLParser.parse_lvalue_func() abort
let p = s:LvalueParser.new(self.reader)
let node = p.parse()
if node.type == s:NODE_IDENTIFIER || node.type == s:NODE_CURLYNAME || node.type == s:NODE_SUBSCRIPT || node.type == s:NODE_DOT || node.type == s:NODE_OPTION || node.type == s:NODE_ENV || node.type == s:NODE_REG
return node
endif
throw s:Err('Invalid Expression', node.pos)
endfunction
" FIXME:
1 0.000003 function! s:VimLParser.parse_lvalue() abort
let p = s:LvalueParser.new(self.reader)
let node = p.parse()
if node.type == s:NODE_IDENTIFIER
if !s:isvarname(node.value)
throw s:Err(printf('E461: Illegal variable name: %s', node.value), node.pos)
endif
endif
if node.type == s:NODE_IDENTIFIER || node.type == s:NODE_CURLYNAME || node.type == s:NODE_SUBSCRIPT || node.type == s:NODE_SLICE || node.type == s:NODE_DOT || node.type == s:NODE_OPTION || node.type == s:NODE_ENV || node.type == s:NODE_REG
return node
endif
throw s:Err('Invalid Expression', node.pos)
endfunction
" TODO: merge with s:VimLParser.parse_lvalue()
1 0.000003 function! s:VimLParser.parse_constlvalue() abort
let p = s:LvalueParser.new(self.reader)
let node = p.parse()
if node.type == s:NODE_IDENTIFIER
if !s:isvarname(node.value)
throw s:Err(printf('E461: Illegal variable name: %s', node.value), node.pos)
endif
endif
if node.type == s:NODE_IDENTIFIER || node.type == s:NODE_CURLYNAME
return node
elseif node.type == s:NODE_SUBSCRIPT || node.type == s:NODE_SLICE || node.type == s:NODE_DOT
throw s:Err('E996: Cannot lock a list or dict', node.pos)
elseif node.type == s:NODE_OPTION
throw s:Err('E996: Cannot lock an option', node.pos)
elseif node.type == s:NODE_ENV
throw s:Err('E996: Cannot lock an environment variable', node.pos)
elseif node.type == s:NODE_REG
throw s:Err('E996: Cannot lock a register', node.pos)
endif
throw s:Err('Invalid Expression', node.pos)
endfunction
1 0.000003 function! s:VimLParser.parse_lvaluelist() abort
let list = []
let node = self.parse_expr()
call add(list, node)
while s:TRUE
call self.reader.skip_white()
if self.ends_excmds(self.reader.peek())
break
endif
let node = self.parse_lvalue()
call add(list, node)
endwhile
return list
endfunction
" FIXME:
1 0.000003 function! s:VimLParser.parse_letlhs() abort
let lhs = {'left': s:NIL, 'list': s:NIL, 'rest': s:NIL}
let tokenizer = s:ExprTokenizer.new(self.reader)
if tokenizer.peek().type == s:TOKEN_SQOPEN
call tokenizer.get()
let lhs.list = []
while s:TRUE
let node = self.parse_lvalue()
call add(lhs.list, node)
let token = tokenizer.get()
if token.type == s:TOKEN_SQCLOSE
break
elseif token.type == s:TOKEN_COMMA
continue
elseif token.type == s:TOKEN_SEMICOLON
let node = self.parse_lvalue()
let lhs.rest = node
let token = tokenizer.get()
if token.type == s:TOKEN_SQCLOSE
break
else
throw s:Err(printf('E475 Invalid argument: %s', token.value), token.pos)
endif
else
throw s:Err(printf('E475 Invalid argument: %s', token.value), token.pos)
endif
endwhile
else
let lhs.left = self.parse_lvalue()
endif
return lhs
endfunction
" TODO: merge with s:VimLParser.parse_letlhs() ?
1 0.000003 function! s:VimLParser.parse_constlhs() abort
let lhs = {'left': s:NIL, 'list': s:NIL, 'rest': s:NIL}
let tokenizer = s:ExprTokenizer.new(self.reader)
if tokenizer.peek().type == s:TOKEN_SQOPEN
call tokenizer.get()
let lhs.list = []
while s:TRUE
let node = self.parse_lvalue()
call add(lhs.list, node)
let token = tokenizer.get()
if token.type == s:TOKEN_SQCLOSE
break
elseif token.type == s:TOKEN_COMMA
continue
elseif token.type == s:TOKEN_SEMICOLON
let node = self.parse_lvalue()
let lhs.rest = node
let token = tokenizer.get()
if token.type == s:TOKEN_SQCLOSE
break
else
throw s:Err(printf('E475 Invalid argument: %s', token.value), token.pos)
endif
else
throw s:Err(printf('E475 Invalid argument: %s', token.value), token.pos)
endif
endwhile
else
let lhs.left = self.parse_constlvalue()
endif
return lhs
endfunction
1 0.000003 function! s:VimLParser.ends_excmds(c) abort
return a:c ==# '' || a:c ==# '|' || a:c ==# '"' || a:c ==# '<EOF>' || a:c ==# '<EOL>'
endfunction
" FIXME: validate argument
1 0.000003 function! s:VimLParser.parse_wincmd() abort
let c = self.reader.getn(1)
if c ==# ''
throw s:Err('E471: Argument required', self.reader.getpos())
elseif c ==# 'g' || c ==# "\x07" " <C-G>
let c2 = self.reader.getn(1)
if c2 ==# '' || s:iswhite(c2)
throw s:Err('E474: Invalid Argument', self.reader.getpos())
endif
endif
let end = self.reader.getpos()
call self.reader.skip_white()
if !self.ends_excmds(self.reader.peek())
throw s:Err('E474: Invalid Argument', self.reader.getpos())
endif
let node = s:Node(s:NODE_EXCMD)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let node.str = self.reader.getstr(self.ea.linepos, end)
call self.add_node(node)
endfunction
" FIXME: validate argument
1 0.000003 function! s:VimLParser.parse_cmd_syntax() abort
let end = self.reader.getpos()
while s:TRUE
let end = self.reader.getpos()
let c = self.reader.peek()
if c ==# '/' || c ==# "'" || c ==# '"'
call self.reader.getn(1)
call self.parse_pattern(c)
elseif c ==# '='
call self.reader.getn(1)
call self.parse_pattern(' ')
elseif self.ends_excmds(c)
break
endif
call self.reader.getn(1)
endwhile
let node = s:Node(s:NODE_EXCMD)
let node.pos = self.ea.cmdpos
let node.ea = self.ea
let node.str = self.reader.getstr(self.ea.linepos, end)
call self.add_node(node)
endfunction
1 0.000025 let s:VimLParser.neovim_additional_commands = [
\ {'name': 'rshada', 'minlen': 3, 'flags': 'BANG|FILE1|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'wshada', 'minlen': 3, 'flags': 'BANG|FILE1|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'}]
1 0.000050 let s:VimLParser.neovim_removed_commands = [
\ {'name': 'Print', 'minlen':1, 'flags': 'RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'fixdel', 'minlen':3, 'flags': 'TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'helpfind', 'minlen':5, 'flags': 'EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'open', 'minlen':1, 'flags': 'RANGE|BANG|EXTRA', 'parser': 'parse_cmd_common'},
\ {'name': 'shell', 'minlen':2, 'flags': 'TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'tearoff', 'minlen':2, 'flags': 'NEEDARG|EXTRA|TRLBAR|NOTRLCOM|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'gvim', 'minlen':2, 'flags': 'BANG|FILES|EDITCMD|ARGOPT|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'}]
" To find new builtin_commands, run the below script.
" $ scripts/update_builtin_commands.sh /path/to/vim/src/ex_cmds.h
1 0.002518 let s:VimLParser.builtin_commands = [
\ {'name': 'append', 'minlen': 1, 'flags': 'BANG|RANGE|ZEROR|TRLBAR|CMDWIN|MODIFY', 'parser': 'parse_cmd_append'},
\ {'name': 'abbreviate', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'abclear', 'minlen': 3, 'flags': 'EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'aboveleft', 'minlen': 3, 'flags': 'NEEDARG|EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'all', 'minlen': 2, 'flags': 'BANG|RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'amenu', 'minlen': 2, 'flags': 'RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'anoremenu', 'minlen': 2, 'flags': 'RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'args', 'minlen': 2, 'flags': 'BANG|FILES|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'argadd', 'minlen': 4, 'flags': 'BANG|NEEDARG|RANGE|NOTADR|ZEROR|FILES|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'argdelete', 'minlen': 4, 'flags': 'BANG|RANGE|NOTADR|FILES|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'argedit', 'minlen': 4, 'flags': 'BANG|NEEDARG|RANGE|NOTADR|FILE1|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'argdo', 'minlen': 5, 'flags': 'BANG|NEEDARG|EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'argglobal', 'minlen': 4, 'flags': 'BANG|FILES|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'arglocal', 'minlen': 4, 'flags': 'BANG|FILES|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'argument', 'minlen': 4, 'flags': 'BANG|RANGE|NOTADR|COUNT|EXTRA|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'ascii', 'minlen': 2, 'flags': 'TRLBAR|SBOXOK|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'autocmd', 'minlen': 2, 'flags': 'BANG|EXTRA|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'augroup', 'minlen': 3, 'flags': 'BANG|WORD1|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'aunmenu', 'minlen': 3, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'buffer', 'minlen': 1, 'flags': 'BANG|RANGE|NOTADR|BUFNAME|BUFUNL|COUNT|EXTRA|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'bNext', 'minlen': 2, 'flags': 'BANG|RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'ball', 'minlen': 2, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'badd', 'minlen': 3, 'flags': 'NEEDARG|FILE1|EDITCMD|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'bdelete', 'minlen': 2, 'flags': 'BANG|RANGE|NOTADR|BUFNAME|COUNT|EXTRA|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'behave', 'minlen': 2, 'flags': 'NEEDARG|WORD1|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'belowright', 'minlen': 3, 'flags': 'NEEDARG|EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'bfirst', 'minlen': 2, 'flags': 'BANG|RANGE|NOTADR|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'blast', 'minlen': 2, 'flags': 'BANG|RANGE|NOTADR|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'bmodified', 'minlen': 2, 'flags': 'BANG|RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'bnext', 'minlen': 2, 'flags': 'BANG|RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'botright', 'minlen': 2, 'flags': 'NEEDARG|EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'bprevious', 'minlen': 2, 'flags': 'BANG|RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'brewind', 'minlen': 2, 'flags': 'BANG|RANGE|NOTADR|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'break', 'minlen': 4, 'flags': 'TRLBAR|SBOXOK|CMDWIN', 'parser': 'parse_cmd_break'},
\ {'name': 'breakadd', 'minlen': 6, 'flags': 'EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'breakdel', 'minlen': 6, 'flags': 'EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'breaklist', 'minlen': 6, 'flags': 'EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'browse', 'minlen': 3, 'flags': 'NEEDARG|EXTRA|NOTRLCOM|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'bufdo', 'minlen': 5, 'flags': 'BANG|NEEDARG|EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'buffers', 'minlen': 7, 'flags': 'BANG|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'bunload', 'minlen': 3, 'flags': 'BANG|RANGE|NOTADR|BUFNAME|COUNT|EXTRA|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'bwipeout', 'minlen': 2, 'flags': 'BANG|RANGE|NOTADR|BUFNAME|BUFUNL|COUNT|EXTRA|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'change', 'minlen': 1, 'flags': 'BANG|WHOLEFOLD|RANGE|COUNT|TRLBAR|CMDWIN|MODIFY', 'parser': 'parse_cmd_common'},
\ {'name': 'cNext', 'minlen': 2, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'cNfile', 'minlen': 3, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'cabbrev', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'cabclear', 'minlen': 4, 'flags': 'EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'caddbuffer', 'minlen': 3, 'flags': 'RANGE|NOTADR|WORD1|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'caddexpr', 'minlen': 5, 'flags': 'NEEDARG|WORD1|NOTRLCOM|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'caddfile', 'minlen': 5, 'flags': 'TRLBAR|FILE1', 'parser': 'parse_cmd_common'},
\ {'name': 'call', 'minlen': 3, 'flags': 'RANGE|NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN', 'parser': 'parse_cmd_call'},
\ {'name': 'catch', 'minlen': 3, 'flags': 'EXTRA|SBOXOK|CMDWIN', 'parser': 'parse_cmd_catch'},
\ {'name': 'cbuffer', 'minlen': 2, 'flags': 'BANG|RANGE|NOTADR|WORD1|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'cc', 'minlen': 2, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'cclose', 'minlen': 3, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'cd', 'minlen': 2, 'flags': 'BANG|FILE1|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'center', 'minlen': 2, 'flags': 'TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY', 'parser': 'parse_cmd_common'},
\ {'name': 'cexpr', 'minlen': 3, 'flags': 'NEEDARG|WORD1|NOTRLCOM|TRLBAR|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'cfile', 'minlen': 2, 'flags': 'TRLBAR|FILE1|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'cfirst', 'minlen': 4, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'cgetbuffer', 'minlen': 5, 'flags': 'RANGE|NOTADR|WORD1|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'cgetexpr', 'minlen': 5, 'flags': 'NEEDARG|WORD1|NOTRLCOM|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'cgetfile', 'minlen': 2, 'flags': 'TRLBAR|FILE1', 'parser': 'parse_cmd_common'},
\ {'name': 'changes', 'minlen': 7, 'flags': 'TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'chdir', 'minlen': 3, 'flags': 'BANG|FILE1|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'checkpath', 'minlen': 3, 'flags': 'TRLBAR|BANG|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'checktime', 'minlen': 6, 'flags': 'RANGE|NOTADR|BUFNAME|COUNT|EXTRA|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'clist', 'minlen': 2, 'flags': 'BANG|EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'clast', 'minlen': 3, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'close', 'minlen': 3, 'flags': 'BANG|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'cmap', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'cmapclear', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'cmenu', 'minlen': 3, 'flags': 'RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'cnext', 'minlen': 2, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'cnewer', 'minlen': 4, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'cnfile', 'minlen': 3, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'cnoremap', 'minlen': 3, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'cnoreabbrev', 'minlen': 6, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'cnoremenu', 'minlen': 7, 'flags': 'RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'copy', 'minlen': 2, 'flags': 'RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|MODIFY', 'parser': 'parse_cmd_common'},
\ {'name': 'colder', 'minlen': 3, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'colorscheme', 'minlen': 4, 'flags': 'WORD1|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'command', 'minlen': 3, 'flags': 'EXTRA|BANG|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'comclear', 'minlen': 4, 'flags': 'TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'compiler', 'minlen': 4, 'flags': 'BANG|TRLBAR|WORD1|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'continue', 'minlen': 3, 'flags': 'TRLBAR|SBOXOK|CMDWIN', 'parser': 'parse_cmd_continue'},
\ {'name': 'confirm', 'minlen': 4, 'flags': 'NEEDARG|EXTRA|NOTRLCOM|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'copen', 'minlen': 4, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'cprevious', 'minlen': 2, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'cpfile', 'minlen': 3, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'cquit', 'minlen': 2, 'flags': 'TRLBAR|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'crewind', 'minlen': 2, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'cscope', 'minlen': 2, 'flags': 'EXTRA|NOTRLCOM|XFILE', 'parser': 'parse_cmd_common'},
\ {'name': 'cstag', 'minlen': 3, 'flags': 'BANG|TRLBAR|WORD1', 'parser': 'parse_cmd_common'},
\ {'name': 'cunmap', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'cunabbrev', 'minlen': 4, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'cunmenu', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'cwindow', 'minlen': 2, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'delete', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|REGSTR|COUNT|TRLBAR|CMDWIN|MODIFY', 'parser': 'parse_cmd_common'},
\ {'name': 'delmarks', 'minlen': 4, 'flags': 'BANG|EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'debug', 'minlen': 3, 'flags': 'NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'debuggreedy', 'minlen': 6, 'flags': 'RANGE|NOTADR|ZEROR|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'delcommand', 'minlen': 4, 'flags': 'NEEDARG|WORD1|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'delfunction', 'minlen': 4, 'flags': 'BANG|NEEDARG|WORD1|CMDWIN', 'parser': 'parse_cmd_delfunction'},
\ {'name': 'diffupdate', 'minlen': 3, 'flags': 'BANG|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'diffget', 'minlen': 5, 'flags': 'RANGE|EXTRA|TRLBAR|MODIFY', 'parser': 'parse_cmd_common'},
\ {'name': 'diffoff', 'minlen': 5, 'flags': 'BANG|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'diffpatch', 'minlen': 5, 'flags': 'EXTRA|FILE1|TRLBAR|MODIFY', 'parser': 'parse_cmd_common'},
\ {'name': 'diffput', 'minlen': 6, 'flags': 'RANGE|EXTRA|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'diffsplit', 'minlen': 5, 'flags': 'EXTRA|FILE1|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'diffthis', 'minlen': 5, 'flags': 'TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'digraphs', 'minlen': 3, 'flags': 'EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'display', 'minlen': 2, 'flags': 'EXTRA|NOTRLCOM|TRLBAR|SBOXOK|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'djump', 'minlen': 2, 'flags': 'BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA', 'parser': 'parse_cmd_common'},
\ {'name': 'dlist', 'minlen': 2, 'flags': 'BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'doautocmd', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'doautoall', 'minlen': 7, 'flags': 'EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'drop', 'minlen': 2, 'flags': 'FILES|EDITCMD|NEEDARG|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'dsearch', 'minlen': 2, 'flags': 'BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'dsplit', 'minlen': 3, 'flags': 'BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA', 'parser': 'parse_cmd_common'},
\ {'name': 'edit', 'minlen': 1, 'flags': 'BANG|FILE1|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'earlier', 'minlen': 2, 'flags': 'TRLBAR|EXTRA|NOSPC|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'echo', 'minlen': 2, 'flags': 'EXTRA|NOTRLCOM|SBOXOK|CMDWIN', 'parser': 'parse_cmd_echo'},
\ {'name': 'echoerr', 'minlen': 5, 'flags': 'EXTRA|NOTRLCOM|SBOXOK|CMDWIN', 'parser': 'parse_cmd_echoerr'},
\ {'name': 'echohl', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|SBOXOK|CMDWIN', 'parser': 'parse_cmd_echohl'},
\ {'name': 'echomsg', 'minlen': 5, 'flags': 'EXTRA|NOTRLCOM|SBOXOK|CMDWIN', 'parser': 'parse_cmd_echomsg'},
\ {'name': 'echon', 'minlen': 5, 'flags': 'EXTRA|NOTRLCOM|SBOXOK|CMDWIN', 'parser': 'parse_cmd_echon'},
\ {'name': 'else', 'minlen': 2, 'flags': 'TRLBAR|SBOXOK|CMDWIN', 'parser': 'parse_cmd_else'},
\ {'name': 'elseif', 'minlen': 5, 'flags': 'EXTRA|NOTRLCOM|SBOXOK|CMDWIN', 'parser': 'parse_cmd_elseif'},
\ {'name': 'emenu', 'minlen': 2, 'flags': 'NEEDARG|EXTRA|TRLBAR|NOTRLCOM|RANGE|NOTADR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'endif', 'minlen': 2, 'flags': 'TRLBAR|SBOXOK|CMDWIN', 'parser': 'parse_cmd_endif'},
\ {'name': 'endfor', 'minlen': 5, 'flags': 'TRLBAR|SBOXOK|CMDWIN', 'parser': 'parse_cmd_endfor'},
\ {'name': 'endfunction', 'minlen': 4, 'flags': 'TRLBAR|CMDWIN', 'parser': 'parse_cmd_endfunction'},
\ {'name': 'endtry', 'minlen': 4, 'flags': 'TRLBAR|SBOXOK|CMDWIN', 'parser': 'parse_cmd_endtry'},
\ {'name': 'endwhile', 'minlen': 4, 'flags': 'TRLBAR|SBOXOK|CMDWIN', 'parser': 'parse_cmd_endwhile'},
\ {'name': 'enew', 'minlen': 3, 'flags': 'BANG|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'ex', 'minlen': 2, 'flags': 'BANG|FILE1|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'execute', 'minlen': 3, 'flags': 'EXTRA|NOTRLCOM|SBOXOK|CMDWIN', 'parser': 'parse_cmd_execute'},
\ {'name': 'exit', 'minlen': 3, 'flags': 'RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'exusage', 'minlen': 3, 'flags': 'TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'file', 'minlen': 1, 'flags': 'RANGE|NOTADR|ZEROR|BANG|FILE1|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'files', 'minlen': 5, 'flags': 'BANG|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'filetype', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'find', 'minlen': 3, 'flags': 'RANGE|NOTADR|BANG|FILE1|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'finally', 'minlen': 4, 'flags': 'TRLBAR|SBOXOK|CMDWIN', 'parser': 'parse_cmd_finally'},
\ {'name': 'finish', 'minlen': 4, 'flags': 'TRLBAR|SBOXOK|CMDWIN', 'parser': 'parse_cmd_finish'},
\ {'name': 'first', 'minlen': 3, 'flags': 'EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'fixdel', 'minlen': 3, 'flags': 'TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'fold', 'minlen': 2, 'flags': 'RANGE|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'foldclose', 'minlen': 5, 'flags': 'RANGE|BANG|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'folddoopen', 'minlen': 5, 'flags': 'RANGE|DFLALL|NEEDARG|EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'folddoclosed', 'minlen': 7, 'flags': 'RANGE|DFLALL|NEEDARG|EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'foldopen', 'minlen': 5, 'flags': 'RANGE|BANG|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'for', 'minlen': 3, 'flags': 'EXTRA|NOTRLCOM|SBOXOK|CMDWIN', 'parser': 'parse_cmd_for'},
\ {'name': 'function', 'minlen': 2, 'flags': 'EXTRA|BANG|CMDWIN', 'parser': 'parse_cmd_function'},
\ {'name': 'global', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|BANG|EXTRA|DFLALL|SBOXOK|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'goto', 'minlen': 2, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR|SBOXOK|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'grep', 'minlen': 2, 'flags': 'RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE', 'parser': 'parse_cmd_common'},
\ {'name': 'grepadd', 'minlen': 5, 'flags': 'RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE', 'parser': 'parse_cmd_common'},
\ {'name': 'gui', 'minlen': 2, 'flags': 'BANG|FILES|EDITCMD|ARGOPT|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'gvim', 'minlen': 2, 'flags': 'BANG|FILES|EDITCMD|ARGOPT|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'hardcopy', 'minlen': 2, 'flags': 'RANGE|COUNT|EXTRA|TRLBAR|DFLALL|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'help', 'minlen': 1, 'flags': 'BANG|EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'helpfind', 'minlen': 5, 'flags': 'EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'helpgrep', 'minlen': 5, 'flags': 'EXTRA|NOTRLCOM|NEEDARG', 'parser': 'parse_cmd_common'},
\ {'name': 'helptags', 'minlen': 5, 'flags': 'NEEDARG|FILES|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'highlight', 'minlen': 2, 'flags': 'BANG|EXTRA|TRLBAR|SBOXOK|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'hide', 'minlen': 3, 'flags': 'BANG|EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'history', 'minlen': 3, 'flags': 'EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'insert', 'minlen': 1, 'flags': 'BANG|RANGE|TRLBAR|CMDWIN|MODIFY', 'parser': 'parse_cmd_insert'},
\ {'name': 'iabbrev', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'iabclear', 'minlen': 4, 'flags': 'EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'if', 'minlen': 2, 'flags': 'EXTRA|NOTRLCOM|SBOXOK|CMDWIN', 'parser': 'parse_cmd_if'},
\ {'name': 'ijump', 'minlen': 2, 'flags': 'BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA', 'parser': 'parse_cmd_common'},
\ {'name': 'ilist', 'minlen': 2, 'flags': 'BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'imap', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'imapclear', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'imenu', 'minlen': 3, 'flags': 'RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'inoremap', 'minlen': 3, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'inoreabbrev', 'minlen': 6, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'inoremenu', 'minlen': 7, 'flags': 'RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'intro', 'minlen': 3, 'flags': 'TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'isearch', 'minlen': 2, 'flags': 'BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'isplit', 'minlen': 3, 'flags': 'BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA', 'parser': 'parse_cmd_common'},
\ {'name': 'iunmap', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'iunabbrev', 'minlen': 4, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'iunmenu', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'join', 'minlen': 1, 'flags': 'BANG|RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|MODIFY', 'parser': 'parse_cmd_common'},
\ {'name': 'jumps', 'minlen': 2, 'flags': 'TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'k', 'minlen': 1, 'flags': 'RANGE|WORD1|TRLBAR|SBOXOK|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'keepalt', 'minlen': 5, 'flags': 'NEEDARG|EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'keepmarks', 'minlen': 3, 'flags': 'NEEDARG|EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'keepjumps', 'minlen': 5, 'flags': 'NEEDARG|EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'keeppatterns', 'minlen': 5, 'flags': 'NEEDARG|EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'lNext', 'minlen': 2, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'lNfile', 'minlen': 3, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'list', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'laddexpr', 'minlen': 3, 'flags': 'NEEDARG|WORD1|NOTRLCOM|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'laddbuffer', 'minlen': 5, 'flags': 'RANGE|NOTADR|WORD1|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'laddfile', 'minlen': 5, 'flags': 'TRLBAR|FILE1', 'parser': 'parse_cmd_common'},
\ {'name': 'last', 'minlen': 2, 'flags': 'EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'language', 'minlen': 3, 'flags': 'EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'later', 'minlen': 3, 'flags': 'TRLBAR|EXTRA|NOSPC|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'lbuffer', 'minlen': 2, 'flags': 'BANG|RANGE|NOTADR|WORD1|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'lcd', 'minlen': 2, 'flags': 'BANG|FILE1|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'lchdir', 'minlen': 3, 'flags': 'BANG|FILE1|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'lclose', 'minlen': 3, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'lcscope', 'minlen': 3, 'flags': 'EXTRA|NOTRLCOM|XFILE', 'parser': 'parse_cmd_common'},
\ {'name': 'left', 'minlen': 2, 'flags': 'TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY', 'parser': 'parse_cmd_common'},
\ {'name': 'leftabove', 'minlen': 5, 'flags': 'NEEDARG|EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'let', 'minlen': 3, 'flags': 'EXTRA|NOTRLCOM|SBOXOK|CMDWIN', 'parser': 'parse_cmd_let'},
\ {'name': 'const', 'minlen': 4, 'flags': 'EXTRA|NOTRLCOM|SBOXOK|CMDWIN', 'parser': 'parse_cmd_const'},
\ {'name': 'lexpr', 'minlen': 3, 'flags': 'NEEDARG|WORD1|NOTRLCOM|TRLBAR|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'lfile', 'minlen': 2, 'flags': 'TRLBAR|FILE1|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'lfirst', 'minlen': 4, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'lgetbuffer', 'minlen': 5, 'flags': 'RANGE|NOTADR|WORD1|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'lgetexpr', 'minlen': 5, 'flags': 'NEEDARG|WORD1|NOTRLCOM|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'lgetfile', 'minlen': 2, 'flags': 'TRLBAR|FILE1', 'parser': 'parse_cmd_common'},
\ {'name': 'lgrep', 'minlen': 3, 'flags': 'RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE', 'parser': 'parse_cmd_common'},
\ {'name': 'lgrepadd', 'minlen': 6, 'flags': 'RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE', 'parser': 'parse_cmd_common'},
\ {'name': 'lhelpgrep', 'minlen': 2, 'flags': 'EXTRA|NOTRLCOM|NEEDARG', 'parser': 'parse_cmd_common'},
\ {'name': 'll', 'minlen': 2, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'llast', 'minlen': 3, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'list', 'minlen': 3, 'flags': 'BANG|EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'lmake', 'minlen': 4, 'flags': 'BANG|EXTRA|NOTRLCOM|TRLBAR|XFILE', 'parser': 'parse_cmd_common'},
\ {'name': 'lmap', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'lmapclear', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'lnext', 'minlen': 3, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'lnewer', 'minlen': 4, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'lnfile', 'minlen': 3, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'lnoremap', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'loadkeymap', 'minlen': 5, 'flags': 'CMDWIN', 'parser': 'parse_cmd_loadkeymap'},
\ {'name': 'loadview', 'minlen': 2, 'flags': 'FILE1|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'lockmarks', 'minlen': 3, 'flags': 'NEEDARG|EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'lockvar', 'minlen': 5, 'flags': 'BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN', 'parser': 'parse_cmd_lockvar'},
\ {'name': 'lolder', 'minlen': 3, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'lopen', 'minlen': 3, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'lprevious', 'minlen': 2, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'lpfile', 'minlen': 3, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'lrewind', 'minlen': 2, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR|BANG', 'parser': 'parse_cmd_common'},
\ {'name': 'ls', 'minlen': 2, 'flags': 'BANG|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'ltag', 'minlen': 2, 'flags': 'NOTADR|TRLBAR|BANG|WORD1', 'parser': 'parse_cmd_common'},
\ {'name': 'lunmap', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'lua', 'minlen': 3, 'flags': 'RANGE|EXTRA|NEEDARG|CMDWIN', 'parser': 'parse_cmd_lua'},
\ {'name': 'luado', 'minlen': 4, 'flags': 'RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'luafile', 'minlen': 4, 'flags': 'RANGE|FILE1|NEEDARG|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'lvimgrep', 'minlen': 2, 'flags': 'RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE', 'parser': 'parse_cmd_common'},
\ {'name': 'lvimgrepadd', 'minlen': 9, 'flags': 'RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE', 'parser': 'parse_cmd_common'},
\ {'name': 'lwindow', 'minlen': 2, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'move', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|MODIFY', 'parser': 'parse_cmd_common'},
\ {'name': 'mark', 'minlen': 2, 'flags': 'RANGE|WORD1|TRLBAR|SBOXOK|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'make', 'minlen': 3, 'flags': 'BANG|EXTRA|NOTRLCOM|TRLBAR|XFILE', 'parser': 'parse_cmd_common'},
\ {'name': 'map', 'minlen': 3, 'flags': 'BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'mapclear', 'minlen': 4, 'flags': 'EXTRA|BANG|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'marks', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'match', 'minlen': 3, 'flags': 'RANGE|NOTADR|EXTRA|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'menu', 'minlen': 2, 'flags': 'RANGE|NOTADR|ZEROR|BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'menutranslate', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'messages', 'minlen': 3, 'flags': 'TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'mkexrc', 'minlen': 2, 'flags': 'BANG|FILE1|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'mksession', 'minlen': 3, 'flags': 'BANG|FILE1|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'mkspell', 'minlen': 4, 'flags': 'BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE', 'parser': 'parse_cmd_common'},
\ {'name': 'mkvimrc', 'minlen': 3, 'flags': 'BANG|FILE1|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'mkview', 'minlen': 5, 'flags': 'BANG|FILE1|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'mode', 'minlen': 3, 'flags': 'WORD1|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'mzscheme', 'minlen': 2, 'flags': 'RANGE|EXTRA|DFLALL|NEEDARG|CMDWIN|SBOXOK', 'parser': 'parse_cmd_mzscheme'},
\ {'name': 'mzfile', 'minlen': 3, 'flags': 'RANGE|FILE1|NEEDARG|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'nbclose', 'minlen': 3, 'flags': 'TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'nbkey', 'minlen': 2, 'flags': 'EXTRA|NOTADR|NEEDARG', 'parser': 'parse_cmd_common'},
\ {'name': 'nbstart', 'minlen': 3, 'flags': 'WORD1|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'next', 'minlen': 1, 'flags': 'RANGE|NOTADR|BANG|FILES|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'new', 'minlen': 3, 'flags': 'BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'nmap', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'nmapclear', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'nmenu', 'minlen': 3, 'flags': 'RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'nnoremap', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'nnoremenu', 'minlen': 7, 'flags': 'RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'noautocmd', 'minlen': 3, 'flags': 'NEEDARG|EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'noremap', 'minlen': 2, 'flags': 'BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'nohlsearch', 'minlen': 3, 'flags': 'TRLBAR|SBOXOK|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'noreabbrev', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'noremenu', 'minlen': 6, 'flags': 'RANGE|NOTADR|ZEROR|BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'normal', 'minlen': 4, 'flags': 'RANGE|BANG|EXTRA|NEEDARG|NOTRLCOM|USECTRLV|SBOXOK|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'number', 'minlen': 2, 'flags': 'RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'nunmap', 'minlen': 3, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'nunmenu', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'oldfiles', 'minlen': 2, 'flags': 'BANG|TRLBAR|SBOXOK|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'open', 'minlen': 1, 'flags': 'RANGE|BANG|EXTRA', 'parser': 'parse_cmd_common'},
\ {'name': 'omap', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'omapclear', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'omenu', 'minlen': 3, 'flags': 'RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'only', 'minlen': 2, 'flags': 'BANG|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'onoremap', 'minlen': 3, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'onoremenu', 'minlen': 7, 'flags': 'RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'options', 'minlen': 3, 'flags': 'TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'ounmap', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'ounmenu', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'ownsyntax', 'minlen': 2, 'flags': 'EXTRA|NOTRLCOM|SBOXOK|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'pclose', 'minlen': 2, 'flags': 'BANG|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'pedit', 'minlen': 3, 'flags': 'BANG|FILE1|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'perl', 'minlen': 2, 'flags': 'RANGE|EXTRA|DFLALL|NEEDARG|SBOXOK|CMDWIN', 'parser': 'parse_cmd_perl'},
\ {'name': 'print', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|SBOXOK', 'parser': 'parse_cmd_common'},
\ {'name': 'profdel', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'profile', 'minlen': 4, 'flags': 'BANG|EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'promptfind', 'minlen': 3, 'flags': 'EXTRA|NOTRLCOM|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'promptrepl', 'minlen': 7, 'flags': 'EXTRA|NOTRLCOM|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'perldo', 'minlen': 5, 'flags': 'RANGE|EXTRA|DFLALL|NEEDARG|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'pop', 'minlen': 2, 'flags': 'RANGE|NOTADR|BANG|COUNT|TRLBAR|ZEROR', 'parser': 'parse_cmd_common'},
\ {'name': 'popup', 'minlen': 4, 'flags': 'NEEDARG|EXTRA|BANG|TRLBAR|NOTRLCOM|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'ppop', 'minlen': 2, 'flags': 'RANGE|NOTADR|BANG|COUNT|TRLBAR|ZEROR', 'parser': 'parse_cmd_common'},
\ {'name': 'preserve', 'minlen': 3, 'flags': 'TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'previous', 'minlen': 4, 'flags': 'EXTRA|RANGE|NOTADR|COUNT|BANG|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'psearch', 'minlen': 2, 'flags': 'BANG|RANGE|WHOLEFOLD|DFLALL|EXTRA', 'parser': 'parse_cmd_common'},
\ {'name': 'ptag', 'minlen': 2, 'flags': 'RANGE|NOTADR|BANG|WORD1|TRLBAR|ZEROR', 'parser': 'parse_cmd_common'},
\ {'name': 'ptNext', 'minlen': 3, 'flags': 'RANGE|NOTADR|BANG|TRLBAR|ZEROR', 'parser': 'parse_cmd_common'},
\ {'name': 'ptfirst', 'minlen': 3, 'flags': 'RANGE|NOTADR|BANG|TRLBAR|ZEROR', 'parser': 'parse_cmd_common'},
\ {'name': 'ptjump', 'minlen': 3, 'flags': 'BANG|TRLBAR|WORD1', 'parser': 'parse_cmd_common'},
\ {'name': 'ptlast', 'minlen': 3, 'flags': 'BANG|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'ptnext', 'minlen': 3, 'flags': 'RANGE|NOTADR|BANG|TRLBAR|ZEROR', 'parser': 'parse_cmd_common'},
\ {'name': 'ptprevious', 'minlen': 3, 'flags': 'RANGE|NOTADR|BANG|TRLBAR|ZEROR', 'parser': 'parse_cmd_common'},
\ {'name': 'ptrewind', 'minlen': 3, 'flags': 'RANGE|NOTADR|BANG|TRLBAR|ZEROR', 'parser': 'parse_cmd_common'},
\ {'name': 'ptselect', 'minlen': 3, 'flags': 'BANG|TRLBAR|WORD1', 'parser': 'parse_cmd_common'},
\ {'name': 'put', 'minlen': 2, 'flags': 'RANGE|WHOLEFOLD|BANG|REGSTR|TRLBAR|ZEROR|CMDWIN|MODIFY', 'parser': 'parse_cmd_common'},
\ {'name': 'pwd', 'minlen': 2, 'flags': 'TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'py3', 'minlen': 3, 'flags': 'RANGE|EXTRA|NEEDARG|CMDWIN', 'parser': 'parse_cmd_python3'},
\ {'name': 'python3', 'minlen': 7, 'flags': 'RANGE|EXTRA|NEEDARG|CMDWIN', 'parser': 'parse_cmd_python3'},
\ {'name': 'py3file', 'minlen': 4, 'flags': 'RANGE|FILE1|NEEDARG|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'python', 'minlen': 2, 'flags': 'RANGE|EXTRA|NEEDARG|CMDWIN', 'parser': 'parse_cmd_python'},
\ {'name': 'pyfile', 'minlen': 3, 'flags': 'RANGE|FILE1|NEEDARG|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'pydo', 'minlen': 3, 'flags': 'RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'py3do', 'minlen': 4, 'flags': 'RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'quit', 'minlen': 1, 'flags': 'BANG|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'quitall', 'minlen': 5, 'flags': 'BANG|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'qall', 'minlen': 2, 'flags': 'BANG|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'read', 'minlen': 1, 'flags': 'BANG|RANGE|WHOLEFOLD|FILE1|ARGOPT|TRLBAR|ZEROR|CMDWIN|MODIFY', 'parser': 'parse_cmd_common'},
\ {'name': 'recover', 'minlen': 3, 'flags': 'BANG|FILE1|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'redo', 'minlen': 3, 'flags': 'TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'redir', 'minlen': 4, 'flags': 'BANG|FILES|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'redraw', 'minlen': 4, 'flags': 'BANG|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'redrawstatus', 'minlen': 7, 'flags': 'BANG|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'registers', 'minlen': 3, 'flags': 'EXTRA|NOTRLCOM|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'resize', 'minlen': 3, 'flags': 'RANGE|NOTADR|TRLBAR|WORD1', 'parser': 'parse_cmd_common'},
\ {'name': 'retab', 'minlen': 3, 'flags': 'TRLBAR|RANGE|WHOLEFOLD|DFLALL|BANG|WORD1|CMDWIN|MODIFY', 'parser': 'parse_cmd_common'},
\ {'name': 'return', 'minlen': 4, 'flags': 'EXTRA|NOTRLCOM|SBOXOK|CMDWIN', 'parser': 'parse_cmd_return'},
\ {'name': 'rewind', 'minlen': 3, 'flags': 'EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'right', 'minlen': 2, 'flags': 'TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY', 'parser': 'parse_cmd_common'},
\ {'name': 'rightbelow', 'minlen': 6, 'flags': 'NEEDARG|EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'ruby', 'minlen': 3, 'flags': 'RANGE|EXTRA|NEEDARG|CMDWIN', 'parser': 'parse_cmd_ruby'},
\ {'name': 'rubydo', 'minlen': 5, 'flags': 'RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'rubyfile', 'minlen': 5, 'flags': 'RANGE|FILE1|NEEDARG|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'rundo', 'minlen': 4, 'flags': 'NEEDARG|FILE1', 'parser': 'parse_cmd_common'},
\ {'name': 'runtime', 'minlen': 2, 'flags': 'BANG|NEEDARG|FILES|TRLBAR|SBOXOK|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'rviminfo', 'minlen': 2, 'flags': 'BANG|FILE1|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'substitute', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|EXTRA|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'sNext', 'minlen': 2, 'flags': 'EXTRA|RANGE|NOTADR|COUNT|BANG|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'sandbox', 'minlen': 3, 'flags': 'NEEDARG|EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'sargument', 'minlen': 2, 'flags': 'BANG|RANGE|NOTADR|COUNT|EXTRA|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'sall', 'minlen': 3, 'flags': 'BANG|RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'saveas', 'minlen': 3, 'flags': 'BANG|DFLALL|FILE1|ARGOPT|CMDWIN|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'sbuffer', 'minlen': 2, 'flags': 'BANG|RANGE|NOTADR|BUFNAME|BUFUNL|COUNT|EXTRA|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'sbNext', 'minlen': 3, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'sball', 'minlen': 3, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'sbfirst', 'minlen': 3, 'flags': 'TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'sblast', 'minlen': 3, 'flags': 'TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'sbmodified', 'minlen': 3, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'sbnext', 'minlen': 3, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'sbprevious', 'minlen': 3, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'sbrewind', 'minlen': 3, 'flags': 'TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'scriptnames', 'minlen': 3, 'flags': 'TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'scriptencoding', 'minlen': 7, 'flags': 'WORD1|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'scscope', 'minlen': 3, 'flags': 'EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'set', 'minlen': 2, 'flags': 'TRLBAR|EXTRA|CMDWIN|SBOXOK', 'parser': 'parse_cmd_common'},
\ {'name': 'setfiletype', 'minlen': 4, 'flags': 'TRLBAR|EXTRA|NEEDARG|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'setglobal', 'minlen': 4, 'flags': 'TRLBAR|EXTRA|CMDWIN|SBOXOK', 'parser': 'parse_cmd_common'},
\ {'name': 'setlocal', 'minlen': 4, 'flags': 'TRLBAR|EXTRA|CMDWIN|SBOXOK', 'parser': 'parse_cmd_common'},
\ {'name': 'sfind', 'minlen': 2, 'flags': 'BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'sfirst', 'minlen': 4, 'flags': 'EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'shell', 'minlen': 2, 'flags': 'TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'simalt', 'minlen': 3, 'flags': 'NEEDARG|WORD1|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'sign', 'minlen': 3, 'flags': 'NEEDARG|RANGE|NOTADR|EXTRA|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'silent', 'minlen': 3, 'flags': 'NEEDARG|EXTRA|BANG|NOTRLCOM|SBOXOK|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'sleep', 'minlen': 2, 'flags': 'RANGE|NOTADR|COUNT|EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'slast', 'minlen': 3, 'flags': 'EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'smagic', 'minlen': 2, 'flags': 'RANGE|WHOLEFOLD|EXTRA|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'smap', 'minlen': 4, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'smapclear', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'smenu', 'minlen': 3, 'flags': 'RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'snext', 'minlen': 2, 'flags': 'RANGE|NOTADR|BANG|FILES|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'sniff', 'minlen': 3, 'flags': 'EXTRA|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'snomagic', 'minlen': 3, 'flags': 'RANGE|WHOLEFOLD|EXTRA|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'snoremap', 'minlen': 4, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'snoremenu', 'minlen': 7, 'flags': 'RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'sort', 'minlen': 3, 'flags': 'RANGE|DFLALL|WHOLEFOLD|BANG|EXTRA|NOTRLCOM|MODIFY', 'parser': 'parse_cmd_common'},
\ {'name': 'source', 'minlen': 2, 'flags': 'BANG|FILE1|TRLBAR|SBOXOK|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'spelldump', 'minlen': 6, 'flags': 'BANG|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'spellgood', 'minlen': 3, 'flags': 'BANG|RANGE|NOTADR|NEEDARG|EXTRA|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'spellinfo', 'minlen': 6, 'flags': 'TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'spellrepall', 'minlen': 6, 'flags': 'TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'spellundo', 'minlen': 6, 'flags': 'BANG|RANGE|NOTADR|NEEDARG|EXTRA|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'spellwrong', 'minlen': 6, 'flags': 'BANG|RANGE|NOTADR|NEEDARG|EXTRA|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'split', 'minlen': 2, 'flags': 'BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'sprevious', 'minlen': 3, 'flags': 'EXTRA|RANGE|NOTADR|COUNT|BANG|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'srewind', 'minlen': 3, 'flags': 'EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'stop', 'minlen': 2, 'flags': 'TRLBAR|BANG|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'stag', 'minlen': 3, 'flags': 'RANGE|NOTADR|BANG|WORD1|TRLBAR|ZEROR', 'parser': 'parse_cmd_common'},
\ {'name': 'startinsert', 'minlen': 4, 'flags': 'BANG|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'startgreplace', 'minlen': 6, 'flags': 'BANG|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'startreplace', 'minlen': 6, 'flags': 'BANG|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'stopinsert', 'minlen': 5, 'flags': 'BANG|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'stjump', 'minlen': 3, 'flags': 'BANG|TRLBAR|WORD1', 'parser': 'parse_cmd_common'},
\ {'name': 'stselect', 'minlen': 3, 'flags': 'BANG|TRLBAR|WORD1', 'parser': 'parse_cmd_common'},
\ {'name': 'sunhide', 'minlen': 3, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'sunmap', 'minlen': 4, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'sunmenu', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'suspend', 'minlen': 3, 'flags': 'TRLBAR|BANG|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'sview', 'minlen': 2, 'flags': 'BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'swapname', 'minlen': 2, 'flags': 'TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'syntax', 'minlen': 2, 'flags': 'EXTRA|NOTRLCOM|CMDWIN', 'parser': 'parse_cmd_syntax'},
\ {'name': 'syntime', 'minlen': 5, 'flags': 'NEEDARG|WORD1|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'syncbind', 'minlen': 4, 'flags': 'TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 't', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|MODIFY', 'parser': 'parse_cmd_common'},
\ {'name': 'tNext', 'minlen': 2, 'flags': 'RANGE|NOTADR|BANG|TRLBAR|ZEROR', 'parser': 'parse_cmd_common'},
\ {'name': 'tabNext', 'minlen': 4, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'tabclose', 'minlen': 4, 'flags': 'RANGE|NOTADR|COUNT|BANG|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'tabdo', 'minlen': 4, 'flags': 'NEEDARG|EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'tabedit', 'minlen': 4, 'flags': 'BANG|FILE1|RANGE|NOTADR|ZEROR|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'tabfind', 'minlen': 4, 'flags': 'BANG|FILE1|RANGE|NOTADR|ZEROR|EDITCMD|ARGOPT|NEEDARG|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'tabfirst', 'minlen': 6, 'flags': 'TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'tablast', 'minlen': 4, 'flags': 'TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'tabmove', 'minlen': 4, 'flags': 'RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'tabnew', 'minlen': 6, 'flags': 'BANG|FILE1|RANGE|NOTADR|ZEROR|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'tabnext', 'minlen': 4, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'tabonly', 'minlen': 4, 'flags': 'BANG|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'tabprevious', 'minlen': 4, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'tabrewind', 'minlen': 4, 'flags': 'TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'tabs', 'minlen': 4, 'flags': 'TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'tab', 'minlen': 3, 'flags': 'NEEDARG|EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'tag', 'minlen': 2, 'flags': 'RANGE|NOTADR|BANG|WORD1|TRLBAR|ZEROR', 'parser': 'parse_cmd_common'},
\ {'name': 'tags', 'minlen': 4, 'flags': 'TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'tcl', 'minlen': 2, 'flags': 'RANGE|EXTRA|NEEDARG|CMDWIN', 'parser': 'parse_cmd_tcl'},
\ {'name': 'tcldo', 'minlen': 4, 'flags': 'RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'tclfile', 'minlen': 4, 'flags': 'RANGE|FILE1|NEEDARG|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'tearoff', 'minlen': 2, 'flags': 'NEEDARG|EXTRA|TRLBAR|NOTRLCOM|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'tfirst', 'minlen': 2, 'flags': 'RANGE|NOTADR|BANG|TRLBAR|ZEROR', 'parser': 'parse_cmd_common'},
\ {'name': 'throw', 'minlen': 2, 'flags': 'EXTRA|NEEDARG|SBOXOK|CMDWIN', 'parser': 'parse_cmd_throw'},
\ {'name': 'tjump', 'minlen': 2, 'flags': 'BANG|TRLBAR|WORD1', 'parser': 'parse_cmd_common'},
\ {'name': 'tlast', 'minlen': 2, 'flags': 'BANG|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'tmenu', 'minlen': 2, 'flags': 'RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'tnext', 'minlen': 2, 'flags': 'RANGE|NOTADR|BANG|TRLBAR|ZEROR', 'parser': 'parse_cmd_common'},
\ {'name': 'topleft', 'minlen': 2, 'flags': 'NEEDARG|EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'tprevious', 'minlen': 2, 'flags': 'RANGE|NOTADR|BANG|TRLBAR|ZEROR', 'parser': 'parse_cmd_common'},
\ {'name': 'trewind', 'minlen': 2, 'flags': 'RANGE|NOTADR|BANG|TRLBAR|ZEROR', 'parser': 'parse_cmd_common'},
\ {'name': 'try', 'minlen': 3, 'flags': 'TRLBAR|SBOXOK|CMDWIN', 'parser': 'parse_cmd_try'},
\ {'name': 'tselect', 'minlen': 2, 'flags': 'BANG|TRLBAR|WORD1', 'parser': 'parse_cmd_common'},
\ {'name': 'tunmenu', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'undo', 'minlen': 1, 'flags': 'RANGE|NOTADR|COUNT|ZEROR|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'undojoin', 'minlen': 5, 'flags': 'TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'undolist', 'minlen': 5, 'flags': 'TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'unabbreviate', 'minlen': 3, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'unhide', 'minlen': 3, 'flags': 'RANGE|NOTADR|COUNT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'unlet', 'minlen': 3, 'flags': 'BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN', 'parser': 'parse_cmd_unlet'},
\ {'name': 'unlockvar', 'minlen': 4, 'flags': 'BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN', 'parser': 'parse_cmd_unlockvar'},
\ {'name': 'unmap', 'minlen': 3, 'flags': 'BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'unmenu', 'minlen': 4, 'flags': 'BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'unsilent', 'minlen': 3, 'flags': 'NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'update', 'minlen': 2, 'flags': 'RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'vglobal', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|EXTRA|DFLALL|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'version', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'verbose', 'minlen': 4, 'flags': 'NEEDARG|RANGE|NOTADR|EXTRA|NOTRLCOM|SBOXOK|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'vertical', 'minlen': 4, 'flags': 'NEEDARG|EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'vimgrep', 'minlen': 3, 'flags': 'RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE', 'parser': 'parse_cmd_common'},
\ {'name': 'vimgrepadd', 'minlen': 8, 'flags': 'RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE', 'parser': 'parse_cmd_common'},
\ {'name': 'visual', 'minlen': 2, 'flags': 'BANG|FILE1|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'viusage', 'minlen': 3, 'flags': 'TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'view', 'minlen': 3, 'flags': 'BANG|FILE1|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'vmap', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'vmapclear', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'vmenu', 'minlen': 3, 'flags': 'RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'vnew', 'minlen': 3, 'flags': 'BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'vnoremap', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'vnoremenu', 'minlen': 7, 'flags': 'RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'vsplit', 'minlen': 2, 'flags': 'BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'vunmap', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'vunmenu', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'windo', 'minlen': 5, 'flags': 'BANG|NEEDARG|EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'},
\ {'name': 'write', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'wNext', 'minlen': 2, 'flags': 'RANGE|WHOLEFOLD|NOTADR|BANG|FILE1|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'wall', 'minlen': 2, 'flags': 'BANG|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'while', 'minlen': 2, 'flags': 'EXTRA|NOTRLCOM|SBOXOK|CMDWIN', 'parser': 'parse_cmd_while'},
\ {'name': 'winsize', 'minlen': 2, 'flags': 'EXTRA|NEEDARG|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'wincmd', 'minlen': 4, 'flags': 'NEEDARG|WORD1|RANGE|NOTADR', 'parser': 'parse_wincmd'},
\ {'name': 'winpos', 'minlen': 4, 'flags': 'EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'wnext', 'minlen': 2, 'flags': 'RANGE|NOTADR|BANG|FILE1|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'wprevious', 'minlen': 2, 'flags': 'RANGE|NOTADR|BANG|FILE1|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'wq', 'minlen': 2, 'flags': 'RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'wqall', 'minlen': 3, 'flags': 'BANG|FILE1|ARGOPT|DFLALL|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'wsverb', 'minlen': 2, 'flags': 'EXTRA|NOTADR|NEEDARG', 'parser': 'parse_cmd_common'},
\ {'name': 'wundo', 'minlen': 2, 'flags': 'BANG|NEEDARG|FILE1', 'parser': 'parse_cmd_common'},
\ {'name': 'wviminfo', 'minlen': 2, 'flags': 'BANG|FILE1|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'xit', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'xall', 'minlen': 2, 'flags': 'BANG|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'xmapclear', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'xmap', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'xmenu', 'minlen': 3, 'flags': 'RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'xnoremap', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'xnoremenu', 'minlen': 7, 'flags': 'RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'xunmap', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'xunmenu', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'yank', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|REGSTR|COUNT|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'z', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|EXTRA|EXFLAGS|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': '!', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|BANG|FILES|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': '#', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': '&', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY', 'parser': 'parse_cmd_common'},
\ {'name': '*', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': '<', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|MODIFY', 'parser': 'parse_cmd_common'},
\ {'name': '=', 'minlen': 1, 'flags': 'RANGE|TRLBAR|DFLALL|EXFLAGS|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': '>', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|MODIFY', 'parser': 'parse_cmd_common'},
\ {'name': '@', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'Next', 'minlen': 1, 'flags': 'EXTRA|RANGE|NOTADR|COUNT|BANG|EDITCMD|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': 'Print', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN', 'parser': 'parse_cmd_common'},
\ {'name': 'X', 'minlen': 1, 'flags': 'TRLBAR', 'parser': 'parse_cmd_common'},
\ {'name': '~', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY', 'parser': 'parse_cmd_common'},
\
\ {'flags': 'TRLBAR', 'minlen': 3, 'name': 'cbottom', 'parser': 'parse_cmd_common'},
\ {'flags': 'BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL', 'minlen': 3, 'name': 'cdo', 'parser': 'parse_cmd_common'},
\ {'flags': 'BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL', 'minlen': 3, 'name': 'cfdo', 'parser': 'parse_cmd_common'},
\ {'flags': 'TRLBAR', 'minlen': 3, 'name': 'chistory', 'parser': 'parse_cmd_common'},
\ {'flags': 'TRLBAR|CMDWIN', 'minlen': 3, 'name': 'clearjumps', 'parser': 'parse_cmd_common'},
\ {'flags': 'BANG|NEEDARG|EXTRA|NOTRLCOM', 'minlen': 4, 'name': 'filter', 'parser': 'parse_cmd_common'},
\ {'flags': 'RANGE|NOTADR|COUNT|TRLBAR', 'minlen': 5, 'name': 'helpclose', 'parser': 'parse_cmd_common'},
\ {'flags': 'TRLBAR', 'minlen': 3, 'name': 'lbottom', 'parser': 'parse_cmd_common'},
\ {'flags': 'BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL', 'minlen': 2, 'name': 'ldo', 'parser': 'parse_cmd_common'},
\ {'flags': 'BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|NOTADR|DFLALL', 'minlen': 3, 'name': 'lfdo', 'parser': 'parse_cmd_common'},
\ {'flags': 'TRLBAR', 'minlen': 3, 'name': 'lhistory', 'parser': 'parse_cmd_common'},
\ {'flags': 'BANG|EXTRA|TRLBAR|CMDWIN', 'minlen': 3, 'name': 'llist', 'parser': 'parse_cmd_common'},
\ {'flags': 'NEEDARG|EXTRA|NOTRLCOM', 'minlen': 3, 'name': 'noswapfile', 'parser': 'parse_cmd_common'},
\ {'flags': 'BANG|FILE1|NEEDARG|TRLBAR|SBOXOK|CMDWIN', 'minlen': 2, 'name': 'packadd', 'parser': 'parse_cmd_common'},
\ {'flags': 'BANG|TRLBAR|SBOXOK|CMDWIN', 'minlen': 5, 'name': 'packloadall', 'parser': 'parse_cmd_common'},
\ {'flags': 'TRLBAR|CMDWIN|SBOXOK', 'minlen': 3, 'name': 'smile', 'parser': 'parse_cmd_common'},
\ {'flags': 'RANGE|EXTRA|NEEDARG|CMDWIN', 'minlen': 3, 'name': 'pyx', 'parser': 'parse_cmd_common'},
\ {'flags': 'RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN', 'minlen': 4, 'name': 'pyxdo', 'parser': 'parse_cmd_common'},
\ {'flags': 'RANGE|EXTRA|NEEDARG|CMDWIN', 'minlen': 7, 'name': 'pythonx', 'parser': 'parse_cmd_common'},
\ {'flags': 'RANGE|FILE1|NEEDARG|CMDWIN', 'minlen': 4, 'name': 'pyxfile', 'parser': 'parse_cmd_common'},
\ {'flags': 'RANGE|BANG|FILES|CMDWIN', 'minlen': 3, 'name': 'terminal', 'parser': 'parse_cmd_common'},
\ {'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'minlen': 3, 'name': 'tmap', 'parser': 'parse_cmd_common'},
\ {'flags': 'EXTRA|TRLBAR|CMDWIN', 'minlen': 5, 'name': 'tmapclear', 'parser': 'parse_cmd_common'},
\ {'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'minlen': 3, 'name': 'tnoremap', 'parser': 'parse_cmd_common'},
\ {'flags': 'EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN', 'minlen': 5, 'name': 'tunmap', 'parser': 'parse_cmd_common'},
\
\ {'flags': 'EX_RANGE|EX_COUNT|EX_TRLBAR', 'minlen': 4, 'name': 'cabove', 'parser': 'parse_cmd_common'},
\ {'flags': 'EX_RANGE|EX_COUNT|EX_TRLBAR', 'minlen': 3, 'name': 'cafter', 'parser': 'parse_cmd_common'},
\ {'flags': 'EX_RANGE|EX_COUNT|EX_TRLBAR', 'minlen': 3, 'name': 'cbefore', 'parser': 'parse_cmd_common'},
\ {'flags': 'EX_RANGE|EX_COUNT|EX_TRLBAR', 'minlen': 4, 'name': 'cbelow', 'parser': 'parse_cmd_common'},
\ {'flags': 'EX_EXTRA|EX_NOTRLCOM|EX_SBOXOK|EX_CMDWIN', 'minlen': 4, 'name': 'const', 'parser': 'parse_cmd_common'},
\ {'flags': 'EX_RANGE|EX_COUNT|EX_TRLBAR', 'minlen': 3, 'name': 'labove', 'parser': 'parse_cmd_common'},
\ {'flags': 'EX_RANGE|EX_COUNT|EX_TRLBAR', 'minlen': 3, 'name': 'lafter', 'parser': 'parse_cmd_common'},
\ {'flags': 'EX_RANGE|EX_COUNT|EX_TRLBAR', 'minlen': 3, 'name': 'lbefore', 'parser': 'parse_cmd_common'},
\ {'flags': 'EX_RANGE|EX_COUNT|EX_TRLBAR', 'minlen': 4, 'name': 'lbelow', 'parser': 'parse_cmd_common'},
\ {'flags': 'EX_TRLBAR|EX_CMDWIN', 'minlen': 7, 'name': 'redrawtabline', 'parser': 'parse_cmd_common'},
\ {'flags': 'EX_WORD1|EX_TRLBAR|EX_CMDWIN', 'minlen': 7, 'name': 'scriptversion', 'parser': 'parse_cmd_common'},
\ {'flags': 'EX_BANG|EX_FILE1|EX_TRLBAR|EX_CMDWIN', 'minlen': 2, 'name': 'tcd', 'parser': 'parse_cmd_common'},
\ {'flags': 'EX_BANG|EX_FILE1|EX_TRLBAR|EX_CMDWIN', 'minlen': 3, 'name': 'tchdir', 'parser': 'parse_cmd_common'},
\ {'flags': 'EX_RANGE|EX_ZEROR|EX_EXTRA|EX_TRLBAR|EX_NOTRLCOM|EX_CTRLV|EX_CMDWIN', 'minlen': 3, 'name': 'tlmenu', 'parser': 'parse_cmd_common'},
\ {'flags': 'EX_RANGE|EX_ZEROR|EX_EXTRA|EX_TRLBAR|EX_NOTRLCOM|EX_CTRLV|EX_CMDWIN', 'minlen': 3, 'name': 'tlnoremenu', 'parser': 'parse_cmd_common'},
\ {'flags': 'EX_RANGE|EX_ZEROR|EX_EXTRA|EX_TRLBAR|EX_NOTRLCOM|EX_CTRLV|EX_CMDWIN', 'minlen': 3, 'name': 'tlunmenu', 'parser': 'parse_cmd_common'},
\ {'flags': 'EX_EXTRA|EX_TRLBAR|EX_CMDWIN', 'minlen': 2, 'name': 'xrestore', 'parser': 'parse_cmd_common'},
\]
1 0.001357 let s:VimLParser.builtin_functions = [
\ {'name': 'abs', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'acos', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'add', 'min_argc': 2, 'max_argc': 2},
\ {'name': 'and', 'min_argc': 2, 'max_argc': 2},
\ {'name': 'append', 'min_argc': 2, 'max_argc': 2},
\ {'name': 'appendbufline', 'min_argc': 3, 'max_argc': 3},
\ {'name': 'argc', 'min_argc': 0, 'max_argc': 1},
\ {'name': 'argidx', 'min_argc': 0, 'max_argc': 0},
\ {'name': 'arglistid', 'min_argc': 0, 'max_argc': 2},
\ {'name': 'argv', 'min_argc': 0, 'max_argc': 2},
\ {'name': 'asin', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'assert_beeps', 'min_argc': 1, 'max_argc': 2},
\ {'name': 'assert_equal', 'min_argc': 2, 'max_argc': 3},
\ {'name': 'assert_equalfile', 'min_argc': 2, 'max_argc': 2},
\ {'name': 'assert_exception', 'min_argc': 1, 'max_argc': 2},
\ {'name': 'assert_fails', 'min_argc': 1, 'max_argc': 3},
\ {'name': 'assert_false', 'min_argc': 1, 'max_argc': 2},
\ {'name': 'assert_inrange', 'min_argc': 3, 'max_argc': 4},
\ {'name': 'assert_match', 'min_argc': 2, 'max_argc': 3},
\ {'name': 'assert_notequal', 'min_argc': 2, 'max_argc': 3},
\ {'name': 'assert_notmatch', 'min_argc': 2, 'max_argc': 3},
\ {'name': 'assert_report', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'assert_true', 'min_argc': 1, 'max_argc': 2},
\ {'name': 'atan', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'atan2', 'min_argc': 2, 'max_argc': 2},
\ {'name': 'balloon_gettext', 'min_argc': 0, 'max_argc': 0},
\ {'name': 'balloon_show', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'balloon_split', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'browse', 'min_argc': 4, 'max_argc': 4},
\ {'name': 'browsedir', 'min_argc': 2, 'max_argc': 2},
\ {'name': 'bufadd', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'bufexists', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'buffer_exists', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'buffer_name', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'buffer_number', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'buflisted', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'bufload', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'bufloaded', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'bufname', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'bufnr', 'min_argc': 1, 'max_argc': 2},
\ {'name': 'bufwinid', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'bufwinnr', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'byte2line', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'byteidx', 'min_argc': 2, 'max_argc': 2},
\ {'name': 'byteidxcomp', 'min_argc': 2, 'max_argc': 2},
\ {'name': 'call', 'min_argc': 2, 'max_argc': 3},
\ {'name': 'ceil', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'ch_canread', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'ch_close', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'ch_close_in', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'ch_evalexpr', 'min_argc': 2, 'max_argc': 3},
\ {'name': 'ch_evalraw', 'min_argc': 2, 'max_argc': 3},
\ {'name': 'ch_getbufnr', 'min_argc': 2, 'max_argc': 2},
\ {'name': 'ch_getjob', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'ch_info', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'ch_log', 'min_argc': 1, 'max_argc': 2},
\ {'name': 'ch_logfile', 'min_argc': 1, 'max_argc': 2},
\ {'name': 'ch_open', 'min_argc': 1, 'max_argc': 2},
\ {'name': 'ch_read', 'min_argc': 1, 'max_argc': 2},
\ {'name': 'ch_readblob', 'min_argc': 1, 'max_argc': 2},
\ {'name': 'ch_readraw', 'min_argc': 1, 'max_argc': 2},
\ {'name': 'ch_sendexpr', 'min_argc': 2, 'max_argc': 3},
\ {'name': 'ch_sendraw', 'min_argc': 2, 'max_argc': 3},
\ {'name': 'ch_setoptions', 'min_argc': 2, 'max_argc': 2},
\ {'name': 'ch_status', 'min_argc': 1, 'max_argc': 2},
\ {'name': 'changenr', 'min_argc': 0, 'max_argc': 0},
\ {'name': 'char2nr', 'min_argc': 1, 'max_argc': 2},
\ {'name': 'chdir', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'cindent', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'clearmatches', 'min_argc': 0, 'max_argc': 1},
\ {'name': 'col', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'complete', 'min_argc': 2, 'max_argc': 2},
\ {'name': 'complete_add', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'complete_check', 'min_argc': 0, 'max_argc': 0},
\ {'name': 'complete_info', 'min_argc': 0, 'max_argc': 1},
\ {'name': 'confirm', 'min_argc': 1, 'max_argc': 4},
\ {'name': 'copy', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'cos', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'cosh', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'count', 'min_argc': 2, 'max_argc': 4},
\ {'name': 'cscope_connection', 'min_argc': 0, 'max_argc': 3},
\ {'name': 'cursor', 'min_argc': 1, 'max_argc': 3},
\ {'name': 'debugbreak', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'deepcopy', 'min_argc': 1, 'max_argc': 2},
\ {'name': 'delete', 'min_argc': 1, 'max_argc': 2},
\ {'name': 'deletebufline', 'min_argc': 2, 'max_argc': 3},
\ {'name': 'did_filetype', 'min_argc': 0, 'max_argc': 0},
\ {'name': 'diff_filler', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'diff_hlID', 'min_argc': 2, 'max_argc': 2},
\ {'name': 'empty', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'environ', 'min_argc': 0, 'max_argc': 0},
\ {'name': 'escape', 'min_argc': 2, 'max_argc': 2},
\ {'name': 'eval', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'eventhandler', 'min_argc': 0, 'max_argc': 0},
\ {'name': 'executable', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'execute', 'min_argc': 1, 'max_argc': 2},
\ {'name': 'exepath', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'exists', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'exp', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'expand', 'min_argc': 1, 'max_argc': 3},
\ {'name': 'expandcmd', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'extend', 'min_argc': 2, 'max_argc': 3},
\ {'name': 'feedkeys', 'min_argc': 1, 'max_argc': 2},
\ {'name': 'file_readable', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'filereadable', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'filewritable', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'filter', 'min_argc': 2, 'max_argc': 2},
\ {'name': 'finddir', 'min_argc': 1, 'max_argc': 3},
\ {'name': 'findfile', 'min_argc': 1, 'max_argc': 3},
\ {'name': 'float2nr', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'floor', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'fmod', 'min_argc': 2, 'max_argc': 2},
\ {'name': 'fnameescape', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'fnamemodify', 'min_argc': 2, 'max_argc': 2},
\ {'name': 'foldclosed', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'foldclosedend', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'foldlevel', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'foldtext', 'min_argc': 0, 'max_argc': 0},
\ {'name': 'foldtextresult', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'foreground', 'min_argc': 0, 'max_argc': 0},
\ {'name': 'funcref', 'min_argc': 1, 'max_argc': 3},
\ {'name': 'function', 'min_argc': 1, 'max_argc': 3},
\ {'name': 'garbagecollect', 'min_argc': 0, 'max_argc': 1},
\ {'name': 'get', 'min_argc': 2, 'max_argc': 3},
\ {'name': 'get_lazy', 'min_argc': 2, 'max_argc': 3},
\ {'name': 'getbufinfo', 'min_argc': 0, 'max_argc': 1},
\ {'name': 'getbufline', 'min_argc': 2, 'max_argc': 3},
\ {'name': 'getbufvar', 'min_argc': 2, 'max_argc': 3},
\ {'name': 'getchangelist', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'getchar', 'min_argc': 0, 'max_argc': 1},
\ {'name': 'getcharmod', 'min_argc': 0, 'max_argc': 0},
\ {'name': 'getcharsearch', 'min_argc': 0, 'max_argc': 0},
\ {'name': 'getcmdline', 'min_argc': 0, 'max_argc': 0},
\ {'name': 'getcmdpos', 'min_argc': 0, 'max_argc': 0},
\ {'name': 'getcmdtype', 'min_argc': 0, 'max_argc': 0},
\ {'name': 'getcmdwintype', 'min_argc': 0, 'max_argc': 0},
\ {'name': 'getcompletion', 'min_argc': 2, 'max_argc': 3},
\ {'name': 'getcurpos', 'min_argc': 0, 'max_argc': 0},
\ {'name': 'getcwd', 'min_argc': 0, 'max_argc': 2},
\ {'name': 'getenv', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'getfontname', 'min_argc': 0, 'max_argc': 1},
\ {'name': 'getfperm', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'getfsize', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'getftime', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'getftype', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'getjumplist', 'min_argc': 0, 'max_argc': 2},
\ {'name': 'getline', 'min_argc': 1, 'max_argc': 2},
\ {'name': 'getloclist', 'min_argc': 1, 'max_argc': 2},
\ {'name': 'getmatches', 'min_argc': 0, 'max_argc': 1},
\ {'name': 'getpid', 'min_argc': 0, 'max_argc': 0},
\ {'name': 'getpos', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'getqflist', 'min_argc': 0, 'max_argc': 1},
\ {'name': 'getreg', 'min_argc': 0, 'max_argc': 3},
\ {'name': 'getregtype', 'min_argc': 0, 'max_argc': 1},
\ {'name': 'gettabinfo', 'min_argc': 0, 'max_argc': 1},
\ {'name': 'gettabvar', 'min_argc': 2, 'max_argc': 3},
\ {'name': 'gettabwinvar', 'min_argc': 3, 'max_argc': 4},
\ {'name': 'gettagstack', 'min_argc': 0, 'max_argc': 1},
\ {'name': 'getwininfo', 'min_argc': 0, 'max_argc': 1},
\ {'name': 'getwinpos', 'min_argc': 0, 'max_argc': 1},
\ {'name': 'getwinposx', 'min_argc': 0, 'max_argc': 0},
\ {'name': 'getwinposy', 'min_argc': 0, 'max_argc': 0},
\ {'name': 'getwinvar', 'min_argc': 2, 'max_argc': 3},
\ {'name': 'glob', 'min_argc': 1, 'max_argc': 4},
\ {'name': 'glob2regpat', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'globpath', 'min_argc': 2, 'max_argc': 5},
\ {'name': 'has', 'min_argc': 1, 'max_argc': 1},
\ {'name': 'has_key', 'min_argc': 2, 'max_argc': 2},
\ {'name': 'haslocaldir', 'min_argc': 0, 'max_argc': 2},