-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Highlight Ruby method definitions without arguments #1523
Conversation
Inheriting from `clike` is enough to deal with constructs like this ```ruby def foo(bar) ... end ``` but not ```ruby def foo ... end ``` This does not highlight call sites, but since much idiomatic Ruby doesn't use parentheses in function calls, call sites can't be consistently highlighted anyway.
Okay, I definitely forgot to consider the knock-on effects of my changes on languages that extend ruby. Before I go changing tests of other languages/defining “function” back to clike’s version in those language, I would like your opinion of whether this change is acceptable. I think the consistent lack of highlighting at call-sites is better than highlighting Additionally, I found that my PR is also still not ready to merge, since it broke static method definitions. class Foo
def self.bar # This is broken in my PR: <def> <self>.bar where <_> is “keyword”
end
end I can’t seem to make it look back past two other highlighted segments so I’d appreciate guidance. |
Ok, I looked into it and the problem has to do with how greedy matching is currently implemented. We might need to change that behavior but for the time being, there is an easy workaround: Your pattern requires that it can match the |
See [Crystal's docs][docs] where `@[Extern]` is highlighted the same as `@[Extern(union: true)]`. [docs]: https://crystal-lang.org/docs/syntax_and_semantics/attributes.html#extern
components/prism-ruby.js
Outdated
@@ -13,7 +13,7 @@ | |||
greedy: true | |||
} | |||
], | |||
'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/ | |||
'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/, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably just nitpicking, but could you please remove the additional comma?
components/prism-ruby.js
Outdated
@@ -75,6 +77,10 @@ | |||
'symbol': { | |||
pattern: /(^|[^:]):[a-zA-Z_]\w*(?:[?!]|\b)/, | |||
lookbehind: true | |||
}, | |||
'function': { | |||
pattern: /(def )[\w.]+/, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a little fun with a Ruby REPL and found that this pattern will also happily match:
my_function_def variable
But at the same time, it doesn't match
def
extra_spaces_and_new_line(arg)
end
Changing the lookbehind group to (\bdef\s+)
ought to solve these cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. (Although I’ve never seen someone put a newline between def
and the method name)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, me either, but the compiler can handle it, so there is probably someone out there using it.
Two things concerning the insides of function names:
Both are illustrated by your example: def self.bar
end |
@RunDevelopment I had intended for class method definitions to be highlighted that way, since that’s how I’m used to seeing it in atom, vscode, Github, and Textmate. A more complete survey, however, reveals that’s far from universal: vim and pygment (which ruby-lang.org uses, and I’m taking that as an endorsement of its style) both highlight Also to my horror I have found it is possible to do this class Foo
def String.bar
42
end
end
String.bar # => 42 |
@cbothner 'function-declaration': {
pattern: /(\bdef\s+)[\w.]+/,
lookbehind: true,
inside: {
'function': /\w+$/,
rest: null
}
} and at the end of the language definition (after Prism.languages.ruby['function-declaration'].inside.rest = Prism.languages.ruby; And like that, we should have a (It seems to work but I haven't thoroughly tested it) |
Sometimes definitions of class methods `def [self.foo]` are highlighted where everything in brackets is the same color; other times `self` and `.` are highlighted as keyword and punctuation. This adds a wrapper `method-definition` which allows users to choose.
Ah, nice job thinking like a platform maker. Here I was thinking we had to make a decision, and your suggestion preserves the user’s a ability to choose. I like that. I think I correctly understood your merged PR #1531 and didn’t use the workaround you initially proposed… |
@cbothner |
@RunDevelopment How is this PR looking? |
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.
Inheriting from
clike
is enough to deal with constructs like thisbut not
Now, admittedly this does not highlight call sites. But since much idiomatic Ruby doesn’t use parentheses in function calls, call sites can’t be consistently highlighted anyway. This behavior is consistent with the ruby definitions used by at least vim, Atom, and Github (e.g. below)
It is also the most internally consistent behavior: all method definitions have the name highlighted; no call sites do.