1 " Language: CoffeeScript
2 " Maintainer: Mick Koch <kchmck@gmail.com>
3 " URL: http://github.com/kchmck/vim-coffee-script
6 if exists("b:current_syntax")
14 " Include JavaScript for coffeeEmbed.
15 syn include @coffeeJS syntax/javascript.vim
17 " Highlight long strings.
20 " CoffeeScript allows dollar signs in identifiers.
23 " These are `matches` instead of `keywords` because vim's highlighting
24 " priority for keywords is higher than matches. This causes keywords to be
25 " highlighted inside matches, even if a match says it shouldn't contain them --
26 " like with coffeeAssign and coffeeDot.
27 syn match coffeeStatement /\<\%(return\|break\|continue\|throw\)\>/
28 hi def link coffeeStatement Statement
30 syn match coffeeRepeat /\<\%(for\|while\|until\|loop\)\>/
31 hi def link coffeeRepeat Repeat
33 syn match coffeeConditional /\<\%(if\|else\|unless\|switch\|when\|then\)\>/
34 hi def link coffeeConditional Conditional
36 syn match coffeeException /\<\%(try\|catch\|finally\)\>/
37 hi def link coffeeException Exception
39 syn match coffeeOperator /\<\%(instanceof\|typeof\|delete\)\>/
40 hi def link coffeeOperator Operator
42 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 coffeeBoolean /\<\%(true\|on\|yes\|false\|off\|no\)\>/
46 hi def link coffeeBoolean Boolean
48 syn match coffeeGlobal /\<\%(null\|undefined\)\>/
49 hi def link coffeeGlobal Type
51 " Keywords reserved by the language
52 syn cluster coffeeReserved contains=coffeeStatement,coffeeRepeat,
53 \ coffeeConditional,coffeeException,
54 \ coffeeOperator,coffeeKeyword,
55 \ coffeeBoolean,coffeeGlobal
58 syn match coffeeSpecialVar /\<\%(this\|prototype\|arguments\)\>/
60 syn match coffeeSpecialVar /@\%(\I\i*\)\?/
61 hi def link coffeeSpecialVar Special
63 " A class-like name that starts with a capital letter
64 syn match coffeeObject /\<\u\w*\>/
65 hi def link coffeeObject Structure
67 " A constant-like name in SCREAMING_CAPS
68 syn match coffeeConstant /\<\u[A-Z0-9_]\+\>/
69 hi def link coffeeConstant Constant
72 syn cluster coffeeIdentifier contains=coffeeSpecialVar,coffeeObject,
73 \ coffeeConstant,coffeePrototype
75 " A non-interpolated string
76 syn cluster coffeeBasicString contains=@Spell,coffeeEscape
77 " An interpolated string
78 syn cluster coffeeInterpString contains=@coffeeBasicString,coffeeInterp
81 syn region coffeeString start=/"/ skip=/\\\\\|\\"/ end=/"/
82 \ contains=@coffeeInterpString
83 syn region coffeeString start=/'/ skip=/\\\\\|\\'/ end=/'/
84 \ contains=@coffeeBasicString
85 hi def link coffeeString String
87 " A integer, including a leading plus or minus
88 syn match coffeeNumber /\i\@<![-+]\?\d\+\%([eE][+-]\?\d\+\)\?/
90 syn match coffeeNumber /\<0[xX]\x\+\>/
91 hi def link coffeeNumber Number
93 " A floating-point number, including a leading plus or minus
94 syn match coffeeFloat /\i\@<![-+]\?\d*\.\@<!\.\d\+\%([eE][+-]\?\d\+\)\?/
95 hi def link coffeeFloat Float
97 syn match coffeeAssignSymbols /:\@<!::\@!\|++\|--\|\%(\s\zs\%(and\|or\)\|&&\|||\|?\|+\|-\|\/\|\*\|%\|<<\|>>\|>>>\|&\||\|\^\)\?=\@<!==\@!>\@!/
99 hi def link coffeeAssignSymbols SpecialChar
101 syn match coffeeAssignBrackets /\[.\+\]/ contained contains=TOP,coffeeAssign
103 " A destructuring assignment
104 syn match coffeeAssign /[}\]]\@<=\s*==\@!>\@!/ contains=coffeeAssignSymbols
105 " A pre-increment or pre-decrement assignment
106 syn match coffeeAssign /\%(++\|--\)\s*\%(@\|@\?\I\)\%(\i\|::\|\.\|?\|\[.\+\]\)*/
107 \ contains=@coffeeIdentifier,coffeeAssignSymbols,
108 \ coffeeAssignBrackets
109 " A normal assignment, or a post-increment or post-decrement assignment
110 syn match coffeeAssign /\%(@\|@\?\I\)\%(\i\|::\|\.\|?\|\[.\+\]\)*\%(++\|--\|\s*\%(and\|or\|&&\|||\|?\|+\|-\|\/\|\*\|%\|<<\|>>\|>>>\|&\||\|\^\)\?=\@<!==\@!>\@!\)/
111 \ contains=@coffeeIdentifier,coffeeAssignSymbols,
112 \ coffeeAssignBrackets
113 hi def link coffeeAssign Identifier
115 " An error for reserved keywords
116 if !exists("coffee_no_reserved_words_error")
117 syn match coffeeReservedError /\<\%(case\|default\|function\|var\|void\|with\|const\|let\|enum\|export\|import\|native\|__hasProp\|__extends\|__slice\|__bind\|__indexOf\)\>/
118 hi def link coffeeReservedError Error
121 " A normal object assignment
122 syn match coffeeObjAssign /@\?\I\i*\s*:\@<!::\@!/
123 \ contains=@coffeeIdentifier,coffeeAssignSymbols
124 hi def link coffeeObjAssign coffeeAssign
126 " Strings used in string assignments, which can't have interpolations
127 syn region coffeeAssignString start=/"/ skip=/\\\\\|\\"/ end=/"/
128 \ contained contains=@coffeeBasicString
129 syn region coffeeAssignString start=/'/ skip=/\\\\\|\\'/ end=/'/
130 \ contained contains=@coffeeBasicString
131 hi def link coffeeAssignString String
133 " An object-string assignment
134 syn match coffeeObjStringAssign /\("\|'\)[^\1]*\1\s*;\@<!::\@!'\@!/
135 \ contains=coffeeAssignString,coffeeAssignSymbols
136 " An object-integer assignment
137 syn match coffeeObjNumberAssign /\d\+\%(\.\d\+\)\?\s*:\@<!::\@!/
138 \ contains=coffeeNumber,coffeeAssignSymbols
140 syn match coffeePrototype /::/
141 hi def link coffeePrototype SpecialChar
143 syn match coffeeFunction /[-=]>/
144 hi def link coffeeFunction Function
146 syn keyword coffeeTodo TODO FIXME XXX contained
147 hi def link coffeeTodo Todo
149 syn match coffeeComment /#.*/ contains=@Spell,coffeeTodo
150 hi def link coffeeComment Comment
152 syn region coffeeBlockComment start=/####\@!/ end=/###/
153 \ contains=@Spell,coffeeTodo
154 hi def link coffeeBlockComment coffeeComment
156 " A comment in a heregex
157 syn region coffeeHeregexComment start=/#/ end=/\ze\/\/\/\|$/
158 \ contained contains=@Spell,coffeeTodo
159 hi def link coffeeHeregexComment coffeeComment
161 " Embedded JavaScript
162 syn region coffeeEmbed matchgroup=coffeeEmbedDelim
163 \ start=/`/ skip=/\\\\\|\\`/ end=/`/
165 hi def link coffeeEmbedDelim Delimiter
167 syn region coffeeInterp matchgroup=coffeeInterpDelim
168 \ start=/\#{/ end=/}/
169 \ contained contains=TOP
170 hi def link coffeeInterpDelim Delimiter
172 " A string escape sequence
173 syn match coffeeEscape /\\\d\d\d\|\\x\x\{2\}\|\\u\x\{4\}\|\\./ contained
174 hi def link coffeeEscape SpecialChar
176 " A regex -- must not follow a parenthesis, number, or identifier, and must not
177 " be followed by a number
178 syn region coffeeRegex start=/\%(\%()\|\i\@<!\d\)\s*\|\i\)\@<!\/\s\@!/
179 \ skip=/\[[^\]]\{-}\/[^\]]\{-}\]/
180 \ end=/\/[gimy]\{,4}\d\@!/
181 \ oneline contains=@coffeeBasicString
182 hi def link coffeeRegex String
185 syn region coffeeHeregex start=/\/\/\// end=/\/\/\/[gimy]\{,4}/
186 \ contains=@coffeeInterpString,coffeeHeregexComment
188 hi def link coffeeHeregex coffeeRegex
191 syn region coffeeHeredoc start=/"""/ end=/"""/ contains=@coffeeInterpString
193 syn region coffeeHeredoc start=/'''/ end=/'''/ contains=@coffeeBasicString
195 hi def link coffeeHeredoc String
197 " An error for trailing whitespace, as long as the line isn't just whitespace
198 if !exists("coffee_no_trailing_space_error")
199 syn match coffeeSpaceError /\S\@<=\s\+$/ display
200 hi def link coffeeSpaceError Error
203 " An error for trailing semicolons, for help transitioning from JavaScript
204 if !exists("coffee_no_trailing_semicolon_error")
205 syn match coffeeSemicolonError /;$/ display
206 hi def link coffeeSemicolonError Error
209 " Ignore reserved words in dot-properties.
210 syn match coffeeDot /\.\@<!\.\i\+/ contains=ALLBUT,@coffeeReserved,
211 \ coffeeReservedError
214 let b:current_syntax = "coffee"