1package r
2
3import (
4 . "github.com/alecthomas/chroma" // nolint
5 "github.com/alecthomas/chroma/lexers/internal"
6)
7
8// Ruby lexer.
9var Ruby = internal.Register(MustNewLexer(
10 &Config{
11 Name: "Ruby",
12 Aliases: []string{"rb", "ruby", "duby"},
13 Filenames: []string{"*.rb", "*.rbw", "Rakefile", "*.rake", "*.gemspec", "*.rbx", "*.duby", "Gemfile"},
14 MimeTypes: []string{"text/x-ruby", "application/x-ruby"},
15 DotAll: true,
16 },
17 Rules{
18 "root": {
19 {`\A#!.+?$`, CommentHashbang, nil},
20 {`#.*?$`, CommentSingle, nil},
21 {`=begin\s.*?\n=end.*?$`, CommentMultiline, nil},
22 {Words(``, `\b`, `BEGIN`, `END`, `alias`, `begin`, `break`, `case`, `defined?`, `do`, `else`, `elsif`, `end`, `ensure`, `for`, `if`, `in`, `next`, `redo`, `rescue`, `raise`, `retry`, `return`, `super`, `then`, `undef`, `unless`, `until`, `when`, `while`, `yield`), Keyword, nil},
23 {`(module)(\s+)([a-zA-Z_]\w*(?:::[a-zA-Z_]\w*)*)`, ByGroups(Keyword, Text, NameNamespace), nil},
24 {`(def)(\s+)`, ByGroups(Keyword, Text), Push("funcname")},
25 {"def(?=[*%&^`~+-/\\[<>=])", Keyword, Push("funcname")},
26 {`(class)(\s+)`, ByGroups(Keyword, Text), Push("classname")},
27 {Words(``, `\b`, `initialize`, `new`, `loop`, `include`, `extend`, `raise`, `attr_reader`, `attr_writer`, `attr_accessor`, `attr`, `catch`, `throw`, `private`, `module_function`, `public`, `protected`, `true`, `false`, `nil`), KeywordPseudo, nil},
28 {`(not|and|or)\b`, OperatorWord, nil},
29 {Words(``, `\?`, `autoload`, `block_given`, `const_defined`, `eql`, `equal`, `frozen`, `include`, `instance_of`, `is_a`, `iterator`, `kind_of`, `method_defined`, `nil`, `private_method_defined`, `protected_method_defined`, `public_method_defined`, `respond_to`, `tainted`), NameBuiltin, nil},
30 {`(chomp|chop|exit|gsub|sub)!`, NameBuiltin, nil},
31 {Words(`(?<!\.)`, `\b`, `Array`, `Float`, `Integer`, `String`, `__id__`, `__send__`, `abort`, `ancestors`, `at_exit`, `autoload`, `binding`, `callcc`, `caller`, `catch`, `chomp`, `chop`, `class_eval`, `class_variables`, `clone`, `const_defined?`, `const_get`, `const_missing`, `const_set`, `constants`, `display`, `dup`, `eval`, `exec`, `exit`, `extend`, `fail`, `fork`, `format`, `freeze`, `getc`, `gets`, `global_variables`, `gsub`, `hash`, `id`, `included_modules`, `inspect`, `instance_eval`, `instance_method`, `instance_methods`, `instance_variable_get`, `instance_variable_set`, `instance_variables`, `lambda`, `load`, `local_variables`, `loop`, `method`, `method_missing`, `methods`, `module_eval`, `name`, `object_id`, `open`, `p`, `print`, `printf`, `private_class_method`, `private_instance_methods`, `private_methods`, `proc`, `protected_instance_methods`, `protected_methods`, `public_class_method`, `public_instance_methods`, `public_methods`, `putc`, `puts`, `raise`, `rand`, `readline`, `readlines`, `require`, `scan`, `select`, `self`, `send`, `set_trace_func`, `singleton_methods`, `sleep`, `split`, `sprintf`, `srand`, `sub`, `syscall`, `system`, `taint`, `test`, `throw`, `to_a`, `to_s`, `trace_var`, `trap`, `untaint`, `untrace_var`, `warn`), NameBuiltin, nil},
32 {`__(FILE|LINE)__\b`, NameBuiltinPseudo, nil},
33 {"(?<!\\w)(<<-?)([\"`\\']?)([a-zA-Z_]\\w*)(\\2)(.*?\\n)", String, nil},
34 {`(<<-?)("|\')()(\2)(.*?\n)`, String, nil},
35 {`__END__`, CommentPreproc, Push("end-part")},
36 {`(?:^|(?<=[=<>~!:])|(?<=(?:\s|;)when\s)|(?<=(?:\s|;)or\s)|(?<=(?:\s|;)and\s)|(?<=\.index\s)|(?<=\.scan\s)|(?<=\.sub\s)|(?<=\.sub!\s)|(?<=\.gsub\s)|(?<=\.gsub!\s)|(?<=\.match\s)|(?<=(?:\s|;)if\s)|(?<=(?:\s|;)elsif\s)|(?<=^when\s)|(?<=^index\s)|(?<=^scan\s)|(?<=^sub\s)|(?<=^gsub\s)|(?<=^sub!\s)|(?<=^gsub!\s)|(?<=^match\s)|(?<=^if\s)|(?<=^elsif\s))(\s*)(/)`, ByGroups(Text, LiteralStringRegex), Push("multiline-regex")},
37 {`(?<=\(|,|\[)/`, LiteralStringRegex, Push("multiline-regex")},
38 {`(\s+)(/)(?![\s=])`, ByGroups(Text, LiteralStringRegex), Push("multiline-regex")},
39 {`(0_?[0-7]+(?:_[0-7]+)*)(\s*)([/?])?`, ByGroups(LiteralNumberOct, Text, Operator), nil},
40 {`(0x[0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*)(\s*)([/?])?`, ByGroups(LiteralNumberHex, Text, Operator), nil},
41 {`(0b[01]+(?:_[01]+)*)(\s*)([/?])?`, ByGroups(LiteralNumberBin, Text, Operator), nil},
42 {`([\d]+(?:_\d+)*)(\s*)([/?])?`, ByGroups(LiteralNumberInteger, Text, Operator), nil},
43 {`@@[a-zA-Z_]\w*`, NameVariableClass, nil},
44 {`@[a-zA-Z_]\w*`, NameVariableInstance, nil},
45 {`\$\w+`, NameVariableGlobal, nil},
46 {"\\$[!@&`\\'+~=/\\\\,;.<>_*$?:\"^-]", NameVariableGlobal, nil},
47 {`\$-[0adFiIlpvw]`, NameVariableGlobal, nil},
48 {`::`, Operator, nil},
49 Include("strings"),
50 {`\?(\\[MC]-)*(\\([\\abefnrstv#"\']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})|\S)(?!\w)`, LiteralStringChar, nil},
51 {`[A-Z]\w+`, NameConstant, nil},
52 {Words(`(\.|::)`, ``, `*`, `**`, `-`, `+`, `-@`, `+@`, `/`, `%`, `&`, `|`, `^`, "`", `~`, `[]`, `[]=`, `<<`, `>>`, `<`, `<>`, `<=>`, `>`, `>=`, `==`, `===`), ByGroups(Operator, NameOperator), nil},
53 {"(\\.|::)([a-zA-Z_]\\w*[!?]?|[*%&^`~+\\-/\\[<>=])", ByGroups(Operator, Name), nil},
54 {`[a-zA-Z_]\w*[!?]?`, Name, nil},
55 {`(\[|\]|\*\*|<<?|>>?|>=|<=|<=>|=~|={3}|!~|&&?|\|\||\.{1,3})`, Operator, nil},
56 {`[-+/*%=<>&!^|~]=?`, Operator, nil},
57 {`[(){};,/?:\\]`, Punctuation, nil},
58 {`\s+`, Text, nil},
59 },
60 "funcname": {
61 {`\(`, Punctuation, Push("defexpr")},
62 {"(?:([a-zA-Z_]\\w*)(\\.))?([a-zA-Z_]\\w*[!?]?|\\*\\*?|[-+]@?|[/%&|^`~]|\\[\\]=?|<<|>>|<=?>|>=?|===?)", ByGroups(NameClass, Operator, NameFunction), Pop(1)},
63 Default(Pop(1)),
64 },
65 "classname": {
66 {`\(`, Punctuation, Push("defexpr")},
67 {`<<`, Operator, Pop(1)},
68 {`[A-Z_]\w*`, NameClass, Pop(1)},
69 Default(Pop(1)),
70 },
71 "defexpr": {
72 {`(\))(\.|::)?`, ByGroups(Punctuation, Operator), Pop(1)},
73 {`\(`, Operator, Push()},
74 Include("root"),
75 },
76 "in-intp": {
77 {`\{`, LiteralStringInterpol, Push()},
78 {`\}`, LiteralStringInterpol, Pop(1)},
79 Include("root"),
80 },
81 "string-intp": {
82 {`#\{`, LiteralStringInterpol, Push("in-intp")},
83 {`#@@?[a-zA-Z_]\w*`, LiteralStringInterpol, nil},
84 {`#\$[a-zA-Z_]\w*`, LiteralStringInterpol, nil},
85 },
86 "string-intp-escaped": {
87 Include("string-intp"),
88 {`\\([\\abefnrstv#"\']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})`, LiteralStringEscape, nil},
89 },
90 "interpolated-regex": {
91 Include("string-intp"),
92 {`[\\#]`, LiteralStringRegex, nil},
93 {`[^\\#]+`, LiteralStringRegex, nil},
94 },
95 "interpolated-string": {
96 Include("string-intp"),
97 {`[\\#]`, LiteralStringOther, nil},
98 {`[^\\#]+`, LiteralStringOther, nil},
99 },
100 "multiline-regex": {
101 Include("string-intp"),
102 {`\\\\`, LiteralStringRegex, nil},
103 {`\\/`, LiteralStringRegex, nil},
104 {`[\\#]`, LiteralStringRegex, nil},
105 {`[^\\/#]+`, LiteralStringRegex, nil},
106 {`/[mixounse]*`, LiteralStringRegex, Pop(1)},
107 },
108 "end-part": {
109 {`.+`, CommentPreproc, Pop(1)},
110 },
111 "strings": {
112 {`\:@{0,2}[a-zA-Z_]\w*[!?]?`, LiteralStringSymbol, nil},
113 {Words(`\:@{0,2}`, ``, `*`, `**`, `-`, `+`, `-@`, `+@`, `/`, `%`, `&`, `|`, `^`, "`", `~`, `[]`, `[]=`, `<<`, `>>`, `<`, `<>`, `<=>`, `>`, `>=`, `==`, `===`), LiteralStringSymbol, nil},
114 {`:'(\\\\|\\'|[^'])*'`, LiteralStringSymbol, nil},
115 {`'(\\\\|\\'|[^'])*'`, LiteralStringSingle, nil},
116 {`:"`, LiteralStringSymbol, Push("simple-sym")},
117 {`([a-zA-Z_]\w*)(:)(?!:)`, ByGroups(LiteralStringSymbol, Punctuation), nil},
118 {`"`, LiteralStringDouble, Push("simple-string")},
119 {"(?<!\\.)`", LiteralStringBacktick, Push("simple-backtick")},
120 {`%[QWx]?\{`, LiteralStringOther, Push("cb-intp-string")},
121 {`%[qsw]\{`, LiteralStringOther, Push("cb-string")},
122 {`%r\{`, LiteralStringRegex, Push("cb-regex")},
123 {`%[QWx]?\[`, LiteralStringOther, Push("sb-intp-string")},
124 {`%[qsw]\[`, LiteralStringOther, Push("sb-string")},
125 {`%r\[`, LiteralStringRegex, Push("sb-regex")},
126 {`%[QWx]?\(`, LiteralStringOther, Push("pa-intp-string")},
127 {`%[qsw]\(`, LiteralStringOther, Push("pa-string")},
128 {`%r\(`, LiteralStringRegex, Push("pa-regex")},
129 {`%[QWx]?<`, LiteralStringOther, Push("ab-intp-string")},
130 {`%[qsw]<`, LiteralStringOther, Push("ab-string")},
131 {`%r<`, LiteralStringRegex, Push("ab-regex")},
132 {`(%r([\W_]))((?:\\\2|(?!\2).)*)(\2[mixounse]*)`, String, nil},
133 {`%[qsw]([\W_])((?:\\\1|(?!\1).)*)\1`, LiteralStringOther, nil},
134 {`(%[QWx]([\W_]))((?:\\\2|(?!\2).)*)(\2)`, String, nil},
135 {`(?<=[-+/*%=<>&!^|~,(])(\s*)(%([\t ])(?:(?:\\\3|(?!\3).)*)\3)`, ByGroups(Text, LiteralStringOther, None), nil},
136 {`^(\s*)(%([\t ])(?:(?:\\\3|(?!\3).)*)\3)`, ByGroups(Text, LiteralStringOther, None), nil},
137 {`(%([^a-zA-Z0-9\s]))((?:\\\2|(?!\2).)*)(\2)`, String, nil},
138 },
139 "simple-string": {
140 Include("string-intp-escaped"),
141 {`[^\\"#]+`, LiteralStringDouble, nil},
142 {`[\\#]`, LiteralStringDouble, nil},
143 {`"`, LiteralStringDouble, Pop(1)},
144 },
145 "simple-sym": {
146 Include("string-intp-escaped"),
147 {`[^\\"#]+`, LiteralStringSymbol, nil},
148 {`[\\#]`, LiteralStringSymbol, nil},
149 {`"`, LiteralStringSymbol, Pop(1)},
150 },
151 "simple-backtick": {
152 Include("string-intp-escaped"),
153 {"[^\\\\`#]+", LiteralStringBacktick, nil},
154 {`[\\#]`, LiteralStringBacktick, nil},
155 {"`", LiteralStringBacktick, Pop(1)},
156 },
157 "cb-intp-string": {
158 {`\\[\\{}]`, LiteralStringOther, nil},
159 {`\{`, LiteralStringOther, Push()},
160 {`\}`, LiteralStringOther, Pop(1)},
161 Include("string-intp-escaped"),
162 {`[\\#{}]`, LiteralStringOther, nil},
163 {`[^\\#{}]+`, LiteralStringOther, nil},
164 },
165 "cb-string": {
166 {`\\[\\{}]`, LiteralStringOther, nil},
167 {`\{`, LiteralStringOther, Push()},
168 {`\}`, LiteralStringOther, Pop(1)},
169 {`[\\#{}]`, LiteralStringOther, nil},
170 {`[^\\#{}]+`, LiteralStringOther, nil},
171 },
172 "cb-regex": {
173 {`\\[\\{}]`, LiteralStringRegex, nil},
174 {`\{`, LiteralStringRegex, Push()},
175 {`\}[mixounse]*`, LiteralStringRegex, Pop(1)},
176 Include("string-intp"),
177 {`[\\#{}]`, LiteralStringRegex, nil},
178 {`[^\\#{}]+`, LiteralStringRegex, nil},
179 },
180 "sb-intp-string": {
181 {`\\[\\\[\]]`, LiteralStringOther, nil},
182 {`\[`, LiteralStringOther, Push()},
183 {`\]`, LiteralStringOther, Pop(1)},
184 Include("string-intp-escaped"),
185 {`[\\#\[\]]`, LiteralStringOther, nil},
186 {`[^\\#\[\]]+`, LiteralStringOther, nil},
187 },
188 "sb-string": {
189 {`\\[\\\[\]]`, LiteralStringOther, nil},
190 {`\[`, LiteralStringOther, Push()},
191 {`\]`, LiteralStringOther, Pop(1)},
192 {`[\\#\[\]]`, LiteralStringOther, nil},
193 {`[^\\#\[\]]+`, LiteralStringOther, nil},
194 },
195 "sb-regex": {
196 {`\\[\\\[\]]`, LiteralStringRegex, nil},
197 {`\[`, LiteralStringRegex, Push()},
198 {`\][mixounse]*`, LiteralStringRegex, Pop(1)},
199 Include("string-intp"),
200 {`[\\#\[\]]`, LiteralStringRegex, nil},
201 {`[^\\#\[\]]+`, LiteralStringRegex, nil},
202 },
203 "pa-intp-string": {
204 {`\\[\\()]`, LiteralStringOther, nil},
205 {`\(`, LiteralStringOther, Push()},
206 {`\)`, LiteralStringOther, Pop(1)},
207 Include("string-intp-escaped"),
208 {`[\\#()]`, LiteralStringOther, nil},
209 {`[^\\#()]+`, LiteralStringOther, nil},
210 },
211 "pa-string": {
212 {`\\[\\()]`, LiteralStringOther, nil},
213 {`\(`, LiteralStringOther, Push()},
214 {`\)`, LiteralStringOther, Pop(1)},
215 {`[\\#()]`, LiteralStringOther, nil},
216 {`[^\\#()]+`, LiteralStringOther, nil},
217 },
218 "pa-regex": {
219 {`\\[\\()]`, LiteralStringRegex, nil},
220 {`\(`, LiteralStringRegex, Push()},
221 {`\)[mixounse]*`, LiteralStringRegex, Pop(1)},
222 Include("string-intp"),
223 {`[\\#()]`, LiteralStringRegex, nil},
224 {`[^\\#()]+`, LiteralStringRegex, nil},
225 },
226 "ab-intp-string": {
227 {`\\[\\<>]`, LiteralStringOther, nil},
228 {`<`, LiteralStringOther, Push()},
229 {`>`, LiteralStringOther, Pop(1)},
230 Include("string-intp-escaped"),
231 {`[\\#<>]`, LiteralStringOther, nil},
232 {`[^\\#<>]+`, LiteralStringOther, nil},
233 },
234 "ab-string": {
235 {`\\[\\<>]`, LiteralStringOther, nil},
236 {`<`, LiteralStringOther, Push()},
237 {`>`, LiteralStringOther, Pop(1)},
238 {`[\\#<>]`, LiteralStringOther, nil},
239 {`[^\\#<>]+`, LiteralStringOther, nil},
240 },
241 "ab-regex": {
242 {`\\[\\<>]`, LiteralStringRegex, nil},
243 {`<`, LiteralStringRegex, Push()},
244 {`>[mixounse]*`, LiteralStringRegex, Pop(1)},
245 Include("string-intp"),
246 {`[\\#<>]`, LiteralStringRegex, nil},
247 {`[^\\#<>]+`, LiteralStringRegex, nil},
248 },
249 },
250))