diff options
Diffstat (limited to 'after')
-rw-r--r-- | after/ftplugin/javascript.vim | 37 | ||||
-rw-r--r-- | after/indent/javascript.vim | 173 | ||||
-rw-r--r-- | after/indent/jsx.vim | 173 | ||||
-rw-r--r-- | after/indent/typescript.vim | 173 | ||||
-rw-r--r-- | after/syntax/javascript.vim | 253 | ||||
-rw-r--r-- | after/syntax/typescript.vim | 253 |
6 files changed, 1062 insertions, 0 deletions
diff --git a/after/ftplugin/javascript.vim b/after/ftplugin/javascript.vim index 26d00bf2..093f0b7b 100644 --- a/after/ftplugin/javascript.vim +++ b/after/ftplugin/javascript.vim @@ -49,3 +49,40 @@ augroup jsx_comment augroup end setlocal suffixesadd+=.jsx +if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'styled-components') != -1 + finish +endif + +" Vim filetype plugin file +" Language: styled-components (js/ts) +" Maintainer: Karl Fleischmann <fleischmann.karl@gmail.com> +" URL: https://github.com/styled-components/vim-styled-components + +fu! s:GetSyntaxNames(lnum, cnum) + return map(synstack(a:lnum, a:cnum), 'synIDattr(v:val, "name")') +endfu + +" re-implement SynSOL of vim-jsx +fu! s:SynSOL(lnum) + return s:GetSyntaxNames(a:lnum, 1) +endfu + +"" Return whether the current line is a jsTemplateString +fu! IsStyledDefinition(lnum) + " iterate through all syntax items in the given line + for item in s:SynSOL(a:lnum) + " if syntax-item is a jsTemplateString return 1 - true + " `==#` is a match case comparison of the item + if item ==# 'styledDefinition' + return 1 + endif + endfor + + " fallback to 0 - false + return 0 +endfu + +if exists('&ofu') + let b:prevofu=&ofu + setl omnifunc=styledcomplete#CompleteSC +endif diff --git a/after/indent/javascript.vim b/after/indent/javascript.vim index 1825446e..275073fa 100644 --- a/after/indent/javascript.vim +++ b/after/indent/javascript.vim @@ -31,3 +31,176 @@ endfunction let &cpo = s:keepcpo unlet s:keepcpo +if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'styled-components') != -1 + finish +endif + +" Vim syntax file +" Language: styled-components (js/ts) +" Maintainer: Karl Fleischmann <fleischmann.karl@gmail.com> +" URL: https://github.com/styled-components/vim-styled-components + +" initialize variable to check, if the indentation expression is run +" multiple times in a row, which indicates an infinite recursion +let s:is_recursion = 0 + +" store current indentexpr for later +let b:js_ts_indent=&indentexpr + +" set indentexpr for this filetype (styled-components) +setlocal indentexpr=GetStyledIndent() + +" add the following keys to trigger reindenting, when in insert mode +" - *; - Indent and insert on press of ';' key. +" - *<:> - Indent and insert on press of ':' key. +set indentkeys+=*;,*<:>,*<Return> + +fu! s:GetSyntaxNames(lnum, cnum) + return map(synstack(a:lnum, a:cnum), 'synIDattr(v:val, "name")') +endfu + +" re-implement SynSOL of vim-jsx +" TODO: add dependency to the readme and remove duplicate implementation +fu! s:SynSOL(lnum) + return s:GetSyntaxNames(a:lnum, 1) +endfu + +" re-implement SynEOL of vim-jsx +" TODO: add dependency to the readme and remove duplicate implementation +fu! s:SynEOL(lnum, offset) + let l:lnum = prevnonblank(a:lnum) + let l:col = strlen(getline(l:lnum)) + + return s:GetSyntaxNames(l:lnum, l:col + a:offset) +endfu + + +"" Return whether the current line is a jsTemplateString +fu! s:IsStyledDefinition(lnum) + " iterate through all syntax items in the given line + for item in s:SynSOL(a:lnum) + " if syntax-item is a jsTemplateString return 1 - true + " `==#` is a match case comparison of the item + if item ==# 'styledDefinition' + return 1 + endif + endfor + + " fallback to 0 - false + return 0 +endfu + +"" Count occurences of `str` at the beginning of the given `lnum` line +fu! s:CountOccurencesInSOL(lnum, str) + let l:occurence = 0 + + " iterate through all items in the given line + for item in s:SynSOL(a:lnum) + " if the syntax-item equals the given str increment the counter + " `==?` is a case isensitive equal operation + if item ==? a:str + let l:occurence += 1 + endif + endfor + + " return the accumulated count of occurences + return l:occurence +endfu + +"" Count occurences of `str` at the end of the given `lnum` line +fu! s:CountOccurencesInEOL(lnum, str, offset) + let l:occurence = 0 + + " iterate through all items in the given line + for item in s:SynEOL(a:lnum, a:offset) + " if the syntax-item equals the given str increment the counter + " `==?` is a case insensitive equal operation + if item == a:str + let l:occurence += 1 + endif + endfor + + " return the accumulated count of occurences + return l:occurence +endfu + +"" Get the indentation of the current line +fu! GetStyledIndent() + if s:IsStyledDefinition(v:lnum) + let l:baseIndent = 0 + + " find last non-styled line + let l:cnum = v:lnum + while s:IsStyledDefinition(l:cnum) + let l:cnum -= 1 + endwhile + + " get indentation of the last non-styled line as base indentation + let l:baseIndent = indent(l:cnum) + + " incrementally build indentation based on current indentation + " - one shiftwidth for the styled definition region + " - one shiftwidth per open nested definition region + let l:styledIndent = &sw + let l:styledIndent += min([ + \ s:CountOccurencesInSOL(v:lnum, 'styledNestedRegion'), + \ s:CountOccurencesInEOL(v:lnum, 'styledNestedRegion', 0) + \ ]) * &sw + + " decrease indentation by one shiftwidth, if the styled definition + " region ends on the current line + " - either directly via styled definition region, or + " - if the very last + if s:CountOccurencesInEOL(v:lnum, 'styledDefinition', 1) == 0 + let l:styledIndent -= &sw + endif + + " return the base indentation + " (for nested styles inside classes/objects/etc.) plus the actual + " indentation inside the styled definition region + return l:baseIndent + l:styledIndent + elseif len(b:js_ts_indent) + let l:result = 0 + let l:offset = 0 + + " increase indentation by one shiftwidth, if the last line ended on a + " styledXmlRegion and this line does not continue with it + " this is a fix for an incorrectly indented xml prop after a + " glamor-styled styledXmlRegion + if s:CountOccurencesInEOL(v:lnum-1, 'styledXmlRegion', 0) == 1 && + \ s:CountOccurencesInSOL(v:lnum, 'styledXmlRegion') == 0 + let l:offset = &sw + endif + + " make sure `GetStyledIndent` and `GetJsxIndent` don't infinitely + " recurse by incrementing a counter variable, before evaluating the + " stored indent expression + if s:is_recursion == 0 + let s:is_recursion = 1 + let l:result = eval(b:js_ts_indent) + endif + + " `is_recursion` being 0 at this point indicates, that + " `eval(b:js_ts_indent)` did itself evaluate it's stored indentexpr + " and thus it can be assumed, that the current line should be + " indented as JS + if s:is_recursion == 0 + " use one of `GetJavascriptIndent` or `GetJsIndent` if existing + " fallback to cindent, if not + if exists('*GetJavascriptIndent') + let l:result = GetJavascriptIndent() + elseif exists('*GetJsIndent') + let l:result = GetJsIndent() + else + let l:result = cindent(v:lnum) + endif + endif + + " reset `is_recursion` counter and return the indentation value + let s:is_recursion = 0 + return l:result + l:offset + endif + + " if all else fails indent according to C-syntax + return cindent(v:lnum) +endfu diff --git a/after/indent/jsx.vim b/after/indent/jsx.vim new file mode 100644 index 00000000..9d8da5d1 --- /dev/null +++ b/after/indent/jsx.vim @@ -0,0 +1,173 @@ +if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'styled-components') != -1 + finish +endif + +" Vim syntax file +" Language: styled-components (js/ts) +" Maintainer: Karl Fleischmann <fleischmann.karl@gmail.com> +" URL: https://github.com/styled-components/vim-styled-components + +" initialize variable to check, if the indentation expression is run +" multiple times in a row, which indicates an infinite recursion +let s:is_recursion = 0 + +" store current indentexpr for later +let b:js_ts_indent=&indentexpr + +" set indentexpr for this filetype (styled-components) +setlocal indentexpr=GetStyledIndent() + +" add the following keys to trigger reindenting, when in insert mode +" - *; - Indent and insert on press of ';' key. +" - *<:> - Indent and insert on press of ':' key. +set indentkeys+=*;,*<:>,*<Return> + +fu! s:GetSyntaxNames(lnum, cnum) + return map(synstack(a:lnum, a:cnum), 'synIDattr(v:val, "name")') +endfu + +" re-implement SynSOL of vim-jsx +" TODO: add dependency to the readme and remove duplicate implementation +fu! s:SynSOL(lnum) + return s:GetSyntaxNames(a:lnum, 1) +endfu + +" re-implement SynEOL of vim-jsx +" TODO: add dependency to the readme and remove duplicate implementation +fu! s:SynEOL(lnum, offset) + let l:lnum = prevnonblank(a:lnum) + let l:col = strlen(getline(l:lnum)) + + return s:GetSyntaxNames(l:lnum, l:col + a:offset) +endfu + + +"" Return whether the current line is a jsTemplateString +fu! s:IsStyledDefinition(lnum) + " iterate through all syntax items in the given line + for item in s:SynSOL(a:lnum) + " if syntax-item is a jsTemplateString return 1 - true + " `==#` is a match case comparison of the item + if item ==# 'styledDefinition' + return 1 + endif + endfor + + " fallback to 0 - false + return 0 +endfu + +"" Count occurences of `str` at the beginning of the given `lnum` line +fu! s:CountOccurencesInSOL(lnum, str) + let l:occurence = 0 + + " iterate through all items in the given line + for item in s:SynSOL(a:lnum) + " if the syntax-item equals the given str increment the counter + " `==?` is a case isensitive equal operation + if item ==? a:str + let l:occurence += 1 + endif + endfor + + " return the accumulated count of occurences + return l:occurence +endfu + +"" Count occurences of `str` at the end of the given `lnum` line +fu! s:CountOccurencesInEOL(lnum, str, offset) + let l:occurence = 0 + + " iterate through all items in the given line + for item in s:SynEOL(a:lnum, a:offset) + " if the syntax-item equals the given str increment the counter + " `==?` is a case insensitive equal operation + if item == a:str + let l:occurence += 1 + endif + endfor + + " return the accumulated count of occurences + return l:occurence +endfu + +"" Get the indentation of the current line +fu! GetStyledIndent() + if s:IsStyledDefinition(v:lnum) + let l:baseIndent = 0 + + " find last non-styled line + let l:cnum = v:lnum + while s:IsStyledDefinition(l:cnum) + let l:cnum -= 1 + endwhile + + " get indentation of the last non-styled line as base indentation + let l:baseIndent = indent(l:cnum) + + " incrementally build indentation based on current indentation + " - one shiftwidth for the styled definition region + " - one shiftwidth per open nested definition region + let l:styledIndent = &sw + let l:styledIndent += min([ + \ s:CountOccurencesInSOL(v:lnum, 'styledNestedRegion'), + \ s:CountOccurencesInEOL(v:lnum, 'styledNestedRegion', 0) + \ ]) * &sw + + " decrease indentation by one shiftwidth, if the styled definition + " region ends on the current line + " - either directly via styled definition region, or + " - if the very last + if s:CountOccurencesInEOL(v:lnum, 'styledDefinition', 1) == 0 + let l:styledIndent -= &sw + endif + + " return the base indentation + " (for nested styles inside classes/objects/etc.) plus the actual + " indentation inside the styled definition region + return l:baseIndent + l:styledIndent + elseif len(b:js_ts_indent) + let l:result = 0 + let l:offset = 0 + + " increase indentation by one shiftwidth, if the last line ended on a + " styledXmlRegion and this line does not continue with it + " this is a fix for an incorrectly indented xml prop after a + " glamor-styled styledXmlRegion + if s:CountOccurencesInEOL(v:lnum-1, 'styledXmlRegion', 0) == 1 && + \ s:CountOccurencesInSOL(v:lnum, 'styledXmlRegion') == 0 + let l:offset = &sw + endif + + " make sure `GetStyledIndent` and `GetJsxIndent` don't infinitely + " recurse by incrementing a counter variable, before evaluating the + " stored indent expression + if s:is_recursion == 0 + let s:is_recursion = 1 + let l:result = eval(b:js_ts_indent) + endif + + " `is_recursion` being 0 at this point indicates, that + " `eval(b:js_ts_indent)` did itself evaluate it's stored indentexpr + " and thus it can be assumed, that the current line should be + " indented as JS + if s:is_recursion == 0 + " use one of `GetJavascriptIndent` or `GetJsIndent` if existing + " fallback to cindent, if not + if exists('*GetJavascriptIndent') + let l:result = GetJavascriptIndent() + elseif exists('*GetJsIndent') + let l:result = GetJsIndent() + else + let l:result = cindent(v:lnum) + endif + endif + + " reset `is_recursion` counter and return the indentation value + let s:is_recursion = 0 + return l:result + l:offset + endif + + " if all else fails indent according to C-syntax + return cindent(v:lnum) +endfu diff --git a/after/indent/typescript.vim b/after/indent/typescript.vim index dc8a5845..996c3d8c 100644 --- a/after/indent/typescript.vim +++ b/after/indent/typescript.vim @@ -32,3 +32,176 @@ endfunction let &cpo = s:keepcpo unlet s:keepcpo +if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'styled-components') != -1 + finish +endif + +" Vim syntax file +" Language: styled-components (js/ts) +" Maintainer: Karl Fleischmann <fleischmann.karl@gmail.com> +" URL: https://github.com/styled-components/vim-styled-components + +" initialize variable to check, if the indentation expression is run +" multiple times in a row, which indicates an infinite recursion +let s:is_recursion = 0 + +" store current indentexpr for later +let b:js_ts_indent=&indentexpr + +" set indentexpr for this filetype (styled-components) +setlocal indentexpr=GetStyledIndent() + +" add the following keys to trigger reindenting, when in insert mode +" - *; - Indent and insert on press of ';' key. +" - *<:> - Indent and insert on press of ':' key. +set indentkeys+=*;,*<:>,*<Return> + +fu! s:GetSyntaxNames(lnum, cnum) + return map(synstack(a:lnum, a:cnum), 'synIDattr(v:val, "name")') +endfu + +" re-implement SynSOL of vim-jsx +" TODO: add dependency to the readme and remove duplicate implementation +fu! s:SynSOL(lnum) + return s:GetSyntaxNames(a:lnum, 1) +endfu + +" re-implement SynEOL of vim-jsx +" TODO: add dependency to the readme and remove duplicate implementation +fu! s:SynEOL(lnum, offset) + let l:lnum = prevnonblank(a:lnum) + let l:col = strlen(getline(l:lnum)) + + return s:GetSyntaxNames(l:lnum, l:col + a:offset) +endfu + + +"" Return whether the current line is a jsTemplateString +fu! s:IsStyledDefinition(lnum) + " iterate through all syntax items in the given line + for item in s:SynSOL(a:lnum) + " if syntax-item is a jsTemplateString return 1 - true + " `==#` is a match case comparison of the item + if item ==# 'styledDefinition' + return 1 + endif + endfor + + " fallback to 0 - false + return 0 +endfu + +"" Count occurences of `str` at the beginning of the given `lnum` line +fu! s:CountOccurencesInSOL(lnum, str) + let l:occurence = 0 + + " iterate through all items in the given line + for item in s:SynSOL(a:lnum) + " if the syntax-item equals the given str increment the counter + " `==?` is a case isensitive equal operation + if item ==? a:str + let l:occurence += 1 + endif + endfor + + " return the accumulated count of occurences + return l:occurence +endfu + +"" Count occurences of `str` at the end of the given `lnum` line +fu! s:CountOccurencesInEOL(lnum, str, offset) + let l:occurence = 0 + + " iterate through all items in the given line + for item in s:SynEOL(a:lnum, a:offset) + " if the syntax-item equals the given str increment the counter + " `==?` is a case insensitive equal operation + if item == a:str + let l:occurence += 1 + endif + endfor + + " return the accumulated count of occurences + return l:occurence +endfu + +"" Get the indentation of the current line +fu! GetStyledIndent() + if s:IsStyledDefinition(v:lnum) + let l:baseIndent = 0 + + " find last non-styled line + let l:cnum = v:lnum + while s:IsStyledDefinition(l:cnum) + let l:cnum -= 1 + endwhile + + " get indentation of the last non-styled line as base indentation + let l:baseIndent = indent(l:cnum) + + " incrementally build indentation based on current indentation + " - one shiftwidth for the styled definition region + " - one shiftwidth per open nested definition region + let l:styledIndent = &sw + let l:styledIndent += min([ + \ s:CountOccurencesInSOL(v:lnum, 'styledNestedRegion'), + \ s:CountOccurencesInEOL(v:lnum, 'styledNestedRegion', 0) + \ ]) * &sw + + " decrease indentation by one shiftwidth, if the styled definition + " region ends on the current line + " - either directly via styled definition region, or + " - if the very last + if s:CountOccurencesInEOL(v:lnum, 'styledDefinition', 1) == 0 + let l:styledIndent -= &sw + endif + + " return the base indentation + " (for nested styles inside classes/objects/etc.) plus the actual + " indentation inside the styled definition region + return l:baseIndent + l:styledIndent + elseif len(b:js_ts_indent) + let l:result = 0 + let l:offset = 0 + + " increase indentation by one shiftwidth, if the last line ended on a + " styledXmlRegion and this line does not continue with it + " this is a fix for an incorrectly indented xml prop after a + " glamor-styled styledXmlRegion + if s:CountOccurencesInEOL(v:lnum-1, 'styledXmlRegion', 0) == 1 && + \ s:CountOccurencesInSOL(v:lnum, 'styledXmlRegion') == 0 + let l:offset = &sw + endif + + " make sure `GetStyledIndent` and `GetJsxIndent` don't infinitely + " recurse by incrementing a counter variable, before evaluating the + " stored indent expression + if s:is_recursion == 0 + let s:is_recursion = 1 + let l:result = eval(b:js_ts_indent) + endif + + " `is_recursion` being 0 at this point indicates, that + " `eval(b:js_ts_indent)` did itself evaluate it's stored indentexpr + " and thus it can be assumed, that the current line should be + " indented as JS + if s:is_recursion == 0 + " use one of `GetJavascriptIndent` or `GetJsIndent` if existing + " fallback to cindent, if not + if exists('*GetJavascriptIndent') + let l:result = GetJavascriptIndent() + elseif exists('*GetJsIndent') + let l:result = GetJsIndent() + else + let l:result = cindent(v:lnum) + endif + endif + + " reset `is_recursion` counter and return the indentation value + let s:is_recursion = 0 + return l:result + l:offset + endif + + " if all else fails indent according to C-syntax + return cindent(v:lnum) +endfu diff --git a/after/syntax/javascript.vim b/after/syntax/javascript.vim index 7b92ecbd..000ac954 100644 --- a/after/syntax/javascript.vim +++ b/after/syntax/javascript.vim @@ -62,3 +62,256 @@ let b:current_syntax = 'javascript.jsx' let &cpo = s:jsx_cpo unlet s:jsx_cpo +if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'styled-components') != -1 + finish +endif + +" Vim syntax file +" Language: styled-components (js/ts) +" Maintainer: Karl Fleischmann <fleischmann.karl@gmail.com> +" URL: https://github.com/styled-components/vim-styled-components + +if exists("b:current_syntax") + let s:current_syntax=b:current_syntax + unlet b:current_syntax +endif + + +" fix for "-" before cssPositioningProp +" - needs to be above CSS include to not match cssVendor definitions +syn region cssCustomPositioningPrefix contained + \ start='-' end='\%(\s\{-}:\)\@=' + \ contains=cssPositioningProp + +" introduce CSS cluster from built-in (or single third party syntax file) +syn include @CSS syntax/css.vim + +" try to include CSS3 definitions from multiple files +" this is only possible on vim version above 7 +if v:version >= 700 + try + syn include @CSS3 syntax/css/*.vim + catch + endtry +endif + +" TODO: include react-native keywords + +" define custom cssAttrRegion +" - add ",", "`" and "{" to the end characters +" - add "cssPseudoClassId" to it's containing elements +" this will incorrectly highlight pseudo elements incorrectly used as +" attributes but correctly highlight actual attributes +syn region cssCustomAttrRegion contained + \ start=":" end="\ze\%(;\|)\|{\|}\|`\)" + \ contains=css.*Attr,cssColor,cssImportant,cssValue.*,cssFunction, + \ cssString.*,cssURL,cssComment,cssUnicodeEscape,cssVendor, + \ cssError,cssAttrComma,cssNoise,cssPseudoClassId, + \ jsTemplateExpression, + \ typescriptInterpolation,typescriptTemplateSubstitution +syn region cssCustomAttrRegion contained + \ start="transition\s*:" end="\ze\%(;\|)\|{\|}\|`\)" + \ contains=css.*Prop,css.*Attr,cssColor,cssImportant,cssValue.*, + \ cssFunction,cssString.*,cssURL,cssComment,cssUnicodeEscape, + \ cssVendor,cssError,cssAttrComma,cssNoise,cssPseudoClassId, + \ jsTemplateExpression, + \ typescriptInterpolation,typescriptTemplateSubstitution + +" define custom css elements to not utilize cssDefinition +syn region cssCustomMediaBlock contained fold transparent matchgroup=cssBraces + \ start="{" end="}" + \ contains=css.*Attr,css.*Prop,cssComment,cssValue.*,cssColor,cssURL, + \ cssImportant,cssError,cssStringQ,cssStringQQ,cssFunction, + \ cssUnicodeEscape,cssVendor,cssTagName,cssClassName, + \ cssIdentifier,cssPseudoClass,cssSelectorOp,cssSelectorOp2, + \ cssAttributeSelector +syn region cssCustomPageWrap contained transparent matchgroup=cssBraces + \ start="{" end="}" + \ contains=cssPageMargin,cssPageProp,cssCustomAttrRegion,css.*Prop, + \ cssComment,cssValue.*,cssColor,cssURL,cssImportant,cssError, + \ cssStringQ,cssStringQQ,cssFunction,cssUnicodeEscape,cssVendor, + \ cssHacks +syn match cssCustomPageMargin contained skipwhite skipnl + \ "@\%(\%(top\|left\|right\|bottom\)-\%(left\|center\|right\|middle\|bottom\)\)\%(-corner\)\=" +syn match cssCustomKeyFrameSelector "\%(\d*%\|\<from\>\|\<to\>\)" contained + \ skipwhite skipnl + +" define css include customly to overwrite nextgroup +syn region cssInclude start="@media\>" end="\ze{" skipwhite skipnl + \ contains=cssMediaProp,cssValueLength,cssMediaKeyword,cssValueInteger, + \ cssMediaMediaAttr,cssVencor,cssMediaType,cssIncludeKeyword, + \ cssMediaComma,cssComment + \ nextgroup=cssCustomMediaBlock + +" define all non-contained css definitions +syn cluster CSSTop + \ contains=cssTagName,cssSelectorOp,cssAttributeSelector,cssClassName, + \ cssBraces,cssIdentifier,cssIncludeKeyword,cssPage,cssKeyFrame, + \ cssFontDescriptor,cssAttrComma,cssPseudoClass,cssUnicodeEscape + +" custom highlights for styled components +" - "&" inside top level +" - cssTagName inside of jsStrings inside of styledPrefix regions +" TODO: override highlighting of cssTagName with more subtle one +syn match styledAmpersand contained "&" +syn region styledTagNameString matchgroup=jsString contained + \ start=+'+ end=+'+ skip=+\\\%(\'\|$\)+ + \ contains=cssTagName +syn region styledTagNameString matchgroup=jsString contained + \ start=+"+ end=+"+ skip=+\\\%(\"\|$\)+ + \ contains=cssTagName +syn region styledTagNameString matchgroup=jsString contained + \ start=+`+ end=+`+ skip=+\\\%(\`\|$\)+ + \ contains=cssTagName + +" define custom API sections that trigger the styledDefinition highlighting +syn match styledPrefix "\<styled\>\.\k\+" + \ transparent fold + \ nextgroup=styledDefinition + \ contains=cssTagName,javascriptTagRef + \ containedin=jsFuncBlock +syn match styledPrefix "\.\<attrs\>\s*(\%(\n\|\s\|.\)\{-})" + \ transparent fold extend + \ nextgroup=styledDefinition + \ contains=jsObject,jsParen + \ containedin=jsFuncBlock +syn match styledPrefix "\.\<extend\>" + \ transparent fold + \ nextgroup=styledDefinition + \ containedin=jsFuncBlock + +" define custom API section, that contains typescript annotations +" this is structurally similar to `jsFuncCall`, but allows type +" annotations (delimited by brackets (e.g. "<>")) between `styled` and +" the function call parenthesis +syn match styledTypescriptPrefix + \ "\<styled\><\%(\[\|\]\|{\|}\||\|&\|:\|;\|,\|?\|'\|\"\|\k\|\s\|\n\)\+>(\%('\k\+'\|\"\k\+\"\|\k\+\))" + \ transparent fold + \ nextgroup=styledDefinition + \ contains=cssTagName, + \ typescriptBraces,typescriptOpSymbols,typescriptEndColons, + \ typescriptParens,typescriptStringS,@typescriptType, + \ typescriptType, + \ styledTagNameString +syn match styledTypescriptPrefix + \ "\<styled\>\%((\%('\k\+'\|\"\k\+\"\|\k\+\))\|\.\k\+\)<\%(\[\|\]\|{\|}\||\|&\|:\|;\|,\|?\|'\|\"\|\k\|\s\|\n\)\+>" + \ transparent fold + \ nextgroup=styledDefinition + \ contains=cssTagName, + \ typescriptBraces,typescriptOpSymbols,typescriptEndColons, + \ typescriptParens,typescriptStringS,@typescriptType, + \ typescriptType, + \ styledTagNameString +syn match styledTypescriptPrefix "\.\<attrs\>\s*(\%(\n\|\s\|.\)\{-})<\%(\[\|\]\|{\|}\||\|&\|:\|;\|,\|?\|'\|\"\|\k\|\s\|\n\)\+>" + \ transparent fold extend + \ nextgroup=styledDefinition + \ contains=cssTagName, + \ typescriptBraces,typescriptOpSymbols,typescriptEndColons, + \ typescriptParens,typescriptStringS,@typescriptType, + \ typescriptType, + \ styledTagNameString +syn match styledTypescriptPrefix "\.\<extend\><\%(\[\|\]\|{\|}\||\|&\|:\|;\|,\|?\|'\|\"\|\k\|\s\|\n\)\+>" + \ transparent fold extend + \ nextgroup=styledDefinition + \ contains=cssTagName, + \ typescriptBraces,typescriptOpSymbols,typescriptEndColons, + \ typescriptParens,typescriptStringS,@typescriptType, + \ typescriptType, + \ styledTagNameString + +" define emotion css prop +" to bypass problems from top-level defined xml/js definitions, this +" plugin re-defines keywords/noise for highlighting inside of the custom +" xmlAttrib definition +syn keyword styledXmlRegionKeyword css contained +syn match styledXmlRegionNoise "\%(=\|{\|}\)" contained +" only include styledDefinitions inside of xmlAttribs, that are wrapped +" in `css={}` regions, `keepend` is necessary to correctly break on the +" higher-level xmlAttrib region end +syn region styledXmlRegion + \ start="\<css\>={" end="}" + \ keepend fold + \ containedin=xmlAttrib + \ contains=styledXmlRegionKeyword,styledXmlRegionNoise,styledDefinition + +" define nested region for indenting +syn region styledNestedRegion contained transparent + \ matchgroup=cssBraces + \ start="{" end="}" + +" re-define cssError to be highlighted correctly in styledNestedRegion +syn match cssError contained "{@<>" + +" extend javascript matches to trigger styledDefinition highlighting +syn match jsTaggedTemplate extend + \ "\<css\>\|\<keyframes\>\|\<injectGlobal\>\|\<fontFace\>\|\<createGlobalStyle\>" + \ nextgroup=styledDefinition +syn match jsFuncCall "\<styled\>\s*(.\+)" transparent + \ nextgroup=styledDefinition +syn match jsFuncCall "\<styled\>\s*(\%('\k\+'\|\"\k\+\"\|`\k\+`\))" + \ contains=styledTagNameString + \ nextgroup=styledDefinition +syn match jsFuncCall "\<styled\>\s*(\%('\k\+'\|\"\k\+\"\|`\k\+`\))<\%(\[\|\]\|{\|}\||\|&\|:\|;\|,\|?\|'\|\"\|\k\|\s\|\n\)\+>" + \ contains=typescriptBraces,typescriptOpSymbols,typescriptEndColons, + \ typescriptParens,typescriptStringS,@typescriptType, + \ typescriptType, + \ styledTagNameString + \ nextgroup=styledDefinition +syn match jsFuncCall "\.\<withComponent\>\s*(\%('\k\+'\|\"\k\+\"\|`\k\+`\))" + \ contains=styledTagNameString +syn match jsFuncCall "\<dc\>\s*(\%('\k\+'\|\"\k\+\"\|`\k\+`\))\%((\)\@=" + \ contains=styledTagNameString + \ nextgroup=styledDefinitionArgument + +" inject css highlighting into custom jsTemplateString region +" - use `extend` to not end all nested jsTemplateExpression on the first +" closing one +syn region styledDefinition contained transparent fold extend + \ start="`" end="`" skip="\\\%(`\|$\)" + \ contains=@CSSTop, + \ css.*Prop,cssValue.*,cssColor,cssUrl,cssImportant,cssError, + \ cssStringQ,cssStringQQ,cssFunction,cssUnicodeEscape,cssVendor, + \ cssHacks, + \ cssCustom.*, + \ jsComment,jsTemplateExpression, + \ typescriptInterpolation,typescriptTemplateSubstitution, + \ styledAmpersand,styledNestedRegion +syn region styledDefinitionArgument contained transparent start=+(+ end=+)+ + \ contains=styledDefinition + +syn cluster typescriptValue add=styledPrefix,jsFuncCall,styledTypescriptPrefix + +""" yajs specific extensions +" define template tag keywords, that trigger styledDefinitions again to be +" contained in and also do contain the `javascriptTagRef` region +syn match javascriptTagRefStyledPrefix transparent fold + \ "\<css\>\|\<keyframes\>\|\<injectGlobal\>\|\<fontFace\>\|\<createGlobalStyle\>" + \ containedin=javascriptTagRef + \ contains=javascriptTagRef + \ nextgroup=styledDefinition +" extend the yajs clusters to include the previously and extraneously defined +" styled-related matches +syn cluster javascriptExpression + \ add=styledPrefix,jsFuncCall,javascriptTagRefStyledPrefix +syn cluster javascriptAfterIdentifier add=styledPrefix,jsFuncCall + +""" yats specific extensions +" extend typescriptIdentifierName to allow styledDefinitions in their +" tagged templates +syn match typescriptIdentifierName extend + \ "\<css\>\|\<keyframes\>\|\<injectGlobal\>\|\<fontFace\>\|\<createGlobalStyle\>" + \ nextgroup=styledDefinition + +" color the custom highlight elements +hi def link cssCustomKeyFrameSelector Constant +hi def link cssCustomPositioningPrefix StorageClass +hi def link styledAmpersand Special + +hi def link styledXmlRegionKeyword Type +hi def link styledXmlRegionNoise Noise +hi def link styledXmlRegion String + + +if exists("s:current_syntax") + let b:current_syntax=s:current_syntax +endif diff --git a/after/syntax/typescript.vim b/after/syntax/typescript.vim index e4aab79f..d1b87c92 100644 --- a/after/syntax/typescript.vim +++ b/after/syntax/typescript.vim @@ -48,3 +48,256 @@ let b:current_syntax = 'typescript.tsx' let &cpo = s:jsx_cpo unlet s:jsx_cpo +if exists('g:polyglot_disabled') && index(g:polyglot_disabled, 'styled-components') != -1 + finish +endif + +" Vim syntax file +" Language: styled-components (js/ts) +" Maintainer: Karl Fleischmann <fleischmann.karl@gmail.com> +" URL: https://github.com/styled-components/vim-styled-components + +if exists("b:current_syntax") + let s:current_syntax=b:current_syntax + unlet b:current_syntax +endif + + +" fix for "-" before cssPositioningProp +" - needs to be above CSS include to not match cssVendor definitions +syn region cssCustomPositioningPrefix contained + \ start='-' end='\%(\s\{-}:\)\@=' + \ contains=cssPositioningProp + +" introduce CSS cluster from built-in (or single third party syntax file) +syn include @CSS syntax/css.vim + +" try to include CSS3 definitions from multiple files +" this is only possible on vim version above 7 +if v:version >= 700 + try + syn include @CSS3 syntax/css/*.vim + catch + endtry +endif + +" TODO: include react-native keywords + +" define custom cssAttrRegion +" - add ",", "`" and "{" to the end characters +" - add "cssPseudoClassId" to it's containing elements +" this will incorrectly highlight pseudo elements incorrectly used as +" attributes but correctly highlight actual attributes +syn region cssCustomAttrRegion contained + \ start=":" end="\ze\%(;\|)\|{\|}\|`\)" + \ contains=css.*Attr,cssColor,cssImportant,cssValue.*,cssFunction, + \ cssString.*,cssURL,cssComment,cssUnicodeEscape,cssVendor, + \ cssError,cssAttrComma,cssNoise,cssPseudoClassId, + \ jsTemplateExpression, + \ typescriptInterpolation,typescriptTemplateSubstitution +syn region cssCustomAttrRegion contained + \ start="transition\s*:" end="\ze\%(;\|)\|{\|}\|`\)" + \ contains=css.*Prop,css.*Attr,cssColor,cssImportant,cssValue.*, + \ cssFunction,cssString.*,cssURL,cssComment,cssUnicodeEscape, + \ cssVendor,cssError,cssAttrComma,cssNoise,cssPseudoClassId, + \ jsTemplateExpression, + \ typescriptInterpolation,typescriptTemplateSubstitution + +" define custom css elements to not utilize cssDefinition +syn region cssCustomMediaBlock contained fold transparent matchgroup=cssBraces + \ start="{" end="}" + \ contains=css.*Attr,css.*Prop,cssComment,cssValue.*,cssColor,cssURL, + \ cssImportant,cssError,cssStringQ,cssStringQQ,cssFunction, + \ cssUnicodeEscape,cssVendor,cssTagName,cssClassName, + \ cssIdentifier,cssPseudoClass,cssSelectorOp,cssSelectorOp2, + \ cssAttributeSelector +syn region cssCustomPageWrap contained transparent matchgroup=cssBraces + \ start="{" end="}" + \ contains=cssPageMargin,cssPageProp,cssCustomAttrRegion,css.*Prop, + \ cssComment,cssValue.*,cssColor,cssURL,cssImportant,cssError, + \ cssStringQ,cssStringQQ,cssFunction,cssUnicodeEscape,cssVendor, + \ cssHacks +syn match cssCustomPageMargin contained skipwhite skipnl + \ "@\%(\%(top\|left\|right\|bottom\)-\%(left\|center\|right\|middle\|bottom\)\)\%(-corner\)\=" +syn match cssCustomKeyFrameSelector "\%(\d*%\|\<from\>\|\<to\>\)" contained + \ skipwhite skipnl + +" define css include customly to overwrite nextgroup +syn region cssInclude start="@media\>" end="\ze{" skipwhite skipnl + \ contains=cssMediaProp,cssValueLength,cssMediaKeyword,cssValueInteger, + \ cssMediaMediaAttr,cssVencor,cssMediaType,cssIncludeKeyword, + \ cssMediaComma,cssComment + \ nextgroup=cssCustomMediaBlock + +" define all non-contained css definitions +syn cluster CSSTop + \ contains=cssTagName,cssSelectorOp,cssAttributeSelector,cssClassName, + \ cssBraces,cssIdentifier,cssIncludeKeyword,cssPage,cssKeyFrame, + \ cssFontDescriptor,cssAttrComma,cssPseudoClass,cssUnicodeEscape + +" custom highlights for styled components +" - "&" inside top level +" - cssTagName inside of jsStrings inside of styledPrefix regions +" TODO: override highlighting of cssTagName with more subtle one +syn match styledAmpersand contained "&" +syn region styledTagNameString matchgroup=jsString contained + \ start=+'+ end=+'+ skip=+\\\%(\'\|$\)+ + \ contains=cssTagName +syn region styledTagNameString matchgroup=jsString contained + \ start=+"+ end=+"+ skip=+\\\%(\"\|$\)+ + \ contains=cssTagName +syn region styledTagNameString matchgroup=jsString contained + \ start=+`+ end=+`+ skip=+\\\%(\`\|$\)+ + \ contains=cssTagName + +" define custom API sections that trigger the styledDefinition highlighting +syn match styledPrefix "\<styled\>\.\k\+" + \ transparent fold + \ nextgroup=styledDefinition + \ contains=cssTagName,javascriptTagRef + \ containedin=jsFuncBlock +syn match styledPrefix "\.\<attrs\>\s*(\%(\n\|\s\|.\)\{-})" + \ transparent fold extend + \ nextgroup=styledDefinition + \ contains=jsObject,jsParen + \ containedin=jsFuncBlock +syn match styledPrefix "\.\<extend\>" + \ transparent fold + \ nextgroup=styledDefinition + \ containedin=jsFuncBlock + +" define custom API section, that contains typescript annotations +" this is structurally similar to `jsFuncCall`, but allows type +" annotations (delimited by brackets (e.g. "<>")) between `styled` and +" the function call parenthesis +syn match styledTypescriptPrefix + \ "\<styled\><\%(\[\|\]\|{\|}\||\|&\|:\|;\|,\|?\|'\|\"\|\k\|\s\|\n\)\+>(\%('\k\+'\|\"\k\+\"\|\k\+\))" + \ transparent fold + \ nextgroup=styledDefinition + \ contains=cssTagName, + \ typescriptBraces,typescriptOpSymbols,typescriptEndColons, + \ typescriptParens,typescriptStringS,@typescriptType, + \ typescriptType, + \ styledTagNameString +syn match styledTypescriptPrefix + \ "\<styled\>\%((\%('\k\+'\|\"\k\+\"\|\k\+\))\|\.\k\+\)<\%(\[\|\]\|{\|}\||\|&\|:\|;\|,\|?\|'\|\"\|\k\|\s\|\n\)\+>" + \ transparent fold + \ nextgroup=styledDefinition + \ contains=cssTagName, + \ typescriptBraces,typescriptOpSymbols,typescriptEndColons, + \ typescriptParens,typescriptStringS,@typescriptType, + \ typescriptType, + \ styledTagNameString +syn match styledTypescriptPrefix "\.\<attrs\>\s*(\%(\n\|\s\|.\)\{-})<\%(\[\|\]\|{\|}\||\|&\|:\|;\|,\|?\|'\|\"\|\k\|\s\|\n\)\+>" + \ transparent fold extend + \ nextgroup=styledDefinition + \ contains=cssTagName, + \ typescriptBraces,typescriptOpSymbols,typescriptEndColons, + \ typescriptParens,typescriptStringS,@typescriptType, + \ typescriptType, + \ styledTagNameString +syn match styledTypescriptPrefix "\.\<extend\><\%(\[\|\]\|{\|}\||\|&\|:\|;\|,\|?\|'\|\"\|\k\|\s\|\n\)\+>" + \ transparent fold extend + \ nextgroup=styledDefinition + \ contains=cssTagName, + \ typescriptBraces,typescriptOpSymbols,typescriptEndColons, + \ typescriptParens,typescriptStringS,@typescriptType, + \ typescriptType, + \ styledTagNameString + +" define emotion css prop +" to bypass problems from top-level defined xml/js definitions, this +" plugin re-defines keywords/noise for highlighting inside of the custom +" xmlAttrib definition +syn keyword styledXmlRegionKeyword css contained +syn match styledXmlRegionNoise "\%(=\|{\|}\)" contained +" only include styledDefinitions inside of xmlAttribs, that are wrapped +" in `css={}` regions, `keepend` is necessary to correctly break on the +" higher-level xmlAttrib region end +syn region styledXmlRegion + \ start="\<css\>={" end="}" + \ keepend fold + \ containedin=xmlAttrib + \ contains=styledXmlRegionKeyword,styledXmlRegionNoise,styledDefinition + +" define nested region for indenting +syn region styledNestedRegion contained transparent + \ matchgroup=cssBraces + \ start="{" end="}" + +" re-define cssError to be highlighted correctly in styledNestedRegion +syn match cssError contained "{@<>" + +" extend javascript matches to trigger styledDefinition highlighting +syn match jsTaggedTemplate extend + \ "\<css\>\|\<keyframes\>\|\<injectGlobal\>\|\<fontFace\>\|\<createGlobalStyle\>" + \ nextgroup=styledDefinition +syn match jsFuncCall "\<styled\>\s*(.\+)" transparent + \ nextgroup=styledDefinition +syn match jsFuncCall "\<styled\>\s*(\%('\k\+'\|\"\k\+\"\|`\k\+`\))" + \ contains=styledTagNameString + \ nextgroup=styledDefinition +syn match jsFuncCall "\<styled\>\s*(\%('\k\+'\|\"\k\+\"\|`\k\+`\))<\%(\[\|\]\|{\|}\||\|&\|:\|;\|,\|?\|'\|\"\|\k\|\s\|\n\)\+>" + \ contains=typescriptBraces,typescriptOpSymbols,typescriptEndColons, + \ typescriptParens,typescriptStringS,@typescriptType, + \ typescriptType, + \ styledTagNameString + \ nextgroup=styledDefinition +syn match jsFuncCall "\.\<withComponent\>\s*(\%('\k\+'\|\"\k\+\"\|`\k\+`\))" + \ contains=styledTagNameString +syn match jsFuncCall "\<dc\>\s*(\%('\k\+'\|\"\k\+\"\|`\k\+`\))\%((\)\@=" + \ contains=styledTagNameString + \ nextgroup=styledDefinitionArgument + +" inject css highlighting into custom jsTemplateString region +" - use `extend` to not end all nested jsTemplateExpression on the first +" closing one +syn region styledDefinition contained transparent fold extend + \ start="`" end="`" skip="\\\%(`\|$\)" + \ contains=@CSSTop, + \ css.*Prop,cssValue.*,cssColor,cssUrl,cssImportant,cssError, + \ cssStringQ,cssStringQQ,cssFunction,cssUnicodeEscape,cssVendor, + \ cssHacks, + \ cssCustom.*, + \ jsComment,jsTemplateExpression, + \ typescriptInterpolation,typescriptTemplateSubstitution, + \ styledAmpersand,styledNestedRegion +syn region styledDefinitionArgument contained transparent start=+(+ end=+)+ + \ contains=styledDefinition + +syn cluster typescriptValue add=styledPrefix,jsFuncCall,styledTypescriptPrefix + +""" yajs specific extensions +" define template tag keywords, that trigger styledDefinitions again to be +" contained in and also do contain the `javascriptTagRef` region +syn match javascriptTagRefStyledPrefix transparent fold + \ "\<css\>\|\<keyframes\>\|\<injectGlobal\>\|\<fontFace\>\|\<createGlobalStyle\>" + \ containedin=javascriptTagRef + \ contains=javascriptTagRef + \ nextgroup=styledDefinition +" extend the yajs clusters to include the previously and extraneously defined +" styled-related matches +syn cluster javascriptExpression + \ add=styledPrefix,jsFuncCall,javascriptTagRefStyledPrefix +syn cluster javascriptAfterIdentifier add=styledPrefix,jsFuncCall + +""" yats specific extensions +" extend typescriptIdentifierName to allow styledDefinitions in their +" tagged templates +syn match typescriptIdentifierName extend + \ "\<css\>\|\<keyframes\>\|\<injectGlobal\>\|\<fontFace\>\|\<createGlobalStyle\>" + \ nextgroup=styledDefinition + +" color the custom highlight elements +hi def link cssCustomKeyFrameSelector Constant +hi def link cssCustomPositioningPrefix StorageClass +hi def link styledAmpersand Special + +hi def link styledXmlRegionKeyword Type +hi def link styledXmlRegionNoise Noise +hi def link styledXmlRegion String + + +if exists("s:current_syntax") + let b:current_syntax=s:current_syntax +endif |