blob: c951fcfe1d92bb96c1e314dfafca1bdd81caa93e [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001" Vim syntax file
Bram Moolenaarc6249bb2006-04-15 20:25:09 +00002" Language: Ruby
3" Maintainer: Doug Kearns <dougkearns@gmail.com>
Bram Moolenaarec7944a2013-06-12 21:29:15 +02004" URL: https://github.com/vim-ruby/vim-ruby
Bram Moolenaarc6249bb2006-04-15 20:25:09 +00005" Release Coordinator: Doug Kearns <dougkearns@gmail.com>
Bram Moolenaar46eea442022-03-30 10:51:39 +01006" Last Change: 2021 Nov 03
Bram Moolenaar6b730e12005-09-16 21:47:57 +00007" ----------------------------------------------------------------------------
8"
Bram Moolenaar071d4272004-06-13 20:20:40 +00009" Previous Maintainer: Mirko Nasato
Bram Moolenaar071d4272004-06-13 20:20:40 +000010" Thanks to perl.vim authors, and to Reimer Behrends. :-) (MN)
Bram Moolenaar6b730e12005-09-16 21:47:57 +000011" ----------------------------------------------------------------------------
Bram Moolenaar071d4272004-06-13 20:20:40 +000012
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020013" Prelude {{{1
Bram Moolenaarc1762cc2007-05-10 16:56:30 +000014if exists("b:current_syntax")
Bram Moolenaar071d4272004-06-13 20:20:40 +000015 finish
16endif
17
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020018" this file uses line continuations
19let s:cpo_sav = &cpo
20set cpo&vim
21
Bram Moolenaar2ed639a2019-12-09 23:11:18 +010022" eRuby Config {{{1
23if exists('main_syntax') && main_syntax == 'eruby'
24 let b:ruby_no_expensive = 1
25endif
26
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020027" Folding Config {{{1
Bram Moolenaar6b730e12005-09-16 21:47:57 +000028if has("folding") && exists("ruby_fold")
29 setlocal foldmethod=syntax
30endif
31
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020032let s:foldable_groups = split(
33 \ get(
34 \ b:,
35 \ 'ruby_foldable_groups',
36 \ get(g:, 'ruby_foldable_groups', 'ALL')
37 \ )
38 \ )
39
40function! s:foldable(...) abort
Bram Moolenaar2ed639a2019-12-09 23:11:18 +010041 if index(s:foldable_groups, 'NONE') > -1
42 return 0
43 endif
44
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020045 if index(s:foldable_groups, 'ALL') > -1
46 return 1
47 endif
48
49 for l:i in a:000
50 if index(s:foldable_groups, l:i) > -1
51 return 1
52 endif
53 endfor
54
55 return 0
Bram Moolenaar2ed639a2019-12-09 23:11:18 +010056endfunction
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020057
Bram Moolenaar2ed639a2019-12-09 23:11:18 +010058function! s:run_syntax_fold(args) abort
59 let [_0, _1, groups, cmd; _] = matchlist(a:args, '\(["'']\)\(.\{-}\)\1\s\+\(.*\)')
60 if call('s:foldable', split(groups))
61 let cmd .= ' fold'
62 endif
63 exe cmd
64endfunction
65
66com! -nargs=* SynFold call s:run_syntax_fold(<q-args>)
67
68" Not-Top Cluster {{{1
Bram Moolenaar46eea442022-03-30 10:51:39 +010069syn cluster rubyNotTop contains=@rubyCommentNotTop,@rubyStringNotTop,@rubyRegexpSpecial,@rubyDeclaration,@rubyExceptionHandler,@rubyClassOperator,rubyConditional,rubyModuleName,rubyClassName,rubySymbolDelimiter,rubyDoubleQuoteSymbolDelimiter,rubySingleQuoteSymbolDelimiter,rubyParentheses,@Spell
Bram Moolenaarc236c162008-07-13 17:41:49 +000070
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020071" Whitespace Errors {{{1
Bram Moolenaar6b730e12005-09-16 21:47:57 +000072if exists("ruby_space_errors")
73 if !exists("ruby_no_trail_space_error")
74 syn match rubySpaceError display excludenl "\s\+$"
75 endif
76 if !exists("ruby_no_tab_space_error")
77 syn match rubySpaceError display " \+\t"me=e-1
78 endif
79endif
80
Bram Moolenaar89bcfda2016-08-30 23:26:57 +020081" Operators {{{1
Bram Moolenaar2ed639a2019-12-09 23:11:18 +010082
83syn match rubyEnglishBooleanOperator "\<\%(and\|or\|not\)\>"
84
85if exists("ruby_operators") || exists("ruby_pseudo_operators")
86 syn match rubyDotOperator "\.\|&\."
87
88 syn match rubyTernaryOperator "\%(\w\|[^\x00-\x7F]\)\@1<!?\|:"
89 syn match rubyArithmeticOperator "\*\*\|[*/%+]\|->\@!"
90 syn match rubyComparisonOperator "<=>\|<=\|<\|>=\|[-=]\@1<!>"
91 syn match rubyBitwiseOperator "[~^|]\|&\.\@!\|<<\|>>"
92 syn match rubyBooleanOperator "\%(\w\|[^\x00-\x7F]\)\@1<!!\|&&\|||"
93 syn match rubyRangeOperator "\.\.\.\="
94 syn match rubyAssignmentOperator "=>\@!\|-=\|/=\|\*\*=\|\*=\|&&=\|&=\|||=\||=\|%=\|+=\|>>=\|<<=\|\^="
Bram Moolenaar4d8f4762021-06-27 15:18:56 +020095 syn match rubyAssignmentOperator "=>\@!" contained containedin=rubyBlockParameterList " TODO: this is inelegant
Bram Moolenaar2ed639a2019-12-09 23:11:18 +010096 syn match rubyEqualityOperator "===\|==\|!=\|!\~\|=\~"
97
98 syn region rubyBracketOperator matchgroup=rubyOperator start="\%(\%(\w\|[^\x00-\x7F]\)[?!]\=\|[]})]\)\@2<=\[" end="]" contains=ALLBUT,@rubyNotTop
99
100 syn match rubyScopeOperator "::"
101 syn match rubySuperClassOperator "<" contained
102 syn match rubyEigenClassOperator "<<" contained
103 syn match rubyLambdaOperator "->"
104 syn match rubySplatOperator "\%([[{(|,=]\_s*\)\@<=\*"
105 syn match rubySplatOperator "\%(^\|\s\)\@1<=\*\%(\h\|[^\x00-\x7F]\|[:$@[]\)\@="
106 syn match rubyDoubleSplatOperator "\%([{(|,]\_s*\)\@<=\*\*"
107 syn match rubyDoubleSplatOperator "\s\@1<=\*\*\%(\h\|[^\x00-\x7F]\|[:$@{]\)\@="
108 syn match rubyProcOperator "\%([[(|,]\_s*\)\@<=&"
109 syn match rubyProcOperator "\s\@1<=&\%(\h\|[^\x00-\x7F]\|[:$@]\|->\)\@="
110
111 syn cluster rubyProperOperator contains=rubyTernaryOperator,rubyArithmeticOperator,rubyComparisonOperator,rubyBitwiseOperator,rubyBooleanOperator,rubyRangeOperator,rubyAssignmentOperator,rubyEqualityOperator,rubyDefinedOperator,rubyEnglishBooleanOperator
112 syn cluster rubyClassOperator contains=rubyEigenClassOperator,rubySuperClassOperator
113 syn cluster rubyPseudoOperator contains=rubyDotOperator,rubyScopeOperator,rubyEigenClassOperator,rubySuperClassOperator,rubyLambdaOperator,rubySplatOperator,rubyDoubleSplatOperator,rubyProcOperator
114 syn cluster rubyOperator contains=ruby.*Operator
Bram Moolenaar9964e462007-05-05 17:54:07 +0000115endif
116
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100117" String Interpolation and Backslash Notation {{{1
Bram Moolenaarc236c162008-07-13 17:41:49 +0000118syn region rubyInterpolation matchgroup=rubyInterpolationDelimiter start="#{" end="}" contained contains=ALLBUT,@rubyNotTop
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100119syn match rubyInterpolation "#\$\%(-\w\|[!$&"'*+,./0:;<>?@\`~_]\|\w\+\)" display contained contains=rubyInterpolationDelimiter,@rubyGlobalVariable
120syn match rubyInterpolation "#@@\=\w\+" display contained contains=rubyInterpolationDelimiter,rubyInstanceVariable,rubyClassVariable
121syn match rubyInterpolationDelimiter "#\ze[$@]" display contained
Bram Moolenaar6b730e12005-09-16 21:47:57 +0000122
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100123syn match rubyStringEscape "\\\_." contained display
124syn match rubyStringEscape "\\\o\{1,3}\|\\x\x\{1,2}" contained display
125syn match rubyStringEscape "\\u\%(\x\{4}\|{\x\{1,6}\%(\s\+\x\{1,6}\)*}\)" contained display
126syn match rubyStringEscape "\%(\\M-\\C-\|\\C-\\M-\|\\M-\\c\|\\c\\M-\|\\c\|\\C-\|\\M-\)\%(\\\o\{1,3}\|\\x\x\{1,2}\|\\\=.\)" contained display
127
128syn match rubyBackslashEscape "\\\\" contained display
129syn match rubyQuoteEscape "\\'" contained display
130syn match rubySpaceEscape "\\ " contained display
131
132syn match rubyParenthesisEscape "\\[()]" contained display
133syn match rubyCurlyBraceEscape "\\[{}]" contained display
134syn match rubyAngleBracketEscape "\\[<>]" contained display
135syn match rubySquareBracketEscape "\\[[\]]" contained display
Bram Moolenaar6b730e12005-09-16 21:47:57 +0000136
Bram Moolenaar4d8f4762021-06-27 15:18:56 +0200137syn region rubyNestedParentheses start="(" skip="\\\\\|\\)" end=")" transparent contained
138syn region rubyNestedCurlyBraces start="{" skip="\\\\\|\\}" end="}" transparent contained
139syn region rubyNestedAngleBrackets start="<" skip="\\\\\|\\>" end=">" transparent contained
140syn region rubyNestedSquareBrackets start="\[" skip="\\\\\|\\\]" end="\]" transparent contained
Bram Moolenaar6b730e12005-09-16 21:47:57 +0000141
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100142syn cluster rubySingleCharEscape contains=rubyBackslashEscape,rubyQuoteEscape,rubySpaceEscape,rubyParenthesisEscape,rubyCurlyBraceEscape,rubyAngleBracketEscape,rubySquareBracketEscape
143syn cluster rubyNestedBrackets contains=rubyNested.\+
144syn cluster rubyStringSpecial contains=rubyInterpolation,rubyStringEscape
145syn cluster rubyStringNotTop contains=@rubyStringSpecial,@rubyNestedBrackets,@rubySingleCharEscape
146
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200147" Regular Expression Metacharacters {{{1
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100148syn region rubyRegexpComment matchgroup=rubyRegexpSpecial start="(?#" skip="\\\\\|\\)" end=")" contained
149syn region rubyRegexpParens matchgroup=rubyRegexpSpecial start="(\(?:\|?<\=[=!]\|?>\|?<[a-z_]\w*>\|?[imx]*-[imx]*:\=\|\%(?#\)\@!\)" skip="\\\\\|\\)" end=")" contained transparent contains=@rubyRegexpSpecial
150syn region rubyRegexpBrackets matchgroup=rubyRegexpCharClass start="\[\^\=" skip="\\\\\|\\\]" end="\]" contained transparent contains=rubyRegexpBrackets,rubyStringEscape,rubyRegexpEscape,rubyRegexpCharClass,rubyRegexpIntersection oneline
151syn match rubyRegexpCharClass "\\[DdHhRSsWw]" contained display
152syn match rubyRegexpCharClass "\[:\^\=\%(alnum\|alpha\|ascii\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|word\|xdigit\):\]" contained
153syn match rubyRegexpCharClass "\\[pP]{^\=.\{-}}" contained display
154syn match rubyRegexpEscape "\\[].*?+^$|\\/(){}[]" contained " see commit e477f10
155syn match rubyRegexpQuantifier "[*?+][?+]\=" contained display
156syn match rubyRegexpQuantifier "{\d\+\%(,\d*\)\=}?\=" contained display
157syn match rubyRegexpAnchor "[$^]\|\\[ABbGZz]" contained display
158syn match rubyRegexpDot "\.\|\\X" contained display
159syn match rubyRegexpIntersection "&&" contained display
160syn match rubyRegexpSpecial "\\K" contained display
161syn match rubyRegexpSpecial "|" contained display
162syn match rubyRegexpSpecial "\\[1-9]\d\=\d\@!" contained display
163syn match rubyRegexpSpecial "\\k<\%([a-z_]\w*\|-\=\d\+\)\%([+-]\d\+\)\=>" contained display
164syn match rubyRegexpSpecial "\\k'\%([a-z_]\w*\|-\=\d\+\)\%([+-]\d\+\)\='" contained display
165syn match rubyRegexpSpecial "\\g<\%([a-z_]\w*\|-\=\d\+\)>" contained display
166syn match rubyRegexpSpecial "\\g'\%([a-z_]\w*\|-\=\d\+\)'" contained display
Bram Moolenaarc236c162008-07-13 17:41:49 +0000167
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100168syn cluster rubyRegexpSpecial contains=@rubyStringSpecial,rubyRegexpSpecial,rubyRegexpEscape,rubyRegexpBrackets,rubyRegexpCharClass,rubyRegexpDot,rubyRegexpQuantifier,rubyRegexpAnchor,rubyRegexpParens,rubyRegexpComment,rubyRegexpIntersection
Bram Moolenaar071d4272004-06-13 20:20:40 +0000169
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100170" Numbers {{{1
171syn match rubyInteger "\%(\%(\w\|[^\x00-\x7F]\|[]})\"']\s*\)\@<!-\)\=\<0[xX]\x\+\%(_\x\+\)*r\=i\=\>" display
172syn match rubyInteger "\%(\%(\w\|[^\x00-\x7F]\|[]})\"']\s*\)\@<!-\)\=\<\%(0[dD]\)\=\%(0\|[1-9]\d*\%(_\d\+\)*\)r\=i\=\>" display
173syn match rubyInteger "\%(\%(\w\|[^\x00-\x7F]\|[]})\"']\s*\)\@<!-\)\=\<0[oO]\=\o\+\%(_\o\+\)*r\=i\=\>" display
174syn match rubyInteger "\%(\%(\w\|[^\x00-\x7F]\|[]})\"']\s*\)\@<!-\)\=\<0[bB][01]\+\%(_[01]\+\)*r\=i\=\>" display
175syn match rubyFloat "\%(\%(\w\|[^\x00-\x7F]\|[]})\"']\s*\)\@<!-\)\=\<\%(0\|[1-9]\d*\%(_\d\+\)*\)\.\d\+\%(_\d\+\)*r\=i\=\>" display
176syn match rubyFloat "\%(\%(\w\|[^\x00-\x7F]\|[]})\"']\s*\)\@<!-\)\=\<\%(0\|[1-9]\d*\%(_\d\+\)*\)\%(\.\d\+\%(_\d\+\)*\)\=\%([eE][-+]\=\d\+\%(_\d\+\)*\)i\=\>" display
Bram Moolenaar071d4272004-06-13 20:20:40 +0000177
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200178" Identifiers {{{1
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100179syn match rubyClassName "\%(\%(^\|[^.]\)\.\s*\)\@<!\<[[:upper:]]\%(\w\|[^\x00-\x7F]\)*\>\%(\s*(\)\@!" contained
180syn match rubyModuleName "\%(\%(^\|[^.]\)\.\s*\)\@<!\<[[:upper:]]\%(\w\|[^\x00-\x7F]\)*\>\%(\s*(\)\@!" contained
181syn match rubyConstant "\%(\%(^\|[^.]\)\.\s*\)\@<!\<[[:upper:]]\%(\w\|[^\x00-\x7F]\)*\>\%(\s*(\)\@!"
182syn match rubyClassVariable "@@\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*" display
183syn match rubyInstanceVariable "@\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*" display
184syn match rubyGlobalVariable "$\%(\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*\|-.\)"
185syn match rubySymbolDelimiter ":" contained
186syn match rubySymbol "[]})\"':]\@1<!:\%(\^\|\~@\|\~\|<<\|<=>\|<=\|<\|===\|[=!]=\|[=!]\~\|!@\|!\|>>\|>=\|>\||\|-@\|-\|/\|\[]=\|\[]\|\*\*\|\*\|&\|%\|+@\|+\|`\)" contains=rubySymbolDelimiter
187syn match rubySymbol "[]})\"':]\@1<!:\$\%(-.\|[`~<=>_,;:!?/.'"@$*\&+0]\)" contains=rubySymbolDelimiter
188syn match rubySymbol "[]})\"':]\@1<!:\%(\$\|@@\=\)\=\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*" contains=rubySymbolDelimiter
189syn match rubySymbol "[]})\"':]\@1<!:\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*\%([?!=]>\@!\)\=" contains=rubySymbolDelimiter
Bram Moolenaar071d4272004-06-13 20:20:40 +0000190
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100191SynFold ':' syn region rubySymbol matchgroup=rubySymbolDelimiter start="[]})\"':]\@1<!:'" end="'" skip="\\\\\|\\'" contains=rubyQuoteEscape,rubyBackslashEscape
192SynFold ':' syn region rubySymbol matchgroup=rubySymbolDelimiter start="[]})\"':]\@1<!:\"" end="\"" skip="\\\\\|\\\"" contains=@rubyStringSpecial
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200193
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100194syn match rubyCapitalizedMethod "\%(\%(^\|[^.]\)\.\s*\)\@<!\<\u\%(\w\|[^\x00-\x7F]\)*\>\%(\s*(\)\@="
195
Bram Moolenaar4d8f4762021-06-27 15:18:56 +0200196syn region rubyParentheses start="(" end=")" contains=ALLBUT,@rubyNotTop contained containedin=rubyBlockParameterList
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100197syn region rubyBlockParameterList start="\%(\%(\<do\>\|{\)\_s*\)\@32<=|" end="|" contains=ALLBUT,@rubyNotTop,@rubyProperOperator
198
199if exists('ruby_global_variable_error')
200 syn match rubyGlobalVariableError "$[^A-Za-z_]" display
201 syn match rubyGlobalVariableError "$-[^0FIKWadilpvw]" display
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200202endif
203
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100204syn match rubyPredefinedVariable #$[!$&"'*+,./0:;<>?@\`~]#
205syn match rubyPredefinedVariable "$\d\+" display
206syn match rubyPredefinedVariable "$_\>" display
207syn match rubyPredefinedVariable "$-[0FIWadilpvw]\>" display
208syn match rubyPredefinedVariable "$\%(stderr\|stdin\|stdout\)\>" display
209syn match rubyPredefinedVariable "$\%(DEBUG\|FILENAME\|LOADED_FEATURES\|LOAD_PATH\|PROGRAM_NAME\|SAFE\|VERBOSE\)\>" display
210syn match rubyPredefinedConstant "\%(\%(^\|[^.]\)\.\s*\)\@<!\<\%(ARGF\|ARGV\|ENV\|DATA\|STDERR\|STDIN\|STDOUT\|TOPLEVEL_BINDING\)\>\%(\s*(\)\@!"
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200211syn match rubyPredefinedConstant "\%(\%(^\|[^.]\)\.\s*\)\@<!\<\%(RUBY_\%(VERSION\|RELEASE_DATE\|PLATFORM\|PATCHLEVEL\|REVISION\|DESCRIPTION\|COPYRIGHT\|ENGINE\)\)\>\%(\s*(\)\@!"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000212
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100213" Deprecated/removed in 1.9
214syn match rubyPredefinedVariable "$="
215syn match rubyPredefinedVariable "$-K\>" display
216syn match rubyPredefinedVariable "$\%(deferr\|defout\)\>" display
217syn match rubyPredefinedVariable "$KCODE\>" display
218" Deprecated/removed in 2.4
219syn match rubyPredefinedConstant "\%(\%(^\|[^.]\)\.\s*\)\@<!\<\%(FALSE\|NIL\|TRUE\)\>\%(\s*(\)\@!"
Bram Moolenaarc236c162008-07-13 17:41:49 +0000220
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100221syn cluster rubyGlobalVariable contains=rubyGlobalVariable,rubyPredefinedVariable,rubyGlobalVariableError
Bram Moolenaar6b730e12005-09-16 21:47:57 +0000222
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100223" Normal Regular Expressions {{{1
224SynFold '/' syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="\%(\%(^\|\<\%(and\|or\|while\|until\|unless\|if\|elsif\|when\|not\|then\|else\)\|[;\~=!|&(,{[<>?:*+-]\)\s*\)\@<=/" end="/[iomxneus]*" skip="\\\\\|\\/" contains=@rubyRegexpSpecial nextgroup=@rubyModifier skipwhite
225SynFold '/' syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="\%(\%(\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*\)\s\+\)\@<=/\%(=\|\_s\)\@!" end="/[iomxneus]*" skip="\\\\\|\\/" contains=@rubyRegexpSpecial nextgroup=@rubyModifier skipwhite
226
227" Generalized Regular Expressions {{{1
228SynFold '%' syn region rubyRegexp matchgroup=rubyPercentRegexpDelimiter start="%r\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1[iomxneus]*" skip="\\\\\|\\\z1" contains=@rubyRegexpSpecial nextgroup=@rubyModifier skipwhite
229SynFold '%' syn region rubyRegexp matchgroup=rubyPercentRegexpDelimiter start="%r{" end="}[iomxneus]*" skip="\\\\\|\\}" contains=@rubyRegexpSpecial
230SynFold '%' syn region rubyRegexp matchgroup=rubyPercentRegexpDelimiter start="%r<" end=">[iomxneus]*" skip="\\\\\|\\>" contains=@rubyRegexpSpecial,rubyNestedAngleBrackets
231SynFold '%' syn region rubyRegexp matchgroup=rubyPercentRegexpDelimiter start="%r\[" end="\][iomxneus]*" skip="\\\\\|\\\]" contains=@rubyRegexpSpecial
232SynFold '%' syn region rubyRegexp matchgroup=rubyPercentRegexpDelimiter start="%r(" end=")[iomxneus]*" skip="\\\\\|\\)" contains=@rubyRegexpSpecial
233SynFold '%' syn region rubyRegexp matchgroup=rubyPercentRegexpDelimiter start="%r\z(\s\)" end="\z1[iomxneus]*" skip="\\\\\|\\\z1" contains=@rubyRegexpSpecial
234
235" Characters {{{1
236syn match rubyCharacter "\%(\w\|[^\x00-\x7F]\|[]})\"'/]\)\@1<!\%(?\%(\\M-\\C-\|\\C-\\M-\|\\M-\\c\|\\c\\M-\|\\c\|\\C-\|\\M-\)\=\%(\\\o\{1,3}\|\\x\x\{1,2}\|\\[[:space:]]\|\\\=[^[:space:]]\)\)"
237syn match rubyCharacter "\%(\w\|[^\x00-\x7F]\|[]})\"'/]\)\@1<!?\\u\%(\x\{4}\|{\x\{1,6}}\)"
238
239" Normal Strings {{{1
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200240let s:spell_cluster = exists('ruby_spellcheck_strings') ? ',@Spell' : ''
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100241let s:fold_arg = s:foldable('string') ? ' fold' : ''
242exe 'syn region rubyString matchgroup=rubyStringDelimiter start="\"" end="\"" skip="\\\\\|\\\"" contains=@rubyStringSpecial' . s:spell_cluster . s:fold_arg
243exe 'syn region rubyString matchgroup=rubyStringDelimiter start="''" end="''" skip="\\\\\|\\''" contains=rubyQuoteEscape,rubyBackslashEscape' . s:spell_cluster . s:fold_arg
244unlet s:spell_cluster s:fold_arg
Bram Moolenaar6b730e12005-09-16 21:47:57 +0000245
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200246" Shell Command Output {{{1
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100247SynFold 'string' syn region rubyString matchgroup=rubyStringDelimiter start="`" end="`" skip="\\\\\|\\`" contains=@rubyStringSpecial
Bram Moolenaar6b730e12005-09-16 21:47:57 +0000248
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100249" Generalized Single Quoted Strings, Symbols, Array of Strings and Array of Symbols {{{1
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200250
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100251" Non-bracket punctuation delimiters {{{2
252let s:names = { '~': 'Tilde', '`': 'BackQuote', '!': 'Bang', '@': 'At', '#': 'Hash', '$': 'Dollar', '%': 'Percent', '^': 'Caret',
253 \ '&': 'Ampersand', '*': 'Asterix', '_': 'Underscore', '-': 'Dash', '+': 'Plus', '=': 'Equals', '|': 'Bar',
254 \ '\': 'Backslash', ':': 'Colon', ';': 'Semicolon', '"': 'DoubleQuote', "'": 'Quote', ',': 'Comma', '.': 'Period',
255 \ '?': 'QuestionMark', '/': 'ForwardSlash' }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000256
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100257for s:delimiter in keys(s:names)
258 let s:group = 'ruby' . s:names[s:delimiter] . 'Escape'
Bram Moolenaar071d4272004-06-13 20:20:40 +0000259
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100260 if s:delimiter =~ '[\"]'
261 let s:delimiter = '\' . s:delimiter
262 endif
Bram Moolenaar6b730e12005-09-16 21:47:57 +0000263
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100264 exe 'syn match ' . s:group . ' "\V\\' . s:delimiter . '" contained display'
265 exe 'syn cluster rubySingleCharEscape add=' . s:group
266 exe 'SynFold ''%'' syn region rubyString matchgroup=rubyPercentStringDelimiter start="\V%q' . s:delimiter . '" end="\V' . s:delimiter . '" skip="\V\\\\\|\\' . s:delimiter . '" contains=rubyBackslashEscape,' . s:group . ' nextgroup=@rubyModifier skipwhite'
267 exe 'SynFold ''%'' syn region rubyString matchgroup=rubyPercentStringDelimiter start="\V%w' . s:delimiter . '" end="\V' . s:delimiter . '" skip="\V\\\\\|\\' . s:delimiter . '" contains=rubyBackslashEscape,rubySpaceEscape,' . s:group . ' nextgroup=@rubyModifier skipwhite'
268 exe 'SynFold ''%'' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="\V%s' . s:delimiter . '" end="\V' . s:delimiter . '" skip="\V\\\\\|\\' . s:delimiter . '" contains=rubyBackslashEscape,' . s:group . ' nextgroup=@rubyModifier skipwhite'
269 exe 'SynFold ''%'' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="\V%i' . s:delimiter . '" end="\V' . s:delimiter . '" skip="\V\\\\\|\\' . s:delimiter . '" contains=rubyBackslashEscape,rubySpaceEscape,' . s:group . ' nextgroup=@rubyModifier skipwhite'
270 exe 'hi def link ' . s:group . ' rubyStringEscape'
271endfor
Bram Moolenaar6b730e12005-09-16 21:47:57 +0000272
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100273unlet s:delimiter s:group s:names
274" }}}2
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200275
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100276SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%q{" end="}" skip="\\\\\|\\}" contains=rubyBackslashEscape,rubyCurlyBraceEscape,rubyNestedCurlyBraces
277SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%q<" end=">" skip="\\\\\|\\>" contains=rubyBackslashEscape,rubyAngleBracketEscape,rubyNestedAngleBrackets
278SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%q\[" end="\]" skip="\\\\\|\\\]" contains=rubyBackslashEscape,rubySquareBracketEscape,rubyNestedSquareBrackets
279SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%q(" end=")" skip="\\\\\|\\)" contains=rubyBackslashEscape,rubyParenthesisEscape,rubyNestedParentheses
280SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%q\z(\s\)" end="\z1" skip="\\\\\|\\\z1" contains=rubyBackslashEscape,rubySpaceEscape
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200281
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100282SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%w{" end="}" skip="\\\\\|\\}" contains=rubyBackslashEscape,rubySpaceEscape,rubyCurlyBraceEscape,rubyNestedCurlyBraces
283SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%w<" end=">" skip="\\\\\|\\>" contains=rubyBackslashEscape,rubySpaceEscape,rubyAngleBracketEscape,rubyNestedAngleBrackets
284SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%w\[" end="\]" skip="\\\\\|\\\]" contains=rubyBackslashEscape,rubySpaceEscape,rubySquareBracketEscape,rubyNestedSquareBrackets
285SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%w(" end=")" skip="\\\\\|\\)" contains=rubyBackslashEscape,rubySpaceEscape,rubyParenthesisEscape,rubyNestedParentheses
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200286
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100287SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%s{" end="}" skip="\\\\\|\\}" contains=rubyBackslashEscape,rubyCurlyBraceEscape,rubyNestedCurlyBraces
288SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%s<" end=">" skip="\\\\\|\\>" contains=rubyBackslashEscape,rubyAngleBracketEscape,rubyNestedAngleBrackets
289SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%s\[" end="\]" skip="\\\\\|\\\]" contains=rubyBackslashEscape,rubySquareBracketEscape,rubyNestedSquareBrackets
290SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%s(" end=")" skip="\\\\\|\\)" contains=rubyBackslashEscape,rubyParenthesisEscape,rubyNestedParentheses
291SynFold '%' syn region rubyString matchgroup=rubyPercentSymbolDelimiter start="%s\z(\s\)" end="\z1" skip="\\\\\|\\\z1" contains=rubyBackslashEscape,rubySpaceEscape
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200292
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100293SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%i{" end="}" skip="\\\\\|\\}" contains=rubyBackslashEscape,rubySpaceEscape,rubyCurlyBraceEscape,rubyNestedCurlyBraces
294SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%i<" end=">" skip="\\\\\|\\>" contains=rubyBackslashEscape,rubySpaceEscape,rubyAngleBracketEscape,rubyNestedAngleBrackets
295SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%i\[" end="\]" skip="\\\\\|\\\]" contains=rubyBackslashEscape,rubySpaceEscape,rubySquareBracketEscape,rubyNestedSquareBrackets
296SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%i(" end=")" skip="\\\\\|\\)" contains=rubyBackslashEscape,rubySpaceEscape,rubyParenthesisEscape,rubyNestedParentheses
297
298" Generalized Double Quoted Strings, Array of Strings, Array of Symbols and Shell Command Output {{{1
299SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="\%(\%(\w\|[^\x00-\x7F]\|]\)\s*\)\@<!%=" end="=" skip="\\\\\|\\=" contains=@rubyStringSpecial nextgroup=@rubyModifier skipwhite
300SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%\z([~`!@#$%^&*_\-+|\:;"',.?/]\)" end="\z1" skip="\\\\\|\\\z1" contains=@rubyStringSpecial nextgroup=@rubyModifier skipwhite
301SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%[QWx]\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1" skip="\\\\\|\\\z1" contains=@rubyStringSpecial nextgroup=@rubyModifier skipwhite
302SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%[QWx]\={" end="}" skip="\\\\\|\\}" contains=@rubyStringSpecial,rubyNestedCurlyBraces
303SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%[QWx]\=<" end=">" skip="\\\\\|\\>" contains=@rubyStringSpecial,rubyNestedAngleBrackets
304SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%[QWx]\=\[" end="\]" skip="\\\\\|\\\]" contains=@rubyStringSpecial,rubyNestedSquareBrackets
305SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%[QWx]\=(" end=")" skip="\\\\\|\\)" contains=@rubyStringSpecial,rubyNestedParentheses
306SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%[Qx]\z(\s\)" end="\z1" skip="\\\\\|\\\z1" contains=@rubyStringSpecial
307
308SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%I\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1" skip="\\\\\|\\\z1" contains=@rubyStringSpecial nextgroup=@rubyModifier skipwhite
309SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%I{" end="}" skip="\\\\\|\\}" contains=@rubyStringSpecial,rubyNestedCurlyBraces
310SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%I<" end=">" skip="\\\\\|\\>" contains=@rubyStringSpecial,rubyNestedAngleBrackets
311SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%I\[" end="\]" skip="\\\\\|\\\]" contains=@rubyStringSpecial,rubyNestedSquareBrackets
312SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%I(" end=")" skip="\\\\\|\\)" contains=@rubyStringSpecial,rubyNestedParentheses
313
314" Here Documents {{{1
315syn region rubyHeredocStart matchgroup=rubyHeredocDelimiter start=+\%(\%(class\|::\|\.\@1<!\.\)\_s*\|\%([]})"'`]\)\s\|\w\)\@<!<<[-~]\=\zs\%(\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*\)+ end=+$+ oneline contains=ALLBUT,@rubyNotTop
316
317syn region rubyHeredocStart matchgroup=rubyHeredocDelimiter start=+\%(\%(class\|::\|\.\@1<!\.\)\_s*\|\%([]})"'`]\)\s\|\w\)\@<!<<[-~]\=\zs"\%([^"]*\)"+ end=+$+ oneline contains=ALLBUT,@rubyNotTop
318syn region rubyHeredocStart matchgroup=rubyHeredocDelimiter start=+\%(\%(class\|::\|\.\@1<!\.\)\_s*\|\%([]})"'`]\)\s\|\w\)\@<!<<[-~]\=\zs'\%([^']*\)'+ end=+$+ oneline contains=ALLBUT,@rubyNotTop
319syn region rubyHeredocStart matchgroup=rubyHeredocDelimiter start=+\%(\%(class\|::\|\.\@1<!\.\)\_s*\|\%([]})"'`]\)\s\|\w\)\@<!<<[-~]\=\zs`\%([^`]*\)`+ end=+$+ oneline contains=ALLBUT,@rubyNotTop
320
321SynFold '<<' syn region rubyString start=+\%(\%(class\|::\|\.\@1<!\.\)\_s*\|\%([]})"'`]\)\s\|\w\)\@<!<<\z(\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*\)\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+2 matchgroup=rubyHeredocDelimiter end=+^\z1$+ contains=rubyHeredocStart,@rubyStringSpecial keepend
322SynFold '<<' syn region rubyString start=+\%(\%(class\|::\|\.\@1<!\.\)\_s*\|\%([]})"'`]\)\s\|\w\)\@<!<<"\z([^"]*\)"\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+2 matchgroup=rubyHeredocDelimiter end=+^\z1$+ contains=rubyHeredocStart,@rubyStringSpecial keepend
323SynFold '<<' syn region rubyString start=+\%(\%(class\|::\|\.\@1<!\.\)\_s*\|\%([]})"'`]\)\s\|\w\)\@<!<<'\z([^']*\)'\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+2 matchgroup=rubyHeredocDelimiter end=+^\z1$+ contains=rubyHeredocStart keepend
324SynFold '<<' syn region rubyString start=+\%(\%(class\|::\|\.\@1<!\.\)\_s*\|\%([]})"'`]\)\s\|\w\)\@<!<<`\z([^`]*\)`\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+2 matchgroup=rubyHeredocDelimiter end=+^\z1$+ contains=rubyHeredocStart,@rubyStringSpecial keepend
325
326SynFold '<<' syn region rubyString start=+\%(\%(class\|::\|\.\@1<!\.\)\_s*\|\%([]})]\)\s\|\w\)\@<!<<[-~]\z(\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*\)\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+3 matchgroup=rubyHeredocDelimiter end=+^\s*\zs\z1$+ contains=rubyHeredocStart,@rubyStringSpecial keepend
327SynFold '<<' syn region rubyString start=+\%(\%(class\|::\|\.\@1<!\.\)\_s*\|\%([]})]\)\s\|\w\)\@<!<<[-~]"\z([^"]*\)"\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+3 matchgroup=rubyHeredocDelimiter end=+^\s*\zs\z1$+ contains=rubyHeredocStart,@rubyStringSpecial keepend
328SynFold '<<' syn region rubyString start=+\%(\%(class\|::\|\.\@1<!\.\)\_s*\|\%([]})]\)\s\|\w\)\@<!<<[-~]'\z([^']*\)'\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+3 matchgroup=rubyHeredocDelimiter end=+^\s*\zs\z1$+ contains=rubyHeredocStart keepend
329SynFold '<<' syn region rubyString start=+\%(\%(class\|::\|\.\@1<!\.\)\_s*\|\%([]})]\)\s\|\w\)\@<!<<[-~]`\z([^`]*\)`\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+3 matchgroup=rubyHeredocDelimiter end=+^\s*\zs\z1$+ contains=rubyHeredocStart,@rubyStringSpecial keepend
Bram Moolenaar071d4272004-06-13 20:20:40 +0000330
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200331" Module, Class, Method and Alias Declarations {{{1
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100332syn match rubyAliasDeclaration "[^[:space:];#.()]\+" contained contains=rubySymbol,@rubyGlobalVariable nextgroup=rubyAliasDeclaration2 skipwhite
333syn match rubyAliasDeclaration2 "[^[:space:];#.()]\+" contained contains=rubySymbol,@rubyGlobalVariable
334syn match rubyMethodDeclaration "[^[:space:];#(]\+" contained contains=rubyConstant,rubyBoolean,rubyPseudoVariable,rubyInstanceVariable,rubyClassVariable,rubyGlobalVariable
Bram Moolenaar4d8f4762021-06-27 15:18:56 +0200335syn match rubyClassDeclaration "[^[:space:];#<]\+" contained contains=rubyClassName,rubyScopeOperator nextgroup=rubySuperClassOperator skipwhite
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100336syn match rubyModuleDeclaration "[^[:space:];#<]\+" contained contains=rubyModuleName,rubyScopeOperator
Bram Moolenaarc1762cc2007-05-10 16:56:30 +0000337
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100338syn match rubyMethodName "\<\%([_[:alpha:]]\|[^\x00-\x7F]\)\%([_[:alnum:]]\|[^\x00-\x7F]\)*[?!=]\=\%([[:alnum:]_.:?!=]\|[^\x00-\x7F]\)\@!" contained containedin=rubyMethodDeclaration
339syn match rubyMethodName "\%(\s\|^\)\@1<=\%([_[:alpha:]]\|[^\x00-\x7F]\)\%([_[:alnum:]]\|[^\x00-\x7F]\)*[?!=]\=\%(\s\|$\)\@=" contained containedin=rubyAliasDeclaration,rubyAliasDeclaration2
340syn match rubyMethodName "\%([[:space:].]\|^\)\@1<=\%(\[\]=\=\|\*\*\|[-+!~]@\=\|[*/%|&^~]\|<<\|>>\|[<>]=\=\|<=>\|===\|[=!]=\|[=!]\~\|!\|`\)\%([[:space:];#(]\|$\)\@=" contained containedin=rubyAliasDeclaration,rubyAliasDeclaration2,rubyMethodDeclaration
341
342syn cluster rubyDeclaration contains=rubyAliasDeclaration,rubyAliasDeclaration2,rubyMethodDeclaration,rubyModuleDeclaration,rubyClassDeclaration,rubyMethodName
Bram Moolenaar1d689522010-05-28 20:54:39 +0200343
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200344" Keywords {{{1
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100345" TODO: reorganise
346syn match rubyControl "\%#=1\<\%(break\|in\|next\|redo\|retry\|return\)\>"
347syn match rubyKeyword "\%#=1\<\%(super\|yield\)\>"
348syn match rubyBoolean "\%#=1\<\%(true\|false\)\>[?!]\@!"
349syn match rubyPseudoVariable "\%#=1\<\(self\|nil\)\>[?!]\@!"
350syn match rubyPseudoVariable "\%#=1\<__\%(ENCODING\|dir\|FILE\|LINE\|callee\|method\)__\>"
351syn match rubyBeginEnd "\%#=1\<\%(BEGIN\|END\)\>"
Bram Moolenaarc236c162008-07-13 17:41:49 +0000352
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200353" Expensive Mode {{{1
354" Match 'end' with the appropriate opening keyword for syntax based folding
355" and special highlighting of module/class/method definitions
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000356if !exists("b:ruby_no_expensive") && !exists("ruby_no_expensive")
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100357 syn match rubyDefine "\<alias\>" nextgroup=rubyAliasDeclaration skipwhite skipnl
358 syn match rubyDefine "\<def\>" nextgroup=rubyMethodDeclaration skipwhite skipnl
359 syn match rubyDefine "\<undef\>" nextgroup=rubyMethodName skipwhite skipnl
360 syn match rubyClass "\<class\>" nextgroup=rubyClassDeclaration,rubyEigenClassOperator skipwhite skipnl
361 syn match rubyModule "\<module\>" nextgroup=rubyModuleDeclaration skipwhite skipnl
Bram Moolenaar1d689522010-05-28 20:54:39 +0200362
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100363 SynFold 'def' syn region rubyMethodBlock start="\<def\>" matchgroup=rubyDefine skip="\<end:\|\%(\<def\_s\+\)\@<=end\>" end="\<end\>" contains=ALLBUT,@rubyNotTop
364 SynFold 'class' syn region rubyClassBlock start="\<class\>" matchgroup=rubyClass skip="\<end:" end="\<end\>" contains=ALLBUT,@rubyNotTop
365 SynFold 'module' syn region rubyModuleBlock start="\<module\>" matchgroup=rubyModule skip="\<end:" end="\<end\>" contains=ALLBUT,@rubyNotTop
Bram Moolenaar071d4272004-06-13 20:20:40 +0000366
Bram Moolenaar46eea442022-03-30 10:51:39 +0100367 " endless def
368 syn match rubyDefine "\<def\s\+\ze[^[:space:];#(]\+\%(\s\+\|\s*(.*)\s*\)=" nextgroup=rubyMethodDeclaration skipwhite
369
Bram Moolenaar6b730e12005-09-16 21:47:57 +0000370 " modifiers
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100371 syn match rubyLineContinuation "\\$" nextgroup=@rubyModifier skipwhite skipnl
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200372 syn match rubyConditionalModifier "\<\%(if\|unless\)\>"
373 syn match rubyRepeatModifier "\<\%(while\|until\)\>"
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100374 syn match rubyRescueModifier "\<rescue\>"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000375
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100376 syn cluster rubyModifier contains=rubyConditionalModifier,rubyRepeatModifier,rubyRescueModifier
377
378 SynFold 'do' syn region rubyDoBlock matchgroup=rubyControl start="\<do\>" skip="\<end:" end="\<end\>" contains=ALLBUT,@rubyNotTop
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200379
Bram Moolenaarc1762cc2007-05-10 16:56:30 +0000380 " curly bracket block or hash literal
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100381 SynFold '{' syn region rubyCurlyBlock matchgroup=rubyCurlyBlockDelimiter start="{" end="}" contains=ALLBUT,@rubyNotTop
382 SynFold '[' syn region rubyArrayLiteral matchgroup=rubyArrayDelimiter start="\%(\%(\w\|[^\x00-\x7F]\)[?!]\=\|[]})]\)\@2<!\[" end="]" contains=ALLBUT,@rubyNotTop
Bram Moolenaar071d4272004-06-13 20:20:40 +0000383
Bram Moolenaarc1762cc2007-05-10 16:56:30 +0000384 " statements without 'do'
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100385 SynFold 'begin' syn region rubyBlockExpression matchgroup=rubyControl start="\<begin\>" skip="\<end:" end="\<end\>" contains=ALLBUT,@rubyNotTop
386 SynFold 'case' syn region rubyCaseExpression matchgroup=rubyConditional start="\<case\>" skip="\<end:" end="\<end\>" contains=ALLBUT,@rubyNotTop
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200387
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100388 SynFold 'if' syn region rubyConditionalExpression matchgroup=rubyConditional start="\%(\%(^\|\.\.\.\=\|[{:,;([<>~\*/%&^|+=-]\|\<then\s\|\%(\<\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*\)\@<![?!]\)\s*\)\@<=\%(if\|unless\)\>" skip="\<end:" end="\<end\>" contains=ALLBUT,@rubyNotTop
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200389
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100390 syn match rubyConditional "\<\%(then\|else\|when\)\>" contained containedin=rubyCaseExpression
391 syn match rubyConditional "\<\%(then\|else\|elsif\)\>" contained containedin=rubyConditionalExpression
Bram Moolenaar071d4272004-06-13 20:20:40 +0000392
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100393 syn match rubyExceptionHandler "\<\%(\%(\%(;\|^\)\s*\)\@<=rescue\|else\|ensure\)\>" contained containedin=rubyBlockExpression,rubyDoBlock
394 syn match rubyExceptionHandler2 "\<\%(\%(\%(;\|^\)\s*\)\@<=rescue\|else\|ensure\)\>" contained containedin=rubyModuleBlock,rubyClassBlock,rubyMethodBlock
395 syn cluster rubyExceptionHandler contains=rubyExceptionHandler,rubyExceptionHandler2
Bram Moolenaar1d689522010-05-28 20:54:39 +0200396
Bram Moolenaarc1762cc2007-05-10 16:56:30 +0000397 " statements with optional 'do'
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100398 syn region rubyOptionalDoLine matchgroup=rubyRepeat start="\<for\>" start="\%(\%(^\|\.\.\.\=\|[{:,;([<>~\*/%&^|+=-]\|\%(\<\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*\)\@<![!?]\)\s*\)\@<=\<\%(until\|while\)\>" matchgroup=rubyOptionalDo end="\<do\>" end="\ze\%(;\|$\)" oneline contains=ALLBUT,@rubyNotTop
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200399
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100400 SynFold 'for' syn region rubyRepeatExpression start="\<for\>" start="\%(\%(^\|\.\.\.\=\|[{:,;([<>~\*/%&^|+=-]\|\%(\<\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*\)\@<![!?]\)\s*\)\@<=\<\%(until\|while\)\>" matchgroup=rubyRepeat skip="\<end:" end="\<end\>" contains=ALLBUT,@rubyNotTop nextgroup=rubyOptionalDoLine
Bram Moolenaar071d4272004-06-13 20:20:40 +0000401
402 if !exists("ruby_minlines")
Bram Moolenaarec7944a2013-06-12 21:29:15 +0200403 let ruby_minlines = 500
Bram Moolenaar071d4272004-06-13 20:20:40 +0000404 endif
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100405 exe "syn sync minlines=" . ruby_minlines
Bram Moolenaar071d4272004-06-13 20:20:40 +0000406
Bram Moolenaar6b730e12005-09-16 21:47:57 +0000407else
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100408 syn match rubyControl "\<def\>" nextgroup=rubyMethodDeclaration skipwhite skipnl
409 syn match rubyControl "\<class\>" nextgroup=rubyClassDeclaration skipwhite skipnl
410 syn match rubyControl "\<module\>" nextgroup=rubyModuleDeclaration skipwhite skipnl
411 syn match rubyControl "\<\%(case\|begin\|do\|for\|if\|unless\|while\|until\|else\|elsif\|rescue\|ensure\|then\|when\|end\)\>"
412 syn match rubyKeyword "\<\%(alias\|undef\)\>"
Bram Moolenaar6b730e12005-09-16 21:47:57 +0000413endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000414
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200415" Special Methods {{{1
Bram Moolenaar6b730e12005-09-16 21:47:57 +0000416if !exists("ruby_no_special_methods")
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100417 syn match rubyAccess "\<\%(public\|protected\|private\)\>" " use re=2
418 syn match rubyAccess "\%#=1\<\%(public\|private\)_class_method\>"
419 syn match rubyAccess "\%#=1\<\%(public\|private\)_constant\>"
420 syn match rubyAccess "\%#=1\<module_function\>"
421 syn match rubyAttribute "\%#=1\%(\%(^\|;\)\s*\)\@<=attr\>\(\s*[.=]\)\@!" " attr is a common variable name
422 syn match rubyAttribute "\%#=1\<attr_\%(accessor\|reader\|writer\)\>"
423 syn match rubyControl "\%#=1\<\%(abort\|at_exit\|exit\|fork\|loop\|trap\)\>"
424 syn match rubyEval "\%#=1\<eval\>"
425 syn match rubyEval "\%#=1\<\%(class\|instance\|module\)_eval\>"
426 syn match rubyException "\%#=1\<\%(raise\|fail\|catch\|throw\)\>"
427 syn match rubyInclude "\%#=1\<\%(autoload\|gem\|load\|require\%(_relative\)\=\)\>"
428 syn match rubyKeyword "\%#=1\<\%(callcc\|caller\|lambda\|proc\)\>"
429 syn match rubyMacro "\%#=1\<\%(extend\|include\|prepend\|refine\|using\)\>"
430 syn match rubyMacro "\%#=1\<\%(alias\|define\|define_singleton\|remove\|undef\)_method\>"
Bram Moolenaar6b730e12005-09-16 21:47:57 +0000431endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000432
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200433" Comments and Documentation {{{1
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100434syn match rubySharpBang "\%^#!.*" display
435syn keyword rubyTodo FIXME NOTE TODO OPTIMIZE HACK REVIEW XXX todo contained
Bram Moolenaar46eea442022-03-30 10:51:39 +0100436syn match rubyEncoding "[[:alnum:]-_]\+" contained display
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100437syn match rubyMagicComment "\c\%<3l#\s*\zs\%(coding\|encoding\):" contained nextgroup=rubyEncoding skipwhite
438syn match rubyMagicComment "\c\%<10l#\s*\zs\%(frozen_string_literal\|warn_indent\|warn_past_scope\):" contained nextgroup=rubyBoolean skipwhite
Bram Moolenaar46eea442022-03-30 10:51:39 +0100439syn match rubyMagicComment "\c\%<10l#\s*\zs\%(shareable_constant_value\):" contained nextgroup=rubyEncoding skipwhite
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100440syn match rubyComment "#.*" contains=@rubyCommentSpecial,rubySpaceError,@Spell
441
442syn cluster rubyCommentSpecial contains=rubySharpBang,rubyTodo,rubyMagicComment
443syn cluster rubyCommentNotTop contains=@rubyCommentSpecial,rubyEncoding
444
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200445if !exists("ruby_no_comment_fold") && s:foldable('#')
446 syn region rubyMultilineComment start="^\s*#.*\n\%(^\s*#\)\@=" end="^\s*#.*\n\%(^\s*#\)\@!" contains=rubyComment transparent fold keepend
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100447 syn region rubyDocumentation start="^=begin\ze\%(\s.*\)\=$" end="^=end\%(\s.*\)\=$" contains=rubySpaceError,rubyTodo,@Spell fold
Bram Moolenaar9964e462007-05-05 17:54:07 +0000448else
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100449 syn region rubyDocumentation start="^=begin\s*$" end="^=end\s*$" contains=rubySpaceError,rubyTodo,@Spell
Bram Moolenaar9964e462007-05-05 17:54:07 +0000450endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000451
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100452" {{{1 Useless Line Continuations
453syn match rubyUselessLineContinuation "\%([.:,;{([<>~\*%&^|+=-]\|%(\%(\w\|[^\x00-\x7F]\)\@1<![?!]\)\s*\zs\\$" nextgroup=rubyUselessLineContinuation skipwhite skipempty
454syn match rubyUselessLineContinuation "\\$" nextgroup=rubyUselessLineContinuation skipwhite skipempty contained
455
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200456" Keyword Nobbling {{{1
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100457" prevent methods with keyword names being highlighted as keywords when called
458syn match rubyKeywordAsMethod "\%(\%(\.\@1<!\.\)\|&\.\|::\)\_s*\%([_[:lower:]][_[:alnum:]]*\|\%(BEGIN\|END\)\>\)" transparent contains=rubyDotOperator,rubyScopeOperator
Bram Moolenaar6b730e12005-09-16 21:47:57 +0000459
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100460" Bang and Predicate Methods and Operators {{{1
461syn match rubyBangPredicateMethod "\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*[?!]"
462
463if !exists("ruby_no_special_methods")
464 syn match rubyControl "\%#=1\<exit!" display
465endif
466syn match rubyDefinedOperator "\%#=1\<defined?" display
467
468" 1.9-style Hash Keys and Keyword Parameters {{{1
Bram Moolenaar4d8f4762021-06-27 15:18:56 +0200469syn match rubySymbol "\%(\w\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*[?!]\=::\@!"he=e-1 contained containedin=rubyBlockParameterList,rubyCurlyBlock
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100470syn match rubySymbol "[]})\"':]\@1<!\<\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*[!?]\=:[[:space:],;]\@="he=e-1
471syn match rubySymbol "[[:space:],{(]\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*[!?]\=:[[:space:],;]\@="hs=s+1,he=e-1
Bram Moolenaar46eea442022-03-30 10:51:39 +0100472syn match rubySingleQuoteSymbolDelimiter "'" contained
473syn match rubySymbol "'\%(\\.\|[^']\)*'::\@!"he=e-1 contains=rubyQuoteEscape,rubyBackslashEscape,rubySingleQuoteSymbolDelimiter
474syn match rubyDoubleQuoteSymbolDelimiter "\"" contained
475syn match rubySymbol "\"\%(\\.\|[^\"]\)*\"::\@!"he=e-1 contains=@rubyStringSpecial,rubyDoubleQuoteSymbolDelimiter
Bram Moolenaarc236c162008-07-13 17:41:49 +0000476
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200477" __END__ Directive {{{1
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100478SynFold '__END__' syn region rubyData matchgroup=rubyDataDirective start="^__END__$" end="\%$"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000479
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200480" Default Highlighting {{{1
Bram Moolenaarc1762cc2007-05-10 16:56:30 +0000481hi def link rubyClass rubyDefine
482hi def link rubyModule rubyDefine
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100483hi def link rubyExceptionHandler2 rubyDefine
Bram Moolenaarc1762cc2007-05-10 16:56:30 +0000484hi def link rubyDefine Define
Bram Moolenaard09091d2019-01-17 16:07:22 +0100485hi def link rubyAccess rubyMacro
486hi def link rubyAttribute rubyMacro
487hi def link rubyMacro Macro
488hi def link rubyMethodName rubyFunction
Bram Moolenaarc1762cc2007-05-10 16:56:30 +0000489hi def link rubyFunction Function
490hi def link rubyConditional Conditional
491hi def link rubyConditionalModifier rubyConditional
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100492hi def link rubyExceptionHandler rubyConditional
493hi def link rubyRescueModifier rubyExceptionHandler
Bram Moolenaarc1762cc2007-05-10 16:56:30 +0000494hi def link rubyRepeat Repeat
495hi def link rubyRepeatModifier rubyRepeat
496hi def link rubyOptionalDo rubyRepeat
497hi def link rubyControl Statement
498hi def link rubyInclude Include
499hi def link rubyInteger Number
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100500hi def link rubyCharacter Character
Bram Moolenaarc1762cc2007-05-10 16:56:30 +0000501hi def link rubyFloat Float
502hi def link rubyBoolean Boolean
503hi def link rubyException Exception
504if !exists("ruby_no_identifiers")
505 hi def link rubyIdentifier Identifier
506else
507 hi def link rubyIdentifier NONE
Bram Moolenaar071d4272004-06-13 20:20:40 +0000508endif
Bram Moolenaarc1762cc2007-05-10 16:56:30 +0000509hi def link rubyClassVariable rubyIdentifier
510hi def link rubyConstant Type
Bram Moolenaard09091d2019-01-17 16:07:22 +0100511hi def link rubyClassName rubyConstant
512hi def link rubyModuleName rubyConstant
Bram Moolenaarc1762cc2007-05-10 16:56:30 +0000513hi def link rubyGlobalVariable rubyIdentifier
Bram Moolenaarc1762cc2007-05-10 16:56:30 +0000514hi def link rubyInstanceVariable rubyIdentifier
515hi def link rubyPredefinedIdentifier rubyIdentifier
516hi def link rubyPredefinedConstant rubyPredefinedIdentifier
517hi def link rubyPredefinedVariable rubyPredefinedIdentifier
518hi def link rubySymbol Constant
519hi def link rubyKeyword Keyword
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100520
Bram Moolenaarc1762cc2007-05-10 16:56:30 +0000521hi def link rubyOperator Operator
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100522hi def link rubyDefinedOperator rubyOperator
523hi def link rubyEnglishBooleanOperator rubyOperator
524if exists("ruby_operators")
525 hi def link rubyTernaryOperator rubyOperator
526 hi def link rubyArithmeticOperator rubyOperator
527 hi def link rubyComparisonOperator rubyOperator
528 hi def link rubyBitwiseOperator rubyOperator
529 hi def link rubyBooleanOperator rubyOperator
530 hi def link rubyRangeOperator rubyOperator
531 hi def link rubyAssignmentOperator rubyOperator
532 hi def link rubyEqualityOperator rubyOperator
533endif
534
535if exists("ruby_pseudo_operators")
536 hi def link rubyPseudoOperator Special
537 hi def link rubyDotOperator rubyPseudoOperator
538 hi def link rubyScopeOperator rubyPseudoOperator
539 hi def link rubySuperClassOperator rubyPseudoOperator
540 hi def link rubyEigenClassOperator rubyPseudoOperator
541 hi def link rubyLambdaOperator rubyPseudoOperator
542 hi def link rubyDoubleSplatOperator rubyPseudoOperator
543 hi def link rubySplatOperator rubyPseudoOperator
544 hi def link rubyProcOperator rubyPseudoOperator
545endif
546
Bram Moolenaarc1762cc2007-05-10 16:56:30 +0000547hi def link rubyBeginEnd Statement
Bram Moolenaarc1762cc2007-05-10 16:56:30 +0000548hi def link rubyEval Statement
549hi def link rubyPseudoVariable Constant
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100550hi def link rubyCapitalizedMethod NONE
Bram Moolenaarc1762cc2007-05-10 16:56:30 +0000551
552hi def link rubyComment Comment
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100553hi def link rubyEncoding Constant
554hi def link rubyMagicComment SpecialComment
Bram Moolenaarc1762cc2007-05-10 16:56:30 +0000555hi def link rubyData Comment
556hi def link rubyDataDirective Delimiter
557hi def link rubyDocumentation Comment
Bram Moolenaarc236c162008-07-13 17:41:49 +0000558hi def link rubyTodo Todo
559
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100560hi def link rubyBackslashEscape rubyStringEscape
Bram Moolenaar1d689522010-05-28 20:54:39 +0200561hi def link rubyQuoteEscape rubyStringEscape
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100562hi def link rubySpaceEscape rubyStringEscape
563hi def link rubyParenthesisEscape rubyStringEscape
564hi def link rubyCurlyBraceEscape rubyStringEscape
565hi def link rubyAngleBracketEscape rubyStringEscape
566hi def link rubySquareBracketEscape rubyStringEscape
Bram Moolenaarc236c162008-07-13 17:41:49 +0000567hi def link rubyStringEscape Special
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100568
Bram Moolenaarc1762cc2007-05-10 16:56:30 +0000569hi def link rubyInterpolationDelimiter Delimiter
Bram Moolenaarc1762cc2007-05-10 16:56:30 +0000570hi def link rubySharpBang PreProc
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100571hi def link rubyStringDelimiter Delimiter
572hi def link rubyHeredocDelimiter rubyStringDelimiter
573hi def link rubyPercentRegexpDelimiter rubyRegexpDelimiter
574hi def link rubyPercentStringDelimiter rubyStringDelimiter
575hi def link rubyPercentSymbolDelimiter rubySymbolDelimiter
Bram Moolenaar46eea442022-03-30 10:51:39 +0100576hi def link rubyDoubleQuoteSymbolDelimiter rubySymbolDelimiter
577hi def link rubySingleQuoteSymbolDelimiter rubySymbolDelimiter
Bram Moolenaarc1762cc2007-05-10 16:56:30 +0000578hi def link rubyRegexpDelimiter rubyStringDelimiter
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200579hi def link rubySymbolDelimiter rubySymbol
Bram Moolenaarc1762cc2007-05-10 16:56:30 +0000580hi def link rubyString String
Bram Moolenaarc236c162008-07-13 17:41:49 +0000581hi def link rubyRegexpEscape rubyRegexpSpecial
582hi def link rubyRegexpQuantifier rubyRegexpSpecial
583hi def link rubyRegexpAnchor rubyRegexpSpecial
584hi def link rubyRegexpDot rubyRegexpCharClass
585hi def link rubyRegexpCharClass rubyRegexpSpecial
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100586hi def link rubyRegexpIntersection rubyRegexpSpecial
Bram Moolenaarc236c162008-07-13 17:41:49 +0000587hi def link rubyRegexpSpecial Special
588hi def link rubyRegexpComment Comment
589hi def link rubyRegexp rubyString
Bram Moolenaarc1762cc2007-05-10 16:56:30 +0000590
Bram Moolenaarc1762cc2007-05-10 16:56:30 +0000591hi def link rubyError Error
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100592if exists("ruby_line_continuation_error")
593 hi def link rubyUselessLineContinuation rubyError
594endif
595hi def link rubyGlobalVariableError rubyError
Bram Moolenaarc1762cc2007-05-10 16:56:30 +0000596hi def link rubySpaceError rubyError
Bram Moolenaar071d4272004-06-13 20:20:40 +0000597
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200598" Postscript {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000599let b:current_syntax = "ruby"
600
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200601let &cpo = s:cpo_sav
602unlet! s:cpo_sav
603
Bram Moolenaar2ed639a2019-12-09 23:11:18 +0100604delc SynFold
605
Bram Moolenaar89bcfda2016-08-30 23:26:57 +0200606" vim: nowrap sw=2 sts=2 ts=8 noet fdm=marker: