blob: 16e114778d7194f1b5816ac09e07ad18388cd49e [file] [log] [blame]
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +02001" Vim syntax file
2" Language: Scala
3" Maintainer: Derek Wyatt
4" URL: https://github.com/derekwyatt/vim-scala
5" License: Same as Vim
Bram Moolenaar89a9c152021-08-29 21:55:35 +02006" Last Change: 23 August 2021
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +02007" ----------------------------------------------------------------------------
8
9if !exists('main_syntax')
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020010 " quit when a syntax file was already loaded
11 if exists("b:current_syntax")
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +020012 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
Bram Moolenaar6aa57292021-08-14 21:25:52 +020069hi link scalaEscapedChar Special
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +020070hi link scalaUnicodeChar Special
71
72syn match scalaOperator "||"
73syn match scalaOperator "&&"
Bram Moolenaar036986f2017-03-16 17:41:02 +010074syn match scalaOperator "|"
75syn match scalaOperator "&"
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +020076hi 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
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200105syn match scalaTypeTypeExtension /)\?\_s*\zs\%(⇒\|=>\|<:\|:>\|=:=\|::\|#\)/ contained contains=scalaTypeOperator nextgroup=scalaTypeTypeDeclaration skipwhite
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +0200106syn match scalaTypeTypePostDeclaration /\<[_\.A-Za-z0-9$]\+\>/ contained nextgroup=scalaTypeTypePostExtension skipwhite
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200107syn match scalaTypeTypePostExtension /\%(⇒\|=>\|<:\|:>\|=:=\|::\)/ contained contains=scalaTypeOperator nextgroup=scalaTypeTypePostDeclaration skipwhite
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +0200108hi 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
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200116syn match scalaTypeExtension /)\?\_s*\zs\%(⇒\|=>\|<:\|:>\|=:=\|::\|#\)/ contained contains=scalaTypeOperator nextgroup=scalaTypeDeclaration skipwhite
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +0200117hi 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
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200123hi clear scalaTypeAnnotation
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +0200124
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200125syn match scalaCaseFollowing /\<[_\.A-Za-z0-9$]\+\>/ contained contains=scalaCapitalWord
126syn match scalaCaseFollowing /`[^`]\+`/ contained contains=scalaCapitalWord
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +0200127hi link scalaCaseFollowing Special
128
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200129syn keyword scalaKeywordModifier abstract override final lazy implicit private protected sealed null super
130syn keyword scalaSpecialFunction implicitly require
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +0200131hi link scalaKeywordModifier Function
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200132hi link scalaSpecialFunction Function
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +0200133
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
Bram Moolenaar036986f2017-03-16 17:41:02 +0100149syn region scalaTripleIString matchgroup=scalaInterpolationBrackets start=/\<[a-zA-Z][a-zA-Z0-9_]*"""/ end=/"""\ze\%([^"]\|$\)/ contains=scalaInterpolation,scalaInterpolationB,scalaEscapedChar,scalaUnicodeChar
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +0200150hi 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
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200156hi clear scalaInterpolationB
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +0200157
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
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200163hi clear scalaFInterpolationB
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +0200164
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
Bram Moolenaare4a3bcf2016-08-26 19:52:37 +0200204hi 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: