1 " Language: CoffeeScript
2 " Maintainer: Mick Koch <kchmck@gmail.com>
3 " URL: http://github.com/kchmck/vim-coffee-script
6 " Bail if our syntax is already loaded.
7 if exists('b:current_syntax') && b:current_syntax == 'coffee'
15 " Include JavaScript for coffeeEmbed.
16 syn include @coffeeJS syntax/javascript.vim
18 " Highlight long strings.
21 " CoffeeScript identifiers can have dollar signs.
24 " These are `matches` instead of `keywords` because vim's highlighting
25 " priority for keywords is higher than matches. This causes keywords to be
26 " highlighted inside matches, even if a match says it shouldn't contain them --
27 " like with coffeeAssign and coffeeDot.
28 syn match coffeeStatement /\<\%(return\|break\|continue\|throw\)\>/ display
29 hi def link coffeeStatement Statement
31 syn match coffeeRepeat /\<\%(for\|while\|until\|loop\)\>/ display
32 hi def link coffeeRepeat Repeat
34 syn match coffeeConditional /\<\%(if\|else\|unless\|switch\|when\|then\)\>/
36 hi def link coffeeConditional Conditional
38 syn match coffeeException /\<\%(try\|catch\|finally\)\>/ display
39 hi def link coffeeException Exception
41 syn match coffeeKeyword /\<\%(new\|in\|of\|by\|and\|or\|not\|is\|isnt\|class\|extends\|super\|own\|do\)\>/
43 hi def link coffeeKeyword Keyword
45 syn match coffeeOperator /\<\%(instanceof\|typeof\|delete\)\>/ display
46 hi def link coffeeOperator Operator
48 " The first case matches symbol operators only if they have an operand before.
49 syn match coffeeExtendedOp /\%(\S\s*\)\@<=[+\-*/%&|\^=!<>?.]\+\|--\|++\|::/
51 syn match coffeeExtendedOp /\%(and\|or\)=/ display
52 hi def link coffeeExtendedOp coffeeOperator
54 " This is separate from `coffeeExtendedOp` to help differentiate commas from
56 syn match coffeeSpecialOp /[,;]/ display
57 hi def link coffeeSpecialOp SpecialChar
59 syn match coffeeBoolean /\<\%(true\|on\|yes\|false\|off\|no\)\>/ display
60 hi def link coffeeBoolean Boolean
62 syn match coffeeGlobal /\<\%(null\|undefined\)\>/ display
63 hi def link coffeeGlobal Type
66 syn match coffeeSpecialVar /\<\%(this\|prototype\|arguments\)\>/ display
68 syn match coffeeSpecialVar /@\%(\I\i*\)\?/ display
69 hi def link coffeeSpecialVar Special
71 " A class-like name that starts with a capital letter
72 syn match coffeeObject /\<\u\w*\>/ display
73 hi def link coffeeObject Structure
75 " A constant-like name in SCREAMING_CAPS
76 syn match coffeeConstant /\<\u[A-Z0-9_]\+\>/ display
77 hi def link coffeeConstant Constant
80 syn cluster coffeeIdentifier contains=coffeeSpecialVar,coffeeObject,
83 " A non-interpolated string
84 syn cluster coffeeBasicString contains=@Spell,coffeeEscape
85 " An interpolated string
86 syn cluster coffeeInterpString contains=@coffeeBasicString,coffeeInterp
89 syn region coffeeString start=/"/ skip=/\\\\\|\\"/ end=/"/
90 \ contains=@coffeeInterpString
91 syn region coffeeString start=/'/ skip=/\\\\\|\\'/ end=/'/
92 \ contains=@coffeeBasicString
93 hi def link coffeeString String
95 " A integer, including a leading plus or minus
96 syn match coffeeNumber /\i\@<![-+]\?\d\+\%([eE][+-]\?\d\+\)\?/ display
98 syn match coffeeNumber /\<0[xX]\x\+\>/ display
99 hi def link coffeeNumber Number
101 " A floating-point number, including a leading plus or minus
102 syn match coffeeFloat /\i\@<![-+]\?\d*\.\@<!\.\d\+\%([eE][+-]\?\d\+\)\?/
104 hi def link coffeeFloat Float
106 " An error for reserved keywords
107 if !exists("coffee_no_reserved_words_error")
108 syn match coffeeReservedError /\<\%(case\|default\|function\|var\|void\|with\|const\|let\|enum\|export\|import\|native\|__hasProp\|__extends\|__slice\|__bind\|__indexOf\)\>/
110 hi def link coffeeReservedError Error
113 " This is separate from `coffeeExtendedOp` since assignments require it.
114 syn match coffeeAssignOp /:/ contained display
115 hi def link coffeeAssignOp coffeeOperator
117 " Strings used in string assignments, which can't have interpolations
118 syn region coffeeAssignString start=/"/ skip=/\\\\\|\\"/ end=/"/ contained
119 \ contains=@coffeeBasicString
120 syn region coffeeAssignString start=/'/ skip=/\\\\\|\\'/ end=/'/ contained
121 \ contains=@coffeeBasicString
122 hi def link coffeeAssignString String
124 " A normal object assignment
125 syn match coffeeObjAssign /@\?\I\i*\s*:\@<!::\@!/
126 \ contains=@coffeeIdentifier,coffeeAssignOp
127 hi def link coffeeObjAssign Identifier
129 " An object-string assignment
130 syn match coffeeObjStringAssign /\("\|'\)[^\1]*\1\s*;\@<!::\@!'\@!/
131 \ contains=coffeeAssignString,coffeeAssignOp
132 " An object-integer assignment
133 syn match coffeeObjNumberAssign /\d\+\%(\.\d\+\)\?\s*:\@<!::\@!/
134 \ contains=coffeeNumber,coffeeAssignOp
136 syn keyword coffeeTodo TODO FIXME XXX contained
137 hi def link coffeeTodo Todo
139 syn match coffeeComment /#.*/ contains=@Spell,coffeeTodo
140 hi def link coffeeComment Comment
142 syn region coffeeBlockComment start=/####\@!/ end=/###/
143 \ contains=@Spell,coffeeTodo
144 hi def link coffeeBlockComment coffeeComment
146 " A comment in a heregex
147 syn region coffeeHeregexComment start=/#/ end=/\ze\/\/\/\|$/ contained
148 \ contains=@Spell,coffeeTodo
149 hi def link coffeeHeregexComment coffeeComment
151 " Embedded JavaScript
152 syn region coffeeEmbed matchgroup=coffeeEmbedDelim
153 \ start=/`/ skip=/\\\\\|\\`/ end=/`/
155 hi def link coffeeEmbedDelim Delimiter
157 syn region coffeeInterp matchgroup=coffeeInterpDelim start=/#{/ end=/}/ contained
158 \ contains=@coffeeAll
159 hi def link coffeeInterpDelim PreProc
161 " A string escape sequence
162 syn match coffeeEscape /\\\d\d\d\|\\x\x\{2\}\|\\u\x\{4\}\|\\./ contained display
163 hi def link coffeeEscape SpecialChar
165 " A regex -- must not follow a parenthesis, number, or identifier, and must not
166 " be followed by a number
167 syn region coffeeRegex start=/\%(\%()\|\i\@<!\d\)\s*\|\i\)\@<!\/=\@!\s\@!/
168 \ skip=/\[[^\]]\{-}\/[^\]]\{-}\]/
169 \ end=/\/[gimy]\{,4}\d\@!/
170 \ oneline contains=@coffeeBasicString
171 hi def link coffeeRegex String
174 syn region coffeeHeregex start=/\/\/\// end=/\/\/\/[gimy]\{,4}/
175 \ contains=@coffeeInterpString,coffeeHeregexComment
177 hi def link coffeeHeregex coffeeRegex
180 syn region coffeeHeredoc start=/"""/ end=/"""/ contains=@coffeeInterpString
182 syn region coffeeHeredoc start=/'''/ end=/'''/ contains=@coffeeBasicString
184 hi def link coffeeHeredoc String
186 " An error for trailing whitespace, as long as the line isn't just whitespace
187 if !exists("coffee_no_trailing_space_error")
188 syn match coffeeSpaceError /\S\@<=\s\+$/ display
189 hi def link coffeeSpaceError Error
192 " An error for trailing semicolons, for help transitioning from JavaScript
193 if !exists("coffee_no_trailing_semicolon_error")
194 syn match coffeeSemicolonError /;$/ display
195 hi def link coffeeSemicolonError Error
198 " Ignore reserved words in dot accesses.
199 syn match coffeeDotAccess /\.\@<!\.\s*\I\i*/he=s+1 contains=@coffeeIdentifier
200 hi def link coffeeDotAccess coffeeExtendedOp
202 " Ignore reserved words in prototype accesses.
203 syn match coffeeProtoAccess /::\s*\I\i*/he=s+2 contains=@coffeeIdentifier
204 hi def link coffeeProtoAccess coffeeExtendedOp
206 " This is required for interpolations to work.
207 syn region coffeeCurlies matchgroup=coffeeCurly start=/{/ end=/}/
208 \ contains=@coffeeAll
209 syn region coffeeBrackets matchgroup=coffeeBracket start=/\[/ end=/\]/
210 \ contains=@coffeeAll
211 syn region coffeeParens matchgroup=coffeeParen start=/(/ end=/)/
212 \ contains=@coffeeAll
214 " These are highlighted the same as commas since they tend to go together.
215 hi def link coffeeBlock coffeeSpecialOp
216 hi def link coffeeBracket coffeeBlock
217 hi def link coffeeCurly coffeeBlock
218 hi def link coffeeParen coffeeBlock
220 " This is used instead of TOP to keep things coffee-specific for good
221 " embedding. `contained` groups aren't included.
222 syn cluster coffeeAll contains=coffeeStatement,coffeeRepeat,coffeeConditional,
223 \ coffeeException,coffeeKeyword,coffeeOperator,
224 \ coffeeExtendedOp,coffeeSpecialOp,coffeeBoolean,
225 \ coffeeGlobal,coffeeSpecialVar,coffeeObject,
226 \ coffeeConstant,coffeeString,coffeeNumber,
227 \ coffeeFloat,coffeeReservedError,coffeeObjAssign,
228 \ coffeeObjStringAssign,coffeeObjNumberAssign,
229 \ coffeeComment,coffeeBlockComment,coffeeEmbed,
230 \ coffeeRegex,coffeeHeregex,coffeeHeredoc,
231 \ coffeeSpaceError,coffeeSemicolonError,
232 \ coffeeDotAccess,coffeeProtoAccess,
233 \ coffeeCurlies,coffeeBrackets,coffeeParens
235 if !exists('b:current_syntax')
236 let b:current_syntax = 'coffee'