Merge commit 'b9da30d92787f41ce610f0345e23ad6ecbfa637d' into main

main
Buddy Sandidge 8 years ago
commit ba22ecdc80

@ -1,4 +1,4 @@
# vim-javascript v1.0.0 # vim-javascript
JavaScript bundle for vim, this bundle provides syntax highlighting and JavaScript bundle for vim, this bundle provides syntax highlighting and
improved indentation. improved indentation.
@ -35,24 +35,37 @@ And install it:
## Configuration Variables ## Configuration Variables
The following variables control certain syntax highlighting features. You can The following variables control certain syntax highlighting plugins. You can
add them to your `.vimrc` to enable/disable their features. add them to your `.vimrc` to enable their features.
-----------------
``` ```
let g:javascript_enable_domhtmlcss = 1 let g:javascript_plugin_jsdoc = 1
``` ```
Enables HTML/CSS syntax highlighting in your JavaScript file. Enables syntax highlighting for [JSDocs](http://usejsdoc.org/).
Default Value: 0 Default Value: 0
----------------- -----------------
``` ```
let g:javascript_ignore_javaScriptdoc = 1 let g:javascript_plugin_ngdoc = 1
``` ```
Disables JSDoc syntax highlighting Enables some additional syntax highlighting for NGDocs. Requires JSDoc plugin
to be enabled as well.
Default Value: 0
-----------------
```
let g:javascript_plugin_flow = 1
```
Enables syntax highlighting for [Flow](https://flowtype.org/).
Default Value: 0 Default Value: 0
@ -84,6 +97,9 @@ variables:
let g:javascript_conceal_super = "Ω" let g:javascript_conceal_super = "Ω"
let g:javascript_conceal_arrow_function = "⇒" let g:javascript_conceal_arrow_function = "⇒"
## Indentation Specific
* `:h cino-:`
## Contributing ## Contributing
@ -101,18 +117,6 @@ proposed change and how it is valuable.
Report a bug on [GitHub Issues](https://github.com/pangloss/vim-javascript/issues). Report a bug on [GitHub Issues](https://github.com/pangloss/vim-javascript/issues).
## A Quick Note on Regexes
Vim 7.4 with patches LESS than 1-7 exhibits a bug that broke how we handle
javascript regexes. Please update to a newer version or run the following
commands to fix:
```
:set regexpengine=1
:syntax enable
```
## License ## License
Distributed under the same terms as Vim itself. See `:help license`. Distributed under the same terms as Vim itself. See `:help license`.

@ -0,0 +1,12 @@
" Vim filetype plugin file
" Language: JavaScript
" Maintainer: vim-javascript community
" URL: https://github.com/pangloss/vim-javascript
setlocal iskeyword+=$ suffixesadd+=.js
if exists('b:undo_ftplugin')
let b:undo_ftplugin .= ' | setlocal iskeyword< suffixesadd<'
else
let b:undo_ftplugin = 'setlocal iskeyword< suffixesadd<'
endif

@ -0,0 +1,87 @@
syntax region jsFlowDefinition contained start=/:/ end=/\%(\s*[,=;)\n]\)\@=/ contains=@jsFlowCluster containedin=jsParen
syntax region jsFlowArgumentDef contained start=/:/ end=/\%(\s*[,)]\|=>\@!\)\@=/ contains=@jsFlowCluster
syntax region jsFlowArray contained matchgroup=jsFlowNoise start=/\[/ end=/\]/ contains=@jsFlowCluster
syntax region jsFlowObject contained matchgroup=jsFlowNoise start=/{/ end=/}/ contains=@jsFlowCluster
syntax region jsFlowParens contained matchgroup=jsFlowNoise start=/(/ end=/)/ contains=@jsFlowCluster
syntax match jsFlowNoise contained /[:;,<>]/
syntax keyword jsFlowType contained boolean number string null void any mixed JSON array function object array bool class
syntax keyword jsFlowTypeof contained typeof skipempty skipempty nextgroup=jsFlowTypeCustom,jsFlowType
syntax match jsFlowTypeCustom contained /[0-9a-zA-Z_.]*/ skipwhite skipempty nextgroup=jsFlowGroup
syntax region jsFlowGroup contained matchgroup=jsFlowNoise start=/</ end=/>/ contains=@jsFlowCluster
syntax region jsFlowArrowArguments contained matchgroup=jsFlowNoise start=/(/ end=/)\%(\s*=>\)\@=/ oneline skipwhite skipempty nextgroup=jsFlowArrow contains=@jsFlowCluster
syntax match jsFlowArrow contained /=>/ skipwhite skipempty nextgroup=jsFlowType,jsFlowTypeCustom,jsFlowParens
syntax match jsFlowMaybe contained /?/ skipwhite skipempty nextgroup=jsFlowType,jsFlowTypeCustom,jsFlowParens,jsFlowArrowArguments
syntax match jsFlowObjectKey contained /[0-9a-zA-Z_$?]*\(\s*:\)\@=/ contains=jsFunctionKey,jsFlowMaybe skipwhite skipempty nextgroup=jsObjectValue containedin=jsObject
syntax match jsFlowOrOperator contained /|/ skipwhite skipempty nextgroup=@jsFlowCluster
syntax match jsFlowReturn contained /:\s*/ contains=jsFlowNoise skipwhite skipempty nextgroup=@jsFlowReturnCluster
syntax region jsFlowReturnObject contained matchgroup=jsFlowNoise start=/{/ end=/}/ contains=@jsFlowCluster skipwhite skipempty nextgroup=jsFuncBlock,jsFlowReturnOrOp
syntax region jsFlowReturnArray contained matchgroup=jsFlowNoise start=/\[/ end=/\]/ contains=@jsFlowCluster skipwhite skipempty nextgroup=jsFuncBlock,jsFlowReturnOrOp
syntax region jsFlowReturnParens contained matchgroup=jsFlowNoise start=/(/ end=/)/ contains=@jsFlowCluster skipwhite skipempty nextgroup=jsFuncBlock,jsFlowReturnOrOp
syntax match jsFlowReturnKeyword contained /\k\+/ contains=jsFlowType,jsFlowTypeCustom skipwhite skipempty nextgroup=jsFlowReturnGroup,jsFuncBlock,jsFlowReturnOrOp
syntax match jsFlowReturnMaybe contained /?/ skipwhite skipempty nextgroup=jsFlowReturnKeyword
syntax region jsFlowReturnGroup contained matchgroup=jsFlowNoise start=/</ end=/>/ contains=@jsFlowCluster skipwhite skipempty nextgroup=jsFuncBlock,jsFlowReturnOrOp
syntax match jsFlowReturnOrOp contained /\s*|\s*/ skipwhite skipempty nextgroup=@jsFlowReturnCluster
syntax region jsFlowFunctionGroup contained matchgroup=jsFlowNoise start=/</ end=/>/ contains=@jsFlowCluster skipwhite skipempty nextgroup=jsFuncArgs
syntax region jsFlowClassGroup contained matchgroup=jsFlowNoise start=/</ end=/>/ contains=@jsFlowCluster skipwhite skipempty nextgroup=jsClassBlock
syntax region jsFlowTypeStatement start=/type/ end=/=\@=/ contains=jsFlowTypeOperator oneline skipwhite skipempty nextgroup=jsFlowTypeValue keepend
syntax region jsFlowTypeValue contained start=/=/ end=/[;\n]/ contains=@jsExpression,jsFlowGroup,jsFlowMaybe
syntax match jsFlowTypeOperator contained /=/
syntax keyword jsFlowTypeKeyword contained type
syntax keyword jsFlowDeclare declare skipwhite skipempty nextgroup=jsFlowTypeStatement,jsClassDefinition,jsStorageClass,jsFlowModule,jsFlowInterface
syntax match jsFlowClassProperty contained /\<[0-9a-zA-Z_$]*\>:\@=/ skipwhite skipempty nextgroup=jsFlowClassDef containedin=jsClassBlock
syntax region jsFlowClassDef contained start=/:/ end=/\%(\s*[,=;)\n]\)\@=/ contains=@jsFlowCluster skipwhite skipempty nextgroup=jsClassValue
syntax region jsFlowModule contained start=/module/ end=/{\@=/ skipempty skipempty nextgroup=jsFlowDeclareBlock contains=jsString
syntax region jsFlowInterface contained start=/interface/ end=/{\@=/ skipempty skipempty nextgroup=jsFlowInterfaceBlock contains=@jsFlowCluster
syntax region jsFlowDeclareBlock contained matchgroup=jsFlowNoise start=/{/ end=/}/ contains=jsFlowDeclare,jsFlowNoise
syntax region jsFlowInterfaceBlock contained matchgroup=jsFlowNoise start=/{/ end=/}/ contains=jsObjectKey,jsObjectKeyString,jsObjectKeyComputed,jsObjectSeparator,jsObjectFuncName,jsObjectMethodType,jsGenerator,jsComment,jsObjectStringKey,jsSpreadExpression,jsFlowNoise keepend
syntax cluster jsFlowReturnCluster contains=jsFlowNoise,jsFlowReturnObject,jsFlowReturnArray,jsFlowReturnKeyword,jsFlowReturnGroup,jsFlowReturnMaybe,jsFlowReturnOrOp
syntax cluster jsFlowCluster contains=jsFlowArray,jsFlowObject,jsFlowNoise,jsFlowTypeof,jsFlowType,jsFlowGroup,jsFlowArrowArguments,jsFlowMaybe,jsFlowParens,jsFlowOrOperator
if version >= 508 || !exists("did_javascript_syn_inits")
if version < 508
let did_javascript_syn_inits = 1
command -nargs=+ HiLink hi link <args>
else
command -nargs=+ HiLink hi def link <args>
endif
HiLink jsFlowDefinition PreProc
HiLink jsFlowClassDef jsFlowDefinition
HiLink jsFlowArgumentDef jsFlowDefinition
HiLink jsFlowType Type
HiLink jsFlowTypeCustom PreProc
HiLink jsFlowTypeof PreProc
HiLink jsFlowArray PreProc
HiLink jsFlowObject PreProc
HiLink jsFlowParens PreProc
HiLink jsFlowGroup PreProc
HiLink jsFlowReturn PreProc
HiLink jsFlowReturnObject jsFlowReturn
HiLink jsFlowReturnArray jsFlowArray
HiLink jsFlowReturnParens jsFlowParens
HiLink jsFlowReturnGroup jsFlowGroup
HiLink jsFlowFunctionGroup PreProc
HiLink jsFlowClassGroup PreProc
HiLink jsFlowArrowArguments PreProc
HiLink jsFlowArrow PreProc
HiLink jsFlowTypeStatement PreProc
HiLink jsFlowTypeKeyword PreProc
HiLink jsFlowTypeOperator PreProc
HiLink jsFlowMaybe PreProc
HiLink jsFlowReturnMaybe PreProc
HiLink jsFlowClassProperty jsClassProperty
HiLink jsFlowDeclare PreProc
HiLink jsFlowModule PreProc
HiLink jsFlowInterface PreProc
HiLink jsFlowNoise Noise
HiLink jsFlowObjectKey jsObjectKey
HiLink jsFlowOrOperator PreProc
HiLink jsFlowReturnOrOp jsFlowOrOperator
delcommand HiLink
endif

@ -0,0 +1,39 @@
"" syntax coloring for javadoc comments (HTML)
syntax region jsComment matchgroup=jsComment start="/\*\s*" end="\*/" contains=jsDocTags,jsCommentTodo,jsCvsTag,@jsHtml,@Spell fold
" tags containing a param
syntax match jsDocTags contained "@\(alias\|api\|augments\|borrows\|class\|constructs\|default\|defaultvalue\|emits\|exception\|exports\|extends\|fires\|kind\|link\|listens\|member\|member[oO]f\|mixes\|module\|name\|namespace\|requires\|template\|throws\|var\|variation\|version\)\>" skipwhite nextgroup=jsDocParam
" tags containing type and param
syntax match jsDocTags contained "@\(arg\|argument\|cfg\|param\|property\|prop\)\>" skipwhite nextgroup=jsDocType
" tags containing type but no param
syntax match jsDocTags contained "@\(callback\|define\|enum\|external\|implements\|this\|type\|typedef\|return\|returns\)\>" skipwhite nextgroup=jsDocTypeNoParam
" tags containing references
syntax match jsDocTags contained "@\(lends\|see\|tutorial\)\>" skipwhite nextgroup=jsDocSeeTag
" other tags (no extra syntax)
syntax match jsDocTags contained "@\(abstract\|access\|accessor\|author\|classdesc\|constant\|const\|constructor\|copyright\|deprecated\|desc\|description\|dict\|event\|example\|file\|file[oO]verview\|final\|function\|global\|ignore\|inheritDoc\|inner\|instance\|interface\|license\|localdoc\|method\|mixin\|nosideeffects\|override\|overview\|preserve\|private\|protected\|public\|readonly\|since\|static\|struct\|todo\|summary\|undocumented\|virtual\)\>"
syntax region jsDocType contained matchgroup=jsDocTypeBrackets start="{" end="}" contains=jsDocTypeRecord oneline skipwhite nextgroup=jsDocParam
syntax match jsDocType contained "\%(#\|\"\|\w\|\.\|:\|\/\)\+" skipwhite nextgroup=jsDocParam
syntax region jsDocTypeRecord contained start=/{/ end=/}/ contains=jsDocTypeRecord extend
syntax region jsDocTypeRecord contained start=/\[/ end=/\]/ contains=jsDocTypeRecord extend
syntax region jsDocTypeNoParam contained start="{" end="}" oneline
syntax match jsDocTypeNoParam contained "\%(#\|\"\|\w\|\.\|:\|\/\)\+"
syntax match jsDocParam contained "\%(#\|\$\|-\|'\|\"\|{.\{-}}\|\w\|\.\|:\|\/\|\[.\{-}]\|=\)\+"
syntax region jsDocSeeTag contained matchgroup=jsDocSeeTag start="{" end="}" contains=jsDocTags
if version >= 508 || !exists("did_javascript_syn_inits")
if version < 508
let did_javascript_syn_inits = 1
command -nargs=+ HiLink hi link <args>
else
command -nargs=+ HiLink hi def link <args>
endif
HiLink jsDocTags Special
HiLink jsDocSeeTag Function
HiLink jsDocType Type
HiLink jsDocTypeBrackets jsDocType
HiLink jsDocTypeRecord jsDocType
HiLink jsDocTypeNoParam Type
HiLink jsDocParam Label
delcommand HiLink
endif

@ -0,0 +1,3 @@
syntax match jsDocTags contained /@\(link\|method[oO]f\|ngdoc\|ng[iI]nject\|restrict\)/ nextgroup=jsDocParam skipwhite
syntax match jsDocType contained "\%(#\|\$\|\w\|\"\|-\|\.\|:\|\/\)\+" nextgroup=jsDocParam skipwhite
syntax match jsDocParam contained "\%(#\|\$\|\w\|\"\|-\|\.\|:\|{\|}\|\/\|\[\|]\|=\)\+"

@ -3,7 +3,7 @@ au BufNewFile,BufRead *.jsm setf javascript
au BufNewFile,BufRead Jakefile setf javascript au BufNewFile,BufRead Jakefile setf javascript
fun! s:SelectJavascript() fun! s:SelectJavascript()
if getline(1) =~# '^#!.*/bin/env\s\+node\>' if getline(1) =~# '^#!.*/bin/\%(env\s\+\)\?node\>'
set ft=javascript set ft=javascript
endif endif
endfun endfun

@ -1,25 +1,25 @@
" Vim indent file " Vim indent file
" Language: Javascript " Language: Javascript
" Acknowledgement: Based off of vim-ruby maintained by Nikolai Weibull http://vim-ruby.rubyforge.org " Maintainer: Chris Paul ( https://github.com/bounceme )
" URL: https://github.com/pangloss/vim-javascript
" 0. Initialization {{{1 " Last Change: November 6, 2016
" =================
" Only load this indent file when no other was loaded. " Only load this indent file when no other was loaded.
if exists("b:did_indent") if exists('b:did_indent')
finish finish
endif endif
let b:did_indent = 1 let b:did_indent = 1
setlocal nosmartindent
" Now, set up our indentation expression and keys that trigger it. " Now, set up our indentation expression and keys that trigger it.
setlocal indentexpr=GetJavascriptIndent() setlocal indentexpr=GetJavascriptIndent()
setlocal formatexpr=Fixedgq(v:lnum,v:count) setlocal autoindent nolisp nosmartindent
setlocal indentkeys=0{,0},0),0],0\,:,!^F,o,O,e setlocal indentkeys=0{,0},0),0],:,!^F,o,O,e
setlocal cinoptions+=j1,J1
let b:undo_indent = 'setlocal indentexpr< smartindent< autoindent< indentkeys< cinoptions<'
" Only define the function once. " Only define the function once.
if exists("*GetJavascriptIndent") if exists('*GetJavascriptIndent')
finish finish
endif endif
@ -28,584 +28,235 @@ set cpo&vim
" Get shiftwidth value " Get shiftwidth value
if exists('*shiftwidth') if exists('*shiftwidth')
func s:sw() function s:sw()
return shiftwidth() return shiftwidth()
endfunc endfunction
else else
func s:sw() function s:sw()
return &sw return &sw
endfunc endfunction
endif endif
" 1. Variables {{{1 let s:case_stmt = '\<\%(case\>\s*[^ \t:].*\|default\s*\):\C'
" ============
let s:js_keywords = '^\s*\(break\|catch\|const\|continue\|debugger\|delete\|do\|else\|finally\|for\|function\|if\|in\|instanceof\|let\|new\|return\|switch\|this\|throw\|try\|typeof\|var\|void\|while\|with\)'
let s:expr_case = '^\s*\(case\s\+[^\:]*\|default\)\s*:\s*'
" Regex of syntax group names that are or delimit string or are comments. " Regex of syntax group names that are or delimit string or are comments.
let s:syng_strcom = '\%(\%(template\)\@<!string\|regex\|comment\)\c' let s:syng_strcom = 'string\|comment\|regex\|special\|doc\|template'
" Regex of syntax group names that are or delimit template strings
let s:syng_template = 'template\c'
" Regex of syntax group names that are strings.
let s:syng_string = 'regex\c'
" Regex of syntax group names that are strings or documentation.
let s:syng_multiline = 'comment\c'
" Regex of syntax group names that are line comment.
let s:syng_linecom = 'linecomment\c'
" Expression used to check whether we should skip a match with searchpair(). " Expression used to check whether we should skip a match with searchpair().
let s:skip_expr = "synIDattr(synID(line('.'),col('.'),1),'name') =~ '".s:syng_strcom."'" let s:skip_expr = "synIDattr(synID(line('.'),col('.'),0),'name') =~? '".s:syng_strcom."'"
function s:skip_func(lnum)
let s:line_term = '\s*\%(\%(\/\/\).*\)\=$' if !s:free || search('`\|\*\/','nW',a:lnum)
let s:free = !eval(s:skip_expr . " . '\\|html'")
" Regex that defines continuation lines, not including (, {, or [. let s:looksyn = s:free ? line('.') : s:looksyn
let s:continuation_regex = '\%([\\*/.:]\|+\@<!+\|-\@<!-\|\%(<%\)\@<!=\|\W[|&?]\|||\|&&\|[^=]=[^=>].*,\)' . s:line_term return !s:free
endif
" Regex that defines continuation lines. let s:looksyn = line('.')
" TODO: this needs to deal with if ...: and so on return (search('\/','nbW',s:looksyn) || search('[''"\\]','nW',s:looksyn)) && eval(s:skip_expr . " . '\\|html'")
let s:msl_regex = s:continuation_regex.'\|'.s:expr_case endfunction
let s:one_line_scope_regex = '\%(\%(\<else\>\|\<\%(if\|for\|while\)\>\s*(\%([^()]*\|[^()]*(\%([^()]*\|[^()]*(\%([^()]*\|[^()]*([^()]*)[^()]*\))[^()]*\))[^()]*\))\)\|=>\)' . s:line_term
" Regex that defines blocks.
let s:block_regex = '\%([{([]\)\s*\%(|\%([*@]\=\h\w*,\=\s*\)\%(,\s*[*@]\=\h\w*\)*|\)\=' . s:line_term
let s:operator_first = '^\s*\%([*/.:?]\|\([-+]\)\1\@!\|||\|&&\)'
let s:var_stmt = '^\s*\%(const\|let\|var\)'
let s:comma_first = '^\s*,'
let s:comma_last = ',\s*$'
let s:case_indent = s:sw() if has('reltime')
let s:case_indent_after = s:sw() function s:GetPair(start,end,flags,skip,time,...)
let s:m = matchlist(&cinoptions, ':\(.\)') return searchpair(a:start,'',a:end,a:flags,a:skip,max([prevnonblank(v:lnum) - 2000,0] + a:000),a:time)
if (len(s:m) > 2) endfunction
let s:case_indent = s:m[1] else
endif function s:GetPair(start,end,flags,skip,...)
let s:m = matchlist(&cinoptions, '=\(.\)') return searchpair(a:start,'',a:end,a:flags,a:skip,max([prevnonblank(v:lnum) - 1000,get(a:000,1)]))
if (len(s:m) > 2) endfunction
let s:case_indent_after = s:m[1]
endif endif
" 2. Auxiliary Functions {{{1
" ======================
" Check if the character at lnum:col is inside a string, comment, or is ascii. function s:current_char()
function s:IsInStringOrComment(lnum, col) return getline('.')[col('.')-1]
return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_strcom
endfunction endfunction
" Check if the character at lnum:col is inside a string. function s:token()
function s:IsInString(lnum, col) return s:current_char() =~ '\k' ? expand('<cword>') : s:current_char()
return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_string
endfunction endfunction
" Check if the character at lnum:col is inside a template string. " NOTE: moves the cursor
function s:IsInTempl(lnum, col) function s:previous_token()
return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_template return search('\<\|[][`^!"%-/:-?{-~]','bW') ? s:token() : ''
endfunction endfunction
" Check if the character at lnum:col is inside a multi-line comment. function s:Trim(ln)
function s:IsInMultilineComment(lnum, col) let pline = substitute(getline(a:ln),'\s*$','','')
return !s:IsLineComment(a:lnum, a:col) && synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_multiline let l:max = max([strridx(pline,'//'),strridx(pline,'/*'),0])
while l:max && synIDattr(synID(a:ln, strlen(pline), 0), 'name') =~? 'comment\|doc'
let pline = substitute(strpart(pline, 0, l:max),'\s*$','','')
let l:max = max([strridx(pline,'//'),strridx(pline,'/*'),0])
endwhile
return pline
endfunction endfunction
" Check if the character at lnum:col is a line comment. " configurable regexes that define continuation lines, not including (, {, or [.
function s:IsLineComment(lnum, col) let s:opfirst = '^' . get(g:,'javascript_opfirst',
return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_linecom \ '\%([<>,?^%|*/&]\|\([-.:+]\)\1\@!\|=>\@!\|in\%(stanceof\)\=\>\)')
endfunction let s:continuation = get(g:,'javascript_continuation',
\ '\%([<=,.?/*^%|&:]\|+\@<!+\|-\@<!-\|=\@<!>\|\<in\%(stanceof\)\=\)') . '$'
" Find line above 'lnum' that isn't empty, in a comment, or in a string. function s:OneScope(lnum,text)
function s:PrevNonBlankNonString(lnum) if cursor(a:lnum, match(' ' . a:text, ')$')) + 1 &&
let in_block = 0 \ s:GetPair('(', ')', 'bW', s:skip_expr, 100) > 0
let lnum = prevnonblank(a:lnum) let token = s:previous_token()
while lnum > 0 if index(split('await each'),token) + 1
" Go in and out of blocks comments as necessary. return s:previous_token() ==# 'for'
" If the line isn't empty (with opt. comment) or in a string, end search.
let line = getline(lnum)
if s:IsInMultilineComment(lnum, matchend(line, '/\*') - 1)
if in_block
let in_block = 0
else
break
endif endif
elseif !in_block && s:IsInMultilineComment(lnum, matchend(line, '\*/') - 1) return index(split('for if let while with'),token) + 1
let in_block = 1
elseif !in_block && line !~ '^\s*\%(//\).*$' && !(s:IsInStringOrComment(lnum, 1) && s:IsInStringOrComment(lnum, strlen(line)))
break
endif endif
let lnum = prevnonblank(lnum - 1) return cursor(a:lnum, match(' ' . a:text, '\%(\<else\|\<do\|=>\)$\C')) + 1
endwhile
return lnum
endfunction endfunction
" Find line above 'lnum' that started the continuation 'lnum' may be part of. function s:iscontOne(i,num,cont)
function s:GetMSL(lnum, in_one_line_scope) let [l:i, l:cont, l:num] = [a:i, a:cont, a:num + !a:num]
" Start on the line we're at and use its indent. let pind = a:num ? indent(l:num) + s:W : 0
let msl = a:lnum let ind = indent(l:i) + (a:cont ? 0 : s:W)
let lnum = s:PrevNonBlankNonString(a:lnum - 1) let bL = 0
while lnum > 0 while l:i >= l:num && (!l:cont || ind > pind)
" If we have a continuation line, or we're in a string, use line as MSL. if indent(l:i) < ind " first line always true for !a:cont, false for !!a:cont
" Otherwise, terminate search as we have found our MSL already. if s:OneScope(l:i,s:Trim(l:i))
let line = getline(lnum) let bL += s:W
let col = match(line, s:msl_regex) + 1 let [l:cont, l:i] = [0, line('.')]
let line2 = getline(msl) elseif !l:cont
let col2 = matchend(line2, ')')
if (col > 0 && !s:IsInStringOrComment(lnum, col)) || s:IsInString(lnum, strlen(line))
let msl = lnum
" if there are more closing brackets, continue from the line which has the matching opening bracket
elseif col2 > 0 && !s:IsInStringOrComment(msl, col2) && s:LineHasOpeningBrackets(msl)[0] == '2' && !a:in_one_line_scope
call cursor(msl, 1)
if searchpair('(', '', ')', 'bW', s:skip_expr) > 0
let lnum = line('.')
let msl = lnum
endif
else
" Don't use lines that are part of a one line scope as msl unless the
" flag in_one_line_scope is set to 1
"
if a:in_one_line_scope
break break
end endif
let msl_one_line = s:Match(lnum, s:one_line_scope_regex) elseif !a:cont
if msl_one_line == 0
break break
endif endif
end let ind = min([ind, indent(l:i)])
let lnum = s:PrevNonBlankNonString(lnum - 1) let l:i = s:PrevCodeLine(l:i - 1)
endwhile endwhile
return msl return bL
endfunction endfunction
function s:RemoveTrailingComments(content) " https://github.com/sweet-js/sweet.js/wiki/design#give-lookbehind-to-the-reader
let single = '\/\/\(.*\)\s*$' function s:IsBlock(...)
let multi = '\/\*\(.*\)\*\/\s*$' let l:ln = get(a:000,0,line('.'))
return substitute(substitute(a:content, single, '', ''), multi, '', '') let char = s:previous_token()
let syn = char =~ '[{>/]' || l:ln != line('.') ? synIDattr(synID(line('.'),col('.')-(char == '{'),0),'name') : ''
if char is ''
return 1
elseif syn =~? 'xml\|jsx'
return char != '{'
elseif syn =~? 'comment'
return search('\/[/*]','bW') && s:IsBlock(l:ln)
elseif char == '>'
return getline('.')[col('.')-2] == '=' || syn =~? '^jsflow'
elseif char == ':'
return cursor(0,match(' ' . strpart(getline('.'),0,col('.')),'.*\zs' . s:case_stmt . '$')) + 1 &&
\ (expand('<cword>') !=# 'default' || s:previous_token() !~ '[,{]')
endif
return index(split('return const let import export yield default delete var void typeof throw new in instanceof'
\ . ' - = ~ ! < * + , / ? ^ % | & ( ['), char) < (0 + (line('.') != l:ln))
endfunction endfunction
" Find if the string is inside var statement (but not the first string) " Find line above 'lnum' that isn't empty, in a comment, or in a string.
function s:InMultiVarStatement(lnum) function s:PrevCodeLine(lnum)
let lnum = s:PrevNonBlankNonString(a:lnum - 1) let l:lnum = prevnonblank(a:lnum)
while l:lnum
" let type = synIDattr(synID(lnum, indent(lnum) + 1, 0), 'name') let syn = synIDattr(synID(l:lnum,matchend(getline(l:lnum), '^\s*[^''"`]'),0),'name')
if syn =~? 'html'
" loop through previous expressions to find a var statement return
while lnum > 0 elseif syn !~? s:syng_strcom
let line = getline(lnum) return l:lnum
endif
" if the line is a js keyword let l:lnum = prevnonblank(l:lnum - 1)
if (line =~ s:js_keywords)
" check if the line is a var stmt
" if the line has a comma first or comma last then we can assume that we
" are in a multiple var statement
if (line =~ s:var_stmt)
return lnum
endif
" other js keywords, not a var
return 0
endif
let lnum = s:PrevNonBlankNonString(lnum - 1)
endwhile endwhile
" beginning of program, not a var
return 0
endfunction
" Find line above with beginning of the var statement or returns 0 if it's not
" this statement
function s:GetVarIndent(lnum)
let lvar = s:InMultiVarStatement(a:lnum)
let prev_lnum = s:PrevNonBlankNonString(a:lnum - 1)
if lvar
let line = s:RemoveTrailingComments(getline(prev_lnum))
" if the previous line doesn't end in a comma, return to regular indent
if (line !~ s:comma_last)
return indent(prev_lnum) - s:sw()
else
return indent(lvar) + s:sw()
endif
endif
return -1
endfunction endfunction
" Check if line 'lnum' has a balanced amount of parentheses.
" Check if line 'lnum' has more opening brackets than closing ones. function s:Balanced(lnum)
function s:LineHasOpeningBrackets(lnum) let l:open = 0
let open_0 = 0 let l:line = getline(a:lnum)
let open_2 = 0 let pos = match(l:line, '[][(){}]', 0)
let open_4 = 0
let line = getline(a:lnum)
let pos = match(line, '[][(){}]', 0)
while pos != -1 while pos != -1
if !s:IsInStringOrComment(a:lnum, pos + 1) if synIDattr(synID(a:lnum,pos + 1,0),'name') !~? s:syng_strcom
let idx = stridx('(){}[]', line[pos]) let l:open += match(' ' . l:line[pos],'[[({]')
if idx % 2 == 0 if l:open < 0
let open_{idx} = open_{idx} + 1 return
else
let open_{idx - 1} = open_{idx - 1} - 1
endif endif
endif endif
let pos = match(line, '[][(){}]', pos + 1) let pos = match(l:line, '[][(){}]', pos + 1)
endwhile endwhile
return (open_0 > 0 ? 1 : (open_0 == 0 ? 0 : 2)) . (open_2 > 0) . (open_4 > 0) return !l:open
endfunction
function s:Match(lnum, regex)
let col = match(getline(a:lnum), a:regex) + 1
return col > 0 && !s:IsInStringOrComment(a:lnum, col) ? col : 0
endfunction
function s:IndentWithContinuation(lnum, ind, width)
" Set up variables to use and search for MSL to the previous line.
let p_lnum = a:lnum
let lnum = s:GetMSL(a:lnum, 1)
let line = getline(lnum)
" If the previous line wasn't a MSL and is continuation return its indent.
" TODO: the || s:IsInString() thing worries me a bit.
if p_lnum != lnum
if s:Match(p_lnum,s:continuation_regex)||s:IsInString(p_lnum,strlen(line))
return a:ind
endif
endif
" Set up more variables now that we know we aren't continuation bound.
let msl_ind = indent(lnum)
" If the previous line ended with [*+/.-=], start a continuation that
" indents an extra level.
if s:Match(lnum, s:continuation_regex)
if lnum == p_lnum
return msl_ind + a:width
else
return msl_ind
endif
endif
return a:ind
endfunction
function s:InOneLineScope(lnum)
let msl = s:GetMSL(a:lnum, 1)
if msl > 0 && s:Match(msl, s:one_line_scope_regex)
return msl
endif
return 0
endfunction
function s:ExitingOneLineScope(lnum)
let msl = s:GetMSL(a:lnum, 1)
if msl > 0
" if the current line is in a one line scope ..
if s:Match(msl, s:one_line_scope_regex)
return 0
else
let prev_msl = s:GetMSL(msl - 1, 1)
if s:Match(prev_msl, s:one_line_scope_regex)
return prev_msl
endif
endif
endif
return 0
endfunction endfunction
" 3. GetJavascriptIndent Function {{{1
" =========================
function GetJavascriptIndent() function GetJavascriptIndent()
" 3.1. Setup {{{2 let b:js_cache = get(b:,'js_cache',[0,0,0])
" ----------
" Set up variables for restoring position in file. Could use v:lnum here.
let vcol = col('.')
" 3.2. Work on the current line {{{2
" -----------------------------
let ind = -1
" Get the current line. " Get the current line.
let line = getline(v:lnum) let l:line = getline(v:lnum)
" previous nonblank line number let syns = synIDattr(synID(v:lnum, 1, 0), 'name')
let prevline = prevnonblank(v:lnum - 1)
if (line =~ s:expr_case) " start with strings,comments,etc.
if (getline(prevline) =~ s:expr_case) if syns =~? 'comment\|doc'
return indent(prevline) if l:line =~ '^\s*\*'
else return cindent(v:lnum)
if (getline(prevline) =~ s:block_regex) elseif l:line !~ '^\s*\/'
return indent(prevline) + s:case_indent return -1
else
return indent(prevline) - s:case_indent_after
endif
endif endif
elseif syns =~? 'string\|template' && l:line !~ '^[''"]'
return -1
endif endif
" If we got a closing bracket on an empty line, find its match and indent let l:lnum = s:PrevCodeLine(v:lnum - 1)
" according to it. For parentheses we indent to its column - 1, for the if !l:lnum
" others we indent to the containing line's MSL's level. Return -1 if fail. return
let col = matchend(line, '^\s*[],})]') endif
if col > 0 && !s:IsInStringOrComment(v:lnum, col)
call cursor(v:lnum, col) let l:line = substitute(substitute(l:line,'^\s*\%(\/\*.\{-}\*\/\s*\)*','',''),'^\/[/*].*','','')
let lvar = s:InMultiVarStatement(v:lnum) " the containing paren, bracket, curly. Many hacks for performance
if lvar call cursor(v:lnum,1)
let prevline_contents = s:RemoveTrailingComments(getline(prevline)) let idx = strlen(l:line) ? stridx('])}',l:line[0]) : -1
if indent(l:lnum)
" check for comma first let [s:looksyn,s:free] = [v:lnum - 1,1]
if (line[col - 1] =~ ',') if b:js_cache[0] >= l:lnum && b:js_cache[0] < v:lnum &&
" if the previous line ends in comma or semicolon don't indent \ (b:js_cache[0] > l:lnum || s:Balanced(l:lnum))
if (prevline_contents =~ '[;,]\s*$') call call('cursor',b:js_cache[1:])
return indent(s:GetMSL(line('.'), 0)) elseif idx + 1
" get previous line indent, if it's comma first return prevline indent call s:GetPair(['\[','(','{'][idx], '])}'[idx],'bW','s:skip_func(s:looksyn)',2000)
elseif (prevline_contents =~ s:comma_first) elseif indent(v:lnum) && syns =~? 'block'
return indent(prevline) call s:GetPair('{','}','bW','s:skip_func(s:looksyn)',2000)
" otherwise we indent 1 level
else else
return indent(lvar) + s:sw() call s:GetPair('[({[]','[])}]','bW','s:skip_func(s:looksyn)',2000)
endif
endif endif
endif
let bs = strpart('(){}[]', stridx(')}]', line[col - 1]) * 2, 2)
if searchpair(escape(bs[0], '\['), '', bs[1], 'bW', s:skip_expr) > 0
if line[col-1]==')' && col('.') != col('$') - 1
let ind = virtcol('.')-1
else else
let ind = indent(s:GetMSL(line('.'), 0)) call s:GetPair('[({[]','[])}]','bW',s:skip_expr,200,l:lnum)
endif
endif endif
return ind
endif
" If the line is comma first, dedent 1 level
if (getline(prevline) =~ s:comma_first)
return indent(prevline) - s:sw()
endif
if (getline(prevline) =~ s:expr_case)
return indent(prevline) + s:case_indent_after
endif
" If line starts with an operator...
if (s:Match(v:lnum, s:operator_first))
if (s:Match(prevline, s:operator_first))
" and so does previous line, don't indent
return indent(prevline)
end
let counts = s:LineHasOpeningBrackets(prevline)
if counts[0] == '2'
call cursor(prevline, 1)
" Search for the opening tag
let mnum = searchpair('(', '', ')', 'bW', s:skip_expr)
if mnum > 0 && s:Match(mnum, s:operator_first)
return indent(mnum)
end
elseif counts[0] != '1' && counts[1] != '1' && counts[2] != '1'
" otherwise, indent 1 level
return indent(prevline) + s:sw()
end
" If previous line starts with an operator...
elseif s:Match(prevline, s:operator_first) && !s:Match(prevline, s:comma_last) && !s:Match(prevline, '};\=' . s:line_term)
let counts = s:LineHasOpeningBrackets(prevline)
if counts[0] == '2' && counts[1] == '1'
call cursor(prevline, 1)
" Search for the opening tag
let mnum = searchpair('(', '', ')', 'bW', s:skip_expr)
if mnum > 0 && !s:Match(mnum, s:operator_first)
return indent(mnum) + s:sw()
end
elseif counts[0] != '1' && counts[1] != '1' && counts[2] != '1'
return indent(prevline) - s:sw()
end
end
if getline(prevline) =~ '^\s*`$' && s:IsInTempl(v:lnum, 1) if idx + 1
if line !~ '^\s*`$' if idx == 2 && search('\S','bW',line('.')) && s:current_char() == ')'
return indent(prevline) + s:sw() call s:GetPair('(',')','bW',s:skip_expr,200)
endif endif
elseif line =~ '^\s*`$' && s:IsInTempl(prevline, 1) return indent(line('.'))
return indent(prevline) - s:sw()
endif endif
" If we are in a multi-line comment, cindent does the right thing. let b:js_cache = [v:lnum] + (line('.') == v:lnum ? [0,0] : [line('.'),col('.')])
if s:IsInMultilineComment(v:lnum, 1) && !s:IsLineComment(v:lnum, 1) let num = b:js_cache[1]
return cindent(v:lnum)
endif
" Check for multiple var assignments
" let var_indent = s:GetVarIndent(v:lnum)
" if var_indent >= 0
" return var_indent
" endif
" 3.3. Work on the previous line. {{{2
" -------------------------------
" If the line is empty and the previous nonblank line was a multi-line let [s:W, pline, isOp, stmt, bL, switch_offset] = [s:sw(), s:Trim(l:lnum),0,0,0,0]
" comment, use that comment's indent. Deduct one char to account for the if num && s:current_char() == '{' && s:IsBlock()
" space in ' */'. let stmt = 1
if line =~ '^\s*$' && s:IsInMultilineComment(prevline, 1) if s:current_char() == ')' && s:GetPair('(', ')', 'bW', s:skip_expr, 100) > 0 && s:previous_token() ==# 'switch'
return indent(prevline) - 1 let switch_offset = &cino !~ ':' || !has('float') ? s:W :
\ float2nr(str2float(matchstr(&cino,'.*:\zs[-0-9.]*')) * (&cino =~# '\%(.*:\)\@>[^,]*s' ? s:W : 1))
if l:line =~# '^' . s:case_stmt
return indent(num) + switch_offset
endif endif
let stmt = pline !~# s:case_stmt . '$'
" Find a non-blank, non-multi-line string line above the current line.
let lnum = s:PrevNonBlankNonString(v:lnum - 1)
" If the line is empty and inside a string, use the previous line.
if line =~ '^\s*$' && lnum != prevline
return indent(prevnonblank(v:lnum))
endif endif
" At the start of the file use zero indent.
if lnum == 0
return 0
endif endif
if stmt || !num
" If the previous line ended with a block opening, add a level of indent. let isOp = l:line =~# s:opfirst || pline =~# s:continuation
if s:Match(lnum, s:block_regex) let bL = s:iscontOne(l:lnum,num,isOp)
if (line =~ s:expr_case) let bL -= (bL && l:line[0] == '{') * s:W
return indent(s:GetMSL(lnum, 0)) + s:sw()/2
else
return indent(s:GetMSL(lnum, 0)) + s:sw()
endif
endif endif
" Set up variables for current line. " main return
let line = getline(lnum) if isOp
let ind = indent(lnum) return (num ? indent(num) : -s:W) + (s:W * 2) + switch_offset + bL
" If the previous line contained an opening bracket, and we are still in it, elseif num
" add indent depending on the bracket type. return indent(num) + s:W + switch_offset + bL
if line =~ '[[({]'
let counts = s:LineHasOpeningBrackets(lnum)
if counts[0] == '1' && searchpair('(', '', ')', 'bW', s:skip_expr) > 0
if col('.') + 1 == col('$') || line =~ s:one_line_scope_regex
return ind + s:sw()
else
return virtcol('.')
endif endif
elseif counts[1] == '1' || counts[2] == '1' && counts[0] != '2' return bL
return ind + s:sw()
else
call cursor(v:lnum, vcol)
end
elseif line =~ '.\+};\=' . s:line_term
call cursor(lnum, 1)
" Search for the opening tag
let mnum = searchpair('{', '', '}', 'bW', s:skip_expr)
if mnum > 0
return indent(s:GetMSL(mnum, 0))
end
elseif line =~ '.\+);\=' || line =~ s:comma_last
let counts = s:LineHasOpeningBrackets(lnum)
if counts[0] == '2'
call cursor(lnum, 1)
" Search for the opening tag
let mnum = searchpair('(', '', ')', 'bW', s:skip_expr)
if mnum > 0
return indent(s:GetMSL(mnum, 0))
end
elseif line !~ s:var_stmt
return indent(prevline)
end
end
" 3.4. Work on the MSL line. {{{2
" --------------------------
let ind_con = ind
let ind = s:IndentWithContinuation(lnum, ind_con, s:sw())
" }}}2
"
"
let ols = s:InOneLineScope(lnum)
if ols > 0
let ind = ind + s:sw()
else
let ols = s:ExitingOneLineScope(lnum)
while ols > 0 && ind > 0
let ind = ind - s:sw()
let ols = s:InOneLineScope(ols - 1)
endwhile
endif
return ind
endfunction endfunction
" }}}1
let &cpo = s:cpo_save let &cpo = s:cpo_save
unlet s:cpo_save unlet s:cpo_save
function! Fixedgq(lnum, count)
let l:tw = &tw ? &tw : 80;
let l:count = a:count
let l:first_char = indent(a:lnum) + 1
if mode() == 'i' " gq was not pressed, but tw was set
return 1
endif
" This gq is only meant to do code with strings, not comments
if s:IsLineComment(a:lnum, l:first_char) || s:IsInMultilineComment(a:lnum, l:first_char)
return 1
endif
if len(getline(a:lnum)) < l:tw && l:count == 1 " No need for gq
return 1
endif
" Put all the lines on one line and do normal spliting after that
if l:count > 1
while l:count > 1
let l:count -= 1
normal J
endwhile
endif
let l:winview = winsaveview()
call cursor(a:lnum, l:tw + 1)
let orig_breakpoint = searchpairpos(' ', '', '\.', 'bcW', '', a:lnum)
call cursor(a:lnum, l:tw + 1)
let breakpoint = searchpairpos(' ', '', '\.', 'bcW', s:skip_expr, a:lnum)
" No need for special treatment, normal gq handles edgecases better
if breakpoint[1] == orig_breakpoint[1]
call winrestview(l:winview)
return 1
endif
" Try breaking after string
if breakpoint[1] <= indent(a:lnum)
call cursor(a:lnum, l:tw + 1)
let breakpoint = searchpairpos('\.', '', ' ', 'cW', s:skip_expr, a:lnum)
endif
if breakpoint[1] != 0
call feedkeys("r\<CR>")
else
let l:count = l:count - 1
endif
" run gq on new lines
if l:count == 1
call feedkeys("gqq")
endif
return 0
endfunction

@ -12,210 +12,223 @@ if !exists("main_syntax")
let main_syntax = 'javascript' let main_syntax = 'javascript'
endif endif
if !exists('g:javascript_conceal') " Dollar sign is permitted anywhere in an identifier
let g:javascript_conceal = 0 if v:version > 704 || v:version == 704 && has('patch1142')
syntax iskeyword @,48-57,_,192-255,$
else
setlocal iskeyword+=$
endif endif
"" dollar sign is permittd anywhere in an identifier
setlocal iskeyword+=$
syntax sync fromstart syntax sync fromstart
" TODO: Figure out what type of casing I need
" syntax case ignore
syntax case match
syntax match jsNoise /[:,\;\.]\{1}/ syntax match jsNoise /[:,\;\.]\{1}/
syntax match jsFuncCall /\k\+\%(\s*(\)\@=/
syntax match jsParensError /[)}\]]/
"" Program Keywords " Program Keywords
syntax keyword jsStorageClass const var let syntax keyword jsStorageClass const var let skipwhite skipempty nextgroup=jsDestructuringBlock,jsDestructuringArray,jsVariableDef
syntax keyword jsOperator delete instanceof typeof void new in syntax match jsVariableDef contained /\k\+/ nextgroup=jsFlowDefinition
syntax keyword jsOperator delete instanceof typeof void new in of
syntax match jsOperator /[\!\|\&\+\-\<\>\=\%\/\*\~\^]\{1}/ syntax match jsOperator /[\!\|\&\+\-\<\>\=\%\/\*\~\^]\{1}/
syntax keyword jsBooleanTrue true syntax keyword jsBooleanTrue true
syntax keyword jsBooleanFalse false syntax keyword jsBooleanFalse false
syntax keyword jsModules import export contained
syntax keyword jsModuleWords default from as contained
syntax keyword jsOf of contained
syntax keyword jsArgsObj arguments
syntax region jsImportContainer start="^\s\?import \?" end=";\|$" contains=jsModules,jsModuleWords,jsLineComment,jsComment,jsStringS,jsStringD,jsTemplateString,jsNoise,jsBlock
syntax region jsExportContainer start="^\s\?export \?" end="$" contains=jsModules,jsModuleWords,jsComment,jsTemplateString,jsStringD,jsStringS,jsRegexpString,jsNumber,jsFloat,jsThis,jsOperator,jsBooleanTrue,jsBooleanFalse,jsNull,jsFunction,jsArrowFunction,jsGlobalObjects,jsExceptions,jsDomErrNo,jsDomNodeConsts,jsHtmlEvents,jsDotNotation,jsBracket,jsParen,jsFuncCall,jsUndefined,jsNan,jsKeyword,jsStorageClass,jsPrototype,jsBuiltins,jsNoise,jsArgsObj,jsBlock,jsClassDefinition
"" JavaScript comments
syntax keyword jsCommentTodo TODO FIXME XXX TBD contained
syntax region jsLineComment start=+\/\/+ end=+$+ keepend contains=jsCommentTodo,@Spell extend
syntax region jsEnvComment start="\%^#!" end="$" display
syntax region jsLineComment start=+^\s*\/\/+ skip=+\n\s*\/\/+ end=+$+ keepend contains=jsCommentTodo,@Spell fold
syntax region jsCvsTag start="\$\cid:" end="\$" oneline contained
syntax region jsComment start="/\*" end="\*/" contains=jsCommentTodo,jsCvsTag,@Spell fold extend
"" JSDoc / JSDoc Toolkit
if !exists("javascript_ignore_javaScriptdoc")
syntax case ignore
"" syntax coloring for javadoc comments (HTML)
"syntax include @javaHtml <sfile>:p:h/html.vim
"unlet b:current_syntax
syntax region jsBlockComment matchgroup=jsComment start="/\*\s*" end="\*/" contains=jsDocTags,jsCommentTodo,jsCvsTag,@jsHtml,@Spell fold
" tags containing a param
syntax match jsDocTags contained "@\(alias\|api\|augments\|borrows\|class\|constructs\|default\|defaultvalue\|emits\|exception\|exports\|extends\|fires\|kind\|link\|listens\|member\|member[oO]f\|mixes\|module\|name\|namespace\|requires\|template\|throws\|var\|variation\|version\)\>" nextgroup=jsDocParam skipwhite
" tags containing type and param
syntax match jsDocTags contained "@\(arg\|argument\|cfg\|param\|property\|prop\)\>" nextgroup=jsDocType skipwhite
" tags containing type but no param
syntax match jsDocTags contained "@\(callback\|define\|enum\|external\|implements\|this\|type\|typedef\|return\|returns\)\>" nextgroup=jsDocTypeNoParam skipwhite
" tags containing references
syntax match jsDocTags contained "@\(lends\|see\|tutorial\)\>" nextgroup=jsDocSeeTag skipwhite
" other tags (no extra syntax)
syntax match jsDocTags contained "@\(abstract\|access\|accessor\|author\|classdesc\|constant\|const\|constructor\|copyright\|deprecated\|desc\|description\|dict\|event\|example\|file\|file[oO]verview\|final\|function\|global\|ignore\|inheritDoc\|inner\|instance\|interface\|license\|localdoc\|method\|mixin\|nosideeffects\|override\|overview\|preserve\|private\|protected\|public\|readonly\|since\|static\|struct\|todo\|summary\|undocumented\|virtual\)\>"
syntax region jsDocType matchgroup=jsDocTypeBrackets start="{" end="}" oneline contained nextgroup=jsDocParam skipwhite contains=jsDocTypeRecord
syntax match jsDocType contained "\%(#\|\"\|\w\|\.\|:\|\/\)\+" nextgroup=jsDocParam skipwhite
syntax region jsDocTypeRecord start=/{/ end=/}/ contained extend contains=jsDocTypeRecord
syntax region jsDocTypeRecord start=/\[/ end=/\]/ contained extend contains=jsDocTypeRecord
syntax region jsDocTypeNoParam start="{" end="}" oneline contained
syntax match jsDocTypeNoParam contained "\%(#\|\"\|\w\|\.\|:\|\/\)\+"
syntax match jsDocParam contained "\%(#\|\$\|-\|'\|\"\|{.\{-}}\|\w\|\.\|:\|\/\|\[.{-}]\|=\)\+"
syntax region jsDocSeeTag contained matchgroup=jsDocSeeTag start="{" end="}" contains=jsDocTags
syntax case match
endif "" JSDoc end
syntax case match
"" Syntax in the JavaScript code " Modules
syntax match jsFuncCall /\k\+\%(\s*(\)\@=/ syntax keyword jsModuleKeywords contained import
syntax match jsSpecial "\v\\%(0|\\x\x\{2\}\|\\u\x\{4\}\|\c[A-Z]|.)" contained syntax keyword jsModuleKeywords contained export skipwhite skipempty nextgroup=jsExportBlock,jsModuleDefault
syntax region jsTemplateVar matchgroup=jsTemplateBraces start=+${+ end=+}+ contained contains=@jsExpression syntax keyword jsModuleOperators contained from
syntax region jsStringD start=+"+ skip=+\\\("\|$\)+ end=+"\|$+ contains=jsSpecial,@htmlPreproc,@Spell syntax keyword jsModuleOperators contained as
syntax region jsStringS start=+'+ skip=+\\\('\|$\)+ end=+'\|$+ contains=jsSpecial,@htmlPreproc,@Spell syntax region jsModuleGroup contained matchgroup=jsModuleBraces start=/{/ end=/}/ contains=jsModuleOperators,jsNoise,jsComment
syntax region jsTemplateString start=+`+ skip=+\\\(`\|$\)+ end=+`+ contains=jsTemplateVar,jsSpecial,@htmlPreproc syntax match jsModuleAsterisk contained /*/
syntax region jsTaggedTemplate start=/\k\+\%([\n\s]\+\)\?`/ end=+`+ contains=jsTemplateString keepend syntax keyword jsModuleDefault contained default skipwhite skipempty nextgroup=@jsExpression
syntax region jsRegexpCharClass start=+\[+ skip=+\\.+ end=+\]+ contained syntax region jsImportContainer start=/\<import\> / end="\%(;\|$\)" contains=jsModuleKeywords,jsModuleOperators,jsComment,jsString,jsTemplateString,jsNoise,jsModuleGroup,jsModuleAsterisk
syntax match jsRegexpBoundary "\v%(\<@![\^$]|\\[bB])" contained syntax region jsExportContainer start=/\<export\> / end="\%(;\|$\)" contains=jsModuleKeywords,jsModuleOperators,jsStorageClass,jsModuleDefault,@jsExpression
syntax match jsRegexpBackRef "\v\\[1-9][0-9]*" contained syntax region jsExportBlock contained matchgroup=jsExportBraces start=/{/ end=/}/ contains=jsModuleOperators,jsNoise,jsComment
syntax match jsRegexpQuantifier "\v\\@<!%([?*+]|\{\d+%(,|,\d+)?})\??" contained
syntax match jsRegexpOr "\v\<@!\|" contained " Strings, Templates, Numbers
syntax match jsRegexpMod "\v\(@<=\?[:=!>]" contained syntax region jsString start=+"+ skip=+\\\("\|$\)+ end=+"\|$+ contains=jsSpecial,@Spell extend
syntax cluster jsRegexpSpecial contains=jsSpecial,jsRegexpBoundary,jsRegexpBackRef,jsRegexpQuantifier,jsRegexpOr,jsRegexpMod syntax region jsString start=+'+ skip=+\\\('\|$\)+ end=+'\|$+ contains=jsSpecial,@Spell extend
syntax region jsRegexpGroup start="\\\@<!(" skip="\\.\|\[\(\\.\|[^]]\)*\]" end="\\\@<!)" contained contains=jsRegexpCharClass,@jsRegexpSpecial keepend syntax region jsTemplateString start=+`+ skip=+\\\(`\|$\)+ end=+`+ contains=jsTemplateVar,jsSpecial extend
syntax region jsRegexpString start=+\%(\%(\%(return\|case\)\s\+\)\@50<=\|\%(\%([)\]"']\|\d\|\w\)\s*\)\@50<!\)/\(\*\|/\)\@!+ skip=+\\.\|\[\%(\\.\|[^]]\)*\]+ end=+/[gimy]\{,4}+ contains=jsRegexpCharClass,jsRegexpGroup,@jsRegexpSpecial,@htmlPreproc oneline keepend syntax match jsTaggedTemplate /\k\+\%(`\)\@=/ nextgroup=jsTemplateString
syntax match jsNumber /\<-\=\d\+\(L\|[eE][+-]\=\d\+\)\=\>\|\<0[xX]\x\+\>/ syntax match jsNumber /\<\d\+\%([eE][+-]\=\d\+\)\=\>\|\<0[bB][01]\+\>\|\<0[oO]\o\+\>\|\<0[xX]\x\+\>/
syntax keyword jsNumber Infinity syntax keyword jsNumber Infinity
syntax match jsFloat /\<-\=\%(\d\+\.\d\+\|\d\+\.\|\.\d\+\)\%([eE][+-]\=\d\+\)\=\>/ syntax match jsFloat /\<\%(\d\+\.\d\+\|\d\+\.\|\.\d\+\)\%([eE][+-]\=\d\+\)\=\>/
syntax match jsObjectKey /\<[a-zA-Z_$][0-9a-zA-Z_$]*\>\(\s*:\)\@=/ contains=jsFunctionKey contained
syntax match jsFunctionKey /\<[a-zA-Z_$][0-9a-zA-Z_$]*\>\(\s*:\s*function\s*\)\@=/ contained " Regular Expressions
syntax match jsDecorator "@" display contains=jsDecoratorFunction nextgroup=jsDecoratorFunction skipwhite syntax match jsSpecial contained "\v\\%(0|\\x\x\{2\}\|\\u\x\{4\}\|\c[A-Z]|.)"
syntax match jsDecoratorFunction "[a-zA-Z_][a-zA-Z0-9_.]*" display contained nextgroup=jsFunc skipwhite syntax region jsTemplateVar contained matchgroup=jsTemplateBraces start=+${+ end=+}+ contains=@jsExpression
syntax region jsRegexpCharClass contained start=+\[+ skip=+\\.+ end=+\]+
syntax match jsRegexpBoundary contained "\v%(\<@![\^$]|\\[bB])"
syntax match jsRegexpBackRef contained "\v\\[1-9][0-9]*"
syntax match jsRegexpQuantifier contained "\v\\@<!%([?*+]|\{\d+%(,|,\d+)?})\??"
syntax match jsRegexpOr contained "\v\<@!\|"
syntax match jsRegexpMod contained "\v\(@<=\?[:=!>]"
syntax region jsRegexpGroup contained start="\\\@<!(" skip="\\.\|\[\(\\.\|[^]]\)*\]" end="\\\@<!)" contains=jsRegexpCharClass,@jsRegexpSpecial keepend
if v:version > 703 || v:version == 603 && has("patch1088")
syntax region jsRegexpString start=+\%(\%(\%(return\|case\)\s\+\)\@50<=\|\%(\%([)\]"']\|\d\|\w\)\s*\)\@50<!\)/\(\*\|/\)\@!+ skip=+\\.\|\[\%(\\.\|[^]]\)*\]+ end=+/[gimy]\{,4}+ contains=jsRegexpCharClass,jsRegexpGroup,@jsRegexpSpecial oneline keepend extend
else
syntax region jsRegexpString start=+\%(\%(\%(return\|case\)\s\+\)\@<=\|\%(\%([)\]"']\|\d\|\w\)\s*\)\@<!\)/\(\*\|/\)\@!+ skip=+\\.\|\[\%(\\.\|[^]]\)*\]+ end=+/[gimy]\{,4}+ contains=jsRegexpCharClass,jsRegexpGroup,@jsRegexpSpecial oneline keepend extend
endif
syntax cluster jsRegexpSpecial contains=jsSpecial,jsRegexpBoundary,jsRegexpBackRef,jsRegexpQuantifier,jsRegexpOr,jsRegexpMod
" Objects
syntax match jsObjectKey contained /\<[0-9a-zA-Z_$]*\>\(\s*:\)\@=/ contains=jsFunctionKey skipwhite skipempty nextgroup=jsObjectValue
syntax match jsObjectColon contained /:/ skipwhite skipempty
syntax region jsObjectKeyString contained start=+"+ skip=+\\\("\|$\)+ end=+"\|$+ contains=jsSpecial,@Spell skipwhite skipempty nextgroup=jsObjectValue
syntax region jsObjectKeyString contained start=+'+ skip=+\\\('\|$\)+ end=+'\|$+ contains=jsSpecial,@Spell skipwhite skipempty nextgroup=jsObjectValue
syntax region jsObjectKeyComputed contained matchgroup=jsBrackets start=/\[/ end=/]/ contains=@jsExpression skipwhite skipempty nextgroup=jsObjectValue,jsFuncArgs extend
syntax match jsObjectSeparator contained /,/
syntax region jsObjectValue contained start=/:/ end=/\%(,\|}\)\@=/ contains=jsObjectColon,@jsExpression extend
syntax match jsObjectFuncName contained /\<[a-zA-Z_$][0-9a-zA-Z_$]*\>[\r\n\t ]*(\@=/ skipwhite skipempty nextgroup=jsFuncArgs
syntax match jsFunctionKey contained /\<[a-zA-Z_$][0-9a-zA-Z_$]*\>\(\s*:\s*function\s*\)\@=/
syntax match jsObjectMethodType contained /\%(get\|set\|static\|async\)\%( \k\+\)\@=/ skipwhite skipempty nextgroup=jsObjectFuncName
syntax region jsObjectStringKey contained start=+"+ skip=+\\\("\|$\)+ end=+"\|$+ contains=jsSpecial,@Spell extend skipwhite skipempty nextgroup=jsFuncArgs,jsObjectValue
syntax region jsObjectStringKey contained start=+'+ skip=+\\\('\|$\)+ end=+'\|$+ contains=jsSpecial,@Spell extend skipwhite skipempty nextgroup=jsFuncArgs,jsObjectValue
exe 'syntax keyword jsNull null '.(exists('g:javascript_conceal_null') ? 'conceal cchar='.g:javascript_conceal_null : '') exe 'syntax keyword jsNull null '.(exists('g:javascript_conceal_null') ? 'conceal cchar='.g:javascript_conceal_null : '')
exe 'syntax keyword jsReturn return '.(exists('g:javascript_conceal_return') ? 'conceal cchar='.g:javascript_conceal_return : '') exe 'syntax keyword jsReturn return contained '.(exists('g:javascript_conceal_return') ? 'conceal cchar='.g:javascript_conceal_return : '')
exe 'syntax keyword jsUndefined undefined '.(exists('g:javascript_conceal_undefined') ? 'conceal cchar='.g:javascript_conceal_undefined : '') exe 'syntax keyword jsUndefined undefined '.(exists('g:javascript_conceal_undefined') ? 'conceal cchar='.g:javascript_conceal_undefined : '')
exe 'syntax keyword jsNan NaN '.(exists('g:javascript_conceal_NaN') ? 'conceal cchar='.g:javascript_conceal_NaN : '') exe 'syntax keyword jsNan NaN '.(exists('g:javascript_conceal_NaN') ? 'conceal cchar='.g:javascript_conceal_NaN : '')
exe 'syntax keyword jsPrototype prototype '.(exists('g:javascript_conceal_prototype') ? 'conceal cchar='.g:javascript_conceal_prototype : '') exe 'syntax keyword jsPrototype prototype '.(exists('g:javascript_conceal_prototype') ? 'conceal cchar='.g:javascript_conceal_prototype : '')
exe 'syntax keyword jsThis this '.(exists('g:javascript_conceal_this') ? 'conceal cchar='.g:javascript_conceal_this : '') exe 'syntax keyword jsThis this '.(exists('g:javascript_conceal_this') ? 'conceal cchar='.g:javascript_conceal_this : '')
exe 'syntax keyword jsStatic static '.(exists('g:javascript_conceal_static') ? 'conceal cchar='.g:javascript_conceal_static : '') exe 'syntax keyword jsSuper super contained '.(exists('g:javascript_conceal_super') ? 'conceal cchar='.g:javascript_conceal_super : '')
exe 'syntax keyword jsSuper super '.(exists('g:javascript_conceal_super') ? 'conceal cchar='.g:javascript_conceal_super : '')
" Statement Keywords
"" Statement Keywords syntax keyword jsStatement contained break continue with yield debugger
syntax keyword jsStatement break continue with syntax keyword jsConditional if skipwhite skipempty nextgroup=jsParenIfElse
syntax keyword jsConditional if else switch syntax keyword jsConditional else skipwhite skipempty nextgroup=jsCommentMisc,jsIfElseBlock
syntax keyword jsRepeat do while for syntax keyword jsConditional switch skipwhite skipempty nextgroup=jsParenSwitch
syntax keyword jsLabel case default syntax keyword jsRepeat while for skipwhite skipempty nextgroup=jsParenRepeat,jsForAwait
syntax keyword jsKeyword yield syntax keyword jsDo do skipwhite skipempty nextgroup=jsRepeatBlock
syntax keyword jsException try catch throw finally syntax keyword jsLabel contained case default
syntax keyword jsTry try skipwhite skipempty nextgroup=jsTryCatchBlock
syntax keyword jsFinally contained finally skipwhite skipempty nextgroup=jsFinallyBlock
syntax keyword jsCatch contained catch skipwhite skipempty nextgroup=jsParenCatch
syntax keyword jsException throw
syntax keyword jsAsyncKeyword async await syntax keyword jsAsyncKeyword async await
syntax match jsSwitchColon contained /:/ skipwhite skipempty nextgroup=jsSwitchBlock
syntax keyword jsGlobalObjects Array Boolean Date Function Iterator Number Object Symbol Map WeakMap Set RegExp String Proxy Promise Buffer ParallelArray ArrayBuffer DataView Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray JSON Math console document window Intl Collator DateTimeFormat NumberFormat " Keywords
syntax keyword jsGlobalObjects Array Boolean Date Function Iterator Number Object Symbol Map WeakMap Set RegExp String Proxy Promise Buffer ParallelArray ArrayBuffer DataView Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray JSON Math console document window Intl Collator DateTimeFormat NumberFormat fetch
syntax keyword jsGlobalNodeObjects module exports global process
syntax match jsGlobalNodeObjects /require/ containedin=jsFuncCall
syntax keyword jsExceptions Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError syntax keyword jsExceptions Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError
syntax keyword jsBuiltins decodeURI decodeURIComponent encodeURI encodeURIComponent eval isFinite isNaN parseFloat parseInt uneval syntax keyword jsBuiltins decodeURI decodeURIComponent encodeURI encodeURIComponent eval isFinite isNaN parseFloat parseInt uneval
" DISCUSS: How imporant is this, really? Perhaps it should be linked to an error because I assume the keywords are reserved?
syntax keyword jsFutureKeys abstract enum int short boolean interface byte long char final native synchronized float package throws goto private transient implements protected volatile double public
syntax keyword jsFutureKeys abstract enum int short boolean interface byte long char final native synchronized float package throws goto private transient debugger implements protected volatile double public " DISCUSS: Should we really be matching stuff like this?
"" DOM/HTML/CSS specified things
" DOM2 Objects " DOM2 Objects
syntax keyword jsGlobalObjects DOMImplementation DocumentFragment Document Node NodeList NamedNodeMap CharacterData Attr Element Text Comment CDATASection DocumentType Notation Entity EntityReference ProcessingInstruction syntax keyword jsGlobalObjects DOMImplementation DocumentFragment Document Node NodeList NamedNodeMap CharacterData Attr Element Text Comment CDATASection DocumentType Notation Entity EntityReference ProcessingInstruction
syntax keyword jsExceptions DOMException syntax keyword jsExceptions DOMException
" DISCUSS: Should we really be matching stuff like this?
" DOM2 CONSTANT " DOM2 CONSTANT
syntax keyword jsDomErrNo INDEX_SIZE_ERR DOMSTRING_SIZE_ERR HIERARCHY_REQUEST_ERR WRONG_DOCUMENT_ERR INVALID_CHARACTER_ERR NO_DATA_ALLOWED_ERR NO_MODIFICATION_ALLOWED_ERR NOT_FOUND_ERR NOT_SUPPORTED_ERR INUSE_ATTRIBUTE_ERR INVALID_STATE_ERR SYNTAX_ERR INVALID_MODIFICATION_ERR NAMESPACE_ERR INVALID_ACCESS_ERR syntax keyword jsDomErrNo INDEX_SIZE_ERR DOMSTRING_SIZE_ERR HIERARCHY_REQUEST_ERR WRONG_DOCUMENT_ERR INVALID_CHARACTER_ERR NO_DATA_ALLOWED_ERR NO_MODIFICATION_ALLOWED_ERR NOT_FOUND_ERR NOT_SUPPORTED_ERR INUSE_ATTRIBUTE_ERR INVALID_STATE_ERR SYNTAX_ERR INVALID_MODIFICATION_ERR NAMESPACE_ERR INVALID_ACCESS_ERR
syntax keyword jsDomNodeConsts ELEMENT_NODE ATTRIBUTE_NODE TEXT_NODE CDATA_SECTION_NODE ENTITY_REFERENCE_NODE ENTITY_NODE PROCESSING_INSTRUCTION_NODE COMMENT_NODE DOCUMENT_NODE DOCUMENT_TYPE_NODE DOCUMENT_FRAGMENT_NODE NOTATION_NODE syntax keyword jsDomNodeConsts ELEMENT_NODE ATTRIBUTE_NODE TEXT_NODE CDATA_SECTION_NODE ENTITY_REFERENCE_NODE ENTITY_NODE PROCESSING_INSTRUCTION_NODE COMMENT_NODE DOCUMENT_NODE DOCUMENT_TYPE_NODE DOCUMENT_FRAGMENT_NODE NOTATION_NODE
" DISCUSS: Should we really be special matching on these props?
" HTML events and internal variables " HTML events and internal variables
syntax case ignore
syntax keyword jsHtmlEvents onblur onclick oncontextmenu ondblclick onfocus onkeydown onkeypress onkeyup onmousedown onmousemove onmouseout onmouseover onmouseup onresize syntax keyword jsHtmlEvents onblur onclick oncontextmenu ondblclick onfocus onkeydown onkeypress onkeyup onmousedown onmousemove onmouseout onmouseover onmouseup onresize
syntax case match
" Follow stuff should be highligh within a special context " Code blocks
" While it can't be handled with context depended with Regex based highlight syntax region jsBracket matchgroup=jsBrackets start=/\[/ end=/\]/ contains=@jsExpression extend fold
" So, turn it off by default syntax region jsParen matchgroup=jsParens start=/(/ end=/)/ contains=@jsAll extend fold
if exists("javascript_enable_domhtmlcss") syntax region jsParenDecorator contained matchgroup=jsParensDecorator start=/(/ end=/)/ contains=@jsAll skipwhite skipempty nextgroup=jsCommentMisc extend fold
syntax region jsParenIfElse contained matchgroup=jsParensIfElse start=/(/ end=/)/ contains=@jsAll skipwhite skipempty nextgroup=jsCommentMisc,jsIfElseBlock extend fold
" DOM2 things syntax region jsParenRepeat contained matchgroup=jsParensRepeat start=/(/ end=/)/ contains=@jsAll skipwhite skipempty nextgroup=jsCommentMisc,jsRepeatBlock extend fold
syntax match jsDomElemAttrs contained /\%(nodeName\|nodeValue\|nodeType\|parentNode\|childNodes\|firstChild\|lastChild\|previousSibling\|nextSibling\|attributes\|ownerDocument\|namespaceURI\|prefix\|localName\|tagName\)\>/ syntax region jsParenSwitch contained matchgroup=jsParensSwitch start=/(/ end=/)/ contains=@jsAll skipwhite skipempty nextgroup=jsSwitchBlock extend fold
syntax match jsDomElemFuncs contained /\%(insertBefore\|replaceChild\|removeChild\|appendChild\|hasChildNodes\|cloneNode\|normalize\|isSupported\|hasAttributes\|getAttribute\|setAttribute\|removeAttribute\|getAttributeNode\|setAttributeNode\|removeAttributeNode\|getElementById\|getElementsByClassName\|getElementsByTagName\|querySelector\|querySelectorAll\|getAttributeNS\|setAttributeNS\|removeAttributeNS\|getAttributeNodeNS\|setAttributeNodeNS\|getElementsByTagNameNS\|hasAttribute\|hasAttributeNS\)\>/ nextgroup=jsParen skipwhite syntax region jsParenCatch contained matchgroup=jsParensCatch start=/(/ end=/)/ skipwhite skipempty nextgroup=jsTryCatchBlock extend fold
" HTML things syntax region jsFuncArgs contained matchgroup=jsFuncParens start=/(/ end=/)/ contains=jsFuncArgCommas,jsComment,jsFuncArgExpression,jsDestructuringBlock,jsRestExpression,jsFlowArgumentDef skipwhite skipempty nextgroup=jsCommentFunction,jsFuncBlock,jsFlowReturn extend fold
syntax match jsHtmlElemAttrs contained /\%(className\|clientHeight\|clientLeft\|clientTop\|clientWidth\|dir\|id\|innerHTML\|lang\|length\|offsetHeight\|offsetLeft\|offsetParent\|offsetTop\|offsetWidth\|scrollHeight\|scrollLeft\|scrollTop\|scrollWidth\|style\|tabIndex\|title\)\>/ syntax region jsClassBlock contained matchgroup=jsClassBraces start=/{/ end=/}/ contains=jsClassFuncName,jsClassMethodType,jsArrowFunction,jsArrowFuncArgs,jsComment,jsGenerator,jsDecorator,jsClassProperty,jsClassPropertyComputed,jsClassStringKey,jsNoise extend fold
syntax match jsHtmlElemFuncs contained /\%(blur\|click\|focus\|scrollIntoView\|addEventListener\|dispatchEvent\|removeEventListener\|item\)\>/ nextgroup=jsParen skipwhite syntax region jsFuncBlock contained matchgroup=jsFuncBraces start=/{/ end=/}/ contains=@jsAll extend fold
syntax region jsIfElseBlock contained matchgroup=jsIfElseBraces start=/{/ end=/}/ contains=@jsAll extend fold
" CSS Styles in JavaScript syntax region jsBlock contained matchgroup=jsBraces start=/{/ end=/}/ contains=@jsAll extend fold
syntax keyword jsCssStyles contained color font fontFamily fontSize fontSizeAdjust fontStretch fontStyle fontVariant fontWeight letterSpacing lineBreak lineHeight quotes rubyAlign rubyOverhang rubyPosition syntax region jsTryCatchBlock contained matchgroup=jsTryCatchBraces start=/{/ end=/}/ contains=@jsAll skipwhite skipempty nextgroup=jsCatch,jsFinally extend fold
syntax keyword jsCssStyles contained textAlign textAlignLast textAutospace textDecoration textIndent textJustify textJustifyTrim textKashidaSpace textOverflowW6 textShadow textTransform textUnderlinePosition syntax region jsFinallyBlock contained matchgroup=jsFinallyBraces start=/{/ end=/}/ contains=@jsAll extend fold
syntax keyword jsCssStyles contained unicodeBidi whiteSpace wordBreak wordSpacing wordWrap writingMode syntax region jsSwitchBlock contained matchgroup=jsSwitchBraces start=/{/ end=/}/ contains=@jsAll,jsLabel,jsSwitchColon extend fold
syntax keyword jsCssStyles contained bottom height left position right top width zIndex syntax region jsRepeatBlock contained matchgroup=jsRepeatBraces start=/{/ end=/}/ contains=@jsAll extend fold
syntax keyword jsCssStyles contained border borderBottom borderLeft borderRight borderTop borderBottomColor borderLeftColor borderTopColor borderBottomStyle borderLeftStyle borderRightStyle borderTopStyle borderBottomWidth borderLeftWidth borderRightWidth borderTopWidth borderColor borderStyle borderWidth borderCollapse borderSpacing captionSide emptyCells tableLayout syntax region jsDestructuringBlock contained matchgroup=jsDestructuringBraces start=/{/ end=/}/ contains=jsDestructuringProperty,jsDestructuringAssignment,jsDestructuringNoise,jsDestructuringPropertyComputed,jsSpreadExpression extend fold
syntax keyword jsCssStyles contained margin marginBottom marginLeft marginRight marginTop outline outlineColor outlineStyle outlineWidth padding paddingBottom paddingLeft paddingRight paddingTop syntax region jsDestructuringArray contained matchgroup=jsDestructuringBraces start=/\[/ end=/\]/ contains=jsDestructuringPropertyValue,jsNoise,jsDestructuringProperty,jsSpreadExpression extend fold
syntax keyword jsCssStyles contained listStyle listStyleImage listStylePosition listStyleType syntax region jsObject matchgroup=jsObjectBraces start=/{/ end=/}/ contains=jsObjectKey,jsObjectKeyString,jsObjectKeyComputed,jsObjectSeparator,jsObjectFuncName,jsObjectMethodType,jsGenerator,jsComment,jsObjectStringKey,jsSpreadExpression,jsDecorator extend fold
syntax keyword jsCssStyles contained background backgroundAttachment backgroundColor backgroundImage backgroundPosition backgroundPositionX backgroundPositionY backgroundRepeat syntax region jsTernaryIf matchgroup=jsTernaryIfOperator start=/?/ end=/\%(:\|[\}]\@=\)/ contains=@jsExpression
syntax keyword jsCssStyles contained clear clip clipBottom clipLeft clipRight clipTop content counterIncrement counterReset cssFloat cursor direction display filter layoutGrid layoutGridChar layoutGridLine layoutGridMode layoutGridType syntax region jsSpreadExpression contained matchgroup=jsSpreadOperator start=/\.\.\./ end=/[,}\]]\@=/ contains=@jsExpression
syntax keyword jsCssStyles contained marks maxHeight maxWidth minHeight minWidth opacity MozOpacity overflow overflowX overflowY verticalAlign visibility zoom cssText syntax region jsRestExpression contained matchgroup=jsRestOperator start=/\.\.\./ end=/[,)]\@=/
syntax keyword jsCssStyles contained scrollbar3dLightColor scrollbarArrowColor scrollbarBaseColor scrollbarDarkShadowColor scrollbarFaceColor scrollbarHighlightColor scrollbarShadowColor scrollbarTrackColor syntax region jsTernaryIf matchgroup=jsTernaryIfOperator start=/?/ end=/\%(:\|[\}]\@=\)/ contains=@jsExpression
" Highlight ways syntax match jsGenerator contained /\*/ skipwhite skipempty nextgroup=jsFuncName,jsFuncArgs
syntax match jsDotNotation "\." nextgroup=jsPrototype,jsDomElemAttrs,jsDomElemFuncs,jsHtmlElemAttrs,jsHtmlElemFuncs syntax match jsFuncName contained /\<[a-zA-Z_$][0-9a-zA-Z_$]*\>/ skipwhite skipempty nextgroup=jsFuncArgs,jsFlowFunctionGroup
syntax match jsDotNotation "\.style\." nextgroup=jsCssStyles syntax region jsFuncArgExpression contained matchgroup=jsFuncArgOperator start=/=/ end=/[,)]\@=/ contains=@jsExpression extend
endif "DOM/HTML/CSS
"" end DOM/HTML/CSS specified things
"" Code blocks
syntax cluster jsExpression contains=jsComment,jsLineComment,jsBlockComment,jsTaggedTemplate,jsTemplateString,jsStringD,jsStringS,jsRegexpString,jsNumber,jsFloat,jsThis,jsStatic,jsSuper,jsOperator,jsBooleanTrue,jsBooleanFalse,jsNull,jsFunction,jsArrowFunction,jsGlobalObjects,jsExceptions,jsFutureKeys,jsDomErrNo,jsDomNodeConsts,jsHtmlEvents,jsDotNotation,jsBracket,jsParen,jsBlock,jsFuncCall,jsUndefined,jsNan,jsKeyword,jsStorageClass,jsPrototype,jsBuiltins,jsNoise,jsCommonJS,jsImportContainer,jsExportContainer,jsArgsObj,jsDecorator,jsAsyncKeyword,jsClassDefinition,jsArrowFunction,jsArrowFuncArgs
syntax cluster jsAll contains=@jsExpression,jsLabel,jsConditional,jsRepeat,jsReturn,jsStatement,jsTernaryIf,jsException
syntax region jsBracket matchgroup=jsBrackets start="\[" end="\]" contains=@jsAll,jsParensErrB,jsParensErrC,jsBracket,jsParen,jsBlock,@htmlPreproc fold
syntax region jsParen matchgroup=jsParens start="(" end=")" contains=@jsAll,jsOf,jsParensErrA,jsParensErrC,jsParen,jsBracket,jsBlock,@htmlPreproc fold extend
syntax region jsClassBlock matchgroup=jsClassBraces start="{" end="}" contains=jsFuncName,jsClassMethodDefinitions,jsOperator,jsArrowFunction,jsArrowFuncArgs,jsComment,jsBlockComment,jsLineComment contained fold
syntax region jsFuncBlock matchgroup=jsFuncBraces start="{" end="}" contains=@jsAll,jsParensErrA,jsParensErrB,jsParen,jsBracket,jsBlock,@htmlPreproc,jsClassDefinition fold extend
syntax region jsBlock matchgroup=jsBraces start="{" end="}" contains=@jsAll,jsParensErrA,jsParensErrB,jsParen,jsBracket,jsBlock,jsObjectKey,@htmlPreproc,jsClassDefinition fold extend
syntax region jsTernaryIf matchgroup=jsTernaryIfOperator start=+?+ end=+:+ contains=@jsExpression,jsTernaryIf
"" catch errors caused by wrong parenthesis
syntax match jsParensError ")\|}\|\]"
syntax match jsParensErrA contained "\]"
syntax match jsParensErrB contained ")"
syntax match jsParensErrC contained "}"
syntax match jsFuncArgDestructuring contained /\({\|}\|=\|:\|\[\|\]\)/ extend
exe 'syntax match jsFunction /\<function\>/ nextgroup=jsGenerator,jsFuncName,jsFuncArgs skipwhite '.(exists('g:javascript_conceal_function') ? 'conceal cchar='.g:javascript_conceal_function : '')
exe 'syntax match jsArrowFunction /=>/ skipwhite nextgroup=jsFuncBlock contains=jsFuncBraces '.(exists('g:javascript_conceal_arrow_function') ? 'conceal cchar='.g:javascript_conceal_arrow_function : '')
syntax match jsGenerator contained '\*' nextgroup=jsFuncName,jsFuncArgs skipwhite
syntax match jsFuncName contained /\<[a-zA-Z_$][0-9a-zA-Z_$]*/ nextgroup=jsFuncArgs skipwhite
syntax region jsFuncArgs contained matchgroup=jsFuncParens start='(' end=')' contains=jsFuncArgCommas,jsFuncArgRest,jsComment,jsLineComment,jsStringS,jsStringD,jsNumber,jsFuncArgDestructuring,jsArrowFunction,jsParen,jsArrowFuncArgs nextgroup=jsFuncBlock keepend skipwhite skipempty
syntax match jsFuncArgCommas contained ',' syntax match jsFuncArgCommas contained ','
syntax match jsFuncArgRest contained /\%(\.\.\.[a-zA-Z_$][0-9a-zA-Z_$]*\))/ contains=jsFuncArgRestDots syntax keyword jsArguments contained arguments
syntax match jsFuncArgRestDots contained /\.\.\./ syntax keyword jsForAwait contained await skipwhite skipempty nextgroup=jsParenRepeat
" Matches a single keyword argument with no parens " Matches a single keyword argument with no parens
syntax match jsArrowFuncArgs /\k\+\s*\%(=>\)\@=/ skipwhite contains=jsFuncArgs nextgroup=jsArrowFunction extend syntax match jsArrowFuncArgs /\k\+\s*\%(=>\)\@=/ skipwhite contains=jsFuncArgs skipwhite skipempty nextgroup=jsArrowFunction extend
" Matches a series of arguments surrounded in parens " Matches a series of arguments surrounded in parens
syntax match jsArrowFuncArgs /([^()]*)\s*\(=>\)\@=/ skipempty skipwhite contains=jsFuncArgs nextgroup=jsArrowFunction extend syntax match jsArrowFuncArgs /([^()]*)\s*\(=>\)\@=/ contains=jsFuncArgs skipempty skipwhite nextgroup=jsArrowFunction extend
exe 'syntax match jsFunction /\<function\>/ skipwhite skipempty nextgroup=jsGenerator,jsFuncName,jsFuncArgs skipwhite '.(exists('g:javascript_conceal_function') ? 'conceal cchar='.g:javascript_conceal_function : '')
exe 'syntax match jsArrowFunction /=>/ skipwhite skipempty nextgroup=jsFuncBlock,jsCommentFunction '.(exists('g:javascript_conceal_arrow_function') ? 'conceal cchar='.g:javascript_conceal_arrow_function : '')
" Classes
syntax keyword jsClassKeywords contained extends class
syntax match jsClassNoise contained /\./
syntax match jsClassMethodType contained /\%(get\|set\|static\|async\)\%( \k\+\)\@=/ skipwhite skipempty nextgroup=jsFuncName,jsClassProperty
syntax match jsClassDefinition /\<class\>\%( [a-zA-Z_$][0-9a-zA-Z_$ \n.]*\)*/ contains=jsClassKeywords,jsClassNoise skipwhite skipempty nextgroup=jsCommentClass,jsClassBlock,jsFlowClassGroup
syntax match jsClassProperty contained /\<[0-9a-zA-Z_$]*\>\(\s*=\)\@=/ skipwhite skipempty nextgroup=jsClassValue
syntax region jsClassValue contained start=/=/ end=/\%(;\|}\|\n\)\@=/ contains=@jsExpression
syntax region jsClassPropertyComputed contained matchgroup=jsBrackets start=/\[/ end=/]/ contains=@jsExpression skipwhite skipempty nextgroup=jsFuncArgs,jsClassValue extend
syntax match jsClassFuncName contained /\<[a-zA-Z_$][0-9a-zA-Z_$]*\>\%(\s*(\)\@=/ skipwhite skipempty nextgroup=jsFuncArgs
syntax region jsClassStringKey contained start=+"+ skip=+\\\("\|$\)+ end=+"\|$+ contains=jsSpecial,@Spell extend skipwhite skipempty nextgroup=jsFuncArgs
syntax region jsClassStringKey contained start=+'+ skip=+\\\('\|$\)+ end=+'\|$+ contains=jsSpecial,@Spell extend skipwhite skipempty nextgroup=jsFuncArgs
" Destructuring
syntax match jsDestructuringPropertyValue contained /\<[0-9a-zA-Z_$]*\>/
syntax match jsDestructuringProperty contained /\<[0-9a-zA-Z_$]*\>\(\s*=\)\@=/ skipwhite skipempty nextgroup=jsDestructuringValue
syntax match jsDestructuringAssignment contained /\<[0-9a-zA-Z_$]*\>\(\s*:\)\@=/ skipwhite skipempty nextgroup=jsDestructuringValueAssignment
syntax region jsDestructuringValue contained start=/=/ end=/[,}\]]\@=/ contains=@jsExpression extend
syntax region jsDestructuringValueAssignment contained start=/:/ end=/[,}=]\@=/ contains=jsDestructuringPropertyValue,jsDestructuringBlock,jsNoise,jsDestructuringNoise skipwhite skipempty nextgroup=jsDestructuringValue extend
syntax match jsDestructuringNoise contained /[,\[\]]/
syntax region jsDestructuringPropertyComputed contained matchgroup=jsBrackets start=/\[/ end=/]/ contains=@jsExpression skipwhite skipempty nextgroup=jsDestructuringValue,jsDestructuringNoise extend fold
" Comments
syntax keyword jsCommentTodo contained TODO FIXME XXX TBD
syntax region jsComment start=/\/\// end=/$/ contains=jsCommentTodo,@Spell extend keepend
syntax region jsComment start=/\/\*/ end=/\*\// contains=jsCommentTodo,@Spell fold extend keepend
syntax region jsEnvComment start=/\%^#!/ end=/$/ display
" Specialized Comments - These are special comment regexes that are used in
" odd places that maintain the proper nextgroup functionality. It sucks we
" can't make jsComment a skippable type of group for nextgroup
syntax region jsCommentFunction contained start=/\/\// end=/$/ contains=jsCommentTodo,@Spell skipwhite skipempty nextgroup=jsFuncBlock,jsFlowReturn extend keepend
syntax region jsCommentFunction contained start=/\/\*/ end=/\*\// contains=jsCommentTodo,@Spell skipwhite skipempty nextgroup=jsFuncBlock,jsFlowReturn fold extend keepend
syntax region jsCommentClass contained start=/\/\// end=/$/ contains=jsCommentTodo,@Spell skipwhite skipempty nextgroup=jsClassBlock,jsFlowClassGroup extend keepend
syntax region jsCommentClass contained start=/\/\*/ end=/\*\// contains=jsCommentTodo,@Spell skipwhite skipempty nextgroup=jsClassBlock,jsFlowClassGroup fold extend keepend
syntax region jsCommentMisc contained start=/\/\// end=/$/ contains=jsCommentTodo,@Spell skipwhite skipempty nextgroup=jsBlock extend keepend
syntax region jsCommentMisc contained start=/\/\*/ end=/\*\// contains=jsCommentTodo,@Spell skipwhite skipempty nextgroup=jsBlock fold extend keepend
" Decorators
syntax match jsDecorator /^\s*@/ nextgroup=jsDecoratorFunction
syntax match jsDecoratorFunction contained /[a-zA-Z_][a-zA-Z0-9_.]*/ nextgroup=jsParenDecorator
if exists("javascript_plugin_jsdoc")
runtime extras/jsdoc.vim
" NGDoc requires JSDoc
if exists("javascript_plugin_ngdoc")
runtime extras/ngdoc.vim
endif
endif
syntax keyword jsClassKeywords extends class contained if exists("javascript_plugin_flow")
syntax match jsClassNoise /\./ contained runtime extras/flow.vim
syntax keyword jsClassMethodDefinitions get set static contained nextgroup=jsFuncName skipwhite skipempty endif
syntax match jsClassDefinition /class [a-zA-Z_$][0-9a-zA-Z_$ \n.]*/ contains=jsClassKeywords,jsClassNoise nextgroup=jsClassBlock skipwhite skipempty
syntax cluster jsExpression contains=jsBracket,jsParen,jsObject,jsBlock,jsTernaryIf,jsTaggedTemplate,jsTemplateString,jsString,jsRegexpString,jsNumber,jsFloat,jsOperator,jsBooleanTrue,jsBooleanFalse,jsNull,jsFunction,jsArrowFunction,jsGlobalObjects,jsExceptions,jsFutureKeys,jsDomErrNo,jsDomNodeConsts,jsHtmlEvents,jsFuncCall,jsUndefined,jsNan,jsPrototype,jsBuiltins,jsNoise,jsClassDefinition,jsArrowFunction,jsArrowFuncArgs,jsParensError,jsComment,jsArguments,jsThis,jsSuper,jsDo
syntax cluster jsAll contains=@jsExpression,jsExportContainer,jsImportContainer,jsStorageClass,jsConditional,jsRepeat,jsReturn,jsStatement,jsException,jsTry,jsAsyncKeyword
" Define the default highlighting. " Define the default highlighting.
" For version 5.7 and earlier: only when not done already " For version 5.7 and earlier: only when not done already
@ -227,25 +240,20 @@ if version >= 508 || !exists("did_javascript_syn_inits")
else else
command -nargs=+ HiLink hi def link <args> command -nargs=+ HiLink hi def link <args>
endif endif
HiLink jsFuncArgRest Special
HiLink jsComment Comment HiLink jsComment Comment
HiLink jsLineComment Comment
HiLink jsEnvComment PreProc HiLink jsEnvComment PreProc
HiLink jsBlockComment Comment HiLink jsParensIfElse jsParens
HiLink jsParensRepeat jsParens
HiLink jsParensSwitch jsParens
HiLink jsParensCatch jsParens
HiLink jsCommentTodo Todo HiLink jsCommentTodo Todo
HiLink jsCvsTag Function HiLink jsString String
HiLink jsDocTags Special HiLink jsObjectKeyString String
HiLink jsDocSeeTag Function
HiLink jsDocType Type
HiLink jsDocTypeBrackets jsDocType
HiLink jsDocTypeRecord jsDocType
HiLink jsDocTypeNoParam Type
HiLink jsDocParam Label
HiLink jsStringS String
HiLink jsStringD String
HiLink jsTemplateString String HiLink jsTemplateString String
HiLink jsObjectStringKey String
HiLink jsClassStringKey String
HiLink jsTaggedTemplate StorageClass HiLink jsTaggedTemplate StorageClass
HiLink jsTernaryIfOperator Conditional HiLink jsTernaryIfOperator Operator
HiLink jsRegexpString String HiLink jsRegexpString String
HiLink jsRegexpBoundary SpecialChar HiLink jsRegexpBoundary SpecialChar
HiLink jsRegexpQuantifier SpecialChar HiLink jsRegexpQuantifier SpecialChar
@ -261,28 +269,30 @@ if version >= 508 || !exists("did_javascript_syn_inits")
HiLink jsLabel Label HiLink jsLabel Label
HiLink jsReturn Statement HiLink jsReturn Statement
HiLink jsRepeat Repeat HiLink jsRepeat Repeat
HiLink jsDo Repeat
HiLink jsStatement Statement HiLink jsStatement Statement
HiLink jsException Exception HiLink jsException Exception
HiLink jsKeyword Keyword HiLink jsTry Exception
HiLink jsFinally Exception
HiLink jsCatch Exception
HiLink jsAsyncKeyword Keyword HiLink jsAsyncKeyword Keyword
HiLink jsForAwait Keyword
HiLink jsArrowFunction Type HiLink jsArrowFunction Type
HiLink jsFunction Type HiLink jsFunction Type
HiLink jsGenerator jsFunction HiLink jsGenerator jsFunction
HiLink jsArrowFuncArgs jsFuncArgs HiLink jsArrowFuncArgs jsFuncArgs
HiLink jsFuncName Function HiLink jsFuncName Function
HiLink jsArgsObj Special HiLink jsClassFuncName jsFuncName
HiLink jsObjectFuncName Function
HiLink jsArguments Special
HiLink jsError Error HiLink jsError Error
HiLink jsParensError Error HiLink jsParensError Error
HiLink jsParensErrA Error
HiLink jsParensErrB Error
HiLink jsParensErrC Error
HiLink jsOperator Operator HiLink jsOperator Operator
HiLink jsOf Operator HiLink jsOf Operator
HiLink jsStorageClass StorageClass HiLink jsStorageClass StorageClass
HiLink jsClassKeywords Structure HiLink jsClassKeywords Keyword
HiLink jsThis Special HiLink jsThis Special
HiLink jsStatic Special HiLink jsSuper Constant
HiLink jsSuper Special
HiLink jsNan Number HiLink jsNan Number
HiLink jsNull Type HiLink jsNull Type
HiLink jsUndefined Type HiLink jsUndefined Type
@ -290,6 +300,7 @@ if version >= 508 || !exists("did_javascript_syn_inits")
HiLink jsFloat Float HiLink jsFloat Float
HiLink jsBooleanTrue Boolean HiLink jsBooleanTrue Boolean
HiLink jsBooleanFalse Boolean HiLink jsBooleanFalse Boolean
HiLink jsObjectColon jsNoise
HiLink jsNoise Noise HiLink jsNoise Noise
HiLink jsBrackets Noise HiLink jsBrackets Noise
HiLink jsParens Noise HiLink jsParens Noise
@ -298,18 +309,47 @@ if version >= 508 || !exists("did_javascript_syn_inits")
HiLink jsFuncParens Noise HiLink jsFuncParens Noise
HiLink jsClassBraces Noise HiLink jsClassBraces Noise
HiLink jsClassNoise Noise HiLink jsClassNoise Noise
HiLink jsIfElseBraces jsBraces
HiLink jsTryCatchBraces jsBraces
HiLink jsModuleBraces jsBraces
HiLink jsObjectBraces Noise
HiLink jsObjectSeparator Noise
HiLink jsFinallyBraces jsBraces
HiLink jsRepeatBraces jsBraces
HiLink jsSwitchBraces jsBraces
HiLink jsExportBraces jsBraces
HiLink jsSpecial Special HiLink jsSpecial Special
HiLink jsTemplateVar Special HiLink jsTemplateVar Special
HiLink jsTemplateBraces jsBraces HiLink jsTemplateBraces jsBraces
HiLink jsGlobalObjects Special HiLink jsGlobalObjects Constant
HiLink jsExceptions Special HiLink jsGlobalNodeObjects Constant
HiLink jsFutureKeys Special HiLink jsExceptions Constant
HiLink jsBuiltins Special HiLink jsBuiltins Constant
HiLink jsModules Include HiLink jsModuleKeywords Include
HiLink jsModuleWords Include HiLink jsModuleOperators Include
HiLink jsModuleDefault Include
HiLink jsDecorator Special HiLink jsDecorator Special
HiLink jsFuncArgRestDots Noise HiLink jsDecoratorFunction Function
HiLink jsFuncArgDestructuring Noise HiLink jsParensDecorator jsParens
HiLink jsFuncArgOperator jsFuncArgs
HiLink jsModuleAsterisk Noise
HiLink jsClassProperty jsObjectKey
HiLink jsSpreadOperator Operator
HiLink jsRestOperator Operator
HiLink jsRestExpression jsFuncArgs
HiLink jsSwitchColon Noise
HiLink jsClassMethodType Type
HiLink jsObjectMethodType Type
HiLink jsClassDefinition jsFuncName
HiLink jsDestructuringBraces Noise
HiLink jsDestructuringProperty jsFuncArgs
HiLink jsDestructuringAssignment jsObjectKey
HiLink jsDestructuringNoise Noise
HiLink jsCommentFunction jsComment
HiLink jsCommentClass jsComment
HiLink jsCommentMisc jsComment
HiLink jsDomErrNo Constant HiLink jsDomErrNo Constant
HiLink jsDomNodeConsts Constant HiLink jsDomNodeConsts Constant
@ -322,14 +362,12 @@ if version >= 508 || !exists("did_javascript_syn_inits")
HiLink jsCssStyles Label HiLink jsCssStyles Label
HiLink jsClassMethodDefinitions Type
delcommand HiLink delcommand HiLink
endif endif
" Define the htmlJavaScript for HTML syntax html.vim " Define the htmlJavaScript for HTML syntax html.vim
syntax cluster htmlJavaScript contains=@jsAll,jsBracket,jsParen,jsBlock syntax cluster htmlJavaScript contains=@jsAll
syntax cluster javaScriptExpression contains=@jsAll,jsBracket,jsParen,jsBlock,@htmlPreproc syntax cluster javaScriptExpression contains=@jsAll
" Vim's default html.vim highlights all javascript as 'Special' " Vim's default html.vim highlights all javascript as 'Special'
hi! def link javaScript NONE hi! def link javaScript NONE

Loading…
Cancel
Save