Commit 7277591992394e27335234828345ff6cbaa33bb0

Cameron Bothner 2018-12-01T16:38:05

Consistent Ruby method highlighting (#1523) Ruby methods might or might be called in C-style creating inconsistent highlighting. This highlights only method definitions and removes the highlighting of C-style-invoked methods.

diff --git a/components/prism-ruby.js b/components/prism-ruby.js
index 53a6840..72b5ebb 100644
--- a/components/prism-ruby.js
+++ b/components/prism-ruby.js
@@ -27,6 +27,8 @@
 		}
 	};
 
+	delete Prism.languages.ruby.function;
+
 	Prism.languages.insertBefore('ruby', 'keyword', {
 		'regex': [
 			{
@@ -75,6 +77,14 @@
 		'symbol': {
 			pattern: /(^|[^:]):[a-zA-Z_]\w*(?:[?!]|\b)/,
 			lookbehind: true
+		},
+		'method-definition': {
+			pattern: /(\bdef\s+)[\w.]+/,
+			lookbehind: true,
+			inside: {
+				'function': /\w+$/,
+				rest: Prism.languages.ruby
+			}
 		}
 	});
 
@@ -128,4 +138,4 @@
 			}
 		}
 	];
-}(Prism));
\ No newline at end of file
+}(Prism));
diff --git a/components/prism-ruby.min.js b/components/prism-ruby.min.js
index 48a5092..7720acc 100644
--- a/components/prism-ruby.min.js
+++ b/components/prism-ruby.min.js
@@ -1 +1 @@
-!function(e){e.languages.ruby=e.languages.extend("clike",{comment:[/#.*/,{pattern:/^=begin(?:\r?\n|\r)(?:.*(?:\r?\n|\r))*?=end/m,greedy:!0}],keyword:/\b(?:alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|protected|private|public|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/});var n={pattern:/#\{[^}]+\}/,inside:{delimiter:{pattern:/^#\{|\}$/,alias:"tag"},rest:e.languages.ruby}};e.languages.insertBefore("ruby","keyword",{regex:[{pattern:/%r([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r\((?:[^()\\]|\\[\s\S])*\)[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r\[(?:[^\[\]\\]|\\[\s\S])*\][gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r<(?:[^<>\\]|\\[\s\S])*>[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/(^|[^\/])\/(?!\/)(\[.+?]|\\.|[^\/\\\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0,greedy:!0}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:{pattern:/(^|[^:]):[a-zA-Z_]\w*(?:[?!]|\b)/,lookbehind:!0}}),e.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|Fixnum|Float|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,constant:/\b[A-Z]\w*(?:[?!]|\b)/}),e.languages.ruby.string=[{pattern:/%[qQiIwWxs]?([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\((?:[^()\\]|\\[\s\S])*\)/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\[(?:[^\[\]\\]|\\[\s\S])*\]/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?<(?:[^<>\\]|\\[\s\S])*>/,greedy:!0,inside:{interpolation:n}},{pattern:/("|')(?:#\{[^}]+\}|\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0,inside:{interpolation:n}}]}(Prism);
\ No newline at end of file
+!function(e){e.languages.ruby=e.languages.extend("clike",{comment:[/#.*/,{pattern:/^=begin(?:\r?\n|\r)(?:.*(?:\r?\n|\r))*?=end/m,greedy:!0}],keyword:/\b(?:alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|protected|private|public|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/});var n={pattern:/#\{[^}]+\}/,inside:{delimiter:{pattern:/^#\{|\}$/,alias:"tag"},rest:e.languages.ruby}};delete e.languages.ruby.function,e.languages.insertBefore("ruby","keyword",{regex:[{pattern:/%r([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r\((?:[^()\\]|\\[\s\S])*\)[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r\[(?:[^\[\]\\]|\\[\s\S])*\][gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r<(?:[^<>\\]|\\[\s\S])*>[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/(^|[^\/])\/(?!\/)(\[.+?]|\\.|[^\/\\\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0,greedy:!0}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:{pattern:/(^|[^:]):[a-zA-Z_]\w*(?:[?!]|\b)/,lookbehind:!0},"method-definition":{pattern:/(\bdef\s+)[\w.]+/,lookbehind:!0,inside:{"function":/\w+$/,rest:e.languages.ruby}}}),e.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|Fixnum|Float|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,constant:/\b[A-Z]\w*(?:[?!]|\b)/}),e.languages.ruby.string=[{pattern:/%[qQiIwWxs]?([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\((?:[^()\\]|\\[\s\S])*\)/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\[(?:[^\[\]\\]|\\[\s\S])*\]/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?<(?:[^<>\\]|\\[\s\S])*>/,greedy:!0,inside:{interpolation:n}},{pattern:/("|')(?:#\{[^}]+\}|\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0,inside:{interpolation:n}}]}(Prism);
\ No newline at end of file
diff --git a/tests/languages/crystal/attribute_feature.test b/tests/languages/crystal/attribute_feature.test
index 02d07af..4fb0bad 100644
--- a/tests/languages/crystal/attribute_feature.test
+++ b/tests/languages/crystal/attribute_feature.test
@@ -11,7 +11,7 @@
 	]],
 	["attribute", [
 		["delimiter", "@["],
-		["function", "CallConvention"], ["punctuation", "("], ["string", [ "\"X86_StdCall\"" ]], ["punctuation", ")"],
+		["constant", "CallConvention"], ["punctuation", "("], ["string", [ "\"X86_StdCall\"" ]], ["punctuation", ")"],
 		["delimiter", "]"]
 	]]
 ]
diff --git a/tests/languages/crystal/keyword_feature.test b/tests/languages/crystal/keyword_feature.test
index ea15473..962bead 100644
--- a/tests/languages/crystal/keyword_feature.test
+++ b/tests/languages/crystal/keyword_feature.test
@@ -1,6 +1,7 @@
 abstract alias as asm begin break case
 class;
-def do else elsif
+def;
+do else elsif
 end ensure enum extend for fun
 if include instance_sizeof
 .is_a?
@@ -17,7 +18,8 @@ __FILE__ __LINE__
 [
 	["keyword", "abstract"], ["keyword", "alias"], ["keyword", "as"], ["keyword", "asm"], ["keyword", "begin"], ["keyword", "break"], ["keyword", "case"],
 	["keyword", "class"], ["punctuation", ";"],
-	["keyword", "def"], ["keyword", "do"], ["keyword", "else"], ["keyword", "elsif"],
+	["keyword", "def"],  ["punctuation", ";"],
+	["keyword", "do"], ["keyword", "else"], ["keyword", "elsif"],
 	["keyword", "end"], ["keyword", "ensure"], ["keyword", "enum"], ["keyword", "extend"], ["keyword", "for"], ["keyword", "fun"],
 	["keyword", "if"], ["keyword", "include"], ["keyword", "instance_sizeof"],
 	["punctuation", "."], ["keyword", "is_a?"],
diff --git a/tests/languages/erb/erb_in_markup_feature.test b/tests/languages/erb/erb_in_markup_feature.test
index 6bdb845..20719ea 100644
--- a/tests/languages/erb/erb_in_markup_feature.test
+++ b/tests/languages/erb/erb_in_markup_feature.test
@@ -19,7 +19,7 @@ ___ERB1___<%= 1 %>___ERB2___<%= 2 %>
 				["punctuation", "."],
 				"now",
 				["punctuation", "."],
-				["function", "strftime"],
+				"strftime",
 				["punctuation", "("],
 				["string", ["'%A'"]],
 				["punctuation", ")"],
@@ -45,4 +45,4 @@ ___ERB1___<%= 1 %>___ERB2___<%= 2 %>
 
 ----------------------------------------------------
 
-Checks for ERB inside Markup
\ No newline at end of file
+Checks for ERB inside Markup
diff --git a/tests/languages/haml/tag_feature.test b/tests/languages/haml/tag_feature.test
index e5927d0..a1e0c0d 100644
--- a/tests/languages/haml/tag_feature.test
+++ b/tests/languages/haml/tag_feature.test
@@ -105,7 +105,7 @@
 		"%html",
 		["attributes", [
 			["punctuation", "{"],
-			["function", "html_attrs"],
+			"html_attrs",
 			["punctuation", "("],
 			["string", ["'fr-fr'"]],
 			["punctuation", ")"],
@@ -158,4 +158,4 @@
 
 Checks for tags: basic element names, attributes, html-style attributes,
 attribute methods, boolean attributes, class and id shortcuts,
-implicit div elements, empty tags and whitespace removal.
\ No newline at end of file
+implicit div elements, empty tags and whitespace removal.
diff --git a/tests/languages/ruby/keyword_feature.test b/tests/languages/ruby/keyword_feature.test
index f9af2a3..c67c45d 100644
--- a/tests/languages/ruby/keyword_feature.test
+++ b/tests/languages/ruby/keyword_feature.test
@@ -5,7 +5,7 @@ begin
 break
 case
 class;
-def
+def;
 define_method
 defined
 do
@@ -56,7 +56,7 @@ yield
 	["keyword", "break"],
 	["keyword", "case"],
 	["keyword", "class"], ["punctuation", ";"],
-	["keyword", "def"],
+	["keyword", "def"], ["punctuation", ";"],
 	["keyword", "define_method"],
 	["keyword", "defined"],
 	["keyword", "do"],
@@ -100,4 +100,4 @@ yield
 
 ----------------------------------------------------
 
-Checks for all keywords.
\ No newline at end of file
+Checks for all keywords.
diff --git a/tests/languages/ruby/method_definition_feature.test b/tests/languages/ruby/method_definition_feature.test
new file mode 100644
index 0000000..ee8b5ec
--- /dev/null
+++ b/tests/languages/ruby/method_definition_feature.test
@@ -0,0 +1,82 @@
+class Circle
+  def self.of_diameter(diameter)
+    new diameter / 2
+  end
+
+  def initialize(radius)
+    @radius = radius
+  end
+
+  def circumference
+    Math::PI * radius ** 2
+  end
+
+  # Seattle style
+  def grow_by factor:
+    @radius = @radius * factor
+  end
+end
+
+----------------------------------------------------
+
+[
+  ["keyword", "class"],
+  ["class-name", ["Circle"]],
+  ["keyword", "def"],
+  ["method-definition", [
+    ["keyword", "self"],
+    ["punctuation", "."],
+    ["function", "of_diameter"]
+  ]],
+  ["punctuation", "("],
+  "diameter",
+  ["punctuation", ")"],
+  ["keyword", "new"],
+  ["class-name", ["diameter"]],
+  ["operator", "/"],
+  ["number", "2"],
+  ["keyword", "end"],
+  ["keyword", "def"],
+  ["method-definition", [
+    ["function", "initialize"]
+  ]],
+  ["punctuation", "("],
+  "radius",
+  ["punctuation", ")"],
+  ["variable", "@radius"],
+  ["operator", "="],
+  " radius\n  ",
+  ["keyword", "end"],
+  ["keyword", "def"],
+  ["method-definition", [
+    ["function", "circumference"]
+  ]],
+  ["constant", "Math"],
+  ["punctuation", ":"],
+  ["punctuation", ":"],
+  ["constant", "PI"],
+  ["operator", "*"],
+  " radius ",
+  ["operator", "*"],
+  ["operator", "*"],
+  ["number", "2"],
+  ["keyword", "end"],
+  ["comment", "# Seattle style"],
+  ["keyword", "def"],
+  ["method-definition", [
+    ["function", "grow_by"]
+  ]],
+  " factor",
+  ["punctuation", ":"],
+  ["variable", "@radius"],
+  ["operator", "="],
+  ["variable", "@radius"],
+  ["operator", "*"],
+  " factor\n  ",
+  ["keyword", "end"],
+  ["keyword", "end"]
+]
+
+----------------------------------------------------
+
+Checks that method definitions are highlighted correctly