1" Vim syntax file 2" Language: Scala 3" Maintainer: Derek Wyatt 4" URL: https://github.com/derekwyatt/vim-scala 5" License: Same as Vim 6" Last Change: 23 August 2021 7" ---------------------------------------------------------------------------- 8 9if !exists('main_syntax') 10 " quit when a syntax file was already loaded 11 if exists("b:current_syntax") 12 finish 13 endif 14 let main_syntax = 'scala' 15endif 16 17scriptencoding utf-8 18 19let b:current_syntax = "scala" 20 21" Allows for embedding, see #59; main_syntax convention instead? Refactor TOP 22" 23" The @Spell here is a weird hack, it means *exclude* if the first group is 24" TOP. Otherwise we get spelling errors highlighted on code elements that 25" match scalaBlock, even with `syn spell notoplevel`. 26function! s:ContainedGroup() 27 try 28 silent syn list @scala 29 return '@scala,@NoSpell' 30 catch /E392/ 31 return 'TOP,@Spell' 32 endtry 33endfunction 34 35unlet! b:current_syntax 36 37syn case match 38syn sync minlines=200 maxlines=1000 39 40syn keyword scalaKeyword catch do else final finally for forSome if 41syn keyword scalaKeyword match return throw try while yield macro 42syn keyword scalaKeyword class trait object extends with nextgroup=scalaInstanceDeclaration skipwhite 43syn keyword scalaKeyword case nextgroup=scalaKeyword,scalaCaseFollowing skipwhite 44syn keyword scalaKeyword val nextgroup=scalaNameDefinition,scalaQuasiQuotes skipwhite 45syn keyword scalaKeyword def var nextgroup=scalaNameDefinition skipwhite 46hi link scalaKeyword Keyword 47 48exe 'syn region scalaBlock start=/{/ end=/}/ contains=' . s:ContainedGroup() . ' fold' 49 50syn keyword scalaAkkaSpecialWord when goto using startWith initialize onTransition stay become unbecome 51hi link scalaAkkaSpecialWord PreProc 52 53syn keyword scalatestSpecialWord shouldBe 54syn match scalatestShouldDSLA /^\s\+\zsit should/ 55syn match scalatestShouldDSLB /\<should\>/ 56hi link scalatestSpecialWord PreProc 57hi link scalatestShouldDSLA PreProc 58hi link scalatestShouldDSLB PreProc 59 60syn match scalaSymbol /'[_A-Za-z0-9$]\+/ 61hi link scalaSymbol Number 62 63syn match scalaChar /'.'/ 64syn match scalaChar /'\\[\\"'ntbrf]'/ contains=scalaEscapedChar 65syn match scalaChar /'\\u[A-Fa-f0-9]\{4}'/ contains=scalaUnicodeChar 66syn match scalaEscapedChar /\\[\\"'ntbrf]/ 67syn match scalaUnicodeChar /\\u[A-Fa-f0-9]\{4}/ 68hi link scalaChar Character 69hi link scalaEscapedChar Special 70hi link scalaUnicodeChar Special 71 72syn match scalaOperator "||" 73syn match scalaOperator "&&" 74syn match scalaOperator "|" 75syn match scalaOperator "&" 76hi link scalaOperator Special 77 78syn match scalaNameDefinition /\<[_A-Za-z0-9$]\+\>/ contained nextgroup=scalaPostNameDefinition,scalaVariableDeclarationList 79syn match scalaNameDefinition /`[^`]\+`/ contained nextgroup=scalaPostNameDefinition 80syn match scalaVariableDeclarationList /\s*,\s*/ contained nextgroup=scalaNameDefinition 81syn match scalaPostNameDefinition /\_s*:\_s*/ contained nextgroup=scalaTypeDeclaration 82hi link scalaNameDefinition Function 83 84syn match scalaInstanceDeclaration /\<[_\.A-Za-z0-9$]\+\>/ contained nextgroup=scalaInstanceHash 85syn match scalaInstanceDeclaration /`[^`]\+`/ contained 86syn match scalaInstanceHash /#/ contained nextgroup=scalaInstanceDeclaration 87hi link scalaInstanceDeclaration Special 88hi link scalaInstanceHash Type 89 90syn match scalaUnimplemented /???/ 91hi link scalaUnimplemented ERROR 92 93syn match scalaCapitalWord /\<[A-Z][A-Za-z0-9$]*\>/ 94hi link scalaCapitalWord Special 95 96" Handle type declarations specially 97syn region scalaTypeStatement matchgroup=Keyword start=/\<type\_s\+\ze/ end=/$/ contains=scalaTypeTypeDeclaration,scalaSquareBrackets,scalaTypeTypeEquals,scalaTypeStatement 98 99" Ugh... duplication of all the scalaType* stuff to handle special highlighting 100" of `type X =` declarations 101syn match scalaTypeTypeDeclaration /(/ contained nextgroup=scalaTypeTypeExtension,scalaTypeTypeEquals contains=scalaRoundBrackets skipwhite 102syn match scalaTypeTypeDeclaration /\%(⇒\|=>\)\ze/ contained nextgroup=scalaTypeTypeDeclaration contains=scalaTypeTypeExtension skipwhite 103syn match scalaTypeTypeDeclaration /\<[_\.A-Za-z0-9$]\+\>/ contained nextgroup=scalaTypeTypeExtension,scalaTypeTypeEquals skipwhite 104syn match scalaTypeTypeEquals /=\ze[^>]/ contained nextgroup=scalaTypeTypePostDeclaration skipwhite 105syn match scalaTypeTypeExtension /)\?\_s*\zs\%(⇒\|=>\|<:\|:>\|=:=\|::\|#\)/ contained contains=scalaTypeOperator nextgroup=scalaTypeTypeDeclaration skipwhite 106syn match scalaTypeTypePostDeclaration /\<[_\.A-Za-z0-9$]\+\>/ contained nextgroup=scalaTypeTypePostExtension skipwhite 107syn match scalaTypeTypePostExtension /\%(⇒\|=>\|<:\|:>\|=:=\|::\)/ contained contains=scalaTypeOperator nextgroup=scalaTypeTypePostDeclaration skipwhite 108hi link scalaTypeTypeDeclaration Type 109hi link scalaTypeTypeExtension Keyword 110hi link scalaTypeTypePostDeclaration Special 111hi link scalaTypeTypePostExtension Keyword 112 113syn match scalaTypeDeclaration /(/ contained nextgroup=scalaTypeExtension contains=scalaRoundBrackets skipwhite 114syn match scalaTypeDeclaration /\%(⇒\|=>\)\ze/ contained nextgroup=scalaTypeDeclaration contains=scalaTypeExtension skipwhite 115syn match scalaTypeDeclaration /\<[_\.A-Za-z0-9$]\+\>/ contained nextgroup=scalaTypeExtension skipwhite 116syn match scalaTypeExtension /)\?\_s*\zs\%(⇒\|=>\|<:\|:>\|=:=\|::\|#\)/ contained contains=scalaTypeOperator nextgroup=scalaTypeDeclaration skipwhite 117hi link scalaTypeDeclaration Type 118hi link scalaTypeExtension Keyword 119hi link scalaTypePostExtension Keyword 120 121syn match scalaTypeAnnotation /\%([_a-zA-Z0-9$\s]:\_s*\)\ze[_=(\.A-Za-z0-9$]\+/ skipwhite nextgroup=scalaTypeDeclaration contains=scalaRoundBrackets 122syn match scalaTypeAnnotation /)\_s*:\_s*\ze[_=(\.A-Za-z0-9$]\+/ skipwhite nextgroup=scalaTypeDeclaration 123hi clear scalaTypeAnnotation 124 125syn match scalaCaseFollowing /\<[_\.A-Za-z0-9$]\+\>/ contained contains=scalaCapitalWord 126syn match scalaCaseFollowing /`[^`]\+`/ contained contains=scalaCapitalWord 127hi link scalaCaseFollowing Special 128 129syn keyword scalaKeywordModifier abstract override final lazy implicit private protected sealed null super 130syn keyword scalaSpecialFunction implicitly require 131hi link scalaKeywordModifier Function 132hi link scalaSpecialFunction Function 133 134syn keyword scalaSpecial this true false ne eq 135syn keyword scalaSpecial new nextgroup=scalaInstanceDeclaration skipwhite 136syn match scalaSpecial "\%(=>\|⇒\|<-\|←\|->\|→\)" 137syn match scalaSpecial /`[^`]\+`/ " Backtick literals 138hi link scalaSpecial PreProc 139 140syn keyword scalaExternal package import 141hi link scalaExternal Include 142 143syn match scalaStringEmbeddedQuote /\\"/ contained 144syn region scalaString start=/"/ end=/"/ contains=scalaStringEmbeddedQuote,scalaEscapedChar,scalaUnicodeChar 145hi link scalaString String 146hi link scalaStringEmbeddedQuote String 147 148syn region scalaIString matchgroup=scalaInterpolationBrackets start=/\<[a-zA-Z][a-zA-Z0-9_]*"/ skip=/\\"/ end=/"/ contains=scalaInterpolation,scalaInterpolationB,scalaEscapedChar,scalaUnicodeChar 149syn region scalaTripleIString matchgroup=scalaInterpolationBrackets start=/\<[a-zA-Z][a-zA-Z0-9_]*"""/ end=/"""\ze\%([^"]\|$\)/ contains=scalaInterpolation,scalaInterpolationB,scalaEscapedChar,scalaUnicodeChar 150hi link scalaIString String 151hi link scalaTripleIString String 152 153syn match scalaInterpolation /\$[a-zA-Z0-9_$]\+/ contained 154exe 'syn region scalaInterpolationB matchgroup=scalaInterpolationBoundary start=/\${/ end=/}/ contained contains=' . s:ContainedGroup() 155hi link scalaInterpolation Function 156hi clear scalaInterpolationB 157 158syn region scalaFString matchgroup=scalaInterpolationBrackets start=/f"/ skip=/\\"/ end=/"/ contains=scalaFInterpolation,scalaFInterpolationB,scalaEscapedChar,scalaUnicodeChar 159syn match scalaFInterpolation /\$[a-zA-Z0-9_$]\+\(%[-A-Za-z0-9\.]\+\)\?/ contained 160exe 'syn region scalaFInterpolationB matchgroup=scalaInterpolationBoundary start=/${/ end=/}\(%[-A-Za-z0-9\.]\+\)\?/ contained contains=' . s:ContainedGroup() 161hi link scalaFString String 162hi link scalaFInterpolation Function 163hi clear scalaFInterpolationB 164 165syn region scalaTripleString start=/"""/ end=/"""\%([^"]\|$\)/ contains=scalaEscapedChar,scalaUnicodeChar 166syn region scalaTripleFString matchgroup=scalaInterpolationBrackets start=/f"""/ end=/"""\%([^"]\|$\)/ contains=scalaFInterpolation,scalaFInterpolationB,scalaEscapedChar,scalaUnicodeChar 167hi link scalaTripleString String 168hi link scalaTripleFString String 169 170hi link scalaInterpolationBrackets Special 171hi link scalaInterpolationBoundary Function 172 173syn match scalaNumber /\<0[dDfFlL]\?\>/ " Just a bare 0 174syn match scalaNumber /\<[1-9]\d*[dDfFlL]\?\>/ " A multi-digit number - octal numbers with leading 0's are deprecated in Scala 175syn match scalaNumber /\<0[xX][0-9a-fA-F]\+[dDfFlL]\?\>/ " Hex number 176syn match scalaNumber /\%(\<\d\+\.\d*\|\.\d\+\)\%([eE][-+]\=\d\+\)\=[fFdD]\=/ " exponential notation 1 177syn match scalaNumber /\<\d\+[eE][-+]\=\d\+[fFdD]\=\>/ " exponential notation 2 178syn match scalaNumber /\<\d\+\%([eE][-+]\=\d\+\)\=[fFdD]\>/ " exponential notation 3 179hi link scalaNumber Number 180 181syn region scalaRoundBrackets start="(" end=")" skipwhite contained contains=scalaTypeDeclaration,scalaSquareBrackets,scalaRoundBrackets 182 183syn region scalaSquareBrackets matchgroup=scalaSquareBracketsBrackets start="\[" end="\]" skipwhite nextgroup=scalaTypeExtension contains=scalaTypeDeclaration,scalaSquareBrackets,scalaTypeOperator,scalaTypeAnnotationParameter 184syn match scalaTypeOperator /[-+=:<>]\+/ contained 185syn match scalaTypeAnnotationParameter /@\<[`_A-Za-z0-9$]\+\>/ contained 186hi link scalaSquareBracketsBrackets Type 187hi link scalaTypeOperator Keyword 188hi link scalaTypeAnnotationParameter Function 189 190syn match scalaShebang "\%^#!.*" display 191syn region scalaMultilineComment start="/\*" end="\*/" contains=scalaMultilineComment,scalaDocLinks,scalaParameterAnnotation,scalaCommentAnnotation,scalaTodo,scalaCommentCodeBlock,@Spell keepend fold 192syn match scalaCommentAnnotation "@[_A-Za-z0-9$]\+" contained 193syn match scalaParameterAnnotation "\%(@tparam\|@param\|@see\)" nextgroup=scalaParamAnnotationValue skipwhite contained 194syn match scalaParamAnnotationValue /[.`_A-Za-z0-9$]\+/ contained 195syn region scalaDocLinks start="\[\[" end="\]\]" contained 196syn region scalaCommentCodeBlock matchgroup=Keyword start="{{{" end="}}}" contained 197syn match scalaTodo "\vTODO|FIXME|XXX" contained 198hi link scalaShebang Comment 199hi link scalaMultilineComment Comment 200hi link scalaDocLinks Function 201hi link scalaParameterAnnotation Function 202hi link scalaParamAnnotationValue Keyword 203hi link scalaCommentAnnotation Function 204hi link scalaCommentCodeBlock String 205hi link scalaTodo Todo 206 207syn match scalaAnnotation /@\<[`_A-Za-z0-9$]\+\>/ 208hi link scalaAnnotation PreProc 209 210syn match scalaTrailingComment "//.*$" contains=scalaTodo,@Spell 211hi link scalaTrailingComment Comment 212 213syn match scalaAkkaFSM /goto([^)]*)\_s\+\<using\>/ contains=scalaAkkaFSMGotoUsing 214syn match scalaAkkaFSM /stay\_s\+using/ 215syn match scalaAkkaFSM /^\s*stay\s*$/ 216syn match scalaAkkaFSM /when\ze([^)]*)/ 217syn match scalaAkkaFSM /startWith\ze([^)]*)/ 218syn match scalaAkkaFSM /initialize\ze()/ 219syn match scalaAkkaFSM /onTransition/ 220syn match scalaAkkaFSM /onTermination/ 221syn match scalaAkkaFSM /whenUnhandled/ 222syn match scalaAkkaFSMGotoUsing /\<using\>/ 223syn match scalaAkkaFSMGotoUsing /\<goto\>/ 224hi link scalaAkkaFSM PreProc 225hi link scalaAkkaFSMGotoUsing PreProc 226 227let b:current_syntax = 'scala' 228 229if main_syntax ==# 'scala' 230 unlet main_syntax 231endif 232 233" vim:set sw=2 sts=2 ts=8 et: 234