This commit is contained in:
Adam Stankiewicz 2016-07-30 13:18:40 +02:00
parent f42e1f477c
commit ab61d2ac8e
No known key found for this signature in database
GPG Key ID: A62480DCEAC884DF
14 changed files with 368 additions and 537 deletions

View File

@ -61,7 +61,7 @@ If you need full functionality of any plugin, please use it directly with your p
- [haxe](https://github.com/yaymukund/vim-haxe) (syntax, ftdetect)
- [html5](https://github.com/othree/html5.vim) (syntax, indent, autoload, ftplugin)
- [jasmine](https://github.com/glanotte/vim-jasmine) (syntax, ftdetect)
- [javascript](https://github.com/pangloss/vim-javascript) (syntax, indent, ftplugin, ftdetect, extras)
- [javascript](https://github.com/pangloss/vim-javascript) (syntax, indent, ftdetect, ftplugin, extras)
- [json](https://github.com/elzr/vim-json) (syntax, indent, ftplugin, ftdetect)
- [jst](https://github.com/briancollins/vim-jst) (syntax, indent, ftdetect)
- [jsx](https://github.com/mxw/vim-jsx) (ftdetect, after)

View File

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

View File

@ -5,7 +5,6 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'jsx') == -1
"
" Language: JSX (JavaScript)
" Maintainer: Max Wang <mxawng@gmail.com>
" Depends: pangloss/vim-javascript
"
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

View File

@ -5,10 +5,12 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'jsx') == -1
"
" Language: JSX (JavaScript)
" Maintainer: Max Wang <mxawng@gmail.com>
" Depends: pangloss/vim-javascript
"
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Save the current JavaScript indentexpr.
let b:jsx_js_indentexpr = &indentexpr
" Prologue; load in XML indentation.
if exists('b:did_indent')
let s:did_indent=b:did_indent
@ -51,19 +53,31 @@ fu! SynXMLish(syns)
return SynAttrXMLish(get(a:syns, -1))
endfu
" Check if a synstack has any XMLish attribute.
fu! SynXMLishAny(syns)
for synattr in a:syns
if SynAttrXMLish(synattr)
return 1
endif
endfor
return 0
endfu
" Check if a synstack denotes the end of a JSX block.
fu! SynJSXBlockEnd(syns)
return get(a:syns, -1) == 'jsBraces' && SynAttrXMLish(get(a:syns, -2))
return get(a:syns, -1) =~ '\%(js\|javascript\)Braces' &&
\ SynAttrXMLish(get(a:syns, -2))
endfu
" Determine how many jsxRegions deep a synstack is.
fu! SynJSXDepth(syns)
return len(filter(copy(a:syns), 'v:val ==# "jsxRegion"'))
endfu
" Check whether `cursyn' continues the same jsxRegion as `prevsyn'.
fu! SynJSXContinues(cursyn, prevsyn)
let curdepth = SynJSXDepth(a:cursyn)
let prevdepth = SynJSXDepth(a:prevsyn)
" In most places, we expect the nesting depths to be the same between any
" two consecutive positions within a jsxRegion (e.g., between a parent and
" child node, between two JSX attributes, etc.). The exception is between
" sibling nodes, where after a completed element (with depth N), we return
" to the parent's nesting (depth N - 1). This case is easily detected,
" since it is the only time when the top syntax element in the synstack is
" jsxRegion---specifically, the jsxRegion corresponding to the parent.
return prevdepth == curdepth ||
\ (prevdepth == curdepth + 1 && get(a:cursyn, -1) ==# 'jsxRegion')
endfu
" Cleverly mix JS and XML indentation.
@ -71,9 +85,12 @@ fu! GetJsxIndent()
let cursyn = SynSOL(v:lnum)
let prevsyn = SynEOL(v:lnum - 1)
" Use XML indenting if the syntax at the end of the previous line was either
" JSX or was the closing brace of a jsBlock whose parent syntax was JSX.
if (SynXMLish(prevsyn) || SynJSXBlockEnd(prevsyn)) && SynXMLishAny(cursyn)
" Use XML indenting iff:
" - the syntax at the end of the previous line was either JSX or was the
" closing brace of a jsBlock whose parent syntax was JSX; and
" - the current line continues the same jsxRegion as the previous line.
if (SynXMLish(prevsyn) || SynJSXBlockEnd(prevsyn)) &&
\ SynJSXContinues(cursyn, prevsyn)
let ind = XmlIndentGet(v:lnum, 0)
" Align '/>' and '>' with '<' for multiline tags.
@ -86,7 +103,13 @@ fu! GetJsxIndent()
let ind = ind + &sw
endif
else
let ind = GetJavascriptIndent()
if len(b:jsx_js_indentexpr)
" Invoke the base JS package's custom indenter. (For vim-javascript,
" e.g., this will be GetJavascriptIndent().)
let ind = eval(b:jsx_js_indentexpr)
else
let ind = cindent(v:lnum)
endif
endif
return ind

View File

@ -48,7 +48,7 @@ syn region jsxChild contained start=+{+ end=++ contains=jsBlock,javascriptBlock
" preceding it, to avoid conflicts with, respectively, the left shift operator
" and generic Flow type annotations (http://flowtype.org/).
syn region jsxRegion
\ contains=@XMLSyntax,jsxRegion,jsxChild,jsBlock,javascriptBlock
\ contains=@Spell,@XMLSyntax,jsxRegion,jsxChild,jsBlock,javascriptBlock
\ start=+\%(<\|\w\)\@<!<\z([a-zA-Z][a-zA-Z0-9:\-.]*\)+
\ skip=+<!--\_.\{-}-->+
\ end=+</\z1\_\s\{-}>+

View File

@ -29,6 +29,8 @@ function! s:is_absolute(path)
return a:path[0] == '/' || a:path =~ '[A-Z]\+:'
endfunction
CompilerSet errorformat+=%-G%\\s%#Compiling%.%#
let s:local_manifest = findfile(s:cargo_manifest_name, '.;')
if s:local_manifest != ''
let s:local_manifest = fnamemodify(s:local_manifest, ':p:h').'/'

View File

@ -228,3 +228,94 @@ if version >= 508 || !exists("did_javascript_syn_inits")
endif
endif
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'javascript') == -1
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 /\k*/ 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
endif

View File

@ -213,3 +213,46 @@ if version >= 508 || !exists("did_javascript_syn_inits")
endif
endif
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'javascript') == -1
"" 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
endif

View File

@ -33,3 +33,10 @@ syntax match jsDocType contained "\%(#\|\$\|\w\|\"\|-\|\.\|:\|\/\)\+" n
syntax match jsDocParam contained "\%(#\|\$\|\w\|\"\|-\|\.\|:\|{\|}\|\/\|\[\|]\|=\)\+"
endif
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'javascript') == -1
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\|\"\|-\|\.\|:\|{\|}\|\/\|\[\|]\|=\)\+"
endif

View File

@ -1,8 +0,0 @@
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'javascript') == -1
setlocal suffixesadd+=.js
if (v:version < 704 || (v:version == 704 && !has('patch002'))) && exists('&regexpengine')
set re=1
end
endif

View File

@ -195,6 +195,11 @@ let b:undo_ftplugin = "
" }}}1
" Code formatting on save
if get(g:, "rustfmt_autosave", 0)
autocmd BufWritePre *.rs call rustfmt#Format()
endif
augroup END
let &cpo = s:save_cpo

View File

@ -60,7 +60,7 @@ if !exists('g:haskell_indent_guard')
endif
setlocal indentexpr=GetHaskellIndent()
setlocal indentkeys=0{,0},0(,0),0[,0],!^F,o,O,0\=,0=where,0=let,0=deriving,0\,,<space>
setlocal indentkeys=0{,0},0(,0),0[,0],!^F,o,O,0\=,0=where,0=let,0=deriving,<space>
function! s:isInBlock(hlstack)
return index(a:hlstack, 'haskellParens') > -1 || index(a:hlstack, 'haskellBrackets') > -1 || index(a:hlstack, 'haskellBlock') > -1
@ -135,8 +135,34 @@ function! GetHaskellIndent()
endif
" comment indentation
if l:prevline =~ '^\s*--'
return match(l:prevline, '\S')
if l:line =~ '^\s*--'
return match(l:prevline, '-- ')
endif
" { foo :: Int
" >>,
"
" |
" ...
" >>,
if l:line =~ '^\s*,'
if s:isInBlock(l:hlstack)
normal! 0
call search(',', 'cW')
let l:n = s:getNesting(s:getHLStack())
call search('[([{]', 'bW')
while l:n != s:getNesting(s:getHLStack())
call search('[([{]', 'bW')
endwhile
return col('.') - 1
else
let l:s = s:indentGuard(match(l:line, ','), l:prevline)
if l:s > -1
return l:s
end
endif
endif
" operator at end of previous line
@ -362,32 +388,6 @@ function! GetHaskellIndent()
endif
endif
" { foo :: Int
" >>,
"
" |
" ...
" >>,
if l:line =~ '^\s*,'
if s:isInBlock(l:hlstack)
normal! 0
call search(',', 'cW')
let l:n = s:getNesting(s:getHLStack())
call search('[(\[{]', 'bW')
while l:n != s:getNesting(s:getHLStack())
call search('[(\[{]', 'bW')
endwhile
return col('.') - 1
else
let l:s = s:indentGuard(match(l:line, ','), l:prevline)
if l:s > -1
return l:s
end
endif
endif
" |
" ...
" >>|

View File

@ -2,24 +2,23 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'javascript') ==
" Vim indent file
" Language: Javascript
" Maintainer: vim-javascript community
" URL: https://github.com/pangloss/vim-javascript
" Acknowledgement: Based off of vim-ruby maintained by Nikolai Weibull http://vim-ruby.rubyforge.org
" 0. Initialization {{{1
" =================
" Only load this indent file when no other was loaded.
if exists("b:did_indent")
finish
endif
let b:did_indent = 1
setlocal nosmartindent
" Now, set up our indentation expression and keys that trigger it.
setlocal indentexpr=GetJavascriptIndent()
setlocal formatexpr=Fixedgq(v:lnum,v:count)
setlocal indentkeys=0{,0},0),0],0\,*<Return>,:,!^F,o,O,e
setlocal cinoptions+=j1,J1,c1
setlocal nolisp
setlocal indentkeys=0{,0},0),0],:,!^F,o,O,e
setlocal cinoptions+=j1,J1
let b:undo_indent = 'setlocal indentexpr< indentkeys< cinoptions<'
" Only define the function once.
if exists("*GetJavascriptIndent")
@ -40,96 +39,60 @@ else
endfunc
endif
" 1. Variables {{{1
" ============
let s:line_pre = '^\s*\%(\/\*.*\*\/\s*\)*'
let s:js_keywords = s:line_pre . '\%(break\|import\|export\|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\)\>\C'
let s:expr_case = s:line_pre . '\%(\%(case\>.*\)\|default\)\s*:\C'
" Regex of syntax group names that are or delimit string or are comments.
let s:syng_strcom = '\%(string\|regex\|special\|doc\|comment\|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_comment = '\%(comment\|doc\)\c'
" 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 = "line('.') < (prevnonblank(v:lnum) - 2000) ? dummy : s:IsSyn(line('.'),col('.'),'')"
func s:lookForParens(start,end,flags,stop)
try
return searchpair(a:start,'',a:end,a:flags,s:skip_expr,a:stop,300)
func s:lookForParens(start,end,flags,time)
try
return searchpair(a:start,'',a:end,a:flags,s:skip_expr,0,a:time)
catch /E118/
return searchpair(a:start,'',a:end,a:flags,0,a:stop)
return searchpair(a:start,'',a:end,a:flags,0,0)
endtry
endfunc
let s:line_term = '\s*\%(\%(\/\/.*\)\=\|\%(\/\*.*\*\/\s*\)*\)$'
let s:line_term = '\s*\%(\%(:\@<!\/\/.*\)\=\|\%(\/\*.*\*\/\s*\)*\)$'
" Regex that defines continuation lines, not including (, {, or [.
let s:continuation_regex = '\%([*.?:]\|+\@<!+\|-\@<!-\|\*\@<!\/\|=\|||\|&&\)' . s:line_term
" configurable regexes that define continuation lines, not including (, {, or [.
if !exists('g:javascript_opfirst')
let g:javascript_opfirst = '\%([,:?^%]\|\([-/.+]\)\%(\1\|\*\|\/\)\@!\|\*\/\@!\|=>\@!\||\|&\|in\%(stanceof\)\=\>\)\C'
endif
let g:javascript_opfirst = s:line_pre . g:javascript_opfirst
let s:one_line_scope_regex = '\%(\<else\>\|=>\)\C' . s:line_term
if !exists('g:javascript_continuation')
let g:javascript_continuation = '\%([*,.?:^%]\|+\@<!+\|-\@<!-\|\*\@<!\/\|=\||\|&\|\<in\%(stanceof\)\=\)\C'
endif
let g:javascript_continuation .= s:line_term
function s:Onescope(lnum)
if getline(a:lnum) =~ s:one_line_scope_regex
return 1
end
let mypos = col('.')
call cursor(a:lnum, 1)
if search('.*\zs\<\%(while\|for\|if\)\>\s*(\C', 'ce', a:lnum) > 0 &&
\ s:lookForParens('(', ')', 'W', a:lnum) > 0 &&
\ col('.') == strlen(s:RemoveTrailingComments(getline(a:lnum)))
call cursor(a:lnum, mypos)
return 1
else
call cursor(a:lnum, mypos)
return 0
end
function s:Onescope(lnum,text,add)
return a:text =~ '\%(\<else\|\<do\|=>' . (a:add ? '\|\<try\|\<finally' : '' ) . '\)\C' . s:line_term ||
\ (a:add && a:text =~ s:line_pre . s:line_term && getline(s:PrevCodeLine(a:lnum - 1)) =~ ')' . s:line_term) ||
\ (cursor(a:lnum, match(a:text, ')' . s:line_term)) > -1 &&
\ s:lookForParens('(', ')', 'cbW', 100) > 0 &&
\ search((a:add ? '\%(function\*\|[A-Za-z_$][0-9A-Za-z_$]*\)\C' :
\ '\<\%(for\%(\s+each\)\=\|if\|let\|switch\|while\|with\)\C') . '\_s*\%#','bW')) &&
\ (a:add || (expand("<cword>") == 'while' ? !s:lookForParens('\<do\>\C', '\<while\>\C','bW',100) : 1))
endfunction
" Regex that defines blocks.
let s:block_regex = '[{([]' . s:line_term
let s:operator_first = s:line_pre . '\%([,:?]\|\([-/.+*]\)\%(\1\|\*\|\/\)\@!\|||\|&&\)'
let s:var_stmt = s:line_pre . '\%(const\|let\|var\)\s\+\C'
let s:comma_last = ',' . s:line_term
" 2. Auxiliary Functions {{{1
" ======================
" Auxiliary Functions {{{2
" Check if the character at lnum:col is inside a string, comment, or is ascii.
function s:IsInStringOrComment(lnum, col)
return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_strcom
endfunction
" Check if the character at lnum:col is inside a string.
function s:IsInString(lnum, col)
return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_string
endfunction
" Check if the character at lnum:col is inside a multi-line comment.
function s:IsInComment(lnum, col)
return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_comment
function s:IsSyn(lnum, col, reg)
return synIDattr(synID(a:lnum, a:col, 1), 'name') =~? (a:reg != '' ? a:reg : s:syng_strcom)
endfunction
" Find line above 'lnum' that isn't empty, in a comment, or in a string.
function s:PrevNonBlankNonString(lnum)
function s:PrevCodeLine(lnum)
let lnum = prevnonblank(a:lnum)
while lnum > 0
let line = getline(lnum)
let com = match(line, '\%(\/\*.*\)\@<!\*\/') + 1
if s:IsInComment(lnum, com)
call cursor(lnum, com)
let parlnum = search('\%(\/\/.*\)\@<!\/\*', 'nbW')
if parlnum > 0
let lnum = parlnum
end
elseif line !~ '^' . s:line_term && !s:IsInStringOrComment(lnum,1)
if !s:IsSyn(lnum, matchend(getline(lnum), '^\s*[^''"]'),'')
break
endif
let lnum = prevnonblank(lnum - 1)
@ -137,94 +100,6 @@ function s:PrevNonBlankNonString(lnum)
return lnum
endfunction
" Find line above 'lnum' that started the continuation 'lnum' may be part of.
function s:GetMSL(lnum, in_one_line_scope)
" Start on the line we're at and use its indent.
let msl = a:lnum
let lnum = s:PrevNonBlankNonString(a:lnum - 1)
while lnum > 0 && !s:Match(msl,s:line_pre . '[])}]')
" If we have a continuation line, or we're in a string, use line as MSL.
" Otherwise, terminate search as we have found our MSL already.
let line = getline(lnum)
let line2 = getline(msl)
if ((s:Match(lnum,s:continuation_regex) || s:Match(lnum, s:comma_last)) &&
\ !s:Match(lnum, s:expr_case)) || s:IsInString(lnum, strlen(line))
let msl = lnum
if s:Match(lnum, s:line_pre . '[]})]') && !a:in_one_line_scope
call cursor(lnum,1)
let parlnum = s:lookForParens('(\|{\|\[', ')\|}\|\]', 'nbW', 0)
if parlnum > 0
let lnum = parlnum
continue
end
end
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
end
let msl_one_line = s:Onescope(lnum)
if msl_one_line == 0
break
endif
end
let lnum = s:PrevNonBlankNonString(lnum - 1)
endwhile
return msl
endfunction
function s:RemoveTrailingComments(content)
let single = '\/\/\%(.*\)\s*$'
let multi = '\/\*\%(.*\)\*\/\s*$'
return substitute(substitute(substitute(a:content, single, '', ''), multi, '', ''), '\s\+$', '', '')
endfunction
" Find if the string is inside var statement (but not the first string)
function s:InMultiVarStatement(lnum, cont, prev)
let lnum = s:PrevNonBlankNonString(a:lnum - 1)
let cont = a:cont
let prev = a:prev
" let type = synIDattr(synID(lnum, indent(lnum) + 1, 0), 'name')
" loop through previous expressions to find a var statement
while lnum > 0 && (s:Match(lnum, s:comma_last) ||(cont && getline(lnum) =~ s:line_pre . '[]})]') ||
\ s:Match(lnum,s:continuation_regex)) || (prev && (s:Match(prev, s:comma_last) ||
\ s:Match(prev,s:continuation_regex)))
" if the line is a js keyword
if cont
let cont = 0
call cursor(lnum,1)
let parlnum = s:lookForParens('(\|{\|\[', ')\|}\|\]', 'nbW', 0)
if parlnum > 0
let lnum = parlnum
end
end
if s:Match(lnum, 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 s:Match(lnum, s:var_stmt) && (s:Match(lnum, s:comma_last)||s:Match(lnum,s:continuation_regex))
return lnum
endif
" other js keywords, not a var
if !s:Match(lnum, s:comma_last)||!s:Match(lnum,s:continuation_regex)
return 0
end
endif
let lnum = s:PrevNonBlankNonString(lnum - 1)
let prev = prev && lnum > 0 ? prev : 0
endwhile
" beginning of program, not a var
return 0
endfunction
" Check if line 'lnum' has more opening brackets than closing ones.
function s:LineHasOpeningBrackets(lnum)
let open_0 = 0
@ -232,335 +107,96 @@ function s:LineHasOpeningBrackets(lnum)
let open_4 = 0
let line = getline(a:lnum)
let pos = match(line, '[][(){}]', 0)
let last = 0
while pos != -1
if !s:IsInStringOrComment(a:lnum, pos + 1)
if !s:IsSyn(a:lnum, pos + 1, '')
let idx = stridx('(){}[]', line[pos])
if idx % 2 == 0
let open_{idx} = open_{idx} + 1
let last = pos
else
let open_{idx - 1} = open_{idx - 1} - 1
endif
endif
let pos = match(line, '[][(){}]', pos + 1)
endwhile
return (open_0 > 0 ? 1 : (open_0 == 0 ? 0 : 2)) . (open_2 > 0 ? 1 : (open_2 == 0 ? 0 : 2)) . (open_4 > 0 ? 1 : (open_4 == 0 ? 0 : 2))
return [(open_0 > 0 ? 1 : (open_0 == 0 ? 0 : 2)) . (open_2 > 0 ? 1 : (open_2 == 0 ? 0 : 2)) .
\ (open_4 > 0 ? 1 : (open_4 == 0 ? 0 : 2)), last]
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
end
elseif s:InMultiVarStatement(p_lnum, 0, s:PrevNonBlankNonString(p_lnum - 1))
return indent(p_lnum) - s:sw()
endif
return a:ind
endfunction
function s:InOneLineScope(lnum)
let msl = s:GetMSL(a:lnum, 1)
if msl > 0 && s:Onescope(msl)
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:Onescope(msl)
return 0
else
let prev_msl = s:GetMSL(msl - 1, 1)
if s:Onescope(prev_msl)
return prev_msl
endif
endif
endif
return 0
endfunction
" 3. GetJavascriptIndent Function {{{1
" =========================
" }}}
function GetJavascriptIndent()
" 3.1. Setup {{{1
" ----------
" Set up variables for restoring position in file. Could use v:lnum here.
" Avoid use of line('.')/col('.') type functions as the curpos can change
let vcol = col('.')
" 3.2. Work on the current line {{{1
" -----------------------------
let ind = -1
if !exists('b:js_cache')
let b:js_cache = [0,0,0]
end
" Get the current line.
let line = getline(v:lnum)
" previous nonblank line number
let prevline = prevnonblank(v:lnum - 1)
" previous line of code
let lnum = s:PrevNonBlankNonString(v:lnum - 1)
" to not change multiline string values
if line !~ '^[''"`]' && synIDattr(synID(v:lnum, 1, 1), 'name') =~? 'string\|template'
return -1
endif
" If we are in a multi-line comment, cindent does the right thing.
if line !~ '^\%(\/\*\|\s*\/\/\)' && s:IsInComment(v:lnum, 1)
return cindent(v:lnum)
endif
" single opening bracket will assume you want a c style of indenting
if line =~ s:line_pre . '{' && !s:Match(lnum,s:block_regex) &&
\ !s:Match(lnum,s:comma_last)
return cindent(v:lnum)
endif
" cindent each line which has a switch label
if (line =~ s:expr_case)
let s:cpo_switch = &cpo
set cpo+=%
let ind = cindent(v:lnum)
let &cpo = s:cpo_switch
return ind
endif
" If we got a closing bracket on an empty line, find its match and indent
" according to it.
let col = line =~ s:line_pre . '[]})]'
if col > 0
let parlnum = v:lnum
while col
call cursor(parlnum, 1)
let parlnum = s:lookForParens('(\|{\|\[', ')\|}\|\]', 'nbW', 0)
let col = s:Match(parlnum, s:line_pre . '[]})]')
if col
continue
end
if parlnum > 0
let ind = s:InMultiVarStatement(parlnum, 0, 0)|| s:LineHasOpeningBrackets(parlnum) !~ '2' ?
\ indent(parlnum) : indent(s:GetMSL(parlnum, 0))
endif
endwhile
return ind
endif
" If line starts with an operator...
if (line =~ s:operator_first)
if (s:Match(lnum, s:operator_first) || (s:Match(lnum, s:line_pre . '[])}]') &&
\ !(s:Match(v:lnum,s:line_pre . '\.') && s:Match(lnum, ')' . s:line_term))))
" and so does previous line, don't indent
return indent(lnum)
end
let counts = s:LineHasOpeningBrackets(lnum)
if counts =~ '2'
call cursor(lnum, 1)
" Search for the opening tag
let parlnum = s:lookForParens('(\|{\|\[', ')\|}\|\]', 'nbW', 0)
if parlnum > 0
return !s:Match(parlnum, s:operator_first) &&
\ synIDattr(synID(v:lnum, 1, 1), 'name') !~? 'jsbracket\|jsparen\|jsobject' ?
\ indent(lnum) + s:sw() : indent(parlnum)
end
elseif synIDattr(synID(v:lnum, 1, 1), 'name') !~? 'jsbracket\|jsparen\|jsobject'
" otherwise, if not in an key/val;array item;param, indent 1 level
return indent(lnum) + s:sw()
end
" If previous line starts with an operator...
elseif (s:Match(lnum, s:operator_first) && !s:Match(lnum,s:continuation_regex)) ||
\ getline(lnum) =~ '[]})];\=' . s:line_term
let counts = s:LineHasOpeningBrackets(lnum)
if counts =~ '2' && !s:Match(lnum, s:operator_first)
call cursor(lnum, 1)
" Search for the opening tag
let mnum = s:lookForParens('(\|{\|\[', ')\|}\|\]', 'nbW', 0)
if mnum > 0 && (s:Match(mnum, s:operator_first) ||
\ (s:Onescope(s:PrevNonBlankNonString(mnum - 1))) && !s:Match(mnum, s:line_pre . '{'))
return indent(mnum) - s:sw()
end
elseif s:Match(lnum, s:operator_first)
if counts !~ '1'
return indent(lnum) - s:sw()
end
end
end
" 3.3. Work on the previous line. {{{1
" -------------------------------
" If the line is empty and the previous nonblank line was a multi-line
" comment, use that comment's indent. Deduct one char to account for the
" space in ' */'.
if line =~ '^\s*$' && getline(prevline) =~ '\%(\%(^\s*\/\/\|\/\*\).*\)\@<!\*\/' &&
\ s:IsInComment(prevline, 1)
return indent(prevline) - 1
endif
" Find a non-blank, non-multi-line string line above the current line.
" If the line is empty and inside a string, use the previous line.
if line =~ '^\s*$' && lnum != prevline
return indent(prevnonblank(v:lnum))
endif
" At the start of the file use zero indent.
let lnum = s:PrevCodeLine(v:lnum - 1)
if lnum == 0
return 0
endif
" If the previous line ended with a block opening, add a level of indent.
if s:Match(lnum, s:block_regex)
return s:InMultiVarStatement(lnum, 0, 0) || s:LineHasOpeningBrackets(lnum) !~ '2' ?
\ indent(lnum) + s:sw() : indent(s:GetMSL(lnum, 0)) + s:sw()
" start with strings,comments,etc.{{{2
if (line !~ '^[''"`]' && s:IsSyn(v:lnum,1,'string\|template')) ||
\ (line !~ '^\s*[/*]' && s:IsSyn(v:lnum,1,s:syng_comment))
return -1
endif
if line !~ '^\%(\/\*\|\s*\/\/\)' && s:IsSyn(v:lnum,1,s:syng_comment)
return cindent(v:lnum)
endif
" Set up variables for current line.
let line = getline(lnum)
let ind = indent(lnum)
" If the previous line contained an opening bracket, and we are still in it,
" add indent depending on the bracket type.
if s:Match(lnum, '[[({})\]]')
let counts = s:LineHasOpeningBrackets(lnum)
if counts =~ '2'
call cursor(lnum,matchend(s:RemoveTrailingComments(line), '.*\zs[])}]'))
while s:lookForParens('(\|{\|\[', ')\|}\|\]', 'bW', 0) == lnum
call cursor(lnum, matchend(s:RemoveTrailingComments(strpart(line,0,col('.'))), '.*\zs[])}]'))
endwhile
let cur = line('.')
if cur < lnum && !s:InMultiVarStatement(cur,0,0)
return indent(s:GetMSL(cur, 0))
end
elseif counts =~ '1' || s:Onescope(lnum)
return ind + s:sw()
if (line =~ s:expr_case)
let cpo_switch = &cpo
set cpo+=%
let ind = cindent(v:lnum)
let &cpo = cpo_switch
return ind
endif
"}}}
" the containing paren, bracket, curly
let pcounts = [0]
if b:js_cache[0] >= lnum && b:js_cache[0] <= v:lnum && b:js_cache[0] &&
\ (b:js_cache[0] > lnum || map(pcounts,'s:LineHasOpeningBrackets(lnum)')[0][0] !~ '2')
let num = pcounts[0][0] =~ '1' ? lnum : b:js_cache[1]
if pcounts[0][0] =~'1'
call cursor(lnum,pcounts[0][1])
end
end
" 3.4. Work on the MSL line. {{{1
" --------------------------
if s:Match(lnum, s:comma_last) && !s:Match(lnum, s:continuation_regex)
return s:Match(lnum, s:var_stmt) ? indent(lnum) + s:sw() : indent(lnum)
elseif s:Match(s:PrevNonBlankNonString(lnum - 1), s:comma_last)
if !s:Match(lnum, s:comma_last) && s:InMultiVarStatement(lnum,1,0)
return indent(lnum) - s:sw()
end
end
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
call cursor(v:lnum,1)
let syns = synIDattr(synID(v:lnum, 1, 1), 'name')
if line[0] =~ '\s' && syns != ''
let pattern = syns =~? 'funcblock' ? ['{','}'] : syns =~? 'jsparen' ? ['(',')'] : syns =~? 'jsbracket'? ['\[','\]'] :
\ ['(\|{\|\[',')\|}\|\]']
let num = s:lookForParens(pattern[0],pattern[1],'bW',2000)
else
let num = s:lookForParens('(\|{\|\[',')\|}\|\]','bW',2000)
end
end
let b:js_cache = [v:lnum,num,line('.') == v:lnum ? b:js_cache[2] : col('.')]
" most significant part
if line =~ s:line_pre . '[])}]'
return indent(num)
end
let inb = num == 0 ? 1 : s:Onescope(num, strpart(getline(num),0,b:js_cache[2] - 1),1)
let switch_offset = (!inb || num == 0) || expand("<cword>") != 'switch' ? 0 : &cino !~ ':' || !has('float') ? s:sw() :
\ float2nr(str2float(matchstr(&cino,'.*:\zs[-0-9.]*')) * (match(&cino,'.*:\zs[^,]*s') ? s:sw() : 1))
if ((line =~ g:javascript_opfirst ||
\ (getline(lnum) =~ g:javascript_continuation && getline(lnum) !~ s:expr_case)) &&
\ inb) || (s:Onescope(lnum,getline(lnum),0) && line !~ s:line_pre . '{')
return (num > 0 ? indent(num) : -s:sw()) + (s:sw() * 2) + switch_offset
elseif num > 0
return indent(num) + s:sw() + switch_offset
end
return ind
endfunction
" }}}1
let &cpo = s:cpo_save
unlet s:cpo_save
" gq{{{2
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:IsInComment(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
"}}}
" vim: foldmethod=marker:foldlevel=1
endif

View File

@ -14,13 +14,13 @@ if !exists("main_syntax")
let main_syntax = 'javascript'
endif
if !exists('g:javascript_conceal')
let g:javascript_conceal = 0
" Dollar sign is permitted anywhere in an identifier
if v:version > 704 || v:version == 704 && has('patch1142')
syntax iskeyword @,48-57,_,192-255,$
else
setlocal iskeyword+=$
endif
" Dollar sign is permittd anywhere in an identifier
setlocal iskeyword+=$
syntax sync fromstart
" TODO: Figure out what type of casing I need
" syntax case ignore
@ -31,7 +31,8 @@ syntax match jsFuncCall /\k\+\%(\s*(\)\@=/
syntax match jsParensError /[)}\]]/
" Program Keywords
syntax keyword jsStorageClass const var let skipwhite skipempty nextgroup=jsDestructuringBlock,jsDestructuringArray
syntax keyword jsStorageClass const var let skipwhite skipempty nextgroup=jsDestructuringBlock,jsDestructuringArray,jsVariableDef
syntax match jsVariableDef contained /\k\+/ nextgroup=jsFlowDefinition
syntax keyword jsOperator delete instanceof typeof void new in of
syntax match jsOperator /[\!\|\&\+\-\<\>\=\%\/\*\~\^]\{1}/
syntax keyword jsBooleanTrue true
@ -44,7 +45,7 @@ syntax keyword jsModuleOperators contained from
syntax keyword jsModuleOperators contained as
syntax region jsModuleGroup contained matchgroup=jsBraces start=/{/ end=/}/ contains=jsModuleOperators,jsNoise,jsComment
syntax match jsModuleAsterisk contained /*/
syntax keyword jsModuleDefault contained default skipwhite kipempty nextgroup=@jsExpression
syntax keyword jsModuleDefault contained default skipwhite skipempty nextgroup=@jsExpression
syntax region jsImportContainer start=/\<import\> / end="\%(;\|$\)" contains=jsModuleKeywords,jsModuleOperators,jsComment,jsString,jsTemplateString,jsNoise,jsModuleGroup,jsModuleAsterisk
syntax region jsExportContainer start=/\<export\> / end="\%(;\|$\)" contains=jsModuleKeywords,jsModuleOperators,jsStorageClass,jsModuleDefault,@jsExpression
syntax region jsExportBlock contained matchgroup=jsBraces start=/{/ end=/}/ contains=jsModuleOperators,jsNoise,jsComment
@ -54,9 +55,9 @@ syntax region jsString start=+"+ skip=+\\\("\|$\)+ end=+"\|$+ cont
syntax region jsString start=+'+ skip=+\\\('\|$\)+ end=+'\|$+ contains=jsSpecial,@Spell extend
syntax region jsTemplateString start=+`+ skip=+\\\(`\|$\)+ end=+`+ contains=jsTemplateVar,jsSpecial extend
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 match jsFloat /\<-\=\%(\d\+\.\d\+\|\d\+\.\|\.\d\+\)\%([eE][+-]\=\d\+\)\=\>/
syntax match jsFloat /\<\%(\d\+\.\d\+\|\d\+\.\|\.\d\+\)\%([eE][+-]\=\d\+\)\=\>/
" Regular Expressions
syntax match jsSpecial contained "\v\\%(0|\\x\x\{2\}\|\\u\x\{4\}\|\c[A-Z]|.)"
@ -75,7 +76,7 @@ else
endif
syntax cluster jsRegexpSpecial contains=jsSpecial,jsRegexpBoundary,jsRegexpBackRef,jsRegexpQuantifier,jsRegexpOr,jsRegexpMod
syntax match jsObjectKey contained /\<[0-9a-zA-Z_$]*\>\(\s*:\)\@=/ contains=jsFunctionKey skipwhite skipempty nextgroup=jsObjectValue,jsFlowParenRegion
syntax match jsObjectKey contained /\<[0-9a-zA-Z_$]*\>\(\s*:\)\@=/ contains=jsFunctionKey skipwhite skipempty nextgroup=jsObjectValue
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
@ -97,10 +98,11 @@ exe 'syntax keyword jsSuper super contained '.(exists('g:javascript_conceal
" Statement Keywords
syntax keyword jsStatement contained break continue with yield debugger
syntax keyword jsConditional if else skipwhite skipempty nextgroup=jsParenIfElse,jsBlock
syntax keyword jsConditional if skipwhite skipempty nextgroup=jsParenIfElse
syntax keyword jsConditional else skipwhite skipempty nextgroup=jsCommentMisc,jsBlock
syntax keyword jsConditional switch skipwhite skipempty nextgroup=jsParenSwitch
syntax keyword jsRepeat while for skipwhite skipempty nextgroup=jsParenRepeat
syntax keyword jsRepeat do skipwhite skipempty nextgroup=jsBlock
syntax keyword jsDo do skipwhite skipempty nextgroup=jsBlock
syntax keyword jsLabel contained case default
syntax keyword jsTry try skipwhite skipempty nextgroup=jsTryCatchBlock
syntax keyword jsFinally contained finally skipwhite skipempty nextgroup=jsBlock
@ -111,6 +113,8 @@ syntax match jsSwitchColon contained /:/ skipwhite skipempty nextgro
" 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
syntax keyword jsGlobalNodeObjects module exports global process
syntax match jsGlobalNodeObjects /require/ contains=jsFuncCall
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
" DISCUSS: How imporant is this, really? Perhaps it should be linked to an error because I assume the keywords are reserved?
@ -133,12 +137,12 @@ syntax keyword jsHtmlEvents onblur onclick oncontextmenu ondblclick onfocus
"" Code blocks
syntax region jsBracket matchgroup=jsBrackets start=/\[/ end=/\]/ contains=@jsExpression extend fold
syntax region jsParen matchgroup=jsParens start=/(/ end=/)/ contains=@jsAll extend fold
syntax region jsParenIfElse contained matchgroup=jsParens start=/(/ end=/)/ contains=@jsAll skipwhite skipempty nextgroup=jsBlock extend fold
syntax region jsParenRepeat contained matchgroup=jsParens start=/(/ end=/)/ contains=@jsAll skipwhite skipempty nextgroup=jsBlock extend fold
syntax region jsParenIfElse contained matchgroup=jsParens start=/(/ end=/)/ contains=@jsAll skipwhite skipempty nextgroup=jsCommentMisc,jsBlock extend fold
syntax region jsParenRepeat contained matchgroup=jsParens start=/(/ end=/)/ contains=@jsAll skipwhite skipempty nextgroup=jsCommentMisc,jsBlock extend fold
syntax region jsParenSwitch contained matchgroup=jsParens start=/(/ end=/)/ contains=@jsAll skipwhite skipempty nextgroup=jsSwitchBlock extend fold
syntax region jsParenCatch contained matchgroup=jsParens start=/(/ end=/)/ skipwhite skipempty nextgroup=jsTryCatchBlock extend fold
syntax region jsFuncArgs contained matchgroup=jsFuncParens start=/(/ end=/)/ contains=jsFuncArgCommas,jsComment,jsFuncArgExpression,jsDestructuringBlock,jsRestExpression,jsFlow skipwhite skipempty nextgroup=jsFuncBlock,jsFlowReturn extend fold
syntax region jsClassBlock contained matchgroup=jsClassBraces start=/{/ end=/}/ contains=jsClassFuncName,jsClassMethodType,jsOperator,jsArrowFunction,jsArrowFuncArgs,jsComment,jsGenerator,jsDecorator,jsClassProperty,jsClassPropertyComputed,jsClassStringKey,jsNoise,jsFlowClassProperty extend fold
syntax region jsFuncArgs contained matchgroup=jsFuncParens start=/(/ end=/)/ contains=jsFuncArgCommas,jsComment,jsFuncArgExpression,jsDestructuringBlock,jsRestExpression,jsFlowArgumentDef skipwhite skipempty nextgroup=jsCommentFunction,jsFuncBlock,jsFlowReturn extend fold
syntax region jsClassBlock contained matchgroup=jsClassBraces start=/{/ end=/}/ contains=jsClassFuncName,jsClassMethodType,jsArrowFunction,jsArrowFuncArgs,jsComment,jsGenerator,jsDecorator,jsClassProperty,jsClassPropertyComputed,jsClassStringKey,jsNoise extend fold
syntax region jsFuncBlock contained matchgroup=jsFuncBraces start=/{/ end=/}/ contains=@jsAll extend fold
syntax region jsBlock contained matchgroup=jsBraces start=/{/ end=/}/ contains=@jsAll extend fold
syntax region jsTryCatchBlock contained matchgroup=jsBraces start=/{/ end=/}/ contains=@jsAll skipwhite skipempty nextgroup=jsCatch,jsFinally extend fold
@ -152,7 +156,7 @@ syntax region jsRestExpression contained matchgroup=jsRestOperator s
syntax region jsTernaryIf matchgroup=jsTernaryIfOperator start=/?/ end=/\%(:\|[\}]\@=\)/ contains=@jsExpression
syntax match jsGenerator contained /\*/ skipwhite skipempty nextgroup=jsFuncName,jsFuncArgs
syntax match jsFuncName contained /\<[a-zA-Z_$][0-9a-zA-Z_$]*\>/ skipwhite skipempty nextgroup=jsFuncArgs
syntax match jsFuncName contained /\<[a-zA-Z_$][0-9a-zA-Z_$]*\>/ skipwhite skipempty nextgroup=jsFuncArgs,jsFlowFunctionGroup
syntax region jsFuncArgExpression contained matchgroup=jsFuncArgOperator start=/=/ end=/[,)]\@=/ contains=@jsExpression extend
syntax match jsFuncArgCommas contained ','
syntax keyword jsArguments contained arguments
@ -168,7 +172,7 @@ exe 'syntax match jsArrowFunction /=>/ skipwhite skipempty nextgroup=jsFunc
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=jsClassBlock,jsFlowClass
syntax match jsClassDefinition /\<class\>\%( [a-zA-Z_$][0-9a-zA-Z_$ \n.]*\)*/ contains=jsClassKeywords,jsClassNoise skipwhite skipempty nextgroup=jsCommentClass,jsClassBlock,jsFlowClassGroup
syntax match jsDecorator contained "@" nextgroup=jsDecoratorFunction
syntax match jsDecoratorFunction contained "[a-zA-Z_][a-zA-Z0-9_.]*"
syntax match jsClassProperty contained /\<[0-9a-zA-Z_$]*\>\(\s*=\)\@=/ skipwhite skipempty nextgroup=jsClassValue
@ -193,6 +197,16 @@ syntax region jsComment start=/\/\// end=/$/ contains=jsCommentTodo,@Spe
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
if exists("javascript_plugin_jsdoc")
runtime extras/jsdoc.vim
" NGDoc requires JSDoc
@ -205,7 +219,7 @@ if exists("javascript_plugin_flow")
runtime extras/flow.vim
endif
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
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.
@ -243,6 +257,7 @@ if version >= 508 || !exists("did_javascript_syn_inits")
HiLink jsLabel Label
HiLink jsReturn Statement
HiLink jsRepeat Repeat
HiLink jsDo Repeat
HiLink jsStatement Statement
HiLink jsException Exception
HiLink jsTry Exception
@ -264,7 +279,7 @@ if version >= 508 || !exists("did_javascript_syn_inits")
HiLink jsStorageClass StorageClass
HiLink jsClassKeywords Structure
HiLink jsThis Special
HiLink jsSuper Special
HiLink jsSuper Constant
HiLink jsNan Number
HiLink jsNull Type
HiLink jsUndefined Type
@ -285,9 +300,10 @@ if version >= 508 || !exists("did_javascript_syn_inits")
HiLink jsSpecial Special
HiLink jsTemplateVar Special
HiLink jsTemplateBraces jsBraces
HiLink jsGlobalObjects Special
HiLink jsExceptions Special
HiLink jsBuiltins Special
HiLink jsGlobalObjects Constant
HiLink jsGlobalNodeObjects Constant
HiLink jsExceptions Constant
HiLink jsBuiltins Constant
HiLink jsModuleKeywords Include
HiLink jsModuleOperators Include
HiLink jsModuleDefault Include
@ -302,12 +318,17 @@ if version >= 508 || !exists("did_javascript_syn_inits")
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 jsDomNodeConsts Constant
HiLink jsDomElemAttrs Label