Skip to content

Commit

Permalink
(enh) lots of small Ruby improvements (#3491)
Browse files Browse the repository at this point in the history
* (enh) lots of small Ruby improvements
* do not scope () as params
* better camel case regex
  • Loading branch information
joshgoebel authored Mar 3, 2022
1 parent 50d3a1e commit 8cea942
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 56 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ New Grammars:

Grammars:

- enh(ruby) lots of small Ruby cleanups/improvements [Josh Goebel][]
- enh(objectivec) add `type` and `variable.language` scopes [Josh Goebel][]
- enh(xml) support processing instructions (#3492) [Josh Goebel][]
- enh(ruby ) better support multi-line IRB prompts
Expand Down
4 changes: 2 additions & 2 deletions src/highlight.js
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,8 @@ const HLJS = function(hljs) {
*/
function emitMultiClass(scope, match) {
let i = 1;
// eslint-disable-next-line no-undefined
while (match[i] !== undefined) {
const max = match.length - 1;
while (i <= max) {
if (!scope._emit[i]) { i++; continue; }
const klass = language.classNameAliases[scope[i]] || scope[i];
const text = match[i];
Expand Down
185 changes: 138 additions & 47 deletions src/languages/ruby.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,71 @@ Category: common
export default function(hljs) {
const regex = hljs.regex;
const RUBY_METHOD_RE = '([a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?)';
// TODO: move concepts like CAMEL_CASE into `modes.js`
const CLASS_NAME_RE = regex.either(
/\b([A-Z]+[a-z0-9]+)+/,
// ends in caps
/\b([A-Z]+[a-z0-9]+)+[A-Z]+/,
)
;
const CLASS_NAME_WITH_NAMESPACE_RE = regex.concat(CLASS_NAME_RE, /(::\w+)*/)
const RUBY_KEYWORDS = {
keyword:
'and then defined module in return redo if BEGIN retry end for self when '
+ 'next until do begin unless END rescue else break undef not super class case '
+ 'require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor '
+ '__FILE__',
built_in: 'proc lambda',
literal:
'true false nil'
"variable.constant": [
"__FILE__",
"__LINE__"
],
"variable.language": [
"self",
"super",
],
keyword: [
"alias",
"and",
"attr_accessor",
"attr_reader",
"attr_writer",
"begin",
"BEGIN",
"break",
"case",
"class",
"defined",
"do",
"else",
"elsif",
"end",
"END",
"ensure",
"for",
"if",
"in",
"include",
"module",
"next",
"not",
"or",
"redo",
"require",
"rescue",
"retry",
"return",
"then",
"undef",
"unless",
"until",
"when",
"while",
"yield",
],
built_in: [
"proc",
"lambda"
],
literal: [
"true",
"false",
"nil"
]
};
const YARDOCTAG = {
className: 'doctag',
Expand All @@ -42,7 +98,7 @@ export default function(hljs) {
relevance: 10
}
),
hljs.COMMENT('^__END__', '\\n$')
hljs.COMMENT('^__END__', hljs.MATCH_NOTHING_RE)
];
const SUBST = {
className: 'subst',
Expand Down Expand Up @@ -156,49 +212,82 @@ export default function(hljs) {
};

const PARAMS = {
className: 'params',
begin: '\\(',
end: '\\)',
endsParent: true,
variants: [
{
match: /\(\)/,
},
{
className: 'params',
begin: /\(/,
end: /(?=\))/,
excludeBegin: true,
endsParent: true,
keywords: RUBY_KEYWORDS,
}
]
};

const CLASS_DEFINITION = {
variants: [
{
match: [
/class\s+/,
CLASS_NAME_WITH_NAMESPACE_RE,
/\s+<\s+/,
CLASS_NAME_WITH_NAMESPACE_RE
]
},
{
match: [
/class\s+/,
CLASS_NAME_WITH_NAMESPACE_RE
]
}
],
scope: {
2: "title.class",
4: "title.class.inherited"
},
keywords: RUBY_KEYWORDS
};

const UPPER_CASE_CONSTANT = {
relevance: 0,
match: /\b[A-Z][A-Z_0-9]+\b/,
className: "variable.constant"
};

const METHOD_DEFINITION = {
match: [
/def/, /\s+/,
RUBY_METHOD_RE
],
scope: {
1: "keyword",
3: "title.function"
},
contains: [
PARAMS
]
};

const OBJECT_CREATION = {
relevance: 0,
match: [
CLASS_NAME_WITH_NAMESPACE_RE,
/\.new[ (]/
],
scope: {
1: "title.class"
}
};

const RUBY_DEFAULT_CONTAINS = [
STRING,
{
className: 'class',
beginKeywords: 'class module',
end: '$|;',
illegal: /=/,
contains: [
hljs.inherit(hljs.TITLE_MODE, { begin: '[A-Za-z_]\\w*(::\\w+)*(\\?|!)?' }),
{
begin: '<\\s*',
contains: [
{
begin: '(' + hljs.IDENT_RE + '::)?' + hljs.IDENT_RE,
// we already get points for <, we don't need poitns
// for the name also
relevance: 0
}
]
}
].concat(COMMENT_MODES)
},
{
className: 'function',
// def method_name(
// def method_name;
// def method_name (end of line)
begin: regex.concat(/def\s+/, regex.lookahead(RUBY_METHOD_RE + "\\s*(\\(|;|$)")),
relevance: 0, // relevance comes from kewords
keywords: "def",
end: '$|;',
contains: [
hljs.inherit(hljs.TITLE_MODE, { begin: RUBY_METHOD_RE }),
PARAMS
].concat(COMMENT_MODES)
},
CLASS_DEFINITION,
OBJECT_CREATION,
UPPER_CASE_CONSTANT,
METHOD_DEFINITION,
{
// swallow namespace qualifiers before symbols
begin: hljs.IDENT_RE + '::' },
Expand Down Expand Up @@ -227,6 +316,8 @@ export default function(hljs) {
className: 'params',
begin: /\|/,
end: /\|/,
excludeBegin: true,
excludeEnd: true,
relevance: 0, // this could be a lot of things (in other languages) other than params
keywords: RUBY_KEYWORDS
},
Expand Down
2 changes: 1 addition & 1 deletion test/markup/erb/default.expect.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<span class="hljs-comment">&lt;%# this is a comment %&gt;</span><span class="language-xml">

&lt;%</span><span class="language-ruby"> <span class="hljs-variable">@posts</span>.each <span class="hljs-keyword">do</span> <span class="hljs-params">|post|</span> </span><span class="language-xml">%&gt;
&lt;%</span><span class="language-ruby"> <span class="hljs-variable">@posts</span>.each <span class="hljs-keyword">do</span> |<span class="hljs-params">post</span>| </span><span class="language-xml">%&gt;
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>&lt;%=</span><span class="language-ruby"> link_to post.title, post </span><span class="language-xml">%&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
&lt;%</span><span class="language-ruby"> <span class="hljs-keyword">end</span> </span><span class="language-xml">%&gt;

Expand Down
2 changes: 1 addition & 1 deletion test/markup/haml/default.expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<span class="hljs-comment"> /html comment</span>
<span class="hljs-comment"> -# ignore this line</span>
<span class="hljs-tag"> %<span class="hljs-selector-tag">ul</span>(<span class="hljs-attr">style</span>=<span class="hljs-string">&#x27;margin: 0&#x27;</span>)</span>
-<span class="language-ruby">items.each <span class="hljs-keyword">do</span> <span class="hljs-params">|i|</span></span>
-<span class="language-ruby">items.each <span class="hljs-keyword">do</span> |<span class="hljs-params">i</span>|</span>
<span class="hljs-tag"> %<span class="hljs-selector-tag">i</span></span>= i
=<span class="language-ruby"> variable</span>
=<span class="language-ruby">variable2</span>
Expand Down
4 changes: 2 additions & 2 deletions test/markup/ruby/heredoc.expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ message = <span class="hljs-string">&lt;&lt;-MESSAGE.chomp
This looks good
MESSAGE</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">foo</span><span class="hljs-params">()</span></span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">foo</span>()
msg = <span class="hljs-string">&lt;&lt;-HTML
&lt;div&gt;
&lt;h4&gt;<span class="hljs-subst">#{bar}</span>&lt;/h4&gt;
&lt;/div&gt;
HTML</span>
<span class="hljs-keyword">end</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">baz</span><span class="hljs-params">()</span></span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">baz</span>()
msg = <span class="hljs-string">&lt;&lt;~FOO
&lt;div&gt;
&lt;h4&gt;<span class="hljs-subst">#{bar}</span>&lt;/h4&gt;
Expand Down
6 changes: 3 additions & 3 deletions test/markup/ruby/prompt.expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<span class="hljs-meta prompt_">jruby-1.7.16 :001 &gt;</span> <span class="hljs-string">&quot;RVM-Format&quot;</span>

<span class="hljs-meta prompt_">&gt;&gt;</span> obj = OpenStruct.new <span class="hljs-symbol">:integer</span> =&gt; <span class="hljs-number">987</span>, <span class="hljs-symbol">:symbol</span> =&gt; <span class="hljs-symbol">:so_great</span>
<span class="hljs-meta prompt_">&gt;&gt;</span> obj = <span class="hljs-title class_">OpenStruct</span>.new <span class="hljs-symbol">:integer</span> =&gt; <span class="hljs-number">987</span>, <span class="hljs-symbol">:symbol</span> =&gt; <span class="hljs-symbol">:so_great</span>
=&gt; #&lt;OpenStruct integer=987, symbol=:so_great&gt;
<span class="hljs-meta prompt_">&gt;&gt;</span> [obj,obj,obj]
=&gt; [#&lt;OpenStruct integer=987, symbol=:so_great&gt;, #&lt;OpenStruct integer=987, symbol=:so_great&gt;, #&lt;OpenStruct integer=987, symbol=:so_great&gt;]
Expand All @@ -22,8 +22,8 @@

<span class="hljs-meta prompt_">irb(main):002:0&gt;</span> test = <span class="hljs-number">1</span>

<span class="hljs-meta prompt_">irb(main):001:1*</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Secret</span></span>
<span class="hljs-meta prompt_">irb(main):002:2*</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">[]</span><span class="hljs-params">(x)</span></span>
<span class="hljs-meta prompt_">irb(main):001:1*</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Secret</span>
<span class="hljs-meta prompt_">irb(main):002:2*</span> <span class="hljs-keyword">def</span> <span class="hljs-title function_">[]</span>(<span class="hljs-params">x</span>)
<span class="hljs-meta prompt_">irb(main):003:2*</span> <span class="hljs-string">&quot;TREASURE&quot;</span> <span class="hljs-keyword">if</span> x==<span class="hljs-number">42</span>
<span class="hljs-meta prompt_">irb(main):004:1*</span> <span class="hljs-keyword">end</span>
<span class="hljs-meta prompt_">irb(main):005:0&gt;</span> <span class="hljs-keyword">end</span>
Expand Down

0 comments on commit 8cea942

Please sign in to comment.