diff --git a/README.md b/README.md index dd7a9a1..925fc87 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ A collection of language packs for Vim. > One to rule them all, one to find them, one to bring them all and in the darkness bind them. - It **won't affect your startup time**, as scripts are loaded only on demand\*. -- It **installs and updates 120+ times faster** than the 142 packages it consists of. +- It **installs and updates 120+ times faster** than the 143 packages it consists of. - Solid syntax and indentation support (other features skipped). Only the best language packs. - All unnecessary files are ignored (like enormous documentation from php support). - No support for esoteric languages, only most popular ones (modern too, like `slim`). @@ -160,6 +160,7 @@ If you need full functionality of any plugin, please use it directly with your p - [slime](https://github.com/slime-lang/vim-slime-syntax) (syntax, indent) - [smt2](https://github.com/bohlender/vim-smt2) (syntax, autoload, ftplugin) - [solidity](https://github.com/tomlion/vim-solidity) (syntax, indent, ftplugin) +- [styled-components](https://github.com/styled-components/vim-styled-components#main) (syntax, indent, ftplugin) - [stylus](https://github.com/wavded/vim-stylus) (syntax, indent, ftplugin) - [svg-indent](https://github.com/jasonshell/vim-svg-indent) (indent) - [svg](https://github.com/vim-scripts/svg.vim) (syntax) diff --git a/after/ftplugin/javascript.vim b/after/ftplugin/javascript.vim index 26d00bf..093f0b7 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 +" 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 1825446..275073f 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 +" 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+=*;,*<:>,* + +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 0000000..9d8da5d --- /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 +" 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+=*;,*<:>,* + +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 dc8a584..996c3d8 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 +" 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+=*;,*<:>,* + +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 7b92ecb..000ac95 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 +" 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*%\|\\|\\)" 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 "\\.\k\+" + \ transparent fold + \ nextgroup=styledDefinition + \ contains=cssTagName,javascriptTagRef + \ containedin=jsFuncBlock +syn match styledPrefix "\.\\s*(\%(\n\|\s\|.\)\{-})" + \ transparent fold extend + \ nextgroup=styledDefinition + \ contains=jsObject,jsParen + \ containedin=jsFuncBlock +syn match styledPrefix "\.\" + \ 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 + \ "\<\%(\[\|\]\|{\|}\||\|&\|:\|;\|,\|?\|'\|\"\|\k\|\s\|\n\)\+>(\%('\k\+'\|\"\k\+\"\|\k\+\))" + \ transparent fold + \ nextgroup=styledDefinition + \ contains=cssTagName, + \ typescriptBraces,typescriptOpSymbols,typescriptEndColons, + \ typescriptParens,typescriptStringS,@typescriptType, + \ typescriptType, + \ styledTagNameString +syn match styledTypescriptPrefix + \ "\\%((\%('\k\+'\|\"\k\+\"\|\k\+\))\|\.\k\+\)<\%(\[\|\]\|{\|}\||\|&\|:\|;\|,\|?\|'\|\"\|\k\|\s\|\n\)\+>" + \ transparent fold + \ nextgroup=styledDefinition + \ contains=cssTagName, + \ typescriptBraces,typescriptOpSymbols,typescriptEndColons, + \ typescriptParens,typescriptStringS,@typescriptType, + \ typescriptType, + \ styledTagNameString +syn match styledTypescriptPrefix "\.\\s*(\%(\n\|\s\|.\)\{-})<\%(\[\|\]\|{\|}\||\|&\|:\|;\|,\|?\|'\|\"\|\k\|\s\|\n\)\+>" + \ transparent fold extend + \ nextgroup=styledDefinition + \ contains=cssTagName, + \ typescriptBraces,typescriptOpSymbols,typescriptEndColons, + \ typescriptParens,typescriptStringS,@typescriptType, + \ typescriptType, + \ styledTagNameString +syn match styledTypescriptPrefix "\.\<\%(\[\|\]\|{\|}\||\|&\|:\|;\|,\|?\|'\|\"\|\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="\={" 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 + \ "\\|\\|\\|\\|\" + \ nextgroup=styledDefinition +syn match jsFuncCall "\\s*(.\+)" transparent + \ nextgroup=styledDefinition +syn match jsFuncCall "\\s*(\%('\k\+'\|\"\k\+\"\|`\k\+`\))" + \ contains=styledTagNameString + \ nextgroup=styledDefinition +syn match jsFuncCall "\\s*(\%('\k\+'\|\"\k\+\"\|`\k\+`\))<\%(\[\|\]\|{\|}\||\|&\|:\|;\|,\|?\|'\|\"\|\k\|\s\|\n\)\+>" + \ contains=typescriptBraces,typescriptOpSymbols,typescriptEndColons, + \ typescriptParens,typescriptStringS,@typescriptType, + \ typescriptType, + \ styledTagNameString + \ nextgroup=styledDefinition +syn match jsFuncCall "\.\\s*(\%('\k\+'\|\"\k\+\"\|`\k\+`\))" + \ contains=styledTagNameString +syn match jsFuncCall "\\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 + \ "\\|\\|\\|\\|\" + \ 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 + \ "\\|\\|\\|\\|\" + \ 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 e4aab79..d1b87c9 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 +" 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*%\|\\|\\)" 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 "\\.\k\+" + \ transparent fold + \ nextgroup=styledDefinition + \ contains=cssTagName,javascriptTagRef + \ containedin=jsFuncBlock +syn match styledPrefix "\.\\s*(\%(\n\|\s\|.\)\{-})" + \ transparent fold extend + \ nextgroup=styledDefinition + \ contains=jsObject,jsParen + \ containedin=jsFuncBlock +syn match styledPrefix "\.\" + \ 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 + \ "\<\%(\[\|\]\|{\|}\||\|&\|:\|;\|,\|?\|'\|\"\|\k\|\s\|\n\)\+>(\%('\k\+'\|\"\k\+\"\|\k\+\))" + \ transparent fold + \ nextgroup=styledDefinition + \ contains=cssTagName, + \ typescriptBraces,typescriptOpSymbols,typescriptEndColons, + \ typescriptParens,typescriptStringS,@typescriptType, + \ typescriptType, + \ styledTagNameString +syn match styledTypescriptPrefix + \ "\\%((\%('\k\+'\|\"\k\+\"\|\k\+\))\|\.\k\+\)<\%(\[\|\]\|{\|}\||\|&\|:\|;\|,\|?\|'\|\"\|\k\|\s\|\n\)\+>" + \ transparent fold + \ nextgroup=styledDefinition + \ contains=cssTagName, + \ typescriptBraces,typescriptOpSymbols,typescriptEndColons, + \ typescriptParens,typescriptStringS,@typescriptType, + \ typescriptType, + \ styledTagNameString +syn match styledTypescriptPrefix "\.\\s*(\%(\n\|\s\|.\)\{-})<\%(\[\|\]\|{\|}\||\|&\|:\|;\|,\|?\|'\|\"\|\k\|\s\|\n\)\+>" + \ transparent fold extend + \ nextgroup=styledDefinition + \ contains=cssTagName, + \ typescriptBraces,typescriptOpSymbols,typescriptEndColons, + \ typescriptParens,typescriptStringS,@typescriptType, + \ typescriptType, + \ styledTagNameString +syn match styledTypescriptPrefix "\.\<\%(\[\|\]\|{\|}\||\|&\|:\|;\|,\|?\|'\|\"\|\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="\={" 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 + \ "\\|\\|\\|\\|\" + \ nextgroup=styledDefinition +syn match jsFuncCall "\\s*(.\+)" transparent + \ nextgroup=styledDefinition +syn match jsFuncCall "\\s*(\%('\k\+'\|\"\k\+\"\|`\k\+`\))" + \ contains=styledTagNameString + \ nextgroup=styledDefinition +syn match jsFuncCall "\\s*(\%('\k\+'\|\"\k\+\"\|`\k\+`\))<\%(\[\|\]\|{\|}\||\|&\|:\|;\|,\|?\|'\|\"\|\k\|\s\|\n\)\+>" + \ contains=typescriptBraces,typescriptOpSymbols,typescriptEndColons, + \ typescriptParens,typescriptStringS,@typescriptType, + \ typescriptType, + \ styledTagNameString + \ nextgroup=styledDefinition +syn match jsFuncCall "\.\\s*(\%('\k\+'\|\"\k\+\"\|`\k\+`\))" + \ contains=styledTagNameString +syn match jsFuncCall "\\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 + \ "\\|\\|\\|\\|\" + \ 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 + \ "\\|\\|\\|\\|\" + \ 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/build b/build index 19a5a0c..a2a720e 100755 --- a/build +++ b/build @@ -25,8 +25,10 @@ download() { for pack in $1; do path="$(cut -d ':' -f 2 <<<"$pack")" dir="tmp/$(cut -d '/' -f 2 <<<"$path")" + repo="$(awk -F\# '{print $1}' <<<"$path")" + branch="$(awk -F\# '{print $2}' <<<"$path")" rm -rf "$dir" - (mkdir -p "$dir" && curl --silent -L "https://codeload.github.com/$path/tar.gz/master" | tar -zx -C "$dir" --strip 1 && printf '.') & + (mkdir -p "$dir" && curl --silent -L "https://codeload.github.com/$repo/tar.gz/${branch:-master}" | tar -zx -C "$dir" --strip 1 && printf '.') & done wait @@ -268,6 +270,7 @@ PACKS=" slime:slime-lang/vim-slime-syntax smt2:bohlender/vim-smt2 solidity:tomlion/vim-solidity + styled-components:styled-components/vim-styled-components#main stylus:wavded/vim-stylus svg-indent:jasonshell/vim-svg-indent svg:vim-scripts/svg.vim