diff --git a/README.mkd b/README.mkd index f516e0c..c4c07f5 100644 --- a/README.mkd +++ b/README.mkd @@ -37,6 +37,31 @@ This above code output following. (let = s:message (printf "hello %d" (+ 1 (* 2 3)))) ``` +## Vim9 script + +Vim9 script is parsed after `vim9script`, inside `:def` functions and Vim9 +lambdas, and for commands with the `:vim9cmd` modifier. `:function` bodies +and commands with `:legacy` use legacy syntax. This includes assignments +and function calls without `:let` and `:call`, declarations with types, +`=>` lambdas with blocks, line continuation without backslash, classes, +interfaces, enums, `:type`, `:import` and `:export`. + +```vim +vim9script +var total: number = [1, 2, 3] + ->reduce((acc, n) => acc + n) +total += 1 +``` + +``` +(vim9script) +(var = total: number (method (list 1 2 3) (reduce (lambda (acc n) (+ acc n))))) +(assign += total 1) +``` + +The Vim script parser is recursive, deeply nested expressions may need a +larger 'maxfuncdepth'. + ## About project name We know a name "VimL" is not the common short form of "Vim scripting language". diff --git a/autoload/vimlparser.vim b/autoload/vimlparser.vim index fe4d25a..f27aa32 100644 --- a/autoload/vimlparser.vim +++ b/autoload/vimlparser.vim @@ -152,6 +152,26 @@ let s:NODE_FINAL = 104 let s:NODE_EXPORT = 105 let s:NODE_IMPORT = 106 let s:NODE_VIM9SCRIPT = 107 +let s:NODE_TUPLE = 108 +let s:NODE_CAST = 109 +let s:NODE_ASSIGN = 110 +let s:NODE_BLOCK = 111 +let s:NODE_ENDBLOCK = 112 +let s:NODE_CLASS = 113 +let s:NODE_ENDCLASS = 114 +let s:NODE_INTERFACE = 115 +let s:NODE_ENDINTERFACE = 116 +let s:NODE_ENUM = 117 +let s:NODE_ENDENUM = 118 +let s:NODE_ENUMVALUE = 119 +let s:NODE_TYPE = 120 +let s:NODE_PUBLIC = 121 +let s:NODE_STATIC = 122 +let s:NODE_ABSTRACT = 123 +let s:NODE_FALSY = 124 +let s:NODE_INTERPOLATION = 125 +let s:NODE_DEFER = 126 +let s:NODE_ECHOWINDOW = 127 let s:TOKEN_EOF = 1 let s:TOKEN_EOL = 2 @@ -224,9 +244,14 @@ let s:TOKEN_DOTDOT = 68 let s:TOKEN_HEREDOC = 69 let s:TOKEN_LSHIFT = 70 let s:TOKEN_RSHIFT = 71 +let s:TOKEN_FATARROW = 72 +let s:TOKEN_QUESTIONQUESTION = 73 let s:MAX_FUNC_ARGS = 20 +" Binary operators that continue a Vim9 expression from the previous line. +let s:VIM9_CONTINUATION_OPS = {'+': 1, '-': 1, '*': 1, '/': 1, '%': 1, '..': 1, '||': 1, '&&': 1, '??': 1, '?': 1, ':': 1, '<<': 1, '>>': 1, '==': 1, '==?': 1, '==#': 1, '!=': 1, '!=?': 1, '!=#': 1, '>=': 1, '>=?': 1, '>=#': 1, '<=': 1, '<=?': 1, '<=#': 1, '=~': 1, '=~?': 1, '=~#': 1, '!~': 1, '!~?': 1, '!~#': 1, '>': 1, '>?': 1, '>#': 1, '<': 1, '' call self.parse_one_cmd() @@ -539,40 +634,318 @@ function! s:VimLParser.parse(reader) abort 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()) + if self.context[0].type ==# s:NODE_BLOCK + throw s:Err('E1026: Missing }', self.reader.getpos()) + elseif self.context[0].type ==# s:NODE_CLASS + throw s:Err('E1101: Missing :endclass', self.reader.getpos()) + elseif self.context[0].type ==# s:NODE_INTERFACE + throw s:Err('E1101: Missing :endinterface', self.reader.getpos()) + elseif self.context[0].type ==# s:NODE_ENUM + throw s:Err('E1101: Missing :endenum', self.reader.getpos()) + endif call self.pop_context() return toplevel endfunction function! s:VimLParser.parse_one_cmd() abort let self.ea = s:ExArg() + let self.vim9cmd = -1 if self.reader.peekn(2) ==# '#!' call self.parse_hashbang() call self.reader.get() return endif - call self.reader.skip_white_and_colon() + let vim9 = self.isvim9() + let colon = s:FALSE + while s:iswhite(self.reader.peekn(1)) || self.reader.peekn(1) ==# ':' + if self.reader.peekn(1) ==# ':' + let colon = s:TRUE + endif + call self.reader.seek_cur(1) + endwhile if self.reader.peekn(1) ==# '' call self.reader.get() return endif - if self.reader.peekn(1) ==# '"' + if self.reader.peekn(1) ==# '"' && !self.isvim9() call self.parse_comment() call self.reader.get() return endif - if self.vim9script && self.reader.peekn(1) ==# '#' + if self.isvim9() && self.reader.peekn(1) ==# '#' call self.parse_comment() call self.reader.get() return endif + if self.context[0].type ==# s:NODE_ENUM && !self.context[0].values_done && self.parse_enum_values() + call self.parse_trail() + return + endif let self.ea.linepos = self.reader.getpos() call self.parse_command_modifiers() - call self.parse_range() + let vim9 = self.isvim9() + if vim9 + " In Vim9 script a range must be preceded by a colon, without it the line + " may be an expression or assignment. + call self.reader.skip_white() + if self.reader.peekn(1) ==# ':' + let colon = s:TRUE + call self.reader.skip_white_and_colon() + endif + if colon + call self.parse_range() + elseif self.parse_vim9_statement() + call self.parse_trail() + return + endif + else + call self.parse_range() + endif call self.parse_command() call self.parse_trail() endfunction +" Recognize a Vim9 expression or assignment without :eval, :call or :let, +" like find_ex_command() in Vim. Return TRUE when the line was parsed. +function! s:VimLParser.parse_vim9_statement() abort + let r = self.reader + let pos = r.tell() + let self.ea.cmdpos = r.getpos() + let c = r.peekn(1) + if c ==# '{' + " "{" by itself is the start of a block. + call r.getn(1) + call r.skip_white() + let block = self.ends_excmds(r.peek()) + call r.seek_set(pos) + if block + return s:FALSE + endif + call self.parse_vim9_expr_cmd() + return s:TRUE + elseif c ==# '(' || c ==# "'" || c ==# '"' || (c ==# '$' && (r.p(1) ==# "'" || r.p(1) ==# '"')) || (c ==# '0' && r.p(1) ==# 'z') + call self.parse_vim9_expr_cmd() + return s:TRUE + elseif c ==# '[' + if self.is_vim9_list_assign() + call self.parse_vim9_assign() + else + call self.parse_vim9_expr_cmd() + endif + return s:TRUE + elseif c ==# '&' || c ==# '$' || (c ==# '@' && r.p(1) !=# '') + call self.parse_vim9_assign_or_expr() + return s:TRUE + elseif (c ==# '+' || c ==# '-') && r.p(1) ==# c + call self.parse_vim9_increment() + return s:TRUE + elseif s:isdigit(c) + call r.read_digit() + call r.skip_white() + let method = r.peekn(2) ==# '->' + call r.seek_set(pos) + if method + call self.parse_vim9_expr_cmd() + endif + return method + elseif !s:iswordc1(c) + return s:FALSE + endif + let name = r.read_vim9_name() + let c = r.peekn(1) + if c ==# '(' || (c ==# '<' && self.is_generic_args()) + " "funcname(" is always a function call. + call r.seek_set(pos) + call self.parse_vim9_expr_cmd() + return s:TRUE + elseif stridx(name, ':') ==# 1 || c ==# '[' || (c ==# '.' && s:iswordc1(r.p(1))) + " "g:name", "name[idx]" and "name.member" start an expression or + " assignment. + call r.seek_set(pos) + call self.parse_vim9_assign_or_expr() + return s:TRUE + endif + call r.skip_white() + let result = s:FALSE + if r.peekn(2) ==# '->' + let result = s:TRUE + elseif self.peek_assign_op() !=# '' + " "name = expr" is an assignment when "name" is a variable or not a + " command. + let result = has_key(self.declared, name) || self.is_vim9_command(pos) ==# s:FALSE + elseif self.ends_excmds(r.peek()) + " A variable followed by an operator on the next line. A variable alone + " has no effect, then it is a command like :new. + let result = has_key(self.declared, name) && (self.is_vim9_command(pos) ==# s:FALSE || self.vim9_line_continues()) + endif + call r.seek_set(pos) + if result + call self.parse_vim9_assign_or_expr() + endif + return result +endfunction + +" Return TRUE when the next line continues the expression on this line. +function! s:VimLParser.vim9_line_continues() abort + let pos = self.reader.tell() + if self.reader.peek() ==# '#' + call self.reader.getn(-1) + endif + let result = self.reader.peek() ==# '' && s:ExprTokenizer.new(self.reader, s:TRUE).next_line_continues() + call self.reader.seek_set(pos) + return result +endfunction + +" Return TRUE when the text at reader position "pos" is an Ex command that +" exists in Vim9 script. +function! s:VimLParser.is_vim9_command(cmdpos) abort + let pos = self.reader.tell() + call self.reader.seek_set(a:cmdpos) + let cmd = self.find_command() + call self.reader.seek_set(pos) + if cmd is# s:NIL + return s:FALSE + endif + return !s:is_removed_in_vim9(cmd.name) +endfunction + +" Return the assignment operator at the cursor, or an empty string. +function! s:VimLParser.peek_assign_op() abort + let s3 = self.reader.peekn(3) + let s2 = self.reader.peekn(2) + let op = '' + if s3 ==# '..=' || s3 ==# '=<<' + let op = s3 + elseif s2 ==# '+=' || s2 ==# '-=' || s2 ==# '*=' || s2 ==# '/=' || s2 ==# '%=' || s2 ==# '.=' + let op = s2 + elseif s2 ==# '==' || s2 ==# '=~' || s2 ==# '=>' + return '' + elseif self.reader.peekn(1) ==# '=' + let op = '=' + endif + return op +endfunction + +" Return TRUE when the generic type arguments of a function call follow: +" "(". +function! s:VimLParser.is_generic_args() abort + let r = self.reader + let pos = r.tell() + call r.getn(1) + let depth = 1 + while depth > 0 + let c = r.peekn(1) + if c ==# '<' + let depth += 1 + elseif c ==# '>' + let depth -= 1 + elseif !s:iswordc(c) && c !=# ',' && c !=# ' ' && c !=# '(' && c !=# ')' && c !=# ':' && c !=# '.' + call r.seek_set(pos) + return s:FALSE + endif + call r.getn(1) + endwhile + let result = r.peekn(1) ==# '(' + call r.seek_set(pos) + return result +endfunction + +" Return TRUE when "[a, b] =" follows: the list is closed on this line and +" followed by an assignment operator. +function! s:VimLParser.is_vim9_list_assign() abort + let r = self.reader + let pos = r.tell() + let depth = 0 + while s:TRUE + let c = r.peekn(1) + if c ==# '' + call r.seek_set(pos) + return s:FALSE + endif + call r.getn(1) + if c ==# '[' + let depth += 1 + elseif c ==# ']' + let depth -= 1 + if depth ==# 0 + break + endif + elseif c ==# "'" || c ==# '"' + while r.peekn(1) !=# '' && r.peekn(1) !=# c + call r.getn(1) + endwhile + call r.getn(1) + endif + endwhile + call r.skip_white() + let op = self.peek_assign_op() + call r.seek_set(pos) + return op !=# '' && op !=# '=<<' +endfunction + +" Vim9 expression used as a command. A function call is like :call, any +" other expression is like :eval. +function! s:VimLParser.parse_vim9_expr_cmd() abort + let left = self.parse_expr() + if left.type ==# s:NODE_CALL + let node = s:Node(s:NODE_EXCALL) + else + let node = s:Node(s:NODE_EVAL) + endif + let node.pos = self.ea.cmdpos + let node.ea = self.ea + let node.left = left + call self.add_node(node) +endfunction + +function! s:VimLParser.parse_vim9_assign_or_expr() abort + let pos = self.reader.tell() + call self.parse_lvalue() + call self.reader.skip_white() + let op = self.peek_assign_op() + call self.reader.seek_set(pos) + if op ==# '' + call self.parse_vim9_expr_cmd() + else + call self.parse_vim9_assign() + endif +endfunction + +" Vim9 assignment without :let: "name = expr", "[a, b] = expr", "name += expr" +function! s:VimLParser.parse_vim9_assign() abort + let lhs = self.parse_letlhs() + call self.reader.skip_white() + let node = s:Node(s:NODE_ASSIGN) + let node.pos = self.ea.cmdpos + let node.ea = self.ea + let node.op = self.peek_assign_op() + let node.left = lhs.left + let node.list = lhs.list + let node.rest = lhs.rest + call self.reader.getn(len(node.op)) + if node.op ==# '=<<' + call self.reader.skip_white() + let node.right = self.parse_heredoc(self.heredoc_prefix()) + else + let node.right = self.parse_expr() + endif + call self.add_node(node) +endfunction + +" Vim9 "++var" and "--var" +function! s:VimLParser.parse_vim9_increment() abort + let node = s:Node(s:NODE_ASSIGN) + let node.pos = self.ea.cmdpos + let node.ea = self.ea + let node.op = self.reader.getn(2) + let node.left = self.parse_lvalue() + let node.list = s:NIL + let node.rest = s:NIL + let node.right = s:NIL + call self.add_node(node) +endfunction + " FIXME: function! s:VimLParser.parse_command_modifiers() abort let modifiers = [] @@ -584,9 +957,22 @@ function! s:VimLParser.parse_command_modifiers() abort call self.reader.skip_white() endif let k = self.reader.read_alpha() + if k ==# 'vim' && self.reader.peekn(1) ==# '9' + let k .= self.reader.read_alnum() + endif let c = self.reader.peekn(1) call self.reader.skip_white() - if stridx('aboveleft', k) ==# 0 && len(k) >= 3 " abo\%[veleft] + if self.isvim9() && (c ==# '(' || c ==# '[' || c ==# '.' || c ==# ':' || self.peek_assign_op() !=# '' || self.reader.peekn(2) ==# '->') + " A Vim9 variable or function, not a modifier. + call self.reader.seek_set(pos) + break + elseif stridx('vim9cmd', k) ==# 0 && len(k) >= 4 " vim9\%[cmd] + call add(modifiers, {'name': 'vim9cmd'}) + let self.vim9cmd = s:TRUE + elseif stridx('legacy', k) ==# 0 && len(k) >= 3 " leg\%[acy] + call add(modifiers, {'name': 'legacy'}) + let self.vim9cmd = s:FALSE + elseif 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'}) @@ -772,7 +1158,7 @@ function! s:VimLParser.parse_command() abort let self.ea.cmdpos = self.reader.getpos() - if self.reader.peekn(1) ==# '' || self.reader.peekn(1) ==# '"' || (self.vim9script && self.reader.peekn(1) ==# '#') + if self.reader.peekn(1) ==# '' || self.ends_excmds(self.reader.peekn(1)) if !empty(self.ea.modifiers) || !empty(self.ea.range) call self.parse_cmd_modifier_range() endif @@ -786,6 +1172,21 @@ function! s:VimLParser.parse_command() abort throw s:Err(printf('E492: Not an editor command: %s', self.reader.peekline()), self.ea.cmdpos) endif + if self.isvim9() && s:is_removed_in_vim9(self.ea.cmd.name) + call self.reader.setpos(self.ea.cmdpos) + throw s:Err(printf('E1100: Command not supported in Vim9 script (missing :var?): %s', self.reader.peekline()), self.ea.cmdpos) + endif + + " In legacy script :final is an abbreviation of :finally. + if self.ea.cmd.name ==# 'final' && !self.isvim9() + for x in self.builtin_commands + if x.name ==# 'finally' + let self.ea.cmd = x + break + endif + endfor + 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 @@ -961,6 +1362,34 @@ function! s:VimLParser._parse_command(parser) abort call self.parse_cmd_export() elseif a:parser ==# 'parse_cmd_import' call self.parse_cmd_import() + elseif a:parser ==# 'parse_cmd_abstract' + call self.parse_cmd_abstract() + elseif a:parser ==# 'parse_cmd_class' + call self.parse_cmd_class() + elseif a:parser ==# 'parse_cmd_endclass' + call self.parse_cmd_endclass() + elseif a:parser ==# 'parse_cmd_interface' + call self.parse_cmd_interface() + elseif a:parser ==# 'parse_cmd_endinterface' + call self.parse_cmd_endinterface() + elseif a:parser ==# 'parse_cmd_enum' + call self.parse_cmd_enum() + elseif a:parser ==# 'parse_cmd_endenum' + call self.parse_cmd_endenum() + elseif a:parser ==# 'parse_cmd_type' + call self.parse_cmd_type() + elseif a:parser ==# 'parse_cmd_public' + call self.parse_cmd_public() + elseif a:parser ==# 'parse_cmd_static' + call self.parse_cmd_static() + elseif a:parser ==# 'parse_cmd_defer' + call self.parse_cmd_defer() + elseif a:parser ==# 'parse_cmd_echowindow' + call self.parse_cmd_echowindow() + elseif a:parser ==# 'parse_cmd_block' + call self.parse_cmd_block() + elseif a:parser ==# 'parse_cmd_endblock' + call self.parse_cmd_endblock() else throw printf('unknown parser: %s', string(a:parser)) endif @@ -976,7 +1405,7 @@ function! s:VimLParser.find_command() abort 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 =~# '[@*!=><&~#]' + elseif c =~# '[@*!=><&~#]' || c ==# '{' || c ==# '}' call self.reader.getn(1) let name = c elseif self.reader.peekn(2) ==# 'py' @@ -1122,7 +1551,7 @@ endfunction function! s:VimLParser.parse_comment() abort let npos = self.reader.getpos() let c = self.reader.get() - if c !=# '"' && !(self.vim9script && c ==# '#') + if c !=# '"' && c !=# '#' throw s:Err(printf('unexpected character: %s', c), npos) endif let node = s:Node(s:NODE_COMMENT) @@ -1141,9 +1570,10 @@ function! s:VimLParser.parse_trail() abort elseif c ==# '|' call self.reader.get() elseif c ==# '"' + " Also in Vim9 script a double quote after a command starts a comment. call self.parse_comment() call self.reader.get() - elseif self.vim9script && c ==# '#' + elseif self.isvim9() && c ==# '#' call self.parse_comment() call self.reader.get() else @@ -1185,12 +1615,24 @@ function! s:VimLParser.parse_cmd_common() abort let node.ea = self.ea let node.str = self.reader.getstr(self.ea.linepos, end) call self.add_node(node) + if (self.ea.cmd.name ==# 'command' || self.ea.cmd.name ==# 'autocmd') && s:ends_with_block(node.str) + " The commands of a user command or autocommand in a block use Vim9 + " syntax: {cmd} ... } + let block = s:Node(s:NODE_BLOCK) + let block.pos = self.ea.cmdpos + let block.ea = self.ea + let block.body = [] + let block.endblock = s:NIL + let node.block = block + call self.push_context(block) + endif endfunction 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 vim9 = self.isvim9() let pc = '' let end = self.reader.getpos() let nospend = end @@ -1220,12 +1662,12 @@ function! s:VimLParser.separate_nextcmd() abort endif call self.reader.getn(1) elseif c ==# '|' || c ==# "\n" || - \ (c ==# '"' && self.ea.cmd.flags !~# '\' + \ (c ==# '"' && !vim9 && self.ea.cmd.flags !~# '\' \ && ((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 !=# '@')) - \ || (self.vim9script && c ==# '#' && s:iswhite(pc) && self.ea.cmd.flags !~# '\') + \ || (vim9 && c ==# '#' && s:iswhite(pc) && self.ea.cmd.flags !~# '\') let has_cpo_bar = s:FALSE " &cpoptions =~ 'b' if (!has_cpo_bar || self.ea.cmd.flags !~# '\') && pc ==# '\' call self.reader.get() @@ -1530,7 +1972,7 @@ function! s:VimLParser.parse_cmd_delfunction() abort endfunction function! s:VimLParser.parse_cmd_return() abort - if self.find_context(s:NODE_FUNCTION) ==# -1 && self.find_context(s:NODE_DEF) ==# -1 + if self.find_context(s:NODE_FUNCTION) ==# -1 && self.find_context(s:NODE_DEF) ==# -1 && self.find_context(s:NODE_LAMBDA) ==# -1 throw s:Err('E133: :return not inside a function', self.ea.cmdpos) endif let node = s:Node(s:NODE_RETURN) @@ -1555,7 +1997,12 @@ function! s:VimLParser.parse_cmd_call() abort throw s:Err('E471: Argument required', self.reader.getpos()) endif let node.left = self.parse_expr() - if node.left.type !=# s:NODE_CALL + " A method call may follow the function call: call Func()->Method() + let base = node.left + while base.type ==# s:NODE_METHOD + let base = base.left + endwhile + if base.type !=# s:NODE_CALL throw s:Err('Not an function call', node.left.pos) endif call self.add_node(node) @@ -1657,31 +2104,7 @@ function! s:VimLParser.parse_cmd_let() abort call self.reader.getn(len(s2)) call self.reader.skip_white() let node.op = s2 - - " compute allowed prefix for heredoc end marker (e.g. EOF) - let pos = self.reader.tell() - while self.reader.tell() > 0 - if self.reader.peek() ==# '' - call self.reader.seek_cur(1) - break - endif - call self.reader.seek_cur(-1) - endwhile - let prefix = '' - while s:TRUE - let c = self.reader.getn(1) - if c ==# ':' - " any presence of leading ':' disables prefix for heredoc end marker - let prefix = '' - break - elseif !s:iswhite(c) - break - endif - let prefix .= c - endwhile - call self.reader.seek_set(pos) - - let node.right = self.parse_heredoc(prefix) + let node.right = self.parse_heredoc(self.heredoc_prefix()) call self.add_node(node) return elseif s1 ==# '=' @@ -1694,7 +2117,38 @@ function! s:VimLParser.parse_cmd_let() abort call self.add_node(node) endfunction +" Compute the allowed prefix for a heredoc end marker (e.g. EOF): the indent +" of the command line. +function! s:VimLParser.heredoc_prefix() abort + let pos = self.reader.tell() + while self.reader.tell() > 0 + if self.reader.peek() ==# '' + call self.reader.seek_cur(1) + break + endif + call self.reader.seek_cur(-1) + endwhile + let prefix = '' + while s:TRUE + let c = self.reader.getn(1) + if c ==# ':' + " any presence of leading ':' disables prefix for heredoc end marker + let prefix = '' + break + elseif !s:iswhite(c) + break + endif + let prefix .= c + endwhile + call self.reader.seek_set(pos) + return prefix +endfunction + function! s:VimLParser.parse_cmd_const() abort + if self.isvim9() + call self.parse_vim9_decl(s:NODE_CONST) + return + endif let pos = self.reader.tell() call self.reader.skip_white() @@ -1730,10 +2184,17 @@ function! s:VimLParser.parse_cmd_const() abort endfunction function! s:VimLParser.parse_cmd_vim9script() abort - call self.reader.skip_white() let node = s:Node(s:NODE_VIM9SCRIPT) let node.pos = self.ea.cmdpos let node.ea = self.ea + let node.noclear = s:FALSE + call self.reader.skip_white() + let pos = self.reader.tell() + if self.reader.read_alpha() ==# 'noclear' + let node.noclear = s:TRUE + else + call self.reader.seek_set(pos) + endif let self.vim9script = 1 call self.add_node(node) endfunction @@ -1757,6 +2218,15 @@ function! s:VimLParser.parse_cmd_def() abort endif let left = self.parse_lvalue_func() + + " Generic function: :def {name}<{type}, ...>( + let type_params = '' + if self.reader.peekn(1) ==# '<' + while self.reader.peekn(1) !=# '' && self.reader.peekn(1) !=# '>' + let type_params .= self.reader.getn(1) + endwhile + let type_params .= self.reader.getn(1) + endif call self.reader.skip_white() " :def {name} @@ -1774,89 +2244,66 @@ function! s:VimLParser.parse_cmd_def() abort let node.left = left let node.rlist = [] let node.default_args = [] - let node.attr = {'range': 0, 'abort': 0, 'dict': 0, 'closure': 0, 'return_type': ''} + let node.attr = {'range': 0, 'abort': 0, 'dict': 0, 'closure': 0, 'return_type': '', 'type_params': type_params} let node.enddef = s:NIL + " The arguments use Vim9 syntax, also in a legacy script. + call self.add_node(node) + call self.push_context(node) call self.reader.getn(1) - call self.reader.skip_white() - if self.reader.peekn(1) ==# ')' - call self.reader.getn(1) - else - let named = {} - while s:TRUE - let varnode = s:Node(s:NODE_IDENTIFIER) - call self.reader.skip_white() - let varnode.type_str = '' - " Check for ...name (variadic) - if self.reader.peekn(3) ==# '...' - call self.reader.getn(3) - call self.reader.skip_white() - let vname = self.reader.read_word() - let varnode.pos = self.reader.getpos() - let varnode.value = '...' . vname - " Optionally read type annotation - call self.reader.skip_white() - if self.reader.peekn(1) ==# ':' - call self.reader.getn(1) - call self.reader.skip_white() - let varnode.type_str = self.read_type() - endif - call add(node.rlist, varnode) - call self.reader.skip_white() - if self.reader.peekn(1) ==# ')' - call self.reader.getn(1) - break - else - throw s:Err(printf('E475: Invalid argument: %s', self.reader.peekn(1)), self.reader.getpos()) - endif - endif - let npos = self.reader.getpos() - let pname = self.reader.read_word() - if pname ==# '' - if self.reader.peekn(1) ==# ')' - call self.reader.getn(1) - break - endif - throw s:Err(printf('E475: Invalid argument: %s', self.reader.peekn(1)), self.reader.getpos()) - endif - if has_key(named, pname) - throw s:Err(printf('E853: Duplicate argument name: %s', pname), npos) - endif - let named[pname] = 1 - let varnode.pos = npos - let varnode.value = pname - call add(node.rlist, varnode) - " Check for type annotation - call self.reader.skip_white() - if self.reader.peekn(1) ==# ':' - call self.reader.getn(1) - call self.reader.skip_white() - let varnode.type_str = self.read_type() - endif - " Check for default value + let named = {} + while s:TRUE + call self.skip_vim9_white() + if self.reader.peekn(1) ==# ')' + call self.reader.getn(1) + break + endif + let varnode = s:Node(s:NODE_IDENTIFIER) + let varnode.pos = self.reader.getpos() + let varnode.type_str = '' + let variadic = self.reader.peekn(3) ==# '...' + if variadic + call self.reader.getn(3) + endif + let pname = self.reader.read_word() + if pname ==# 'this' && self.reader.peekn(1) ==# '.' + " constructor argument that sets an object variable: this.name + let pname .= self.reader.getn(1) . self.reader.read_word() + endif + if pname ==# '' + throw s:Err(printf('E475: Invalid argument: %s', self.reader.peekn(1)), self.reader.getpos()) + endif + if has_key(named, pname) && pname !=# '_' + throw s:Err(printf('E853: Duplicate argument name: %s', pname), varnode.pos) + endif + let named[pname] = 1 + let self.declared[pname] = 1 + let varnode.value = pname + if variadic + let varnode.value = '...' . pname + endif + call add(node.rlist, varnode) + " Check for type annotation + if self.reader.peekn(1) ==# ':' + call self.reader.getn(1) call self.reader.skip_white() - if self.reader.peekn(1) ==# '=' - call self.reader.getn(1) - call self.reader.skip_white() - call add(node.default_args, self.parse_expr()) - elseif len(node.default_args) > 0 - throw s:Err('E989: Non-default argument follows default argument', varnode.pos) - endif + let varnode.type_str = self.read_type() + endif + " Check for default value + call self.reader.skip_white() + if self.reader.peekn(1) ==# '=' && !variadic + call self.reader.getn(1) call self.reader.skip_white() - if self.reader.peekn(1) ==# ',' - call self.reader.getn(1) - call self.reader.skip_white() - if self.reader.peekn(1) ==# ')' - call self.reader.getn(1) - break - endif - elseif self.reader.peekn(1) ==# ')' - call self.reader.getn(1) - break - else - throw s:Err(printf('E475: Invalid argument: %s', self.reader.peekn(1)), self.reader.getpos()) - endif - endwhile - endif + call add(node.default_args, self.parse_expr()) + elseif len(node.default_args) > 0 && !variadic + throw s:Err('E989: Non-default argument follows default argument', varnode.pos) + endif + call self.skip_vim9_white() + if self.reader.peekn(1) ==# ',' + call self.reader.getn(1) + elseif self.reader.peekn(1) !=# ')' + throw s:Err(printf('E475: Invalid argument: %s', self.reader.peekn(1)), self.reader.getpos()) + endif + endwhile " Check for return type annotation ': type' call self.reader.skip_white() if self.reader.peekn(1) ==# ':' @@ -1864,8 +2311,25 @@ function! s:VimLParser.parse_cmd_def() abort call self.reader.skip_white() let node.attr.return_type = self.read_type() endif - call self.add_node(node) - call self.push_context(node) + " A method in an interface and an abstract method have no body. + if self.abstract || self.context[1].type ==# s:NODE_INTERFACE + call self.pop_context() + endif +endfunction + +" Skip white space, comments and line breaks, e.g. in the argument list of a +" :def function. +function! s:VimLParser.skip_vim9_white() abort + while s:TRUE + call self.reader.skip_white() + if self.reader.peek() ==# '#' + call self.reader.getn(-1) + endif + if self.reader.peek() !=# '' + break + endif + call self.reader.get() + endwhile endfunction function! s:VimLParser.read_type() abort @@ -1879,6 +2343,12 @@ function! s:VimLParser.read_type() abort break endif endwhile + " Handle func: rettype + if type_str ==# 'func' && self.reader.peekn(1) ==# ':' && s:iswhite(self.reader.p(1)) + call self.reader.getn(1) + call self.reader.skip_white() + return type_str . ': ' . self.read_type() + endif " Handle generics: type<...> if self.reader.peekn(1) ==# '<' let type_str .= self.reader.getn(1) @@ -1913,14 +2383,46 @@ function! s:VimLParser.read_type() abort " Check for ': rettype' after func params call self.reader.skip_white() if self.reader.peekn(1) ==# ':' - let type_str .= self.reader.getn(1) + call self.reader.getn(1) call self.reader.skip_white() - let type_str .= self.read_type() + let type_str .= ': ' . self.read_type() endif endif return type_str endfunction +" Parse the statements of a Vim9 lambda "(args) => {", up to the "}" at the +" start of a line. Only a comment may follow the "{". +function! s:VimLParser.parse_lambda_block(node) abort + let ea = self.ea + let vim9cmd = self.vim9cmd + call self.reader.skip_white() + if self.reader.peek() ==# '#' + call self.reader.getn(-1) + endif + if self.reader.peek() !=# '' + throw s:Err(printf('E488: Trailing characters: %s', self.reader.peekline()), self.reader.getpos()) + endif + call self.reader.get() + call self.push_context(a:node) + while s:TRUE + if self.reader.peek() ==# '' + throw s:Err('E1171: Missing } after inline function', self.reader.getpos()) + endif + let pos = self.reader.tell() + call self.reader.skip_white() + if self.context[0] is# a:node && self.reader.peek() ==# '}' + call self.reader.get() + break + endif + call self.reader.seek_set(pos) + call self.parse_one_cmd() + endwhile + call self.pop_context() + let self.ea = ea + let self.vim9cmd = vim9cmd +endfunction + function! s:VimLParser.parse_cmd_enddef() abort call self.check_missing_endif('ENDDEF', self.ea.cmdpos) call self.check_missing_endtry('ENDDEF', self.ea.cmdpos) @@ -1938,133 +2440,117 @@ function! s:VimLParser.parse_cmd_enddef() abort endfunction function! s:VimLParser.parse_cmd_var() abort - let pos = self.reader.tell() - call self.reader.skip_white() + call self.parse_vim9_decl(s:NODE_VAR) +endfunction - " :var - if self.ends_excmds(self.reader.peek()) - call self.reader.seek_set(pos) - call self.parse_cmd_common() - return - endif +function! s:VimLParser.parse_cmd_final() abort + call self.parse_vim9_decl(s:NODE_FINAL) +endfunction - " Read variable name directly (avoid LvalueParser eating ':' as part of name) - let npos = self.reader.getpos() - let vname = self.reader.read_word() - if vname ==# '' - call self.reader.seek_set(pos) - call self.parse_cmd_common() - return - endif - let left = s:Node(s:NODE_IDENTIFIER) - let left.pos = npos - let left.value = vname +" Vim9 declaration with :var, :final or :const: +" var name[: type] [= expr] +" var [name[: type], ...[; rest]] = expr +" var name[: type] =<< [trim] [eval] END +function! s:VimLParser.parse_vim9_decl(type) abort + let pos = self.reader.tell() call self.reader.skip_white() - " Check for type annotation - let type_str = '' - if self.reader.peekn(1) ==# ':' - call self.reader.getn(1) - call self.reader.skip_white() - let type_str = self.read_type() - call self.reader.skip_white() - endif - - let s1 = self.reader.peekn(1) - let s2 = self.reader.peekn(2) - if s2 ==# '..' - let s2 = self.reader.peekn(3) - endif - - " :var {var-name} (no assignment) - if self.ends_excmds(s1) || (s2 !=# '+=' && s2 !=# '-=' && s2 !=# '.=' && s2 !=# '..=' && s2 !=# '*=' && s2 !=# '/=' && s2 !=# '%=' && s1 !=# '=') + " :var without argument lists variables + if self.ends_excmds(self.reader.peek()) call self.reader.seek_set(pos) call self.parse_cmd_common() return endif - " :var left op right - let node = s:Node(s:NODE_VAR) + let node = s:Node(a:type) let node.pos = self.ea.cmdpos let node.ea = self.ea let node.op = '' - let node.left = left + let node.left = s:NIL let node.list = s:NIL let node.rest = s:NIL let node.right = s:NIL - let node.type_str = type_str - if s2 ==# '+=' || s2 ==# '-=' || s2 ==# '.=' || s2 ==# '..=' || s2 ==# '*=' || s2 ==# '/=' || s2 ==# '%=' - call self.reader.getn(len(s2)) - let node.op = s2 - elseif s1 ==# '=' + let node.type_str = '' + if self.reader.peekn(1) ==# '[' call self.reader.getn(1) - let node.op = s1 + let node.list = [] + while s:TRUE + call add(node.list, self.parse_vim9_decl_name()) + call self.reader.skip_white() + let c = self.reader.getn(1) + if c ==# ';' + let node.rest = self.parse_vim9_decl_name() + call self.reader.skip_white() + let c = self.reader.getn(1) + endif + if c ==# ']' + break + elseif c !=# ',' + throw s:Err(printf('E475: Invalid argument: %s', c), self.reader.getpos()) + endif + endwhile + for x in node.list + call self.declare(x) + endfor + call self.declare(node.rest) else - throw 'NOT REACHED' + let node.left = self.parse_vim9_decl_name() + let node.type_str = node.left.type_str + call self.declare(node.left) + endif + call self.reader.skip_white() + let node.op = self.peek_assign_op() + call self.reader.getn(len(node.op)) + if node.op ==# '=<<' + call self.reader.skip_white() + let node.right = self.parse_heredoc(self.heredoc_prefix()) + elseif node.op !=# '' + let node.right = self.parse_expr() endif - let node.right = self.parse_expr() call self.add_node(node) endfunction -function! s:VimLParser.parse_cmd_final() abort - let pos = self.reader.tell() +" Variable name with an optional type in a Vim9 declaration: "name: type" +function! s:VimLParser.parse_vim9_decl_name() abort call self.reader.skip_white() - - " :final - if self.ends_excmds(self.reader.peek()) - call self.reader.seek_set(pos) - call self.parse_cmd_common() - return - endif - - " Read variable name directly - let npos = self.reader.getpos() - let vname = self.reader.read_word() - if vname ==# '' - call self.reader.seek_set(pos) - call self.parse_cmd_common() - return + let node = s:Node(s:NODE_IDENTIFIER) + let node.pos = self.reader.getpos() + let node.value = self.reader.read_vim9_name() + let node.type_str = '' + if node.value ==# '' + throw s:Err(printf('E475: Invalid argument: %s', self.reader.peekline()), node.pos) endif - let left = s:Node(s:NODE_IDENTIFIER) - let left.pos = npos - let left.value = vname - call self.reader.skip_white() - - " Check for type annotation - let type_str = '' if self.reader.peekn(1) ==# ':' call self.reader.getn(1) call self.reader.skip_white() - let type_str = self.read_type() - call self.reader.skip_white() + let node.type_str = self.read_type() endif + return node +endfunction - let s1 = self.reader.peekn(1) +function! s:VimLParser.parse_cmd_export() abort + call self.parse_wrapper(s:NODE_EXPORT) +endfunction - " :final {var-name} - if self.ends_excmds(s1) || s1 !=# '=' - call self.reader.seek_set(pos) - call self.parse_cmd_common() - return - endif +function! s:VimLParser.parse_cmd_public() abort + call self.parse_wrapper(s:NODE_PUBLIC) +endfunction - " :final left = right - let node = s:Node(s:NODE_FINAL) - let node.pos = self.ea.cmdpos - let node.ea = self.ea - call self.reader.getn(1) - let node.op = s1 - let node.left = left - let node.list = s:NIL - let node.rest = s:NIL - let node.right = self.parse_expr() - let node.type_str = type_str - call self.add_node(node) +function! s:VimLParser.parse_cmd_static() abort + call self.parse_wrapper(s:NODE_STATIC) endfunction -function! s:VimLParser.parse_cmd_export() abort +function! s:VimLParser.parse_cmd_abstract() abort + let self.abstract = s:TRUE + call self.parse_wrapper(s:NODE_ABSTRACT) + let self.abstract = s:FALSE +endfunction + +" Parse a command that applies to the following command, like :export +" and :static. The nodes of the following command go into the body. +function! s:VimLParser.parse_wrapper(type) abort call self.reader.skip_white() - let export_pos = self.ea.cmdpos + let wrapper_pos = self.ea.cmdpos " Re-find the inner command let self.ea.cmdpos = self.reader.getpos() let self.ea.cmd = self.find_command() @@ -2077,57 +2563,286 @@ function! s:VimLParser.parse_cmd_export() abort endif call self.reader.skip_white() let self.ea.argpos = self.reader.getpos() - let export_node = s:Node(s:NODE_EXPORT) - let export_node.pos = export_pos - let export_node.ea = self.ea - let export_node.body = [] + let wrapper = s:Node(a:type) + let wrapper.pos = wrapper_pos + let wrapper.ea = self.ea + let wrapper.body = [] " Remember current context body position let ctx = self.context[0] let before = len(ctx.body) " Parse the inner command call self._parse_command(self.ea.cmd.parser) - " Move newly-added nodes into export body + " Move newly-added nodes into the wrapper body while len(ctx.body) > before let moved_node = ctx.body[before] call remove(ctx.body, before) - call add(export_node.body, moved_node) + call add(wrapper.body, moved_node) endwhile - call add(ctx.body, export_node) + call add(ctx.body, wrapper) endfunction -function! s:VimLParser.parse_cmd_import() abort - let node = s:Node(s:NODE_IMPORT) +" :class {name} [extends {class}] [implements {interface}, ...] +function! s:VimLParser.parse_cmd_class() abort + let node = s:Node(s:NODE_CLASS) let node.pos = self.ea.cmdpos let node.ea = self.ea - let node.left = s:NIL - let node.str = '' - call self.reader.skip_white() - " Read the rest of the import line, stopping at a trailing comment. - let line = '' - let pending_ws = '' - let last_was_white = s:FALSE + let node.name = self.read_class_name() + let node.extends = '' + let node.implements = [] + let node.body = [] + let node.endclass = s:NIL while s:TRUE - let c = self.reader.peekn(1) - if c ==# '' + call self.reader.skip_white() + let pos = self.reader.tell() + let key = self.reader.read_alpha() + if key ==# 'extends' + call self.reader.skip_white() + let node.extends = self.read_type() + elseif key ==# 'implements' || key ==# 'specifies' + let node.implements = self.read_type_list() + else + call self.reader.seek_set(pos) break endif - if c ==# '#' && last_was_white - " Consume the rest of the line, so parse_trail doesn't see it. - call self.reader.getn(-1) + endwhile + call self.add_node(node) + call self.push_context(node) +endfunction + +function! s:VimLParser.parse_cmd_endclass() abort + call self.parse_class_end(s:NODE_CLASS, 'E1316: Class can only be defined in Vim9 script') +endfunction + +" :interface {name} [extends {interface}, ...] +function! s:VimLParser.parse_cmd_interface() abort + let node = s:Node(s:NODE_INTERFACE) + let node.pos = self.ea.cmdpos + let node.ea = self.ea + let node.name = self.read_class_name() + let node.extends = [] + let node.body = [] + let node.endinterface = s:NIL + call self.reader.skip_white() + let pos = self.reader.tell() + if self.reader.read_alpha() ==# 'extends' + let node.extends = self.read_type_list() + else + call self.reader.seek_set(pos) + endif + call self.add_node(node) + call self.push_context(node) +endfunction + +function! s:VimLParser.parse_cmd_endinterface() abort + call self.parse_class_end(s:NODE_INTERFACE, 'E1345: :endinterface without :interface') +endfunction + +" :enum {name} [implements {interface}, ...] +function! s:VimLParser.parse_cmd_enum() abort + let node = s:Node(s:NODE_ENUM) + let node.pos = self.ea.cmdpos + let node.ea = self.ea + let node.name = self.read_class_name() + let node.implements = [] + let node.enumvalues = [] + let node.body = [] + let node.endenum = s:NIL + " The enum values come first. + let node.values_done = s:FALSE + call self.reader.skip_white() + let pos = self.reader.tell() + if self.reader.read_alpha() ==# 'implements' + let node.implements = self.read_type_list() + else + call self.reader.seek_set(pos) + endif + call self.add_node(node) + call self.push_context(node) +endfunction + +function! s:VimLParser.parse_cmd_endenum() abort + call self.parse_class_end(s:NODE_ENUM, 'E1419: :endenum without :enum') +endfunction + +" Parse the enum values at the start of an enum: "Name[(args)], ..." +" Return FALSE when the line is not a list of values. +function! s:VimLParser.parse_enum_values() abort + let enumnode = self.context[0] + let pos = self.reader.tell() + let word = self.reader.read_word() + let c = self.reader.peekn(1) + call self.reader.seek_set(pos) + if word ==# '' || word ==# 'var' || word ==# 'final' || word ==# 'const' || word ==# 'def' + \ || word ==# 'static' || word ==# 'public' || word ==# 'endenum' + \ || (c !=# '' && c !=# ',' && c !=# '(' && !s:iswhite(c)) + let enumnode.values_done = s:TRUE + return s:FALSE + endif + while s:TRUE + call self.skip_vim9_white() + let node = s:Node(s:NODE_ENUMVALUE) + let node.pos = self.reader.getpos() + let node.value = self.reader.read_word() + let node.rlist = [] + if self.reader.peekn(1) ==# '(' + let p = s:ExprParser.new(self.reader, self) + call p.tokenizer.get() + let node.rlist = p.parse_rlist() + endif + call add(enumnode.enumvalues, node) + call self.reader.skip_white() + if self.reader.peekn(1) !=# ',' break endif call self.reader.getn(1) - if s:iswhite(c) - let pending_ws .= c - let last_was_white = s:TRUE - else - let line .= pending_ws . c - let pending_ws = '' - let last_was_white = s:FALSE + call self.skip_vim9_white() + if self.reader.peek() ==# '' + break + endif + let pos = self.reader.tell() + let word = self.reader.read_word() + call self.reader.seek_set(pos) + if word ==# 'endenum' + break + endif + endwhile + let enumnode.values_done = s:TRUE + return s:TRUE +endfunction + +function! s:VimLParser.parse_class_end(type, msg) abort + call self.check_missing_endif(self.ea.cmd.name, self.ea.cmdpos) + call self.check_missing_endtry(self.ea.cmd.name, self.ea.cmdpos) + call self.check_missing_endwhile(self.ea.cmd.name, self.ea.cmdpos) + call self.check_missing_endfor(self.ea.cmd.name, self.ea.cmdpos) + call self.check_missing_enddef(self.ea.cmd.name, self.ea.cmdpos) + if self.context[0].type !=# a:type + throw s:Err(a:msg, self.ea.cmdpos) + endif + if a:type ==# s:NODE_CLASS + let node = s:Node(s:NODE_ENDCLASS) + let self.context[0].endclass = node + elseif a:type ==# s:NODE_INTERFACE + let node = s:Node(s:NODE_ENDINTERFACE) + let self.context[0].endinterface = node + else + let node = s:Node(s:NODE_ENDENUM) + let self.context[0].endenum = node + endif + let node.pos = self.ea.cmdpos + let node.ea = self.ea + call self.pop_context() +endfunction + +" :type {name} = {type} +function! s:VimLParser.parse_cmd_type() abort + if !self.isvim9() + call self.parse_cmd_common() + return + endif + let node = s:Node(s:NODE_TYPE) + let node.pos = self.ea.cmdpos + let node.ea = self.ea + let node.name = self.read_class_name() + call self.reader.skip_white() + if self.reader.getn(1) !=# '=' + throw s:Err('E1403: Missing "=" in type alias', self.reader.getpos()) + endif + call self.reader.skip_white() + let node.type_str = self.read_type() + let self.declared[node.name] = 1 + call self.add_node(node) +endfunction + +function! s:VimLParser.read_class_name() abort + call self.reader.skip_white() + let name = self.reader.read_word() + if name ==# '' + throw s:Err(printf('E475: Invalid argument: %s', self.reader.peekline()), self.reader.getpos()) + endif + let self.declared[name] = 1 + return name +endfunction + +" A comma separated list of types, e.g. after "implements". +function! s:VimLParser.read_type_list() abort + let list = [] + while s:TRUE + call self.reader.skip_white() + call add(list, self.read_type()) + call self.reader.skip_white() + if self.reader.peekn(1) !=# ',' + break endif + call self.reader.getn(1) endwhile - let node.str = line + return list +endfunction + +" :import [autoload] {expr} [as {name}] +function! s:VimLParser.parse_cmd_import() abort + let node = s:Node(s:NODE_IMPORT) + let node.pos = self.ea.cmdpos + let node.ea = self.ea + let node.autoload = s:FALSE + let node.alias = '' + call self.reader.skip_white() + let start = self.reader.getpos() + let pos = self.reader.tell() + if self.reader.read_alpha() ==# 'autoload' && s:iswhite(self.reader.peekn(1)) + let node.autoload = s:TRUE + call self.reader.skip_white() + else + call self.reader.seek_set(pos) + endif + let node.left = self.parse_expr() + let end = self.reader.getpos() + call self.reader.skip_white() + let pos = self.reader.tell() + if self.reader.read_alpha() ==# 'as' && s:iswhite(self.reader.peekn(1)) + call self.reader.skip_white() + let node.alias = self.reader.read_word() + let self.declared[node.alias] = 1 + let end = self.reader.getpos() + else + call self.reader.seek_set(pos) + endif + " The text of the arguments. + let node.str = self.reader.getstr(start, end) + call self.add_node(node) +endfunction + +function! s:VimLParser.parse_cmd_block() abort + if !self.isvim9() + call self.parse_cmd_common() + return + endif + let node = s:Node(s:NODE_BLOCK) + let node.pos = self.ea.cmdpos + let node.ea = self.ea + let node.body = [] + let node.endblock = s:NIL call self.add_node(node) + call self.push_context(node) +endfunction + +function! s:VimLParser.parse_cmd_endblock() abort + if !self.isvim9() + call self.parse_cmd_common() + return + endif + call self.check_missing_endif('}', self.ea.cmdpos) + call self.check_missing_endtry('}', self.ea.cmdpos) + call self.check_missing_endwhile('}', self.ea.cmdpos) + call self.check_missing_endfor('}', self.ea.cmdpos) + if self.context[0].type !=# s:NODE_BLOCK + throw s:Err('E1128: } without {', self.ea.cmdpos) + endif + let node = s:Node(s:NODE_ENDBLOCK) + let node.pos = self.ea.cmdpos + let node.ea = self.ea + let self.context[0].endblock = node + call self.pop_context() endfunction function! s:VimLParser.parse_cmd_unlet() abort @@ -2254,10 +2969,21 @@ function! s:VimLParser.parse_cmd_for() abort let node.left = s:NIL let node.right = s:NIL let node.endfor = s:NIL - let lhs = self.parse_letlhs() + if self.isvim9() + let lhs = self.parse_vim9_forlhs() + else + let lhs = self.parse_letlhs() + endif let node.left = lhs.left let node.list = lhs.list let node.rest = lhs.rest + call self.declare(node.left) + if node.list isnot# s:NIL + for x in node.list + call self.declare(x) + endfor + endif + call self.declare(node.rest) call self.reader.skip_white() let epos = self.reader.getpos() if self.reader.read_alpha() !=# 'in' @@ -2268,6 +2994,35 @@ function! s:VimLParser.parse_cmd_for() abort call self.push_context(node) endfunction +" Vim9 :for loop variables with optional types: "name: type" or +" "[name: type, ...]" +function! s:VimLParser.parse_vim9_forlhs() abort + let lhs = {'left': s:NIL, 'list': s:NIL, 'rest': s:NIL} + call self.reader.skip_white() + if self.reader.peekn(1) !=# '[' + let lhs.left = self.parse_vim9_decl_name() + return lhs + endif + call self.reader.getn(1) + let lhs.list = [] + while s:TRUE + call add(lhs.list, self.parse_vim9_decl_name()) + call self.reader.skip_white() + let c = self.reader.getn(1) + if c ==# ';' + let lhs.rest = self.parse_vim9_decl_name() + call self.reader.skip_white() + let c = self.reader.getn(1) + endif + if c ==# ']' + break + elseif c !=# ',' + throw s:Err(printf('E475: Invalid argument: %s', c), self.reader.getpos()) + endif + endwhile + return lhs +endfunction + 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) @@ -2429,6 +3184,26 @@ function! s:VimLParser.parse_cmd_echoconsole() abort call self.add_node(node) endfunction +function! s:VimLParser.parse_cmd_echowindow() abort + let node = s:Node(s:NODE_ECHOWINDOW) + let node.pos = self.ea.cmdpos + let node.ea = self.ea + let node.list = self.parse_exprlist() + call self.add_node(node) +endfunction + +" :defer {func}({args}) +function! s:VimLParser.parse_cmd_defer() abort + let node = s:Node(s:NODE_DEFER) + let node.pos = self.ea.cmdpos + let node.ea = self.ea + let node.left = self.parse_expr() + if node.left.type !=# s:NODE_CALL + throw s:Err('E107: Missing parentheses', node.left.pos) + endif + call self.add_node(node) +endfunction + function! s:VimLParser.parse_cmd_execute() abort let node = s:Node(s:NODE_EXECUTE) let node.pos = self.ea.cmdpos @@ -2438,7 +3213,7 @@ function! s:VimLParser.parse_cmd_execute() abort endfunction function! s:VimLParser.parse_expr() abort - return s:ExprParser.new(self.reader).parse() + return s:ExprParser.new(self.reader, self).parse() endfunction function! s:VimLParser.parse_exprlist() abort @@ -2456,7 +3231,7 @@ function! s:VimLParser.parse_exprlist() abort endfunction function! s:VimLParser.parse_lvalue_func() abort - let p = s:LvalueParser.new(self.reader) + let p = s:LvalueParser.new(self.reader, self) 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 @@ -2466,7 +3241,7 @@ endfunction " FIXME: function! s:VimLParser.parse_lvalue() abort - let p = s:LvalueParser.new(self.reader) + let p = s:LvalueParser.new(self.reader, self) let node = p.parse() if node.type ==# s:NODE_IDENTIFIER if !s:isvarname(node.value) @@ -2481,7 +3256,7 @@ endfunction " TODO: merge with s:VimLParser.parse_lvalue() function! s:VimLParser.parse_constlvalue() abort - let p = s:LvalueParser.new(self.reader) + let p = s:LvalueParser.new(self.reader, self) let node = p.parse() if node.type ==# s:NODE_IDENTIFIER if !s:isvarname(node.value) @@ -2521,7 +3296,7 @@ endfunction " FIXME: function! s:VimLParser.parse_letlhs() abort let lhs = {'left': s:NIL, 'list': s:NIL, 'rest': s:NIL} - let tokenizer = s:ExprTokenizer.new(self.reader) + let tokenizer = s:ExprTokenizer.new(self.reader, self.isvim9()) if tokenizer.peek().type ==# s:TOKEN_SQOPEN call tokenizer.get() let lhs.list = [] @@ -2555,7 +3330,7 @@ endfunction " TODO: merge with s:VimLParser.parse_letlhs() ? function! s:VimLParser.parse_constlhs() abort let lhs = {'left': s:NIL, 'list': s:NIL, 'rest': s:NIL} - let tokenizer = s:ExprTokenizer.new(self.reader) + let tokenizer = s:ExprTokenizer.new(self.reader, self.isvim9()) if tokenizer.peek().type ==# s:TOKEN_SQOPEN call tokenizer.get() let lhs.list = [] @@ -2587,8 +3362,12 @@ function! s:VimLParser.parse_constlhs() abort endfunction function! s:VimLParser.ends_excmds(c) abort - if self.vim9script && a:c ==# '#' - return 1 + if self.isvim9() + if a:c ==# '#' + return 1 + elseif a:c ==# '"' + return 0 + endif endif return a:c ==# '' || a:c ==# '|' || a:c ==# '"' || a:c ==# '' || a:c ==# '' endfunction @@ -2660,7 +3439,7 @@ let s:VimLParser.builtin_commands = [ \ {'name': 'abbreviate', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, \ {'name': 'abclear', 'minlen': 3, 'flags': 'EXTRA|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, \ {'name': 'aboveleft', 'minlen': 3, 'flags': 'NEEDARG|EXTRA|NOTRLCOM', 'parser': 'parse_cmd_common'}, - \ {'name': 'abstract', 'minlen': 3, 'flags': 'EXTRA|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, + \ {'name': 'abstract', 'minlen': 3, 'flags': 'EXTRA|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_abstract'}, \ {'name': 'all', 'minlen': 2, 'flags': 'BANG|RANGE|COUNT|TRLBAR', 'parser': 'parse_cmd_common'}, \ {'name': 'amenu', 'minlen': 2, 'flags': 'RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, \ {'name': 'anoremenu', 'minlen': 2, 'flags': 'RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, @@ -2736,7 +3515,7 @@ let s:VimLParser.builtin_commands = [ \ {'name': 'chistory', 'minlen': 3, 'flags': 'RANGE|COUNT|TRLBAR', 'parser': 'parse_cmd_common'}, \ {'name': 'clist', 'minlen': 2, 'flags': 'BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, \ {'name': 'clast', 'minlen': 3, 'flags': 'RANGE|COUNT|TRLBAR|BANG', 'parser': 'parse_cmd_common'}, - \ {'name': 'class', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, + \ {'name': 'class', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_class'}, \ {'name': 'close', 'minlen': 3, 'flags': 'BANG|RANGE|COUNT|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, \ {'name': 'clearjumps', 'minlen': 3, 'flags': 'TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, \ {'name': 'cmap', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, @@ -2773,7 +3552,7 @@ let s:VimLParser.builtin_commands = [ \ {'name': 'debug', 'minlen': 3, 'flags': 'NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, \ {'name': 'debuggreedy', 'minlen': 6, 'flags': 'RANGE|ZEROR|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, \ {'name': 'def', 'minlen': 3, 'flags': 'EXTRA|BANG|SBOXOK|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_def'}, - \ {'name': 'defer', 'minlen': 4, 'flags': 'NEEDARG|EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, + \ {'name': 'defer', 'minlen': 4, 'flags': 'NEEDARG|EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_defer'}, \ {'name': 'defcompile', 'minlen': 4, 'flags': 'SBOXOK|CMDWIN|LOCK_OK|TRLBAR', 'parser': 'parse_cmd_common'}, \ {'name': 'delcommand', 'minlen': 4, 'flags': 'NEEDARG|WORD1|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, \ {'name': 'delfunction', 'minlen': 4, 'flags': 'BANG|NEEDARG|WORD1|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_delfunction'}, @@ -2801,22 +3580,22 @@ let s:VimLParser.builtin_commands = [ \ {'name': 'echohl', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|SBOXOK|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_echohl'}, \ {'name': 'echomsg', 'minlen': 5, 'flags': 'EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_echomsg'}, \ {'name': 'echoconsole', 'minlen': 5, 'flags': 'EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_echoconsole'}, - \ {'name': 'echowindow', 'minlen': 5, 'flags': 'EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, + \ {'name': 'echowindow', 'minlen': 5, 'flags': 'EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_echowindow'}, \ {'name': 'echon', 'minlen': 5, 'flags': 'EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_echon'}, \ {'name': 'else', 'minlen': 2, 'flags': 'TRLBAR|SBOXOK|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_else'}, \ {'name': 'elseif', 'minlen': 5, 'flags': 'EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_elseif'}, \ {'name': 'emenu', 'minlen': 2, 'flags': 'NEEDARG|EXTRA|TRLBAR|NOTRLCOM|RANGE|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, \ {'name': 'endif', 'minlen': 2, 'flags': 'TRLBAR|SBOXOK|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_endif'}, - \ {'name': 'endinterface', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, - \ {'name': 'endclass', 'minlen': 4, 'flags': 'EXTRA|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, + \ {'name': 'endinterface', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_endinterface'}, + \ {'name': 'endclass', 'minlen': 4, 'flags': 'EXTRA|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_endclass'}, \ {'name': 'enddef', 'minlen': 4, 'flags': 'TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_enddef'}, - \ {'name': 'endenum', 'minlen': 4, 'flags': 'EXTRA|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, + \ {'name': 'endenum', 'minlen': 4, 'flags': 'EXTRA|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_endenum'}, \ {'name': 'endfunction', 'minlen': 4, 'flags': 'TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_endfunction'}, \ {'name': 'endfor', 'minlen': 5, 'flags': 'TRLBAR|SBOXOK|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_endfor'}, \ {'name': 'endtry', 'minlen': 4, 'flags': 'TRLBAR|SBOXOK|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_endtry'}, \ {'name': 'endwhile', 'minlen': 4, 'flags': 'TRLBAR|SBOXOK|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_endwhile'}, \ {'name': 'enew', 'minlen': 3, 'flags': 'BANG|TRLBAR', 'parser': 'parse_cmd_common'}, - \ {'name': 'enum', 'minlen': 3, 'flags': 'EXTRA|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, + \ {'name': 'enum', 'minlen': 3, 'flags': 'EXTRA|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_enum'}, \ {'name': 'eval', 'minlen': 2, 'flags': 'EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_eval'}, \ {'name': 'ex', 'minlen': 2, 'flags': 'BANG|FILE1|CMDARG|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'}, \ {'name': 'execute', 'minlen': 3, 'flags': 'EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_execute'}, @@ -2870,7 +3649,7 @@ let s:VimLParser.builtin_commands = [ \ {'name': 'inoreabbrev', 'minlen': 6, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, \ {'name': 'inoremenu', 'minlen': 7, 'flags': 'RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, \ {'name': 'intro', 'minlen': 3, 'flags': 'TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, - \ {'name': 'interface', 'minlen': 4, 'flags': 'EXTRA|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, + \ {'name': 'interface', 'minlen': 4, 'flags': 'EXTRA|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_interface'}, \ {'name': 'isearch', 'minlen': 2, 'flags': 'BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK', '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|CTRLV|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, @@ -3022,6 +3801,7 @@ let s:VimLParser.builtin_commands = [ \ {'name': 'ptprevious', 'minlen': 3, 'flags': 'RANGE|BANG|TRLBAR|ZEROR', 'parser': 'parse_cmd_common'}, \ {'name': 'ptrewind', 'minlen': 3, 'flags': 'RANGE|BANG|TRLBAR|ZEROR', 'parser': 'parse_cmd_common'}, \ {'name': 'ptselect', 'minlen': 3, 'flags': 'BANG|TRLBAR|WORD1', 'parser': 'parse_cmd_common'}, + \ {'name': 'public', 'minlen': 3, 'flags': 'EXTRA|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_public'}, \ {'name': 'put', 'minlen': 2, 'flags': 'RANGE|WHOLEFOLD|BANG|REGSTR|TRLBAR|ZEROR|CMDWIN|LOCK_OK|MODIFY', 'parser': 'parse_cmd_common'}, \ {'name': 'pwd', 'minlen': 2, 'flags': 'TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, \ {'name': 'python', 'minlen': 2, 'flags': 'RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT', 'parser': 'parse_cmd_python'}, @@ -3114,7 +3894,7 @@ let s:VimLParser.builtin_commands = [ \ {'name': 'startinsert', 'minlen': 4, 'flags': 'BANG|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, \ {'name': 'startgreplace', 'minlen': 6, 'flags': 'BANG|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, \ {'name': 'startreplace', 'minlen': 6, 'flags': 'BANG|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, - \ {'name': 'static', 'minlen': 4, 'flags': 'EXTRA|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, + \ {'name': 'static', 'minlen': 4, 'flags': 'EXTRA|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_static'}, \ {'name': 'stopinsert', 'minlen': 5, 'flags': 'BANG|TRLBAR|CMDWIN|LOCK_OK', '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'}, @@ -3173,7 +3953,7 @@ let s:VimLParser.builtin_commands = [ \ {'name': 'tselect', 'minlen': 2, 'flags': 'BANG|TRLBAR|WORD1', 'parser': 'parse_cmd_common'}, \ {'name': 'tunmenu', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, \ {'name': 'tunmap', 'minlen': 5, 'flags': 'EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, - \ {'name': 'type', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, + \ {'name': 'type', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_type'}, \ {'name': 'undo', 'minlen': 1, 'flags': 'RANGE|COUNT|ZEROR|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, \ {'name': 'undojoin', 'minlen': 5, 'flags': 'TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, \ {'name': 'undolist', 'minlen': 5, 'flags': 'TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, @@ -3240,14 +4020,21 @@ let s:VimLParser.builtin_commands = [ \ {'name': '=', 'minlen': 1, 'flags': 'RANGE|TRLBAR|DFLALL|FLAGS|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, \ {'name': '>', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK|MODIFY', 'parser': 'parse_cmd_common'}, \ {'name': '@', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|LOCK_OK|NONWHITE_OK', 'parser': 'parse_cmd_common'}, - \ {'name': '{', 'minlen': 1, 'flags': 'TRLBAR|LOCK_OK|CMDWIN', 'parser': 'parse_cmd_common'}, - \ {'name': '}', 'minlen': 1, 'flags': 'TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, + \ {'name': '{', 'minlen': 1, 'flags': 'TRLBAR|LOCK_OK|CMDWIN', 'parser': 'parse_cmd_block'}, + \ {'name': '}', 'minlen': 1, 'flags': 'TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_endblock'}, \ {'name': '~', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|MODIFY|NONWHITE_OK', 'parser': 'parse_cmd_common'}, \ {'name': 'Next', 'minlen': 1, 'flags': 'EXTRA|RANGE|COUNT|BANG|CMDARG|ARGOPT|TRLBAR', 'parser': 'parse_cmd_common'}, \ {'name': 'Print', 'minlen': 1, 'flags': 'RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, \ {'name': 'X', 'minlen': 1, 'flags': 'TRLBAR', 'parser': 'parse_cmd_common'}, \ {'name': '++', 'minlen': 1, 'flags': 'EXTRA|TRLBAR|SBOXOK|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, \ {'name': '--', 'minlen': 1, 'flags': 'EXTRA|TRLBAR|SBOXOK|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, + \ {'name': 'clipreset', 'minlen': 4, 'flags': 'TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, + \ {'name': 'iput', 'minlen': 2, 'flags': 'RANGE|WHOLEFOLD|BANG|REGSTR|TRLBAR|ZEROR|CMDWIN|LOCK_OK|MODIFY', 'parser': 'parse_cmd_common'}, + \ {'name': 'pbuffer', 'minlen': 2, 'flags': 'BANG|RANGE|BUFNAME|BUFUNL|COUNT|EXTRA|CMDARG|TRLBAR', 'parser': 'parse_cmd_common'}, + \ {'name': 'redrawtabpanel', 'minlen': 10, 'flags': 'TRLBAR|CMDWIN|LOCK_OK', 'parser': 'parse_cmd_common'}, + \ {'name': 'this', 'minlen': 3, 'flags': 'EXTRA|NEEDARG|SBOXOK|CMDWIN|LOCK_OK|WHOLE', 'parser': 'parse_cmd_common'}, + \ {'name': 'uniq', 'minlen': 3, 'flags': 'RANGE|DFLALL|WHOLEFOLD|BANG|EXTRA|NOTRLCOM|MODIFY', 'parser': 'parse_cmd_common'}, + \ {'name': 'wlrestore', 'minlen': 2, 'flags': 'EXTRA|TRLBAR|CMDWIN|LOCK_OK|BANG', 'parser': 'parse_cmd_common'}, \] " To find new builtin_functions, run the below script. @@ -3812,9 +4599,16 @@ function! s:ExprTokenizer.new(...) abort return obj endfunction -function! s:ExprTokenizer.__init__(reader) abort +function! s:ExprTokenizer.__init__(reader, ...) abort let self.reader = a:reader let self.cache = {} + let self.vim9 = s:FALSE + if len(a:000) > 0 + let self.vim9 = a:000[0] + endif + " Nesting level of brackets, inside which a Vim9 expression may continue + " on the next line. + let self.depth = 0 endfunction function! s:ExprTokenizer.token(type, value, pos) abort @@ -3829,6 +4623,9 @@ function! s:ExprTokenizer.peek() abort endfunction function! s:ExprTokenizer.get() abort + if self.vim9 + call self.skip_vim9_newline(s:FALSE) + endif " FIXME: remove dirty hack if has_key(self.cache, self.reader.tell()) let x = self.cache[self.reader.tell()] @@ -3842,6 +4639,77 @@ function! s:ExprTokenizer.get() abort return r endfunction +" In Vim9 script an expression continues on the next line inside brackets, +" after an operator (a:force), and before an operator that starts the next +" line. Comments and empty lines in between are skipped. +function! s:ExprTokenizer.skip_vim9_newline(force_newline) abort + let r = self.reader + let force = a:force_newline + while s:TRUE + let pos = r.tell() + call r.skip_white() + if r.peek() ==# '#' && r.tell() > 0 && (s:iswhite(r.p(-1)) || r.p(-1) ==# '') + call r.getn(-1) + endif + if r.peek() !=# '' || !(force || self.depth > 0 || self.next_line_continues()) || self.next_line_is_enddef() + call r.seek_set(pos) + return + endif + call r.get() + let force = s:TRUE + endwhile +endfunction + +" :enddef cannot be used at the start of a continuation line. +function! s:ExprTokenizer.next_line_is_enddef() abort + let r = self.reader + let pos = r.tell() + call r.get() + call r.skip_white() + let result = r.read_alpha() ==# 'enddef' && !s:iswordc(r.peekn(1)) + call r.seek_set(pos) + return result +endfunction + +" Return TRUE when the next line, ignoring comments and empty lines, starts +" with an operator that continues the expression. +function! s:ExprTokenizer.next_line_continues() abort + let r = self.reader + let pos = r.tell() + while r.peek() ==# '' + call r.get() + call r.skip_white() + if r.peek() ==# '#' + call r.getn(-1) + endif + endwhile + let c = r.peek() + let continues = s:FALSE + if c ==# '-' && r.p(1) ==# '>' + let continues = s:TRUE + elseif c ==# '.' && s:iswordc1(r.p(1)) + let continues = s:TRUE + elseif c ==# 'i' && r.p(1) ==# 's' + let op = r.read_alpha() + if op ==# 'is' || op ==# 'isnot' + if r.peek() ==# '?' || r.peek() ==# '#' + call r.get() + endif + let continues = s:iswhite(r.peek()) || r.peek() ==# '' + endif + elseif c !=# '' && stridx('+-*/%.|&?:=!<>', c) !=# -1 + let op = '' + while r.peek() !=# '' && stridx('+-*/%.|&?:=!<>~#', r.peek()) !=# -1 + let op .= r.get() + endwhile + if has_key(s:VIM9_CONTINUATION_OPS, op) + let continues = s:iswhite(r.peek()) || r.peek() ==# '' + endif + endif + call r.seek_set(pos) + return continues +endfunction + function! s:ExprTokenizer.get2() abort let r = self.reader let pos = r.getpos() @@ -3862,12 +4730,20 @@ function! s:ExprTokenizer.get2() abort let s = r.getn(3) let s .= r.read_bdigit() return self.token(s:TOKEN_NUMBER, s, pos) + elseif c ==# '0' && (r.p(1) ==# 'O' || r.p(1) ==# 'o') && s:isodigit(r.p(2)) + let s = r.getn(3) + let s .= r.read_odigit() + return self.token(s:TOKEN_NUMBER, s, pos) elseif c ==# '0' && (r.p(1) ==# 'Z' || r.p(1) ==# 'z') && r.p(2) !=# '.' let s = r.getn(2) let s .= r.read_blob() return self.token(s:TOKEN_BLOB, s, pos) elseif s:isdigit(c) let s = r.read_digit() + " Vim9 script allows a single quote between digits: 1'000'000 + while self.vim9 && r.p(0) ==# "'" && s:isdigit(r.p(1)) + let s .= r.getn(1) . r.read_digit() + endwhile if r.p(0) ==# '.' && s:isdigit(r.p(1)) let s .= r.getn(1) let s .= r.read_digit() @@ -3900,7 +4776,11 @@ function! s:ExprTokenizer.get2() abort return self.token(s:TOKEN_ISNOT, 'isnot', pos) endif elseif s:isnamec1(c) - let s = r.read_name() + if self.vim9 + let s = r.read_vim9_name() + else + let s = r.read_name() + endif return self.token(s:TOKEN_IDENTIFIER, s, pos) elseif c ==# '|' && r.p(1) ==# '|' call r.seek_cur(2) @@ -3908,6 +4788,9 @@ function! s:ExprTokenizer.get2() abort elseif c ==# '&' && r.p(1) ==# '&' call r.seek_cur(2) return self.token(s:TOKEN_ANDAND, '&&', pos) + elseif c ==# '=' && r.p(1) ==# '>' && self.vim9 + call r.seek_cur(2) + return self.token(s:TOKEN_FATARROW, '=>', pos) elseif c ==# '=' && r.p(1) ==# '=' if r.p(2) ==# '?' call r.seek_cur(3) @@ -4036,6 +4919,9 @@ function! s:ExprTokenizer.get2() abort elseif c ==# '!' call r.seek_cur(1) return self.token(s:TOKEN_NOT, '!', pos) + elseif c ==# '?' && r.p(1) ==# '?' + call r.seek_cur(2) + return self.token(s:TOKEN_QUESTIONQUESTION, '??', pos) elseif c ==# '?' call r.seek_cur(1) return self.token(s:TOKEN_QUESTION, '?', pos) @@ -4043,7 +4929,7 @@ function! s:ExprTokenizer.get2() abort call r.seek_cur(1) return self.token(s:TOKEN_COLON, ':', pos) elseif c ==# '#' - if r.p(1) ==# '{' + if r.p(1) ==# '{' && !self.vim9 call r.seek_cur(2) return self.token(s:TOKEN_LITCOPEN, '#{', pos) else @@ -4202,9 +5088,16 @@ function! s:ExprParser.new(...) abort return obj endfunction -function! s:ExprParser.__init__(reader) abort +function! s:ExprParser.__init__(reader, ...) abort let self.reader = a:reader - let self.tokenizer = s:ExprTokenizer.new(a:reader) + " The VimLParser using this parser, if any. + let self.parser = s:NIL + let self.vim9 = s:FALSE + if len(a:000) > 0 + let self.parser = a:000[0] + let self.vim9 = self.parser.isvim9() + endif + let self.tokenizer = s:ExprTokenizer.new(a:reader, self.vim9) endfunction function! s:ExprParser.parse() abort @@ -4212,11 +5105,18 @@ function! s:ExprParser.parse() abort endfunction " expr1: expr2 ? expr1 : expr1 +" expr2 ?? expr1 function! s:ExprParser.parse_expr1() abort let left = self.parse_expr2() let pos = self.reader.tell() let token = self.tokenizer.get() - if token.type ==# s:TOKEN_QUESTION + if token.type ==# s:TOKEN_QUESTIONQUESTION + let node = s:Node(s:NODE_FALSY) + let node.pos = token.pos + let node.left = left + let node.right = self.parse_expr1() + let left = node + elseif token.type ==# s:TOKEN_QUESTION let node = s:Node(s:NODE_TERNARY) let node.pos = token.pos let node.cond = left @@ -4505,7 +5405,7 @@ function! s:ExprParser.parse_expr5() abort let node.left = left let node.right = self.parse_expr5_5() let left = node - elseif token.type ==# s:TOKEN_DOT " TODO check scriptversion? + elseif token.type ==# s:TOKEN_DOT && !self.vim9 " TODO check scriptversion? let node = s:Node(s:NODE_CONCAT) let node.pos = token.pos let node.left = left @@ -4584,6 +5484,9 @@ endfunction " - expr7 " + expr7 function! s:ExprParser.parse_expr7() abort + if self.vim9 + call self.tokenizer.skip_vim9_newline(s:TRUE) + endif let pos = self.reader.tell() let token = self.tokenizer.get() if token.type ==# s:TOKEN_NOT @@ -4601,6 +5504,17 @@ function! s:ExprParser.parse_expr7() abort let node.pos = token.pos let node.left = self.parse_expr7() return node + elseif token.type ==# s:TOKEN_LT && self.vim9 && self.reader.peekn(4) !=? 'SID>' + " Vim9 type cast: expr + let node = s:Node(s:NODE_CAST) + let node.pos = token.pos + let node.type_str = self.parser.read_type() + let token = self.tokenizer.get() + if token.type !=# s:TOKEN_GT + throw s:Err(printf('unexpected token: %s', token.value), token.pos) + endif + let node.left = self.parse_expr7() + return node else call self.reader.seek_set(pos) let node = self.parse_expr8() @@ -4621,8 +5535,34 @@ function! s:ExprParser.parse_expr8() abort let pos = self.reader.tell() let c = self.reader.peek() let token = self.tokenizer.get() - if !s:iswhite(c) && token.type ==# s:TOKEN_SQOPEN + " In Vim9 script no white space or line break is allowed before "[" and + " "(", a member "." may start a continuation line. + let attached = !s:iswhite(c) && !(self.vim9 && c ==# '') + if self.vim9 && c ==# '<' && self.parser.is_generic_args() + " Vim9 generic function call: Func(args) + call self.reader.seek_set(pos) + let type_args = self.reader.getn(1) + let depth = 1 + while depth > 0 + let c = self.reader.getn(1) + if c ==# '<' + let depth += 1 + elseif c ==# '>' + let depth -= 1 + endif + let type_args .= c + endwhile + let token = self.tokenizer.get() + let node = s:Node(s:NODE_CALL) + let node.pos = token.pos + let node.left = left + let node.type_args = type_args + let node.rlist = self.parse_rlist() + let left = node + unlet node + elseif attached && token.type ==# s:TOKEN_SQOPEN let npos = token.pos + let self.tokenizer.depth += 1 if self.tokenizer.peek().type ==# s:TOKEN_COLON call self.tokenizer.get() let node = s:Node(s:NODE_SLICE) @@ -4634,6 +5574,7 @@ function! s:ExprParser.parse_expr8() abort let node.rlist[1] = self.parse_expr1() endif let token = self.tokenizer.get() + let self.tokenizer.depth -= 1 if token.type !=# s:TOKEN_SQCLOSE throw s:Err(printf('unexpected token: %s', token.value), token.pos) endif @@ -4651,6 +5592,7 @@ function! s:ExprParser.parse_expr8() abort let node.rlist[1] = self.parse_expr1() endif let token = self.tokenizer.get() + let self.tokenizer.depth -= 1 if token.type !=# s:TOKEN_SQCLOSE throw s:Err(printf('unexpected token: %s', token.value), token.pos) endif @@ -4661,6 +5603,7 @@ function! s:ExprParser.parse_expr8() abort let node.left = left let node.right = right let token = self.tokenizer.get() + let self.tokenizer.depth -= 1 if token.type !=# s:TOKEN_SQCLOSE throw s:Err(printf('unexpected token: %s', token.value), token.pos) endif @@ -4684,14 +5627,14 @@ function! s:ExprParser.parse_expr8() abort let node.right = right let left = node unlet node - elseif token.type ==# s:TOKEN_POPEN + elseif token.type ==# s:TOKEN_POPEN && (attached || !self.vim9) let node = s:Node(s:NODE_CALL) let node.pos = token.pos let node.left = left let node.rlist = self.parse_rlist() let left = node unlet node - elseif !s:iswhite(c) && token.type ==# s:TOKEN_DOT " TODO check scriptversion? + elseif (attached || (self.vim9 && c ==# '')) && token.type ==# s:TOKEN_DOT " TODO check scriptversion? let node = self.parse_dot(token, left) if node is# s:NIL call self.reader.seek_set(pos) @@ -4709,9 +5652,11 @@ endfunction function! s:ExprParser.parse_rlist() abort let rlist = [] + let self.tokenizer.depth += 1 let token = self.tokenizer.peek() if self.tokenizer.peek().type ==# s:TOKEN_PCLOSE call self.tokenizer.get() + let self.tokenizer.depth -= 1 else while s:TRUE call add(rlist, self.parse_expr1()) @@ -4720,9 +5665,11 @@ function! s:ExprParser.parse_rlist() abort " XXX: Vim allows foo(a, b, ). Lint should warn it. if self.tokenizer.peek().type ==# s:TOKEN_PCLOSE call self.tokenizer.get() + let self.tokenizer.depth -= 1 break endif elseif token.type ==# s:TOKEN_PCLOSE + let self.tokenizer.depth -= 1 break else throw s:Err(printf('unexpected token: %s', token.value), token.pos) @@ -4777,6 +5724,7 @@ function! s:ExprParser.parse_expr9() abort let node = s:Node(s:NODE_LIST) let node.pos = token.pos let node.value = [] + let self.tokenizer.depth += 1 let token = self.tokenizer.peek() if token.type ==# s:TOKEN_SQCLOSE call self.tokenizer.get() @@ -4798,6 +5746,9 @@ function! s:ExprParser.parse_expr9() abort endif endwhile endif + let self.tokenizer.depth -= 1 + elseif token.type ==# s:TOKEN_COPEN && self.vim9 + let node = self.parse_vim9_dict(token) elseif token.type ==# s:TOKEN_COPEN || token.type ==# s:TOKEN_LITCOPEN let is_litdict = token.type ==# s:TOKEN_LITCOPEN let savepos = self.reader.tell() @@ -4915,9 +5866,13 @@ function! s:ExprParser.parse_expr9() abort endif endwhile return node + elseif token.type ==# s:TOKEN_POPEN && self.vim9 + let node = self.parse_vim9_paren(token) elseif token.type ==# s:TOKEN_POPEN + let self.tokenizer.depth += 1 let node = self.parse_expr1() let token = self.tokenizer.get() + let self.tokenizer.depth -= 1 if token.type !=# s:TOKEN_PCLOSE throw s:Err(printf('unexpected token: %s', token.value), token.pos) endif @@ -4938,6 +5893,8 @@ function! s:ExprParser.parse_expr9() abort elseif token.type ==# s:TOKEN_IS || token.type ==# s:TOKEN_ISCS || token.type ==# s:TOKEN_ISNOT || token.type ==# s:TOKEN_ISNOTCS call self.reader.seek_set(pos) let node = self.parse_identifier() + elseif token.type ==# s:TOKEN_ENV && token.value ==# '$' && (self.reader.p(0) ==# '"' || self.reader.p(0) ==# "'") + let node = self.parse_interpolation(token) elseif token.type ==# s:TOKEN_ENV let node = s:Node(s:NODE_ENV) let node.pos = token.pos @@ -4952,11 +5909,252 @@ function! s:ExprParser.parse_expr9() abort return node endfunction +" Interpolated string: $"text {expr1} text" or $'text {expr1} text' +" .value is a list of NODE_STRING parts, in the quotes of the string, and +" expressions. +function! s:ExprParser.parse_interpolation(token) abort + let r = self.reader + let node = s:Node(s:NODE_INTERPOLATION) + let node.pos = a:token.pos + let node.value = [] + let quote = r.get() + let str = '' + let strpos = r.getpos() + while s:TRUE + let c = r.p(0) + if c ==# '' || c ==# '' + throw s:Err('unexpected EOL', r.getpos()) + elseif c ==# quote && quote ==# "'" && r.p(1) ==# "'" + let str .= r.getn(2) + elseif c ==# quote + call r.seek_cur(1) + break + elseif c ==# '\' && quote ==# '"' + let str .= r.getn(2) + elseif (c ==# '{' && r.p(1) ==# '{') || (c ==# '}' && r.p(1) ==# '}') + let str .= r.getn(2) + elseif c ==# '{' + if str !=# '' + let part = s:Node(s:NODE_STRING) + let part.pos = strpos + let part.value = quote . str . quote + call add(node.value, part) + let str = '' + endif + call r.seek_cur(1) + call add(node.value, self.parse_expr1()) + call r.skip_white() + if r.p(0) !=# '}' + throw s:Err(printf('unexpected token: %s', r.p(0)), r.getpos()) + endif + call r.seek_cur(1) + let strpos = r.getpos() + else + let str .= r.getn(1) + endif + endwhile + if str !=# '' + let part = s:Node(s:NODE_STRING) + let part.pos = strpos + let part.value = quote . str . quote + call add(node.value, part) + endif + return node +endfunction + +" Vim9 lambda, tuple or expression in parentheses, after the "(": +" (args) => expr1 +" (args): type => { +" () (expr1,) (expr1, expr1, ...) +" (expr1) +function! s:ExprParser.parse_vim9_paren(popen) abort + if self.is_vim9_lambda() + return self.parse_vim9_lambda(a:popen) + endif + let self.tokenizer.depth += 1 + let token = self.tokenizer.peek() + if token.type ==# s:TOKEN_PCLOSE + call self.tokenizer.get() + let self.tokenizer.depth -= 1 + let node = s:Node(s:NODE_TUPLE) + let node.pos = a:popen.pos + let node.value = [] + return node + endif + let node = self.parse_expr1() + let token = self.tokenizer.get() + if token.type ==# s:TOKEN_COMMA + let tuple = s:Node(s:NODE_TUPLE) + let tuple.pos = a:popen.pos + let tuple.value = [node] + while self.tokenizer.peek().type !=# s:TOKEN_PCLOSE + call add(tuple.value, self.parse_expr1()) + let token = self.tokenizer.peek() + if token.type ==# s:TOKEN_COMMA + call self.tokenizer.get() + elseif token.type !=# s:TOKEN_PCLOSE + throw s:Err(printf('unexpected token: %s', token.value), token.pos) + endif + endwhile + let token = self.tokenizer.get() + let node = tuple + endif + let self.tokenizer.depth -= 1 + if token.type !=# s:TOKEN_PCLOSE + throw s:Err(printf('unexpected token: %s', token.value), token.pos) + endif + return node +endfunction + +" Return TRUE when the text after "(" is the argument list of a Vim9 lambda, +" i.e. names with optional types, ")", an optional return type and "=>". +function! s:ExprParser.is_vim9_lambda() abort + let r = self.reader + let pos = r.tell() + let result = s:FALSE + while s:TRUE + call r.skip_white() + if r.peekn(1) ==# ')' + break + endif + if r.peekn(3) ==# '...' + call r.getn(3) + endif + if r.read_word() ==# '' + call r.seek_set(pos) + return s:FALSE + endif + if r.peekn(1) ==# ':' + call r.getn(1) + call r.skip_white() + call self.parser.read_type() + endif + call r.skip_white() + if r.peekn(1) ==# ',' + call r.getn(1) + elseif r.peekn(1) !=# ')' + call r.seek_set(pos) + return s:FALSE + endif + endwhile + call r.getn(1) + if r.peekn(1) ==# ':' + call r.getn(1) + call r.skip_white() + call self.parser.read_type() + endif + call r.skip_white() + let result = r.peekn(2) ==# '=>' + call r.seek_set(pos) + return result +endfunction + +function! s:ExprParser.parse_vim9_lambda(token) abort + let r = self.reader + let node = s:Node(s:NODE_LAMBDA) + let node.pos = a:token.pos + let node.rlist = [] + let node.left = s:NIL + let node.body = [] + let node.rettype = '' + while s:TRUE + call r.skip_white() + if r.peekn(1) ==# ')' + call r.getn(1) + break + endif + let varnode = s:Node(s:NODE_IDENTIFIER) + let varnode.pos = r.getpos() + let varnode.value = '' + let varnode.type_str = '' + if r.peekn(3) ==# '...' + let varnode.value = r.getn(3) + endif + let name = r.read_word() + let varnode.value .= name + let self.parser.declared[name] = 1 + if r.peekn(1) ==# ':' + call r.getn(1) + call r.skip_white() + let varnode.type_str = self.parser.read_type() + endif + call add(node.rlist, varnode) + call r.skip_white() + if r.peekn(1) ==# ',' + call r.getn(1) + endif + endwhile + if r.peekn(1) ==# ':' + call r.getn(1) + call r.skip_white() + let node.rettype = self.parser.read_type() + endif + call r.skip_white() + call r.getn(2) + call r.skip_white() + let pos = r.tell() + if r.peekn(1) ==# '{' + call r.getn(1) + call r.skip_white() + if r.peek() ==# '' || r.peek() ==# '#' + call self.parser.parse_lambda_block(node) + return node + endif + call r.seek_set(pos) + endif + let node.left = self.parse_expr1() + return node +endfunction + +" Vim9 dictionary: {key: expr1, "key": expr1, [expr1]: expr1, ...} +" A key made of word characters and "-" is a literal string. +function! s:ExprParser.parse_vim9_dict(copen) abort + let node = s:Node(s:NODE_DICT) + let node.pos = a:copen.pos + let node.value = [] + let self.tokenizer.depth += 1 + while s:TRUE + let token = self.tokenizer.peek() + if token.type ==# s:TOKEN_CCLOSE + call self.tokenizer.get() + break + endif + if token.type ==# s:TOKEN_SQOPEN + call self.tokenizer.get() + let key = self.parse_expr1() + let token = self.tokenizer.get() + if token.type !=# s:TOKEN_SQCLOSE + throw s:Err(printf('unexpected token: %s', token.value), token.pos) + endif + elseif token.type ==# s:TOKEN_SQUOTE || token.type ==# s:TOKEN_DQUOTE + let key = self.parse_expr1() + else + call self.tokenizer.skip_vim9_newline(s:FALSE) + let key = self.tokenizer.parse_dict_literal_key() + endif + let token = self.tokenizer.get() + if token.type !=# s:TOKEN_COLON + throw s:Err(printf('unexpected token: %s', token.value), token.pos) + endif + let val = self.parse_expr1() + call add(node.value, [key, val]) + let token = self.tokenizer.get() + if token.type ==# s:TOKEN_CCLOSE + break + elseif token.type !=# s:TOKEN_COMMA + throw s:Err(printf('unexpected token: %s', token.value), token.pos) + endif + endwhile + let self.tokenizer.depth -= 1 + return node +endfunction + " SUBSCRIPT or CONCAT " dict "." [0-9A-Za-z_]+ => (subscript dict key) " str "." expr6 => (concat str expr6) +" In Vim9 script "." is always a member access. function! s:ExprParser.parse_dot(token, left) abort - if a:left.type !=# s:NODE_IDENTIFIER && a:left.type !=# s:NODE_CURLYNAME && a:left.type !=# s:NODE_DICT && a:left.type !=# s:NODE_SUBSCRIPT && a:left.type !=# s:NODE_CALL && a:left.type !=# s:NODE_DOT + if !self.vim9 && a:left.type !=# s:NODE_IDENTIFIER && a:left.type !=# s:NODE_CURLYNAME && a:left.type !=# s:NODE_DICT && a:left.type !=# s:NODE_SUBSCRIPT && a:left.type !=# s:NODE_CALL && a:left.type !=# s:NODE_DOT return s:NIL endif if !s:iswordc(self.reader.p(0)) @@ -4964,7 +6162,7 @@ function! s:ExprParser.parse_dot(token, left) abort endif let pos = self.reader.getpos() let name = self.reader.read_word() - if s:isnamec(self.reader.p(0)) + if !self.vim9 && s:isnamec(self.reader.p(0)) " XXX: foo is str => ok, foo is obj => invalid expression " foo.s:bar or foo.bar#baz return s:NIL @@ -5006,6 +6204,17 @@ endfunction function! s:ExprParser.parse_identifier() abort call self.reader.skip_white() let npos = self.reader.getpos() + if self.vim9 + " Vim9 script has no curly-braces names. + let node = s:Node(s:NODE_IDENTIFIER) + let node.pos = npos + if self.reader.peekn(5) ==? '' + let node.value = self.reader.getn(5) . self.reader.read_vim9_name() + else + let node.value = self.reader.read_vim9_name() + endif + return node + endif let curly_parts = self.parse_curly_parts() if len(curly_parts) ==# 1 && curly_parts[0].type ==# s:NODE_CURLYNAMEPART let node = s:Node(s:NODE_IDENTIFIER) @@ -5198,7 +6407,19 @@ function! s:StringReader.__init__(lines) abort let col += len(c) let offset += len(c) endfor - while lnum + 1 < len(a:lines) && a:lines[lnum + 1] =~# '^\s*\\' + while s:TRUE + " Comment lines "\ and #\ may appear between continuation lines. + let next = lnum + 1 + while next < len(a:lines) && a:lines[next] =~# '^\s*["#]\\ ' + let next += 1 + endwhile + if next >= len(a:lines) || a:lines[next] !~# '^\s*\\' + break + endif + while lnum + 1 < next + let offset += len(a:lines[lnum + 1]) + 1 + let lnum += 1 + endwhile let skip = s:TRUE let col = 0 for c in split(a:lines[lnum + 1], '\zs') @@ -5432,6 +6653,20 @@ function! s:StringReader.read_name() abort return r endfunction +" Read a Vim9 variable or function name. Unlike read_name() a colon is only +" part of the name after a one letter scope, e.g. "g:name". +function! s:StringReader.read_vim9_name() abort + let r = '' + let c = self.peekn(1) + if c !=# '' && stridx('bgltsvw', c) !=# -1 && self.p(1) ==# ':' && !s:iswhite(self.p(2)) + let r = self.getn(2) + endif + while s:iswordc(self.peekn(1)) || self.peekn(1) ==# '#' + let r .= self.getn(1) + endwhile + return r +endfunction + function! s:StringReader.skip_white() abort while s:iswhite(self.peekn(1)) call self.seek_cur(1) @@ -5706,6 +6941,47 @@ function! s:Compiler.compile(node) abort elseif a:node.type ==# s:NODE_VIM9SCRIPT call self.compile_vim9script(a:node) return s:NIL + elseif a:node.type ==# s:NODE_ASSIGN + call self.compile_assign(a:node) + return s:NIL + elseif a:node.type ==# s:NODE_BLOCK + call self.compile_block(a:node) + return s:NIL + elseif a:node.type ==# s:NODE_CLASS + call self.compile_class(a:node) + return s:NIL + elseif a:node.type ==# s:NODE_INTERFACE + call self.compile_interface(a:node) + return s:NIL + elseif a:node.type ==# s:NODE_ENUM + call self.compile_enum(a:node) + return s:NIL + elseif a:node.type ==# s:NODE_TYPE + call self.compile_type(a:node) + return s:NIL + elseif a:node.type ==# s:NODE_PUBLIC + call self.compile_wrapper(a:node, 'public') + return s:NIL + elseif a:node.type ==# s:NODE_STATIC + call self.compile_wrapper(a:node, 'static') + return s:NIL + elseif a:node.type ==# s:NODE_ABSTRACT + call self.compile_wrapper(a:node, 'abstract') + return s:NIL + elseif a:node.type ==# s:NODE_DEFER + call self.compile_defer(a:node) + return s:NIL + elseif a:node.type ==# s:NODE_ECHOWINDOW + call self.compile_echowindow(a:node) + return s:NIL + elseif a:node.type ==# s:NODE_TUPLE + return self.compile_tuple(a:node) + elseif a:node.type ==# s:NODE_FALSY + return self.compile_falsy(a:node) + elseif a:node.type ==# s:NODE_INTERPOLATION + return self.compile_interpolation(a:node) + elseif a:node.type ==# s:NODE_CAST + return self.compile_cast(a:node) else throw printf('Compiler: unknown node: %s', string(a:node)) endif @@ -5728,7 +7004,15 @@ function! s:Compiler.compile_comment(node) abort endfunction function! s:Compiler.compile_excmd(node) abort - call self.out('(excmd "%s")', escape(a:node.str, '\"')) + if !has_key(a:node, 'block') + call self.out('(excmd "%s")', escape(a:node.str, '\"')) + return + endif + call self.out('(excmd "%s"', escape(a:node.str, '\"')) + call self.incindent(' ') + call self.compile_body(a:node.block.body) + call self.out(')') + call self.decindent() endfunction function! s:Compiler.compile_function(node) abort @@ -5794,8 +7078,15 @@ function! s:Compiler.compile_let(node) abort call self.out('(let %s %s %s)', a:node.op, left, right) endfunction -" TODO: merge with s:Compiler.compile_let() ? -function! s:Compiler.compile_const(node) abort +function! s:Compiler.compile_block(node) abort + call self.out('(block') + call self.incindent(' ') + call self.compile_body(a:node.body) + call self.out(')') + call self.decindent() +endfunction + +function! s:Compiler.compile_assign(node) abort let left = '' if a:node.left isnot# s:NIL let left = self.compile(a:node.left) @@ -5806,8 +7097,16 @@ function! s:Compiler.compile_const(node) abort endif let left = '(' . left . ')' endif - let right = self.compile(a:node.right) - call self.out('(const %s %s %s)', a:node.op, left, right) + if a:node.right is# s:NIL + call self.out('(assign %s %s)', a:node.op, left) + else + call self.out('(assign %s %s %s)', a:node.op, left, self.compile(a:node.right)) + endif +endfunction + +" TODO: merge with s:Compiler.compile_let() ? +function! s:Compiler.compile_const(node) abort + call self.compile_decl(a:node, 'const') endfunction function! s:Compiler.compile_unlet(node) abort @@ -5866,11 +7165,11 @@ endfunction function! s:Compiler.compile_for(node) abort let left = '' if a:node.left isnot# s:NIL - let left = self.compile(a:node.left) + let left = self.compile_decl_name(a:node.left) else - let left = join(map(a:node.list, 'self.compile(v:val)'), ' ') + let left = join(map(a:node.list, 'self.compile_decl_name(v:val)'), ' ') if a:node.rest isnot# s:NIL - let left .= ' . ' . self.compile(a:node.rest) + let left .= ' . ' . self.compile_decl_name(a:node.rest) endif let left = '(' . left . ')' endif @@ -5950,6 +7249,15 @@ function! s:Compiler.compile_echoconsole(node) abort call self.out('(echoconsole %s)', join(list, ' ')) endfunction +function! s:Compiler.compile_echowindow(node) abort + let list = map(a:node.list, 'self.compile(v:val)') + call self.out('(echowindow %s)', join(list, ' ')) +endfunction + +function! s:Compiler.compile_defer(node) abort + call self.out('(defer %s)', self.compile(a:node.left)) +endfunction + function! s:Compiler.compile_execute(node) abort let list = map(a:node.list, 'self.compile(v:val)') call self.out('(execute %s)', join(list, ' ')) @@ -6151,10 +7459,14 @@ endfunction function! s:Compiler.compile_call(node) abort let rlist = map(a:node.rlist, 'self.compile(v:val)') + let left = self.compile(a:node.left) + if has_key(a:node, 'type_args') + let left .= a:node.type_args + endif if empty(rlist) - return printf('(%s)', self.compile(a:node.left)) + return printf('(%s)', left) else - return printf('(%s %s)', self.compile(a:node.left), join(rlist, ' ')) + return printf('(%s %s)', left, join(rlist, ' ')) endif endfunction @@ -6233,7 +7545,49 @@ endfunction function! s:Compiler.compile_lambda(node) abort let rlist = map(a:node.rlist, 'self.compile(v:val)') - return printf('(lambda (%s) %s)', join(rlist, ' '), self.compile(a:node.left)) + if a:node.left isnot# s:NIL + return printf('(lambda (%s) %s)', join(rlist, ' '), self.compile(a:node.left)) + endif + " Vim9 lambda with a block: put the statements on one line. + let compiler = s:Compiler.new() + call compiler.compile_body(a:node.body) + let body = [] + for line in compiler.lines + let text = '' + for c in split(line, '\zs') + if text !=# '' || c !=# ' ' + let text .= c + endif + endfor + call add(body, text) + endfor + return printf('(lambda (%s) %s)', join(rlist, ' '), join(body, ' ')) +endfunction + +function! s:Compiler.compile_falsy(node) abort + return printf('(?? %s %s)', self.compile(a:node.left), self.compile(a:node.right)) +endfunction + +function! s:Compiler.compile_interpolation(node) abort + let value = map(a:node.value, 'self.compile(v:val)') + if empty(value) + return '(interpolation)' + else + return printf('(interpolation %s)', join(value, ' ')) + endif +endfunction + +function! s:Compiler.compile_tuple(node) abort + let value = map(a:node.value, 'self.compile(v:val)') + if empty(value) + return '(tuple)' + else + return printf('(tuple %s)', join(value, ' ')) + endif +endfunction + +function! s:Compiler.compile_cast(node) abort + return printf('(cast <%s> %s)', a:node.type_str, self.compile(a:node.left)) endfunction function! s:Compiler.compile_heredoc(node) abort @@ -6252,11 +7606,15 @@ function! s:Compiler.compile_heredoc(node) abort endfunction function! s:Compiler.compile_vim9script(node) abort - call self.out('(vim9script)') + if a:node.noclear + call self.out('(vim9script noclear)') + else + call self.out('(vim9script)') + endif endfunction function! s:Compiler.compile_def(node) abort - let left = self.compile(a:node.left) + let left = self.compile(a:node.left) . a:node.attr.type_params let rlist = map(a:node.rlist, 'self.compile(v:val)') let default_args = map(a:node.default_args, 'self.compile(v:val)') if !empty(rlist) @@ -6289,51 +7647,112 @@ function! s:Compiler.compile_def(node) abort endfunction function! s:Compiler.compile_var(node) abort - let left = '' - if a:node.left isnot# s:NIL - let left = self.compile(a:node.left) - else - let left = join(map(a:node.list, 'self.compile(v:val)'), ' ') - if a:node.rest isnot# s:NIL - let left .= ' . ' . self.compile(a:node.rest) - endif - let left = '(' . left . ')' - endif - if a:node.type_str !=# '' - let left .= ': ' . a:node.type_str - endif - let right = self.compile(a:node.right) - call self.out('(var %s %s %s)', a:node.op, left, right) + call self.compile_decl(a:node, 'var') endfunction function! s:Compiler.compile_final(node) abort + call self.compile_decl(a:node, 'final') +endfunction + +" A declared name with its Vim9 type, if any: "name: type" +function! s:Compiler.compile_decl_name(node) abort + let name = self.compile(a:node) + if has_key(a:node, 'type_str') && a:node.type_str !=# '' + let name .= ': ' . a:node.type_str + endif + return name +endfunction + +function! s:Compiler.compile_decl(node, cmd) abort let left = '' if a:node.left isnot# s:NIL - let left = self.compile(a:node.left) + let left = self.compile_decl_name(a:node.left) else - let left = join(map(a:node.list, 'self.compile(v:val)'), ' ') + let left = join(map(a:node.list, 'self.compile_decl_name(v:val)'), ' ') if a:node.rest isnot# s:NIL - let left .= ' . ' . self.compile(a:node.rest) + let left .= ' . ' . self.compile_decl_name(a:node.rest) endif let left = '(' . left . ')' endif - if a:node.type_str !=# '' - let left .= ': ' . a:node.type_str + if a:node.right is# s:NIL + call self.out('(%s %s)', a:cmd, left) + else + call self.out('(%s %s %s %s)', a:cmd, a:node.op, left, self.compile(a:node.right)) endif - let right = self.compile(a:node.right) - call self.out('(final %s %s %s)', a:node.op, left, right) endfunction function! s:Compiler.compile_export(node) abort - call self.out('(export') + call self.compile_wrapper(a:node, 'export') +endfunction + +function! s:Compiler.compile_wrapper(node, name) abort + call self.out('(%s', a:name) + call self.incindent(' ') + call self.compile_body(a:node.body) + call self.out(')') + call self.decindent() +endfunction + +function! s:Compiler.compile_class(node) abort + let s = a:node.name + if a:node.extends !=# '' + let s .= ' extends ' . a:node.extends + endif + if !empty(a:node.implements) + let s .= ' implements ' . join(a:node.implements, ', ') + endif + call self.out('(class %s', s) + call self.incindent(' ') + call self.compile_body(a:node.body) + call self.out(')') + call self.decindent() +endfunction + +function! s:Compiler.compile_interface(node) abort + let s = a:node.name + if !empty(a:node.extends) + let s .= ' extends ' . join(a:node.extends, ', ') + endif + call self.out('(interface %s', s) + call self.incindent(' ') + call self.compile_body(a:node.body) + call self.out(')') + call self.decindent() +endfunction + +function! s:Compiler.compile_enum(node) abort + let s = a:node.name + if !empty(a:node.implements) + let s .= ' implements ' . join(a:node.implements, ', ') + endif + call self.out('(enum %s', s) call self.incindent(' ') + for value in a:node.enumvalues + let rlist = map(value.rlist, 'self.compile(v:val)') + if empty(rlist) + call self.out('(%s)', value.value) + else + call self.out('(%s %s)', value.value, join(rlist, ' ')) + endif + endfor call self.compile_body(a:node.body) call self.out(')') call self.decindent() endfunction +function! s:Compiler.compile_type(node) abort + call self.out('(type %s %s)', a:node.name, a:node.type_str) +endfunction + function! s:Compiler.compile_import(node) abort - call self.out('(import "%s")', escape(a:node.str, '\"')) + let s = self.compile(a:node.left) + if a:node.autoload + let s = 'autoload ' . s + endif + if a:node.alias !=# '' + let s .= ' as ' . a:node.alias + endif + call self.out('(import %s)', s) endfunction " TODO: under construction diff --git a/js/vimlfunc.js b/js/vimlfunc.js index 06a749f..eb75fde 100644 --- a/js/vimlfunc.js +++ b/js/vimlfunc.js @@ -51,7 +51,7 @@ var pat_vim2js = { "\\w" : "[0-9A-Za-z_]", "\\w\\|[:#]" : "[0-9A-Za-z_]|[:#]", "\\x" : "[0-9A-Fa-f]", - "^++" : "^\+\+", + "^++" : "^\\+\\+", "^++bad=\\(keep\\|drop\\|.\\)\\>" : "^\\+\\+bad=(keep|drop|.)\\b", "^++bad=drop" : "^\\+\\+bad=drop", "^++bad=keep" : "^\\+\\+bad=keep", @@ -71,6 +71,7 @@ var pat_vim2js = { "^\\h" : "^[A-Za-z_]", "^\\s" : "^\\s", "^\\s*\\\\" : "^\\s*\\\\", + "^\\s*[\"#]\\\\ " : "^\\s*[\"#]\\\\ ", "^[ \\t]$" : "^[ \\t]$", "^[A-Za-z]$" : "^[A-Za-z]$", "^[0-9A-Za-z]$" : "^[0-9A-Za-z]$", diff --git a/js/vimlparser.js b/js/vimlparser.js index d62b57e..e599d5c 100644 --- a/js/vimlparser.js +++ b/js/vimlparser.js @@ -51,7 +51,7 @@ var pat_vim2js = { "\\w" : "[0-9A-Za-z_]", "\\w\\|[:#]" : "[0-9A-Za-z_]|[:#]", "\\x" : "[0-9A-Fa-f]", - "^++" : "^\+\+", + "^++" : "^\\+\\+", "^++bad=\\(keep\\|drop\\|.\\)\\>" : "^\\+\\+bad=(keep|drop|.)\\b", "^++bad=drop" : "^\\+\\+bad=drop", "^++bad=keep" : "^\\+\\+bad=keep", @@ -71,6 +71,7 @@ var pat_vim2js = { "^\\h" : "^[A-Za-z_]", "^\\s" : "^\\s", "^\\s*\\\\" : "^\\s*\\\\", + "^\\s*[\"#]\\\\ " : "^\\s*[\"#]\\\\ ", "^[ \\t]$" : "^[ \\t]$", "^[A-Za-z]$" : "^[A-Za-z]$", "^[0-9A-Za-z]$" : "^[0-9A-Za-z]$", @@ -333,6 +334,26 @@ var NODE_FINAL = 104; var NODE_EXPORT = 105; var NODE_IMPORT = 106; var NODE_VIM9SCRIPT = 107; +var NODE_TUPLE = 108; +var NODE_CAST = 109; +var NODE_ASSIGN = 110; +var NODE_BLOCK = 111; +var NODE_ENDBLOCK = 112; +var NODE_CLASS = 113; +var NODE_ENDCLASS = 114; +var NODE_INTERFACE = 115; +var NODE_ENDINTERFACE = 116; +var NODE_ENUM = 117; +var NODE_ENDENUM = 118; +var NODE_ENUMVALUE = 119; +var NODE_TYPE = 120; +var NODE_PUBLIC = 121; +var NODE_STATIC = 122; +var NODE_ABSTRACT = 123; +var NODE_FALSY = 124; +var NODE_INTERPOLATION = 125; +var NODE_DEFER = 126; +var NODE_ECHOWINDOW = 127; var TOKEN_EOF = 1; var TOKEN_EOL = 2; var TOKEN_SPACE = 3; @@ -404,7 +425,11 @@ var TOKEN_DOTDOT = 68; var TOKEN_HEREDOC = 69; var TOKEN_LSHIFT = 70; var TOKEN_RSHIFT = 71; +var TOKEN_FATARROW = 72; +var TOKEN_QUESTIONQUESTION = 73; var MAX_FUNC_ARGS = 20; +// Binary operators that continue a Vim9 expression from the previous line. +var VIM9_CONTINUATION_OPS = {"+":1, "-":1, "*":1, "/":1, "%":1, "..":1, "||":1, "&&":1, "??":1, "?":1, ":":1, "<<":1, ">>":1, "==":1, "==?":1, "==#":1, "!=":1, "!=?":1, "!=#":1, ">=":1, ">=?":1, ">=#":1, "<=":1, "<=?":1, "<=#":1, "=~":1, "=~?":1, "=~#":1, "!~":1, "!~?":1, "!~#":1, ">":1, ">?":1, ">#":1, "<":1, "") { this.parse_one_cmd(); @@ -713,39 +813,342 @@ VimLParser.prototype.parse = function(reader) { this.check_missing_endtry("TOPLEVEL", this.reader.getpos()); this.check_missing_endwhile("TOPLEVEL", this.reader.getpos()); this.check_missing_endfor("TOPLEVEL", this.reader.getpos()); + if (this.context[0].type == NODE_BLOCK) { + throw Err("E1026: Missing }", this.reader.getpos()); + } + else if (this.context[0].type == NODE_CLASS) { + throw Err("E1101: Missing :endclass", this.reader.getpos()); + } + else if (this.context[0].type == NODE_INTERFACE) { + throw Err("E1101: Missing :endinterface", this.reader.getpos()); + } + else if (this.context[0].type == NODE_ENUM) { + throw Err("E1101: Missing :endenum", this.reader.getpos()); + } this.pop_context(); return toplevel; } VimLParser.prototype.parse_one_cmd = function() { this.ea = ExArg(); + this.vim9cmd = -1; if (this.reader.peekn(2) == "#!") { this.parse_hashbang(); this.reader.get(); return; } - this.reader.skip_white_and_colon(); + var vim9 = this.isvim9(); + var colon = FALSE; + while (iswhite(this.reader.peekn(1)) || this.reader.peekn(1) == ":") { + if (this.reader.peekn(1) == ":") { + var colon = TRUE; + } + this.reader.seek_cur(1); + } if (this.reader.peekn(1) == "") { this.reader.get(); return; } - if (this.reader.peekn(1) == "\"") { + if (this.reader.peekn(1) == "\"" && !this.isvim9()) { this.parse_comment(); this.reader.get(); return; } - if (this.vim9script && this.reader.peekn(1) == "#") { + if (this.isvim9() && this.reader.peekn(1) == "#") { this.parse_comment(); this.reader.get(); return; } + if (this.context[0].type == NODE_ENUM && !this.context[0].values_done && this.parse_enum_values()) { + this.parse_trail(); + return; + } this.ea.linepos = this.reader.getpos(); this.parse_command_modifiers(); - this.parse_range(); + var vim9 = this.isvim9(); + if (vim9) { + // In Vim9 script a range must be preceded by a colon, without it the line + // may be an expression or assignment. + this.reader.skip_white(); + if (this.reader.peekn(1) == ":") { + var colon = TRUE; + this.reader.skip_white_and_colon(); + } + if (colon) { + this.parse_range(); + } + else if (this.parse_vim9_statement()) { + this.parse_trail(); + return; + } + } + else { + this.parse_range(); + } this.parse_command(); this.parse_trail(); } +// Recognize a Vim9 expression or assignment without :eval, :call or :let, +// like find_ex_command() in Vim. Return TRUE when the line was parsed. +VimLParser.prototype.parse_vim9_statement = function() { + var r = this.reader; + var pos = r.tell(); + this.ea.cmdpos = r.getpos(); + var c = r.peekn(1); + if (c == "{") { + // "{" by itself is the start of a block. + r.getn(1); + r.skip_white(); + var block = this.ends_excmds(r.peek()); + r.seek_set(pos); + if (block) { + return FALSE; + } + this.parse_vim9_expr_cmd(); + return TRUE; + } + else if (c == "(" || c == "'" || c == "\"" || c == "$" && (r.p(1) == "'" || r.p(1) == "\"") || c == "0" && r.p(1) == "z") { + this.parse_vim9_expr_cmd(); + return TRUE; + } + else if (c == "[") { + if (this.is_vim9_list_assign()) { + this.parse_vim9_assign(); + } + else { + this.parse_vim9_expr_cmd(); + } + return TRUE; + } + else if (c == "&" || c == "$" || c == "@" && r.p(1) != "") { + this.parse_vim9_assign_or_expr(); + return TRUE; + } + else if ((c == "+" || c == "-") && r.p(1) == c) { + this.parse_vim9_increment(); + return TRUE; + } + else if (isdigit(c)) { + r.read_digit(); + r.skip_white(); + var method = r.peekn(2) == "->"; + r.seek_set(pos); + if (method) { + this.parse_vim9_expr_cmd(); + } + return method; + } + else if (!iswordc1(c)) { + return FALSE; + } + var name = r.read_vim9_name(); + var c = r.peekn(1); + if (c == "(" || c == "<" && this.is_generic_args()) { + // "funcname(" is always a function call. + r.seek_set(pos); + this.parse_vim9_expr_cmd(); + return TRUE; + } + else if (viml_stridx(name, ":") == 1 || c == "[" || c == "." && iswordc1(r.p(1))) { + // "g:name", "name[idx]" and "name.member" start an expression or + // assignment. + r.seek_set(pos); + this.parse_vim9_assign_or_expr(); + return TRUE; + } + r.skip_white(); + var result = FALSE; + if (r.peekn(2) == "->") { + var result = TRUE; + } + else if (this.peek_assign_op() != "") { + // "name = expr" is an assignment when "name" is a variable or not a + // command. + var result = viml_has_key(this.declared, name) || this.is_vim9_command(pos) == FALSE; + } + else if (this.ends_excmds(r.peek())) { + // A variable followed by an operator on the next line. A variable alone + // has no effect, then it is a command like :new. + var result = viml_has_key(this.declared, name) && (this.is_vim9_command(pos) == FALSE || this.vim9_line_continues()); + } + r.seek_set(pos); + if (result) { + this.parse_vim9_assign_or_expr(); + } + return result; +} + +// Return TRUE when the next line continues the expression on this line. +VimLParser.prototype.vim9_line_continues = function() { + var pos = this.reader.tell(); + if (this.reader.peek() == "#") { + this.reader.getn(-1); + } + var result = this.reader.peek() == "" && new ExprTokenizer(this.reader, TRUE).next_line_continues(); + this.reader.seek_set(pos); + return result; +} + +// Return TRUE when the text at reader position "pos" is an Ex command that +// exists in Vim9 script. +VimLParser.prototype.is_vim9_command = function(cmdpos) { + var pos = this.reader.tell(); + this.reader.seek_set(cmdpos); + var cmd = this.find_command(); + this.reader.seek_set(pos); + if (cmd === NIL) { + return FALSE; + } + return !is_removed_in_vim9(cmd.name); +} + +// Return the assignment operator at the cursor, or an empty string. +VimLParser.prototype.peek_assign_op = function() { + var s3 = this.reader.peekn(3); + var s2 = this.reader.peekn(2); + var op = ""; + if (s3 == "..=" || s3 == "=<<") { + var op = s3; + } + else if (s2 == "+=" || s2 == "-=" || s2 == "*=" || s2 == "/=" || s2 == "%=" || s2 == ".=") { + var op = s2; + } + else if (s2 == "==" || s2 == "=~" || s2 == "=>") { + return ""; + } + else if (this.reader.peekn(1) == "=") { + var op = "="; + } + return op; +} + +// Return TRUE when the generic type arguments of a function call follow: +// "(". +VimLParser.prototype.is_generic_args = function() { + var r = this.reader; + var pos = r.tell(); + r.getn(1); + var depth = 1; + while (depth > 0) { + var c = r.peekn(1); + if (c == "<") { + depth += 1; + } + else if (c == ">") { + depth -= 1; + } + else if (!iswordc(c) && c != "," && c != " " && c != "(" && c != ")" && c != ":" && c != ".") { + r.seek_set(pos); + return FALSE; + } + r.getn(1); + } + var result = r.peekn(1) == "("; + r.seek_set(pos); + return result; +} + +// Return TRUE when "[a, b] =" follows: the list is closed on this line and +// followed by an assignment operator. +VimLParser.prototype.is_vim9_list_assign = function() { + var r = this.reader; + var pos = r.tell(); + var depth = 0; + while (TRUE) { + var c = r.peekn(1); + if (c == "") { + r.seek_set(pos); + return FALSE; + } + r.getn(1); + if (c == "[") { + depth += 1; + } + else if (c == "]") { + depth -= 1; + if (depth == 0) { + break; + } + } + else if (c == "'" || c == "\"") { + while (r.peekn(1) != "" && r.peekn(1) != c) { + r.getn(1); + } + r.getn(1); + } + } + r.skip_white(); + var op = this.peek_assign_op(); + r.seek_set(pos); + return op != "" && op != "=<<"; +} + +// Vim9 expression used as a command. A function call is like :call, any +// other expression is like :eval. +VimLParser.prototype.parse_vim9_expr_cmd = function() { + var left = this.parse_expr(); + if (left.type == NODE_CALL) { + var node = Node(NODE_EXCALL); + } + else { + var node = Node(NODE_EVAL); + } + node.pos = this.ea.cmdpos; + node.ea = this.ea; + node.left = left; + this.add_node(node); +} + +VimLParser.prototype.parse_vim9_assign_or_expr = function() { + var pos = this.reader.tell(); + this.parse_lvalue(); + this.reader.skip_white(); + var op = this.peek_assign_op(); + this.reader.seek_set(pos); + if (op == "") { + this.parse_vim9_expr_cmd(); + } + else { + this.parse_vim9_assign(); + } +} + +// Vim9 assignment without :let: "name = expr", "[a, b] = expr", "name += expr" +VimLParser.prototype.parse_vim9_assign = function() { + var lhs = this.parse_letlhs(); + this.reader.skip_white(); + var node = Node(NODE_ASSIGN); + node.pos = this.ea.cmdpos; + node.ea = this.ea; + node.op = this.peek_assign_op(); + node.left = lhs.left; + node.list = lhs.list; + node.rest = lhs.rest; + this.reader.getn(viml_len(node.op)); + if (node.op == "=<<") { + this.reader.skip_white(); + node.right = this.parse_heredoc(this.heredoc_prefix()); + } + else { + node.right = this.parse_expr(); + } + this.add_node(node); +} + +// Vim9 "++var" and "--var" +VimLParser.prototype.parse_vim9_increment = function() { + var node = Node(NODE_ASSIGN); + node.pos = this.ea.cmdpos; + node.ea = this.ea; + node.op = this.reader.getn(2); + node.left = this.parse_lvalue(); + node.list = NIL; + node.rest = NIL; + node.right = NIL; + this.add_node(node); +} + // FIXME: VimLParser.prototype.parse_command_modifiers = function() { var modifiers = []; @@ -757,9 +1160,27 @@ VimLParser.prototype.parse_command_modifiers = function() { this.reader.skip_white(); } var k = this.reader.read_alpha(); + if (k == "vim" && this.reader.peekn(1) == "9") { + k += this.reader.read_alnum(); + } var c = this.reader.peekn(1); this.reader.skip_white(); - if (viml_stridx("aboveleft", k) == 0 && viml_len(k) >= 3) { + if (this.isvim9() && (c == "(" || c == "[" || c == "." || c == ":" || this.peek_assign_op() != "" || this.reader.peekn(2) == "->")) { + // A Vim9 variable or function, not a modifier. + this.reader.seek_set(pos); + break; + } + else if (viml_stridx("vim9cmd", k) == 0 && viml_len(k) >= 4) { + // vim9\%[cmd] + viml_add(modifiers, {"name":"vim9cmd"}); + this.vim9cmd = TRUE; + } + else if (viml_stridx("legacy", k) == 0 && viml_len(k) >= 3) { + // leg\%[acy] + viml_add(modifiers, {"name":"legacy"}); + this.vim9cmd = FALSE; + } + else if (viml_stridx("aboveleft", k) == 0 && viml_len(k) >= 3) { // abo\%[veleft] viml_add(modifiers, {"name":"aboveleft"}); } @@ -996,7 +1417,7 @@ VimLParser.prototype.parse_pattern = function(delimiter) { VimLParser.prototype.parse_command = function() { this.reader.skip_white_and_colon(); this.ea.cmdpos = this.reader.getpos(); - if (this.reader.peekn(1) == "" || this.reader.peekn(1) == "\"" || this.vim9script && this.reader.peekn(1) == "#") { + if (this.reader.peekn(1) == "" || this.ends_excmds(this.reader.peekn(1))) { if (!viml_empty(this.ea.modifiers) || !viml_empty(this.ea.range)) { this.parse_cmd_modifier_range(); } @@ -1007,6 +1428,21 @@ VimLParser.prototype.parse_command = function() { this.reader.setpos(this.ea.cmdpos); throw Err(viml_printf("E492: Not an editor command: %s", this.reader.peekline()), this.ea.cmdpos); } + if (this.isvim9() && is_removed_in_vim9(this.ea.cmd.name)) { + this.reader.setpos(this.ea.cmdpos); + throw Err(viml_printf("E1100: Command not supported in Vim9 script (missing :var?): %s", this.reader.peekline()), this.ea.cmdpos); + } + // In legacy script :final is an abbreviation of :finally. + if (this.ea.cmd.name == "final" && !this.isvim9()) { + var __c6 = this.builtin_commands; + for (var __i6 = 0; __i6 < __c6.length; ++__i6) { + var x = __c6[__i6]; + if (x.name == "finally") { + this.ea.cmd = x; + break; + } + } + } if (this.reader.peekn(1) == "!" && this.ea.cmd.name != "substitute" && this.ea.cmd.name != "smagic" && this.ea.cmd.name != "snomagic") { this.reader.getn(1); this.ea.forceit = TRUE; @@ -1232,6 +1668,48 @@ VimLParser.prototype._parse_command = function(parser) { else if (parser == "parse_cmd_import") { this.parse_cmd_import(); } + else if (parser == "parse_cmd_abstract") { + this.parse_cmd_abstract(); + } + else if (parser == "parse_cmd_class") { + this.parse_cmd_class(); + } + else if (parser == "parse_cmd_endclass") { + this.parse_cmd_endclass(); + } + else if (parser == "parse_cmd_interface") { + this.parse_cmd_interface(); + } + else if (parser == "parse_cmd_endinterface") { + this.parse_cmd_endinterface(); + } + else if (parser == "parse_cmd_enum") { + this.parse_cmd_enum(); + } + else if (parser == "parse_cmd_endenum") { + this.parse_cmd_endenum(); + } + else if (parser == "parse_cmd_type") { + this.parse_cmd_type(); + } + else if (parser == "parse_cmd_public") { + this.parse_cmd_public(); + } + else if (parser == "parse_cmd_static") { + this.parse_cmd_static(); + } + else if (parser == "parse_cmd_defer") { + this.parse_cmd_defer(); + } + else if (parser == "parse_cmd_echowindow") { + this.parse_cmd_echowindow(); + } + else if (parser == "parse_cmd_block") { + this.parse_cmd_block(); + } + else if (parser == "parse_cmd_endblock") { + this.parse_cmd_endblock(); + } else { throw viml_printf("unknown parser: %s", viml_string(parser)); } @@ -1248,7 +1726,7 @@ VimLParser.prototype.find_command = function() { this.reader.getn(1); var name = "substitute"; } - else if (viml_eqregh(c, "[@*!=><&~#]")) { + else if (viml_eqregh(c, "[@*!=><&~#]") || c == "{" || c == "}") { this.reader.getn(1); var name = c; } @@ -1273,9 +1751,9 @@ VimLParser.prototype.find_command = function() { return this.find_command_cache[name]; } var cmd = NIL; - var __c4 = this.builtin_commands; - for (var __i4 = 0; __i4 < __c4.length; ++__i4) { - var x = __c4[__i4]; + var __c7 = this.builtin_commands; + for (var __i7 = 0; __i7 < __c7.length; ++__i7) { + var x = __c7[__i7]; if (viml_stridx(x.name, name) == 0 && viml_len(name) >= x.minlen) { delete cmd; var cmd = x; @@ -1283,18 +1761,18 @@ VimLParser.prototype.find_command = function() { } } if (this.neovim) { - var __c5 = this.neovim_additional_commands; - for (var __i5 = 0; __i5 < __c5.length; ++__i5) { - var x = __c5[__i5]; + var __c8 = this.neovim_additional_commands; + for (var __i8 = 0; __i8 < __c8.length; ++__i8) { + var x = __c8[__i8]; if (viml_stridx(x.name, name) == 0 && viml_len(name) >= x.minlen) { delete cmd; var cmd = x; break; } } - var __c6 = this.neovim_removed_commands; - for (var __i6 = 0; __i6 < __c6.length; ++__i6) { - var x = __c6[__i6]; + var __c9 = this.neovim_removed_commands; + for (var __i9 = 0; __i9 < __c9.length; ++__i9) { + var x = __c9[__i9]; if (viml_stridx(x.name, name) == 0 && viml_len(name) >= x.minlen) { delete cmd; var cmd = NIL; @@ -1405,7 +1883,7 @@ VimLParser.prototype.read_cmdarg = function() { VimLParser.prototype.parse_comment = function() { var npos = this.reader.getpos(); var c = this.reader.get(); - if (c != "\"" && !(this.vim9script && c == "#")) { + if (c != "\"" && c != "#") { throw Err(viml_printf("unexpected character: %s", c), npos); } var node = Node(NODE_COMMENT); @@ -1427,10 +1905,11 @@ VimLParser.prototype.parse_trail = function() { this.reader.get(); } else if (c == "\"") { + // Also in Vim9 script a double quote after a command starts a comment. this.parse_comment(); this.reader.get(); } - else if (this.vim9script && c == "#") { + else if (this.isvim9() && c == "#") { this.parse_comment(); this.reader.get(); } @@ -1475,12 +1954,24 @@ VimLParser.prototype.parse_cmd_common = function() { node.ea = this.ea; node.str = this.reader.getstr(this.ea.linepos, end); this.add_node(node); + if ((this.ea.cmd.name == "command" || this.ea.cmd.name == "autocmd") && ends_with_block(node.str)) { + // The commands of a user command or autocommand in a block use Vim9 + // syntax: {cmd} ... } + var block = Node(NODE_BLOCK); + block.pos = this.ea.cmdpos; + block.ea = this.ea; + block.body = []; + block.endblock = NIL; + node.block = block; + this.push_context(block); + } } VimLParser.prototype.separate_nextcmd = function() { if (this.ea.cmd.name == "vimgrep" || this.ea.cmd.name == "vimgrepadd" || this.ea.cmd.name == "lvimgrep" || this.ea.cmd.name == "lvimgrepadd") { this.skip_vimgrep_pat(); } + var vim9 = this.isvim9(); var pc = ""; var end = this.reader.getpos(); var nospend = end; @@ -1513,7 +2004,7 @@ VimLParser.prototype.separate_nextcmd = function() { } this.reader.getn(1); } - else if (c == "|" || c == "\n" || c == "\"" && !viml_eqregh(this.ea.cmd.flags, "\\") && (this.ea.cmd.name != "@" && this.ea.cmd.name != "*" || this.reader.getpos() != this.ea.argpos) && (this.ea.cmd.name != "redir" || this.reader.getpos().i != this.ea.argpos.i + 1 || pc != "@") || this.vim9script && c == "#" && iswhite(pc) && !viml_eqregh(this.ea.cmd.flags, "\\")) { + else if (c == "|" || c == "\n" || c == "\"" && !vim9 && !viml_eqregh(this.ea.cmd.flags, "\\") && (this.ea.cmd.name != "@" && this.ea.cmd.name != "*" || this.reader.getpos() != this.ea.argpos) && (this.ea.cmd.name != "redir" || this.reader.getpos().i != this.ea.argpos.i + 1 || pc != "@") || vim9 && c == "#" && iswhite(pc) && !viml_eqregh(this.ea.cmd.flags, "\\")) { var has_cpo_bar = FALSE; // &cpoptions =~ 'b' if ((!has_cpo_bar || !viml_eqregh(this.ea.cmd.flags, "\\")) && pc == "\\") { @@ -1833,7 +2324,7 @@ VimLParser.prototype.parse_cmd_delfunction = function() { } VimLParser.prototype.parse_cmd_return = function() { - if (this.find_context(NODE_FUNCTION) == -1 && this.find_context(NODE_DEF) == -1) { + if (this.find_context(NODE_FUNCTION) == -1 && this.find_context(NODE_DEF) == -1 && this.find_context(NODE_LAMBDA) == -1) { throw Err("E133: :return not inside a function", this.ea.cmdpos); } var node = Node(NODE_RETURN); @@ -1858,7 +2349,12 @@ VimLParser.prototype.parse_cmd_call = function() { throw Err("E471: Argument required", this.reader.getpos()); } node.left = this.parse_expr(); - if (node.left.type != NODE_CALL) { + // A method call may follow the function call: call Func()->Method() + var base = node.left; + while (base.type == NODE_METHOD) { + var base = base.left; + } + if (base.type != NODE_CALL) { throw Err("Not an function call", node.left.pos); } this.add_node(node); @@ -1958,30 +2454,7 @@ VimLParser.prototype.parse_cmd_let = function() { this.reader.getn(viml_len(s2)); this.reader.skip_white(); node.op = s2; - // compute allowed prefix for heredoc end marker (e.g. EOF) - var pos = this.reader.tell(); - while (this.reader.tell() > 0) { - if (this.reader.peek() == "") { - this.reader.seek_cur(1); - break; - } - this.reader.seek_cur(-1); - } - var prefix = ""; - while (TRUE) { - var c = this.reader.getn(1); - if (c == ":") { - // any presence of leading ':' disables prefix for heredoc end marker - var prefix = ""; - break; - } - else if (!iswhite(c)) { - break; - } - prefix += c; - } - this.reader.seek_set(pos); - node.right = this.parse_heredoc(prefix); + node.right = this.parse_heredoc(this.heredoc_prefix()); this.add_node(node); return; } @@ -1996,7 +2469,39 @@ VimLParser.prototype.parse_cmd_let = function() { this.add_node(node); } +// Compute the allowed prefix for a heredoc end marker (e.g. EOF): the indent +// of the command line. +VimLParser.prototype.heredoc_prefix = function() { + var pos = this.reader.tell(); + while (this.reader.tell() > 0) { + if (this.reader.peek() == "") { + this.reader.seek_cur(1); + break; + } + this.reader.seek_cur(-1); + } + var prefix = ""; + while (TRUE) { + var c = this.reader.getn(1); + if (c == ":") { + // any presence of leading ':' disables prefix for heredoc end marker + var prefix = ""; + break; + } + else if (!iswhite(c)) { + break; + } + prefix += c; + } + this.reader.seek_set(pos); + return prefix; +} + VimLParser.prototype.parse_cmd_const = function() { + if (this.isvim9()) { + this.parse_vim9_decl(NODE_CONST); + return; + } var pos = this.reader.tell(); this.reader.skip_white(); // :const @@ -2028,10 +2533,18 @@ VimLParser.prototype.parse_cmd_const = function() { } VimLParser.prototype.parse_cmd_vim9script = function() { - this.reader.skip_white(); var node = Node(NODE_VIM9SCRIPT); node.pos = this.ea.cmdpos; node.ea = this.ea; + node.noclear = FALSE; + this.reader.skip_white(); + var pos = this.reader.tell(); + if (this.reader.read_alpha() == "noclear") { + node.noclear = TRUE; + } + else { + this.reader.seek_set(pos); + } this.vim9script = 1; this.add_node(node); } @@ -2052,6 +2565,14 @@ VimLParser.prototype.parse_cmd_def = function() { return; } var left = this.parse_lvalue_func(); + // Generic function: :def {name}<{type}, ...>( + var type_params = ""; + if (this.reader.peekn(1) == "<") { + while (this.reader.peekn(1) != "" && this.reader.peekn(1) != ">") { + type_params += this.reader.getn(1); + } + type_params += this.reader.getn(1); + } this.reader.skip_white(); // :def {name} if (this.reader.peekn(1) != "(") { @@ -2067,103 +2588,94 @@ VimLParser.prototype.parse_cmd_def = function() { node.left = left; node.rlist = []; node.default_args = []; - node.attr = {"range":0, "abort":0, "dict":0, "closure":0, "return_type":""}; + node.attr = {"range":0, "abort":0, "dict":0, "closure":0, "return_type":"", "type_params":type_params}; node.enddef = NIL; + // The arguments use Vim9 syntax, also in a legacy script. + this.add_node(node); + this.push_context(node); this.reader.getn(1); + var named = {}; + while (TRUE) { + this.skip_vim9_white(); + if (this.reader.peekn(1) == ")") { + this.reader.getn(1); + break; + } + var varnode = Node(NODE_IDENTIFIER); + varnode.pos = this.reader.getpos(); + varnode.type_str = ""; + var variadic = this.reader.peekn(3) == "..."; + if (variadic) { + this.reader.getn(3); + } + var pname = this.reader.read_word(); + if (pname == "this" && this.reader.peekn(1) == ".") { + // constructor argument that sets an object variable: this.name + pname += this.reader.getn(1) + this.reader.read_word(); + } + if (pname == "") { + throw Err(viml_printf("E475: Invalid argument: %s", this.reader.peekn(1)), this.reader.getpos()); + } + if (viml_has_key(named, pname) && pname != "_") { + throw Err(viml_printf("E853: Duplicate argument name: %s", pname), varnode.pos); + } + named[pname] = 1; + this.declared[pname] = 1; + varnode.value = pname; + if (variadic) { + varnode.value = "..." + pname; + } + viml_add(node.rlist, varnode); + // Check for type annotation + if (this.reader.peekn(1) == ":") { + this.reader.getn(1); + this.reader.skip_white(); + varnode.type_str = this.read_type(); + } + // Check for default value + this.reader.skip_white(); + if (this.reader.peekn(1) == "=" && !variadic) { + this.reader.getn(1); + this.reader.skip_white(); + viml_add(node.default_args, this.parse_expr()); + } + else if (viml_len(node.default_args) > 0 && !variadic) { + throw Err("E989: Non-default argument follows default argument", varnode.pos); + } + this.skip_vim9_white(); + if (this.reader.peekn(1) == ",") { + this.reader.getn(1); + } + else if (this.reader.peekn(1) != ")") { + throw Err(viml_printf("E475: Invalid argument: %s", this.reader.peekn(1)), this.reader.getpos()); + } + } + // Check for return type annotation ': type' this.reader.skip_white(); - if (this.reader.peekn(1) == ")") { + if (this.reader.peekn(1) == ":") { this.reader.getn(1); + this.reader.skip_white(); + node.attr.return_type = this.read_type(); } - else { - var named = {}; - while (TRUE) { - var varnode = Node(NODE_IDENTIFIER); - this.reader.skip_white(); - varnode.type_str = ""; - // Check for ...name (variadic) - if (this.reader.peekn(3) == "...") { - this.reader.getn(3); - this.reader.skip_white(); - var vname = this.reader.read_word(); - varnode.pos = this.reader.getpos(); - varnode.value = "..." + vname; - // Optionally read type annotation - this.reader.skip_white(); - if (this.reader.peekn(1) == ":") { - this.reader.getn(1); - this.reader.skip_white(); - varnode.type_str = this.read_type(); - } - viml_add(node.rlist, varnode); - this.reader.skip_white(); - if (this.reader.peekn(1) == ")") { - this.reader.getn(1); - break; - } - else { - throw Err(viml_printf("E475: Invalid argument: %s", this.reader.peekn(1)), this.reader.getpos()); - } - } - var npos = this.reader.getpos(); - var pname = this.reader.read_word(); - if (pname == "") { - if (this.reader.peekn(1) == ")") { - this.reader.getn(1); - break; - } - throw Err(viml_printf("E475: Invalid argument: %s", this.reader.peekn(1)), this.reader.getpos()); - } - if (viml_has_key(named, pname)) { - throw Err(viml_printf("E853: Duplicate argument name: %s", pname), npos); - } - named[pname] = 1; - varnode.pos = npos; - varnode.value = pname; - viml_add(node.rlist, varnode); - // Check for type annotation - this.reader.skip_white(); - if (this.reader.peekn(1) == ":") { - this.reader.getn(1); - this.reader.skip_white(); - varnode.type_str = this.read_type(); - } - // Check for default value - this.reader.skip_white(); - if (this.reader.peekn(1) == "=") { - this.reader.getn(1); - this.reader.skip_white(); - viml_add(node.default_args, this.parse_expr()); - } - else if (viml_len(node.default_args) > 0) { - throw Err("E989: Non-default argument follows default argument", varnode.pos); - } - this.reader.skip_white(); - if (this.reader.peekn(1) == ",") { - this.reader.getn(1); - this.reader.skip_white(); - if (this.reader.peekn(1) == ")") { - this.reader.getn(1); - break; - } - } - else if (this.reader.peekn(1) == ")") { - this.reader.getn(1); - break; - } - else { - throw Err(viml_printf("E475: Invalid argument: %s", this.reader.peekn(1)), this.reader.getpos()); - } - } + // A method in an interface and an abstract method have no body. + if (this.abstract || this.context[1].type == NODE_INTERFACE) { + this.pop_context(); } - // Check for return type annotation ': type' - this.reader.skip_white(); - if (this.reader.peekn(1) == ":") { - this.reader.getn(1); +} + +// Skip white space, comments and line breaks, e.g. in the argument list of a +// :def function. +VimLParser.prototype.skip_vim9_white = function() { + while (TRUE) { this.reader.skip_white(); - node.attr.return_type = this.read_type(); + if (this.reader.peek() == "#") { + this.reader.getn(-1); + } + if (this.reader.peek() != "") { + break; + } + this.reader.get(); } - this.add_node(node); - this.push_context(node); } VimLParser.prototype.read_type = function() { @@ -2178,6 +2690,12 @@ VimLParser.prototype.read_type = function() { break; } } + // Handle func: rettype + if (type_str == "func" && this.reader.peekn(1) == ":" && iswhite(this.reader.p(1))) { + this.reader.getn(1); + this.reader.skip_white(); + return type_str + ": " + this.read_type(); + } // Handle generics: type<...> if (this.reader.peekn(1) == "<") { type_str += this.reader.getn(1); @@ -2216,14 +2734,46 @@ VimLParser.prototype.read_type = function() { // Check for ': rettype' after func params this.reader.skip_white(); if (this.reader.peekn(1) == ":") { - type_str += this.reader.getn(1); + this.reader.getn(1); this.reader.skip_white(); - type_str += this.read_type(); + type_str += ": " + this.read_type(); } } return type_str; } +// Parse the statements of a Vim9 lambda "(args) => {", up to the "}" at the +// start of a line. Only a comment may follow the "{". +VimLParser.prototype.parse_lambda_block = function(node) { + var ea = this.ea; + var vim9cmd = this.vim9cmd; + this.reader.skip_white(); + if (this.reader.peek() == "#") { + this.reader.getn(-1); + } + if (this.reader.peek() != "") { + throw Err(viml_printf("E488: Trailing characters: %s", this.reader.peekline()), this.reader.getpos()); + } + this.reader.get(); + this.push_context(node); + while (TRUE) { + if (this.reader.peek() == "") { + throw Err("E1171: Missing } after inline function", this.reader.getpos()); + } + var pos = this.reader.tell(); + this.reader.skip_white(); + if (this.context[0] === node && this.reader.peek() == "}") { + this.reader.get(); + break; + } + this.reader.seek_set(pos); + this.parse_one_cmd(); + } + this.pop_context(); + this.ea = ea; + this.vim9cmd = vim9cmd; +} + VimLParser.prototype.parse_cmd_enddef = function() { this.check_missing_endif("ENDDEF", this.ea.cmdpos); this.check_missing_endtry("ENDDEF", this.ea.cmdpos); @@ -2241,123 +2791,120 @@ VimLParser.prototype.parse_cmd_enddef = function() { } VimLParser.prototype.parse_cmd_var = function() { + this.parse_vim9_decl(NODE_VAR); +} + +VimLParser.prototype.parse_cmd_final = function() { + this.parse_vim9_decl(NODE_FINAL); +} + +// Vim9 declaration with :var, :final or :const: +// var name[: type] [= expr] +// var [name[: type], ...[; rest]] = expr +// var name[: type] =<< [trim] [eval] END +VimLParser.prototype.parse_vim9_decl = function(type) { var pos = this.reader.tell(); this.reader.skip_white(); - // :var + // :var without argument lists variables if (this.ends_excmds(this.reader.peek())) { this.reader.seek_set(pos); this.parse_cmd_common(); return; } - // Read variable name directly (avoid LvalueParser eating ':' as part of name) - var npos = this.reader.getpos(); - var vname = this.reader.read_word(); - if (vname == "") { - this.reader.seek_set(pos); - this.parse_cmd_common(); - return; - } - var left = Node(NODE_IDENTIFIER); - left.pos = npos; - left.value = vname; - this.reader.skip_white(); - // Check for type annotation - var type_str = ""; - if (this.reader.peekn(1) == ":") { - this.reader.getn(1); - this.reader.skip_white(); - var type_str = this.read_type(); - this.reader.skip_white(); - } - var s1 = this.reader.peekn(1); - var s2 = this.reader.peekn(2); - if (s2 == "..") { - var s2 = this.reader.peekn(3); - } - // :var {var-name} (no assignment) - if (this.ends_excmds(s1) || s2 != "+=" && s2 != "-=" && s2 != ".=" && s2 != "..=" && s2 != "*=" && s2 != "/=" && s2 != "%=" && s1 != "=") { - this.reader.seek_set(pos); - this.parse_cmd_common(); - return; - } - // :var left op right - var node = Node(NODE_VAR); + var node = Node(type); node.pos = this.ea.cmdpos; node.ea = this.ea; node.op = ""; - node.left = left; + node.left = NIL; node.list = NIL; node.rest = NIL; node.right = NIL; - node.type_str = type_str; - if (s2 == "+=" || s2 == "-=" || s2 == ".=" || s2 == "..=" || s2 == "*=" || s2 == "/=" || s2 == "%=") { - this.reader.getn(viml_len(s2)); - node.op = s2; - } - else if (s1 == "=") { + node.type_str = ""; + if (this.reader.peekn(1) == "[") { this.reader.getn(1); - node.op = s1; + node.list = []; + while (TRUE) { + viml_add(node.list, this.parse_vim9_decl_name()); + this.reader.skip_white(); + var c = this.reader.getn(1); + if (c == ";") { + node.rest = this.parse_vim9_decl_name(); + this.reader.skip_white(); + var c = this.reader.getn(1); + } + if (c == "]") { + break; + } + else if (c != ",") { + throw Err(viml_printf("E475: Invalid argument: %s", c), this.reader.getpos()); + } + } + var __c10 = node.list; + for (var __i10 = 0; __i10 < __c10.length; ++__i10) { + var x = __c10[__i10]; + this.declare(x); + } + this.declare(node.rest); } else { - throw "NOT REACHED"; + node.left = this.parse_vim9_decl_name(); + node.type_str = node.left.type_str; + this.declare(node.left); + } + this.reader.skip_white(); + node.op = this.peek_assign_op(); + this.reader.getn(viml_len(node.op)); + if (node.op == "=<<") { + this.reader.skip_white(); + node.right = this.parse_heredoc(this.heredoc_prefix()); + } + else if (node.op != "") { + node.right = this.parse_expr(); } - node.right = this.parse_expr(); this.add_node(node); } -VimLParser.prototype.parse_cmd_final = function() { - var pos = this.reader.tell(); +// Variable name with an optional type in a Vim9 declaration: "name: type" +VimLParser.prototype.parse_vim9_decl_name = function() { this.reader.skip_white(); - // :final - if (this.ends_excmds(this.reader.peek())) { - this.reader.seek_set(pos); - this.parse_cmd_common(); - return; - } - // Read variable name directly - var npos = this.reader.getpos(); - var vname = this.reader.read_word(); - if (vname == "") { - this.reader.seek_set(pos); - this.parse_cmd_common(); - return; + var node = Node(NODE_IDENTIFIER); + node.pos = this.reader.getpos(); + node.value = this.reader.read_vim9_name(); + node.type_str = ""; + if (node.value == "") { + throw Err(viml_printf("E475: Invalid argument: %s", this.reader.peekline()), node.pos); } - var left = Node(NODE_IDENTIFIER); - left.pos = npos; - left.value = vname; - this.reader.skip_white(); - // Check for type annotation - var type_str = ""; if (this.reader.peekn(1) == ":") { this.reader.getn(1); this.reader.skip_white(); - var type_str = this.read_type(); - this.reader.skip_white(); - } - var s1 = this.reader.peekn(1); - // :final {var-name} - if (this.ends_excmds(s1) || s1 != "=") { - this.reader.seek_set(pos); - this.parse_cmd_common(); - return; + node.type_str = this.read_type(); } - // :final left = right - var node = Node(NODE_FINAL); - node.pos = this.ea.cmdpos; - node.ea = this.ea; - this.reader.getn(1); - node.op = s1; - node.left = left; - node.list = NIL; - node.rest = NIL; - node.right = this.parse_expr(); - node.type_str = type_str; - this.add_node(node); + return node; } VimLParser.prototype.parse_cmd_export = function() { + this.parse_wrapper(NODE_EXPORT); +} + +VimLParser.prototype.parse_cmd_public = function() { + this.parse_wrapper(NODE_PUBLIC); +} + +VimLParser.prototype.parse_cmd_static = function() { + this.parse_wrapper(NODE_STATIC); +} + +VimLParser.prototype.parse_cmd_abstract = function() { + this.abstract = TRUE; + this.parse_wrapper(NODE_ABSTRACT); + this.abstract = FALSE; +} + +// Parse a command that applies to the following command, like :export +// and :static. The nodes of the following command go into the body. +VimLParser.prototype.parse_wrapper = function(type) { this.reader.skip_white(); - var export_pos = this.ea.cmdpos; + var wrapper_pos = this.ea.cmdpos; // Re-find the inner command this.ea.cmdpos = this.reader.getpos(); this.ea.cmd = this.find_command(); @@ -2370,60 +2917,294 @@ VimLParser.prototype.parse_cmd_export = function() { } this.reader.skip_white(); this.ea.argpos = this.reader.getpos(); - var export_node = Node(NODE_EXPORT); - export_node.pos = export_pos; - export_node.ea = this.ea; - export_node.body = []; + var wrapper = Node(type); + wrapper.pos = wrapper_pos; + wrapper.ea = this.ea; + wrapper.body = []; // Remember current context body position var ctx = this.context[0]; var before = viml_len(ctx.body); // Parse the inner command this._parse_command(this.ea.cmd.parser); - // Move newly-added nodes into export body + // Move newly-added nodes into the wrapper body while (viml_len(ctx.body) > before) { var moved_node = ctx.body[before]; viml_remove(ctx.body, before); - viml_add(export_node.body, moved_node); + viml_add(wrapper.body, moved_node); } - viml_add(ctx.body, export_node); + viml_add(ctx.body, wrapper); } -VimLParser.prototype.parse_cmd_import = function() { - var node = Node(NODE_IMPORT); +// :class {name} [extends {class}] [implements {interface}, ...] +VimLParser.prototype.parse_cmd_class = function() { + var node = Node(NODE_CLASS); node.pos = this.ea.cmdpos; node.ea = this.ea; - node.left = NIL; - node.str = ""; - this.reader.skip_white(); - // Read the rest of the import line, stopping at a trailing comment. - var line = ""; - var pending_ws = ""; - var last_was_white = FALSE; + node.name = this.read_class_name(); + node.extends = ""; + node.implements = []; + node.body = []; + node.endclass = NIL; while (TRUE) { - var c = this.reader.peekn(1); - if (c == "") { + this.reader.skip_white(); + var pos = this.reader.tell(); + var key = this.reader.read_alpha(); + if (key == "extends") { + this.reader.skip_white(); + node.extends = this.read_type(); + } + else if (key == "implements" || key == "specifies") { + node.implements = this.read_type_list(); + } + else { + this.reader.seek_set(pos); break; } - if (c == "#" && last_was_white) { - // Consume the rest of the line, so parse_trail doesn't see it. - this.reader.getn(-1); + } + this.add_node(node); + this.push_context(node); +} + +VimLParser.prototype.parse_cmd_endclass = function() { + this.parse_class_end(NODE_CLASS, "E1316: Class can only be defined in Vim9 script"); +} + +// :interface {name} [extends {interface}, ...] +VimLParser.prototype.parse_cmd_interface = function() { + var node = Node(NODE_INTERFACE); + node.pos = this.ea.cmdpos; + node.ea = this.ea; + node.name = this.read_class_name(); + node.extends = []; + node.body = []; + node.endinterface = NIL; + this.reader.skip_white(); + var pos = this.reader.tell(); + if (this.reader.read_alpha() == "extends") { + node.extends = this.read_type_list(); + } + else { + this.reader.seek_set(pos); + } + this.add_node(node); + this.push_context(node); +} + +VimLParser.prototype.parse_cmd_endinterface = function() { + this.parse_class_end(NODE_INTERFACE, "E1345: :endinterface without :interface"); +} + +// :enum {name} [implements {interface}, ...] +VimLParser.prototype.parse_cmd_enum = function() { + var node = Node(NODE_ENUM); + node.pos = this.ea.cmdpos; + node.ea = this.ea; + node.name = this.read_class_name(); + node.implements = []; + node.enumvalues = []; + node.body = []; + node.endenum = NIL; + // The enum values come first. + node.values_done = FALSE; + this.reader.skip_white(); + var pos = this.reader.tell(); + if (this.reader.read_alpha() == "implements") { + node.implements = this.read_type_list(); + } + else { + this.reader.seek_set(pos); + } + this.add_node(node); + this.push_context(node); +} + +VimLParser.prototype.parse_cmd_endenum = function() { + this.parse_class_end(NODE_ENUM, "E1419: :endenum without :enum"); +} + +// Parse the enum values at the start of an enum: "Name[(args)], ..." +// Return FALSE when the line is not a list of values. +VimLParser.prototype.parse_enum_values = function() { + var enumnode = this.context[0]; + var pos = this.reader.tell(); + var word = this.reader.read_word(); + var c = this.reader.peekn(1); + this.reader.seek_set(pos); + if (word == "" || word == "var" || word == "final" || word == "const" || word == "def" || word == "static" || word == "public" || word == "endenum" || c != "" && c != "," && c != "(" && !iswhite(c)) { + enumnode.values_done = TRUE; + return FALSE; + } + while (TRUE) { + this.skip_vim9_white(); + var node = Node(NODE_ENUMVALUE); + node.pos = this.reader.getpos(); + node.value = this.reader.read_word(); + node.rlist = []; + if (this.reader.peekn(1) == "(") { + var p = new ExprParser(this.reader, this); + p.tokenizer.get(); + node.rlist = p.parse_rlist(); + } + viml_add(enumnode.enumvalues, node); + this.reader.skip_white(); + if (this.reader.peekn(1) != ",") { break; } this.reader.getn(1); - if (iswhite(c)) { - pending_ws += c; - var last_was_white = TRUE; + this.skip_vim9_white(); + if (this.reader.peek() == "") { + break; } - else { - line += pending_ws + c; - var pending_ws = ""; - var last_was_white = FALSE; + var pos = this.reader.tell(); + var word = this.reader.read_word(); + this.reader.seek_set(pos); + if (word == "endenum") { + break; } } - node.str = line; + enumnode.values_done = TRUE; + return TRUE; +} + +VimLParser.prototype.parse_class_end = function(type, msg) { + this.check_missing_endif(this.ea.cmd.name, this.ea.cmdpos); + this.check_missing_endtry(this.ea.cmd.name, this.ea.cmdpos); + this.check_missing_endwhile(this.ea.cmd.name, this.ea.cmdpos); + this.check_missing_endfor(this.ea.cmd.name, this.ea.cmdpos); + this.check_missing_enddef(this.ea.cmd.name, this.ea.cmdpos); + if (this.context[0].type != type) { + throw Err(msg, this.ea.cmdpos); + } + if (type == NODE_CLASS) { + var node = Node(NODE_ENDCLASS); + this.context[0].endclass = node; + } + else if (type == NODE_INTERFACE) { + var node = Node(NODE_ENDINTERFACE); + this.context[0].endinterface = node; + } + else { + var node = Node(NODE_ENDENUM); + this.context[0].endenum = node; + } + node.pos = this.ea.cmdpos; + node.ea = this.ea; + this.pop_context(); +} + +// :type {name} = {type} +VimLParser.prototype.parse_cmd_type = function() { + if (!this.isvim9()) { + this.parse_cmd_common(); + return; + } + var node = Node(NODE_TYPE); + node.pos = this.ea.cmdpos; + node.ea = this.ea; + node.name = this.read_class_name(); + this.reader.skip_white(); + if (this.reader.getn(1) != "=") { + throw Err("E1403: Missing \"=\" in type alias", this.reader.getpos()); + } + this.reader.skip_white(); + node.type_str = this.read_type(); + this.declared[node.name] = 1; this.add_node(node); } +VimLParser.prototype.read_class_name = function() { + this.reader.skip_white(); + var name = this.reader.read_word(); + if (name == "") { + throw Err(viml_printf("E475: Invalid argument: %s", this.reader.peekline()), this.reader.getpos()); + } + this.declared[name] = 1; + return name; +} + +// A comma separated list of types, e.g. after "implements". +VimLParser.prototype.read_type_list = function() { + var list = []; + while (TRUE) { + this.reader.skip_white(); + viml_add(list, this.read_type()); + this.reader.skip_white(); + if (this.reader.peekn(1) != ",") { + break; + } + this.reader.getn(1); + } + return list; +} + +// :import [autoload] {expr} [as {name}] +VimLParser.prototype.parse_cmd_import = function() { + var node = Node(NODE_IMPORT); + node.pos = this.ea.cmdpos; + node.ea = this.ea; + node.autoload = FALSE; + node.alias = ""; + this.reader.skip_white(); + var start = this.reader.getpos(); + var pos = this.reader.tell(); + if (this.reader.read_alpha() == "autoload" && iswhite(this.reader.peekn(1))) { + node.autoload = TRUE; + this.reader.skip_white(); + } + else { + this.reader.seek_set(pos); + } + node.left = this.parse_expr(); + var end = this.reader.getpos(); + this.reader.skip_white(); + var pos = this.reader.tell(); + if (this.reader.read_alpha() == "as" && iswhite(this.reader.peekn(1))) { + this.reader.skip_white(); + node.alias = this.reader.read_word(); + this.declared[node.alias] = 1; + var end = this.reader.getpos(); + } + else { + this.reader.seek_set(pos); + } + // The text of the arguments. + node.str = this.reader.getstr(start, end); + this.add_node(node); +} + +VimLParser.prototype.parse_cmd_block = function() { + if (!this.isvim9()) { + this.parse_cmd_common(); + return; + } + var node = Node(NODE_BLOCK); + node.pos = this.ea.cmdpos; + node.ea = this.ea; + node.body = []; + node.endblock = NIL; + this.add_node(node); + this.push_context(node); +} + +VimLParser.prototype.parse_cmd_endblock = function() { + if (!this.isvim9()) { + this.parse_cmd_common(); + return; + } + this.check_missing_endif("}", this.ea.cmdpos); + this.check_missing_endtry("}", this.ea.cmdpos); + this.check_missing_endwhile("}", this.ea.cmdpos); + this.check_missing_endfor("}", this.ea.cmdpos); + if (this.context[0].type != NODE_BLOCK) { + throw Err("E1128: } without {", this.ea.cmdpos); + } + var node = Node(NODE_ENDBLOCK); + node.pos = this.ea.cmdpos; + node.ea = this.ea; + this.context[0].endblock = node; + this.pop_context(); +} + VimLParser.prototype.parse_cmd_unlet = function() { var node = Node(NODE_UNLET); node.pos = this.ea.cmdpos; @@ -2548,18 +3329,62 @@ VimLParser.prototype.parse_cmd_for = function() { node.left = NIL; node.right = NIL; node.endfor = NIL; - var lhs = this.parse_letlhs(); + if (this.isvim9()) { + var lhs = this.parse_vim9_forlhs(); + } + else { + var lhs = this.parse_letlhs(); + } node.left = lhs.left; node.list = lhs.list; node.rest = lhs.rest; + this.declare(node.left); + if (node.list !== NIL) { + var __c11 = node.list; + for (var __i11 = 0; __i11 < __c11.length; ++__i11) { + var x = __c11[__i11]; + this.declare(x); + } + } + this.declare(node.rest); this.reader.skip_white(); var epos = this.reader.getpos(); if (this.reader.read_alpha() != "in") { throw Err("Missing \"in\" after :for", epos); } - node.right = this.parse_expr(); - this.add_node(node); - this.push_context(node); + node.right = this.parse_expr(); + this.add_node(node); + this.push_context(node); +} + +// Vim9 :for loop variables with optional types: "name: type" or +// "[name: type, ...]" +VimLParser.prototype.parse_vim9_forlhs = function() { + var lhs = {"left":NIL, "list":NIL, "rest":NIL}; + this.reader.skip_white(); + if (this.reader.peekn(1) != "[") { + lhs.left = this.parse_vim9_decl_name(); + return lhs; + } + this.reader.getn(1); + lhs.list = []; + while (TRUE) { + viml_add(lhs.list, this.parse_vim9_decl_name()); + this.reader.skip_white(); + var c = this.reader.getn(1); + if (c == ";") { + lhs.rest = this.parse_vim9_decl_name(); + this.reader.skip_white(); + var c = this.reader.getn(1); + } + if (c == "]") { + break; + } + else if (c != ",") { + throw Err(viml_printf("E475: Invalid argument: %s", c), this.reader.getpos()); + } + } + return lhs; } VimLParser.prototype.parse_cmd_endfor = function() { @@ -2726,6 +3551,26 @@ VimLParser.prototype.parse_cmd_echoconsole = function() { this.add_node(node); } +VimLParser.prototype.parse_cmd_echowindow = function() { + var node = Node(NODE_ECHOWINDOW); + node.pos = this.ea.cmdpos; + node.ea = this.ea; + node.list = this.parse_exprlist(); + this.add_node(node); +} + +// :defer {func}({args}) +VimLParser.prototype.parse_cmd_defer = function() { + var node = Node(NODE_DEFER); + node.pos = this.ea.cmdpos; + node.ea = this.ea; + node.left = this.parse_expr(); + if (node.left.type != NODE_CALL) { + throw Err("E107: Missing parentheses", node.left.pos); + } + this.add_node(node); +} + VimLParser.prototype.parse_cmd_execute = function() { var node = Node(NODE_EXECUTE); node.pos = this.ea.cmdpos; @@ -2735,7 +3580,7 @@ VimLParser.prototype.parse_cmd_execute = function() { } VimLParser.prototype.parse_expr = function() { - return new ExprParser(this.reader).parse(); + return new ExprParser(this.reader, this).parse(); } VimLParser.prototype.parse_exprlist = function() { @@ -2753,7 +3598,7 @@ VimLParser.prototype.parse_exprlist = function() { } VimLParser.prototype.parse_lvalue_func = function() { - var p = new LvalueParser(this.reader); + var p = new LvalueParser(this.reader, this); var node = p.parse(); if (node.type == NODE_IDENTIFIER || node.type == NODE_CURLYNAME || node.type == NODE_SUBSCRIPT || node.type == NODE_DOT || node.type == NODE_OPTION || node.type == NODE_ENV || node.type == NODE_REG) { return node; @@ -2763,7 +3608,7 @@ VimLParser.prototype.parse_lvalue_func = function() { // FIXME: VimLParser.prototype.parse_lvalue = function() { - var p = new LvalueParser(this.reader); + var p = new LvalueParser(this.reader, this); var node = p.parse(); if (node.type == NODE_IDENTIFIER) { if (!isvarname(node.value)) { @@ -2778,7 +3623,7 @@ VimLParser.prototype.parse_lvalue = function() { // TODO: merge with s:VimLParser.parse_lvalue() VimLParser.prototype.parse_constlvalue = function() { - var p = new LvalueParser(this.reader); + var p = new LvalueParser(this.reader, this); var node = p.parse(); if (node.type == NODE_IDENTIFIER) { if (!isvarname(node.value)) { @@ -2821,7 +3666,7 @@ VimLParser.prototype.parse_lvaluelist = function() { // FIXME: VimLParser.prototype.parse_letlhs = function() { var lhs = {"left":NIL, "list":NIL, "rest":NIL}; - var tokenizer = new ExprTokenizer(this.reader); + var tokenizer = new ExprTokenizer(this.reader, this.isvim9()); if (tokenizer.peek().type == TOKEN_SQOPEN) { tokenizer.get(); lhs.list = []; @@ -2860,7 +3705,7 @@ VimLParser.prototype.parse_letlhs = function() { // TODO: merge with s:VimLParser.parse_letlhs() ? VimLParser.prototype.parse_constlhs = function() { var lhs = {"left":NIL, "list":NIL, "rest":NIL}; - var tokenizer = new ExprTokenizer(this.reader); + var tokenizer = new ExprTokenizer(this.reader, this.isvim9()); if (tokenizer.peek().type == TOKEN_SQOPEN) { tokenizer.get(); lhs.list = []; @@ -2897,8 +3742,13 @@ VimLParser.prototype.parse_constlhs = function() { } VimLParser.prototype.ends_excmds = function(c) { - if (this.vim9script && c == "#") { - return 1; + if (this.isvim9()) { + if (c == "#") { + return 1; + } + else if (c == "\"") { + return 0; + } } return c == "" || c == "|" || c == "\"" || c == "" || c == ""; } @@ -2958,14 +3808,22 @@ VimLParser.prototype.neovim_additional_commands = [{"name":"rshada", "minlen":3, VimLParser.prototype.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 -VimLParser.prototype.builtin_commands = [{"name":"append", "minlen":1, "flags":"BANG|RANGE|ZEROR|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_append"}, {"name":"abbreviate", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"abclear", "minlen":3, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"aboveleft", "minlen":3, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"abstract", "minlen":3, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"all", "minlen":2, "flags":"BANG|RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"amenu", "minlen":2, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"anoremenu", "minlen":2, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"args", "minlen":2, "flags":"BANG|FILES|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"argadd", "minlen":4, "flags":"BANG|RANGE|ZEROR|FILES|TRLBAR", "parser":"parse_cmd_common"}, {"name":"argdelete", "minlen":4, "flags":"BANG|RANGE|FILES|TRLBAR", "parser":"parse_cmd_common"}, {"name":"argdo", "minlen":5, "flags":"BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser":"parse_cmd_common"}, {"name":"argdedupe", "minlen":6, "flags":"TRLBAR", "parser":"parse_cmd_common"}, {"name":"argedit", "minlen":4, "flags":"BANG|NEEDARG|RANGE|ZEROR|FILES|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"argglobal", "minlen":4, "flags":"BANG|FILES|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"arglocal", "minlen":4, "flags":"BANG|FILES|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"argument", "minlen":4, "flags":"BANG|RANGE|COUNT|EXTRA|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"ascii", "minlen":2, "flags":"TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"autocmd", "minlen":2, "flags":"BANG|EXTRA|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"augroup", "minlen":3, "flags":"BANG|WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"aunmenu", "minlen":3, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"buffer", "minlen":1, "flags":"BANG|RANGE|BUFNAME|BUFUNL|COUNT|EXTRA|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"bNext", "minlen":2, "flags":"BANG|RANGE|COUNT|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"ball", "minlen":2, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"badd", "minlen":3, "flags":"NEEDARG|FILE1|CMDARG|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"balt", "minlen":4, "flags":"NEEDARG|FILE1|CMDARG|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"bdelete", "minlen":2, "flags":"BANG|RANGE|BUFNAME|COUNT|EXTRA|TRLBAR", "parser":"parse_cmd_common"}, {"name":"behave", "minlen":2, "flags":"BANG|NEEDARG|WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"belowright", "minlen":3, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"bfirst", "minlen":2, "flags":"BANG|RANGE|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"blast", "minlen":2, "flags":"BANG|RANGE|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"bmodified", "minlen":2, "flags":"BANG|RANGE|COUNT|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"bnext", "minlen":2, "flags":"BANG|RANGE|COUNT|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"botright", "minlen":2, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"bprevious", "minlen":2, "flags":"BANG|RANGE|COUNT|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"brewind", "minlen":2, "flags":"BANG|RANGE|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"break", "minlen":4, "flags":"TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_break"}, {"name":"breakadd", "minlen":6, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"breakdel", "minlen":6, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"breaklist", "minlen":6, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"browse", "minlen":3, "flags":"NEEDARG|EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"buffers", "minlen":7, "flags":"BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"bufdo", "minlen":4, "flags":"BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser":"parse_cmd_common"}, {"name":"bunload", "minlen":3, "flags":"BANG|RANGE|BUFNAME|COUNT|EXTRA|TRLBAR", "parser":"parse_cmd_common"}, {"name":"bwipeout", "minlen":2, "flags":"BANG|RANGE|BUFNAME|BUFUNL|COUNT|EXTRA|TRLBAR", "parser":"parse_cmd_common"}, {"name":"change", "minlen":1, "flags":"BANG|WHOLEFOLD|RANGE|COUNT|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"cNext", "minlen":2, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"cNfile", "minlen":3, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"cabbrev", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"cabclear", "minlen":4, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"cabove", "minlen":4, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"caddbuffer", "minlen":3, "flags":"RANGE|WORD1|TRLBAR", "parser":"parse_cmd_common"}, {"name":"caddexpr", "minlen":5, "flags":"NEEDARG|WORD1|NOTRLCOM|EXPR_ARG", "parser":"parse_cmd_common"}, {"name":"caddfile", "minlen":5, "flags":"TRLBAR|FILE1", "parser":"parse_cmd_common"}, {"name":"cafter", "minlen":3, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"call", "minlen":3, "flags":"RANGE|NEEDARG|EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_call"}, {"name":"catch", "minlen":3, "flags":"EXTRA|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_catch"}, {"name":"cbuffer", "minlen":2, "flags":"BANG|RANGE|WORD1|TRLBAR", "parser":"parse_cmd_common"}, {"name":"cbefore", "minlen":3, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"cbelow", "minlen":4, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"cbottom", "minlen":3, "flags":"TRLBAR", "parser":"parse_cmd_common"}, {"name":"cc", "minlen":2, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"cclose", "minlen":3, "flags":"TRLBAR", "parser":"parse_cmd_common"}, {"name":"cd", "minlen":2, "flags":"BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"cdo", "minlen":3, "flags":"BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser":"parse_cmd_common"}, {"name":"center", "minlen":2, "flags":"TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"cexpr", "minlen":3, "flags":"NEEDARG|WORD1|NOTRLCOM|EXPR_ARG|BANG", "parser":"parse_cmd_common"}, {"name":"cfile", "minlen":2, "flags":"TRLBAR|FILE1|BANG", "parser":"parse_cmd_common"}, {"name":"cfdo", "minlen":3, "flags":"BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser":"parse_cmd_common"}, {"name":"cfirst", "minlen":4, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"cgetfile", "minlen":2, "flags":"TRLBAR|FILE1", "parser":"parse_cmd_common"}, {"name":"cgetbuffer", "minlen":5, "flags":"RANGE|WORD1|TRLBAR", "parser":"parse_cmd_common"}, {"name":"cgetexpr", "minlen":5, "flags":"NEEDARG|WORD1|NOTRLCOM|EXPR_ARG", "parser":"parse_cmd_common"}, {"name":"chdir", "minlen":3, "flags":"BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"changes", "minlen":7, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"checkpath", "minlen":3, "flags":"TRLBAR|BANG|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"checktime", "minlen":6, "flags":"RANGE|BUFNAME|COUNT|EXTRA|TRLBAR", "parser":"parse_cmd_common"}, {"name":"chistory", "minlen":3, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"clist", "minlen":2, "flags":"BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"clast", "minlen":3, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"class", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"close", "minlen":3, "flags":"BANG|RANGE|COUNT|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"clearjumps", "minlen":3, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"cmap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"cmapclear", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"cmenu", "minlen":3, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"cnext", "minlen":2, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"cnewer", "minlen":4, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"cnfile", "minlen":3, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"cnoremap", "minlen":3, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"cnoreabbrev", "minlen":6, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"cnoremenu", "minlen":7, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"copy", "minlen":2, "flags":"RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"colder", "minlen":3, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"colorscheme", "minlen":4, "flags":"WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"command", "minlen":3, "flags":"EXTRA|BANG|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"comclear", "minlen":4, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"compiler", "minlen":4, "flags":"BANG|TRLBAR|WORD1|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"continue", "minlen":3, "flags":"TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_continue"}, {"name":"confirm", "minlen":4, "flags":"NEEDARG|EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"const", "minlen":4, "flags":"EXTRA|BANG|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_const"}, {"name":"copen", "minlen":4, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"cprevious", "minlen":2, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"cpfile", "minlen":3, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"cquit", "minlen":2, "flags":"RANGE|COUNT|ZEROR|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"crewind", "minlen":2, "flags":"RANGE|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|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"cunabbrev", "minlen":4, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"cunmenu", "minlen":5, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"cwindow", "minlen":2, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"delete", "minlen":1, "flags":"RANGE|WHOLEFOLD|REGSTR|COUNT|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"delmarks", "minlen":4, "flags":"BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"debug", "minlen":3, "flags":"NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"debuggreedy", "minlen":6, "flags":"RANGE|ZEROR|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"def", "minlen":3, "flags":"EXTRA|BANG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_def"}, {"name":"defer", "minlen":4, "flags":"NEEDARG|EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"defcompile", "minlen":4, "flags":"SBOXOK|CMDWIN|LOCK_OK|TRLBAR", "parser":"parse_cmd_common"}, {"name":"delcommand", "minlen":4, "flags":"NEEDARG|WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"delfunction", "minlen":4, "flags":"BANG|NEEDARG|WORD1|CMDWIN|LOCK_OK", "parser":"parse_cmd_delfunction"}, {"name":"display", "minlen":2, "flags":"EXTRA|NOTRLCOM|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"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":"BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"disassemble", "minlen":4, "flags":"BANG|EXTRA|NEEDARG|TRLBAR|CMDWIN|LOCK_OK", "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|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"doautocmd", "minlen":2, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"doautoall", "minlen":7, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"drop", "minlen":2, "flags":"FILES|CMDARG|NEEDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"dsearch", "minlen":2, "flags":"BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK", "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|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"earlier", "minlen":2, "flags":"TRLBAR|EXTRA|NOSPC|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"echo", "minlen":2, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_echo"}, {"name":"echoerr", "minlen":5, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_echoerr"}, {"name":"echohl", "minlen":5, "flags":"EXTRA|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_echohl"}, {"name":"echomsg", "minlen":5, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_echomsg"}, {"name":"echoconsole", "minlen":5, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_echoconsole"}, {"name":"echowindow", "minlen":5, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"echon", "minlen":5, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_echon"}, {"name":"else", "minlen":2, "flags":"TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_else"}, {"name":"elseif", "minlen":5, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_elseif"}, {"name":"emenu", "minlen":2, "flags":"NEEDARG|EXTRA|TRLBAR|NOTRLCOM|RANGE|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"endif", "minlen":2, "flags":"TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_endif"}, {"name":"endinterface", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"endclass", "minlen":4, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"enddef", "minlen":4, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_enddef"}, {"name":"endenum", "minlen":4, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"endfunction", "minlen":4, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_endfunction"}, {"name":"endfor", "minlen":5, "flags":"TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_endfor"}, {"name":"endtry", "minlen":4, "flags":"TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_endtry"}, {"name":"endwhile", "minlen":4, "flags":"TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_endwhile"}, {"name":"enew", "minlen":3, "flags":"BANG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"enum", "minlen":3, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"eval", "minlen":2, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_eval"}, {"name":"ex", "minlen":2, "flags":"BANG|FILE1|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"execute", "minlen":3, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_execute"}, {"name":"exit", "minlen":3, "flags":"RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"export", "minlen":3, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|CMDWIN|LOCK_OK", "parser":"parse_cmd_export"}, {"name":"exusage", "minlen":3, "flags":"TRLBAR", "parser":"parse_cmd_common"}, {"name":"file", "minlen":1, "flags":"RANGE|ZEROR|BANG|FILE1|TRLBAR", "parser":"parse_cmd_common"}, {"name":"files", "minlen":5, "flags":"BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"filetype", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"filter", "minlen":4, "flags":"BANG|NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"find", "minlen":3, "flags":"RANGE|BANG|FILE1|CMDARG|ARGOPT|TRLBAR|NEEDARG", "parser":"parse_cmd_common"}, {"name":"final", "minlen":4, "flags":"EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_final"}, {"name":"finally", "minlen":6, "flags":"TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_finally"}, {"name":"finish", "minlen":4, "flags":"TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_finish"}, {"name":"first", "minlen":3, "flags":"EXTRA|BANG|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"fixdel", "minlen":3, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"fold", "minlen":2, "flags":"RANGE|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"foldclose", "minlen":5, "flags":"RANGE|BANG|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "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|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"for", "minlen":3, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_for"}, {"name":"function", "minlen":2, "flags":"EXTRA|BANG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_function"}, {"name":"global", "minlen":1, "flags":"RANGE|WHOLEFOLD|BANG|EXTRA|DFLALL|SBOXOK|CMDWIN|LOCK_OK|NONWHITE_OK", "parser":"parse_cmd_common"}, {"name":"goto", "minlen":2, "flags":"RANGE|COUNT|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"grep", "minlen":2, "flags":"RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE", "parser":"parse_cmd_common"}, {"name":"grepadd", "minlen":5, "flags":"RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE", "parser":"parse_cmd_common"}, {"name":"gui", "minlen":2, "flags":"BANG|FILES|CMDARG|ARGOPT|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"gvim", "minlen":2, "flags":"BANG|FILES|CMDARG|ARGOPT|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"help", "minlen":1, "flags":"BANG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"helpclose", "minlen":5, "flags":"RANGE|COUNT|TRLBAR", "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|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"hardcopy", "minlen":2, "flags":"RANGE|COUNT|EXTRA|EXPAND|TRLBAR|DFLALL|BANG", "parser":"parse_cmd_common"}, {"name":"highlight", "minlen":2, "flags":"BANG|EXTRA|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"hide", "minlen":3, "flags":"BANG|RANGE|COUNT|EXTRA|TRLBAR", "parser":"parse_cmd_common"}, {"name":"history", "minlen":3, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"horizontal", "minlen":2, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"insert", "minlen":1, "flags":"BANG|RANGE|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_insert"}, {"name":"iabbrev", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"iabclear", "minlen":4, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"if", "minlen":2, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "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|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"imap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"imapclear", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"imenu", "minlen":3, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"import", "minlen":3, "flags":"EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser":"parse_cmd_import"}, {"name":"inoremap", "minlen":3, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"inoreabbrev", "minlen":6, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"inoremenu", "minlen":7, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"intro", "minlen":3, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"interface", "minlen":4, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"isearch", "minlen":2, "flags":"BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK", "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|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"iunabbrev", "minlen":4, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"iunmenu", "minlen":5, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"join", "minlen":1, "flags":"BANG|RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"jumps", "minlen":2, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"k", "minlen":1, "flags":"RANGE|WORD1|TRLBAR|SBOXOK|CMDWIN|LOCK_OK|NONWHITE_OK", "parser":"parse_cmd_common"}, {"name":"keepmarks", "minlen":2, "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":"keepalt", "minlen":5, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"list", "minlen":1, "flags":"RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"lNext", "minlen":2, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"lNfile", "minlen":3, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"last", "minlen":2, "flags":"EXTRA|BANG|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"labove", "minlen":3, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"language", "minlen":3, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"laddexpr", "minlen":3, "flags":"NEEDARG|WORD1|NOTRLCOM|EXPR_ARG", "parser":"parse_cmd_common"}, {"name":"laddbuffer", "minlen":5, "flags":"RANGE|WORD1|TRLBAR", "parser":"parse_cmd_common"}, {"name":"laddfile", "minlen":5, "flags":"TRLBAR|FILE1", "parser":"parse_cmd_common"}, {"name":"lafter", "minlen":3, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"later", "minlen":3, "flags":"TRLBAR|EXTRA|NOSPC|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"lbuffer", "minlen":2, "flags":"BANG|RANGE|WORD1|TRLBAR", "parser":"parse_cmd_common"}, {"name":"lbefore", "minlen":3, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"lbelow", "minlen":4, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"lbottom", "minlen":3, "flags":"TRLBAR", "parser":"parse_cmd_common"}, {"name":"lcd", "minlen":2, "flags":"BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"lchdir", "minlen":3, "flags":"BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"lclose", "minlen":3, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"lcscope", "minlen":3, "flags":"EXTRA|NOTRLCOM|XFILE", "parser":"parse_cmd_common"}, {"name":"ldo", "minlen":2, "flags":"BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser":"parse_cmd_common"}, {"name":"left", "minlen":2, "flags":"TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"leftabove", "minlen":5, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"let", "minlen":3, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_let"}, {"name":"lexpr", "minlen":3, "flags":"NEEDARG|WORD1|NOTRLCOM|EXPR_ARG|BANG", "parser":"parse_cmd_common"}, {"name":"legacy", "minlen":3, "flags":"NEEDARG|EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"lfile", "minlen":2, "flags":"TRLBAR|FILE1|BANG", "parser":"parse_cmd_common"}, {"name":"lfdo", "minlen":3, "flags":"BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser":"parse_cmd_common"}, {"name":"lfirst", "minlen":4, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"lgetfile", "minlen":2, "flags":"TRLBAR|FILE1", "parser":"parse_cmd_common"}, {"name":"lgetbuffer", "minlen":5, "flags":"RANGE|WORD1|TRLBAR", "parser":"parse_cmd_common"}, {"name":"lgetexpr", "minlen":5, "flags":"NEEDARG|WORD1|NOTRLCOM|EXPR_ARG", "parser":"parse_cmd_common"}, {"name":"lgrep", "minlen":3, "flags":"RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE", "parser":"parse_cmd_common"}, {"name":"lgrepadd", "minlen":6, "flags":"RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE", "parser":"parse_cmd_common"}, {"name":"lhelpgrep", "minlen":2, "flags":"EXTRA|NOTRLCOM|NEEDARG", "parser":"parse_cmd_common"}, {"name":"lhistory", "minlen":3, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"ll", "minlen":2, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"llast", "minlen":3, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"llist", "minlen":3, "flags":"BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"lmap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"lmapclear", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"lmake", "minlen":4, "flags":"BANG|EXTRA|NOTRLCOM|TRLBAR|XFILE", "parser":"parse_cmd_common"}, {"name":"lnoremap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"lnext", "minlen":3, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"lnewer", "minlen":4, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"lnfile", "minlen":3, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"loadview", "minlen":2, "flags":"FILE1|TRLBAR", "parser":"parse_cmd_common"}, {"name":"loadkeymap", "minlen":5, "flags":"CMDWIN|LOCK_OK", "parser":"parse_cmd_loadkeymap"}, {"name":"lockmarks", "minlen":3, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"lockvar", "minlen":5, "flags":"BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_lockvar"}, {"name":"lolder", "minlen":3, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"lopen", "minlen":3, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"lprevious", "minlen":2, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"lpfile", "minlen":3, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"lrewind", "minlen":2, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"ltag", "minlen":2, "flags":"TRLBAR|BANG|WORD1", "parser":"parse_cmd_common"}, {"name":"lunmap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"lua", "minlen":3, "flags":"RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_lua"}, {"name":"luado", "minlen":4, "flags":"RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"luafile", "minlen":4, "flags":"RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"lvimgrep", "minlen":2, "flags":"RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"lvimgrepadd", "minlen":9, "flags":"RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"lwindow", "minlen":2, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"ls", "minlen":2, "flags":"BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"move", "minlen":1, "flags":"RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"mark", "minlen":2, "flags":"RANGE|WORD1|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "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|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"mapclear", "minlen":4, "flags":"EXTRA|BANG|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"marks", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"match", "minlen":3, "flags":"RANGE|EXTRA|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"menu", "minlen":2, "flags":"RANGE|ZEROR|BANG|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"menutranslate", "minlen":5, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"messages", "minlen":3, "flags":"EXTRA|TRLBAR|RANGE|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"mkexrc", "minlen":2, "flags":"BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "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|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"mkview", "minlen":5, "flags":"BANG|FILE1|TRLBAR", "parser":"parse_cmd_common"}, {"name":"mode", "minlen":3, "flags":"WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"mzscheme", "minlen":2, "flags":"RANGE|EXTRA|DFLALL|NEEDARG|CMDWIN|LOCK_OK|SBOXOK|RESTRICT", "parser":"parse_cmd_mzscheme"}, {"name":"mzfile", "minlen":3, "flags":"RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"next", "minlen":1, "flags":"RANGE|BANG|FILES|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"nbkey", "minlen":2, "flags":"EXTRA|NEEDARG", "parser":"parse_cmd_common"}, {"name":"nbclose", "minlen":3, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"nbstart", "minlen":3, "flags":"WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"new", "minlen":3, "flags":"BANG|FILE1|RANGE|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"nmap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"nmapclear", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"nmenu", "minlen":3, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"nnoremap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"nnoremenu", "minlen":7, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"noremap", "minlen":2, "flags":"BANG|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"noautocmd", "minlen":3, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"nohlsearch", "minlen":3, "flags":"TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"noreabbrev", "minlen":5, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"noremenu", "minlen":6, "flags":"RANGE|ZEROR|BANG|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"noswapfile", "minlen":3, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"normal", "minlen":4, "flags":"RANGE|BANG|EXTRA|NEEDARG|NOTRLCOM|CTRLV|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"number", "minlen":2, "flags":"RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"nunmap", "minlen":3, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"nunmenu", "minlen":5, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"open", "minlen":1, "flags":"RANGE|BANG|EXTRA", "parser":"parse_cmd_common"}, {"name":"oldfiles", "minlen":2, "flags":"BANG|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"omap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"omapclear", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"omenu", "minlen":3, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"only", "minlen":2, "flags":"BANG|RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"onoremap", "minlen":3, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"onoremenu", "minlen":7, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"options", "minlen":3, "flags":"TRLBAR", "parser":"parse_cmd_common"}, {"name":"ounmap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"ounmenu", "minlen":5, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"ownsyntax", "minlen":2, "flags":"EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"print", "minlen":1, "flags":"RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK|SBOXOK", "parser":"parse_cmd_common"}, {"name":"packadd", "minlen":2, "flags":"BANG|FILE1|NEEDARG|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"packloadall", "minlen":5, "flags":"BANG|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"pclose", "minlen":2, "flags":"BANG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"perl", "minlen":2, "flags":"RANGE|EXTRA|DFLALL|NEEDARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_perl"}, {"name":"perldo", "minlen":5, "flags":"RANGE|EXTRA|DFLALL|NEEDARG|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"pedit", "minlen":3, "flags":"BANG|FILE1|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"pop", "minlen":2, "flags":"RANGE|BANG|COUNT|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"popup", "minlen":4, "flags":"NEEDARG|EXTRA|BANG|TRLBAR|NOTRLCOM|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"ppop", "minlen":2, "flags":"RANGE|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|COUNT|BANG|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"promptfind", "minlen":3, "flags":"EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"promptrepl", "minlen":7, "flags":"EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"profile", "minlen":4, "flags":"BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"profdel", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"psearch", "minlen":2, "flags":"BANG|RANGE|WHOLEFOLD|DFLALL|EXTRA", "parser":"parse_cmd_common"}, {"name":"ptag", "minlen":2, "flags":"RANGE|BANG|WORD1|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"ptNext", "minlen":3, "flags":"RANGE|BANG|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"ptfirst", "minlen":3, "flags":"RANGE|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|BANG|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"ptprevious", "minlen":3, "flags":"RANGE|BANG|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"ptrewind", "minlen":3, "flags":"RANGE|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|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"pwd", "minlen":2, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"python", "minlen":2, "flags":"RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_python"}, {"name":"pydo", "minlen":3, "flags":"RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"pyfile", "minlen":3, "flags":"RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"py3", "minlen":3, "flags":"RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_python3"}, {"name":"py3do", "minlen":4, "flags":"RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"python3", "minlen":7, "flags":"RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_python3"}, {"name":"py3file", "minlen":4, "flags":"RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"pyx", "minlen":3, "flags":"RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"pyxdo", "minlen":4, "flags":"RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"pythonx", "minlen":7, "flags":"RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"pyxfile", "minlen":4, "flags":"RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"quit", "minlen":1, "flags":"BANG|RANGE|COUNT|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"quitall", "minlen":5, "flags":"BANG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"qall", "minlen":2, "flags":"BANG|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"read", "minlen":1, "flags":"BANG|RANGE|WHOLEFOLD|FILE1|ARGOPT|TRLBAR|ZEROR|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"recover", "minlen":3, "flags":"BANG|FILE1|TRLBAR", "parser":"parse_cmd_common"}, {"name":"redo", "minlen":3, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"redir", "minlen":4, "flags":"BANG|FILES|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"redraw", "minlen":4, "flags":"BANG|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"redrawstatus", "minlen":7, "flags":"BANG|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"redrawtabline", "minlen":7, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"registers", "minlen":3, "flags":"EXTRA|NOTRLCOM|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"resize", "minlen":3, "flags":"RANGE|TRLBAR|WORD1|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"retab", "minlen":3, "flags":"TRLBAR|RANGE|WHOLEFOLD|DFLALL|BANG|WORD1|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"return", "minlen":4, "flags":"EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_return"}, {"name":"rewind", "minlen":3, "flags":"EXTRA|BANG|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"right", "minlen":2, "flags":"TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"rightbelow", "minlen":6, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"runtime", "minlen":2, "flags":"BANG|NEEDARG|FILES|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"ruby", "minlen":3, "flags":"RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_ruby"}, {"name":"rubydo", "minlen":5, "flags":"RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"rubyfile", "minlen":5, "flags":"RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"rundo", "minlen":4, "flags":"NEEDARG|FILE1", "parser":"parse_cmd_common"}, {"name":"rviminfo", "minlen":2, "flags":"BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"substitute", "minlen":1, "flags":"RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|NONWHITE_OK", "parser":"parse_cmd_common"}, {"name":"sNext", "minlen":2, "flags":"EXTRA|RANGE|COUNT|BANG|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sargument", "minlen":2, "flags":"BANG|RANGE|COUNT|EXTRA|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sall", "minlen":3, "flags":"BANG|RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sandbox", "minlen":3, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"saveas", "minlen":3, "flags":"BANG|FILE1|ARGOPT|CMDWIN|LOCK_OK|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sbuffer", "minlen":2, "flags":"BANG|RANGE|BUFNAME|BUFUNL|COUNT|EXTRA|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sbNext", "minlen":3, "flags":"RANGE|COUNT|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sball", "minlen":3, "flags":"RANGE|COUNT|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sbfirst", "minlen":3, "flags":"CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sblast", "minlen":3, "flags":"CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sbmodified", "minlen":3, "flags":"RANGE|COUNT|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sbnext", "minlen":3, "flags":"RANGE|COUNT|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sbprevious", "minlen":3, "flags":"RANGE|COUNT|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sbrewind", "minlen":3, "flags":"CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"scriptnames", "minlen":2, "flags":"BANG|RANGE|COUNT|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"scriptencoding", "minlen":7, "flags":"WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"scriptversion", "minlen":7, "flags":"WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"scscope", "minlen":3, "flags":"EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"set", "minlen":2, "flags":"BANG|TRLBAR|EXTRA|CMDWIN|LOCK_OK|SBOXOK", "parser":"parse_cmd_common"}, {"name":"setfiletype", "minlen":4, "flags":"TRLBAR|EXTRA|NEEDARG|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"setglobal", "minlen":4, "flags":"BANG|TRLBAR|EXTRA|CMDWIN|LOCK_OK|SBOXOK", "parser":"parse_cmd_common"}, {"name":"setlocal", "minlen":4, "flags":"BANG|TRLBAR|EXTRA|CMDWIN|LOCK_OK|SBOXOK", "parser":"parse_cmd_common"}, {"name":"sfind", "minlen":2, "flags":"BANG|FILE1|RANGE|CMDARG|ARGOPT|TRLBAR|NEEDARG", "parser":"parse_cmd_common"}, {"name":"sfirst", "minlen":4, "flags":"EXTRA|BANG|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"shell", "minlen":2, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"simalt", "minlen":2, "flags":"NEEDARG|WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"sign", "minlen":3, "flags":"NEEDARG|RANGE|EXTRA|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"silent", "minlen":3, "flags":"NEEDARG|EXTRA|BANG|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"sleep", "minlen":2, "flags":"BANG|RANGE|COUNT|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"slast", "minlen":3, "flags":"EXTRA|BANG|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"smagic", "minlen":2, "flags":"RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|NONWHITE_OK", "parser":"parse_cmd_common"}, {"name":"smap", "minlen":4, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"smapclear", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"smenu", "minlen":3, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"snext", "minlen":2, "flags":"RANGE|BANG|FILES|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"snomagic", "minlen":3, "flags":"RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|NONWHITE_OK", "parser":"parse_cmd_common"}, {"name":"snoremap", "minlen":4, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"snoremenu", "minlen":7, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"source", "minlen":2, "flags":"BANG|FILE1|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"sort", "minlen":3, "flags":"RANGE|DFLALL|WHOLEFOLD|BANG|EXTRA|NOTRLCOM|MODIFY", "parser":"parse_cmd_common"}, {"name":"split", "minlen":2, "flags":"BANG|FILE1|RANGE|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"spellgood", "minlen":3, "flags":"BANG|RANGE|NEEDARG|EXTRA|TRLBAR", "parser":"parse_cmd_common"}, {"name":"spelldump", "minlen":6, "flags":"BANG|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":"spellrare", "minlen":7, "flags":"BANG|RANGE|NEEDARG|EXTRA|TRLBAR", "parser":"parse_cmd_common"}, {"name":"spellundo", "minlen":6, "flags":"BANG|RANGE|NEEDARG|EXTRA|TRLBAR", "parser":"parse_cmd_common"}, {"name":"spellwrong", "minlen":6, "flags":"BANG|RANGE|NEEDARG|EXTRA|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sprevious", "minlen":3, "flags":"EXTRA|RANGE|COUNT|BANG|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"srewind", "minlen":2, "flags":"EXTRA|BANG|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"stop", "minlen":2, "flags":"TRLBAR|BANG|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"stag", "minlen":3, "flags":"RANGE|BANG|WORD1|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"startinsert", "minlen":4, "flags":"BANG|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"startgreplace", "minlen":6, "flags":"BANG|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"startreplace", "minlen":6, "flags":"BANG|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"static", "minlen":4, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"stopinsert", "minlen":5, "flags":"BANG|TRLBAR|CMDWIN|LOCK_OK", "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|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sunmap", "minlen":4, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"sunmenu", "minlen":5, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"suspend", "minlen":3, "flags":"TRLBAR|BANG|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"sview", "minlen":2, "flags":"BANG|FILE1|RANGE|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"swapname", "minlen":2, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"syntax", "minlen":2, "flags":"EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser":"parse_cmd_syntax"}, {"name":"syntime", "minlen":5, "flags":"NEEDARG|WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"syncbind", "minlen":4, "flags":"TRLBAR", "parser":"parse_cmd_common"}, {"name":"smile", "minlen":3, "flags":"TRLBAR|CMDWIN|LOCK_OK|SBOXOK", "parser":"parse_cmd_common"}, {"name":"t", "minlen":1, "flags":"RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"tNext", "minlen":2, "flags":"RANGE|BANG|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"tag", "minlen":2, "flags":"RANGE|BANG|WORD1|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"tags", "minlen":4, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tab", "minlen":3, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"tabclose", "minlen":4, "flags":"BANG|RANGE|ZEROR|EXTRA|NOSPC|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tabdo", "minlen":4, "flags":"NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser":"parse_cmd_common"}, {"name":"tabedit", "minlen":4, "flags":"BANG|FILE1|RANGE|ZEROR|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"tabfind", "minlen":4, "flags":"BANG|FILE1|RANGE|ZEROR|CMDARG|ARGOPT|NEEDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"tabfirst", "minlen":6, "flags":"TRLBAR", "parser":"parse_cmd_common"}, {"name":"tabmove", "minlen":4, "flags":"RANGE|ZEROR|EXTRA|NOSPC|TRLBAR", "parser":"parse_cmd_common"}, {"name":"tablast", "minlen":4, "flags":"TRLBAR", "parser":"parse_cmd_common"}, {"name":"tabnext", "minlen":4, "flags":"RANGE|ZEROR|EXTRA|NOSPC|TRLBAR", "parser":"parse_cmd_common"}, {"name":"tabnew", "minlen":6, "flags":"BANG|FILE1|RANGE|ZEROR|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"tabonly", "minlen":4, "flags":"BANG|RANGE|ZEROR|EXTRA|NOSPC|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tabprevious", "minlen":4, "flags":"RANGE|ZEROR|EXTRA|NOSPC|TRLBAR", "parser":"parse_cmd_common"}, {"name":"tabNext", "minlen":4, "flags":"RANGE|ZEROR|EXTRA|NOSPC|TRLBAR", "parser":"parse_cmd_common"}, {"name":"tabrewind", "minlen":4, "flags":"TRLBAR", "parser":"parse_cmd_common"}, {"name":"tabs", "minlen":4, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tcd", "minlen":2, "flags":"BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tchdir", "minlen":3, "flags":"BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tcl", "minlen":3, "flags":"RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_tcl"}, {"name":"tcldo", "minlen":4, "flags":"RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"tclfile", "minlen":4, "flags":"RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"tearoff", "minlen":2, "flags":"NEEDARG|EXTRA|TRLBAR|NOTRLCOM|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"terminal", "minlen":3, "flags":"RANGE|BANG|FILES|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tfirst", "minlen":2, "flags":"RANGE|BANG|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"throw", "minlen":2, "flags":"EXTRA|NEEDARG|SBOXOK|CMDWIN|LOCK_OK", "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":"tlmenu", "minlen":3, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tlnoremenu", "minlen":3, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tlunmenu", "minlen":3, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tmenu", "minlen":2, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tmap", "minlen":3, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tmapclear", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tnext", "minlen":2, "flags":"RANGE|BANG|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"tnoremap", "minlen":3, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"topleft", "minlen":2, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"tprevious", "minlen":2, "flags":"RANGE|BANG|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"trewind", "minlen":2, "flags":"RANGE|BANG|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"try", "minlen":3, "flags":"TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_try"}, {"name":"tselect", "minlen":2, "flags":"BANG|TRLBAR|WORD1", "parser":"parse_cmd_common"}, {"name":"tunmenu", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tunmap", "minlen":5, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"type", "minlen":2, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"undo", "minlen":1, "flags":"RANGE|COUNT|ZEROR|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"undojoin", "minlen":5, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"undolist", "minlen":5, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"unabbreviate", "minlen":3, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"unhide", "minlen":3, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"unlet", "minlen":3, "flags":"BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_unlet"}, {"name":"unlockvar", "minlen":4, "flags":"BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_unlockvar"}, {"name":"unmap", "minlen":3, "flags":"BANG|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"unmenu", "minlen":4, "flags":"BANG|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"unsilent", "minlen":3, "flags":"NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "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|LOCK_OK|NONWHITE_OK", "parser":"parse_cmd_common"}, {"name":"var", "minlen":2, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_var"}, {"name":"version", "minlen":2, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"verbose", "minlen":4, "flags":"NEEDARG|RANGE|EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"vertical", "minlen":4, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"visual", "minlen":2, "flags":"BANG|FILE1|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"view", "minlen":3, "flags":"BANG|FILE1|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"vimgrep", "minlen":3, "flags":"RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"vimgrepadd", "minlen":8, "flags":"RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"vim9cmd", "minlen":4, "flags":"NEEDARG|EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"vim9script", "minlen":5, "flags":"WORD1|CMDWIN|LOCK_OK", "parser":"parse_cmd_vim9script"}, {"name":"viusage", "minlen":3, "flags":"TRLBAR", "parser":"parse_cmd_common"}, {"name":"vmap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"vmapclear", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"vmenu", "minlen":3, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"vnoremap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"vnew", "minlen":3, "flags":"BANG|FILE1|RANGE|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"vnoremenu", "minlen":7, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"vsplit", "minlen":2, "flags":"BANG|FILE1|RANGE|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"vunmap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"vunmenu", "minlen":5, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"write", "minlen":1, "flags":"RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"wNext", "minlen":2, "flags":"RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"wall", "minlen":2, "flags":"BANG|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"while", "minlen":2, "flags":"EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_while"}, {"name":"winsize", "minlen":2, "flags":"EXTRA|NEEDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"wincmd", "minlen":4, "flags":"NEEDARG|WORD1|RANGE|CMDWIN|LOCK_OK", "parser":"parse_wincmd"}, {"name":"windo", "minlen":4, "flags":"NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser":"parse_cmd_common"}, {"name":"winpos", "minlen":4, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"wnext", "minlen":2, "flags":"RANGE|BANG|FILE1|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"wprevious", "minlen":2, "flags":"RANGE|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|TRLBAR", "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|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"xit", "minlen":1, "flags":"RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"xall", "minlen":2, "flags":"BANG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"xmap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"xmapclear", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"xmenu", "minlen":3, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"xnoremap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"xnoremenu", "minlen":7, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"xrestore", "minlen":2, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"xunmap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"xunmenu", "minlen":5, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"yank", "minlen":1, "flags":"RANGE|WHOLEFOLD|REGSTR|COUNT|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"z", "minlen":1, "flags":"RANGE|WHOLEFOLD|BANG|EXTRA|FLAGS|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"!", "minlen":1, "flags":"RANGE|WHOLEFOLD|BANG|FILES|CMDWIN|LOCK_OK|NONWHITE_OK", "parser":"parse_cmd_common"}, {"name":"#", "minlen":1, "flags":"RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"&", "minlen":1, "flags":"RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|MODIFY|NONWHITE_OK", "parser":"parse_cmd_common"}, {"name":"*", "minlen":1, "flags":"RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|LOCK_OK|NONWHITE_OK", "parser":"parse_cmd_common"}, {"name":"<", "minlen":1, "flags":"RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"=", "minlen":1, "flags":"RANGE|TRLBAR|DFLALL|FLAGS|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":">", "minlen":1, "flags":"RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"@", "minlen":1, "flags":"RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|LOCK_OK|NONWHITE_OK", "parser":"parse_cmd_common"}, {"name":"{", "minlen":1, "flags":"TRLBAR|LOCK_OK|CMDWIN", "parser":"parse_cmd_common"}, {"name":"}", "minlen":1, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"~", "minlen":1, "flags":"RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|MODIFY|NONWHITE_OK", "parser":"parse_cmd_common"}, {"name":"Next", "minlen":1, "flags":"EXTRA|RANGE|COUNT|BANG|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"Print", "minlen":1, "flags":"RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"X", "minlen":1, "flags":"TRLBAR", "parser":"parse_cmd_common"}, {"name":"++", "minlen":1, "flags":"EXTRA|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"--", "minlen":1, "flags":"EXTRA|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}]; +VimLParser.prototype.builtin_commands = [{"name":"append", "minlen":1, "flags":"BANG|RANGE|ZEROR|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_append"}, {"name":"abbreviate", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"abclear", "minlen":3, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"aboveleft", "minlen":3, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"abstract", "minlen":3, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_abstract"}, {"name":"all", "minlen":2, "flags":"BANG|RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"amenu", "minlen":2, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"anoremenu", "minlen":2, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"args", "minlen":2, "flags":"BANG|FILES|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"argadd", "minlen":4, "flags":"BANG|RANGE|ZEROR|FILES|TRLBAR", "parser":"parse_cmd_common"}, {"name":"argdelete", "minlen":4, "flags":"BANG|RANGE|FILES|TRLBAR", "parser":"parse_cmd_common"}, {"name":"argdo", "minlen":5, "flags":"BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser":"parse_cmd_common"}, {"name":"argdedupe", "minlen":6, "flags":"TRLBAR", "parser":"parse_cmd_common"}, {"name":"argedit", "minlen":4, "flags":"BANG|NEEDARG|RANGE|ZEROR|FILES|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"argglobal", "minlen":4, "flags":"BANG|FILES|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"arglocal", "minlen":4, "flags":"BANG|FILES|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"argument", "minlen":4, "flags":"BANG|RANGE|COUNT|EXTRA|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"ascii", "minlen":2, "flags":"TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"autocmd", "minlen":2, "flags":"BANG|EXTRA|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"augroup", "minlen":3, "flags":"BANG|WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"aunmenu", "minlen":3, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"buffer", "minlen":1, "flags":"BANG|RANGE|BUFNAME|BUFUNL|COUNT|EXTRA|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"bNext", "minlen":2, "flags":"BANG|RANGE|COUNT|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"ball", "minlen":2, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"badd", "minlen":3, "flags":"NEEDARG|FILE1|CMDARG|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"balt", "minlen":4, "flags":"NEEDARG|FILE1|CMDARG|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"bdelete", "minlen":2, "flags":"BANG|RANGE|BUFNAME|COUNT|EXTRA|TRLBAR", "parser":"parse_cmd_common"}, {"name":"behave", "minlen":2, "flags":"BANG|NEEDARG|WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"belowright", "minlen":3, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"bfirst", "minlen":2, "flags":"BANG|RANGE|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"blast", "minlen":2, "flags":"BANG|RANGE|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"bmodified", "minlen":2, "flags":"BANG|RANGE|COUNT|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"bnext", "minlen":2, "flags":"BANG|RANGE|COUNT|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"botright", "minlen":2, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"bprevious", "minlen":2, "flags":"BANG|RANGE|COUNT|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"brewind", "minlen":2, "flags":"BANG|RANGE|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"break", "minlen":4, "flags":"TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_break"}, {"name":"breakadd", "minlen":6, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"breakdel", "minlen":6, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"breaklist", "minlen":6, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"browse", "minlen":3, "flags":"NEEDARG|EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"buffers", "minlen":7, "flags":"BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"bufdo", "minlen":4, "flags":"BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser":"parse_cmd_common"}, {"name":"bunload", "minlen":3, "flags":"BANG|RANGE|BUFNAME|COUNT|EXTRA|TRLBAR", "parser":"parse_cmd_common"}, {"name":"bwipeout", "minlen":2, "flags":"BANG|RANGE|BUFNAME|BUFUNL|COUNT|EXTRA|TRLBAR", "parser":"parse_cmd_common"}, {"name":"change", "minlen":1, "flags":"BANG|WHOLEFOLD|RANGE|COUNT|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"cNext", "minlen":2, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"cNfile", "minlen":3, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"cabbrev", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"cabclear", "minlen":4, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"cabove", "minlen":4, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"caddbuffer", "minlen":3, "flags":"RANGE|WORD1|TRLBAR", "parser":"parse_cmd_common"}, {"name":"caddexpr", "minlen":5, "flags":"NEEDARG|WORD1|NOTRLCOM|EXPR_ARG", "parser":"parse_cmd_common"}, {"name":"caddfile", "minlen":5, "flags":"TRLBAR|FILE1", "parser":"parse_cmd_common"}, {"name":"cafter", "minlen":3, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"call", "minlen":3, "flags":"RANGE|NEEDARG|EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_call"}, {"name":"catch", "minlen":3, "flags":"EXTRA|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_catch"}, {"name":"cbuffer", "minlen":2, "flags":"BANG|RANGE|WORD1|TRLBAR", "parser":"parse_cmd_common"}, {"name":"cbefore", "minlen":3, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"cbelow", "minlen":4, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"cbottom", "minlen":3, "flags":"TRLBAR", "parser":"parse_cmd_common"}, {"name":"cc", "minlen":2, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"cclose", "minlen":3, "flags":"TRLBAR", "parser":"parse_cmd_common"}, {"name":"cd", "minlen":2, "flags":"BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"cdo", "minlen":3, "flags":"BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser":"parse_cmd_common"}, {"name":"center", "minlen":2, "flags":"TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"cexpr", "minlen":3, "flags":"NEEDARG|WORD1|NOTRLCOM|EXPR_ARG|BANG", "parser":"parse_cmd_common"}, {"name":"cfile", "minlen":2, "flags":"TRLBAR|FILE1|BANG", "parser":"parse_cmd_common"}, {"name":"cfdo", "minlen":3, "flags":"BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser":"parse_cmd_common"}, {"name":"cfirst", "minlen":4, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"cgetfile", "minlen":2, "flags":"TRLBAR|FILE1", "parser":"parse_cmd_common"}, {"name":"cgetbuffer", "minlen":5, "flags":"RANGE|WORD1|TRLBAR", "parser":"parse_cmd_common"}, {"name":"cgetexpr", "minlen":5, "flags":"NEEDARG|WORD1|NOTRLCOM|EXPR_ARG", "parser":"parse_cmd_common"}, {"name":"chdir", "minlen":3, "flags":"BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"changes", "minlen":7, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"checkpath", "minlen":3, "flags":"TRLBAR|BANG|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"checktime", "minlen":6, "flags":"RANGE|BUFNAME|COUNT|EXTRA|TRLBAR", "parser":"parse_cmd_common"}, {"name":"chistory", "minlen":3, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"clist", "minlen":2, "flags":"BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"clast", "minlen":3, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"class", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_class"}, {"name":"close", "minlen":3, "flags":"BANG|RANGE|COUNT|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"clearjumps", "minlen":3, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"cmap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"cmapclear", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"cmenu", "minlen":3, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"cnext", "minlen":2, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"cnewer", "minlen":4, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"cnfile", "minlen":3, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"cnoremap", "minlen":3, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"cnoreabbrev", "minlen":6, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"cnoremenu", "minlen":7, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"copy", "minlen":2, "flags":"RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"colder", "minlen":3, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"colorscheme", "minlen":4, "flags":"WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"command", "minlen":3, "flags":"EXTRA|BANG|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"comclear", "minlen":4, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"compiler", "minlen":4, "flags":"BANG|TRLBAR|WORD1|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"continue", "minlen":3, "flags":"TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_continue"}, {"name":"confirm", "minlen":4, "flags":"NEEDARG|EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"const", "minlen":4, "flags":"EXTRA|BANG|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_const"}, {"name":"copen", "minlen":4, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"cprevious", "minlen":2, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"cpfile", "minlen":3, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"cquit", "minlen":2, "flags":"RANGE|COUNT|ZEROR|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"crewind", "minlen":2, "flags":"RANGE|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|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"cunabbrev", "minlen":4, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"cunmenu", "minlen":5, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"cwindow", "minlen":2, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"delete", "minlen":1, "flags":"RANGE|WHOLEFOLD|REGSTR|COUNT|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"delmarks", "minlen":4, "flags":"BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"debug", "minlen":3, "flags":"NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"debuggreedy", "minlen":6, "flags":"RANGE|ZEROR|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"def", "minlen":3, "flags":"EXTRA|BANG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_def"}, {"name":"defer", "minlen":4, "flags":"NEEDARG|EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_defer"}, {"name":"defcompile", "minlen":4, "flags":"SBOXOK|CMDWIN|LOCK_OK|TRLBAR", "parser":"parse_cmd_common"}, {"name":"delcommand", "minlen":4, "flags":"NEEDARG|WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"delfunction", "minlen":4, "flags":"BANG|NEEDARG|WORD1|CMDWIN|LOCK_OK", "parser":"parse_cmd_delfunction"}, {"name":"display", "minlen":2, "flags":"EXTRA|NOTRLCOM|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"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":"BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"disassemble", "minlen":4, "flags":"BANG|EXTRA|NEEDARG|TRLBAR|CMDWIN|LOCK_OK", "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|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"doautocmd", "minlen":2, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"doautoall", "minlen":7, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"drop", "minlen":2, "flags":"FILES|CMDARG|NEEDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"dsearch", "minlen":2, "flags":"BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK", "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|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"earlier", "minlen":2, "flags":"TRLBAR|EXTRA|NOSPC|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"echo", "minlen":2, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_echo"}, {"name":"echoerr", "minlen":5, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_echoerr"}, {"name":"echohl", "minlen":5, "flags":"EXTRA|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_echohl"}, {"name":"echomsg", "minlen":5, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_echomsg"}, {"name":"echoconsole", "minlen":5, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_echoconsole"}, {"name":"echowindow", "minlen":5, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_echowindow"}, {"name":"echon", "minlen":5, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_echon"}, {"name":"else", "minlen":2, "flags":"TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_else"}, {"name":"elseif", "minlen":5, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_elseif"}, {"name":"emenu", "minlen":2, "flags":"NEEDARG|EXTRA|TRLBAR|NOTRLCOM|RANGE|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"endif", "minlen":2, "flags":"TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_endif"}, {"name":"endinterface", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_endinterface"}, {"name":"endclass", "minlen":4, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_endclass"}, {"name":"enddef", "minlen":4, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_enddef"}, {"name":"endenum", "minlen":4, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_endenum"}, {"name":"endfunction", "minlen":4, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_endfunction"}, {"name":"endfor", "minlen":5, "flags":"TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_endfor"}, {"name":"endtry", "minlen":4, "flags":"TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_endtry"}, {"name":"endwhile", "minlen":4, "flags":"TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_endwhile"}, {"name":"enew", "minlen":3, "flags":"BANG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"enum", "minlen":3, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_enum"}, {"name":"eval", "minlen":2, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_eval"}, {"name":"ex", "minlen":2, "flags":"BANG|FILE1|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"execute", "minlen":3, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_execute"}, {"name":"exit", "minlen":3, "flags":"RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"export", "minlen":3, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|CMDWIN|LOCK_OK", "parser":"parse_cmd_export"}, {"name":"exusage", "minlen":3, "flags":"TRLBAR", "parser":"parse_cmd_common"}, {"name":"file", "minlen":1, "flags":"RANGE|ZEROR|BANG|FILE1|TRLBAR", "parser":"parse_cmd_common"}, {"name":"files", "minlen":5, "flags":"BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"filetype", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"filter", "minlen":4, "flags":"BANG|NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"find", "minlen":3, "flags":"RANGE|BANG|FILE1|CMDARG|ARGOPT|TRLBAR|NEEDARG", "parser":"parse_cmd_common"}, {"name":"final", "minlen":4, "flags":"EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_final"}, {"name":"finally", "minlen":6, "flags":"TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_finally"}, {"name":"finish", "minlen":4, "flags":"TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_finish"}, {"name":"first", "minlen":3, "flags":"EXTRA|BANG|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"fixdel", "minlen":3, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"fold", "minlen":2, "flags":"RANGE|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"foldclose", "minlen":5, "flags":"RANGE|BANG|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "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|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"for", "minlen":3, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_for"}, {"name":"function", "minlen":2, "flags":"EXTRA|BANG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_function"}, {"name":"global", "minlen":1, "flags":"RANGE|WHOLEFOLD|BANG|EXTRA|DFLALL|SBOXOK|CMDWIN|LOCK_OK|NONWHITE_OK", "parser":"parse_cmd_common"}, {"name":"goto", "minlen":2, "flags":"RANGE|COUNT|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"grep", "minlen":2, "flags":"RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE", "parser":"parse_cmd_common"}, {"name":"grepadd", "minlen":5, "flags":"RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE", "parser":"parse_cmd_common"}, {"name":"gui", "minlen":2, "flags":"BANG|FILES|CMDARG|ARGOPT|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"gvim", "minlen":2, "flags":"BANG|FILES|CMDARG|ARGOPT|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"help", "minlen":1, "flags":"BANG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"helpclose", "minlen":5, "flags":"RANGE|COUNT|TRLBAR", "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|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"hardcopy", "minlen":2, "flags":"RANGE|COUNT|EXTRA|EXPAND|TRLBAR|DFLALL|BANG", "parser":"parse_cmd_common"}, {"name":"highlight", "minlen":2, "flags":"BANG|EXTRA|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"hide", "minlen":3, "flags":"BANG|RANGE|COUNT|EXTRA|TRLBAR", "parser":"parse_cmd_common"}, {"name":"history", "minlen":3, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"horizontal", "minlen":2, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"insert", "minlen":1, "flags":"BANG|RANGE|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_insert"}, {"name":"iabbrev", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"iabclear", "minlen":4, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"if", "minlen":2, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "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|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"imap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"imapclear", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"imenu", "minlen":3, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"import", "minlen":3, "flags":"EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser":"parse_cmd_import"}, {"name":"inoremap", "minlen":3, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"inoreabbrev", "minlen":6, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"inoremenu", "minlen":7, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"intro", "minlen":3, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"interface", "minlen":4, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_interface"}, {"name":"isearch", "minlen":2, "flags":"BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK", "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|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"iunabbrev", "minlen":4, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"iunmenu", "minlen":5, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"join", "minlen":1, "flags":"BANG|RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"jumps", "minlen":2, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"k", "minlen":1, "flags":"RANGE|WORD1|TRLBAR|SBOXOK|CMDWIN|LOCK_OK|NONWHITE_OK", "parser":"parse_cmd_common"}, {"name":"keepmarks", "minlen":2, "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":"keepalt", "minlen":5, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"list", "minlen":1, "flags":"RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"lNext", "minlen":2, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"lNfile", "minlen":3, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"last", "minlen":2, "flags":"EXTRA|BANG|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"labove", "minlen":3, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"language", "minlen":3, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"laddexpr", "minlen":3, "flags":"NEEDARG|WORD1|NOTRLCOM|EXPR_ARG", "parser":"parse_cmd_common"}, {"name":"laddbuffer", "minlen":5, "flags":"RANGE|WORD1|TRLBAR", "parser":"parse_cmd_common"}, {"name":"laddfile", "minlen":5, "flags":"TRLBAR|FILE1", "parser":"parse_cmd_common"}, {"name":"lafter", "minlen":3, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"later", "minlen":3, "flags":"TRLBAR|EXTRA|NOSPC|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"lbuffer", "minlen":2, "flags":"BANG|RANGE|WORD1|TRLBAR", "parser":"parse_cmd_common"}, {"name":"lbefore", "minlen":3, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"lbelow", "minlen":4, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"lbottom", "minlen":3, "flags":"TRLBAR", "parser":"parse_cmd_common"}, {"name":"lcd", "minlen":2, "flags":"BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"lchdir", "minlen":3, "flags":"BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"lclose", "minlen":3, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"lcscope", "minlen":3, "flags":"EXTRA|NOTRLCOM|XFILE", "parser":"parse_cmd_common"}, {"name":"ldo", "minlen":2, "flags":"BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser":"parse_cmd_common"}, {"name":"left", "minlen":2, "flags":"TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"leftabove", "minlen":5, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"let", "minlen":3, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_let"}, {"name":"lexpr", "minlen":3, "flags":"NEEDARG|WORD1|NOTRLCOM|EXPR_ARG|BANG", "parser":"parse_cmd_common"}, {"name":"legacy", "minlen":3, "flags":"NEEDARG|EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"lfile", "minlen":2, "flags":"TRLBAR|FILE1|BANG", "parser":"parse_cmd_common"}, {"name":"lfdo", "minlen":3, "flags":"BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser":"parse_cmd_common"}, {"name":"lfirst", "minlen":4, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"lgetfile", "minlen":2, "flags":"TRLBAR|FILE1", "parser":"parse_cmd_common"}, {"name":"lgetbuffer", "minlen":5, "flags":"RANGE|WORD1|TRLBAR", "parser":"parse_cmd_common"}, {"name":"lgetexpr", "minlen":5, "flags":"NEEDARG|WORD1|NOTRLCOM|EXPR_ARG", "parser":"parse_cmd_common"}, {"name":"lgrep", "minlen":3, "flags":"RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE", "parser":"parse_cmd_common"}, {"name":"lgrepadd", "minlen":6, "flags":"RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE", "parser":"parse_cmd_common"}, {"name":"lhelpgrep", "minlen":2, "flags":"EXTRA|NOTRLCOM|NEEDARG", "parser":"parse_cmd_common"}, {"name":"lhistory", "minlen":3, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"ll", "minlen":2, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"llast", "minlen":3, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"llist", "minlen":3, "flags":"BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"lmap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"lmapclear", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"lmake", "minlen":4, "flags":"BANG|EXTRA|NOTRLCOM|TRLBAR|XFILE", "parser":"parse_cmd_common"}, {"name":"lnoremap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"lnext", "minlen":3, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"lnewer", "minlen":4, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"lnfile", "minlen":3, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"loadview", "minlen":2, "flags":"FILE1|TRLBAR", "parser":"parse_cmd_common"}, {"name":"loadkeymap", "minlen":5, "flags":"CMDWIN|LOCK_OK", "parser":"parse_cmd_loadkeymap"}, {"name":"lockmarks", "minlen":3, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"lockvar", "minlen":5, "flags":"BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_lockvar"}, {"name":"lolder", "minlen":3, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"lopen", "minlen":3, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"lprevious", "minlen":2, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"lpfile", "minlen":3, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"lrewind", "minlen":2, "flags":"RANGE|COUNT|TRLBAR|BANG", "parser":"parse_cmd_common"}, {"name":"ltag", "minlen":2, "flags":"TRLBAR|BANG|WORD1", "parser":"parse_cmd_common"}, {"name":"lunmap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"lua", "minlen":3, "flags":"RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_lua"}, {"name":"luado", "minlen":4, "flags":"RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"luafile", "minlen":4, "flags":"RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"lvimgrep", "minlen":2, "flags":"RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"lvimgrepadd", "minlen":9, "flags":"RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"lwindow", "minlen":2, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"ls", "minlen":2, "flags":"BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"move", "minlen":1, "flags":"RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"mark", "minlen":2, "flags":"RANGE|WORD1|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "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|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"mapclear", "minlen":4, "flags":"EXTRA|BANG|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"marks", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"match", "minlen":3, "flags":"RANGE|EXTRA|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"menu", "minlen":2, "flags":"RANGE|ZEROR|BANG|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"menutranslate", "minlen":5, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"messages", "minlen":3, "flags":"EXTRA|TRLBAR|RANGE|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"mkexrc", "minlen":2, "flags":"BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "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|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"mkview", "minlen":5, "flags":"BANG|FILE1|TRLBAR", "parser":"parse_cmd_common"}, {"name":"mode", "minlen":3, "flags":"WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"mzscheme", "minlen":2, "flags":"RANGE|EXTRA|DFLALL|NEEDARG|CMDWIN|LOCK_OK|SBOXOK|RESTRICT", "parser":"parse_cmd_mzscheme"}, {"name":"mzfile", "minlen":3, "flags":"RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"next", "minlen":1, "flags":"RANGE|BANG|FILES|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"nbkey", "minlen":2, "flags":"EXTRA|NEEDARG", "parser":"parse_cmd_common"}, {"name":"nbclose", "minlen":3, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"nbstart", "minlen":3, "flags":"WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"new", "minlen":3, "flags":"BANG|FILE1|RANGE|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"nmap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"nmapclear", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"nmenu", "minlen":3, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"nnoremap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"nnoremenu", "minlen":7, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"noremap", "minlen":2, "flags":"BANG|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"noautocmd", "minlen":3, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"nohlsearch", "minlen":3, "flags":"TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"noreabbrev", "minlen":5, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"noremenu", "minlen":6, "flags":"RANGE|ZEROR|BANG|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"noswapfile", "minlen":3, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"normal", "minlen":4, "flags":"RANGE|BANG|EXTRA|NEEDARG|NOTRLCOM|CTRLV|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"number", "minlen":2, "flags":"RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"nunmap", "minlen":3, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"nunmenu", "minlen":5, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"open", "minlen":1, "flags":"RANGE|BANG|EXTRA", "parser":"parse_cmd_common"}, {"name":"oldfiles", "minlen":2, "flags":"BANG|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"omap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"omapclear", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"omenu", "minlen":3, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"only", "minlen":2, "flags":"BANG|RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"onoremap", "minlen":3, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"onoremenu", "minlen":7, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"options", "minlen":3, "flags":"TRLBAR", "parser":"parse_cmd_common"}, {"name":"ounmap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"ounmenu", "minlen":5, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"ownsyntax", "minlen":2, "flags":"EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"print", "minlen":1, "flags":"RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK|SBOXOK", "parser":"parse_cmd_common"}, {"name":"packadd", "minlen":2, "flags":"BANG|FILE1|NEEDARG|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"packloadall", "minlen":5, "flags":"BANG|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"pclose", "minlen":2, "flags":"BANG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"perl", "minlen":2, "flags":"RANGE|EXTRA|DFLALL|NEEDARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_perl"}, {"name":"perldo", "minlen":5, "flags":"RANGE|EXTRA|DFLALL|NEEDARG|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"pedit", "minlen":3, "flags":"BANG|FILE1|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"pop", "minlen":2, "flags":"RANGE|BANG|COUNT|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"popup", "minlen":4, "flags":"NEEDARG|EXTRA|BANG|TRLBAR|NOTRLCOM|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"ppop", "minlen":2, "flags":"RANGE|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|COUNT|BANG|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"promptfind", "minlen":3, "flags":"EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"promptrepl", "minlen":7, "flags":"EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"profile", "minlen":4, "flags":"BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"profdel", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"psearch", "minlen":2, "flags":"BANG|RANGE|WHOLEFOLD|DFLALL|EXTRA", "parser":"parse_cmd_common"}, {"name":"ptag", "minlen":2, "flags":"RANGE|BANG|WORD1|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"ptNext", "minlen":3, "flags":"RANGE|BANG|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"ptfirst", "minlen":3, "flags":"RANGE|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|BANG|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"ptprevious", "minlen":3, "flags":"RANGE|BANG|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"ptrewind", "minlen":3, "flags":"RANGE|BANG|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"ptselect", "minlen":3, "flags":"BANG|TRLBAR|WORD1", "parser":"parse_cmd_common"}, {"name":"public", "minlen":3, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_public"}, {"name":"put", "minlen":2, "flags":"RANGE|WHOLEFOLD|BANG|REGSTR|TRLBAR|ZEROR|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"pwd", "minlen":2, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"python", "minlen":2, "flags":"RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_python"}, {"name":"pydo", "minlen":3, "flags":"RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"pyfile", "minlen":3, "flags":"RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"py3", "minlen":3, "flags":"RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_python3"}, {"name":"py3do", "minlen":4, "flags":"RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"python3", "minlen":7, "flags":"RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_python3"}, {"name":"py3file", "minlen":4, "flags":"RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"pyx", "minlen":3, "flags":"RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"pyxdo", "minlen":4, "flags":"RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"pythonx", "minlen":7, "flags":"RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"pyxfile", "minlen":4, "flags":"RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"quit", "minlen":1, "flags":"BANG|RANGE|COUNT|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"quitall", "minlen":5, "flags":"BANG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"qall", "minlen":2, "flags":"BANG|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"read", "minlen":1, "flags":"BANG|RANGE|WHOLEFOLD|FILE1|ARGOPT|TRLBAR|ZEROR|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"recover", "minlen":3, "flags":"BANG|FILE1|TRLBAR", "parser":"parse_cmd_common"}, {"name":"redo", "minlen":3, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"redir", "minlen":4, "flags":"BANG|FILES|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"redraw", "minlen":4, "flags":"BANG|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"redrawstatus", "minlen":7, "flags":"BANG|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"redrawtabline", "minlen":7, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"registers", "minlen":3, "flags":"EXTRA|NOTRLCOM|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"resize", "minlen":3, "flags":"RANGE|TRLBAR|WORD1|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"retab", "minlen":3, "flags":"TRLBAR|RANGE|WHOLEFOLD|DFLALL|BANG|WORD1|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"return", "minlen":4, "flags":"EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_return"}, {"name":"rewind", "minlen":3, "flags":"EXTRA|BANG|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"right", "minlen":2, "flags":"TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"rightbelow", "minlen":6, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"runtime", "minlen":2, "flags":"BANG|NEEDARG|FILES|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"ruby", "minlen":3, "flags":"RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_ruby"}, {"name":"rubydo", "minlen":5, "flags":"RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"rubyfile", "minlen":5, "flags":"RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"rundo", "minlen":4, "flags":"NEEDARG|FILE1", "parser":"parse_cmd_common"}, {"name":"rviminfo", "minlen":2, "flags":"BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"substitute", "minlen":1, "flags":"RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|NONWHITE_OK", "parser":"parse_cmd_common"}, {"name":"sNext", "minlen":2, "flags":"EXTRA|RANGE|COUNT|BANG|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sargument", "minlen":2, "flags":"BANG|RANGE|COUNT|EXTRA|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sall", "minlen":3, "flags":"BANG|RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sandbox", "minlen":3, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"saveas", "minlen":3, "flags":"BANG|FILE1|ARGOPT|CMDWIN|LOCK_OK|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sbuffer", "minlen":2, "flags":"BANG|RANGE|BUFNAME|BUFUNL|COUNT|EXTRA|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sbNext", "minlen":3, "flags":"RANGE|COUNT|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sball", "minlen":3, "flags":"RANGE|COUNT|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sbfirst", "minlen":3, "flags":"CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sblast", "minlen":3, "flags":"CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sbmodified", "minlen":3, "flags":"RANGE|COUNT|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sbnext", "minlen":3, "flags":"RANGE|COUNT|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sbprevious", "minlen":3, "flags":"RANGE|COUNT|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sbrewind", "minlen":3, "flags":"CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"scriptnames", "minlen":2, "flags":"BANG|RANGE|COUNT|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"scriptencoding", "minlen":7, "flags":"WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"scriptversion", "minlen":7, "flags":"WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"scscope", "minlen":3, "flags":"EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"set", "minlen":2, "flags":"BANG|TRLBAR|EXTRA|CMDWIN|LOCK_OK|SBOXOK", "parser":"parse_cmd_common"}, {"name":"setfiletype", "minlen":4, "flags":"TRLBAR|EXTRA|NEEDARG|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"setglobal", "minlen":4, "flags":"BANG|TRLBAR|EXTRA|CMDWIN|LOCK_OK|SBOXOK", "parser":"parse_cmd_common"}, {"name":"setlocal", "minlen":4, "flags":"BANG|TRLBAR|EXTRA|CMDWIN|LOCK_OK|SBOXOK", "parser":"parse_cmd_common"}, {"name":"sfind", "minlen":2, "flags":"BANG|FILE1|RANGE|CMDARG|ARGOPT|TRLBAR|NEEDARG", "parser":"parse_cmd_common"}, {"name":"sfirst", "minlen":4, "flags":"EXTRA|BANG|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"shell", "minlen":2, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"simalt", "minlen":2, "flags":"NEEDARG|WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"sign", "minlen":3, "flags":"NEEDARG|RANGE|EXTRA|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"silent", "minlen":3, "flags":"NEEDARG|EXTRA|BANG|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"sleep", "minlen":2, "flags":"BANG|RANGE|COUNT|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"slast", "minlen":3, "flags":"EXTRA|BANG|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"smagic", "minlen":2, "flags":"RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|NONWHITE_OK", "parser":"parse_cmd_common"}, {"name":"smap", "minlen":4, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"smapclear", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"smenu", "minlen":3, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"snext", "minlen":2, "flags":"RANGE|BANG|FILES|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"snomagic", "minlen":3, "flags":"RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|NONWHITE_OK", "parser":"parse_cmd_common"}, {"name":"snoremap", "minlen":4, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"snoremenu", "minlen":7, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"source", "minlen":2, "flags":"BANG|FILE1|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"sort", "minlen":3, "flags":"RANGE|DFLALL|WHOLEFOLD|BANG|EXTRA|NOTRLCOM|MODIFY", "parser":"parse_cmd_common"}, {"name":"split", "minlen":2, "flags":"BANG|FILE1|RANGE|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"spellgood", "minlen":3, "flags":"BANG|RANGE|NEEDARG|EXTRA|TRLBAR", "parser":"parse_cmd_common"}, {"name":"spelldump", "minlen":6, "flags":"BANG|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":"spellrare", "minlen":7, "flags":"BANG|RANGE|NEEDARG|EXTRA|TRLBAR", "parser":"parse_cmd_common"}, {"name":"spellundo", "minlen":6, "flags":"BANG|RANGE|NEEDARG|EXTRA|TRLBAR", "parser":"parse_cmd_common"}, {"name":"spellwrong", "minlen":6, "flags":"BANG|RANGE|NEEDARG|EXTRA|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sprevious", "minlen":3, "flags":"EXTRA|RANGE|COUNT|BANG|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"srewind", "minlen":2, "flags":"EXTRA|BANG|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"stop", "minlen":2, "flags":"TRLBAR|BANG|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"stag", "minlen":3, "flags":"RANGE|BANG|WORD1|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"startinsert", "minlen":4, "flags":"BANG|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"startgreplace", "minlen":6, "flags":"BANG|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"startreplace", "minlen":6, "flags":"BANG|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"static", "minlen":4, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_static"}, {"name":"stopinsert", "minlen":5, "flags":"BANG|TRLBAR|CMDWIN|LOCK_OK", "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|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"sunmap", "minlen":4, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"sunmenu", "minlen":5, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"suspend", "minlen":3, "flags":"TRLBAR|BANG|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"sview", "minlen":2, "flags":"BANG|FILE1|RANGE|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"swapname", "minlen":2, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"syntax", "minlen":2, "flags":"EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser":"parse_cmd_syntax"}, {"name":"syntime", "minlen":5, "flags":"NEEDARG|WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"syncbind", "minlen":4, "flags":"TRLBAR", "parser":"parse_cmd_common"}, {"name":"smile", "minlen":3, "flags":"TRLBAR|CMDWIN|LOCK_OK|SBOXOK", "parser":"parse_cmd_common"}, {"name":"t", "minlen":1, "flags":"RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"tNext", "minlen":2, "flags":"RANGE|BANG|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"tag", "minlen":2, "flags":"RANGE|BANG|WORD1|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"tags", "minlen":4, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tab", "minlen":3, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"tabclose", "minlen":4, "flags":"BANG|RANGE|ZEROR|EXTRA|NOSPC|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tabdo", "minlen":4, "flags":"NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser":"parse_cmd_common"}, {"name":"tabedit", "minlen":4, "flags":"BANG|FILE1|RANGE|ZEROR|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"tabfind", "minlen":4, "flags":"BANG|FILE1|RANGE|ZEROR|CMDARG|ARGOPT|NEEDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"tabfirst", "minlen":6, "flags":"TRLBAR", "parser":"parse_cmd_common"}, {"name":"tabmove", "minlen":4, "flags":"RANGE|ZEROR|EXTRA|NOSPC|TRLBAR", "parser":"parse_cmd_common"}, {"name":"tablast", "minlen":4, "flags":"TRLBAR", "parser":"parse_cmd_common"}, {"name":"tabnext", "minlen":4, "flags":"RANGE|ZEROR|EXTRA|NOSPC|TRLBAR", "parser":"parse_cmd_common"}, {"name":"tabnew", "minlen":6, "flags":"BANG|FILE1|RANGE|ZEROR|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"tabonly", "minlen":4, "flags":"BANG|RANGE|ZEROR|EXTRA|NOSPC|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tabprevious", "minlen":4, "flags":"RANGE|ZEROR|EXTRA|NOSPC|TRLBAR", "parser":"parse_cmd_common"}, {"name":"tabNext", "minlen":4, "flags":"RANGE|ZEROR|EXTRA|NOSPC|TRLBAR", "parser":"parse_cmd_common"}, {"name":"tabrewind", "minlen":4, "flags":"TRLBAR", "parser":"parse_cmd_common"}, {"name":"tabs", "minlen":4, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tcd", "minlen":2, "flags":"BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tchdir", "minlen":3, "flags":"BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tcl", "minlen":3, "flags":"RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_tcl"}, {"name":"tcldo", "minlen":4, "flags":"RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"tclfile", "minlen":4, "flags":"RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser":"parse_cmd_common"}, {"name":"tearoff", "minlen":2, "flags":"NEEDARG|EXTRA|TRLBAR|NOTRLCOM|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"terminal", "minlen":3, "flags":"RANGE|BANG|FILES|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tfirst", "minlen":2, "flags":"RANGE|BANG|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"throw", "minlen":2, "flags":"EXTRA|NEEDARG|SBOXOK|CMDWIN|LOCK_OK", "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":"tlmenu", "minlen":3, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tlnoremenu", "minlen":3, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tlunmenu", "minlen":3, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tmenu", "minlen":2, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tmap", "minlen":3, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tmapclear", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tnext", "minlen":2, "flags":"RANGE|BANG|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"tnoremap", "minlen":3, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"topleft", "minlen":2, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"tprevious", "minlen":2, "flags":"RANGE|BANG|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"trewind", "minlen":2, "flags":"RANGE|BANG|TRLBAR|ZEROR", "parser":"parse_cmd_common"}, {"name":"try", "minlen":3, "flags":"TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_try"}, {"name":"tselect", "minlen":2, "flags":"BANG|TRLBAR|WORD1", "parser":"parse_cmd_common"}, {"name":"tunmenu", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"tunmap", "minlen":5, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"type", "minlen":2, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_type"}, {"name":"undo", "minlen":1, "flags":"RANGE|COUNT|ZEROR|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"undojoin", "minlen":5, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"undolist", "minlen":5, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"unabbreviate", "minlen":3, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"unhide", "minlen":3, "flags":"RANGE|COUNT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"unlet", "minlen":3, "flags":"BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_unlet"}, {"name":"unlockvar", "minlen":4, "flags":"BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_unlockvar"}, {"name":"unmap", "minlen":3, "flags":"BANG|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"unmenu", "minlen":4, "flags":"BANG|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"unsilent", "minlen":3, "flags":"NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "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|LOCK_OK|NONWHITE_OK", "parser":"parse_cmd_common"}, {"name":"var", "minlen":2, "flags":"EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_var"}, {"name":"version", "minlen":2, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"verbose", "minlen":4, "flags":"NEEDARG|RANGE|EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"vertical", "minlen":4, "flags":"NEEDARG|EXTRA|NOTRLCOM", "parser":"parse_cmd_common"}, {"name":"visual", "minlen":2, "flags":"BANG|FILE1|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"view", "minlen":3, "flags":"BANG|FILE1|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"vimgrep", "minlen":3, "flags":"RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"vimgrepadd", "minlen":8, "flags":"RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"vim9cmd", "minlen":4, "flags":"NEEDARG|EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"vim9script", "minlen":5, "flags":"WORD1|CMDWIN|LOCK_OK", "parser":"parse_cmd_vim9script"}, {"name":"viusage", "minlen":3, "flags":"TRLBAR", "parser":"parse_cmd_common"}, {"name":"vmap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"vmapclear", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"vmenu", "minlen":3, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"vnoremap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"vnew", "minlen":3, "flags":"BANG|FILE1|RANGE|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"vnoremenu", "minlen":7, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"vsplit", "minlen":2, "flags":"BANG|FILE1|RANGE|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"vunmap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"vunmenu", "minlen":5, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"write", "minlen":1, "flags":"RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"wNext", "minlen":2, "flags":"RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"wall", "minlen":2, "flags":"BANG|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"while", "minlen":2, "flags":"EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_while"}, {"name":"winsize", "minlen":2, "flags":"EXTRA|NEEDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"wincmd", "minlen":4, "flags":"NEEDARG|WORD1|RANGE|CMDWIN|LOCK_OK", "parser":"parse_wincmd"}, {"name":"windo", "minlen":4, "flags":"NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser":"parse_cmd_common"}, {"name":"winpos", "minlen":4, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"wnext", "minlen":2, "flags":"RANGE|BANG|FILE1|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"wprevious", "minlen":2, "flags":"RANGE|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|TRLBAR", "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|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"xit", "minlen":1, "flags":"RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"xall", "minlen":2, "flags":"BANG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"xmap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"xmapclear", "minlen":5, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"xmenu", "minlen":3, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"xnoremap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"xnoremenu", "minlen":7, "flags":"RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"xrestore", "minlen":2, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"xunmap", "minlen":2, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"xunmenu", "minlen":5, "flags":"EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"yank", "minlen":1, "flags":"RANGE|WHOLEFOLD|REGSTR|COUNT|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"z", "minlen":1, "flags":"RANGE|WHOLEFOLD|BANG|EXTRA|FLAGS|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"!", "minlen":1, "flags":"RANGE|WHOLEFOLD|BANG|FILES|CMDWIN|LOCK_OK|NONWHITE_OK", "parser":"parse_cmd_common"}, {"name":"#", "minlen":1, "flags":"RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"&", "minlen":1, "flags":"RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|MODIFY|NONWHITE_OK", "parser":"parse_cmd_common"}, {"name":"*", "minlen":1, "flags":"RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|LOCK_OK|NONWHITE_OK", "parser":"parse_cmd_common"}, {"name":"<", "minlen":1, "flags":"RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"=", "minlen":1, "flags":"RANGE|TRLBAR|DFLALL|FLAGS|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":">", "minlen":1, "flags":"RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"@", "minlen":1, "flags":"RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|LOCK_OK|NONWHITE_OK", "parser":"parse_cmd_common"}, {"name":"{", "minlen":1, "flags":"TRLBAR|LOCK_OK|CMDWIN", "parser":"parse_cmd_block"}, {"name":"}", "minlen":1, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_endblock"}, {"name":"~", "minlen":1, "flags":"RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|MODIFY|NONWHITE_OK", "parser":"parse_cmd_common"}, {"name":"Next", "minlen":1, "flags":"EXTRA|RANGE|COUNT|BANG|CMDARG|ARGOPT|TRLBAR", "parser":"parse_cmd_common"}, {"name":"Print", "minlen":1, "flags":"RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"X", "minlen":1, "flags":"TRLBAR", "parser":"parse_cmd_common"}, {"name":"++", "minlen":1, "flags":"EXTRA|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"--", "minlen":1, "flags":"EXTRA|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"clipreset", "minlen":4, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"iput", "minlen":2, "flags":"RANGE|WHOLEFOLD|BANG|REGSTR|TRLBAR|ZEROR|CMDWIN|LOCK_OK|MODIFY", "parser":"parse_cmd_common"}, {"name":"pbuffer", "minlen":2, "flags":"BANG|RANGE|BUFNAME|BUFUNL|COUNT|EXTRA|CMDARG|TRLBAR", "parser":"parse_cmd_common"}, {"name":"redrawtabpanel", "minlen":10, "flags":"TRLBAR|CMDWIN|LOCK_OK", "parser":"parse_cmd_common"}, {"name":"this", "minlen":3, "flags":"EXTRA|NEEDARG|SBOXOK|CMDWIN|LOCK_OK|WHOLE", "parser":"parse_cmd_common"}, {"name":"uniq", "minlen":3, "flags":"RANGE|DFLALL|WHOLEFOLD|BANG|EXTRA|NOTRLCOM|MODIFY", "parser":"parse_cmd_common"}, {"name":"wlrestore", "minlen":2, "flags":"EXTRA|TRLBAR|CMDWIN|LOCK_OK|BANG", "parser":"parse_cmd_common"}]; // To find new builtin_functions, run the below script. // $ scripts/update_builtin_functions.sh /path/to/vim/src/evalfunc.c VimLParser.prototype.builtin_functions = [{"name":"abs", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"acos", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"add", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"and", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"append", "min_argc":2, "max_argc":2, "argtype":"FEARG_2"}, {"name":"appendbufline", "min_argc":3, "max_argc":3, "argtype":"FEARG_3"}, {"name":"argc", "min_argc":0, "max_argc":1, "argtype":"0"}, {"name":"argidx", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"arglistid", "min_argc":0, "max_argc":2, "argtype":"0"}, {"name":"argv", "min_argc":0, "max_argc":2, "argtype":"0"}, {"name":"asin", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"assert_beeps", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"assert_equal", "min_argc":2, "max_argc":3, "argtype":"FEARG_2"}, {"name":"assert_equalfile", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"assert_exception", "min_argc":1, "max_argc":2, "argtype":"0"}, {"name":"assert_fails", "min_argc":1, "max_argc":5, "argtype":"FEARG_1"}, {"name":"assert_false", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"assert_inrange", "min_argc":3, "max_argc":4, "argtype":"FEARG_3"}, {"name":"assert_match", "min_argc":2, "max_argc":3, "argtype":"FEARG_2"}, {"name":"assert_nobeep", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"assert_notequal", "min_argc":2, "max_argc":3, "argtype":"FEARG_2"}, {"name":"assert_notmatch", "min_argc":2, "max_argc":3, "argtype":"FEARG_2"}, {"name":"assert_report", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"assert_true", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"atan", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"atan2", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"autocmd_add", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"autocmd_delete", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"autocmd_get", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"balloon_gettext", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"balloon_show", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"balloon_split", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"blob2list", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"browse", "min_argc":4, "max_argc":4, "argtype":"0"}, {"name":"browsedir", "min_argc":2, "max_argc":2, "argtype":"0"}, {"name":"bufadd", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"bufexists", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"buffer_exists", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"buffer_name", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"buffer_number", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"buflisted", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"bufload", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"bufloaded", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"bufname", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"bufnr", "min_argc":0, "max_argc":2, "argtype":"FEARG_1"}, {"name":"bufwinid", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"bufwinnr", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"byte2line", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"byteidx", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"byteidxcomp", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"call", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"ceil", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"ch_canread", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"ch_close", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"ch_close_in", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"ch_evalexpr", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"ch_evalraw", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"ch_getbufnr", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"ch_getjob", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"ch_info", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"ch_log", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"ch_logfile", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"ch_open", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"ch_read", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"ch_readblob", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"ch_readraw", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"ch_sendexpr", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"ch_sendraw", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"ch_setoptions", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"ch_status", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"changenr", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"char2nr", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"charclass", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"charcol", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"charidx", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"chdir", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"cindent", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"clearmatches", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"col", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"complete", "min_argc":2, "max_argc":2, "argtype":"FEARG_2"}, {"name":"complete_add", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"complete_check", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"complete_info", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"confirm", "min_argc":1, "max_argc":4, "argtype":"FEARG_1"}, {"name":"copy", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"cos", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"cosh", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"count", "min_argc":2, "max_argc":4, "argtype":"FEARG_1"}, {"name":"cscope_connection", "min_argc":0, "max_argc":3, "argtype":"0"}, {"name":"cursor", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"debugbreak", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"deepcopy", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"delete", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"deletebufline", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"did_filetype", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"diff_filler", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"diff_hlID", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"digraph_get", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"digraph_getlist", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"digraph_set", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"digraph_setlist", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"echoraw", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"empty", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"environ", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"escape", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"eval", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"eventhandler", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"executable", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"execute", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"exepath", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"exists", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"exists_compiled", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"exp", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"expand", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"expandcmd", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"extend", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"extendnew", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"feedkeys", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"file_readable", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"filereadable", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"filewritable", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"filter", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"finddir", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"findfile", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"flatten", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"flattennew", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"float2nr", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"floor", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"fmod", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"fnameescape", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"fnamemodify", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"foldclosed", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"foldclosedend", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"foldlevel", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"foldtext", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"foldtextresult", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"foreground", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"fullcommand", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"funcref", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"function", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"garbagecollect", "min_argc":0, "max_argc":1, "argtype":"0"}, {"name":"get", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"getbufinfo", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"getbufline", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"getbufvar", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"getchangelist", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"getchar", "min_argc":0, "max_argc":1, "argtype":"0"}, {"name":"getcharmod", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"getcharpos", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"getcharsearch", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"getcharstr", "min_argc":0, "max_argc":1, "argtype":"0"}, {"name":"getcmdcompltype", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"getcmdline", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"getcmdpos", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"getcmdscreenpos", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"getcmdtype", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"getcmdwintype", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"getcompletion", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"getcurpos", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"getcursorcharpos", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"getcwd", "min_argc":0, "max_argc":2, "argtype":"FEARG_1"}, {"name":"getenv", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"getfontname", "min_argc":0, "max_argc":1, "argtype":"0"}, {"name":"getfperm", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"getfsize", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"getftime", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"getftype", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"getimstatus", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"getjumplist", "min_argc":0, "max_argc":2, "argtype":"FEARG_1"}, {"name":"getline", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"getloclist", "min_argc":1, "max_argc":2, "argtype":"0"}, {"name":"getmarklist", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"getmatches", "min_argc":0, "max_argc":1, "argtype":"0"}, {"name":"getmousepos", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"getpid", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"getpos", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"getqflist", "min_argc":0, "max_argc":1, "argtype":"0"}, {"name":"getreg", "min_argc":0, "max_argc":3, "argtype":"FEARG_1"}, {"name":"getreginfo", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"getregtype", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"getscriptinfo", "min_argc":0, "max_argc":1, "argtype":"0"}, {"name":"gettabinfo", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"gettabvar", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"gettabwinvar", "min_argc":3, "max_argc":4, "argtype":"FEARG_1"}, {"name":"gettagstack", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"gettext", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"getwininfo", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"getwinpos", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"getwinposx", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"getwinposy", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"getwinvar", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"glob", "min_argc":1, "max_argc":4, "argtype":"FEARG_1"}, {"name":"glob2regpat", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"globpath", "min_argc":2, "max_argc":5, "argtype":"FEARG_2"}, {"name":"has", "min_argc":1, "max_argc":2, "argtype":"0"}, {"name":"has_key", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"haslocaldir", "min_argc":0, "max_argc":2, "argtype":"FEARG_1"}, {"name":"hasmapto", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"highlightID", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"highlight_exists", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"histadd", "min_argc":2, "max_argc":2, "argtype":"FEARG_2"}, {"name":"histdel", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"histget", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"histnr", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"hlID", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"hlexists", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"hlget", "min_argc":0, "max_argc":2, "argtype":"FEARG_1"}, {"name":"hlset", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"hostname", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"iconv", "min_argc":3, "max_argc":3, "argtype":"FEARG_1"}, {"name":"indent", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"index", "min_argc":2, "max_argc":4, "argtype":"FEARG_1"}, {"name":"indexof", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"input", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"inputdialog", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"inputlist", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"inputrestore", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"inputsave", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"inputsecret", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"insert", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"interrupt", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"invert", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"isabsolutepath", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"isdirectory", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"isinf", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"islocked", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"isnan", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"items", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"job_getchannel", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"job_info", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"job_setoptions", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"job_start", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"job_status", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"job_stop", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"join", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"js_decode", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"js_encode", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"json_decode", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"json_encode", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"keys", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"last_buffer_nr", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"len", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"libcall", "min_argc":3, "max_argc":3, "argtype":"FEARG_3"}, {"name":"libcallnr", "min_argc":3, "max_argc":3, "argtype":"FEARG_3"}, {"name":"line", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"line2byte", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"lispindent", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"list2blob", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"list2str", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"listener_add", "min_argc":1, "max_argc":2, "argtype":"FEARG_2"}, {"name":"listener_flush", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"listener_remove", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"localtime", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"log", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"log10", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"luaeval", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"map", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"maparg", "min_argc":1, "max_argc":4, "argtype":"FEARG_1"}, {"name":"mapcheck", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"maplist", "min_argc":0, "max_argc":1, "argtype":"0"}, {"name":"mapnew", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"mapset", "min_argc":3, "max_argc":3, "argtype":"FEARG_1"}, {"name":"match", "min_argc":2, "max_argc":4, "argtype":"FEARG_1"}, {"name":"matchadd", "min_argc":2, "max_argc":5, "argtype":"FEARG_1"}, {"name":"matchaddpos", "min_argc":2, "max_argc":5, "argtype":"FEARG_1"}, {"name":"matcharg", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"matchdelete", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"matchend", "min_argc":2, "max_argc":4, "argtype":"FEARG_1"}, {"name":"matchfuzzy", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"matchfuzzypos", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"matchlist", "min_argc":2, "max_argc":4, "argtype":"FEARG_1"}, {"name":"matchstr", "min_argc":2, "max_argc":4, "argtype":"FEARG_1"}, {"name":"matchstrpos", "min_argc":2, "max_argc":4, "argtype":"FEARG_1"}, {"name":"max", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"menu_info", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"min", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"mkdir", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"mode", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"mzeval", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"nextnonblank", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"nr2char", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"or", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"pathshorten", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"perleval", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"popup_atcursor", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"popup_beval", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"popup_clear", "min_argc":0, "max_argc":1, "argtype":"0"}, {"name":"popup_close", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"popup_create", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"popup_dialog", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"popup_filter_menu", "min_argc":2, "max_argc":2, "argtype":"0"}, {"name":"popup_filter_yesno", "min_argc":2, "max_argc":2, "argtype":"0"}, {"name":"popup_findinfo", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"popup_findpreview", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"popup_getoptions", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"popup_getpos", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"popup_hide", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"popup_list", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"popup_locate", "min_argc":2, "max_argc":2, "argtype":"0"}, {"name":"popup_menu", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"popup_move", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"popup_notification", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"popup_setoptions", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"popup_settext", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"popup_show", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"pow", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"prevnonblank", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"printf", "min_argc":1, "max_argc":19, "argtype":"FEARG_2"}, {"name":"prompt_getprompt", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"prompt_setcallback", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"prompt_setinterrupt", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"prompt_setprompt", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"prop_add", "min_argc":3, "max_argc":3, "argtype":"FEARG_1"}, {"name":"prop_add_list", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"prop_clear", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"prop_find", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"prop_list", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"prop_remove", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"prop_type_add", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"prop_type_change", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"prop_type_delete", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"prop_type_get", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"prop_type_list", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"pum_getpos", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"pumvisible", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"py3eval", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"pyeval", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"pyxeval", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"rand", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"range", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"readblob", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"readdir", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"readdirex", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"readfile", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"reduce", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"reg_executing", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"reg_recording", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"reltime", "min_argc":0, "max_argc":2, "argtype":"FEARG_1"}, {"name":"reltimefloat", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"reltimestr", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"remote_expr", "min_argc":2, "max_argc":4, "argtype":"FEARG_1"}, {"name":"remote_foreground", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"remote_peek", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"remote_read", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"remote_send", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"remote_startserver", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"remove", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"rename", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"repeat", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"resolve", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"reverse", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"round", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"rubyeval", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"screenattr", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"screenchar", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"screenchars", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"screencol", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"screenpos", "min_argc":3, "max_argc":3, "argtype":"FEARG_1"}, {"name":"screenrow", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"screenstring", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"search", "min_argc":1, "max_argc":5, "argtype":"FEARG_1"}, {"name":"searchcount", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"searchdecl", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"searchpair", "min_argc":3, "max_argc":7, "argtype":"0"}, {"name":"searchpairpos", "min_argc":3, "max_argc":7, "argtype":"0"}, {"name":"searchpos", "min_argc":1, "max_argc":5, "argtype":"FEARG_1"}, {"name":"server2client", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"serverlist", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"setbufline", "min_argc":3, "max_argc":3, "argtype":"FEARG_3"}, {"name":"setbufvar", "min_argc":3, "max_argc":3, "argtype":"FEARG_3"}, {"name":"setcellwidths", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"setcharpos", "min_argc":2, "max_argc":2, "argtype":"FEARG_2"}, {"name":"setcharsearch", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"setcmdline", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"setcmdpos", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"setcursorcharpos", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"setenv", "min_argc":2, "max_argc":2, "argtype":"FEARG_2"}, {"name":"setfperm", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"setline", "min_argc":2, "max_argc":2, "argtype":"FEARG_2"}, {"name":"setloclist", "min_argc":2, "max_argc":4, "argtype":"FEARG_2"}, {"name":"setmatches", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"setpos", "min_argc":2, "max_argc":2, "argtype":"FEARG_2"}, {"name":"setqflist", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"setreg", "min_argc":2, "max_argc":3, "argtype":"FEARG_2"}, {"name":"settabvar", "min_argc":3, "max_argc":3, "argtype":"FEARG_3"}, {"name":"settabwinvar", "min_argc":4, "max_argc":4, "argtype":"FEARG_4"}, {"name":"settagstack", "min_argc":2, "max_argc":3, "argtype":"FEARG_2"}, {"name":"setwinvar", "min_argc":3, "max_argc":3, "argtype":"FEARG_3"}, {"name":"sha256", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"shellescape", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"shiftwidth", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"sign_define", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"sign_getdefined", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"sign_getplaced", "min_argc":0, "max_argc":2, "argtype":"FEARG_1"}, {"name":"sign_jump", "min_argc":3, "max_argc":3, "argtype":"FEARG_1"}, {"name":"sign_place", "min_argc":4, "max_argc":5, "argtype":"FEARG_1"}, {"name":"sign_placelist", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"sign_undefine", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"sign_unplace", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"sign_unplacelist", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"simplify", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"sin", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"sinh", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"slice", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"sort", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"sound_clear", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"sound_playevent", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"sound_playfile", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"sound_stop", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"soundfold", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"spellbadword", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"spellsuggest", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"split", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"sqrt", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"srand", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"state", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"str2float", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"str2list", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"str2nr", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"strcharlen", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"strcharpart", "min_argc":2, "max_argc":4, "argtype":"FEARG_1"}, {"name":"strchars", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"strdisplaywidth", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"strftime", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"strgetchar", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"stridx", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"string", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"strlen", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"strpart", "min_argc":2, "max_argc":4, "argtype":"FEARG_1"}, {"name":"strptime", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"strridx", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"strtrans", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"strwidth", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"submatch", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"substitute", "min_argc":4, "max_argc":4, "argtype":"FEARG_1"}, {"name":"swapinfo", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"swapname", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"synID", "min_argc":3, "max_argc":3, "argtype":"0"}, {"name":"synIDattr", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"synIDtrans", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"synconcealed", "min_argc":2, "max_argc":2, "argtype":"0"}, {"name":"synstack", "min_argc":2, "max_argc":2, "argtype":"0"}, {"name":"system", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"systemlist", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"tabpagebuflist", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"tabpagenr", "min_argc":0, "max_argc":1, "argtype":"0"}, {"name":"tabpagewinnr", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"tagfiles", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"taglist", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"tan", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"tanh", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"tempname", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"term_dumpdiff", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"term_dumpload", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"term_dumpwrite", "min_argc":2, "max_argc":3, "argtype":"FEARG_2"}, {"name":"term_getaltscreen", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"term_getansicolors", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"term_getattr", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"term_getcursor", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"term_getjob", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"term_getline", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"term_getscrolled", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"term_getsize", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"term_getstatus", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"term_gettitle", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"term_gettty", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"term_list", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"term_scrape", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"term_sendkeys", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"term_setansicolors", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"term_setapi", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"term_setkill", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"term_setrestore", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"term_setsize", "min_argc":3, "max_argc":3, "argtype":"FEARG_1"}, {"name":"term_start", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"term_wait", "min_argc":1, "max_argc":2, "argtype":"FEARG_1"}, {"name":"terminalprops", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"test_alloc_fail", "min_argc":3, "max_argc":3, "argtype":"FEARG_1"}, {"name":"test_autochdir", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"test_feedinput", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"test_garbagecollect_now", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"test_garbagecollect_soon", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"test_getvalue", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"test_gui_drop_files", "min_argc":4, "max_argc":4, "argtype":"0"}, {"name":"test_gui_event", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"test_gui_mouse_event", "min_argc":5, "max_argc":5, "argtype":"0"}, {"name":"test_ignore_error", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"test_null_blob", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"test_null_channel", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"test_null_dict", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"test_null_function", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"test_null_job", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"test_null_list", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"test_null_partial", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"test_null_string", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"test_option_not_set", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"test_override", "min_argc":2, "max_argc":2, "argtype":"FEARG_2"}, {"name":"test_refcount", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"test_scrollbar", "min_argc":3, "max_argc":3, "argtype":"FEARG_2"}, {"name":"test_setmouse", "min_argc":2, "max_argc":2, "argtype":"0"}, {"name":"test_settime", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"test_srand_seed", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"test_unknown", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"test_void", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"timer_info", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"timer_pause", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"timer_start", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"timer_stop", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"timer_stopall", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"tolower", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"toupper", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"tr", "min_argc":3, "max_argc":3, "argtype":"FEARG_1"}, {"name":"trim", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"trunc", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"type", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"typename", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"undofile", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"undotree", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"uniq", "min_argc":1, "max_argc":3, "argtype":"FEARG_1"}, {"name":"values", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"virtcol", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"virtcol2col", "min_argc":3, "max_argc":3, "argtype":"FEARG_1"}, {"name":"visualmode", "min_argc":0, "max_argc":1, "argtype":"0"}, {"name":"wildmenumode", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"win_execute", "min_argc":2, "max_argc":3, "argtype":"FEARG_2"}, {"name":"win_findbuf", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"win_getid", "min_argc":0, "max_argc":2, "argtype":"FEARG_1"}, {"name":"win_gettype", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"win_gotoid", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"win_id2tabwin", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"win_id2win", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"win_move_separator", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"win_move_statusline", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}, {"name":"win_screenpos", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"win_splitmove", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"winbufnr", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"wincol", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"windowsversion", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"winheight", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"winlayout", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"winline", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"winnr", "min_argc":0, "max_argc":1, "argtype":"FEARG_1"}, {"name":"winrestcmd", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"winrestview", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"winsaveview", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"winwidth", "min_argc":1, "max_argc":1, "argtype":"FEARG_1"}, {"name":"wordcount", "min_argc":0, "max_argc":0, "argtype":"0"}, {"name":"writefile", "min_argc":2, "max_argc":3, "argtype":"FEARG_1"}, {"name":"xor", "min_argc":2, "max_argc":2, "argtype":"FEARG_1"}]; function ExprTokenizer() { this.__init__.apply(this, arguments); } ExprTokenizer.prototype.__init__ = function(reader) { + var a000 = Array.prototype.slice.call(arguments, 1); this.reader = reader; this.cache = {}; + this.vim9 = FALSE; + if (viml_len(a000) > 0) { + this.vim9 = a000[0]; + } + // Nesting level of brackets, inside which a Vim9 expression may continue + // on the next line. + this.depth = 0; } ExprTokenizer.prototype.token = function(type, value, pos) { @@ -2980,6 +3838,9 @@ ExprTokenizer.prototype.peek = function() { } ExprTokenizer.prototype.get = function() { + if (this.vim9) { + this.skip_vim9_newline(FALSE); + } // FIXME: remove dirty hack if (viml_has_key(this.cache, this.reader.tell())) { var x = this.cache[this.reader.tell()]; @@ -2993,6 +3854,80 @@ ExprTokenizer.prototype.get = function() { return r; } +// In Vim9 script an expression continues on the next line inside brackets, +// after an operator (a:force), and before an operator that starts the next +// line. Comments and empty lines in between are skipped. +ExprTokenizer.prototype.skip_vim9_newline = function(force_newline) { + var r = this.reader; + var force = force_newline; + while (TRUE) { + var pos = r.tell(); + r.skip_white(); + if (r.peek() == "#" && r.tell() > 0 && (iswhite(r.p(-1)) || r.p(-1) == "")) { + r.getn(-1); + } + if (r.peek() != "" || !(force || this.depth > 0 || this.next_line_continues()) || this.next_line_is_enddef()) { + r.seek_set(pos); + return; + } + r.get(); + var force = TRUE; + } +} + +// :enddef cannot be used at the start of a continuation line. +ExprTokenizer.prototype.next_line_is_enddef = function() { + var r = this.reader; + var pos = r.tell(); + r.get(); + r.skip_white(); + var result = r.read_alpha() == "enddef" && !iswordc(r.peekn(1)); + r.seek_set(pos); + return result; +} + +// Return TRUE when the next line, ignoring comments and empty lines, starts +// with an operator that continues the expression. +ExprTokenizer.prototype.next_line_continues = function() { + var r = this.reader; + var pos = r.tell(); + while (r.peek() == "") { + r.get(); + r.skip_white(); + if (r.peek() == "#") { + r.getn(-1); + } + } + var c = r.peek(); + var continues = FALSE; + if (c == "-" && r.p(1) == ">") { + var continues = TRUE; + } + else if (c == "." && iswordc1(r.p(1))) { + var continues = TRUE; + } + else if (c == "i" && r.p(1) == "s") { + var op = r.read_alpha(); + if (op == "is" || op == "isnot") { + if (r.peek() == "?" || r.peek() == "#") { + r.get(); + } + var continues = iswhite(r.peek()) || r.peek() == ""; + } + } + else if (c != "" && viml_stridx("+-*/%.|&?:=!<>", c) != -1) { + var op = ""; + while (r.peek() != "" && viml_stridx("+-*/%.|&?:=!<>~#", r.peek()) != -1) { + op += r.get(); + } + if (viml_has_key(VIM9_CONTINUATION_OPS, op)) { + var continues = iswhite(r.peek()) || r.peek() == ""; + } + } + r.seek_set(pos); + return continues; +} + ExprTokenizer.prototype.get2 = function() { var r = this.reader; var pos = r.getpos(); @@ -3018,6 +3953,11 @@ ExprTokenizer.prototype.get2 = function() { s += r.read_bdigit(); return this.token(TOKEN_NUMBER, s, pos); } + else if (c == "0" && (r.p(1) == "O" || r.p(1) == "o") && isodigit(r.p(2))) { + var s = r.getn(3); + s += r.read_odigit(); + return this.token(TOKEN_NUMBER, s, pos); + } else if (c == "0" && (r.p(1) == "Z" || r.p(1) == "z") && r.p(2) != ".") { var s = r.getn(2); s += r.read_blob(); @@ -3025,6 +3965,10 @@ ExprTokenizer.prototype.get2 = function() { } else if (isdigit(c)) { var s = r.read_digit(); + // Vim9 script allows a single quote between digits: 1'000'000 + while (this.vim9 && r.p(0) == "'" && isdigit(r.p(1))) { + s += r.getn(1) + r.read_digit(); + } if (r.p(0) == "." && isdigit(r.p(1))) { s += r.getn(1); s += r.read_digit(); @@ -3064,7 +4008,12 @@ ExprTokenizer.prototype.get2 = function() { } } else if (isnamec1(c)) { - var s = r.read_name(); + if (this.vim9) { + var s = r.read_vim9_name(); + } + else { + var s = r.read_name(); + } return this.token(TOKEN_IDENTIFIER, s, pos); } else if (c == "|" && r.p(1) == "|") { @@ -3075,6 +4024,10 @@ ExprTokenizer.prototype.get2 = function() { r.seek_cur(2); return this.token(TOKEN_ANDAND, "&&", pos); } + else if (c == "=" && r.p(1) == ">" && this.vim9) { + r.seek_cur(2); + return this.token(TOKEN_FATARROW, "=>", pos); + } else if (c == "=" && r.p(1) == "=") { if (r.p(2) == "?") { r.seek_cur(3); @@ -3241,6 +4194,10 @@ ExprTokenizer.prototype.get2 = function() { r.seek_cur(1); return this.token(TOKEN_NOT, "!", pos); } + else if (c == "?" && r.p(1) == "?") { + r.seek_cur(2); + return this.token(TOKEN_QUESTIONQUESTION, "??", pos); + } else if (c == "?") { r.seek_cur(1); return this.token(TOKEN_QUESTION, "?", pos); @@ -3250,7 +4207,7 @@ ExprTokenizer.prototype.get2 = function() { return this.token(TOKEN_COLON, ":", pos); } else if (c == "#") { - if (r.p(1) == "{") { + if (r.p(1) == "{" && !this.vim9) { r.seek_cur(2); return this.token(TOKEN_LITCOPEN, "#{", pos); } @@ -3428,8 +4385,16 @@ ExprTokenizer.prototype.parse_dict_literal_key = function() { function ExprParser() { this.__init__.apply(this, arguments); } ExprParser.prototype.__init__ = function(reader) { + var a000 = Array.prototype.slice.call(arguments, 1); this.reader = reader; - this.tokenizer = new ExprTokenizer(reader); + // The VimLParser using this parser, if any. + this.parser = NIL; + this.vim9 = FALSE; + if (viml_len(a000) > 0) { + this.parser = a000[0]; + this.vim9 = this.parser.isvim9(); + } + this.tokenizer = new ExprTokenizer(reader, this.vim9); } ExprParser.prototype.parse = function() { @@ -3437,11 +4402,19 @@ ExprParser.prototype.parse = function() { } // expr1: expr2 ? expr1 : expr1 +// expr2 ?? expr1 ExprParser.prototype.parse_expr1 = function() { var left = this.parse_expr2(); var pos = this.reader.tell(); var token = this.tokenizer.get(); - if (token.type == TOKEN_QUESTION) { + if (token.type == TOKEN_QUESTIONQUESTION) { + var node = Node(NODE_FALSY); + node.pos = token.pos; + node.left = left; + node.right = this.parse_expr1(); + var left = node; + } + else if (token.type == TOKEN_QUESTION) { var node = Node(NODE_TERNARY); node.pos = token.pos; node.cond = left; @@ -3767,7 +4740,7 @@ ExprParser.prototype.parse_expr5 = function() { node.right = this.parse_expr5_5(); var left = node; } - else if (token.type == TOKEN_DOT) { + else if (token.type == TOKEN_DOT && !this.vim9) { // TODO check scriptversion? var node = Node(NODE_CONCAT); node.pos = token.pos; @@ -3853,6 +4826,9 @@ ExprParser.prototype.parse_expr6 = function() { // - expr7 // + expr7 ExprParser.prototype.parse_expr7 = function() { + if (this.vim9) { + this.tokenizer.skip_vim9_newline(TRUE); + } var pos = this.reader.tell(); var token = this.tokenizer.get(); if (token.type == TOKEN_NOT) { @@ -3873,6 +4849,18 @@ ExprParser.prototype.parse_expr7 = function() { node.left = this.parse_expr7(); return node; } + else if (token.type == TOKEN_LT && this.vim9 && !viml_equalci(this.reader.peekn(4), "SID>")) { + // Vim9 type cast: expr + var node = Node(NODE_CAST); + node.pos = token.pos; + node.type_str = this.parser.read_type(); + var token = this.tokenizer.get(); + if (token.type != TOKEN_GT) { + throw Err(viml_printf("unexpected token: %s", token.value), token.pos); + } + node.left = this.parse_expr7(); + return node; + } else { this.reader.seek_set(pos); var node = this.parse_expr8(); @@ -3893,8 +4881,36 @@ ExprParser.prototype.parse_expr8 = function() { var pos = this.reader.tell(); var c = this.reader.peek(); var token = this.tokenizer.get(); - if (!iswhite(c) && token.type == TOKEN_SQOPEN) { + // In Vim9 script no white space or line break is allowed before "[" and + // "(", a member "." may start a continuation line. + var attached = !iswhite(c) && !(this.vim9 && c == ""); + if (this.vim9 && c == "<" && this.parser.is_generic_args()) { + // Vim9 generic function call: Func(args) + this.reader.seek_set(pos); + var type_args = this.reader.getn(1); + var depth = 1; + while (depth > 0) { + var c = this.reader.getn(1); + if (c == "<") { + depth += 1; + } + else if (c == ">") { + depth -= 1; + } + type_args += c; + } + var token = this.tokenizer.get(); + var node = Node(NODE_CALL); + node.pos = token.pos; + node.left = left; + node.type_args = type_args; + node.rlist = this.parse_rlist(); + var left = node; + delete node; + } + else if (attached && token.type == TOKEN_SQOPEN) { var npos = token.pos; + this.tokenizer.depth += 1; if (this.tokenizer.peek().type == TOKEN_COLON) { this.tokenizer.get(); var node = Node(NODE_SLICE); @@ -3906,6 +4922,7 @@ ExprParser.prototype.parse_expr8 = function() { node.rlist[1] = this.parse_expr1(); } var token = this.tokenizer.get(); + this.tokenizer.depth -= 1; if (token.type != TOKEN_SQCLOSE) { throw Err(viml_printf("unexpected token: %s", token.value), token.pos); } @@ -3924,6 +4941,7 @@ ExprParser.prototype.parse_expr8 = function() { node.rlist[1] = this.parse_expr1(); } var token = this.tokenizer.get(); + this.tokenizer.depth -= 1; if (token.type != TOKEN_SQCLOSE) { throw Err(viml_printf("unexpected token: %s", token.value), token.pos); } @@ -3935,6 +4953,7 @@ ExprParser.prototype.parse_expr8 = function() { node.left = left; node.right = right; var token = this.tokenizer.get(); + this.tokenizer.depth -= 1; if (token.type != TOKEN_SQCLOSE) { throw Err(viml_printf("unexpected token: %s", token.value), token.pos); } @@ -3960,7 +4979,7 @@ ExprParser.prototype.parse_expr8 = function() { var left = node; delete node; } - else if (token.type == TOKEN_POPEN) { + else if (token.type == TOKEN_POPEN && (attached || !this.vim9)) { var node = Node(NODE_CALL); node.pos = token.pos; node.left = left; @@ -3968,7 +4987,7 @@ ExprParser.prototype.parse_expr8 = function() { var left = node; delete node; } - else if (!iswhite(c) && token.type == TOKEN_DOT) { + else if ((attached || this.vim9 && c == "") && token.type == TOKEN_DOT) { // TODO check scriptversion? var node = this.parse_dot(token, left); if (node === NIL) { @@ -3988,9 +5007,11 @@ ExprParser.prototype.parse_expr8 = function() { ExprParser.prototype.parse_rlist = function() { var rlist = []; + this.tokenizer.depth += 1; var token = this.tokenizer.peek(); if (this.tokenizer.peek().type == TOKEN_PCLOSE) { this.tokenizer.get(); + this.tokenizer.depth -= 1; } else { while (TRUE) { @@ -4000,10 +5021,12 @@ ExprParser.prototype.parse_rlist = function() { // XXX: Vim allows foo(a, b, ). Lint should warn it. if (this.tokenizer.peek().type == TOKEN_PCLOSE) { this.tokenizer.get(); + this.tokenizer.depth -= 1; break; } } else if (token.type == TOKEN_PCLOSE) { + this.tokenizer.depth -= 1; break; } else { @@ -4063,6 +5086,7 @@ ExprParser.prototype.parse_expr9 = function() { var node = Node(NODE_LIST); node.pos = token.pos; node.value = []; + this.tokenizer.depth += 1; var token = this.tokenizer.peek(); if (token.type == TOKEN_SQCLOSE) { this.tokenizer.get(); @@ -4087,6 +5111,10 @@ ExprParser.prototype.parse_expr9 = function() { } } } + this.tokenizer.depth -= 1; + } + else if (token.type == TOKEN_COPEN && this.vim9) { + var node = this.parse_vim9_dict(token); } else if (token.type == TOKEN_COPEN || token.type == TOKEN_LITCOPEN) { var is_litdict = token.type == TOKEN_LITCOPEN; @@ -4173,98 +5201,358 @@ ExprParser.prototype.parse_expr9 = function() { return node; } } - // dict - var node = Node(NODE_DICT); - node.pos = nodepos; - node.value = []; - this.reader.seek_set(savepos); + // dict + var node = Node(NODE_DICT); + node.pos = nodepos; + node.value = []; + this.reader.seek_set(savepos); + var token = this.tokenizer.peek(); + if (token.type == TOKEN_CCLOSE) { + this.tokenizer.get(); + return node; + } + while (1) { + var key = is_litdict ? this.tokenizer.parse_dict_literal_key() : this.parse_expr1(); + var token = this.tokenizer.get(); + if (token.type == TOKEN_CCLOSE) { + if (!viml_empty(node.value)) { + throw Err(viml_printf("unexpected token: %s", token.value), token.pos); + } + this.reader.seek_set(pos); + var node = this.parse_identifier(); + break; + } + if (token.type != TOKEN_COLON) { + throw Err(viml_printf("unexpected token: %s", token.value), token.pos); + } + var val = this.parse_expr1(); + viml_add(node.value, [key, val]); + var token = this.tokenizer.get(); + if (token.type == TOKEN_COMMA) { + if (this.tokenizer.peek().type == TOKEN_CCLOSE) { + this.tokenizer.get(); + break; + } + } + else if (token.type == TOKEN_CCLOSE) { + break; + } + else { + throw Err(viml_printf("unexpected token: %s", token.value), token.pos); + } + } + return node; + } + else if (token.type == TOKEN_POPEN && this.vim9) { + var node = this.parse_vim9_paren(token); + } + else if (token.type == TOKEN_POPEN) { + this.tokenizer.depth += 1; + var node = this.parse_expr1(); + var token = this.tokenizer.get(); + this.tokenizer.depth -= 1; + if (token.type != TOKEN_PCLOSE) { + throw Err(viml_printf("unexpected token: %s", token.value), token.pos); + } + } + else if (token.type == TOKEN_OPTION) { + var node = Node(NODE_OPTION); + node.pos = token.pos; + node.value = token.value; + } + else if (token.type == TOKEN_IDENTIFIER) { + this.reader.seek_set(pos); + var node = this.parse_identifier(); + } + else if (FALSE && (token.type == TOKEN_COLON || token.type == TOKEN_SHARP)) { + // XXX: no parse error but invalid expression + this.reader.seek_set(pos); + var node = this.parse_identifier(); + } + else if (token.type == TOKEN_LT && viml_equalci(this.reader.peekn(4), "SID>")) { + this.reader.seek_set(pos); + var node = this.parse_identifier(); + } + else if (token.type == TOKEN_IS || token.type == TOKEN_ISCS || token.type == TOKEN_ISNOT || token.type == TOKEN_ISNOTCS) { + this.reader.seek_set(pos); + var node = this.parse_identifier(); + } + else if (token.type == TOKEN_ENV && token.value == "$" && (this.reader.p(0) == "\"" || this.reader.p(0) == "'")) { + var node = this.parse_interpolation(token); + } + else if (token.type == TOKEN_ENV) { + var node = Node(NODE_ENV); + node.pos = token.pos; + node.value = token.value; + } + else if (token.type == TOKEN_REG) { + var node = Node(NODE_REG); + node.pos = token.pos; + node.value = token.value; + } + else { + throw Err(viml_printf("unexpected token: %s", token.value), token.pos); + } + return node; +} + +// Interpolated string: $"text {expr1} text" or $'text {expr1} text' +// .value is a list of NODE_STRING parts, in the quotes of the string, and +// expressions. +ExprParser.prototype.parse_interpolation = function(token) { + var r = this.reader; + var node = Node(NODE_INTERPOLATION); + node.pos = token.pos; + node.value = []; + var quote = r.get(); + var str = ""; + var strpos = r.getpos(); + while (TRUE) { + var c = r.p(0); + if (c == "" || c == "") { + throw Err("unexpected EOL", r.getpos()); + } + else if (c == quote && quote == "'" && r.p(1) == "'") { + str += r.getn(2); + } + else if (c == quote) { + r.seek_cur(1); + break; + } + else if (c == "\\" && quote == "\"") { + str += r.getn(2); + } + else if (c == "{" && r.p(1) == "{" || c == "}" && r.p(1) == "}") { + str += r.getn(2); + } + else if (c == "{") { + if (str != "") { + var part = Node(NODE_STRING); + part.pos = strpos; + part.value = quote + str + quote; + viml_add(node.value, part); + var str = ""; + } + r.seek_cur(1); + viml_add(node.value, this.parse_expr1()); + r.skip_white(); + if (r.p(0) != "}") { + throw Err(viml_printf("unexpected token: %s", r.p(0)), r.getpos()); + } + r.seek_cur(1); + var strpos = r.getpos(); + } + else { + str += r.getn(1); + } + } + if (str != "") { + var part = Node(NODE_STRING); + part.pos = strpos; + part.value = quote + str + quote; + viml_add(node.value, part); + } + return node; +} + +// Vim9 lambda, tuple or expression in parentheses, after the "(": +// (args) => expr1 +// (args): type => { +// () (expr1,) (expr1, expr1, ...) +// (expr1) +ExprParser.prototype.parse_vim9_paren = function(popen) { + if (this.is_vim9_lambda()) { + return this.parse_vim9_lambda(popen); + } + this.tokenizer.depth += 1; + var token = this.tokenizer.peek(); + if (token.type == TOKEN_PCLOSE) { + this.tokenizer.get(); + this.tokenizer.depth -= 1; + var node = Node(NODE_TUPLE); + node.pos = popen.pos; + node.value = []; + return node; + } + var node = this.parse_expr1(); + var token = this.tokenizer.get(); + if (token.type == TOKEN_COMMA) { + var tuple = Node(NODE_TUPLE); + tuple.pos = popen.pos; + tuple.value = [node]; + while (this.tokenizer.peek().type != TOKEN_PCLOSE) { + viml_add(tuple.value, this.parse_expr1()); + var token = this.tokenizer.peek(); + if (token.type == TOKEN_COMMA) { + this.tokenizer.get(); + } + else if (token.type != TOKEN_PCLOSE) { + throw Err(viml_printf("unexpected token: %s", token.value), token.pos); + } + } + var token = this.tokenizer.get(); + var node = tuple; + } + this.tokenizer.depth -= 1; + if (token.type != TOKEN_PCLOSE) { + throw Err(viml_printf("unexpected token: %s", token.value), token.pos); + } + return node; +} + +// Return TRUE when the text after "(" is the argument list of a Vim9 lambda, +// i.e. names with optional types, ")", an optional return type and "=>". +ExprParser.prototype.is_vim9_lambda = function() { + var r = this.reader; + var pos = r.tell(); + var result = FALSE; + while (TRUE) { + r.skip_white(); + if (r.peekn(1) == ")") { + break; + } + if (r.peekn(3) == "...") { + r.getn(3); + } + if (r.read_word() == "") { + r.seek_set(pos); + return FALSE; + } + if (r.peekn(1) == ":") { + r.getn(1); + r.skip_white(); + this.parser.read_type(); + } + r.skip_white(); + if (r.peekn(1) == ",") { + r.getn(1); + } + else if (r.peekn(1) != ")") { + r.seek_set(pos); + return FALSE; + } + } + r.getn(1); + if (r.peekn(1) == ":") { + r.getn(1); + r.skip_white(); + this.parser.read_type(); + } + r.skip_white(); + var result = r.peekn(2) == "=>"; + r.seek_set(pos); + return result; +} + +ExprParser.prototype.parse_vim9_lambda = function(token) { + var r = this.reader; + var node = Node(NODE_LAMBDA); + node.pos = token.pos; + node.rlist = []; + node.left = NIL; + node.body = []; + node.rettype = ""; + while (TRUE) { + r.skip_white(); + if (r.peekn(1) == ")") { + r.getn(1); + break; + } + var varnode = Node(NODE_IDENTIFIER); + varnode.pos = r.getpos(); + varnode.value = ""; + varnode.type_str = ""; + if (r.peekn(3) == "...") { + varnode.value = r.getn(3); + } + var name = r.read_word(); + varnode.value += name; + this.parser.declared[name] = 1; + if (r.peekn(1) == ":") { + r.getn(1); + r.skip_white(); + varnode.type_str = this.parser.read_type(); + } + viml_add(node.rlist, varnode); + r.skip_white(); + if (r.peekn(1) == ",") { + r.getn(1); + } + } + if (r.peekn(1) == ":") { + r.getn(1); + r.skip_white(); + node.rettype = this.parser.read_type(); + } + r.skip_white(); + r.getn(2); + r.skip_white(); + var pos = r.tell(); + if (r.peekn(1) == "{") { + r.getn(1); + r.skip_white(); + if (r.peek() == "" || r.peek() == "#") { + this.parser.parse_lambda_block(node); + return node; + } + r.seek_set(pos); + } + node.left = this.parse_expr1(); + return node; +} + +// Vim9 dictionary: {key: expr1, "key": expr1, [expr1]: expr1, ...} +// A key made of word characters and "-" is a literal string. +ExprParser.prototype.parse_vim9_dict = function(copen) { + var node = Node(NODE_DICT); + node.pos = copen.pos; + node.value = []; + this.tokenizer.depth += 1; + while (TRUE) { var token = this.tokenizer.peek(); if (token.type == TOKEN_CCLOSE) { this.tokenizer.get(); - return node; + break; } - while (1) { - var key = is_litdict ? this.tokenizer.parse_dict_literal_key() : this.parse_expr1(); - var token = this.tokenizer.get(); - if (token.type == TOKEN_CCLOSE) { - if (!viml_empty(node.value)) { - throw Err(viml_printf("unexpected token: %s", token.value), token.pos); - } - this.reader.seek_set(pos); - var node = this.parse_identifier(); - break; - } - if (token.type != TOKEN_COLON) { - throw Err(viml_printf("unexpected token: %s", token.value), token.pos); - } - var val = this.parse_expr1(); - viml_add(node.value, [key, val]); + if (token.type == TOKEN_SQOPEN) { + this.tokenizer.get(); + var key = this.parse_expr1(); var token = this.tokenizer.get(); - if (token.type == TOKEN_COMMA) { - if (this.tokenizer.peek().type == TOKEN_CCLOSE) { - this.tokenizer.get(); - break; - } - } - else if (token.type == TOKEN_CCLOSE) { - break; - } - else { + if (token.type != TOKEN_SQCLOSE) { throw Err(viml_printf("unexpected token: %s", token.value), token.pos); } } - return node; - } - else if (token.type == TOKEN_POPEN) { - var node = this.parse_expr1(); + else if (token.type == TOKEN_SQUOTE || token.type == TOKEN_DQUOTE) { + var key = this.parse_expr1(); + } + else { + this.tokenizer.skip_vim9_newline(FALSE); + var key = this.tokenizer.parse_dict_literal_key(); + } var token = this.tokenizer.get(); - if (token.type != TOKEN_PCLOSE) { + if (token.type != TOKEN_COLON) { + throw Err(viml_printf("unexpected token: %s", token.value), token.pos); + } + var val = this.parse_expr1(); + viml_add(node.value, [key, val]); + var token = this.tokenizer.get(); + if (token.type == TOKEN_CCLOSE) { + break; + } + else if (token.type != TOKEN_COMMA) { throw Err(viml_printf("unexpected token: %s", token.value), token.pos); } } - else if (token.type == TOKEN_OPTION) { - var node = Node(NODE_OPTION); - node.pos = token.pos; - node.value = token.value; - } - else if (token.type == TOKEN_IDENTIFIER) { - this.reader.seek_set(pos); - var node = this.parse_identifier(); - } - else if (FALSE && (token.type == TOKEN_COLON || token.type == TOKEN_SHARP)) { - // XXX: no parse error but invalid expression - this.reader.seek_set(pos); - var node = this.parse_identifier(); - } - else if (token.type == TOKEN_LT && viml_equalci(this.reader.peekn(4), "SID>")) { - this.reader.seek_set(pos); - var node = this.parse_identifier(); - } - else if (token.type == TOKEN_IS || token.type == TOKEN_ISCS || token.type == TOKEN_ISNOT || token.type == TOKEN_ISNOTCS) { - this.reader.seek_set(pos); - var node = this.parse_identifier(); - } - else if (token.type == TOKEN_ENV) { - var node = Node(NODE_ENV); - node.pos = token.pos; - node.value = token.value; - } - else if (token.type == TOKEN_REG) { - var node = Node(NODE_REG); - node.pos = token.pos; - node.value = token.value; - } - else { - throw Err(viml_printf("unexpected token: %s", token.value), token.pos); - } + this.tokenizer.depth -= 1; return node; } // SUBSCRIPT or CONCAT // dict "." [0-9A-Za-z_]+ => (subscript dict key) // str "." expr6 => (concat str expr6) +// In Vim9 script "." is always a member access. ExprParser.prototype.parse_dot = function(token, left) { - if (left.type != NODE_IDENTIFIER && left.type != NODE_CURLYNAME && left.type != NODE_DICT && left.type != NODE_SUBSCRIPT && left.type != NODE_CALL && left.type != NODE_DOT) { + if (!this.vim9 && left.type != NODE_IDENTIFIER && left.type != NODE_CURLYNAME && left.type != NODE_DICT && left.type != NODE_SUBSCRIPT && left.type != NODE_CALL && left.type != NODE_DOT) { return NIL; } if (!iswordc(this.reader.p(0))) { @@ -4272,7 +5560,7 @@ ExprParser.prototype.parse_dot = function(token, left) { } var pos = this.reader.getpos(); var name = this.reader.read_word(); - if (isnamec(this.reader.p(0))) { + if (!this.vim9 && isnamec(this.reader.p(0))) { // XXX: foo is str => ok, foo is obj => invalid expression // foo.s:bar or foo.bar#baz return NIL; @@ -4314,6 +5602,18 @@ ExprParser.prototype.parse_concat = function(token, left) { ExprParser.prototype.parse_identifier = function() { this.reader.skip_white(); var npos = this.reader.getpos(); + if (this.vim9) { + // Vim9 script has no curly-braces names. + var node = Node(NODE_IDENTIFIER); + node.pos = npos; + if (viml_equalci(this.reader.peekn(5), "")) { + node.value = this.reader.getn(5) + this.reader.read_vim9_name(); + } + else { + node.value = this.reader.read_vim9_name(); + } + return node; + } var curly_parts = this.parse_curly_parts(); if (viml_len(curly_parts) == 1 && curly_parts[0].type == NODE_CURLYNAMEPART) { var node = Node(NODE_IDENTIFIER); @@ -4509,20 +5809,32 @@ StringReader.prototype.__init__ = function(lines) { var offset = 0; while (lnum < viml_len(lines)) { var col = 0; - var __c7 = viml_split(lines[lnum], "\\zs"); - for (var __i7 = 0; __i7 < __c7.length; ++__i7) { - var c = __c7[__i7]; + var __c12 = viml_split(lines[lnum], "\\zs"); + for (var __i12 = 0; __i12 < __c12.length; ++__i12) { + var c = __c12[__i12]; viml_add(this.buf, c); viml_add(this.pos, [lnum + 1, col + 1, offset]); col += viml_len(c); offset += viml_len(c); } - while (lnum + 1 < viml_len(lines) && viml_eqregh(lines[lnum + 1], "^\\s*\\\\")) { + while (TRUE) { + // Comment lines "\ and #\ may appear between continuation lines. + var next = lnum + 1; + while (next < viml_len(lines) && viml_eqregh(lines[next], "^\\s*[\"#]\\\\ ")) { + next += 1; + } + if (next >= viml_len(lines) || !viml_eqregh(lines[next], "^\\s*\\\\")) { + break; + } + while (lnum + 1 < next) { + offset += viml_len(lines[lnum + 1]) + 1; + lnum += 1; + } var skip = TRUE; var col = 0; - var __c8 = viml_split(lines[lnum + 1], "\\zs"); - for (var __i8 = 0; __i8 < __c8.length; ++__i8) { - var c = __c8[__i8]; + var __c13 = viml_split(lines[lnum + 1], "\\zs"); + for (var __i13 = 0; __i13 < __c13.length; ++__i13) { + var c = __c13[__i13]; if (skip) { if (c == "\\") { var skip = FALSE; @@ -4624,9 +5936,9 @@ StringReader.prototype.readline = function() { StringReader.prototype.getstr = function(begin, end) { var r = ""; - var __c9 = viml_range(begin.i, end.i - 1); - for (var __i9 = 0; __i9 < __c9.length; ++__i9) { - var i = __c9[__i9]; + var __c14 = viml_range(begin.i, end.i - 1); + for (var __i14 = 0; __i14 < __c14.length; ++__i14) { + var i = __c14[__i14]; if (i >= viml_len(this.buf)) { break; } @@ -4762,6 +6074,20 @@ StringReader.prototype.read_name = function() { return r; } +// Read a Vim9 variable or function name. Unlike read_name() a colon is only +// part of the name after a one letter scope, e.g. "g:name". +StringReader.prototype.read_vim9_name = function() { + var r = ""; + var c = this.peekn(1); + if (c != "" && viml_stridx("bgltsvw", c) != -1 && this.p(1) == ":" && !iswhite(this.p(2))) { + var r = this.getn(2); + } + while (iswordc(this.peekn(1)) || this.peekn(1) == "#") { + r += this.getn(1); + } + return r; +} + StringReader.prototype.skip_white = function() { while (iswhite(this.peekn(1))) { this.seek_cur(1); @@ -5128,6 +6454,62 @@ Compiler.prototype.compile = function(node) { this.compile_vim9script(node); return NIL; } + else if (node.type == NODE_ASSIGN) { + this.compile_assign(node); + return NIL; + } + else if (node.type == NODE_BLOCK) { + this.compile_block(node); + return NIL; + } + else if (node.type == NODE_CLASS) { + this.compile_class(node); + return NIL; + } + else if (node.type == NODE_INTERFACE) { + this.compile_interface(node); + return NIL; + } + else if (node.type == NODE_ENUM) { + this.compile_enum(node); + return NIL; + } + else if (node.type == NODE_TYPE) { + this.compile_type(node); + return NIL; + } + else if (node.type == NODE_PUBLIC) { + this.compile_wrapper(node, "public"); + return NIL; + } + else if (node.type == NODE_STATIC) { + this.compile_wrapper(node, "static"); + return NIL; + } + else if (node.type == NODE_ABSTRACT) { + this.compile_wrapper(node, "abstract"); + return NIL; + } + else if (node.type == NODE_DEFER) { + this.compile_defer(node); + return NIL; + } + else if (node.type == NODE_ECHOWINDOW) { + this.compile_echowindow(node); + return NIL; + } + else if (node.type == NODE_TUPLE) { + return this.compile_tuple(node); + } + else if (node.type == NODE_FALSY) { + return this.compile_falsy(node); + } + else if (node.type == NODE_INTERPOLATION) { + return this.compile_interpolation(node); + } + else if (node.type == NODE_CAST) { + return this.compile_cast(node); + } else { throw viml_printf("Compiler: unknown node: %s", viml_string(node)); } @@ -5135,9 +6517,9 @@ Compiler.prototype.compile = function(node) { } Compiler.prototype.compile_body = function(body) { - var __c10 = body; - for (var __i10 = 0; __i10 < __c10.length; ++__i10) { - var node = __c10[__i10]; + var __c15 = body; + for (var __i15 = 0; __i15 < __c15.length; ++__i15) { + var node = __c15[__i15]; this.compile(node); } } @@ -5152,7 +6534,15 @@ Compiler.prototype.compile_comment = function(node) { } Compiler.prototype.compile_excmd = function(node) { - this.out("(excmd \"%s\")", viml_escape(node.str, "\\\"")); + if (!viml_has_key(node, "block")) { + this.out("(excmd \"%s\")", viml_escape(node.str, "\\\"")); + return; + } + this.out("(excmd \"%s\"", viml_escape(node.str, "\\\"")); + this.incindent(" "); + this.compile_body(node.block.body); + this.out(")"); + this.decindent(); } Compiler.prototype.compile_function = function(node) { @@ -5165,9 +6555,9 @@ Compiler.prototype.compile_function = function(node) { viml_remove(rlist, -1); var remaining = TRUE; } - var __c11 = viml_range(viml_len(rlist)); - for (var __i11 = 0; __i11 < __c11.length; ++__i11) { - var i = __c11[__i11]; + var __c16 = viml_range(viml_len(rlist)); + for (var __i16 = 0; __i16 < __c16.length; ++__i16) { + var i = __c16[__i16]; if (i < viml_len(rlist) - viml_len(default_args)) { left += viml_printf(" %s", rlist[i]); } @@ -5223,8 +6613,15 @@ Compiler.prototype.compile_let = function(node) { this.out("(let %s %s %s)", node.op, left, right); } -// TODO: merge with s:Compiler.compile_let() ? -Compiler.prototype.compile_const = function(node) { +Compiler.prototype.compile_block = function(node) { + this.out("(block"); + this.incindent(" "); + this.compile_body(node.body); + this.out(")"); + this.decindent(); +} + +Compiler.prototype.compile_assign = function(node) { var left = ""; if (node.left !== NIL) { var left = this.compile(node.left); @@ -5236,8 +6633,17 @@ Compiler.prototype.compile_const = function(node) { } var left = "(" + left + ")"; } - var right = this.compile(node.right); - this.out("(const %s %s %s)", node.op, left, right); + if (node.right === NIL) { + this.out("(assign %s %s)", node.op, left); + } + else { + this.out("(assign %s %s %s)", node.op, left, this.compile(node.right)); + } +} + +// TODO: merge with s:Compiler.compile_let() ? +Compiler.prototype.compile_const = function(node) { + this.compile_decl(node, "const"); } Compiler.prototype.compile_unlet = function(node) { @@ -5270,9 +6676,9 @@ Compiler.prototype.compile_if = function(node) { this.incindent(" "); this.compile_body(node.body); this.decindent(); - var __c12 = node.elseif; - for (var __i12 = 0; __i12 < __c12.length; ++__i12) { - var enode = __c12[__i12]; + var __c17 = node.elseif; + for (var __i17 = 0; __i17 < __c17.length; ++__i17) { + var enode = __c17[__i17]; this.out(" elseif %s", this.compile(enode.cond)); this.incindent(" "); this.compile_body(enode.body); @@ -5300,12 +6706,12 @@ Compiler.prototype.compile_while = function(node) { Compiler.prototype.compile_for = function(node) { var left = ""; if (node.left !== NIL) { - var left = this.compile(node.left); + var left = this.compile_decl_name(node.left); } else { - var left = viml_join(node.list.map((function(vval) { return this.compile(vval); }).bind(this)), " "); + var left = viml_join(node.list.map((function(vval) { return this.compile_decl_name(vval); }).bind(this)), " "); if (node.rest !== NIL) { - left += " . " + this.compile(node.rest); + left += " . " + this.compile_decl_name(node.rest); } var left = "(" + left + ")"; } @@ -5329,9 +6735,9 @@ Compiler.prototype.compile_try = function(node) { this.out("(try"); this.incindent(" "); this.compile_body(node.body); - var __c13 = node.catch; - for (var __i13 = 0; __i13 < __c13.length; ++__i13) { - var cnode = __c13[__i13]; + var __c18 = node.catch; + for (var __i18 = 0; __i18 < __c18.length; ++__i18) { + var cnode = __c18[__i18]; if (cnode.pattern !== NIL) { this.decindent(); this.out(" catch /%s/", cnode.pattern); @@ -5388,6 +6794,15 @@ Compiler.prototype.compile_echoconsole = function(node) { this.out("(echoconsole %s)", viml_join(list, " ")); } +Compiler.prototype.compile_echowindow = function(node) { + var list = node.list.map((function(vval) { return this.compile(vval); }).bind(this)); + this.out("(echowindow %s)", viml_join(list, " ")); +} + +Compiler.prototype.compile_defer = function(node) { + this.out("(defer %s)", this.compile(node.left)); +} + Compiler.prototype.compile_execute = function(node) { var list = node.list.map((function(vval) { return this.compile(vval); }).bind(this)); this.out("(execute %s)", viml_join(list, " ")); @@ -5589,11 +7004,15 @@ Compiler.prototype.compile_method = function(node) { Compiler.prototype.compile_call = function(node) { var rlist = node.rlist.map((function(vval) { return this.compile(vval); }).bind(this)); + var left = this.compile(node.left); + if (viml_has_key(node, "type_args")) { + left += node.type_args; + } if (viml_empty(rlist)) { - return viml_printf("(%s)", this.compile(node.left)); + return viml_printf("(%s)", left); } else { - return viml_printf("(%s %s)", this.compile(node.left), viml_join(rlist, " ")); + return viml_printf("(%s %s)", left, viml_join(rlist, " ")); } } @@ -5660,9 +7079,9 @@ Compiler.prototype.compile_curlynameexpr = function(node) { Compiler.prototype.escape_string = function(str) { var m = {"\n":"\\n", "\t":"\\t", "\r":"\\r"}; var out = "\""; - var __c14 = viml_range(viml_len(str)); - for (var __i14 = 0; __i14 < __c14.length; ++__i14) { - var i = __c14[__i14]; + var __c19 = viml_range(viml_len(str)); + for (var __i19 = 0; __i19 < __c19.length; ++__i19) { + var i = __c19[__i19]; var c = str[i]; if (viml_has_key(m, c)) { out += m[c]; @@ -5677,7 +7096,55 @@ Compiler.prototype.escape_string = function(str) { Compiler.prototype.compile_lambda = function(node) { var rlist = node.rlist.map((function(vval) { return this.compile(vval); }).bind(this)); - return viml_printf("(lambda (%s) %s)", viml_join(rlist, " "), this.compile(node.left)); + if (node.left !== NIL) { + return viml_printf("(lambda (%s) %s)", viml_join(rlist, " "), this.compile(node.left)); + } + // Vim9 lambda with a block: put the statements on one line. + var compiler = new Compiler(); + compiler.compile_body(node.body); + var body = []; + var __c20 = compiler.lines; + for (var __i20 = 0; __i20 < __c20.length; ++__i20) { + var line = __c20[__i20]; + var text = ""; + var __c21 = viml_split(line, "\\zs"); + for (var __i21 = 0; __i21 < __c21.length; ++__i21) { + var c = __c21[__i21]; + if (text != "" || c != " ") { + text += c; + } + } + viml_add(body, text); + } + return viml_printf("(lambda (%s) %s)", viml_join(rlist, " "), viml_join(body, " ")); +} + +Compiler.prototype.compile_falsy = function(node) { + return viml_printf("(?? %s %s)", this.compile(node.left), this.compile(node.right)); +} + +Compiler.prototype.compile_interpolation = function(node) { + var value = node.value.map((function(vval) { return this.compile(vval); }).bind(this)); + if (viml_empty(value)) { + return "(interpolation)"; + } + else { + return viml_printf("(interpolation %s)", viml_join(value, " ")); + } +} + +Compiler.prototype.compile_tuple = function(node) { + var value = node.value.map((function(vval) { return this.compile(vval); }).bind(this)); + if (viml_empty(value)) { + return "(tuple)"; + } + else { + return viml_printf("(tuple %s)", viml_join(value, " ")); + } +} + +Compiler.prototype.compile_cast = function(node) { + return viml_printf("(cast <%s> %s)", node.type_str, this.compile(node.left)); } Compiler.prototype.compile_heredoc = function(node) { @@ -5698,11 +7165,16 @@ Compiler.prototype.compile_heredoc = function(node) { } Compiler.prototype.compile_vim9script = function(node) { - this.out("(vim9script)"); + if (node.noclear) { + this.out("(vim9script noclear)"); + } + else { + this.out("(vim9script)"); + } } Compiler.prototype.compile_def = function(node) { - var left = this.compile(node.left); + var left = this.compile(node.left) + node.attr.type_params; var rlist = node.rlist.map((function(vval) { return this.compile(vval); }).bind(this)); var default_args = node.default_args.map((function(vval) { return this.compile(vval); }).bind(this)); if (!viml_empty(rlist)) { @@ -5712,9 +7184,9 @@ Compiler.prototype.compile_def = function(node) { viml_remove(rlist, -1); var remaining = TRUE; } - var __c15 = viml_range(viml_len(rlist)); - for (var __i15 = 0; __i15 < __c15.length; ++__i15) { - var i = __c15[__i15]; + var __c22 = viml_range(viml_len(rlist)); + for (var __i22 = 0; __i22 < __c22.length; ++__i22) { + var i = __c22[__i22]; if (i < viml_len(rlist) - viml_len(default_args)) { left += viml_printf(" %s", rlist[i]); } @@ -5739,53 +7211,117 @@ Compiler.prototype.compile_def = function(node) { } Compiler.prototype.compile_var = function(node) { + this.compile_decl(node, "var"); +} + +Compiler.prototype.compile_final = function(node) { + this.compile_decl(node, "final"); +} + +// A declared name with its Vim9 type, if any: "name: type" +Compiler.prototype.compile_decl_name = function(node) { + var name = this.compile(node); + if (viml_has_key(node, "type_str") && node.type_str != "") { + name += ": " + node.type_str; + } + return name; +} + +Compiler.prototype.compile_decl = function(node, cmd) { var left = ""; if (node.left !== NIL) { - var left = this.compile(node.left); + var left = this.compile_decl_name(node.left); } else { - var left = viml_join(node.list.map((function(vval) { return this.compile(vval); }).bind(this)), " "); + var left = viml_join(node.list.map((function(vval) { return this.compile_decl_name(vval); }).bind(this)), " "); if (node.rest !== NIL) { - left += " . " + this.compile(node.rest); + left += " . " + this.compile_decl_name(node.rest); } var left = "(" + left + ")"; } - if (node.type_str != "") { - left += ": " + node.type_str; + if (node.right === NIL) { + this.out("(%s %s)", cmd, left); + } + else { + this.out("(%s %s %s %s)", cmd, node.op, left, this.compile(node.right)); } - var right = this.compile(node.right); - this.out("(var %s %s %s)", node.op, left, right); } -Compiler.prototype.compile_final = function(node) { - var left = ""; - if (node.left !== NIL) { - var left = this.compile(node.left); +Compiler.prototype.compile_export = function(node) { + this.compile_wrapper(node, "export"); +} + +Compiler.prototype.compile_wrapper = function(node, name) { + this.out("(%s", name); + this.incindent(" "); + this.compile_body(node.body); + this.out(")"); + this.decindent(); +} + +Compiler.prototype.compile_class = function(node) { + var s = node.name; + if (node.extends != "") { + s += " extends " + node.extends; } - else { - var left = viml_join(node.list.map((function(vval) { return this.compile(vval); }).bind(this)), " "); - if (node.rest !== NIL) { - left += " . " + this.compile(node.rest); - } - var left = "(" + left + ")"; + if (!viml_empty(node.implements)) { + s += " implements " + viml_join(node.implements, ", "); } - if (node.type_str != "") { - left += ": " + node.type_str; + this.out("(class %s", s); + this.incindent(" "); + this.compile_body(node.body); + this.out(")"); + this.decindent(); +} + +Compiler.prototype.compile_interface = function(node) { + var s = node.name; + if (!viml_empty(node.extends)) { + s += " extends " + viml_join(node.extends, ", "); } - var right = this.compile(node.right); - this.out("(final %s %s %s)", node.op, left, right); + this.out("(interface %s", s); + this.incindent(" "); + this.compile_body(node.body); + this.out(")"); + this.decindent(); } -Compiler.prototype.compile_export = function(node) { - this.out("(export"); +Compiler.prototype.compile_enum = function(node) { + var s = node.name; + if (!viml_empty(node.implements)) { + s += " implements " + viml_join(node.implements, ", "); + } + this.out("(enum %s", s); this.incindent(" "); + var __c23 = node.enumvalues; + for (var __i23 = 0; __i23 < __c23.length; ++__i23) { + var value = __c23[__i23]; + var rlist = value.rlist.map((function(vval) { return this.compile(vval); }).bind(this)); + if (viml_empty(rlist)) { + this.out("(%s)", value.value); + } + else { + this.out("(%s %s)", value.value, viml_join(rlist, " ")); + } + } this.compile_body(node.body); this.out(")"); this.decindent(); } +Compiler.prototype.compile_type = function(node) { + this.out("(type %s %s)", node.name, node.type_str); +} + Compiler.prototype.compile_import = function(node) { - this.out("(import \"%s\")", viml_escape(node.str, "\\\"")); + var s = this.compile(node.left); + if (node.autoload) { + var s = "autoload " + s; + } + if (node.alias != "") { + s += " as " + node.alias; + } + this.out("(import %s)", s); } // TODO: under construction @@ -6468,9 +8004,9 @@ RegexpParser.prototype.get_token_sq_char_class = function() { var r = this.reader.read_alpha(); if (this.reader.p(0) == ":" && this.reader.p(1) == "]") { this.reader.seek_cur(2); - var __c16 = class_names; - for (var __i16 = 0; __i16 < __c16.length; ++__i16) { - var name = __c16[__i16]; + var __c24 = class_names; + for (var __i24 = 0; __i24 < __c24.length; ++__i24) { + var name = __c24[__i24]; if (r == name) { return "[:" + name + ":]"; } @@ -6603,9 +8139,9 @@ RegexpParser.prototype.getoctchrs = function() { RegexpParser.prototype.gethexchrs = function(n) { var r = ""; - var __c17 = viml_range(n); - for (var __i17 = 0; __i17 < __c17.length; ++__i17) { - var i = __c17[__i17]; + var __c25 = viml_range(n); + for (var __i25 = 0; __i25 < __c25.length; ++__i25) { + var i = __c25[__i25]; var c = this.reader.peek(); if (!isxdigit(c)) { break; diff --git a/py/vimlfunc.py b/py/vimlfunc.py index 12cf5ce..7e35441 100644 --- a/py/vimlfunc.py +++ b/py/vimlfunc.py @@ -73,6 +73,7 @@ class AttributeDict(dict): "^\\h": "^[A-Za-z_]", "^\\s": "^\\s", "^\\s*\\\\": "^\\s*\\\\", + "^\\s*[\"#]\\\\ ": "^\\s*[\"#]\\\\ ", "^[ \\t]$": "^[ \\t]$", "^[A-Za-z]$": "^[A-Za-z]$", "^[0-9A-Za-z]$": "^[0-9A-Za-z]$", diff --git a/py/vimlparser.py b/py/vimlparser.py index 1a3be50..013806f 100644 --- a/py/vimlparser.py +++ b/py/vimlparser.py @@ -73,6 +73,7 @@ class AttributeDict(dict): "^\\h": "^[A-Za-z_]", "^\\s": "^\\s", "^\\s*\\\\": "^\\s*\\\\", + "^\\s*[\"#]\\\\ ": "^\\s*[\"#]\\\\ ", "^[ \\t]$": "^[ \\t]$", "^[A-Za-z]$": "^[A-Za-z]$", "^[0-9A-Za-z]$": "^[0-9A-Za-z]$", @@ -320,6 +321,26 @@ def viml_stridx(a, b): NODE_EXPORT = 105 NODE_IMPORT = 106 NODE_VIM9SCRIPT = 107 +NODE_TUPLE = 108 +NODE_CAST = 109 +NODE_ASSIGN = 110 +NODE_BLOCK = 111 +NODE_ENDBLOCK = 112 +NODE_CLASS = 113 +NODE_ENDCLASS = 114 +NODE_INTERFACE = 115 +NODE_ENDINTERFACE = 116 +NODE_ENUM = 117 +NODE_ENDENUM = 118 +NODE_ENUMVALUE = 119 +NODE_TYPE = 120 +NODE_PUBLIC = 121 +NODE_STATIC = 122 +NODE_ABSTRACT = 123 +NODE_FALSY = 124 +NODE_INTERPOLATION = 125 +NODE_DEFER = 126 +NODE_ECHOWINDOW = 127 TOKEN_EOF = 1 TOKEN_EOL = 2 TOKEN_SPACE = 3 @@ -391,7 +412,11 @@ def viml_stridx(a, b): TOKEN_HEREDOC = 69 TOKEN_LSHIFT = 70 TOKEN_RSHIFT = 71 +TOKEN_FATARROW = 72 +TOKEN_QUESTIONQUESTION = 73 MAX_FUNC_ARGS = 20 +# Binary operators that continue a Vim9 expression from the previous line. +VIM9_CONTINUATION_OPS = AttributeDict({"+": 1, "-": 1, "*": 1, "/": 1, "%": 1, "..": 1, "||": 1, "&&": 1, "??": 1, "?": 1, ":": 1, "<<": 1, ">>": 1, "==": 1, "==?": 1, "==#": 1, "!=": 1, "!=?": 1, "!=#": 1, ">=": 1, ">=?": 1, ">=#": 1, "<=": 1, "<=?": 1, "<=#": 1, "=~": 1, "=~?": 1, "=~#": 1, "!~": 1, "!~?": 1, "!~#": 1, ">": 1, ">?": 1, ">#": 1, "<": 1, "": self.parse_one_cmd() @@ -678,33 +764,274 @@ def parse(self, reader): self.check_missing_endtry("TOPLEVEL", self.reader.getpos()) self.check_missing_endwhile("TOPLEVEL", self.reader.getpos()) self.check_missing_endfor("TOPLEVEL", self.reader.getpos()) + if self.context[0].type == NODE_BLOCK: + raise VimLParserException(Err("E1026: Missing }", self.reader.getpos())) + elif self.context[0].type == NODE_CLASS: + raise VimLParserException(Err("E1101: Missing :endclass", self.reader.getpos())) + elif self.context[0].type == NODE_INTERFACE: + raise VimLParserException(Err("E1101: Missing :endinterface", self.reader.getpos())) + elif self.context[0].type == NODE_ENUM: + raise VimLParserException(Err("E1101: Missing :endenum", self.reader.getpos())) self.pop_context() return toplevel def parse_one_cmd(self): self.ea = ExArg() + self.vim9cmd = -1 if self.reader.peekn(2) == "#!": self.parse_hashbang() self.reader.get() return - self.reader.skip_white_and_colon() + vim9 = self.isvim9() + colon = FALSE + while iswhite(self.reader.peekn(1)) or self.reader.peekn(1) == ":": + if self.reader.peekn(1) == ":": + colon = TRUE + self.reader.seek_cur(1) if self.reader.peekn(1) == "": self.reader.get() return - if self.reader.peekn(1) == "\"": + if self.reader.peekn(1) == "\"" and not self.isvim9(): self.parse_comment() self.reader.get() return - if self.vim9script and self.reader.peekn(1) == "#": + if self.isvim9() and self.reader.peekn(1) == "#": self.parse_comment() self.reader.get() return + if self.context[0].type == NODE_ENUM and not self.context[0].values_done and self.parse_enum_values(): + self.parse_trail() + return self.ea.linepos = self.reader.getpos() self.parse_command_modifiers() - self.parse_range() + vim9 = self.isvim9() + if vim9: + # In Vim9 script a range must be preceded by a colon, without it the line + # may be an expression or assignment. + self.reader.skip_white() + if self.reader.peekn(1) == ":": + colon = TRUE + self.reader.skip_white_and_colon() + if colon: + self.parse_range() + elif self.parse_vim9_statement(): + self.parse_trail() + return + else: + self.parse_range() self.parse_command() self.parse_trail() + # Recognize a Vim9 expression or assignment without :eval, :call or :let, + # like find_ex_command() in Vim. Return TRUE when the line was parsed. + def parse_vim9_statement(self): + r = self.reader + pos = r.tell() + self.ea.cmdpos = r.getpos() + c = r.peekn(1) + if c == "{": + # "{" by itself is the start of a block. + r.getn(1) + r.skip_white() + block = self.ends_excmds(r.peek()) + r.seek_set(pos) + if block: + return FALSE + self.parse_vim9_expr_cmd() + return TRUE + elif c == "(" or c == "'" or c == "\"" or c == "$" and (r.p(1) == "'" or r.p(1) == "\"") or c == "0" and r.p(1) == "z": + self.parse_vim9_expr_cmd() + return TRUE + elif c == "[": + if self.is_vim9_list_assign(): + self.parse_vim9_assign() + else: + self.parse_vim9_expr_cmd() + return TRUE + elif c == "&" or c == "$" or c == "@" and r.p(1) != "": + self.parse_vim9_assign_or_expr() + return TRUE + elif (c == "+" or c == "-") and r.p(1) == c: + self.parse_vim9_increment() + return TRUE + elif isdigit(c): + r.read_digit() + r.skip_white() + method = r.peekn(2) == "->" + r.seek_set(pos) + if method: + self.parse_vim9_expr_cmd() + return method + elif not iswordc1(c): + return FALSE + name = r.read_vim9_name() + c = r.peekn(1) + if c == "(" or c == "<" and self.is_generic_args(): + # "funcname(" is always a function call. + r.seek_set(pos) + self.parse_vim9_expr_cmd() + return TRUE + elif viml_stridx(name, ":") == 1 or c == "[" or c == "." and iswordc1(r.p(1)): + # "g:name", "name[idx]" and "name.member" start an expression or + # assignment. + r.seek_set(pos) + self.parse_vim9_assign_or_expr() + return TRUE + r.skip_white() + result = FALSE + if r.peekn(2) == "->": + result = TRUE + elif self.peek_assign_op() != "": + # "name = expr" is an assignment when "name" is a variable or not a + # command. + result = viml_has_key(self.declared, name) or self.is_vim9_command(pos) == FALSE + elif self.ends_excmds(r.peek()): + # A variable followed by an operator on the next line. A variable alone + # has no effect, then it is a command like :new. + result = viml_has_key(self.declared, name) and (self.is_vim9_command(pos) == FALSE or self.vim9_line_continues()) + r.seek_set(pos) + if result: + self.parse_vim9_assign_or_expr() + return result + + # Return TRUE when the next line continues the expression on this line. + def vim9_line_continues(self): + pos = self.reader.tell() + if self.reader.peek() == "#": + self.reader.getn(-1) + result = self.reader.peek() == "" and ExprTokenizer(self.reader, TRUE).next_line_continues() + self.reader.seek_set(pos) + return result + + # Return TRUE when the text at reader position "pos" is an Ex command that + # exists in Vim9 script. + def is_vim9_command(self, cmdpos): + pos = self.reader.tell() + self.reader.seek_set(cmdpos) + cmd = self.find_command() + self.reader.seek_set(pos) + if cmd is NIL: + return FALSE + return not is_removed_in_vim9(cmd.name) + + # Return the assignment operator at the cursor, or an empty string. + def peek_assign_op(self): + s3 = self.reader.peekn(3) + s2 = self.reader.peekn(2) + op = "" + if s3 == "..=" or s3 == "=<<": + op = s3 + elif s2 == "+=" or s2 == "-=" or s2 == "*=" or s2 == "/=" or s2 == "%=" or s2 == ".=": + op = s2 + elif s2 == "==" or s2 == "=~" or s2 == "=>": + return "" + elif self.reader.peekn(1) == "=": + op = "=" + return op + + # Return TRUE when the generic type arguments of a function call follow: + # "(". + def is_generic_args(self): + r = self.reader + pos = r.tell() + r.getn(1) + depth = 1 + while depth > 0: + c = r.peekn(1) + if c == "<": + depth += 1 + elif c == ">": + depth -= 1 + elif not iswordc(c) and c != "," and c != " " and c != "(" and c != ")" and c != ":" and c != ".": + r.seek_set(pos) + return FALSE + r.getn(1) + result = r.peekn(1) == "(" + r.seek_set(pos) + return result + + # Return TRUE when "[a, b] =" follows: the list is closed on this line and + # followed by an assignment operator. + def is_vim9_list_assign(self): + r = self.reader + pos = r.tell() + depth = 0 + while TRUE: + c = r.peekn(1) + if c == "": + r.seek_set(pos) + return FALSE + r.getn(1) + if c == "[": + depth += 1 + elif c == "]": + depth -= 1 + if depth == 0: + break + elif c == "'" or c == "\"": + while r.peekn(1) != "" and r.peekn(1) != c: + r.getn(1) + r.getn(1) + r.skip_white() + op = self.peek_assign_op() + r.seek_set(pos) + return op != "" and op != "=<<" + + # Vim9 expression used as a command. A function call is like :call, any + # other expression is like :eval. + def parse_vim9_expr_cmd(self): + left = self.parse_expr() + if left.type == NODE_CALL: + node = Node(NODE_EXCALL) + else: + node = Node(NODE_EVAL) + node.pos = self.ea.cmdpos + node.ea = self.ea + node.left = left + self.add_node(node) + + def parse_vim9_assign_or_expr(self): + pos = self.reader.tell() + self.parse_lvalue() + self.reader.skip_white() + op = self.peek_assign_op() + self.reader.seek_set(pos) + if op == "": + self.parse_vim9_expr_cmd() + else: + self.parse_vim9_assign() + + # Vim9 assignment without :let: "name = expr", "[a, b] = expr", "name += expr" + def parse_vim9_assign(self): + lhs = self.parse_letlhs() + self.reader.skip_white() + node = Node(NODE_ASSIGN) + node.pos = self.ea.cmdpos + node.ea = self.ea + node.op = self.peek_assign_op() + node.left = lhs.left + node.list = lhs.list + node.rest = lhs.rest + self.reader.getn(viml_len(node.op)) + if node.op == "=<<": + self.reader.skip_white() + node.right = self.parse_heredoc(self.heredoc_prefix()) + else: + node.right = self.parse_expr() + self.add_node(node) + + # Vim9 "++var" and "--var" + def parse_vim9_increment(self): + node = Node(NODE_ASSIGN) + node.pos = self.ea.cmdpos + node.ea = self.ea + node.op = self.reader.getn(2) + node.left = self.parse_lvalue() + node.list = NIL + node.rest = NIL + node.right = NIL + self.add_node(node) + # FIXME: def parse_command_modifiers(self): modifiers = [] @@ -715,9 +1042,23 @@ def parse_command_modifiers(self): d = self.reader.read_digit() self.reader.skip_white() k = self.reader.read_alpha() + if k == "vim" and self.reader.peekn(1) == "9": + k += self.reader.read_alnum() c = self.reader.peekn(1) self.reader.skip_white() - if viml_stridx("aboveleft", k) == 0 and viml_len(k) >= 3: + if self.isvim9() and (c == "(" or c == "[" or c == "." or c == ":" or self.peek_assign_op() != "" or self.reader.peekn(2) == "->"): + # A Vim9 variable or function, not a modifier. + self.reader.seek_set(pos) + break + elif viml_stridx("vim9cmd", k) == 0 and viml_len(k) >= 4: + # vim9\%[cmd] + viml_add(modifiers, AttributeDict({"name": "vim9cmd"})) + self.vim9cmd = TRUE + elif viml_stridx("legacy", k) == 0 and viml_len(k) >= 3: + # leg\%[acy] + viml_add(modifiers, AttributeDict({"name": "legacy"})) + self.vim9cmd = FALSE + elif viml_stridx("aboveleft", k) == 0 and viml_len(k) >= 3: # abo\%[veleft] viml_add(modifiers, AttributeDict({"name": "aboveleft"})) elif viml_stridx("belowright", k) == 0 and viml_len(k) >= 3: @@ -888,7 +1229,7 @@ def parse_pattern(self, delimiter): def parse_command(self): self.reader.skip_white_and_colon() self.ea.cmdpos = self.reader.getpos() - if self.reader.peekn(1) == "" or self.reader.peekn(1) == "\"" or self.vim9script and self.reader.peekn(1) == "#": + if self.reader.peekn(1) == "" or self.ends_excmds(self.reader.peekn(1)): if not viml_empty(self.ea.modifiers) or not viml_empty(self.ea.range): self.parse_cmd_modifier_range() return @@ -896,6 +1237,15 @@ def parse_command(self): if self.ea.cmd is NIL: self.reader.setpos(self.ea.cmdpos) raise VimLParserException(Err(viml_printf("E492: Not an editor command: %s", self.reader.peekline()), self.ea.cmdpos)) + if self.isvim9() and is_removed_in_vim9(self.ea.cmd.name): + self.reader.setpos(self.ea.cmdpos) + raise VimLParserException(Err(viml_printf("E1100: Command not supported in Vim9 script (missing :var?): %s", self.reader.peekline()), self.ea.cmdpos)) + # In legacy script :final is an abbreviation of :finally. + if self.ea.cmd.name == "final" and not self.isvim9(): + for x in self.builtin_commands: + if x.name == "finally": + self.ea.cmd = x + break if self.reader.peekn(1) == "!" and self.ea.cmd.name != "substitute" and self.ea.cmd.name != "smagic" and self.ea.cmd.name != "snomagic": self.reader.getn(1) self.ea.forceit = TRUE @@ -1049,6 +1399,34 @@ def _parse_command(self, parser): self.parse_cmd_export() elif parser == "parse_cmd_import": self.parse_cmd_import() + elif parser == "parse_cmd_abstract": + self.parse_cmd_abstract() + elif parser == "parse_cmd_class": + self.parse_cmd_class() + elif parser == "parse_cmd_endclass": + self.parse_cmd_endclass() + elif parser == "parse_cmd_interface": + self.parse_cmd_interface() + elif parser == "parse_cmd_endinterface": + self.parse_cmd_endinterface() + elif parser == "parse_cmd_enum": + self.parse_cmd_enum() + elif parser == "parse_cmd_endenum": + self.parse_cmd_endenum() + elif parser == "parse_cmd_type": + self.parse_cmd_type() + elif parser == "parse_cmd_public": + self.parse_cmd_public() + elif parser == "parse_cmd_static": + self.parse_cmd_static() + elif parser == "parse_cmd_defer": + self.parse_cmd_defer() + elif parser == "parse_cmd_echowindow": + self.parse_cmd_echowindow() + elif parser == "parse_cmd_block": + self.parse_cmd_block() + elif parser == "parse_cmd_endblock": + self.parse_cmd_endblock() else: raise VimLParserException(viml_printf("unknown parser: %s", viml_string(parser))) @@ -1061,7 +1439,7 @@ def find_command(self): elif c == "s" and viml_eqregh(self.reader.peekn(5), "\\v^s%(c[^sr][^i][^p]|g|i[^mlg]|I|r[^e])"): self.reader.getn(1) name = "substitute" - elif viml_eqregh(c, "[@*!=><&~#]"): + elif viml_eqregh(c, "[@*!=><&~#]") or c == "{" or c == "}": self.reader.getn(1) name = c elif self.reader.peekn(2) == "py": @@ -1172,7 +1550,7 @@ def read_cmdarg(self): def parse_comment(self): npos = self.reader.getpos() c = self.reader.get() - if c != "\"" and not (self.vim9script and c == "#"): + if c != "\"" and c != "#": raise VimLParserException(Err(viml_printf("unexpected character: %s", c), npos)) node = Node(NODE_COMMENT) node.pos = npos @@ -1190,9 +1568,10 @@ def parse_trail(self): elif c == "|": self.reader.get() elif c == "\"": + # Also in Vim9 script a double quote after a command starts a comment. self.parse_comment() self.reader.get() - elif self.vim9script and c == "#": + elif self.isvim9() and c == "#": self.parse_comment() self.reader.get() else: @@ -1226,10 +1605,21 @@ def parse_cmd_common(self): node.ea = self.ea node.str = self.reader.getstr(self.ea.linepos, end) self.add_node(node) + if (self.ea.cmd.name == "command" or self.ea.cmd.name == "autocmd") and ends_with_block(node.str): + # The commands of a user command or autocommand in a block use Vim9 + # syntax: {cmd} ... } + block = Node(NODE_BLOCK) + block.pos = self.ea.cmdpos + block.ea = self.ea + block.body = [] + block.endblock = NIL + node.block = block + self.push_context(block) def separate_nextcmd(self): if self.ea.cmd.name == "vimgrep" or self.ea.cmd.name == "vimgrepadd" or self.ea.cmd.name == "lvimgrep" or self.ea.cmd.name == "lvimgrepadd": self.skip_vimgrep_pat() + vim9 = self.isvim9() pc = "" end = self.reader.getpos() nospend = end @@ -1256,7 +1646,7 @@ def separate_nextcmd(self): if c != "`": raise VimLParserException(Err(viml_printf("unexpected character: %s", c), self.reader.getpos())) self.reader.getn(1) - elif c == "|" or c == "\n" or c == "\"" and not viml_eqregh(self.ea.cmd.flags, "\\") and (self.ea.cmd.name != "@" and self.ea.cmd.name != "*" or self.reader.getpos() != self.ea.argpos) and (self.ea.cmd.name != "redir" or self.reader.getpos().i != self.ea.argpos.i + 1 or pc != "@") or self.vim9script and c == "#" and iswhite(pc) and not viml_eqregh(self.ea.cmd.flags, "\\"): + elif c == "|" or c == "\n" or c == "\"" and not vim9 and not viml_eqregh(self.ea.cmd.flags, "\\") and (self.ea.cmd.name != "@" and self.ea.cmd.name != "*" or self.reader.getpos() != self.ea.argpos) and (self.ea.cmd.name != "redir" or self.reader.getpos().i != self.ea.argpos.i + 1 or pc != "@") or vim9 and c == "#" and iswhite(pc) and not viml_eqregh(self.ea.cmd.flags, "\\"): has_cpo_bar = FALSE # &cpoptions =~ 'b' if (not has_cpo_bar or not viml_eqregh(self.ea.cmd.flags, "\\")) and pc == "\\": @@ -1505,7 +1895,7 @@ def parse_cmd_delfunction(self): self.add_node(node) def parse_cmd_return(self): - if self.find_context(NODE_FUNCTION) == -1 and self.find_context(NODE_DEF) == -1: + if self.find_context(NODE_FUNCTION) == -1 and self.find_context(NODE_DEF) == -1 and self.find_context(NODE_LAMBDA) == -1: raise VimLParserException(Err("E133: :return not inside a function", self.ea.cmdpos)) node = Node(NODE_RETURN) node.pos = self.ea.cmdpos @@ -1526,7 +1916,11 @@ def parse_cmd_call(self): if self.ends_excmds(c): raise VimLParserException(Err("E471: Argument required", self.reader.getpos())) node.left = self.parse_expr() - if node.left.type != NODE_CALL: + # A method call may follow the function call: call Func()->Method() + base = node.left + while base.type == NODE_METHOD: + base = base.left + if base.type != NODE_CALL: raise VimLParserException(Err("Not an function call", node.left.pos)) self.add_node(node) @@ -1609,25 +2003,7 @@ def parse_cmd_let(self): self.reader.getn(viml_len(s2)) self.reader.skip_white() node.op = s2 - # compute allowed prefix for heredoc end marker (e.g. EOF) - pos = self.reader.tell() - while self.reader.tell() > 0: - if self.reader.peek() == "": - self.reader.seek_cur(1) - break - self.reader.seek_cur(-1) - prefix = "" - while TRUE: - c = self.reader.getn(1) - if c == ":": - # any presence of leading ':' disables prefix for heredoc end marker - prefix = "" - break - elif not iswhite(c): - break - prefix += c - self.reader.seek_set(pos) - node.right = self.parse_heredoc(prefix) + node.right = self.parse_heredoc(self.heredoc_prefix()) self.add_node(node) return elif s1 == "=": @@ -1638,7 +2014,32 @@ def parse_cmd_let(self): node.right = self.parse_expr() self.add_node(node) + # Compute the allowed prefix for a heredoc end marker (e.g. EOF): the indent + # of the command line. + def heredoc_prefix(self): + pos = self.reader.tell() + while self.reader.tell() > 0: + if self.reader.peek() == "": + self.reader.seek_cur(1) + break + self.reader.seek_cur(-1) + prefix = "" + while TRUE: + c = self.reader.getn(1) + if c == ":": + # any presence of leading ':' disables prefix for heredoc end marker + prefix = "" + break + elif not iswhite(c): + break + prefix += c + self.reader.seek_set(pos) + return prefix + def parse_cmd_const(self): + if self.isvim9(): + self.parse_vim9_decl(NODE_CONST) + return pos = self.reader.tell() self.reader.skip_white() # :const @@ -1667,10 +2068,16 @@ def parse_cmd_const(self): self.add_node(node) def parse_cmd_vim9script(self): - self.reader.skip_white() node = Node(NODE_VIM9SCRIPT) node.pos = self.ea.cmdpos node.ea = self.ea + node.noclear = FALSE + self.reader.skip_white() + pos = self.reader.tell() + if self.reader.read_alpha() == "noclear": + node.noclear = TRUE + else: + self.reader.seek_set(pos) self.vim9script = 1 self.add_node(node) @@ -1688,6 +2095,12 @@ def parse_cmd_def(self): self.parse_cmd_common() return left = self.parse_lvalue_func() + # Generic function: :def {name}<{type}, ...>( + type_params = "" + if self.reader.peekn(1) == "<": + while self.reader.peekn(1) != "" and self.reader.peekn(1) != ">": + type_params += self.reader.getn(1) + type_params += self.reader.getn(1) self.reader.skip_white() # :def {name} if self.reader.peekn(1) != "(": @@ -1702,85 +2115,76 @@ def parse_cmd_def(self): node.left = left node.rlist = [] node.default_args = [] - node.attr = AttributeDict({"range": 0, "abort": 0, "dict": 0, "closure": 0, "return_type": ""}) + node.attr = AttributeDict({"range": 0, "abort": 0, "dict": 0, "closure": 0, "return_type": "", "type_params": type_params}) node.enddef = NIL + # The arguments use Vim9 syntax, also in a legacy script. + self.add_node(node) + self.push_context(node) self.reader.getn(1) - self.reader.skip_white() - if self.reader.peekn(1) == ")": - self.reader.getn(1) - else: - named = AttributeDict({}) - while TRUE: - varnode = Node(NODE_IDENTIFIER) - self.reader.skip_white() - varnode.type_str = "" - # Check for ...name (variadic) - if self.reader.peekn(3) == "...": - self.reader.getn(3) - self.reader.skip_white() - vname = self.reader.read_word() - varnode.pos = self.reader.getpos() - varnode.value = "..." + vname - # Optionally read type annotation - self.reader.skip_white() - if self.reader.peekn(1) == ":": - self.reader.getn(1) - self.reader.skip_white() - varnode.type_str = self.read_type() - viml_add(node.rlist, varnode) - self.reader.skip_white() - if self.reader.peekn(1) == ")": - self.reader.getn(1) - break - else: - raise VimLParserException(Err(viml_printf("E475: Invalid argument: %s", self.reader.peekn(1)), self.reader.getpos())) - npos = self.reader.getpos() - pname = self.reader.read_word() - if pname == "": - if self.reader.peekn(1) == ")": - self.reader.getn(1) - break - raise VimLParserException(Err(viml_printf("E475: Invalid argument: %s", self.reader.peekn(1)), self.reader.getpos())) - if viml_has_key(named, pname): - raise VimLParserException(Err(viml_printf("E853: Duplicate argument name: %s", pname), npos)) - named[pname] = 1 - varnode.pos = npos - varnode.value = pname - viml_add(node.rlist, varnode) - # Check for type annotation - self.reader.skip_white() - if self.reader.peekn(1) == ":": - self.reader.getn(1) - self.reader.skip_white() - varnode.type_str = self.read_type() - # Check for default value + named = AttributeDict({}) + while TRUE: + self.skip_vim9_white() + if self.reader.peekn(1) == ")": + self.reader.getn(1) + break + varnode = Node(NODE_IDENTIFIER) + varnode.pos = self.reader.getpos() + varnode.type_str = "" + variadic = self.reader.peekn(3) == "..." + if variadic: + self.reader.getn(3) + pname = self.reader.read_word() + if pname == "this" and self.reader.peekn(1) == ".": + # constructor argument that sets an object variable: this.name + pname += self.reader.getn(1) + self.reader.read_word() + if pname == "": + raise VimLParserException(Err(viml_printf("E475: Invalid argument: %s", self.reader.peekn(1)), self.reader.getpos())) + if viml_has_key(named, pname) and pname != "_": + raise VimLParserException(Err(viml_printf("E853: Duplicate argument name: %s", pname), varnode.pos)) + named[pname] = 1 + self.declared[pname] = 1 + varnode.value = pname + if variadic: + varnode.value = "..." + pname + viml_add(node.rlist, varnode) + # Check for type annotation + if self.reader.peekn(1) == ":": + self.reader.getn(1) self.reader.skip_white() - if self.reader.peekn(1) == "=": - self.reader.getn(1) - self.reader.skip_white() - viml_add(node.default_args, self.parse_expr()) - elif viml_len(node.default_args) > 0: - raise VimLParserException(Err("E989: Non-default argument follows default argument", varnode.pos)) + varnode.type_str = self.read_type() + # Check for default value + self.reader.skip_white() + if self.reader.peekn(1) == "=" and not variadic: + self.reader.getn(1) self.reader.skip_white() - if self.reader.peekn(1) == ",": - self.reader.getn(1) - self.reader.skip_white() - if self.reader.peekn(1) == ")": - self.reader.getn(1) - break - elif self.reader.peekn(1) == ")": - self.reader.getn(1) - break - else: - raise VimLParserException(Err(viml_printf("E475: Invalid argument: %s", self.reader.peekn(1)), self.reader.getpos())) + viml_add(node.default_args, self.parse_expr()) + elif viml_len(node.default_args) > 0 and not variadic: + raise VimLParserException(Err("E989: Non-default argument follows default argument", varnode.pos)) + self.skip_vim9_white() + if self.reader.peekn(1) == ",": + self.reader.getn(1) + elif self.reader.peekn(1) != ")": + raise VimLParserException(Err(viml_printf("E475: Invalid argument: %s", self.reader.peekn(1)), self.reader.getpos())) # Check for return type annotation ': type' self.reader.skip_white() if self.reader.peekn(1) == ":": self.reader.getn(1) self.reader.skip_white() node.attr.return_type = self.read_type() - self.add_node(node) - self.push_context(node) + # A method in an interface and an abstract method have no body. + if self.abstract or self.context[1].type == NODE_INTERFACE: + self.pop_context() + + # Skip white space, comments and line breaks, e.g. in the argument list of a + # :def function. + def skip_vim9_white(self): + while TRUE: + self.reader.skip_white() + if self.reader.peek() == "#": + self.reader.getn(-1) + if self.reader.peek() != "": + break + self.reader.get() def read_type(self): type_str = "" @@ -1791,6 +2195,11 @@ def read_type(self): type_str += self.reader.getn(1) else: break + # Handle func: rettype + if type_str == "func" and self.reader.peekn(1) == ":" and iswhite(self.reader.p(1)): + self.reader.getn(1) + self.reader.skip_white() + return type_str + ": " + self.read_type() # Handle generics: type<...> if self.reader.peekn(1) == "<": type_str += self.reader.getn(1) @@ -1820,11 +2229,37 @@ def read_type(self): # Check for ': rettype' after func params self.reader.skip_white() if self.reader.peekn(1) == ":": - type_str += self.reader.getn(1) + self.reader.getn(1) self.reader.skip_white() - type_str += self.read_type() + type_str += ": " + self.read_type() return type_str + # Parse the statements of a Vim9 lambda "(args) => {", up to the "}" at the + # start of a line. Only a comment may follow the "{". + def parse_lambda_block(self, node): + ea = self.ea + vim9cmd = self.vim9cmd + self.reader.skip_white() + if self.reader.peek() == "#": + self.reader.getn(-1) + if self.reader.peek() != "": + raise VimLParserException(Err(viml_printf("E488: Trailing characters: %s", self.reader.peekline()), self.reader.getpos())) + self.reader.get() + self.push_context(node) + while TRUE: + if self.reader.peek() == "": + raise VimLParserException(Err("E1171: Missing } after inline function", self.reader.getpos())) + pos = self.reader.tell() + self.reader.skip_white() + if self.context[0] is node and self.reader.peek() == "}": + self.reader.get() + break + self.reader.seek_set(pos) + self.parse_one_cmd() + self.pop_context() + self.ea = ea + self.vim9cmd = vim9cmd + def parse_cmd_enddef(self): self.check_missing_endif("ENDDEF", self.ea.cmdpos) self.check_missing_endtry("ENDDEF", self.ea.cmdpos) @@ -1840,164 +2275,349 @@ def parse_cmd_enddef(self): self.pop_context() def parse_cmd_var(self): + self.parse_vim9_decl(NODE_VAR) + + def parse_cmd_final(self): + self.parse_vim9_decl(NODE_FINAL) + + # Vim9 declaration with :var, :final or :const: + # var name[: type] [= expr] + # var [name[: type], ...[; rest]] = expr + # var name[: type] =<< [trim] [eval] END + def parse_vim9_decl(self, type): pos = self.reader.tell() self.reader.skip_white() - # :var + # :var without argument lists variables if self.ends_excmds(self.reader.peek()): self.reader.seek_set(pos) self.parse_cmd_common() return - # Read variable name directly (avoid LvalueParser eating ':' as part of name) - npos = self.reader.getpos() - vname = self.reader.read_word() - if vname == "": - self.reader.seek_set(pos) - self.parse_cmd_common() - return - left = Node(NODE_IDENTIFIER) - left.pos = npos - left.value = vname - self.reader.skip_white() - # Check for type annotation - type_str = "" - if self.reader.peekn(1) == ":": - self.reader.getn(1) - self.reader.skip_white() - type_str = self.read_type() - self.reader.skip_white() - s1 = self.reader.peekn(1) - s2 = self.reader.peekn(2) - if s2 == "..": - s2 = self.reader.peekn(3) - # :var {var-name} (no assignment) - if self.ends_excmds(s1) or s2 != "+=" and s2 != "-=" and s2 != ".=" and s2 != "..=" and s2 != "*=" and s2 != "/=" and s2 != "%=" and s1 != "=": - self.reader.seek_set(pos) - self.parse_cmd_common() - return - # :var left op right - node = Node(NODE_VAR) + node = Node(type) node.pos = self.ea.cmdpos node.ea = self.ea node.op = "" - node.left = left + node.left = NIL node.list = NIL node.rest = NIL node.right = NIL - node.type_str = type_str - if s2 == "+=" or s2 == "-=" or s2 == ".=" or s2 == "..=" or s2 == "*=" or s2 == "/=" or s2 == "%=": - self.reader.getn(viml_len(s2)) - node.op = s2 - elif s1 == "=": + node.type_str = "" + if self.reader.peekn(1) == "[": self.reader.getn(1) - node.op = s1 + node.list = [] + while TRUE: + viml_add(node.list, self.parse_vim9_decl_name()) + self.reader.skip_white() + c = self.reader.getn(1) + if c == ";": + node.rest = self.parse_vim9_decl_name() + self.reader.skip_white() + c = self.reader.getn(1) + if c == "]": + break + elif c != ",": + raise VimLParserException(Err(viml_printf("E475: Invalid argument: %s", c), self.reader.getpos())) + for x in node.list: + self.declare(x) + self.declare(node.rest) else: - raise VimLParserException("NOT REACHED") - node.right = self.parse_expr() + node.left = self.parse_vim9_decl_name() + node.type_str = node.left.type_str + self.declare(node.left) + self.reader.skip_white() + node.op = self.peek_assign_op() + self.reader.getn(viml_len(node.op)) + if node.op == "=<<": + self.reader.skip_white() + node.right = self.parse_heredoc(self.heredoc_prefix()) + elif node.op != "": + node.right = self.parse_expr() self.add_node(node) - def parse_cmd_final(self): + # Variable name with an optional type in a Vim9 declaration: "name: type" + def parse_vim9_decl_name(self): + self.reader.skip_white() + node = Node(NODE_IDENTIFIER) + node.pos = self.reader.getpos() + node.value = self.reader.read_vim9_name() + node.type_str = "" + if node.value == "": + raise VimLParserException(Err(viml_printf("E475: Invalid argument: %s", self.reader.peekline()), node.pos)) + if self.reader.peekn(1) == ":": + self.reader.getn(1) + self.reader.skip_white() + node.type_str = self.read_type() + return node + + def parse_cmd_export(self): + self.parse_wrapper(NODE_EXPORT) + + def parse_cmd_public(self): + self.parse_wrapper(NODE_PUBLIC) + + def parse_cmd_static(self): + self.parse_wrapper(NODE_STATIC) + + def parse_cmd_abstract(self): + self.abstract = TRUE + self.parse_wrapper(NODE_ABSTRACT) + self.abstract = FALSE + + # Parse a command that applies to the following command, like :export + # and :static. The nodes of the following command go into the body. + def parse_wrapper(self, type): + self.reader.skip_white() + wrapper_pos = self.ea.cmdpos + # Re-find the inner command + self.ea.cmdpos = self.reader.getpos() + self.ea.cmd = self.find_command() + if self.ea.cmd is NIL: + raise VimLParserException(Err(viml_printf("E492: Not an editor command: %s", self.reader.peekline()), self.ea.cmdpos)) + if self.reader.peekn(1) == "!" and self.ea.cmd.name != "substitute" and self.ea.cmd.name != "smagic" and self.ea.cmd.name != "snomagic": + self.reader.getn(1) + self.ea.forceit = TRUE + self.reader.skip_white() + self.ea.argpos = self.reader.getpos() + wrapper = Node(type) + wrapper.pos = wrapper_pos + wrapper.ea = self.ea + wrapper.body = [] + # Remember current context body position + ctx = self.context[0] + before = viml_len(ctx.body) + # Parse the inner command + self._parse_command(self.ea.cmd.parser) + # Move newly-added nodes into the wrapper body + while viml_len(ctx.body) > before: + moved_node = ctx.body[before] + viml_remove(ctx.body, before) + viml_add(wrapper.body, moved_node) + viml_add(ctx.body, wrapper) + + # :class {name} [extends {class}] [implements {interface}, ...] + def parse_cmd_class(self): + node = Node(NODE_CLASS) + node.pos = self.ea.cmdpos + node.ea = self.ea + node.name = self.read_class_name() + node.extends = "" + node.implements = [] + node.body = [] + node.endclass = NIL + while TRUE: + self.reader.skip_white() + pos = self.reader.tell() + key = self.reader.read_alpha() + if key == "extends": + self.reader.skip_white() + node.extends = self.read_type() + elif key == "implements" or key == "specifies": + node.implements = self.read_type_list() + else: + self.reader.seek_set(pos) + break + self.add_node(node) + self.push_context(node) + + def parse_cmd_endclass(self): + self.parse_class_end(NODE_CLASS, "E1316: Class can only be defined in Vim9 script") + + # :interface {name} [extends {interface}, ...] + def parse_cmd_interface(self): + node = Node(NODE_INTERFACE) + node.pos = self.ea.cmdpos + node.ea = self.ea + node.name = self.read_class_name() + node.extends = [] + node.body = [] + node.endinterface = NIL + self.reader.skip_white() pos = self.reader.tell() + if self.reader.read_alpha() == "extends": + node.extends = self.read_type_list() + else: + self.reader.seek_set(pos) + self.add_node(node) + self.push_context(node) + + def parse_cmd_endinterface(self): + self.parse_class_end(NODE_INTERFACE, "E1345: :endinterface without :interface") + + # :enum {name} [implements {interface}, ...] + def parse_cmd_enum(self): + node = Node(NODE_ENUM) + node.pos = self.ea.cmdpos + node.ea = self.ea + node.name = self.read_class_name() + node.implements = [] + node.enumvalues = [] + node.body = [] + node.endenum = NIL + # The enum values come first. + node.values_done = FALSE self.reader.skip_white() - # :final - if self.ends_excmds(self.reader.peek()): + pos = self.reader.tell() + if self.reader.read_alpha() == "implements": + node.implements = self.read_type_list() + else: self.reader.seek_set(pos) - self.parse_cmd_common() - return - # Read variable name directly - npos = self.reader.getpos() - vname = self.reader.read_word() - if vname == "": + self.add_node(node) + self.push_context(node) + + def parse_cmd_endenum(self): + self.parse_class_end(NODE_ENUM, "E1419: :endenum without :enum") + + # Parse the enum values at the start of an enum: "Name[(args)], ..." + # Return FALSE when the line is not a list of values. + def parse_enum_values(self): + enumnode = self.context[0] + pos = self.reader.tell() + word = self.reader.read_word() + c = self.reader.peekn(1) + self.reader.seek_set(pos) + if word == "" or word == "var" or word == "final" or word == "const" or word == "def" or word == "static" or word == "public" or word == "endenum" or c != "" and c != "," and c != "(" and not iswhite(c): + enumnode.values_done = TRUE + return FALSE + while TRUE: + self.skip_vim9_white() + node = Node(NODE_ENUMVALUE) + node.pos = self.reader.getpos() + node.value = self.reader.read_word() + node.rlist = [] + if self.reader.peekn(1) == "(": + p = ExprParser(self.reader, self) + p.tokenizer.get() + node.rlist = p.parse_rlist() + viml_add(enumnode.enumvalues, node) + self.reader.skip_white() + if self.reader.peekn(1) != ",": + break + self.reader.getn(1) + self.skip_vim9_white() + if self.reader.peek() == "": + break + pos = self.reader.tell() + word = self.reader.read_word() self.reader.seek_set(pos) + if word == "endenum": + break + enumnode.values_done = TRUE + return TRUE + + def parse_class_end(self, type, msg): + self.check_missing_endif(self.ea.cmd.name, self.ea.cmdpos) + self.check_missing_endtry(self.ea.cmd.name, self.ea.cmdpos) + self.check_missing_endwhile(self.ea.cmd.name, self.ea.cmdpos) + self.check_missing_endfor(self.ea.cmd.name, self.ea.cmdpos) + self.check_missing_enddef(self.ea.cmd.name, self.ea.cmdpos) + if self.context[0].type != type: + raise VimLParserException(Err(msg, self.ea.cmdpos)) + if type == NODE_CLASS: + node = Node(NODE_ENDCLASS) + self.context[0].endclass = node + elif type == NODE_INTERFACE: + node = Node(NODE_ENDINTERFACE) + self.context[0].endinterface = node + else: + node = Node(NODE_ENDENUM) + self.context[0].endenum = node + node.pos = self.ea.cmdpos + node.ea = self.ea + self.pop_context() + + # :type {name} = {type} + def parse_cmd_type(self): + if not self.isvim9(): self.parse_cmd_common() return - left = Node(NODE_IDENTIFIER) - left.pos = npos - left.value = vname + node = Node(NODE_TYPE) + node.pos = self.ea.cmdpos + node.ea = self.ea + node.name = self.read_class_name() self.reader.skip_white() - # Check for type annotation - type_str = "" - if self.reader.peekn(1) == ":": + if self.reader.getn(1) != "=": + raise VimLParserException(Err("E1403: Missing \"=\" in type alias", self.reader.getpos())) + self.reader.skip_white() + node.type_str = self.read_type() + self.declared[node.name] = 1 + self.add_node(node) + + def read_class_name(self): + self.reader.skip_white() + name = self.reader.read_word() + if name == "": + raise VimLParserException(Err(viml_printf("E475: Invalid argument: %s", self.reader.peekline()), self.reader.getpos())) + self.declared[name] = 1 + return name + + # A comma separated list of types, e.g. after "implements". + def read_type_list(self): + list = [] + while TRUE: + self.reader.skip_white() + viml_add(list, self.read_type()) + self.reader.skip_white() + if self.reader.peekn(1) != ",": + break self.reader.getn(1) + return list + + # :import [autoload] {expr} [as {name}] + def parse_cmd_import(self): + node = Node(NODE_IMPORT) + node.pos = self.ea.cmdpos + node.ea = self.ea + node.autoload = FALSE + node.alias = "" + self.reader.skip_white() + start = self.reader.getpos() + pos = self.reader.tell() + if self.reader.read_alpha() == "autoload" and iswhite(self.reader.peekn(1)): + node.autoload = TRUE self.reader.skip_white() - type_str = self.read_type() + else: + self.reader.seek_set(pos) + node.left = self.parse_expr() + end = self.reader.getpos() + self.reader.skip_white() + pos = self.reader.tell() + if self.reader.read_alpha() == "as" and iswhite(self.reader.peekn(1)): self.reader.skip_white() - s1 = self.reader.peekn(1) - # :final {var-name} - if self.ends_excmds(s1) or s1 != "=": + node.alias = self.reader.read_word() + self.declared[node.alias] = 1 + end = self.reader.getpos() + else: self.reader.seek_set(pos) + # The text of the arguments. + node.str = self.reader.getstr(start, end) + self.add_node(node) + + def parse_cmd_block(self): + if not self.isvim9(): self.parse_cmd_common() return - # :final left = right - node = Node(NODE_FINAL) + node = Node(NODE_BLOCK) node.pos = self.ea.cmdpos node.ea = self.ea - self.reader.getn(1) - node.op = s1 - node.left = left - node.list = NIL - node.rest = NIL - node.right = self.parse_expr() - node.type_str = type_str + node.body = [] + node.endblock = NIL self.add_node(node) + self.push_context(node) - def parse_cmd_export(self): - self.reader.skip_white() - export_pos = self.ea.cmdpos - # Re-find the inner command - self.ea.cmdpos = self.reader.getpos() - self.ea.cmd = self.find_command() - if self.ea.cmd is NIL: - raise VimLParserException(Err(viml_printf("E492: Not an editor command: %s", self.reader.peekline()), self.ea.cmdpos)) - if self.reader.peekn(1) == "!" and self.ea.cmd.name != "substitute" and self.ea.cmd.name != "smagic" and self.ea.cmd.name != "snomagic": - self.reader.getn(1) - self.ea.forceit = TRUE - self.reader.skip_white() - self.ea.argpos = self.reader.getpos() - export_node = Node(NODE_EXPORT) - export_node.pos = export_pos - export_node.ea = self.ea - export_node.body = [] - # Remember current context body position - ctx = self.context[0] - before = viml_len(ctx.body) - # Parse the inner command - self._parse_command(self.ea.cmd.parser) - # Move newly-added nodes into export body - while viml_len(ctx.body) > before: - moved_node = ctx.body[before] - viml_remove(ctx.body, before) - viml_add(export_node.body, moved_node) - viml_add(ctx.body, export_node) - - def parse_cmd_import(self): - node = Node(NODE_IMPORT) + def parse_cmd_endblock(self): + if not self.isvim9(): + self.parse_cmd_common() + return + self.check_missing_endif("}", self.ea.cmdpos) + self.check_missing_endtry("}", self.ea.cmdpos) + self.check_missing_endwhile("}", self.ea.cmdpos) + self.check_missing_endfor("}", self.ea.cmdpos) + if self.context[0].type != NODE_BLOCK: + raise VimLParserException(Err("E1128: } without {", self.ea.cmdpos)) + node = Node(NODE_ENDBLOCK) node.pos = self.ea.cmdpos node.ea = self.ea - node.left = NIL - node.str = "" - self.reader.skip_white() - # Read the rest of the import line, stopping at a trailing comment. - line = "" - pending_ws = "" - last_was_white = FALSE - while TRUE: - c = self.reader.peekn(1) - if c == "": - break - if c == "#" and last_was_white: - # Consume the rest of the line, so parse_trail doesn't see it. - self.reader.getn(-1) - break - self.reader.getn(1) - if iswhite(c): - pending_ws += c - last_was_white = TRUE - else: - line += pending_ws + c - pending_ws = "" - last_was_white = FALSE - node.str = line - self.add_node(node) + self.context[0].endblock = node + self.pop_context() def parse_cmd_unlet(self): node = Node(NODE_UNLET) @@ -2105,10 +2725,18 @@ def parse_cmd_for(self): node.left = NIL node.right = NIL node.endfor = NIL - lhs = self.parse_letlhs() + if self.isvim9(): + lhs = self.parse_vim9_forlhs() + else: + lhs = self.parse_letlhs() node.left = lhs.left node.list = lhs.list node.rest = lhs.rest + self.declare(node.left) + if node.list is not NIL: + for x in node.list: + self.declare(x) + self.declare(node.rest) self.reader.skip_white() epos = self.reader.getpos() if self.reader.read_alpha() != "in": @@ -2117,6 +2745,30 @@ def parse_cmd_for(self): self.add_node(node) self.push_context(node) + # Vim9 :for loop variables with optional types: "name: type" or + # "[name: type, ...]" + def parse_vim9_forlhs(self): + lhs = AttributeDict({"left": NIL, "list": NIL, "rest": NIL}) + self.reader.skip_white() + if self.reader.peekn(1) != "[": + lhs.left = self.parse_vim9_decl_name() + return lhs + self.reader.getn(1) + lhs.list = [] + while TRUE: + viml_add(lhs.list, self.parse_vim9_decl_name()) + self.reader.skip_white() + c = self.reader.getn(1) + if c == ";": + lhs.rest = self.parse_vim9_decl_name() + self.reader.skip_white() + c = self.reader.getn(1) + if c == "]": + break + elif c != ",": + raise VimLParserException(Err(viml_printf("E475: Invalid argument: %s", c), self.reader.getpos())) + return lhs + def parse_cmd_endfor(self): if self.context[0].type != NODE_FOR: raise VimLParserException(Err("E588: :endfor without :for", self.ea.cmdpos)) @@ -2252,6 +2904,23 @@ def parse_cmd_echoconsole(self): node.list = self.parse_exprlist() self.add_node(node) + def parse_cmd_echowindow(self): + node = Node(NODE_ECHOWINDOW) + node.pos = self.ea.cmdpos + node.ea = self.ea + node.list = self.parse_exprlist() + self.add_node(node) + + # :defer {func}({args}) + def parse_cmd_defer(self): + node = Node(NODE_DEFER) + node.pos = self.ea.cmdpos + node.ea = self.ea + node.left = self.parse_expr() + if node.left.type != NODE_CALL: + raise VimLParserException(Err("E107: Missing parentheses", node.left.pos)) + self.add_node(node) + def parse_cmd_execute(self): node = Node(NODE_EXECUTE) node.pos = self.ea.cmdpos @@ -2260,7 +2929,7 @@ def parse_cmd_execute(self): self.add_node(node) def parse_expr(self): - return ExprParser(self.reader).parse() + return ExprParser(self.reader, self).parse() def parse_exprlist(self): list = [] @@ -2274,7 +2943,7 @@ def parse_exprlist(self): return list def parse_lvalue_func(self): - p = LvalueParser(self.reader) + p = LvalueParser(self.reader, self) node = p.parse() if node.type == NODE_IDENTIFIER or node.type == NODE_CURLYNAME or node.type == NODE_SUBSCRIPT or node.type == NODE_DOT or node.type == NODE_OPTION or node.type == NODE_ENV or node.type == NODE_REG: return node @@ -2282,7 +2951,7 @@ def parse_lvalue_func(self): # FIXME: def parse_lvalue(self): - p = LvalueParser(self.reader) + p = LvalueParser(self.reader, self) node = p.parse() if node.type == NODE_IDENTIFIER: if not isvarname(node.value): @@ -2293,7 +2962,7 @@ def parse_lvalue(self): # TODO: merge with s:VimLParser.parse_lvalue() def parse_constlvalue(self): - p = LvalueParser(self.reader) + p = LvalueParser(self.reader, self) node = p.parse() if node.type == NODE_IDENTIFIER: if not isvarname(node.value): @@ -2325,7 +2994,7 @@ def parse_lvaluelist(self): # FIXME: def parse_letlhs(self): lhs = AttributeDict({"left": NIL, "list": NIL, "rest": NIL}) - tokenizer = ExprTokenizer(self.reader) + tokenizer = ExprTokenizer(self.reader, self.isvim9()) if tokenizer.peek().type == TOKEN_SQOPEN: tokenizer.get() lhs.list = [] @@ -2354,7 +3023,7 @@ def parse_letlhs(self): # TODO: merge with s:VimLParser.parse_letlhs() ? def parse_constlhs(self): lhs = AttributeDict({"left": NIL, "list": NIL, "rest": NIL}) - tokenizer = ExprTokenizer(self.reader) + tokenizer = ExprTokenizer(self.reader, self.isvim9()) if tokenizer.peek().type == TOKEN_SQOPEN: tokenizer.get() lhs.list = [] @@ -2381,8 +3050,11 @@ def parse_constlhs(self): return lhs def ends_excmds(self, c): - if self.vim9script and c == "#": - return 1 + if self.isvim9(): + if c == "#": + return 1 + elif c == "\"": + return 0 return c == "" or c == "|" or c == "\"" or c == "" or c == "" # FIXME: validate argument @@ -2429,7 +3101,7 @@ def parse_cmd_syntax(self): neovim_removed_commands = [AttributeDict({"name": "Print", "minlen": 1, "flags": "RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN", "parser": "parse_cmd_common"}), AttributeDict({"name": "fixdel", "minlen": 3, "flags": "TRLBAR|CMDWIN", "parser": "parse_cmd_common"}), AttributeDict({"name": "helpfind", "minlen": 5, "flags": "EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "open", "minlen": 1, "flags": "RANGE|BANG|EXTRA", "parser": "parse_cmd_common"}), AttributeDict({"name": "shell", "minlen": 2, "flags": "TRLBAR|CMDWIN", "parser": "parse_cmd_common"}), AttributeDict({"name": "tearoff", "minlen": 2, "flags": "NEEDARG|EXTRA|TRLBAR|NOTRLCOM|CMDWIN", "parser": "parse_cmd_common"}), AttributeDict({"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 - builtin_commands = [AttributeDict({"name": "append", "minlen": 1, "flags": "BANG|RANGE|ZEROR|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_append"}), AttributeDict({"name": "abbreviate", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "abclear", "minlen": 3, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "aboveleft", "minlen": 3, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "abstract", "minlen": 3, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "all", "minlen": 2, "flags": "BANG|RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "amenu", "minlen": 2, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "anoremenu", "minlen": 2, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "args", "minlen": 2, "flags": "BANG|FILES|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "argadd", "minlen": 4, "flags": "BANG|RANGE|ZEROR|FILES|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "argdelete", "minlen": 4, "flags": "BANG|RANGE|FILES|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "argdo", "minlen": 5, "flags": "BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser": "parse_cmd_common"}), AttributeDict({"name": "argdedupe", "minlen": 6, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "argedit", "minlen": 4, "flags": "BANG|NEEDARG|RANGE|ZEROR|FILES|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "argglobal", "minlen": 4, "flags": "BANG|FILES|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "arglocal", "minlen": 4, "flags": "BANG|FILES|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "argument", "minlen": 4, "flags": "BANG|RANGE|COUNT|EXTRA|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "ascii", "minlen": 2, "flags": "TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "autocmd", "minlen": 2, "flags": "BANG|EXTRA|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "augroup", "minlen": 3, "flags": "BANG|WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "aunmenu", "minlen": 3, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "buffer", "minlen": 1, "flags": "BANG|RANGE|BUFNAME|BUFUNL|COUNT|EXTRA|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "bNext", "minlen": 2, "flags": "BANG|RANGE|COUNT|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "ball", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "badd", "minlen": 3, "flags": "NEEDARG|FILE1|CMDARG|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "balt", "minlen": 4, "flags": "NEEDARG|FILE1|CMDARG|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "bdelete", "minlen": 2, "flags": "BANG|RANGE|BUFNAME|COUNT|EXTRA|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "behave", "minlen": 2, "flags": "BANG|NEEDARG|WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "belowright", "minlen": 3, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "bfirst", "minlen": 2, "flags": "BANG|RANGE|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "blast", "minlen": 2, "flags": "BANG|RANGE|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "bmodified", "minlen": 2, "flags": "BANG|RANGE|COUNT|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "bnext", "minlen": 2, "flags": "BANG|RANGE|COUNT|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "botright", "minlen": 2, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "bprevious", "minlen": 2, "flags": "BANG|RANGE|COUNT|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "brewind", "minlen": 2, "flags": "BANG|RANGE|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "break", "minlen": 4, "flags": "TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_break"}), AttributeDict({"name": "breakadd", "minlen": 6, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "breakdel", "minlen": 6, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "breaklist", "minlen": 6, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "browse", "minlen": 3, "flags": "NEEDARG|EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "buffers", "minlen": 7, "flags": "BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "bufdo", "minlen": 4, "flags": "BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser": "parse_cmd_common"}), AttributeDict({"name": "bunload", "minlen": 3, "flags": "BANG|RANGE|BUFNAME|COUNT|EXTRA|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "bwipeout", "minlen": 2, "flags": "BANG|RANGE|BUFNAME|BUFUNL|COUNT|EXTRA|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "change", "minlen": 1, "flags": "BANG|WHOLEFOLD|RANGE|COUNT|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "cNext", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "cNfile", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "cabbrev", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "cabclear", "minlen": 4, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "cabove", "minlen": 4, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "caddbuffer", "minlen": 3, "flags": "RANGE|WORD1|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "caddexpr", "minlen": 5, "flags": "NEEDARG|WORD1|NOTRLCOM|EXPR_ARG", "parser": "parse_cmd_common"}), AttributeDict({"name": "caddfile", "minlen": 5, "flags": "TRLBAR|FILE1", "parser": "parse_cmd_common"}), AttributeDict({"name": "cafter", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "call", "minlen": 3, "flags": "RANGE|NEEDARG|EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_call"}), AttributeDict({"name": "catch", "minlen": 3, "flags": "EXTRA|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_catch"}), AttributeDict({"name": "cbuffer", "minlen": 2, "flags": "BANG|RANGE|WORD1|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "cbefore", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "cbelow", "minlen": 4, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "cbottom", "minlen": 3, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "cc", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "cclose", "minlen": 3, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "cd", "minlen": 2, "flags": "BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "cdo", "minlen": 3, "flags": "BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser": "parse_cmd_common"}), AttributeDict({"name": "center", "minlen": 2, "flags": "TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "cexpr", "minlen": 3, "flags": "NEEDARG|WORD1|NOTRLCOM|EXPR_ARG|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "cfile", "minlen": 2, "flags": "TRLBAR|FILE1|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "cfdo", "minlen": 3, "flags": "BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser": "parse_cmd_common"}), AttributeDict({"name": "cfirst", "minlen": 4, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "cgetfile", "minlen": 2, "flags": "TRLBAR|FILE1", "parser": "parse_cmd_common"}), AttributeDict({"name": "cgetbuffer", "minlen": 5, "flags": "RANGE|WORD1|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "cgetexpr", "minlen": 5, "flags": "NEEDARG|WORD1|NOTRLCOM|EXPR_ARG", "parser": "parse_cmd_common"}), AttributeDict({"name": "chdir", "minlen": 3, "flags": "BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "changes", "minlen": 7, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "checkpath", "minlen": 3, "flags": "TRLBAR|BANG|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "checktime", "minlen": 6, "flags": "RANGE|BUFNAME|COUNT|EXTRA|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "chistory", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "clist", "minlen": 2, "flags": "BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "clast", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "class", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "close", "minlen": 3, "flags": "BANG|RANGE|COUNT|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "clearjumps", "minlen": 3, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "cmap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "cmapclear", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "cmenu", "minlen": 3, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "cnext", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "cnewer", "minlen": 4, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "cnfile", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "cnoremap", "minlen": 3, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "cnoreabbrev", "minlen": 6, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "cnoremenu", "minlen": 7, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "copy", "minlen": 2, "flags": "RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "colder", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "colorscheme", "minlen": 4, "flags": "WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "command", "minlen": 3, "flags": "EXTRA|BANG|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "comclear", "minlen": 4, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "compiler", "minlen": 4, "flags": "BANG|TRLBAR|WORD1|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "continue", "minlen": 3, "flags": "TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_continue"}), AttributeDict({"name": "confirm", "minlen": 4, "flags": "NEEDARG|EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "const", "minlen": 4, "flags": "EXTRA|BANG|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_const"}), AttributeDict({"name": "copen", "minlen": 4, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "cprevious", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "cpfile", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "cquit", "minlen": 2, "flags": "RANGE|COUNT|ZEROR|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "crewind", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "cscope", "minlen": 2, "flags": "EXTRA|NOTRLCOM|XFILE", "parser": "parse_cmd_common"}), AttributeDict({"name": "cstag", "minlen": 3, "flags": "BANG|TRLBAR|WORD1", "parser": "parse_cmd_common"}), AttributeDict({"name": "cunmap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "cunabbrev", "minlen": 4, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "cunmenu", "minlen": 5, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "cwindow", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "delete", "minlen": 1, "flags": "RANGE|WHOLEFOLD|REGSTR|COUNT|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "delmarks", "minlen": 4, "flags": "BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "debug", "minlen": 3, "flags": "NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "debuggreedy", "minlen": 6, "flags": "RANGE|ZEROR|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "def", "minlen": 3, "flags": "EXTRA|BANG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_def"}), AttributeDict({"name": "defer", "minlen": 4, "flags": "NEEDARG|EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "defcompile", "minlen": 4, "flags": "SBOXOK|CMDWIN|LOCK_OK|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "delcommand", "minlen": 4, "flags": "NEEDARG|WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "delfunction", "minlen": 4, "flags": "BANG|NEEDARG|WORD1|CMDWIN|LOCK_OK", "parser": "parse_cmd_delfunction"}), AttributeDict({"name": "display", "minlen": 2, "flags": "EXTRA|NOTRLCOM|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "diffupdate", "minlen": 3, "flags": "BANG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "diffget", "minlen": 5, "flags": "RANGE|EXTRA|TRLBAR|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "diffoff", "minlen": 5, "flags": "BANG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "diffpatch", "minlen": 5, "flags": "EXTRA|FILE1|TRLBAR|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "diffput", "minlen": 6, "flags": "RANGE|EXTRA|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "diffsplit", "minlen": 5, "flags": "EXTRA|FILE1|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "diffthis", "minlen": 5, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "digraphs", "minlen": 3, "flags": "BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "disassemble", "minlen": 4, "flags": "BANG|EXTRA|NEEDARG|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "djump", "minlen": 2, "flags": "BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA", "parser": "parse_cmd_common"}), AttributeDict({"name": "dlist", "minlen": 2, "flags": "BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "doautocmd", "minlen": 2, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "doautoall", "minlen": 7, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "drop", "minlen": 2, "flags": "FILES|CMDARG|NEEDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "dsearch", "minlen": 2, "flags": "BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "dsplit", "minlen": 3, "flags": "BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA", "parser": "parse_cmd_common"}), AttributeDict({"name": "edit", "minlen": 1, "flags": "BANG|FILE1|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "earlier", "minlen": 2, "flags": "TRLBAR|EXTRA|NOSPC|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "echo", "minlen": 2, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_echo"}), AttributeDict({"name": "echoerr", "minlen": 5, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_echoerr"}), AttributeDict({"name": "echohl", "minlen": 5, "flags": "EXTRA|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_echohl"}), AttributeDict({"name": "echomsg", "minlen": 5, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_echomsg"}), AttributeDict({"name": "echoconsole", "minlen": 5, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_echoconsole"}), AttributeDict({"name": "echowindow", "minlen": 5, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "echon", "minlen": 5, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_echon"}), AttributeDict({"name": "else", "minlen": 2, "flags": "TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_else"}), AttributeDict({"name": "elseif", "minlen": 5, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_elseif"}), AttributeDict({"name": "emenu", "minlen": 2, "flags": "NEEDARG|EXTRA|TRLBAR|NOTRLCOM|RANGE|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "endif", "minlen": 2, "flags": "TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_endif"}), AttributeDict({"name": "endinterface", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "endclass", "minlen": 4, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "enddef", "minlen": 4, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_enddef"}), AttributeDict({"name": "endenum", "minlen": 4, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "endfunction", "minlen": 4, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_endfunction"}), AttributeDict({"name": "endfor", "minlen": 5, "flags": "TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_endfor"}), AttributeDict({"name": "endtry", "minlen": 4, "flags": "TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_endtry"}), AttributeDict({"name": "endwhile", "minlen": 4, "flags": "TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_endwhile"}), AttributeDict({"name": "enew", "minlen": 3, "flags": "BANG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "enum", "minlen": 3, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "eval", "minlen": 2, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_eval"}), AttributeDict({"name": "ex", "minlen": 2, "flags": "BANG|FILE1|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "execute", "minlen": 3, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_execute"}), AttributeDict({"name": "exit", "minlen": 3, "flags": "RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "export", "minlen": 3, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|CMDWIN|LOCK_OK", "parser": "parse_cmd_export"}), AttributeDict({"name": "exusage", "minlen": 3, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "file", "minlen": 1, "flags": "RANGE|ZEROR|BANG|FILE1|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "files", "minlen": 5, "flags": "BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "filetype", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "filter", "minlen": 4, "flags": "BANG|NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "find", "minlen": 3, "flags": "RANGE|BANG|FILE1|CMDARG|ARGOPT|TRLBAR|NEEDARG", "parser": "parse_cmd_common"}), AttributeDict({"name": "final", "minlen": 4, "flags": "EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_final"}), AttributeDict({"name": "finally", "minlen": 6, "flags": "TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_finally"}), AttributeDict({"name": "finish", "minlen": 4, "flags": "TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_finish"}), AttributeDict({"name": "first", "minlen": 3, "flags": "EXTRA|BANG|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "fixdel", "minlen": 3, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "fold", "minlen": 2, "flags": "RANGE|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "foldclose", "minlen": 5, "flags": "RANGE|BANG|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "folddoopen", "minlen": 5, "flags": "RANGE|DFLALL|NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "folddoclosed", "minlen": 7, "flags": "RANGE|DFLALL|NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "foldopen", "minlen": 5, "flags": "RANGE|BANG|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "for", "minlen": 3, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_for"}), AttributeDict({"name": "function", "minlen": 2, "flags": "EXTRA|BANG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_function"}), AttributeDict({"name": "global", "minlen": 1, "flags": "RANGE|WHOLEFOLD|BANG|EXTRA|DFLALL|SBOXOK|CMDWIN|LOCK_OK|NONWHITE_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "goto", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "grep", "minlen": 2, "flags": "RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE", "parser": "parse_cmd_common"}), AttributeDict({"name": "grepadd", "minlen": 5, "flags": "RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE", "parser": "parse_cmd_common"}), AttributeDict({"name": "gui", "minlen": 2, "flags": "BANG|FILES|CMDARG|ARGOPT|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "gvim", "minlen": 2, "flags": "BANG|FILES|CMDARG|ARGOPT|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "help", "minlen": 1, "flags": "BANG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "helpclose", "minlen": 5, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "helpfind", "minlen": 5, "flags": "EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "helpgrep", "minlen": 5, "flags": "EXTRA|NOTRLCOM|NEEDARG", "parser": "parse_cmd_common"}), AttributeDict({"name": "helptags", "minlen": 5, "flags": "NEEDARG|FILES|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "hardcopy", "minlen": 2, "flags": "RANGE|COUNT|EXTRA|EXPAND|TRLBAR|DFLALL|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "highlight", "minlen": 2, "flags": "BANG|EXTRA|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "hide", "minlen": 3, "flags": "BANG|RANGE|COUNT|EXTRA|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "history", "minlen": 3, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "horizontal", "minlen": 2, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "insert", "minlen": 1, "flags": "BANG|RANGE|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_insert"}), AttributeDict({"name": "iabbrev", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "iabclear", "minlen": 4, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "if", "minlen": 2, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_if"}), AttributeDict({"name": "ijump", "minlen": 2, "flags": "BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA", "parser": "parse_cmd_common"}), AttributeDict({"name": "ilist", "minlen": 2, "flags": "BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "imap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "imapclear", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "imenu", "minlen": 3, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "import", "minlen": 3, "flags": "EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser": "parse_cmd_import"}), AttributeDict({"name": "inoremap", "minlen": 3, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "inoreabbrev", "minlen": 6, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "inoremenu", "minlen": 7, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "intro", "minlen": 3, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "interface", "minlen": 4, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "isearch", "minlen": 2, "flags": "BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "isplit", "minlen": 3, "flags": "BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA", "parser": "parse_cmd_common"}), AttributeDict({"name": "iunmap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "iunabbrev", "minlen": 4, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "iunmenu", "minlen": 5, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "join", "minlen": 1, "flags": "BANG|RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "jumps", "minlen": 2, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "k", "minlen": 1, "flags": "RANGE|WORD1|TRLBAR|SBOXOK|CMDWIN|LOCK_OK|NONWHITE_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "keepmarks", "minlen": 2, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "keepjumps", "minlen": 5, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "keeppatterns", "minlen": 5, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "keepalt", "minlen": 5, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "list", "minlen": 1, "flags": "RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "lNext", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "lNfile", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "last", "minlen": 2, "flags": "EXTRA|BANG|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "labove", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "language", "minlen": 3, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "laddexpr", "minlen": 3, "flags": "NEEDARG|WORD1|NOTRLCOM|EXPR_ARG", "parser": "parse_cmd_common"}), AttributeDict({"name": "laddbuffer", "minlen": 5, "flags": "RANGE|WORD1|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "laddfile", "minlen": 5, "flags": "TRLBAR|FILE1", "parser": "parse_cmd_common"}), AttributeDict({"name": "lafter", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "later", "minlen": 3, "flags": "TRLBAR|EXTRA|NOSPC|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "lbuffer", "minlen": 2, "flags": "BANG|RANGE|WORD1|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "lbefore", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "lbelow", "minlen": 4, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "lbottom", "minlen": 3, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "lcd", "minlen": 2, "flags": "BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "lchdir", "minlen": 3, "flags": "BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "lclose", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "lcscope", "minlen": 3, "flags": "EXTRA|NOTRLCOM|XFILE", "parser": "parse_cmd_common"}), AttributeDict({"name": "ldo", "minlen": 2, "flags": "BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser": "parse_cmd_common"}), AttributeDict({"name": "left", "minlen": 2, "flags": "TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "leftabove", "minlen": 5, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "let", "minlen": 3, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_let"}), AttributeDict({"name": "lexpr", "minlen": 3, "flags": "NEEDARG|WORD1|NOTRLCOM|EXPR_ARG|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "legacy", "minlen": 3, "flags": "NEEDARG|EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "lfile", "minlen": 2, "flags": "TRLBAR|FILE1|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "lfdo", "minlen": 3, "flags": "BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser": "parse_cmd_common"}), AttributeDict({"name": "lfirst", "minlen": 4, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "lgetfile", "minlen": 2, "flags": "TRLBAR|FILE1", "parser": "parse_cmd_common"}), AttributeDict({"name": "lgetbuffer", "minlen": 5, "flags": "RANGE|WORD1|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "lgetexpr", "minlen": 5, "flags": "NEEDARG|WORD1|NOTRLCOM|EXPR_ARG", "parser": "parse_cmd_common"}), AttributeDict({"name": "lgrep", "minlen": 3, "flags": "RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE", "parser": "parse_cmd_common"}), AttributeDict({"name": "lgrepadd", "minlen": 6, "flags": "RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE", "parser": "parse_cmd_common"}), AttributeDict({"name": "lhelpgrep", "minlen": 2, "flags": "EXTRA|NOTRLCOM|NEEDARG", "parser": "parse_cmd_common"}), AttributeDict({"name": "lhistory", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "ll", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "llast", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "llist", "minlen": 3, "flags": "BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "lmap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "lmapclear", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "lmake", "minlen": 4, "flags": "BANG|EXTRA|NOTRLCOM|TRLBAR|XFILE", "parser": "parse_cmd_common"}), AttributeDict({"name": "lnoremap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "lnext", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "lnewer", "minlen": 4, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "lnfile", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "loadview", "minlen": 2, "flags": "FILE1|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "loadkeymap", "minlen": 5, "flags": "CMDWIN|LOCK_OK", "parser": "parse_cmd_loadkeymap"}), AttributeDict({"name": "lockmarks", "minlen": 3, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "lockvar", "minlen": 5, "flags": "BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_lockvar"}), AttributeDict({"name": "lolder", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "lopen", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "lprevious", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "lpfile", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "lrewind", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "ltag", "minlen": 2, "flags": "TRLBAR|BANG|WORD1", "parser": "parse_cmd_common"}), AttributeDict({"name": "lunmap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "lua", "minlen": 3, "flags": "RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_lua"}), AttributeDict({"name": "luado", "minlen": 4, "flags": "RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "luafile", "minlen": 4, "flags": "RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "lvimgrep", "minlen": 2, "flags": "RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "lvimgrepadd", "minlen": 9, "flags": "RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "lwindow", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "ls", "minlen": 2, "flags": "BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "move", "minlen": 1, "flags": "RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "mark", "minlen": 2, "flags": "RANGE|WORD1|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "make", "minlen": 3, "flags": "BANG|EXTRA|NOTRLCOM|TRLBAR|XFILE", "parser": "parse_cmd_common"}), AttributeDict({"name": "map", "minlen": 3, "flags": "BANG|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "mapclear", "minlen": 4, "flags": "EXTRA|BANG|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "marks", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "match", "minlen": 3, "flags": "RANGE|EXTRA|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "menu", "minlen": 2, "flags": "RANGE|ZEROR|BANG|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "menutranslate", "minlen": 5, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "messages", "minlen": 3, "flags": "EXTRA|TRLBAR|RANGE|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "mkexrc", "minlen": 2, "flags": "BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "mksession", "minlen": 3, "flags": "BANG|FILE1|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "mkspell", "minlen": 4, "flags": "BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE", "parser": "parse_cmd_common"}), AttributeDict({"name": "mkvimrc", "minlen": 3, "flags": "BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "mkview", "minlen": 5, "flags": "BANG|FILE1|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "mode", "minlen": 3, "flags": "WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "mzscheme", "minlen": 2, "flags": "RANGE|EXTRA|DFLALL|NEEDARG|CMDWIN|LOCK_OK|SBOXOK|RESTRICT", "parser": "parse_cmd_mzscheme"}), AttributeDict({"name": "mzfile", "minlen": 3, "flags": "RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "next", "minlen": 1, "flags": "RANGE|BANG|FILES|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "nbkey", "minlen": 2, "flags": "EXTRA|NEEDARG", "parser": "parse_cmd_common"}), AttributeDict({"name": "nbclose", "minlen": 3, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "nbstart", "minlen": 3, "flags": "WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "new", "minlen": 3, "flags": "BANG|FILE1|RANGE|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "nmap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "nmapclear", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "nmenu", "minlen": 3, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "nnoremap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "nnoremenu", "minlen": 7, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "noremap", "minlen": 2, "flags": "BANG|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "noautocmd", "minlen": 3, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "nohlsearch", "minlen": 3, "flags": "TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "noreabbrev", "minlen": 5, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "noremenu", "minlen": 6, "flags": "RANGE|ZEROR|BANG|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "noswapfile", "minlen": 3, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "normal", "minlen": 4, "flags": "RANGE|BANG|EXTRA|NEEDARG|NOTRLCOM|CTRLV|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "number", "minlen": 2, "flags": "RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "nunmap", "minlen": 3, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "nunmenu", "minlen": 5, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "open", "minlen": 1, "flags": "RANGE|BANG|EXTRA", "parser": "parse_cmd_common"}), AttributeDict({"name": "oldfiles", "minlen": 2, "flags": "BANG|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "omap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "omapclear", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "omenu", "minlen": 3, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "only", "minlen": 2, "flags": "BANG|RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "onoremap", "minlen": 3, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "onoremenu", "minlen": 7, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "options", "minlen": 3, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "ounmap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "ounmenu", "minlen": 5, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "ownsyntax", "minlen": 2, "flags": "EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "print", "minlen": 1, "flags": "RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK|SBOXOK", "parser": "parse_cmd_common"}), AttributeDict({"name": "packadd", "minlen": 2, "flags": "BANG|FILE1|NEEDARG|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "packloadall", "minlen": 5, "flags": "BANG|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "pclose", "minlen": 2, "flags": "BANG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "perl", "minlen": 2, "flags": "RANGE|EXTRA|DFLALL|NEEDARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_perl"}), AttributeDict({"name": "perldo", "minlen": 5, "flags": "RANGE|EXTRA|DFLALL|NEEDARG|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "pedit", "minlen": 3, "flags": "BANG|FILE1|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "pop", "minlen": 2, "flags": "RANGE|BANG|COUNT|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "popup", "minlen": 4, "flags": "NEEDARG|EXTRA|BANG|TRLBAR|NOTRLCOM|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "ppop", "minlen": 2, "flags": "RANGE|BANG|COUNT|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "preserve", "minlen": 3, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "previous", "minlen": 4, "flags": "EXTRA|RANGE|COUNT|BANG|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "promptfind", "minlen": 3, "flags": "EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "promptrepl", "minlen": 7, "flags": "EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "profile", "minlen": 4, "flags": "BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "profdel", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "psearch", "minlen": 2, "flags": "BANG|RANGE|WHOLEFOLD|DFLALL|EXTRA", "parser": "parse_cmd_common"}), AttributeDict({"name": "ptag", "minlen": 2, "flags": "RANGE|BANG|WORD1|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "ptNext", "minlen": 3, "flags": "RANGE|BANG|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "ptfirst", "minlen": 3, "flags": "RANGE|BANG|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "ptjump", "minlen": 3, "flags": "BANG|TRLBAR|WORD1", "parser": "parse_cmd_common"}), AttributeDict({"name": "ptlast", "minlen": 3, "flags": "BANG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "ptnext", "minlen": 3, "flags": "RANGE|BANG|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "ptprevious", "minlen": 3, "flags": "RANGE|BANG|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "ptrewind", "minlen": 3, "flags": "RANGE|BANG|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "ptselect", "minlen": 3, "flags": "BANG|TRLBAR|WORD1", "parser": "parse_cmd_common"}), AttributeDict({"name": "put", "minlen": 2, "flags": "RANGE|WHOLEFOLD|BANG|REGSTR|TRLBAR|ZEROR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "pwd", "minlen": 2, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "python", "minlen": 2, "flags": "RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_python"}), AttributeDict({"name": "pydo", "minlen": 3, "flags": "RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "pyfile", "minlen": 3, "flags": "RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "py3", "minlen": 3, "flags": "RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_python3"}), AttributeDict({"name": "py3do", "minlen": 4, "flags": "RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "python3", "minlen": 7, "flags": "RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_python3"}), AttributeDict({"name": "py3file", "minlen": 4, "flags": "RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "pyx", "minlen": 3, "flags": "RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "pyxdo", "minlen": 4, "flags": "RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "pythonx", "minlen": 7, "flags": "RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "pyxfile", "minlen": 4, "flags": "RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "quit", "minlen": 1, "flags": "BANG|RANGE|COUNT|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "quitall", "minlen": 5, "flags": "BANG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "qall", "minlen": 2, "flags": "BANG|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "read", "minlen": 1, "flags": "BANG|RANGE|WHOLEFOLD|FILE1|ARGOPT|TRLBAR|ZEROR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "recover", "minlen": 3, "flags": "BANG|FILE1|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "redo", "minlen": 3, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "redir", "minlen": 4, "flags": "BANG|FILES|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "redraw", "minlen": 4, "flags": "BANG|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "redrawstatus", "minlen": 7, "flags": "BANG|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "redrawtabline", "minlen": 7, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "registers", "minlen": 3, "flags": "EXTRA|NOTRLCOM|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "resize", "minlen": 3, "flags": "RANGE|TRLBAR|WORD1|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "retab", "minlen": 3, "flags": "TRLBAR|RANGE|WHOLEFOLD|DFLALL|BANG|WORD1|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "return", "minlen": 4, "flags": "EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_return"}), AttributeDict({"name": "rewind", "minlen": 3, "flags": "EXTRA|BANG|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "right", "minlen": 2, "flags": "TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "rightbelow", "minlen": 6, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "runtime", "minlen": 2, "flags": "BANG|NEEDARG|FILES|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "ruby", "minlen": 3, "flags": "RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_ruby"}), AttributeDict({"name": "rubydo", "minlen": 5, "flags": "RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "rubyfile", "minlen": 5, "flags": "RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "rundo", "minlen": 4, "flags": "NEEDARG|FILE1", "parser": "parse_cmd_common"}), AttributeDict({"name": "rviminfo", "minlen": 2, "flags": "BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "substitute", "minlen": 1, "flags": "RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|NONWHITE_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "sNext", "minlen": 2, "flags": "EXTRA|RANGE|COUNT|BANG|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sargument", "minlen": 2, "flags": "BANG|RANGE|COUNT|EXTRA|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sall", "minlen": 3, "flags": "BANG|RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sandbox", "minlen": 3, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "saveas", "minlen": 3, "flags": "BANG|FILE1|ARGOPT|CMDWIN|LOCK_OK|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sbuffer", "minlen": 2, "flags": "BANG|RANGE|BUFNAME|BUFUNL|COUNT|EXTRA|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sbNext", "minlen": 3, "flags": "RANGE|COUNT|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sball", "minlen": 3, "flags": "RANGE|COUNT|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sbfirst", "minlen": 3, "flags": "CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sblast", "minlen": 3, "flags": "CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sbmodified", "minlen": 3, "flags": "RANGE|COUNT|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sbnext", "minlen": 3, "flags": "RANGE|COUNT|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sbprevious", "minlen": 3, "flags": "RANGE|COUNT|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sbrewind", "minlen": 3, "flags": "CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "scriptnames", "minlen": 2, "flags": "BANG|RANGE|COUNT|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "scriptencoding", "minlen": 7, "flags": "WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "scriptversion", "minlen": 7, "flags": "WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "scscope", "minlen": 3, "flags": "EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "set", "minlen": 2, "flags": "BANG|TRLBAR|EXTRA|CMDWIN|LOCK_OK|SBOXOK", "parser": "parse_cmd_common"}), AttributeDict({"name": "setfiletype", "minlen": 4, "flags": "TRLBAR|EXTRA|NEEDARG|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "setglobal", "minlen": 4, "flags": "BANG|TRLBAR|EXTRA|CMDWIN|LOCK_OK|SBOXOK", "parser": "parse_cmd_common"}), AttributeDict({"name": "setlocal", "minlen": 4, "flags": "BANG|TRLBAR|EXTRA|CMDWIN|LOCK_OK|SBOXOK", "parser": "parse_cmd_common"}), AttributeDict({"name": "sfind", "minlen": 2, "flags": "BANG|FILE1|RANGE|CMDARG|ARGOPT|TRLBAR|NEEDARG", "parser": "parse_cmd_common"}), AttributeDict({"name": "sfirst", "minlen": 4, "flags": "EXTRA|BANG|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "shell", "minlen": 2, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "simalt", "minlen": 2, "flags": "NEEDARG|WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "sign", "minlen": 3, "flags": "NEEDARG|RANGE|EXTRA|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "silent", "minlen": 3, "flags": "NEEDARG|EXTRA|BANG|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "sleep", "minlen": 2, "flags": "BANG|RANGE|COUNT|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "slast", "minlen": 3, "flags": "EXTRA|BANG|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "smagic", "minlen": 2, "flags": "RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|NONWHITE_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "smap", "minlen": 4, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "smapclear", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "smenu", "minlen": 3, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "snext", "minlen": 2, "flags": "RANGE|BANG|FILES|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "snomagic", "minlen": 3, "flags": "RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|NONWHITE_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "snoremap", "minlen": 4, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "snoremenu", "minlen": 7, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "source", "minlen": 2, "flags": "BANG|FILE1|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "sort", "minlen": 3, "flags": "RANGE|DFLALL|WHOLEFOLD|BANG|EXTRA|NOTRLCOM|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "split", "minlen": 2, "flags": "BANG|FILE1|RANGE|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "spellgood", "minlen": 3, "flags": "BANG|RANGE|NEEDARG|EXTRA|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "spelldump", "minlen": 6, "flags": "BANG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "spellinfo", "minlen": 6, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "spellrepall", "minlen": 6, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "spellrare", "minlen": 7, "flags": "BANG|RANGE|NEEDARG|EXTRA|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "spellundo", "minlen": 6, "flags": "BANG|RANGE|NEEDARG|EXTRA|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "spellwrong", "minlen": 6, "flags": "BANG|RANGE|NEEDARG|EXTRA|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sprevious", "minlen": 3, "flags": "EXTRA|RANGE|COUNT|BANG|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "srewind", "minlen": 2, "flags": "EXTRA|BANG|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "stop", "minlen": 2, "flags": "TRLBAR|BANG|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "stag", "minlen": 3, "flags": "RANGE|BANG|WORD1|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "startinsert", "minlen": 4, "flags": "BANG|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "startgreplace", "minlen": 6, "flags": "BANG|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "startreplace", "minlen": 6, "flags": "BANG|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "static", "minlen": 4, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "stopinsert", "minlen": 5, "flags": "BANG|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "stjump", "minlen": 3, "flags": "BANG|TRLBAR|WORD1", "parser": "parse_cmd_common"}), AttributeDict({"name": "stselect", "minlen": 3, "flags": "BANG|TRLBAR|WORD1", "parser": "parse_cmd_common"}), AttributeDict({"name": "sunhide", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sunmap", "minlen": 4, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "sunmenu", "minlen": 5, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "suspend", "minlen": 3, "flags": "TRLBAR|BANG|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "sview", "minlen": 2, "flags": "BANG|FILE1|RANGE|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "swapname", "minlen": 2, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "syntax", "minlen": 2, "flags": "EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser": "parse_cmd_syntax"}), AttributeDict({"name": "syntime", "minlen": 5, "flags": "NEEDARG|WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "syncbind", "minlen": 4, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "smile", "minlen": 3, "flags": "TRLBAR|CMDWIN|LOCK_OK|SBOXOK", "parser": "parse_cmd_common"}), AttributeDict({"name": "t", "minlen": 1, "flags": "RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "tNext", "minlen": 2, "flags": "RANGE|BANG|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tag", "minlen": 2, "flags": "RANGE|BANG|WORD1|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tags", "minlen": 4, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tab", "minlen": 3, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabclose", "minlen": 4, "flags": "BANG|RANGE|ZEROR|EXTRA|NOSPC|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabdo", "minlen": 4, "flags": "NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabedit", "minlen": 4, "flags": "BANG|FILE1|RANGE|ZEROR|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabfind", "minlen": 4, "flags": "BANG|FILE1|RANGE|ZEROR|CMDARG|ARGOPT|NEEDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabfirst", "minlen": 6, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabmove", "minlen": 4, "flags": "RANGE|ZEROR|EXTRA|NOSPC|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tablast", "minlen": 4, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabnext", "minlen": 4, "flags": "RANGE|ZEROR|EXTRA|NOSPC|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabnew", "minlen": 6, "flags": "BANG|FILE1|RANGE|ZEROR|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabonly", "minlen": 4, "flags": "BANG|RANGE|ZEROR|EXTRA|NOSPC|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabprevious", "minlen": 4, "flags": "RANGE|ZEROR|EXTRA|NOSPC|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabNext", "minlen": 4, "flags": "RANGE|ZEROR|EXTRA|NOSPC|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabrewind", "minlen": 4, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabs", "minlen": 4, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tcd", "minlen": 2, "flags": "BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tchdir", "minlen": 3, "flags": "BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tcl", "minlen": 3, "flags": "RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_tcl"}), AttributeDict({"name": "tcldo", "minlen": 4, "flags": "RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "tclfile", "minlen": 4, "flags": "RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "tearoff", "minlen": 2, "flags": "NEEDARG|EXTRA|TRLBAR|NOTRLCOM|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "terminal", "minlen": 3, "flags": "RANGE|BANG|FILES|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tfirst", "minlen": 2, "flags": "RANGE|BANG|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "throw", "minlen": 2, "flags": "EXTRA|NEEDARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_throw"}), AttributeDict({"name": "tjump", "minlen": 2, "flags": "BANG|TRLBAR|WORD1", "parser": "parse_cmd_common"}), AttributeDict({"name": "tlast", "minlen": 2, "flags": "BANG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tlmenu", "minlen": 3, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tlnoremenu", "minlen": 3, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tlunmenu", "minlen": 3, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tmenu", "minlen": 2, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tmap", "minlen": 3, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tmapclear", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tnext", "minlen": 2, "flags": "RANGE|BANG|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tnoremap", "minlen": 3, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "topleft", "minlen": 2, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "tprevious", "minlen": 2, "flags": "RANGE|BANG|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "trewind", "minlen": 2, "flags": "RANGE|BANG|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "try", "minlen": 3, "flags": "TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_try"}), AttributeDict({"name": "tselect", "minlen": 2, "flags": "BANG|TRLBAR|WORD1", "parser": "parse_cmd_common"}), AttributeDict({"name": "tunmenu", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tunmap", "minlen": 5, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "type", "minlen": 2, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "undo", "minlen": 1, "flags": "RANGE|COUNT|ZEROR|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "undojoin", "minlen": 5, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "undolist", "minlen": 5, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "unabbreviate", "minlen": 3, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "unhide", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "unlet", "minlen": 3, "flags": "BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_unlet"}), AttributeDict({"name": "unlockvar", "minlen": 4, "flags": "BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_unlockvar"}), AttributeDict({"name": "unmap", "minlen": 3, "flags": "BANG|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "unmenu", "minlen": 4, "flags": "BANG|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "unsilent", "minlen": 3, "flags": "NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "update", "minlen": 2, "flags": "RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "vglobal", "minlen": 1, "flags": "RANGE|WHOLEFOLD|EXTRA|DFLALL|CMDWIN|LOCK_OK|NONWHITE_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "var", "minlen": 2, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_var"}), AttributeDict({"name": "version", "minlen": 2, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "verbose", "minlen": 4, "flags": "NEEDARG|RANGE|EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "vertical", "minlen": 4, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "visual", "minlen": 2, "flags": "BANG|FILE1|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "view", "minlen": 3, "flags": "BANG|FILE1|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "vimgrep", "minlen": 3, "flags": "RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "vimgrepadd", "minlen": 8, "flags": "RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "vim9cmd", "minlen": 4, "flags": "NEEDARG|EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "vim9script", "minlen": 5, "flags": "WORD1|CMDWIN|LOCK_OK", "parser": "parse_cmd_vim9script"}), AttributeDict({"name": "viusage", "minlen": 3, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "vmap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "vmapclear", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "vmenu", "minlen": 3, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "vnoremap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "vnew", "minlen": 3, "flags": "BANG|FILE1|RANGE|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "vnoremenu", "minlen": 7, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "vsplit", "minlen": 2, "flags": "BANG|FILE1|RANGE|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "vunmap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "vunmenu", "minlen": 5, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "write", "minlen": 1, "flags": "RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "wNext", "minlen": 2, "flags": "RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "wall", "minlen": 2, "flags": "BANG|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "while", "minlen": 2, "flags": "EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_while"}), AttributeDict({"name": "winsize", "minlen": 2, "flags": "EXTRA|NEEDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "wincmd", "minlen": 4, "flags": "NEEDARG|WORD1|RANGE|CMDWIN|LOCK_OK", "parser": "parse_wincmd"}), AttributeDict({"name": "windo", "minlen": 4, "flags": "NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser": "parse_cmd_common"}), AttributeDict({"name": "winpos", "minlen": 4, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "wnext", "minlen": 2, "flags": "RANGE|BANG|FILE1|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "wprevious", "minlen": 2, "flags": "RANGE|BANG|FILE1|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "wq", "minlen": 2, "flags": "RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "wqall", "minlen": 3, "flags": "BANG|FILE1|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "wundo", "minlen": 2, "flags": "BANG|NEEDARG|FILE1", "parser": "parse_cmd_common"}), AttributeDict({"name": "wviminfo", "minlen": 2, "flags": "BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "xit", "minlen": 1, "flags": "RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "xall", "minlen": 2, "flags": "BANG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "xmap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "xmapclear", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "xmenu", "minlen": 3, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "xnoremap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "xnoremenu", "minlen": 7, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "xrestore", "minlen": 2, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "xunmap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "xunmenu", "minlen": 5, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "yank", "minlen": 1, "flags": "RANGE|WHOLEFOLD|REGSTR|COUNT|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "z", "minlen": 1, "flags": "RANGE|WHOLEFOLD|BANG|EXTRA|FLAGS|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "!", "minlen": 1, "flags": "RANGE|WHOLEFOLD|BANG|FILES|CMDWIN|LOCK_OK|NONWHITE_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "#", "minlen": 1, "flags": "RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "&", "minlen": 1, "flags": "RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|MODIFY|NONWHITE_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "*", "minlen": 1, "flags": "RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|LOCK_OK|NONWHITE_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "<", "minlen": 1, "flags": "RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "=", "minlen": 1, "flags": "RANGE|TRLBAR|DFLALL|FLAGS|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": ">", "minlen": 1, "flags": "RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "@", "minlen": 1, "flags": "RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|LOCK_OK|NONWHITE_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "{", "minlen": 1, "flags": "TRLBAR|LOCK_OK|CMDWIN", "parser": "parse_cmd_common"}), AttributeDict({"name": "}", "minlen": 1, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "~", "minlen": 1, "flags": "RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|MODIFY|NONWHITE_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "Next", "minlen": 1, "flags": "EXTRA|RANGE|COUNT|BANG|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "Print", "minlen": 1, "flags": "RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "X", "minlen": 1, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "++", "minlen": 1, "flags": "EXTRA|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "--", "minlen": 1, "flags": "EXTRA|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"})] + builtin_commands = [AttributeDict({"name": "append", "minlen": 1, "flags": "BANG|RANGE|ZEROR|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_append"}), AttributeDict({"name": "abbreviate", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "abclear", "minlen": 3, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "aboveleft", "minlen": 3, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "abstract", "minlen": 3, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_abstract"}), AttributeDict({"name": "all", "minlen": 2, "flags": "BANG|RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "amenu", "minlen": 2, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "anoremenu", "minlen": 2, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "args", "minlen": 2, "flags": "BANG|FILES|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "argadd", "minlen": 4, "flags": "BANG|RANGE|ZEROR|FILES|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "argdelete", "minlen": 4, "flags": "BANG|RANGE|FILES|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "argdo", "minlen": 5, "flags": "BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser": "parse_cmd_common"}), AttributeDict({"name": "argdedupe", "minlen": 6, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "argedit", "minlen": 4, "flags": "BANG|NEEDARG|RANGE|ZEROR|FILES|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "argglobal", "minlen": 4, "flags": "BANG|FILES|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "arglocal", "minlen": 4, "flags": "BANG|FILES|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "argument", "minlen": 4, "flags": "BANG|RANGE|COUNT|EXTRA|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "ascii", "minlen": 2, "flags": "TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "autocmd", "minlen": 2, "flags": "BANG|EXTRA|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "augroup", "minlen": 3, "flags": "BANG|WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "aunmenu", "minlen": 3, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "buffer", "minlen": 1, "flags": "BANG|RANGE|BUFNAME|BUFUNL|COUNT|EXTRA|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "bNext", "minlen": 2, "flags": "BANG|RANGE|COUNT|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "ball", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "badd", "minlen": 3, "flags": "NEEDARG|FILE1|CMDARG|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "balt", "minlen": 4, "flags": "NEEDARG|FILE1|CMDARG|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "bdelete", "minlen": 2, "flags": "BANG|RANGE|BUFNAME|COUNT|EXTRA|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "behave", "minlen": 2, "flags": "BANG|NEEDARG|WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "belowright", "minlen": 3, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "bfirst", "minlen": 2, "flags": "BANG|RANGE|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "blast", "minlen": 2, "flags": "BANG|RANGE|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "bmodified", "minlen": 2, "flags": "BANG|RANGE|COUNT|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "bnext", "minlen": 2, "flags": "BANG|RANGE|COUNT|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "botright", "minlen": 2, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "bprevious", "minlen": 2, "flags": "BANG|RANGE|COUNT|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "brewind", "minlen": 2, "flags": "BANG|RANGE|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "break", "minlen": 4, "flags": "TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_break"}), AttributeDict({"name": "breakadd", "minlen": 6, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "breakdel", "minlen": 6, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "breaklist", "minlen": 6, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "browse", "minlen": 3, "flags": "NEEDARG|EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "buffers", "minlen": 7, "flags": "BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "bufdo", "minlen": 4, "flags": "BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser": "parse_cmd_common"}), AttributeDict({"name": "bunload", "minlen": 3, "flags": "BANG|RANGE|BUFNAME|COUNT|EXTRA|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "bwipeout", "minlen": 2, "flags": "BANG|RANGE|BUFNAME|BUFUNL|COUNT|EXTRA|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "change", "minlen": 1, "flags": "BANG|WHOLEFOLD|RANGE|COUNT|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "cNext", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "cNfile", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "cabbrev", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "cabclear", "minlen": 4, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "cabove", "minlen": 4, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "caddbuffer", "minlen": 3, "flags": "RANGE|WORD1|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "caddexpr", "minlen": 5, "flags": "NEEDARG|WORD1|NOTRLCOM|EXPR_ARG", "parser": "parse_cmd_common"}), AttributeDict({"name": "caddfile", "minlen": 5, "flags": "TRLBAR|FILE1", "parser": "parse_cmd_common"}), AttributeDict({"name": "cafter", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "call", "minlen": 3, "flags": "RANGE|NEEDARG|EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_call"}), AttributeDict({"name": "catch", "minlen": 3, "flags": "EXTRA|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_catch"}), AttributeDict({"name": "cbuffer", "minlen": 2, "flags": "BANG|RANGE|WORD1|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "cbefore", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "cbelow", "minlen": 4, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "cbottom", "minlen": 3, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "cc", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "cclose", "minlen": 3, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "cd", "minlen": 2, "flags": "BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "cdo", "minlen": 3, "flags": "BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser": "parse_cmd_common"}), AttributeDict({"name": "center", "minlen": 2, "flags": "TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "cexpr", "minlen": 3, "flags": "NEEDARG|WORD1|NOTRLCOM|EXPR_ARG|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "cfile", "minlen": 2, "flags": "TRLBAR|FILE1|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "cfdo", "minlen": 3, "flags": "BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser": "parse_cmd_common"}), AttributeDict({"name": "cfirst", "minlen": 4, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "cgetfile", "minlen": 2, "flags": "TRLBAR|FILE1", "parser": "parse_cmd_common"}), AttributeDict({"name": "cgetbuffer", "minlen": 5, "flags": "RANGE|WORD1|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "cgetexpr", "minlen": 5, "flags": "NEEDARG|WORD1|NOTRLCOM|EXPR_ARG", "parser": "parse_cmd_common"}), AttributeDict({"name": "chdir", "minlen": 3, "flags": "BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "changes", "minlen": 7, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "checkpath", "minlen": 3, "flags": "TRLBAR|BANG|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "checktime", "minlen": 6, "flags": "RANGE|BUFNAME|COUNT|EXTRA|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "chistory", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "clist", "minlen": 2, "flags": "BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "clast", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "class", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_class"}), AttributeDict({"name": "close", "minlen": 3, "flags": "BANG|RANGE|COUNT|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "clearjumps", "minlen": 3, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "cmap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "cmapclear", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "cmenu", "minlen": 3, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "cnext", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "cnewer", "minlen": 4, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "cnfile", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "cnoremap", "minlen": 3, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "cnoreabbrev", "minlen": 6, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "cnoremenu", "minlen": 7, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "copy", "minlen": 2, "flags": "RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "colder", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "colorscheme", "minlen": 4, "flags": "WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "command", "minlen": 3, "flags": "EXTRA|BANG|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "comclear", "minlen": 4, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "compiler", "minlen": 4, "flags": "BANG|TRLBAR|WORD1|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "continue", "minlen": 3, "flags": "TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_continue"}), AttributeDict({"name": "confirm", "minlen": 4, "flags": "NEEDARG|EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "const", "minlen": 4, "flags": "EXTRA|BANG|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_const"}), AttributeDict({"name": "copen", "minlen": 4, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "cprevious", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "cpfile", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "cquit", "minlen": 2, "flags": "RANGE|COUNT|ZEROR|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "crewind", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "cscope", "minlen": 2, "flags": "EXTRA|NOTRLCOM|XFILE", "parser": "parse_cmd_common"}), AttributeDict({"name": "cstag", "minlen": 3, "flags": "BANG|TRLBAR|WORD1", "parser": "parse_cmd_common"}), AttributeDict({"name": "cunmap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "cunabbrev", "minlen": 4, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "cunmenu", "minlen": 5, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "cwindow", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "delete", "minlen": 1, "flags": "RANGE|WHOLEFOLD|REGSTR|COUNT|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "delmarks", "minlen": 4, "flags": "BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "debug", "minlen": 3, "flags": "NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "debuggreedy", "minlen": 6, "flags": "RANGE|ZEROR|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "def", "minlen": 3, "flags": "EXTRA|BANG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_def"}), AttributeDict({"name": "defer", "minlen": 4, "flags": "NEEDARG|EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_defer"}), AttributeDict({"name": "defcompile", "minlen": 4, "flags": "SBOXOK|CMDWIN|LOCK_OK|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "delcommand", "minlen": 4, "flags": "NEEDARG|WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "delfunction", "minlen": 4, "flags": "BANG|NEEDARG|WORD1|CMDWIN|LOCK_OK", "parser": "parse_cmd_delfunction"}), AttributeDict({"name": "display", "minlen": 2, "flags": "EXTRA|NOTRLCOM|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "diffupdate", "minlen": 3, "flags": "BANG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "diffget", "minlen": 5, "flags": "RANGE|EXTRA|TRLBAR|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "diffoff", "minlen": 5, "flags": "BANG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "diffpatch", "minlen": 5, "flags": "EXTRA|FILE1|TRLBAR|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "diffput", "minlen": 6, "flags": "RANGE|EXTRA|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "diffsplit", "minlen": 5, "flags": "EXTRA|FILE1|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "diffthis", "minlen": 5, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "digraphs", "minlen": 3, "flags": "BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "disassemble", "minlen": 4, "flags": "BANG|EXTRA|NEEDARG|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "djump", "minlen": 2, "flags": "BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA", "parser": "parse_cmd_common"}), AttributeDict({"name": "dlist", "minlen": 2, "flags": "BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "doautocmd", "minlen": 2, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "doautoall", "minlen": 7, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "drop", "minlen": 2, "flags": "FILES|CMDARG|NEEDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "dsearch", "minlen": 2, "flags": "BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "dsplit", "minlen": 3, "flags": "BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA", "parser": "parse_cmd_common"}), AttributeDict({"name": "edit", "minlen": 1, "flags": "BANG|FILE1|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "earlier", "minlen": 2, "flags": "TRLBAR|EXTRA|NOSPC|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "echo", "minlen": 2, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_echo"}), AttributeDict({"name": "echoerr", "minlen": 5, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_echoerr"}), AttributeDict({"name": "echohl", "minlen": 5, "flags": "EXTRA|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_echohl"}), AttributeDict({"name": "echomsg", "minlen": 5, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_echomsg"}), AttributeDict({"name": "echoconsole", "minlen": 5, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_echoconsole"}), AttributeDict({"name": "echowindow", "minlen": 5, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_echowindow"}), AttributeDict({"name": "echon", "minlen": 5, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_echon"}), AttributeDict({"name": "else", "minlen": 2, "flags": "TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_else"}), AttributeDict({"name": "elseif", "minlen": 5, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_elseif"}), AttributeDict({"name": "emenu", "minlen": 2, "flags": "NEEDARG|EXTRA|TRLBAR|NOTRLCOM|RANGE|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "endif", "minlen": 2, "flags": "TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_endif"}), AttributeDict({"name": "endinterface", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_endinterface"}), AttributeDict({"name": "endclass", "minlen": 4, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_endclass"}), AttributeDict({"name": "enddef", "minlen": 4, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_enddef"}), AttributeDict({"name": "endenum", "minlen": 4, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_endenum"}), AttributeDict({"name": "endfunction", "minlen": 4, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_endfunction"}), AttributeDict({"name": "endfor", "minlen": 5, "flags": "TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_endfor"}), AttributeDict({"name": "endtry", "minlen": 4, "flags": "TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_endtry"}), AttributeDict({"name": "endwhile", "minlen": 4, "flags": "TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_endwhile"}), AttributeDict({"name": "enew", "minlen": 3, "flags": "BANG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "enum", "minlen": 3, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_enum"}), AttributeDict({"name": "eval", "minlen": 2, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_eval"}), AttributeDict({"name": "ex", "minlen": 2, "flags": "BANG|FILE1|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "execute", "minlen": 3, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_execute"}), AttributeDict({"name": "exit", "minlen": 3, "flags": "RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "export", "minlen": 3, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|CMDWIN|LOCK_OK", "parser": "parse_cmd_export"}), AttributeDict({"name": "exusage", "minlen": 3, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "file", "minlen": 1, "flags": "RANGE|ZEROR|BANG|FILE1|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "files", "minlen": 5, "flags": "BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "filetype", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "filter", "minlen": 4, "flags": "BANG|NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "find", "minlen": 3, "flags": "RANGE|BANG|FILE1|CMDARG|ARGOPT|TRLBAR|NEEDARG", "parser": "parse_cmd_common"}), AttributeDict({"name": "final", "minlen": 4, "flags": "EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_final"}), AttributeDict({"name": "finally", "minlen": 6, "flags": "TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_finally"}), AttributeDict({"name": "finish", "minlen": 4, "flags": "TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_finish"}), AttributeDict({"name": "first", "minlen": 3, "flags": "EXTRA|BANG|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "fixdel", "minlen": 3, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "fold", "minlen": 2, "flags": "RANGE|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "foldclose", "minlen": 5, "flags": "RANGE|BANG|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "folddoopen", "minlen": 5, "flags": "RANGE|DFLALL|NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "folddoclosed", "minlen": 7, "flags": "RANGE|DFLALL|NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "foldopen", "minlen": 5, "flags": "RANGE|BANG|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "for", "minlen": 3, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_for"}), AttributeDict({"name": "function", "minlen": 2, "flags": "EXTRA|BANG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_function"}), AttributeDict({"name": "global", "minlen": 1, "flags": "RANGE|WHOLEFOLD|BANG|EXTRA|DFLALL|SBOXOK|CMDWIN|LOCK_OK|NONWHITE_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "goto", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "grep", "minlen": 2, "flags": "RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE", "parser": "parse_cmd_common"}), AttributeDict({"name": "grepadd", "minlen": 5, "flags": "RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE", "parser": "parse_cmd_common"}), AttributeDict({"name": "gui", "minlen": 2, "flags": "BANG|FILES|CMDARG|ARGOPT|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "gvim", "minlen": 2, "flags": "BANG|FILES|CMDARG|ARGOPT|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "help", "minlen": 1, "flags": "BANG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "helpclose", "minlen": 5, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "helpfind", "minlen": 5, "flags": "EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "helpgrep", "minlen": 5, "flags": "EXTRA|NOTRLCOM|NEEDARG", "parser": "parse_cmd_common"}), AttributeDict({"name": "helptags", "minlen": 5, "flags": "NEEDARG|FILES|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "hardcopy", "minlen": 2, "flags": "RANGE|COUNT|EXTRA|EXPAND|TRLBAR|DFLALL|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "highlight", "minlen": 2, "flags": "BANG|EXTRA|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "hide", "minlen": 3, "flags": "BANG|RANGE|COUNT|EXTRA|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "history", "minlen": 3, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "horizontal", "minlen": 2, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "insert", "minlen": 1, "flags": "BANG|RANGE|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_insert"}), AttributeDict({"name": "iabbrev", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "iabclear", "minlen": 4, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "if", "minlen": 2, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_if"}), AttributeDict({"name": "ijump", "minlen": 2, "flags": "BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA", "parser": "parse_cmd_common"}), AttributeDict({"name": "ilist", "minlen": 2, "flags": "BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "imap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "imapclear", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "imenu", "minlen": 3, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "import", "minlen": 3, "flags": "EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser": "parse_cmd_import"}), AttributeDict({"name": "inoremap", "minlen": 3, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "inoreabbrev", "minlen": 6, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "inoremenu", "minlen": 7, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "intro", "minlen": 3, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "interface", "minlen": 4, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_interface"}), AttributeDict({"name": "isearch", "minlen": 2, "flags": "BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "isplit", "minlen": 3, "flags": "BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA", "parser": "parse_cmd_common"}), AttributeDict({"name": "iunmap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "iunabbrev", "minlen": 4, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "iunmenu", "minlen": 5, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "join", "minlen": 1, "flags": "BANG|RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "jumps", "minlen": 2, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "k", "minlen": 1, "flags": "RANGE|WORD1|TRLBAR|SBOXOK|CMDWIN|LOCK_OK|NONWHITE_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "keepmarks", "minlen": 2, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "keepjumps", "minlen": 5, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "keeppatterns", "minlen": 5, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "keepalt", "minlen": 5, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "list", "minlen": 1, "flags": "RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "lNext", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "lNfile", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "last", "minlen": 2, "flags": "EXTRA|BANG|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "labove", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "language", "minlen": 3, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "laddexpr", "minlen": 3, "flags": "NEEDARG|WORD1|NOTRLCOM|EXPR_ARG", "parser": "parse_cmd_common"}), AttributeDict({"name": "laddbuffer", "minlen": 5, "flags": "RANGE|WORD1|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "laddfile", "minlen": 5, "flags": "TRLBAR|FILE1", "parser": "parse_cmd_common"}), AttributeDict({"name": "lafter", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "later", "minlen": 3, "flags": "TRLBAR|EXTRA|NOSPC|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "lbuffer", "minlen": 2, "flags": "BANG|RANGE|WORD1|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "lbefore", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "lbelow", "minlen": 4, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "lbottom", "minlen": 3, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "lcd", "minlen": 2, "flags": "BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "lchdir", "minlen": 3, "flags": "BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "lclose", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "lcscope", "minlen": 3, "flags": "EXTRA|NOTRLCOM|XFILE", "parser": "parse_cmd_common"}), AttributeDict({"name": "ldo", "minlen": 2, "flags": "BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser": "parse_cmd_common"}), AttributeDict({"name": "left", "minlen": 2, "flags": "TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "leftabove", "minlen": 5, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "let", "minlen": 3, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_let"}), AttributeDict({"name": "lexpr", "minlen": 3, "flags": "NEEDARG|WORD1|NOTRLCOM|EXPR_ARG|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "legacy", "minlen": 3, "flags": "NEEDARG|EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "lfile", "minlen": 2, "flags": "TRLBAR|FILE1|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "lfdo", "minlen": 3, "flags": "BANG|NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser": "parse_cmd_common"}), AttributeDict({"name": "lfirst", "minlen": 4, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "lgetfile", "minlen": 2, "flags": "TRLBAR|FILE1", "parser": "parse_cmd_common"}), AttributeDict({"name": "lgetbuffer", "minlen": 5, "flags": "RANGE|WORD1|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "lgetexpr", "minlen": 5, "flags": "NEEDARG|WORD1|NOTRLCOM|EXPR_ARG", "parser": "parse_cmd_common"}), AttributeDict({"name": "lgrep", "minlen": 3, "flags": "RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE", "parser": "parse_cmd_common"}), AttributeDict({"name": "lgrepadd", "minlen": 6, "flags": "RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE", "parser": "parse_cmd_common"}), AttributeDict({"name": "lhelpgrep", "minlen": 2, "flags": "EXTRA|NOTRLCOM|NEEDARG", "parser": "parse_cmd_common"}), AttributeDict({"name": "lhistory", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "ll", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "llast", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "llist", "minlen": 3, "flags": "BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "lmap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "lmapclear", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "lmake", "minlen": 4, "flags": "BANG|EXTRA|NOTRLCOM|TRLBAR|XFILE", "parser": "parse_cmd_common"}), AttributeDict({"name": "lnoremap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "lnext", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "lnewer", "minlen": 4, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "lnfile", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "loadview", "minlen": 2, "flags": "FILE1|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "loadkeymap", "minlen": 5, "flags": "CMDWIN|LOCK_OK", "parser": "parse_cmd_loadkeymap"}), AttributeDict({"name": "lockmarks", "minlen": 3, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "lockvar", "minlen": 5, "flags": "BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_lockvar"}), AttributeDict({"name": "lolder", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "lopen", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "lprevious", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "lpfile", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "lrewind", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR|BANG", "parser": "parse_cmd_common"}), AttributeDict({"name": "ltag", "minlen": 2, "flags": "TRLBAR|BANG|WORD1", "parser": "parse_cmd_common"}), AttributeDict({"name": "lunmap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "lua", "minlen": 3, "flags": "RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_lua"}), AttributeDict({"name": "luado", "minlen": 4, "flags": "RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "luafile", "minlen": 4, "flags": "RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "lvimgrep", "minlen": 2, "flags": "RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "lvimgrepadd", "minlen": 9, "flags": "RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "lwindow", "minlen": 2, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "ls", "minlen": 2, "flags": "BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "move", "minlen": 1, "flags": "RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "mark", "minlen": 2, "flags": "RANGE|WORD1|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "make", "minlen": 3, "flags": "BANG|EXTRA|NOTRLCOM|TRLBAR|XFILE", "parser": "parse_cmd_common"}), AttributeDict({"name": "map", "minlen": 3, "flags": "BANG|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "mapclear", "minlen": 4, "flags": "EXTRA|BANG|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "marks", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "match", "minlen": 3, "flags": "RANGE|EXTRA|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "menu", "minlen": 2, "flags": "RANGE|ZEROR|BANG|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "menutranslate", "minlen": 5, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "messages", "minlen": 3, "flags": "EXTRA|TRLBAR|RANGE|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "mkexrc", "minlen": 2, "flags": "BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "mksession", "minlen": 3, "flags": "BANG|FILE1|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "mkspell", "minlen": 4, "flags": "BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE", "parser": "parse_cmd_common"}), AttributeDict({"name": "mkvimrc", "minlen": 3, "flags": "BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "mkview", "minlen": 5, "flags": "BANG|FILE1|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "mode", "minlen": 3, "flags": "WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "mzscheme", "minlen": 2, "flags": "RANGE|EXTRA|DFLALL|NEEDARG|CMDWIN|LOCK_OK|SBOXOK|RESTRICT", "parser": "parse_cmd_mzscheme"}), AttributeDict({"name": "mzfile", "minlen": 3, "flags": "RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "next", "minlen": 1, "flags": "RANGE|BANG|FILES|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "nbkey", "minlen": 2, "flags": "EXTRA|NEEDARG", "parser": "parse_cmd_common"}), AttributeDict({"name": "nbclose", "minlen": 3, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "nbstart", "minlen": 3, "flags": "WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "new", "minlen": 3, "flags": "BANG|FILE1|RANGE|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "nmap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "nmapclear", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "nmenu", "minlen": 3, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "nnoremap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "nnoremenu", "minlen": 7, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "noremap", "minlen": 2, "flags": "BANG|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "noautocmd", "minlen": 3, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "nohlsearch", "minlen": 3, "flags": "TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "noreabbrev", "minlen": 5, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "noremenu", "minlen": 6, "flags": "RANGE|ZEROR|BANG|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "noswapfile", "minlen": 3, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "normal", "minlen": 4, "flags": "RANGE|BANG|EXTRA|NEEDARG|NOTRLCOM|CTRLV|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "number", "minlen": 2, "flags": "RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "nunmap", "minlen": 3, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "nunmenu", "minlen": 5, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "open", "minlen": 1, "flags": "RANGE|BANG|EXTRA", "parser": "parse_cmd_common"}), AttributeDict({"name": "oldfiles", "minlen": 2, "flags": "BANG|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "omap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "omapclear", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "omenu", "minlen": 3, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "only", "minlen": 2, "flags": "BANG|RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "onoremap", "minlen": 3, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "onoremenu", "minlen": 7, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "options", "minlen": 3, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "ounmap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "ounmenu", "minlen": 5, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "ownsyntax", "minlen": 2, "flags": "EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "print", "minlen": 1, "flags": "RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK|SBOXOK", "parser": "parse_cmd_common"}), AttributeDict({"name": "packadd", "minlen": 2, "flags": "BANG|FILE1|NEEDARG|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "packloadall", "minlen": 5, "flags": "BANG|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "pclose", "minlen": 2, "flags": "BANG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "perl", "minlen": 2, "flags": "RANGE|EXTRA|DFLALL|NEEDARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_perl"}), AttributeDict({"name": "perldo", "minlen": 5, "flags": "RANGE|EXTRA|DFLALL|NEEDARG|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "pedit", "minlen": 3, "flags": "BANG|FILE1|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "pop", "minlen": 2, "flags": "RANGE|BANG|COUNT|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "popup", "minlen": 4, "flags": "NEEDARG|EXTRA|BANG|TRLBAR|NOTRLCOM|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "ppop", "minlen": 2, "flags": "RANGE|BANG|COUNT|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "preserve", "minlen": 3, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "previous", "minlen": 4, "flags": "EXTRA|RANGE|COUNT|BANG|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "promptfind", "minlen": 3, "flags": "EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "promptrepl", "minlen": 7, "flags": "EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "profile", "minlen": 4, "flags": "BANG|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "profdel", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "psearch", "minlen": 2, "flags": "BANG|RANGE|WHOLEFOLD|DFLALL|EXTRA", "parser": "parse_cmd_common"}), AttributeDict({"name": "ptag", "minlen": 2, "flags": "RANGE|BANG|WORD1|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "ptNext", "minlen": 3, "flags": "RANGE|BANG|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "ptfirst", "minlen": 3, "flags": "RANGE|BANG|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "ptjump", "minlen": 3, "flags": "BANG|TRLBAR|WORD1", "parser": "parse_cmd_common"}), AttributeDict({"name": "ptlast", "minlen": 3, "flags": "BANG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "ptnext", "minlen": 3, "flags": "RANGE|BANG|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "ptprevious", "minlen": 3, "flags": "RANGE|BANG|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "ptrewind", "minlen": 3, "flags": "RANGE|BANG|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "ptselect", "minlen": 3, "flags": "BANG|TRLBAR|WORD1", "parser": "parse_cmd_common"}), AttributeDict({"name": "public", "minlen": 3, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_public"}), AttributeDict({"name": "put", "minlen": 2, "flags": "RANGE|WHOLEFOLD|BANG|REGSTR|TRLBAR|ZEROR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "pwd", "minlen": 2, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "python", "minlen": 2, "flags": "RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_python"}), AttributeDict({"name": "pydo", "minlen": 3, "flags": "RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "pyfile", "minlen": 3, "flags": "RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "py3", "minlen": 3, "flags": "RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_python3"}), AttributeDict({"name": "py3do", "minlen": 4, "flags": "RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "python3", "minlen": 7, "flags": "RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_python3"}), AttributeDict({"name": "py3file", "minlen": 4, "flags": "RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "pyx", "minlen": 3, "flags": "RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "pyxdo", "minlen": 4, "flags": "RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "pythonx", "minlen": 7, "flags": "RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "pyxfile", "minlen": 4, "flags": "RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "quit", "minlen": 1, "flags": "BANG|RANGE|COUNT|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "quitall", "minlen": 5, "flags": "BANG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "qall", "minlen": 2, "flags": "BANG|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "read", "minlen": 1, "flags": "BANG|RANGE|WHOLEFOLD|FILE1|ARGOPT|TRLBAR|ZEROR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "recover", "minlen": 3, "flags": "BANG|FILE1|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "redo", "minlen": 3, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "redir", "minlen": 4, "flags": "BANG|FILES|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "redraw", "minlen": 4, "flags": "BANG|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "redrawstatus", "minlen": 7, "flags": "BANG|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "redrawtabline", "minlen": 7, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "registers", "minlen": 3, "flags": "EXTRA|NOTRLCOM|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "resize", "minlen": 3, "flags": "RANGE|TRLBAR|WORD1|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "retab", "minlen": 3, "flags": "TRLBAR|RANGE|WHOLEFOLD|DFLALL|BANG|WORD1|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "return", "minlen": 4, "flags": "EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_return"}), AttributeDict({"name": "rewind", "minlen": 3, "flags": "EXTRA|BANG|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "right", "minlen": 2, "flags": "TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "rightbelow", "minlen": 6, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "runtime", "minlen": 2, "flags": "BANG|NEEDARG|FILES|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "ruby", "minlen": 3, "flags": "RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_ruby"}), AttributeDict({"name": "rubydo", "minlen": 5, "flags": "RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "rubyfile", "minlen": 5, "flags": "RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "rundo", "minlen": 4, "flags": "NEEDARG|FILE1", "parser": "parse_cmd_common"}), AttributeDict({"name": "rviminfo", "minlen": 2, "flags": "BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "substitute", "minlen": 1, "flags": "RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|NONWHITE_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "sNext", "minlen": 2, "flags": "EXTRA|RANGE|COUNT|BANG|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sargument", "minlen": 2, "flags": "BANG|RANGE|COUNT|EXTRA|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sall", "minlen": 3, "flags": "BANG|RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sandbox", "minlen": 3, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "saveas", "minlen": 3, "flags": "BANG|FILE1|ARGOPT|CMDWIN|LOCK_OK|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sbuffer", "minlen": 2, "flags": "BANG|RANGE|BUFNAME|BUFUNL|COUNT|EXTRA|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sbNext", "minlen": 3, "flags": "RANGE|COUNT|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sball", "minlen": 3, "flags": "RANGE|COUNT|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sbfirst", "minlen": 3, "flags": "CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sblast", "minlen": 3, "flags": "CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sbmodified", "minlen": 3, "flags": "RANGE|COUNT|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sbnext", "minlen": 3, "flags": "RANGE|COUNT|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sbprevious", "minlen": 3, "flags": "RANGE|COUNT|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sbrewind", "minlen": 3, "flags": "CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "scriptnames", "minlen": 2, "flags": "BANG|RANGE|COUNT|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "scriptencoding", "minlen": 7, "flags": "WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "scriptversion", "minlen": 7, "flags": "WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "scscope", "minlen": 3, "flags": "EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "set", "minlen": 2, "flags": "BANG|TRLBAR|EXTRA|CMDWIN|LOCK_OK|SBOXOK", "parser": "parse_cmd_common"}), AttributeDict({"name": "setfiletype", "minlen": 4, "flags": "TRLBAR|EXTRA|NEEDARG|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "setglobal", "minlen": 4, "flags": "BANG|TRLBAR|EXTRA|CMDWIN|LOCK_OK|SBOXOK", "parser": "parse_cmd_common"}), AttributeDict({"name": "setlocal", "minlen": 4, "flags": "BANG|TRLBAR|EXTRA|CMDWIN|LOCK_OK|SBOXOK", "parser": "parse_cmd_common"}), AttributeDict({"name": "sfind", "minlen": 2, "flags": "BANG|FILE1|RANGE|CMDARG|ARGOPT|TRLBAR|NEEDARG", "parser": "parse_cmd_common"}), AttributeDict({"name": "sfirst", "minlen": 4, "flags": "EXTRA|BANG|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "shell", "minlen": 2, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "simalt", "minlen": 2, "flags": "NEEDARG|WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "sign", "minlen": 3, "flags": "NEEDARG|RANGE|EXTRA|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "silent", "minlen": 3, "flags": "NEEDARG|EXTRA|BANG|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "sleep", "minlen": 2, "flags": "BANG|RANGE|COUNT|EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "slast", "minlen": 3, "flags": "EXTRA|BANG|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "smagic", "minlen": 2, "flags": "RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|NONWHITE_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "smap", "minlen": 4, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "smapclear", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "smenu", "minlen": 3, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "snext", "minlen": 2, "flags": "RANGE|BANG|FILES|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "snomagic", "minlen": 3, "flags": "RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|NONWHITE_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "snoremap", "minlen": 4, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "snoremenu", "minlen": 7, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "source", "minlen": 2, "flags": "BANG|FILE1|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "sort", "minlen": 3, "flags": "RANGE|DFLALL|WHOLEFOLD|BANG|EXTRA|NOTRLCOM|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "split", "minlen": 2, "flags": "BANG|FILE1|RANGE|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "spellgood", "minlen": 3, "flags": "BANG|RANGE|NEEDARG|EXTRA|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "spelldump", "minlen": 6, "flags": "BANG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "spellinfo", "minlen": 6, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "spellrepall", "minlen": 6, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "spellrare", "minlen": 7, "flags": "BANG|RANGE|NEEDARG|EXTRA|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "spellundo", "minlen": 6, "flags": "BANG|RANGE|NEEDARG|EXTRA|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "spellwrong", "minlen": 6, "flags": "BANG|RANGE|NEEDARG|EXTRA|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sprevious", "minlen": 3, "flags": "EXTRA|RANGE|COUNT|BANG|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "srewind", "minlen": 2, "flags": "EXTRA|BANG|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "stop", "minlen": 2, "flags": "TRLBAR|BANG|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "stag", "minlen": 3, "flags": "RANGE|BANG|WORD1|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "startinsert", "minlen": 4, "flags": "BANG|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "startgreplace", "minlen": 6, "flags": "BANG|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "startreplace", "minlen": 6, "flags": "BANG|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "static", "minlen": 4, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_static"}), AttributeDict({"name": "stopinsert", "minlen": 5, "flags": "BANG|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "stjump", "minlen": 3, "flags": "BANG|TRLBAR|WORD1", "parser": "parse_cmd_common"}), AttributeDict({"name": "stselect", "minlen": 3, "flags": "BANG|TRLBAR|WORD1", "parser": "parse_cmd_common"}), AttributeDict({"name": "sunhide", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "sunmap", "minlen": 4, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "sunmenu", "minlen": 5, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "suspend", "minlen": 3, "flags": "TRLBAR|BANG|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "sview", "minlen": 2, "flags": "BANG|FILE1|RANGE|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "swapname", "minlen": 2, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "syntax", "minlen": 2, "flags": "EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser": "parse_cmd_syntax"}), AttributeDict({"name": "syntime", "minlen": 5, "flags": "NEEDARG|WORD1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "syncbind", "minlen": 4, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "smile", "minlen": 3, "flags": "TRLBAR|CMDWIN|LOCK_OK|SBOXOK", "parser": "parse_cmd_common"}), AttributeDict({"name": "t", "minlen": 1, "flags": "RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "tNext", "minlen": 2, "flags": "RANGE|BANG|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tag", "minlen": 2, "flags": "RANGE|BANG|WORD1|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tags", "minlen": 4, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tab", "minlen": 3, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabclose", "minlen": 4, "flags": "BANG|RANGE|ZEROR|EXTRA|NOSPC|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabdo", "minlen": 4, "flags": "NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabedit", "minlen": 4, "flags": "BANG|FILE1|RANGE|ZEROR|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabfind", "minlen": 4, "flags": "BANG|FILE1|RANGE|ZEROR|CMDARG|ARGOPT|NEEDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabfirst", "minlen": 6, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabmove", "minlen": 4, "flags": "RANGE|ZEROR|EXTRA|NOSPC|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tablast", "minlen": 4, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabnext", "minlen": 4, "flags": "RANGE|ZEROR|EXTRA|NOSPC|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabnew", "minlen": 6, "flags": "BANG|FILE1|RANGE|ZEROR|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabonly", "minlen": 4, "flags": "BANG|RANGE|ZEROR|EXTRA|NOSPC|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabprevious", "minlen": 4, "flags": "RANGE|ZEROR|EXTRA|NOSPC|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabNext", "minlen": 4, "flags": "RANGE|ZEROR|EXTRA|NOSPC|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabrewind", "minlen": 4, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tabs", "minlen": 4, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tcd", "minlen": 2, "flags": "BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tchdir", "minlen": 3, "flags": "BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tcl", "minlen": 3, "flags": "RANGE|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_tcl"}), AttributeDict({"name": "tcldo", "minlen": 4, "flags": "RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "tclfile", "minlen": 4, "flags": "RANGE|FILE1|NEEDARG|CMDWIN|LOCK_OK|RESTRICT", "parser": "parse_cmd_common"}), AttributeDict({"name": "tearoff", "minlen": 2, "flags": "NEEDARG|EXTRA|TRLBAR|NOTRLCOM|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "terminal", "minlen": 3, "flags": "RANGE|BANG|FILES|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tfirst", "minlen": 2, "flags": "RANGE|BANG|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "throw", "minlen": 2, "flags": "EXTRA|NEEDARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_throw"}), AttributeDict({"name": "tjump", "minlen": 2, "flags": "BANG|TRLBAR|WORD1", "parser": "parse_cmd_common"}), AttributeDict({"name": "tlast", "minlen": 2, "flags": "BANG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tlmenu", "minlen": 3, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tlnoremenu", "minlen": 3, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tlunmenu", "minlen": 3, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tmenu", "minlen": 2, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tmap", "minlen": 3, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tmapclear", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tnext", "minlen": 2, "flags": "RANGE|BANG|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "tnoremap", "minlen": 3, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "topleft", "minlen": 2, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "tprevious", "minlen": 2, "flags": "RANGE|BANG|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "trewind", "minlen": 2, "flags": "RANGE|BANG|TRLBAR|ZEROR", "parser": "parse_cmd_common"}), AttributeDict({"name": "try", "minlen": 3, "flags": "TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_try"}), AttributeDict({"name": "tselect", "minlen": 2, "flags": "BANG|TRLBAR|WORD1", "parser": "parse_cmd_common"}), AttributeDict({"name": "tunmenu", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "tunmap", "minlen": 5, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "type", "minlen": 2, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_type"}), AttributeDict({"name": "undo", "minlen": 1, "flags": "RANGE|COUNT|ZEROR|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "undojoin", "minlen": 5, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "undolist", "minlen": 5, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "unabbreviate", "minlen": 3, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "unhide", "minlen": 3, "flags": "RANGE|COUNT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "unlet", "minlen": 3, "flags": "BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_unlet"}), AttributeDict({"name": "unlockvar", "minlen": 4, "flags": "BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_unlockvar"}), AttributeDict({"name": "unmap", "minlen": 3, "flags": "BANG|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "unmenu", "minlen": 4, "flags": "BANG|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "unsilent", "minlen": 3, "flags": "NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "update", "minlen": 2, "flags": "RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "vglobal", "minlen": 1, "flags": "RANGE|WHOLEFOLD|EXTRA|DFLALL|CMDWIN|LOCK_OK|NONWHITE_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "var", "minlen": 2, "flags": "EXTRA|NOTRLCOM|EXPR_ARG|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_var"}), AttributeDict({"name": "version", "minlen": 2, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "verbose", "minlen": 4, "flags": "NEEDARG|RANGE|EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "vertical", "minlen": 4, "flags": "NEEDARG|EXTRA|NOTRLCOM", "parser": "parse_cmd_common"}), AttributeDict({"name": "visual", "minlen": 2, "flags": "BANG|FILE1|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "view", "minlen": 3, "flags": "BANG|FILE1|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "vimgrep", "minlen": 3, "flags": "RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "vimgrepadd", "minlen": 8, "flags": "RANGE|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "vim9cmd", "minlen": 4, "flags": "NEEDARG|EXTRA|NOTRLCOM|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "vim9script", "minlen": 5, "flags": "WORD1|CMDWIN|LOCK_OK", "parser": "parse_cmd_vim9script"}), AttributeDict({"name": "viusage", "minlen": 3, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "vmap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "vmapclear", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "vmenu", "minlen": 3, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "vnoremap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "vnew", "minlen": 3, "flags": "BANG|FILE1|RANGE|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "vnoremenu", "minlen": 7, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "vsplit", "minlen": 2, "flags": "BANG|FILE1|RANGE|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "vunmap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "vunmenu", "minlen": 5, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "write", "minlen": 1, "flags": "RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "wNext", "minlen": 2, "flags": "RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "wall", "minlen": 2, "flags": "BANG|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "while", "minlen": 2, "flags": "EXTRA|NOTRLCOM|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_while"}), AttributeDict({"name": "winsize", "minlen": 2, "flags": "EXTRA|NEEDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "wincmd", "minlen": 4, "flags": "NEEDARG|WORD1|RANGE|CMDWIN|LOCK_OK", "parser": "parse_wincmd"}), AttributeDict({"name": "windo", "minlen": 4, "flags": "NEEDARG|EXTRA|NOTRLCOM|RANGE|DFLALL|EXPAND", "parser": "parse_cmd_common"}), AttributeDict({"name": "winpos", "minlen": 4, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "wnext", "minlen": 2, "flags": "RANGE|BANG|FILE1|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "wprevious", "minlen": 2, "flags": "RANGE|BANG|FILE1|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "wq", "minlen": 2, "flags": "RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "wqall", "minlen": 3, "flags": "BANG|FILE1|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "wundo", "minlen": 2, "flags": "BANG|NEEDARG|FILE1", "parser": "parse_cmd_common"}), AttributeDict({"name": "wviminfo", "minlen": 2, "flags": "BANG|FILE1|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "xit", "minlen": 1, "flags": "RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "xall", "minlen": 2, "flags": "BANG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "xmap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "xmapclear", "minlen": 5, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "xmenu", "minlen": 3, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "xnoremap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "xnoremenu", "minlen": 7, "flags": "RANGE|ZEROR|EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "xrestore", "minlen": 2, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "xunmap", "minlen": 2, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "xunmenu", "minlen": 5, "flags": "EXTRA|TRLBAR|NOTRLCOM|CTRLV|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "yank", "minlen": 1, "flags": "RANGE|WHOLEFOLD|REGSTR|COUNT|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "z", "minlen": 1, "flags": "RANGE|WHOLEFOLD|BANG|EXTRA|FLAGS|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "!", "minlen": 1, "flags": "RANGE|WHOLEFOLD|BANG|FILES|CMDWIN|LOCK_OK|NONWHITE_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "#", "minlen": 1, "flags": "RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "&", "minlen": 1, "flags": "RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|MODIFY|NONWHITE_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "*", "minlen": 1, "flags": "RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|LOCK_OK|NONWHITE_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "<", "minlen": 1, "flags": "RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "=", "minlen": 1, "flags": "RANGE|TRLBAR|DFLALL|FLAGS|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": ">", "minlen": 1, "flags": "RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "@", "minlen": 1, "flags": "RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|LOCK_OK|NONWHITE_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "{", "minlen": 1, "flags": "TRLBAR|LOCK_OK|CMDWIN", "parser": "parse_cmd_block"}), AttributeDict({"name": "}", "minlen": 1, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_endblock"}), AttributeDict({"name": "~", "minlen": 1, "flags": "RANGE|WHOLEFOLD|EXTRA|CMDWIN|LOCK_OK|MODIFY|NONWHITE_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "Next", "minlen": 1, "flags": "EXTRA|RANGE|COUNT|BANG|CMDARG|ARGOPT|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "Print", "minlen": 1, "flags": "RANGE|WHOLEFOLD|COUNT|FLAGS|TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "X", "minlen": 1, "flags": "TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "++", "minlen": 1, "flags": "EXTRA|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "--", "minlen": 1, "flags": "EXTRA|TRLBAR|SBOXOK|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "clipreset", "minlen": 4, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "iput", "minlen": 2, "flags": "RANGE|WHOLEFOLD|BANG|REGSTR|TRLBAR|ZEROR|CMDWIN|LOCK_OK|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "pbuffer", "minlen": 2, "flags": "BANG|RANGE|BUFNAME|BUFUNL|COUNT|EXTRA|CMDARG|TRLBAR", "parser": "parse_cmd_common"}), AttributeDict({"name": "redrawtabpanel", "minlen": 10, "flags": "TRLBAR|CMDWIN|LOCK_OK", "parser": "parse_cmd_common"}), AttributeDict({"name": "this", "minlen": 3, "flags": "EXTRA|NEEDARG|SBOXOK|CMDWIN|LOCK_OK|WHOLE", "parser": "parse_cmd_common"}), AttributeDict({"name": "uniq", "minlen": 3, "flags": "RANGE|DFLALL|WHOLEFOLD|BANG|EXTRA|NOTRLCOM|MODIFY", "parser": "parse_cmd_common"}), AttributeDict({"name": "wlrestore", "minlen": 2, "flags": "EXTRA|TRLBAR|CMDWIN|LOCK_OK|BANG", "parser": "parse_cmd_common"})] # To find new builtin_functions, run the below script. # $ scripts/update_builtin_functions.sh /path/to/vim/src/evalfunc.c builtin_functions = [AttributeDict({"name": "abs", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "acos", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "add", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "and", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "append", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_2"}), AttributeDict({"name": "appendbufline", "min_argc": 3, "max_argc": 3, "argtype": "FEARG_3"}), AttributeDict({"name": "argc", "min_argc": 0, "max_argc": 1, "argtype": "0"}), AttributeDict({"name": "argidx", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "arglistid", "min_argc": 0, "max_argc": 2, "argtype": "0"}), AttributeDict({"name": "argv", "min_argc": 0, "max_argc": 2, "argtype": "0"}), AttributeDict({"name": "asin", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "assert_beeps", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "assert_equal", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_2"}), AttributeDict({"name": "assert_equalfile", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "assert_exception", "min_argc": 1, "max_argc": 2, "argtype": "0"}), AttributeDict({"name": "assert_fails", "min_argc": 1, "max_argc": 5, "argtype": "FEARG_1"}), AttributeDict({"name": "assert_false", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "assert_inrange", "min_argc": 3, "max_argc": 4, "argtype": "FEARG_3"}), AttributeDict({"name": "assert_match", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_2"}), AttributeDict({"name": "assert_nobeep", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "assert_notequal", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_2"}), AttributeDict({"name": "assert_notmatch", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_2"}), AttributeDict({"name": "assert_report", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "assert_true", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "atan", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "atan2", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "autocmd_add", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "autocmd_delete", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "autocmd_get", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "balloon_gettext", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "balloon_show", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "balloon_split", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "blob2list", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "browse", "min_argc": 4, "max_argc": 4, "argtype": "0"}), AttributeDict({"name": "browsedir", "min_argc": 2, "max_argc": 2, "argtype": "0"}), AttributeDict({"name": "bufadd", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "bufexists", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "buffer_exists", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "buffer_name", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "buffer_number", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "buflisted", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "bufload", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "bufloaded", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "bufname", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "bufnr", "min_argc": 0, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "bufwinid", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "bufwinnr", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "byte2line", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "byteidx", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "byteidxcomp", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "call", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "ceil", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "ch_canread", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "ch_close", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "ch_close_in", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "ch_evalexpr", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "ch_evalraw", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "ch_getbufnr", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "ch_getjob", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "ch_info", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "ch_log", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "ch_logfile", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "ch_open", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "ch_read", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "ch_readblob", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "ch_readraw", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "ch_sendexpr", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "ch_sendraw", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "ch_setoptions", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "ch_status", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "changenr", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "char2nr", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "charclass", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "charcol", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "charidx", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "chdir", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "cindent", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "clearmatches", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "col", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "complete", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_2"}), AttributeDict({"name": "complete_add", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "complete_check", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "complete_info", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "confirm", "min_argc": 1, "max_argc": 4, "argtype": "FEARG_1"}), AttributeDict({"name": "copy", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "cos", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "cosh", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "count", "min_argc": 2, "max_argc": 4, "argtype": "FEARG_1"}), AttributeDict({"name": "cscope_connection", "min_argc": 0, "max_argc": 3, "argtype": "0"}), AttributeDict({"name": "cursor", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "debugbreak", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "deepcopy", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "delete", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "deletebufline", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "did_filetype", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "diff_filler", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "diff_hlID", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "digraph_get", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "digraph_getlist", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "digraph_set", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "digraph_setlist", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "echoraw", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "empty", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "environ", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "escape", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "eval", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "eventhandler", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "executable", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "execute", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "exepath", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "exists", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "exists_compiled", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "exp", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "expand", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "expandcmd", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "extend", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "extendnew", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "feedkeys", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "file_readable", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "filereadable", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "filewritable", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "filter", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "finddir", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "findfile", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "flatten", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "flattennew", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "float2nr", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "floor", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "fmod", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "fnameescape", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "fnamemodify", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "foldclosed", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "foldclosedend", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "foldlevel", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "foldtext", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "foldtextresult", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "foreground", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "fullcommand", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "funcref", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "function", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "garbagecollect", "min_argc": 0, "max_argc": 1, "argtype": "0"}), AttributeDict({"name": "get", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "getbufinfo", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "getbufline", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "getbufvar", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "getchangelist", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "getchar", "min_argc": 0, "max_argc": 1, "argtype": "0"}), AttributeDict({"name": "getcharmod", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "getcharpos", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "getcharsearch", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "getcharstr", "min_argc": 0, "max_argc": 1, "argtype": "0"}), AttributeDict({"name": "getcmdcompltype", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "getcmdline", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "getcmdpos", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "getcmdscreenpos", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "getcmdtype", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "getcmdwintype", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "getcompletion", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "getcurpos", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "getcursorcharpos", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "getcwd", "min_argc": 0, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "getenv", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "getfontname", "min_argc": 0, "max_argc": 1, "argtype": "0"}), AttributeDict({"name": "getfperm", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "getfsize", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "getftime", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "getftype", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "getimstatus", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "getjumplist", "min_argc": 0, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "getline", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "getloclist", "min_argc": 1, "max_argc": 2, "argtype": "0"}), AttributeDict({"name": "getmarklist", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "getmatches", "min_argc": 0, "max_argc": 1, "argtype": "0"}), AttributeDict({"name": "getmousepos", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "getpid", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "getpos", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "getqflist", "min_argc": 0, "max_argc": 1, "argtype": "0"}), AttributeDict({"name": "getreg", "min_argc": 0, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "getreginfo", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "getregtype", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "getscriptinfo", "min_argc": 0, "max_argc": 1, "argtype": "0"}), AttributeDict({"name": "gettabinfo", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "gettabvar", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "gettabwinvar", "min_argc": 3, "max_argc": 4, "argtype": "FEARG_1"}), AttributeDict({"name": "gettagstack", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "gettext", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "getwininfo", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "getwinpos", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "getwinposx", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "getwinposy", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "getwinvar", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "glob", "min_argc": 1, "max_argc": 4, "argtype": "FEARG_1"}), AttributeDict({"name": "glob2regpat", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "globpath", "min_argc": 2, "max_argc": 5, "argtype": "FEARG_2"}), AttributeDict({"name": "has", "min_argc": 1, "max_argc": 2, "argtype": "0"}), AttributeDict({"name": "has_key", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "haslocaldir", "min_argc": 0, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "hasmapto", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "highlightID", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "highlight_exists", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "histadd", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_2"}), AttributeDict({"name": "histdel", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "histget", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "histnr", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "hlID", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "hlexists", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "hlget", "min_argc": 0, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "hlset", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "hostname", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "iconv", "min_argc": 3, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "indent", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "index", "min_argc": 2, "max_argc": 4, "argtype": "FEARG_1"}), AttributeDict({"name": "indexof", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "input", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "inputdialog", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "inputlist", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "inputrestore", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "inputsave", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "inputsecret", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "insert", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "interrupt", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "invert", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "isabsolutepath", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "isdirectory", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "isinf", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "islocked", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "isnan", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "items", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "job_getchannel", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "job_info", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "job_setoptions", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "job_start", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "job_status", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "job_stop", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "join", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "js_decode", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "js_encode", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "json_decode", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "json_encode", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "keys", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "last_buffer_nr", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "len", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "libcall", "min_argc": 3, "max_argc": 3, "argtype": "FEARG_3"}), AttributeDict({"name": "libcallnr", "min_argc": 3, "max_argc": 3, "argtype": "FEARG_3"}), AttributeDict({"name": "line", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "line2byte", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "lispindent", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "list2blob", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "list2str", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "listener_add", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_2"}), AttributeDict({"name": "listener_flush", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "listener_remove", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "localtime", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "log", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "log10", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "luaeval", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "map", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "maparg", "min_argc": 1, "max_argc": 4, "argtype": "FEARG_1"}), AttributeDict({"name": "mapcheck", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "maplist", "min_argc": 0, "max_argc": 1, "argtype": "0"}), AttributeDict({"name": "mapnew", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "mapset", "min_argc": 3, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "match", "min_argc": 2, "max_argc": 4, "argtype": "FEARG_1"}), AttributeDict({"name": "matchadd", "min_argc": 2, "max_argc": 5, "argtype": "FEARG_1"}), AttributeDict({"name": "matchaddpos", "min_argc": 2, "max_argc": 5, "argtype": "FEARG_1"}), AttributeDict({"name": "matcharg", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "matchdelete", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "matchend", "min_argc": 2, "max_argc": 4, "argtype": "FEARG_1"}), AttributeDict({"name": "matchfuzzy", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "matchfuzzypos", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "matchlist", "min_argc": 2, "max_argc": 4, "argtype": "FEARG_1"}), AttributeDict({"name": "matchstr", "min_argc": 2, "max_argc": 4, "argtype": "FEARG_1"}), AttributeDict({"name": "matchstrpos", "min_argc": 2, "max_argc": 4, "argtype": "FEARG_1"}), AttributeDict({"name": "max", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "menu_info", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "min", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "mkdir", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "mode", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "mzeval", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "nextnonblank", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "nr2char", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "or", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "pathshorten", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "perleval", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "popup_atcursor", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "popup_beval", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "popup_clear", "min_argc": 0, "max_argc": 1, "argtype": "0"}), AttributeDict({"name": "popup_close", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "popup_create", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "popup_dialog", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "popup_filter_menu", "min_argc": 2, "max_argc": 2, "argtype": "0"}), AttributeDict({"name": "popup_filter_yesno", "min_argc": 2, "max_argc": 2, "argtype": "0"}), AttributeDict({"name": "popup_findinfo", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "popup_findpreview", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "popup_getoptions", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "popup_getpos", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "popup_hide", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "popup_list", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "popup_locate", "min_argc": 2, "max_argc": 2, "argtype": "0"}), AttributeDict({"name": "popup_menu", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "popup_move", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "popup_notification", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "popup_setoptions", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "popup_settext", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "popup_show", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "pow", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "prevnonblank", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "printf", "min_argc": 1, "max_argc": 19, "argtype": "FEARG_2"}), AttributeDict({"name": "prompt_getprompt", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "prompt_setcallback", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "prompt_setinterrupt", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "prompt_setprompt", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "prop_add", "min_argc": 3, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "prop_add_list", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "prop_clear", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "prop_find", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "prop_list", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "prop_remove", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "prop_type_add", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "prop_type_change", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "prop_type_delete", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "prop_type_get", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "prop_type_list", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "pum_getpos", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "pumvisible", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "py3eval", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "pyeval", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "pyxeval", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "rand", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "range", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "readblob", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "readdir", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "readdirex", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "readfile", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "reduce", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "reg_executing", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "reg_recording", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "reltime", "min_argc": 0, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "reltimefloat", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "reltimestr", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "remote_expr", "min_argc": 2, "max_argc": 4, "argtype": "FEARG_1"}), AttributeDict({"name": "remote_foreground", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "remote_peek", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "remote_read", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "remote_send", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "remote_startserver", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "remove", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "rename", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "repeat", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "resolve", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "reverse", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "round", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "rubyeval", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "screenattr", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "screenchar", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "screenchars", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "screencol", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "screenpos", "min_argc": 3, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "screenrow", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "screenstring", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "search", "min_argc": 1, "max_argc": 5, "argtype": "FEARG_1"}), AttributeDict({"name": "searchcount", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "searchdecl", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "searchpair", "min_argc": 3, "max_argc": 7, "argtype": "0"}), AttributeDict({"name": "searchpairpos", "min_argc": 3, "max_argc": 7, "argtype": "0"}), AttributeDict({"name": "searchpos", "min_argc": 1, "max_argc": 5, "argtype": "FEARG_1"}), AttributeDict({"name": "server2client", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "serverlist", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "setbufline", "min_argc": 3, "max_argc": 3, "argtype": "FEARG_3"}), AttributeDict({"name": "setbufvar", "min_argc": 3, "max_argc": 3, "argtype": "FEARG_3"}), AttributeDict({"name": "setcellwidths", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "setcharpos", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_2"}), AttributeDict({"name": "setcharsearch", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "setcmdline", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "setcmdpos", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "setcursorcharpos", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "setenv", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_2"}), AttributeDict({"name": "setfperm", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "setline", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_2"}), AttributeDict({"name": "setloclist", "min_argc": 2, "max_argc": 4, "argtype": "FEARG_2"}), AttributeDict({"name": "setmatches", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "setpos", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_2"}), AttributeDict({"name": "setqflist", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "setreg", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_2"}), AttributeDict({"name": "settabvar", "min_argc": 3, "max_argc": 3, "argtype": "FEARG_3"}), AttributeDict({"name": "settabwinvar", "min_argc": 4, "max_argc": 4, "argtype": "FEARG_4"}), AttributeDict({"name": "settagstack", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_2"}), AttributeDict({"name": "setwinvar", "min_argc": 3, "max_argc": 3, "argtype": "FEARG_3"}), AttributeDict({"name": "sha256", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "shellescape", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "shiftwidth", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "sign_define", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "sign_getdefined", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "sign_getplaced", "min_argc": 0, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "sign_jump", "min_argc": 3, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "sign_place", "min_argc": 4, "max_argc": 5, "argtype": "FEARG_1"}), AttributeDict({"name": "sign_placelist", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "sign_undefine", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "sign_unplace", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "sign_unplacelist", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "simplify", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "sin", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "sinh", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "slice", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "sort", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "sound_clear", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "sound_playevent", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "sound_playfile", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "sound_stop", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "soundfold", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "spellbadword", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "spellsuggest", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "split", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "sqrt", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "srand", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "state", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "str2float", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "str2list", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "str2nr", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "strcharlen", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "strcharpart", "min_argc": 2, "max_argc": 4, "argtype": "FEARG_1"}), AttributeDict({"name": "strchars", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "strdisplaywidth", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "strftime", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "strgetchar", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "stridx", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "string", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "strlen", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "strpart", "min_argc": 2, "max_argc": 4, "argtype": "FEARG_1"}), AttributeDict({"name": "strptime", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "strridx", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "strtrans", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "strwidth", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "submatch", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "substitute", "min_argc": 4, "max_argc": 4, "argtype": "FEARG_1"}), AttributeDict({"name": "swapinfo", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "swapname", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "synID", "min_argc": 3, "max_argc": 3, "argtype": "0"}), AttributeDict({"name": "synIDattr", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "synIDtrans", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "synconcealed", "min_argc": 2, "max_argc": 2, "argtype": "0"}), AttributeDict({"name": "synstack", "min_argc": 2, "max_argc": 2, "argtype": "0"}), AttributeDict({"name": "system", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "systemlist", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "tabpagebuflist", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "tabpagenr", "min_argc": 0, "max_argc": 1, "argtype": "0"}), AttributeDict({"name": "tabpagewinnr", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "tagfiles", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "taglist", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "tan", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "tanh", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "tempname", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "term_dumpdiff", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "term_dumpload", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "term_dumpwrite", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_2"}), AttributeDict({"name": "term_getaltscreen", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "term_getansicolors", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "term_getattr", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "term_getcursor", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "term_getjob", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "term_getline", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "term_getscrolled", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "term_getsize", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "term_getstatus", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "term_gettitle", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "term_gettty", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "term_list", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "term_scrape", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "term_sendkeys", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "term_setansicolors", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "term_setapi", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "term_setkill", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "term_setrestore", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "term_setsize", "min_argc": 3, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "term_start", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "term_wait", "min_argc": 1, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "terminalprops", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "test_alloc_fail", "min_argc": 3, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "test_autochdir", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "test_feedinput", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "test_garbagecollect_now", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "test_garbagecollect_soon", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "test_getvalue", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "test_gui_drop_files", "min_argc": 4, "max_argc": 4, "argtype": "0"}), AttributeDict({"name": "test_gui_event", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "test_gui_mouse_event", "min_argc": 5, "max_argc": 5, "argtype": "0"}), AttributeDict({"name": "test_ignore_error", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "test_null_blob", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "test_null_channel", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "test_null_dict", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "test_null_function", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "test_null_job", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "test_null_list", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "test_null_partial", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "test_null_string", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "test_option_not_set", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "test_override", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_2"}), AttributeDict({"name": "test_refcount", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "test_scrollbar", "min_argc": 3, "max_argc": 3, "argtype": "FEARG_2"}), AttributeDict({"name": "test_setmouse", "min_argc": 2, "max_argc": 2, "argtype": "0"}), AttributeDict({"name": "test_settime", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "test_srand_seed", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "test_unknown", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "test_void", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "timer_info", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "timer_pause", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "timer_start", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "timer_stop", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "timer_stopall", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "tolower", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "toupper", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "tr", "min_argc": 3, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "trim", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "trunc", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "type", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "typename", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "undofile", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "undotree", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "uniq", "min_argc": 1, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "values", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "virtcol", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "virtcol2col", "min_argc": 3, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "visualmode", "min_argc": 0, "max_argc": 1, "argtype": "0"}), AttributeDict({"name": "wildmenumode", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "win_execute", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_2"}), AttributeDict({"name": "win_findbuf", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "win_getid", "min_argc": 0, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "win_gettype", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "win_gotoid", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "win_id2tabwin", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "win_id2win", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "win_move_separator", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "win_move_statusline", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"}), AttributeDict({"name": "win_screenpos", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "win_splitmove", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "winbufnr", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "wincol", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "windowsversion", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "winheight", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "winlayout", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "winline", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "winnr", "min_argc": 0, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "winrestcmd", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "winrestview", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "winsaveview", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "winwidth", "min_argc": 1, "max_argc": 1, "argtype": "FEARG_1"}), AttributeDict({"name": "wordcount", "min_argc": 0, "max_argc": 0, "argtype": "0"}), AttributeDict({"name": "writefile", "min_argc": 2, "max_argc": 3, "argtype": "FEARG_1"}), AttributeDict({"name": "xor", "min_argc": 2, "max_argc": 2, "argtype": "FEARG_1"})] @@ -2437,9 +3109,15 @@ def parse_cmd_syntax(self): class ExprTokenizer: - def __init__(self, reader): + def __init__(self, reader, *a000): self.reader = reader self.cache = AttributeDict({}) + self.vim9 = FALSE + if viml_len(a000) > 0: + self.vim9 = a000[0] + # Nesting level of brackets, inside which a Vim9 expression may continue + # on the next line. + self.depth = 0 def token(self, type, value, pos): return AttributeDict({"type": type, "value": value, "pos": pos}) @@ -2451,6 +3129,8 @@ def peek(self): return r def get(self): + if self.vim9: + self.skip_vim9_newline(FALSE) # FIXME: remove dirty hack if viml_has_key(self.cache, self.reader.tell()): x = self.cache[self.reader.tell()] @@ -2462,6 +3142,64 @@ def get(self): self.cache[pos] = [self.reader.tell(), r] return r + # In Vim9 script an expression continues on the next line inside brackets, + # after an operator (a:force), and before an operator that starts the next + # line. Comments and empty lines in between are skipped. + def skip_vim9_newline(self, force_newline): + r = self.reader + force = force_newline + while TRUE: + pos = r.tell() + r.skip_white() + if r.peek() == "#" and r.tell() > 0 and (iswhite(r.p(-1)) or r.p(-1) == ""): + r.getn(-1) + if r.peek() != "" or not (force or self.depth > 0 or self.next_line_continues()) or self.next_line_is_enddef(): + r.seek_set(pos) + return + r.get() + force = TRUE + + # :enddef cannot be used at the start of a continuation line. + def next_line_is_enddef(self): + r = self.reader + pos = r.tell() + r.get() + r.skip_white() + result = r.read_alpha() == "enddef" and not iswordc(r.peekn(1)) + r.seek_set(pos) + return result + + # Return TRUE when the next line, ignoring comments and empty lines, starts + # with an operator that continues the expression. + def next_line_continues(self): + r = self.reader + pos = r.tell() + while r.peek() == "": + r.get() + r.skip_white() + if r.peek() == "#": + r.getn(-1) + c = r.peek() + continues = FALSE + if c == "-" and r.p(1) == ">": + continues = TRUE + elif c == "." and iswordc1(r.p(1)): + continues = TRUE + elif c == "i" and r.p(1) == "s": + op = r.read_alpha() + if op == "is" or op == "isnot": + if r.peek() == "?" or r.peek() == "#": + r.get() + continues = iswhite(r.peek()) or r.peek() == "" + elif c != "" and viml_stridx("+-*/%.|&?:=!<>", c) != -1: + op = "" + while r.peek() != "" and viml_stridx("+-*/%.|&?:=!<>~#", r.peek()) != -1: + op += r.get() + if viml_has_key(VIM9_CONTINUATION_OPS, op): + continues = iswhite(r.peek()) or r.peek() == "" + r.seek_set(pos) + return continues + def get2(self): r = self.reader pos = r.getpos() @@ -2482,12 +3220,19 @@ def get2(self): s = r.getn(3) s += r.read_bdigit() return self.token(TOKEN_NUMBER, s, pos) + elif c == "0" and (r.p(1) == "O" or r.p(1) == "o") and isodigit(r.p(2)): + s = r.getn(3) + s += r.read_odigit() + return self.token(TOKEN_NUMBER, s, pos) elif c == "0" and (r.p(1) == "Z" or r.p(1) == "z") and r.p(2) != ".": s = r.getn(2) s += r.read_blob() return self.token(TOKEN_BLOB, s, pos) elif isdigit(c): s = r.read_digit() + # Vim9 script allows a single quote between digits: 1'000'000 + while self.vim9 and r.p(0) == "'" and isdigit(r.p(1)): + s += r.getn(1) + r.read_digit() if r.p(0) == "." and isdigit(r.p(1)): s += r.getn(1) s += r.read_digit() @@ -2516,7 +3261,10 @@ def get2(self): r.seek_cur(5) return self.token(TOKEN_ISNOT, "isnot", pos) elif isnamec1(c): - s = r.read_name() + if self.vim9: + s = r.read_vim9_name() + else: + s = r.read_name() return self.token(TOKEN_IDENTIFIER, s, pos) elif c == "|" and r.p(1) == "|": r.seek_cur(2) @@ -2524,6 +3272,9 @@ def get2(self): elif c == "&" and r.p(1) == "&": r.seek_cur(2) return self.token(TOKEN_ANDAND, "&&", pos) + elif c == "=" and r.p(1) == ">" and self.vim9: + r.seek_cur(2) + return self.token(TOKEN_FATARROW, "=>", pos) elif c == "=" and r.p(1) == "=": if r.p(2) == "?": r.seek_cur(3) @@ -2644,6 +3395,9 @@ def get2(self): elif c == "!": r.seek_cur(1) return self.token(TOKEN_NOT, "!", pos) + elif c == "?" and r.p(1) == "?": + r.seek_cur(2) + return self.token(TOKEN_QUESTIONQUESTION, "??", pos) elif c == "?": r.seek_cur(1) return self.token(TOKEN_QUESTION, "?", pos) @@ -2651,7 +3405,7 @@ def get2(self): r.seek_cur(1) return self.token(TOKEN_COLON, ":", pos) elif c == "#": - if r.p(1) == "{": + if r.p(1) == "{" and not self.vim9: r.seek_cur(2) return self.token(TOKEN_LITCOPEN, "#{", pos) else: @@ -2786,19 +3540,32 @@ def parse_dict_literal_key(self): class ExprParser: - def __init__(self, reader): + def __init__(self, reader, *a000): self.reader = reader - self.tokenizer = ExprTokenizer(reader) + # The VimLParser using this parser, if any. + self.parser = NIL + self.vim9 = FALSE + if viml_len(a000) > 0: + self.parser = a000[0] + self.vim9 = self.parser.isvim9() + self.tokenizer = ExprTokenizer(reader, self.vim9) def parse(self): return self.parse_expr1() # expr1: expr2 ? expr1 : expr1 + # expr2 ?? expr1 def parse_expr1(self): left = self.parse_expr2() pos = self.reader.tell() token = self.tokenizer.get() - if token.type == TOKEN_QUESTION: + if token.type == TOKEN_QUESTIONQUESTION: + node = Node(NODE_FALSY) + node.pos = token.pos + node.left = left + node.right = self.parse_expr1() + left = node + elif token.type == TOKEN_QUESTION: node = Node(NODE_TERNARY) node.pos = token.pos node.cond = left @@ -3077,7 +3844,7 @@ def parse_expr5(self): node.left = left node.right = self.parse_expr5_5() left = node - elif token.type == TOKEN_DOT: + elif token.type == TOKEN_DOT and not self.vim9: # TODO check scriptversion? node = Node(NODE_CONCAT) node.pos = token.pos @@ -3148,6 +3915,8 @@ def parse_expr6(self): # - expr7 # + expr7 def parse_expr7(self): + if self.vim9: + self.tokenizer.skip_vim9_newline(TRUE) pos = self.reader.tell() token = self.tokenizer.get() if token.type == TOKEN_NOT: @@ -3165,6 +3934,16 @@ def parse_expr7(self): node.pos = token.pos node.left = self.parse_expr7() return node + elif token.type == TOKEN_LT and self.vim9 and not viml_equalci(self.reader.peekn(4), "SID>"): + # Vim9 type cast: expr + node = Node(NODE_CAST) + node.pos = token.pos + node.type_str = self.parser.read_type() + token = self.tokenizer.get() + if token.type != TOKEN_GT: + raise VimLParserException(Err(viml_printf("unexpected token: %s", token.value), token.pos)) + node.left = self.parse_expr7() + return node else: self.reader.seek_set(pos) node = self.parse_expr8() @@ -3183,8 +3962,32 @@ def parse_expr8(self): pos = self.reader.tell() c = self.reader.peek() token = self.tokenizer.get() - if not iswhite(c) and token.type == TOKEN_SQOPEN: + # In Vim9 script no white space or line break is allowed before "[" and + # "(", a member "." may start a continuation line. + attached = not iswhite(c) and not (self.vim9 and c == "") + if self.vim9 and c == "<" and self.parser.is_generic_args(): + # Vim9 generic function call: Func(args) + self.reader.seek_set(pos) + type_args = self.reader.getn(1) + depth = 1 + while depth > 0: + c = self.reader.getn(1) + if c == "<": + depth += 1 + elif c == ">": + depth -= 1 + type_args += c + token = self.tokenizer.get() + node = Node(NODE_CALL) + node.pos = token.pos + node.left = left + node.type_args = type_args + node.rlist = self.parse_rlist() + left = node + del node + elif attached and token.type == TOKEN_SQOPEN: npos = token.pos + self.tokenizer.depth += 1 if self.tokenizer.peek().type == TOKEN_COLON: self.tokenizer.get() node = Node(NODE_SLICE) @@ -3195,6 +3998,7 @@ def parse_expr8(self): if token.type != TOKEN_SQCLOSE: node.rlist[1] = self.parse_expr1() token = self.tokenizer.get() + self.tokenizer.depth -= 1 if token.type != TOKEN_SQCLOSE: raise VimLParserException(Err(viml_printf("unexpected token: %s", token.value), token.pos)) left = node @@ -3210,6 +4014,7 @@ def parse_expr8(self): if token.type != TOKEN_SQCLOSE: node.rlist[1] = self.parse_expr1() token = self.tokenizer.get() + self.tokenizer.depth -= 1 if token.type != TOKEN_SQCLOSE: raise VimLParserException(Err(viml_printf("unexpected token: %s", token.value), token.pos)) left = node @@ -3219,6 +4024,7 @@ def parse_expr8(self): node.left = left node.right = right token = self.tokenizer.get() + self.tokenizer.depth -= 1 if token.type != TOKEN_SQCLOSE: raise VimLParserException(Err(viml_printf("unexpected token: %s", token.value), token.pos)) left = node @@ -3238,14 +4044,14 @@ def parse_expr8(self): node.right = right left = node del node - elif token.type == TOKEN_POPEN: + elif token.type == TOKEN_POPEN and (attached or not self.vim9): node = Node(NODE_CALL) node.pos = token.pos node.left = left node.rlist = self.parse_rlist() left = node del node - elif not iswhite(c) and token.type == TOKEN_DOT: + elif (attached or self.vim9 and c == "") and token.type == TOKEN_DOT: # TODO check scriptversion? node = self.parse_dot(token, left) if node is NIL: @@ -3260,9 +4066,11 @@ def parse_expr8(self): def parse_rlist(self): rlist = [] + self.tokenizer.depth += 1 token = self.tokenizer.peek() if self.tokenizer.peek().type == TOKEN_PCLOSE: self.tokenizer.get() + self.tokenizer.depth -= 1 else: while TRUE: viml_add(rlist, self.parse_expr1()) @@ -3271,8 +4079,10 @@ def parse_rlist(self): # XXX: Vim allows foo(a, b, ). Lint should warn it. if self.tokenizer.peek().type == TOKEN_PCLOSE: self.tokenizer.get() + self.tokenizer.depth -= 1 break elif token.type == TOKEN_PCLOSE: + self.tokenizer.depth -= 1 break else: raise VimLParserException(Err(viml_printf("unexpected token: %s", token.value), token.pos)) @@ -3322,6 +4132,7 @@ def parse_expr9(self): node = Node(NODE_LIST) node.pos = token.pos node.value = [] + self.tokenizer.depth += 1 token = self.tokenizer.peek() if token.type == TOKEN_SQCLOSE: self.tokenizer.get() @@ -3339,6 +4150,9 @@ def parse_expr9(self): break else: raise VimLParserException(Err(viml_printf("unexpected token: %s", token.value), token.pos)) + self.tokenizer.depth -= 1 + elif token.type == TOKEN_COPEN and self.vim9: + node = self.parse_vim9_dict(token) elif token.type == TOKEN_COPEN or token.type == TOKEN_LITCOPEN: is_litdict = token.type == TOKEN_LITCOPEN savepos = self.reader.tell() @@ -3438,9 +4252,13 @@ def parse_expr9(self): else: raise VimLParserException(Err(viml_printf("unexpected token: %s", token.value), token.pos)) return node + elif token.type == TOKEN_POPEN and self.vim9: + node = self.parse_vim9_paren(token) elif token.type == TOKEN_POPEN: + self.tokenizer.depth += 1 node = self.parse_expr1() token = self.tokenizer.get() + self.tokenizer.depth -= 1 if token.type != TOKEN_PCLOSE: raise VimLParserException(Err(viml_printf("unexpected token: %s", token.value), token.pos)) elif token.type == TOKEN_OPTION: @@ -3460,6 +4278,8 @@ def parse_expr9(self): elif token.type == TOKEN_IS or token.type == TOKEN_ISCS or token.type == TOKEN_ISNOT or token.type == TOKEN_ISNOTCS: self.reader.seek_set(pos) node = self.parse_identifier() + elif token.type == TOKEN_ENV and token.value == "$" and (self.reader.p(0) == "\"" or self.reader.p(0) == "'"): + node = self.parse_interpolation(token) elif token.type == TOKEN_ENV: node = Node(NODE_ENV) node.pos = token.pos @@ -3472,17 +4292,221 @@ def parse_expr9(self): raise VimLParserException(Err(viml_printf("unexpected token: %s", token.value), token.pos)) return node + # Interpolated string: $"text {expr1} text" or $'text {expr1} text' + # .value is a list of NODE_STRING parts, in the quotes of the string, and + # expressions. + def parse_interpolation(self, token): + r = self.reader + node = Node(NODE_INTERPOLATION) + node.pos = token.pos + node.value = [] + quote = r.get() + str = "" + strpos = r.getpos() + while TRUE: + c = r.p(0) + if c == "" or c == "": + raise VimLParserException(Err("unexpected EOL", r.getpos())) + elif c == quote and quote == "'" and r.p(1) == "'": + str += r.getn(2) + elif c == quote: + r.seek_cur(1) + break + elif c == "\\" and quote == "\"": + str += r.getn(2) + elif c == "{" and r.p(1) == "{" or c == "}" and r.p(1) == "}": + str += r.getn(2) + elif c == "{": + if str != "": + part = Node(NODE_STRING) + part.pos = strpos + part.value = quote + str + quote + viml_add(node.value, part) + str = "" + r.seek_cur(1) + viml_add(node.value, self.parse_expr1()) + r.skip_white() + if r.p(0) != "}": + raise VimLParserException(Err(viml_printf("unexpected token: %s", r.p(0)), r.getpos())) + r.seek_cur(1) + strpos = r.getpos() + else: + str += r.getn(1) + if str != "": + part = Node(NODE_STRING) + part.pos = strpos + part.value = quote + str + quote + viml_add(node.value, part) + return node + + # Vim9 lambda, tuple or expression in parentheses, after the "(": + # (args) => expr1 + # (args): type => { + # () (expr1,) (expr1, expr1, ...) + # (expr1) + def parse_vim9_paren(self, popen): + if self.is_vim9_lambda(): + return self.parse_vim9_lambda(popen) + self.tokenizer.depth += 1 + token = self.tokenizer.peek() + if token.type == TOKEN_PCLOSE: + self.tokenizer.get() + self.tokenizer.depth -= 1 + node = Node(NODE_TUPLE) + node.pos = popen.pos + node.value = [] + return node + node = self.parse_expr1() + token = self.tokenizer.get() + if token.type == TOKEN_COMMA: + tuple = Node(NODE_TUPLE) + tuple.pos = popen.pos + tuple.value = [node] + while self.tokenizer.peek().type != TOKEN_PCLOSE: + viml_add(tuple.value, self.parse_expr1()) + token = self.tokenizer.peek() + if token.type == TOKEN_COMMA: + self.tokenizer.get() + elif token.type != TOKEN_PCLOSE: + raise VimLParserException(Err(viml_printf("unexpected token: %s", token.value), token.pos)) + token = self.tokenizer.get() + node = tuple + self.tokenizer.depth -= 1 + if token.type != TOKEN_PCLOSE: + raise VimLParserException(Err(viml_printf("unexpected token: %s", token.value), token.pos)) + return node + + # Return TRUE when the text after "(" is the argument list of a Vim9 lambda, + # i.e. names with optional types, ")", an optional return type and "=>". + def is_vim9_lambda(self): + r = self.reader + pos = r.tell() + result = FALSE + while TRUE: + r.skip_white() + if r.peekn(1) == ")": + break + if r.peekn(3) == "...": + r.getn(3) + if r.read_word() == "": + r.seek_set(pos) + return FALSE + if r.peekn(1) == ":": + r.getn(1) + r.skip_white() + self.parser.read_type() + r.skip_white() + if r.peekn(1) == ",": + r.getn(1) + elif r.peekn(1) != ")": + r.seek_set(pos) + return FALSE + r.getn(1) + if r.peekn(1) == ":": + r.getn(1) + r.skip_white() + self.parser.read_type() + r.skip_white() + result = r.peekn(2) == "=>" + r.seek_set(pos) + return result + + def parse_vim9_lambda(self, token): + r = self.reader + node = Node(NODE_LAMBDA) + node.pos = token.pos + node.rlist = [] + node.left = NIL + node.body = [] + node.rettype = "" + while TRUE: + r.skip_white() + if r.peekn(1) == ")": + r.getn(1) + break + varnode = Node(NODE_IDENTIFIER) + varnode.pos = r.getpos() + varnode.value = "" + varnode.type_str = "" + if r.peekn(3) == "...": + varnode.value = r.getn(3) + name = r.read_word() + varnode.value += name + self.parser.declared[name] = 1 + if r.peekn(1) == ":": + r.getn(1) + r.skip_white() + varnode.type_str = self.parser.read_type() + viml_add(node.rlist, varnode) + r.skip_white() + if r.peekn(1) == ",": + r.getn(1) + if r.peekn(1) == ":": + r.getn(1) + r.skip_white() + node.rettype = self.parser.read_type() + r.skip_white() + r.getn(2) + r.skip_white() + pos = r.tell() + if r.peekn(1) == "{": + r.getn(1) + r.skip_white() + if r.peek() == "" or r.peek() == "#": + self.parser.parse_lambda_block(node) + return node + r.seek_set(pos) + node.left = self.parse_expr1() + return node + + # Vim9 dictionary: {key: expr1, "key": expr1, [expr1]: expr1, ...} + # A key made of word characters and "-" is a literal string. + def parse_vim9_dict(self, copen): + node = Node(NODE_DICT) + node.pos = copen.pos + node.value = [] + self.tokenizer.depth += 1 + while TRUE: + token = self.tokenizer.peek() + if token.type == TOKEN_CCLOSE: + self.tokenizer.get() + break + if token.type == TOKEN_SQOPEN: + self.tokenizer.get() + key = self.parse_expr1() + token = self.tokenizer.get() + if token.type != TOKEN_SQCLOSE: + raise VimLParserException(Err(viml_printf("unexpected token: %s", token.value), token.pos)) + elif token.type == TOKEN_SQUOTE or token.type == TOKEN_DQUOTE: + key = self.parse_expr1() + else: + self.tokenizer.skip_vim9_newline(FALSE) + key = self.tokenizer.parse_dict_literal_key() + token = self.tokenizer.get() + if token.type != TOKEN_COLON: + raise VimLParserException(Err(viml_printf("unexpected token: %s", token.value), token.pos)) + val = self.parse_expr1() + viml_add(node.value, [key, val]) + token = self.tokenizer.get() + if token.type == TOKEN_CCLOSE: + break + elif token.type != TOKEN_COMMA: + raise VimLParserException(Err(viml_printf("unexpected token: %s", token.value), token.pos)) + self.tokenizer.depth -= 1 + return node + # SUBSCRIPT or CONCAT # dict "." [0-9A-Za-z_]+ => (subscript dict key) # str "." expr6 => (concat str expr6) + # In Vim9 script "." is always a member access. def parse_dot(self, token, left): - if left.type != NODE_IDENTIFIER and left.type != NODE_CURLYNAME and left.type != NODE_DICT and left.type != NODE_SUBSCRIPT and left.type != NODE_CALL and left.type != NODE_DOT: + if not self.vim9 and left.type != NODE_IDENTIFIER and left.type != NODE_CURLYNAME and left.type != NODE_DICT and left.type != NODE_SUBSCRIPT and left.type != NODE_CALL and left.type != NODE_DOT: return NIL if not iswordc(self.reader.p(0)): return NIL pos = self.reader.getpos() name = self.reader.read_word() - if isnamec(self.reader.p(0)): + if not self.vim9 and isnamec(self.reader.p(0)): # XXX: foo is str => ok, foo is obj => invalid expression # foo.s:bar or foo.bar#baz return NIL @@ -3518,6 +4542,15 @@ def parse_concat(self, token, left): def parse_identifier(self): self.reader.skip_white() npos = self.reader.getpos() + if self.vim9: + # Vim9 script has no curly-braces names. + node = Node(NODE_IDENTIFIER) + node.pos = npos + if viml_equalci(self.reader.peekn(5), ""): + node.value = self.reader.getn(5) + self.reader.read_vim9_name() + else: + node.value = self.reader.read_vim9_name() + return node curly_parts = self.parse_curly_parts() if viml_len(curly_parts) == 1 and curly_parts[0].type == NODE_CURLYNAMEPART: node = Node(NODE_IDENTIFIER) @@ -3687,7 +4720,16 @@ def __init__(self, lines): viml_add(self.pos, [lnum + 1, col + 1, offset]) col += viml_len(c) offset += viml_len(c) - while lnum + 1 < viml_len(lines) and viml_eqregh(lines[lnum + 1], "^\\s*\\\\"): + while TRUE: + # Comment lines "\ and #\ may appear between continuation lines. + next = lnum + 1 + while next < viml_len(lines) and viml_eqregh(lines[next], "^\\s*[\"#]\\\\ "): + next += 1 + if next >= viml_len(lines) or not viml_eqregh(lines[next], "^\\s*\\\\"): + break + while lnum + 1 < next: + offset += viml_len(lines[lnum + 1]) + 1 + lnum += 1 skip = TRUE col = 0 for c in viml_split(lines[lnum + 1], "\\zs"): @@ -3867,6 +4909,17 @@ def read_name(self): r += self.getn(1) return r + # Read a Vim9 variable or function name. Unlike read_name() a colon is only + # part of the name after a one letter scope, e.g. "g:name". + def read_vim9_name(self): + r = "" + c = self.peekn(1) + if c != "" and viml_stridx("bgltsvw", c) != -1 and self.p(1) == ":" and not iswhite(self.p(2)): + r = self.getn(2) + while iswordc(self.peekn(1)) or self.peekn(1) == "#": + r += self.getn(1) + return r + def skip_white(self): while iswhite(self.peekn(1)): self.seek_cur(1) @@ -4125,6 +5178,47 @@ def compile(self, node): elif node.type == NODE_VIM9SCRIPT: self.compile_vim9script(node) return NIL + elif node.type == NODE_ASSIGN: + self.compile_assign(node) + return NIL + elif node.type == NODE_BLOCK: + self.compile_block(node) + return NIL + elif node.type == NODE_CLASS: + self.compile_class(node) + return NIL + elif node.type == NODE_INTERFACE: + self.compile_interface(node) + return NIL + elif node.type == NODE_ENUM: + self.compile_enum(node) + return NIL + elif node.type == NODE_TYPE: + self.compile_type(node) + return NIL + elif node.type == NODE_PUBLIC: + self.compile_wrapper(node, "public") + return NIL + elif node.type == NODE_STATIC: + self.compile_wrapper(node, "static") + return NIL + elif node.type == NODE_ABSTRACT: + self.compile_wrapper(node, "abstract") + return NIL + elif node.type == NODE_DEFER: + self.compile_defer(node) + return NIL + elif node.type == NODE_ECHOWINDOW: + self.compile_echowindow(node) + return NIL + elif node.type == NODE_TUPLE: + return self.compile_tuple(node) + elif node.type == NODE_FALSY: + return self.compile_falsy(node) + elif node.type == NODE_INTERPOLATION: + return self.compile_interpolation(node) + elif node.type == NODE_CAST: + return self.compile_cast(node) else: raise VimLParserException(viml_printf("Compiler: unknown node: %s", viml_string(node))) return NIL @@ -4141,7 +5235,14 @@ def compile_comment(self, node): self.out(";%s", node.str) def compile_excmd(self, node): - self.out("(excmd \"%s\")", viml_escape(node.str, "\\\"")) + if not viml_has_key(node, "block"): + self.out("(excmd \"%s\")", viml_escape(node.str, "\\\"")) + return + self.out("(excmd \"%s\"", viml_escape(node.str, "\\\"")) + self.incindent(" ") + self.compile_body(node.block.body) + self.out(")") + self.decindent() def compile_function(self, node): left = self.compile(node.left) @@ -4192,8 +5293,14 @@ def compile_let(self, node): right = self.compile(node.right) self.out("(let %s %s %s)", node.op, left, right) - # TODO: merge with s:Compiler.compile_let() ? - def compile_const(self, node): + def compile_block(self, node): + self.out("(block") + self.incindent(" ") + self.compile_body(node.body) + self.out(")") + self.decindent() + + def compile_assign(self, node): left = "" if node.left is not NIL: left = self.compile(node.left) @@ -4202,8 +5309,14 @@ def compile_const(self, node): if node.rest is not NIL: left += " . " + self.compile(node.rest) left = "(" + left + ")" - right = self.compile(node.right) - self.out("(const %s %s %s)", node.op, left, right) + if node.right is NIL: + self.out("(assign %s %s)", node.op, left) + else: + self.out("(assign %s %s %s)", node.op, left, self.compile(node.right)) + + # TODO: merge with s:Compiler.compile_let() ? + def compile_const(self, node): + self.compile_decl(node, "const") def compile_unlet(self, node): list = [self.compile(vval) for vval in node.list] @@ -4252,11 +5365,11 @@ def compile_while(self, node): def compile_for(self, node): left = "" if node.left is not NIL: - left = self.compile(node.left) + left = self.compile_decl_name(node.left) else: - left = viml_join([self.compile(vval) for vval in node.list], " ") + left = viml_join([self.compile_decl_name(vval) for vval in node.list], " ") if node.rest is not NIL: - left += " . " + self.compile(node.rest) + left += " . " + self.compile_decl_name(node.rest) left = "(" + left + ")" right = self.compile(node.right) self.out("(for %s %s", left, right) @@ -4320,6 +5433,13 @@ def compile_echoconsole(self, node): list = [self.compile(vval) for vval in node.list] self.out("(echoconsole %s)", viml_join(list, " ")) + def compile_echowindow(self, node): + list = [self.compile(vval) for vval in node.list] + self.out("(echowindow %s)", viml_join(list, " ")) + + def compile_defer(self, node): + self.out("(defer %s)", self.compile(node.left)) + def compile_execute(self, node): list = [self.compile(vval) for vval in node.list] self.out("(execute %s)", viml_join(list, " ")) @@ -4472,10 +5592,13 @@ def compile_method(self, node): def compile_call(self, node): rlist = [self.compile(vval) for vval in node.rlist] + left = self.compile(node.left) + if viml_has_key(node, "type_args"): + left += node.type_args if viml_empty(rlist): - return viml_printf("(%s)", self.compile(node.left)) + return viml_printf("(%s)", left) else: - return viml_printf("(%s %s)", self.compile(node.left), viml_join(rlist, " ")) + return viml_printf("(%s %s)", left, viml_join(rlist, " ")) def compile_number(self, node): return node.value @@ -4535,7 +5658,39 @@ def escape_string(self, str): def compile_lambda(self, node): rlist = [self.compile(vval) for vval in node.rlist] - return viml_printf("(lambda (%s) %s)", viml_join(rlist, " "), self.compile(node.left)) + if node.left is not NIL: + return viml_printf("(lambda (%s) %s)", viml_join(rlist, " "), self.compile(node.left)) + # Vim9 lambda with a block: put the statements on one line. + compiler = Compiler() + compiler.compile_body(node.body) + body = [] + for line in compiler.lines: + text = "" + for c in viml_split(line, "\\zs"): + if text != "" or c != " ": + text += c + viml_add(body, text) + return viml_printf("(lambda (%s) %s)", viml_join(rlist, " "), viml_join(body, " ")) + + def compile_falsy(self, node): + return viml_printf("(?? %s %s)", self.compile(node.left), self.compile(node.right)) + + def compile_interpolation(self, node): + value = [self.compile(vval) for vval in node.value] + if viml_empty(value): + return "(interpolation)" + else: + return viml_printf("(interpolation %s)", viml_join(value, " ")) + + def compile_tuple(self, node): + value = [self.compile(vval) for vval in node.value] + if viml_empty(value): + return "(tuple)" + else: + return viml_printf("(tuple %s)", viml_join(value, " ")) + + def compile_cast(self, node): + return viml_printf("(cast <%s> %s)", node.type_str, self.compile(node.left)) def compile_heredoc(self, node): if viml_empty(node.rlist): @@ -4550,10 +5705,13 @@ def compile_heredoc(self, node): return viml_printf("(heredoc %s %s %s)", rlist, op, body) def compile_vim9script(self, node): - self.out("(vim9script)") + if node.noclear: + self.out("(vim9script noclear)") + else: + self.out("(vim9script)") def compile_def(self, node): - left = self.compile(node.left) + left = self.compile(node.left) + node.attr.type_params rlist = [self.compile(vval) for vval in node.rlist] default_args = [self.compile(vval) for vval in node.default_args] if not viml_empty(rlist): @@ -4579,42 +5737,90 @@ def compile_def(self, node): self.decindent() def compile_var(self, node): - left = "" - if node.left is not NIL: - left = self.compile(node.left) - else: - left = viml_join([self.compile(vval) for vval in node.list], " ") - if node.rest is not NIL: - left += " . " + self.compile(node.rest) - left = "(" + left + ")" - if node.type_str != "": - left += ": " + node.type_str - right = self.compile(node.right) - self.out("(var %s %s %s)", node.op, left, right) + self.compile_decl(node, "var") def compile_final(self, node): + self.compile_decl(node, "final") + + # A declared name with its Vim9 type, if any: "name: type" + def compile_decl_name(self, node): + name = self.compile(node) + if viml_has_key(node, "type_str") and node.type_str != "": + name += ": " + node.type_str + return name + + def compile_decl(self, node, cmd): left = "" if node.left is not NIL: - left = self.compile(node.left) + left = self.compile_decl_name(node.left) else: - left = viml_join([self.compile(vval) for vval in node.list], " ") + left = viml_join([self.compile_decl_name(vval) for vval in node.list], " ") if node.rest is not NIL: - left += " . " + self.compile(node.rest) + left += " . " + self.compile_decl_name(node.rest) left = "(" + left + ")" - if node.type_str != "": - left += ": " + node.type_str - right = self.compile(node.right) - self.out("(final %s %s %s)", node.op, left, right) + if node.right is NIL: + self.out("(%s %s)", cmd, left) + else: + self.out("(%s %s %s %s)", cmd, node.op, left, self.compile(node.right)) def compile_export(self, node): - self.out("(export") + self.compile_wrapper(node, "export") + + def compile_wrapper(self, node, name): + self.out("(%s", name) + self.incindent(" ") + self.compile_body(node.body) + self.out(")") + self.decindent() + + def compile_class(self, node): + s = node.name + if node.extends != "": + s += " extends " + node.extends + if not viml_empty(node.implements): + s += " implements " + viml_join(node.implements, ", ") + self.out("(class %s", s) + self.incindent(" ") + self.compile_body(node.body) + self.out(")") + self.decindent() + + def compile_interface(self, node): + s = node.name + if not viml_empty(node.extends): + s += " extends " + viml_join(node.extends, ", ") + self.out("(interface %s", s) + self.incindent(" ") + self.compile_body(node.body) + self.out(")") + self.decindent() + + def compile_enum(self, node): + s = node.name + if not viml_empty(node.implements): + s += " implements " + viml_join(node.implements, ", ") + self.out("(enum %s", s) self.incindent(" ") + for value in node.enumvalues: + rlist = [self.compile(vval) for vval in value.rlist] + if viml_empty(rlist): + self.out("(%s)", value.value) + else: + self.out("(%s %s)", value.value, viml_join(rlist, " ")) self.compile_body(node.body) self.out(")") self.decindent() + def compile_type(self, node): + self.out("(type %s %s)", node.name, node.type_str) + def compile_import(self, node): - self.out("(import \"%s\")", viml_escape(node.str, "\\\"")) + s = self.compile(node.left) + if node.autoload: + s = "autoload " + s + if node.alias != "": + s += " as " + node.alias + self.out("(import %s)", s) # TODO: under construction diff --git a/test/test_call_method.ok b/test/test_call_method.ok new file mode 100644 index 0000000..e3c76e0 --- /dev/null +++ b/test/test_call_method.ok @@ -0,0 +1,3 @@ +(let = s:l (list 1)) +(call (method (remove s:l 0) (string))) +(call (method (method (get s:l 0) (string)) (len))) diff --git a/test/test_call_method.vim b/test/test_call_method.vim new file mode 100644 index 0000000..3d687b6 --- /dev/null +++ b/test/test_call_method.vim @@ -0,0 +1,3 @@ +let s:l = [1] +call remove(s:l, 0)->string() +call get(s:l, 0)->string()->len() diff --git a/test/test_cmdblock.ok b/test/test_cmdblock.ok new file mode 100644 index 0000000..856e43c --- /dev/null +++ b/test/test_cmdblock.ok @@ -0,0 +1,11 @@ +; legacy script +(excmd "command -register YankHelpGrep {" + (const = SAVE @") + (excmd "normal! y") + (execute (interpolation "helpgrep " (getreg ''))) + (assign = @" SAVE) + (excmd "copen")) +(excmd "autocmd BufWritePre * {" + (var = x 1) + (echo x)) +(excmd "command NoBlock echo '{'") diff --git a/test/test_cmdblock.vim b/test/test_cmdblock.vim new file mode 100644 index 0000000..208aaee --- /dev/null +++ b/test/test_cmdblock.vim @@ -0,0 +1,13 @@ +" legacy script +command -register YankHelpGrep { + const SAVE = @" + normal! y + execute $"helpgrep {getreg('')}" + @" = SAVE + copen +} +autocmd BufWritePre * { + var x = 1 + echo x +} +command NoBlock echo '{' diff --git a/test/test_continuation_comment.ok b/test/test_continuation_comment.ok new file mode 100644 index 0000000..de0b445 --- /dev/null +++ b/test/test_continuation_comment.ok @@ -0,0 +1,2 @@ +(let = s:list (list 1 2)) +(echo s:list) diff --git a/test/test_continuation_comment.vim b/test/test_continuation_comment.vim new file mode 100644 index 0000000..a41dea4 --- /dev/null +++ b/test/test_continuation_comment.vim @@ -0,0 +1,7 @@ +let s:list = [ + \ 1, + "\ a legacy comment line + "\ another one + \ 2, + \ ] +echo s:list diff --git a/test/test_err_argopt.ok b/test/test_err_argopt.ok new file mode 100644 index 0000000..e71a332 --- /dev/null +++ b/test/test_err_argopt.ok @@ -0,0 +1 @@ +vimlparser: E474: Invalid Argument: line 1 col 3 diff --git a/test/test_err_argopt.vim b/test/test_err_argopt.vim new file mode 100644 index 0000000..e6f977f --- /dev/null +++ b/test/test_err_argopt.vim @@ -0,0 +1 @@ +x ++ diff --git a/test/test_err_vim9enddef_continuation.ok b/test/test_err_vim9enddef_continuation.ok new file mode 100644 index 0000000..18bd080 --- /dev/null +++ b/test/test_err_vim9enddef_continuation.ok @@ -0,0 +1 @@ +vimlparser: unexpected token: : line 3 col 18 diff --git a/test/test_err_vim9enddef_continuation.vim b/test/test_err_vim9enddef_continuation.vim new file mode 100644 index 0000000..8754945 --- /dev/null +++ b/test/test_err_vim9enddef_continuation.vim @@ -0,0 +1,4 @@ +vim9script +def T() + var x: number = +enddef diff --git a/test/test_err_vim9removed_command.ok b/test/test_err_vim9removed_command.ok new file mode 100644 index 0000000..76ed6e5 --- /dev/null +++ b/test/test_err_vim9removed_command.ok @@ -0,0 +1 @@ +vimlparser: E1100: Command not supported in Vim9 script (missing :var?): k a: line 2 col 1 diff --git a/test/test_err_vim9removed_command.vim b/test/test_err_vim9removed_command.vim new file mode 100644 index 0000000..1584cc9 --- /dev/null +++ b/test/test_err_vim9removed_command.vim @@ -0,0 +1,2 @@ +vim9script +k a diff --git a/test/test_interpolation.ok b/test/test_interpolation.ok new file mode 100644 index 0000000..db92ee4 --- /dev/null +++ b/test/test_interpolation.ok @@ -0,0 +1,7 @@ +(let = s:name 'Vim') +(echo (interpolation "Hello " s:name "!")) +(echo (interpolation 'It''s ' (concat s:name "9") ' {{literal}} \n')) +(echo (interpolation (+ 1 2) "{{}}") (interpolation) (interpolation "\"" s:name "\"")) +(echo (?? (get g: 'x') 'default')) +(echo (?? 0 (?? 1 2))) +(echo 0o17 0O7) diff --git a/test/test_interpolation.vim b/test/test_interpolation.vim new file mode 100644 index 0000000..b3df405 --- /dev/null +++ b/test/test_interpolation.vim @@ -0,0 +1,7 @@ +let s:name = 'Vim' +echo $"Hello {s:name}!" +echo $'It''s {s:name .. "9"} {{literal}} \n' +echo $"{1 + 2}{{}}" $"" $"\"{s:name}\"" +echo get(g:, 'x') ?? 'default' +echo 0 ?? 1 ?? 2 +echo 0o17 0O7 diff --git a/test/test_vim9assign_undeclared.ok b/test/test_vim9assign_undeclared.ok new file mode 100644 index 0000000..ebc1664 --- /dev/null +++ b/test/test_vim9assign_undeclared.ok @@ -0,0 +1,3 @@ +(vim9script) +(assign = foo 1) +(var = t (tuple 1 2)) diff --git a/test/test_vim9assign_undeclared.vim b/test/test_vim9assign_undeclared.vim new file mode 100644 index 0000000..53d9a31 --- /dev/null +++ b/test/test_vim9assign_undeclared.vim @@ -0,0 +1,3 @@ +vim9script +foo = 1 +var t = (1, 2) diff --git a/test/test_vim9class.ok b/test/test_vim9class.ok new file mode 100644 index 0000000..dd42ed1 --- /dev/null +++ b/test/test_vim9class.ok @@ -0,0 +1,52 @@ +(vim9script) +(interface HasSurface + (var size: number) + (def (Surface): number)) +(abstract + (class Shape + (var = color 'black') + (public + (var = thickness 10)) + (static + (var count: number)) + (public + (static + (var result: number))) + (static + (final = LIMIT 9)) + (abstract + (def (Draw))) + (static + (def (Create): Shape + (return null_object))))) +(class Square extends Shape implements HasSurface + (var size: number) + (var _protected: list) + (def (new this.size (this.color v:none)) + (assign = (dot this _protected) (list))) + (def (Surface): number + (return (* (dot this size) (dot this size)))) + (def (Draw) + (call ((dot super Draw))))) +(enum Color + (White) + (Red) + (Green) + (Blue) + (Black)) +(enum Planet implements HasSurface + (Earth 1 false) + (Jupiter 95 true) + (Saturn 146 true) + (var moons: number) + (var has_rings: bool) + (def (GetMoons): number + (return (dot this moons)))) +(type ListOfStrings list) +(export + (class Exported)) +(export + (abstract + (class ExportedAbstract))) +(var = sq ((dot Square new) 3)) +(echo ((dot sq Surface)) ((dot (dot Planet Earth) GetMoons)) (dot (dot Color Red) name)) diff --git a/test/test_vim9class.vim b/test/test_vim9class.vim new file mode 100644 index 0000000..a872354 --- /dev/null +++ b/test/test_vim9class.vim @@ -0,0 +1,51 @@ +vim9script +interface HasSurface + var size: number + def Surface(): number +endinterface +abstract class Shape + var color = 'black' + public var thickness = 10 + static var count: number + public static var result: number + static final LIMIT = 9 + abstract def Draw() + static def Create(): Shape + return null_object + enddef +endclass +class Square extends Shape implements HasSurface + var size: number + var _protected: list + def new(this.size, this.color = v:none) + this._protected = [] + enddef + def Surface(): number + return this.size * this.size + enddef + def Draw() + super.Draw() + enddef +endclass +enum Color + White, + Red, + Green, Blue, Black +endenum +enum Planet implements HasSurface + Earth(1, false), + Jupiter(95, true), + Saturn(146, true) + var moons: number + var has_rings: bool + def GetMoons(): number + return this.moons + enddef +endenum +type ListOfStrings = list +export class Exported +endclass +export abstract class ExportedAbstract +endclass +var sq = Square.new(3) +echo sq.Surface() Planet.Earth.GetMoons() Color.Red.name diff --git a/test/test_vim9cmd.ok b/test/test_vim9cmd.ok new file mode 100644 index 0000000..074bfc3 --- /dev/null +++ b/test/test_vim9cmd.ok @@ -0,0 +1,14 @@ +; legacy script +(var = x (dict ('key' 1))) +(assign = (dot x key) 2) +(echo (dot x key)) +; comment +(let = s:d (dict)) +(echowindow 'msg' s:d) +(def (F) + (let = s:d (dict ('a' 1))) + (let = s:e 1) + ; legacy comment + (defer (delete 'file')) + (var = y 1) + (assign = y 2)) diff --git a/test/test_vim9cmd.vim b/test/test_vim9cmd.vim new file mode 100644 index 0000000..63bbadc --- /dev/null +++ b/test/test_vim9cmd.vim @@ -0,0 +1,13 @@ +" legacy script +vim9cmd var x = {key: 1} +vim9cmd x.key = 2 +vim9 echo x.key # comment +let s:d = {} +echowindow 'msg' s:d +def F() + legacy let s:d = {'a': 1} + legacy let s:e = 1 " legacy comment + defer delete('file') + var y = 1 + y = 2 +enddef diff --git a/test/test_vim9continuation_comment.ok b/test/test_vim9continuation_comment.ok new file mode 100644 index 0000000..89a53ff --- /dev/null +++ b/test/test_vim9continuation_comment.ok @@ -0,0 +1,3 @@ +(vim9script) +(excmd "syntax region IncSearch oneline start='Ex ' end='command'") +(echo 'next') diff --git a/test/test_vim9continuation_comment.vim b/test/test_vim9continuation_comment.vim new file mode 100644 index 0000000..b51ca2b --- /dev/null +++ b/test/test_vim9continuation_comment.vim @@ -0,0 +1,7 @@ +vim9script +syntax region IncSearch + \ oneline + #\ a Vim9 comment line + \ start='Ex ' + \ end='command' +echo 'next' diff --git a/test/test_vim9decl.ok b/test/test_vim9decl.ok new file mode 100644 index 0000000..1e1acf0 --- /dev/null +++ b/test/test_vim9decl.ok @@ -0,0 +1,22 @@ +(vim9script) +(var a: any) +(var b: bool) +(var s: string) +(var = l: list> (list)) +(var = (first _ last) (list 'A' 'M' 'Z')) +(var = (name _ country . _) (GetNameCountry)) +(var = (d: number e: string . rest) (tuple 1 'I' 'one')) +(var =<< lines (heredoc (list "trim") "END" (list " text"))) +(final = f: list (list 7)) +(const = NAMES (list 'Paul' 'Mary')) +(const = I09: func: number (lambda (n) (+ n 1))) +(const = I12: func(number): number (lambda (n) (+ n 1))) +(var = t: tuple (tuple 1 'a')) +(for x: number (list 1 2) + (echo x)) +(for (k: string v: any) (items (dict)) + (echo k v)) +(for b:i (list 1 2 3)) +(var count: number) +(assign += count 1) +(excmd "var") diff --git a/test/test_vim9decl.vim b/test/test_vim9decl.vim new file mode 100644 index 0000000..cb9f961 --- /dev/null +++ b/test/test_vim9decl.vim @@ -0,0 +1,26 @@ +vim9script +var a: any | var b: bool +var s: string +var l: list> = [] +var [first, _, last] = ['A', 'M', 'Z'] +var [name, _, country; _] = GetNameCountry() +var [d: number, e: string; rest] = (1, 'I', 'one') +var lines =<< trim END + text +END +final f: list = [7] +const NAMES = ['Paul', 'Mary'] +const I09: func: number = (n: number) => n + 1 +const I12: func(number): number = (n): number => n + 1 +var t: tuple = (1, 'a') +for x: number in [1, 2] + echo x +endfor +for [k: string, v: any] in items({}) + echo k v +endfor +for b:i in [1, 2, 3] +endfor +var count: number +count += 1 +var diff --git a/test/test_vim9def2.ok b/test/test_vim9def2.ok new file mode 100644 index 0000000..f1c1fce --- /dev/null +++ b/test/test_vim9def2.ok @@ -0,0 +1,14 @@ +(vim9script) +(def (SubBlankHyphen text (separator ' ')): string + (return (method text (substitute '[[:blank:]]' separator 'g')))) +(def (Zip first second): list> + (return (list))) +(def (In20s _ _ year): void + (assign += count (?: (>= year 2020) 1 0))) +(def (F . ...l): number + ; comment + (return (method (Zip l l) (len)))) +(def (g:Global) + (def (Inner): string + (return 'inner')) + (echo (Inner))) diff --git a/test/test_vim9def2.vim b/test/test_vim9def2.vim new file mode 100644 index 0000000..08a1898 --- /dev/null +++ b/test/test_vim9def2.vim @@ -0,0 +1,22 @@ +vim9script +def SubBlankHyphen( + text: string, # the text + separator: string = ' ' +): string + return text->substitute('[[:blank:]]', separator, 'g') +enddef +def Zip(first: list, second: list): list> + return [] +enddef +def In20s(_, _, year: number): void + count += year >= 2020 ? 1 : 0 +enddef +def F(...l: list): number # comment + return Zip(l, l)->len() +enddef +def! g:Global() + def Inner(): string + return 'inner' + enddef + echo Inner() +enddef diff --git a/test/test_vim9expr.ok b/test/test_vim9expr.ok new file mode 100644 index 0000000..67452b6 --- /dev/null +++ b/test/test_vim9expr.ok @@ -0,0 +1,15 @@ +(vim9script) +(var = d (dict ('key' 1) ('q' 2) ("dq" 3) ((+ 1 1) 4) ('09' 5) ('a-b' 6))) +(var = e (dict)) +(var = g (concat (concat g:foo b:bar) v:true)) +(var = l (list 1 2)) +(var = m (dict ('a' 1) ('b' (list 1 2)))) +(var = text (concat (concat 'V' 'i') 'm')) +(var = version (+ (* 9 100) 2)) +(var = latest (?: (== v:version 902) 'current' 'out-of-date')) +(var = s (concat (dot d key) (dot d q))) +(var = r (method (list 1 2) (reverse))) +(var = call (Foo 1 2)) +(var = slice (slice l 1 2)) +(var = nested (dot (subscript (dot (dot d a) b) 0) c)) +(echo "done") diff --git a/test/test_vim9expr.vim b/test/test_vim9expr.vim new file mode 100644 index 0000000..5480e25 --- /dev/null +++ b/test/test_vim9expr.vim @@ -0,0 +1,33 @@ +vim9script +var d = {key: 1, 'q': 2, "dq": 3, [1 + 1]: 4, 09: 5, a-b: 6} +var e = {} +var g = g:foo .. b:bar .. v:true +var l = [ + 1, # one + # comment line + + 2, +] +var m = { + a: 1, + b: [1, + 2], +} +var text = 'V' + .. 'i' + .. 'm' +var version = 9 * + 100 + + 2 +var latest = v:version == 902 + ? 'current' : + 'out-of-date' +var s = d.key .. d + .q +var r = [1, 2] + ->reverse() +var call = Foo(1, + 2) +var slice = l[1 : 2] +var nested = d.a.b[0].c +echo "done" diff --git a/test/test_vim9import.ok b/test/test_vim9import.ok index 3c82121..2992504 100644 --- a/test/test_vim9import.ok +++ b/test/test_vim9import.ok @@ -1,9 +1,20 @@ (vim9script) -(import "autoload 'mylib.vim'") -(import "'./util.vim' as util") -(import "'./x.vim' as util2") +(import autoload 'mylib.vim') +(import './util.vim' as util) +(import './x.vim' as util2) +; trailing comment (export (def (MyFunc): string (return "hello"))) (export (var = myval 42)) +(import TMP as Imp) +(import "myscript.vim") +(export + (const = MYCONST 1)) +(export + (final = myfinal (list))) +(export + (function (LegacyFunc) + (return 1))) +(echo (dot Imp y) ((dot util Func))) diff --git a/test/test_vim9import.vim b/test/test_vim9import.vim index 7b61318..0c9d048 100644 --- a/test/test_vim9import.vim +++ b/test/test_vim9import.vim @@ -6,3 +6,11 @@ export def MyFunc(): string return "hello" enddef export var myval = 42 +import TMP as Imp +import "myscript.vim" +export const MYCONST = 1 +export final myfinal = [] +export function LegacyFunc() + return 1 +endfunction +echo Imp.y util.Func() diff --git a/test/test_vim9lambda.ok b/test/test_vim9lambda.ok new file mode 100644 index 0000000..b847d2d --- /dev/null +++ b/test/test_vim9lambda.ok @@ -0,0 +1,13 @@ +(vim9script) +(var = F1 (lambda (n) (+ n 1))) +(var = F2 (lambda (n) (+ n 1))) +(var = F3 (lambda () 0)) +(var = F4 (lambda (_ val) (> val 0))) +(var = F5 (lambda (...args) (var = opts (dict)) (for arg args (echo arg)) (return opts))) +(var = timer (timer_start 700 (lambda (_) (echo 'x')) (dict ('repeat' 3)))) +(var = t0 (tuple)) +(var = t1 (tuple 1)) +(var = t2 (tuple 1 'a' (list 2))) +(var = p (* (+ 1 2) 3)) +(var = c (list 1 (cast g:two))) +(var = m (method (list 3 1) (sort (lambda (a b) (- a b))))) diff --git a/test/test_vim9lambda.vim b/test/test_vim9lambda.vim new file mode 100644 index 0000000..c9f9959 --- /dev/null +++ b/test/test_vim9lambda.vim @@ -0,0 +1,22 @@ +vim9script +var F1 = (n) => n + 1 +var F2 = (n: number): number => n + 1 +var F3 = () => 0 +var F4 = (_, val: number): bool => + val > 0 +var F5 = (...args: list): dict => { + var opts = {} + for arg in args + echo arg + endfor + return opts +} +var timer = timer_start(700, (_): void => { + echo 'x' + }, {repeat: 3}) +var t0 = () +var t1 = (1,) +var t2 = (1, 'a', [2]) +var p = (1 + 2) * 3 +var c = [1, g:two] +var m = [3, 1]->sort((a, b) => a - b) diff --git a/test/test_vim9mode_legacy.ok b/test/test_vim9mode_legacy.ok new file mode 100644 index 0000000..9e07094 --- /dev/null +++ b/test/test_vim9mode_legacy.ok @@ -0,0 +1,15 @@ +; A :def function in a legacy script uses Vim9 syntax. +(def (g:Vim9Func): number + ; Vim9 comment + (var = n 1) + ; trailing comment + (return n)) +(function (LegacyFunc) + ; legacy comment + (try + (let = x 1) + finally + (let = x 2))) +; legacy script +(def (Legacy (d (dict ('key' 1))) (n (+ 1 1))) + (echo d)) diff --git a/test/test_vim9mode_legacy.vim b/test/test_vim9mode_legacy.vim new file mode 100644 index 0000000..f654d17 --- /dev/null +++ b/test/test_vim9mode_legacy.vim @@ -0,0 +1,18 @@ +" A :def function in a legacy script uses Vim9 syntax. +def g:Vim9Func(): number + # Vim9 comment + var n = 1 # trailing comment + return n +enddef +function! LegacyFunc() + " legacy comment + try + let x = 1 + fina + let x = 2 + endtry +endfunction +" legacy script +def Legacy(d: dict = {key: 1}, n = 1 + 1) + echo d +enddef diff --git a/test/test_vim9mode_vim9.ok b/test/test_vim9mode_vim9.ok new file mode 100644 index 0000000..cfacd96 --- /dev/null +++ b/test/test_vim9mode_vim9.ok @@ -0,0 +1,11 @@ +(vim9script noclear) +; A legacy :function in a Vim9 script uses legacy syntax. +(function (LegacyFunc) + ; legacy comment + (let = x 1) + ; trailing comment + (return x)) +(def (Vim9Func) + ; Vim9 comment + (echo "string") + ; trailing comment) diff --git a/test/test_vim9mode_vim9.vim b/test/test_vim9mode_vim9.vim new file mode 100644 index 0000000..d609755 --- /dev/null +++ b/test/test_vim9mode_vim9.vim @@ -0,0 +1,11 @@ +vim9script noclear +# A legacy :function in a Vim9 script uses legacy syntax. +function LegacyFunc() + " legacy comment + let x = 1 " trailing comment + return x +endfunction +def Vim9Func() + # Vim9 comment + echo "string" # trailing comment +enddef diff --git a/test/test_vim9name_command.ok b/test/test_vim9name_command.ok new file mode 100644 index 0000000..41127aa --- /dev/null +++ b/test/test_vim9name_command.ok @@ -0,0 +1,6 @@ +(vim9script) +(def (Highlight new list) + (eval (method list (add new)))) +(def (Open) + (excmd "new") + (excmd "vertical new")) diff --git a/test/test_vim9name_command.vim b/test/test_vim9name_command.vim new file mode 100644 index 0000000..96d543f --- /dev/null +++ b/test/test_vim9name_command.vim @@ -0,0 +1,9 @@ +vim9script +def Highlight(new: string, list: list) + list + ->add(new) +enddef +def Open() + new + vertical new +enddef diff --git a/test/test_vim9number.ok b/test/test_vim9number.ok new file mode 100644 index 0000000..92c8dc5 --- /dev/null +++ b/test/test_vim9number.ok @@ -0,0 +1,4 @@ +(vim9script) +(var = big 1'000'000) +(var = s (interpolation big " is " (?: (> big 0) 'positive' 'not'))) +(var = f (?? big 0)) diff --git a/test/test_vim9number.vim b/test/test_vim9number.vim new file mode 100644 index 0000000..ab02113 --- /dev/null +++ b/test/test_vim9number.vim @@ -0,0 +1,4 @@ +vim9script +var big = 1'000'000 +var s = $"{big} is {big > 0 ? 'positive' : 'not'}" +var f = big ?? 0 diff --git a/test/test_vim9stmt.ok b/test/test_vim9stmt.ok new file mode 100644 index 0000000..025ee4f --- /dev/null +++ b/test/test_vim9stmt.ok @@ -0,0 +1,48 @@ +(vim9script) +(var = n 0) +(var = l (list 1 2)) +(var = d (dict ('a' 1))) +(assign = n 2) +(assign += n 1) +(assign ..= n 'x') +(assign = (subscript l 0) 3) +(assign = (slice l 0 1) (list 4 5)) +(assign = (dot d a) 2) +(assign = (subscript d 'b') 3) +(assign = (n l) (list 1 (list 2))) +(assign = (n . l) (list 1 2 3)) +(assign = g:var 1) +(assign = b:var 2) +(assign = &tabstop 8) +(assign = &l:shiftwidth 2) +(assign = $ENV 'x') +(assign = @a 'reg') +(assign ++ n) +(assign -- n) +(call (Foo)) +(call (g:Foo 1 2)) +(eval (method l (add 3))) +(eval (method l (add 4))) +(eval (method 'text' (setline 1))) +(eval (method "text" (setline 1))) +(eval (method (list 1 2) (len))) +(eval (method (dict ('a' 1)) (len))) +(eval (method (+ 1 2) (string))) +(eval (method 0z1234 (len))) +(eval (method 123 (string))) +(call (foo#bar#Baz)) +(call (Generic 1)) +(var = lines (list)) +(assign =<< lines (heredoc (list "trim") "END" (list " one"))) +(assign = n 1) +; comment +(call (Foo)) +(excmd "nnoremap = ") +(echo n) +(excmd "%s/a/b/g") +(excmd "1,2d") +(block + (echo 'block')) +(excmd "silent! :%delete _") +(if 1) +;}}} diff --git a/test/test_vim9stmt.vim b/test/test_vim9stmt.vim new file mode 100644 index 0000000..35caf01 --- /dev/null +++ b/test/test_vim9stmt.vim @@ -0,0 +1,51 @@ +vim9script +var n = 0 +var l = [1, 2] +var d = {a: 1} +n = 2 +n += 1 +n ..= 'x' +l[0] = 3 +l[0 : 1] = [4, 5] +d.a = 2 +d['b'] = 3 +[n, l] = [1, [2]] +[n; l] = [1, 2, 3] +g:var = 1 +b:var = 2 +&tabstop = 8 +&l:shiftwidth = 2 +$ENV = 'x' +@a = 'reg' +++n +--n +Foo() +g:Foo(1, 2) +l->add(3) +l + ->add(4) +'text'->setline(1) +"text"->setline(1) +[1, 2]->len() +{a: 1}->len() +(1 + 2)->string() +0z1234->len() +123->string() +foo#bar#Baz() +Generic(1) +var lines = [] +lines =<< trim END + one +END +n = 1 # comment +silent! Foo() +nnoremap = +echo n +:%s/a/b/g +:1,2d +{ + echo 'block' +} +silent! :%delete _ +if 1 +endif "}}}