From 7277591992394e27335234828345ff6cbaa33bb0 Mon Sep 17 00:00:00 2001 From: Cameron Bothner Date: Sat, 1 Dec 2018 16:38:05 -0500 Subject: [PATCH] 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. --- components/prism-ruby.js | 12 ++- components/prism-ruby.min.js | 2 +- .../languages/crystal/attribute_feature.test | 2 +- tests/languages/crystal/keyword_feature.test | 6 +- .../languages/erb/erb_in_markup_feature.test | 4 +- tests/languages/haml/tag_feature.test | 4 +- tests/languages/ruby/keyword_feature.test | 6 +- .../ruby/method_definition_feature.test | 82 +++++++++++++++++++ 8 files changed, 106 insertions(+), 12 deletions(-) create mode 100644 tests/languages/ruby/method_definition_feature.test diff --git a/components/prism-ruby.js b/components/prism-ruby.js index 53a6840c54..72b5ebbade 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 48a5092369..7720acc7d2 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 02d07afd7a..4fb0bad1d0 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 ea15473e98..962beadf84 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 6bdb845705..20719ea8c6 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 e5927d04a9..a1e0c0de8d 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 f9af2a3599..c67c45d01a 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 0000000000..ee8b5ec530 --- /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