Skip to content
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

fix(ruby) symbols, string interpolation, class names with underscores #4213

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

jimtng
Copy link

@jimtng jimtng commented Feb 25, 2025

Also fix #3676

Change from:

image image image

To:

image image image

Checklist

  • Added markup tests
  • Updated the changelog at CHANGES.md

@jimtng jimtng force-pushed the ruby-class-underscore branch from 169267e to f1ae3ab Compare February 25, 2025 14:21
@jimtng jimtng changed the title fix(ruby): highlight entire class names with underscore fix(ruby) highlight entire class name even when it contains underscores Feb 25, 2025
@jimtng jimtng force-pushed the ruby-class-underscore branch 3 times, most recently from 39e0632 to 5e38774 Compare February 28, 2025 12:49
@jimtng jimtng changed the title fix(ruby) highlight entire class name even when it contains underscores fix(ruby) symbols, string interpolation, class names with underscores Feb 28, 2025
@jimtng jimtng force-pushed the ruby-class-underscore branch from 5e38774 to 67644b9 Compare February 28, 2025 13:24
Comment on lines -20 to +14
const CLASS_NAME_WITH_NAMESPACE_RE = regex.concat(CLASS_NAME_RE, /(::\w+)*/)
const CLASS_NAME_RE = /\b([A-Z]+[a-z0-9_]+)+[A-Z]*/;
Copy link
Member

@joshgoebel joshgoebel Mar 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this removal break (at least) the inheritance highlighting?

Copy link
Author

@jimtng jimtng Mar 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you give an example syntax of what you mean?

Class::With::Namespace

will work fine and better, because it doesn't highlight the :: much like it doesn't here in github, or vscode.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

class C::E < A::B
end

We have special rules to match syntax where we KNOW an identifier is a class (or class with namespaces).

it doesn't here in github, or vscode

Striving for exact matches against other highlighting tools isn't a thing we care about here.


In this case I'm sympathetic to not highlighting the ::, but only if it can be done without adding a lot of complexity or advanced parsing to the grammar.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You really want something like [class](::[class])* but our multi-match engine can't really handle that - with discrete coloring of the different pieces. Maybe if you tried a long sequence with some items that matched 0 length, but I'm not sure I've tested multi-matching in that type of scenario before.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This case would've worked fine, except it didn't recognise single-letter classes. I've adjusted it to do so.

class C::E < A::B
end
image

Copy link
Member

@joshgoebel joshgoebel Mar 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use "show the structure". as you develop. If you're matching all those "one off" with just your class rule then you're missing out on the fact that the portion after the < is not just a title.class, it's a title.class.inherited.

This is why the simple multi-match rules exist - to flesh out more detail as well as handle cases like class A where we KNOW A is a class here, not a constant (as it would be with non other context).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't aware of the different handling for title.class.inherited.

Whilst special casing class A works using a multi-match rule, it wouldn't help for A.method(foo) which will still be matched as a constant. So I'd suggest we simplify and not handle the class A case at all.

In the current version, it doesn't work either: https://highlightjs.org/demo#lang=ruby&v=1&theme=atom-one-dark&code=Y2xhc3MgQQplbmQKCscNOjpCywsgPCBDOjpExxJGb286OkZvbyA8yQvKGsYVyEjEC8VXQSA9ICdYJw%3D%3D

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the latest commit here, it looks like this

image

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

{
className: 'symbol',
begin: hljs.UNDERSCORE_IDENT_RE + '(!|\\?)?:',
relevance: 0
},
{
className: 'symbol',
begin: ':(?!\\s)',
begin: '(?<!:):(?!\\s|:)',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't use negative lookbehind until v12 as that would be a breaking change.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rule on line 378 is designed to deal with :: and prevent false symbol positives - until v12 where it would be simpler to use negative lookbehind.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing this negative lookbehind will cause this:
image

The rule on line 378 doesn't seem to do its job.

So I had to adjust line 378 so I can remove the negative lookbehind.

@jimtng jimtng requested a review from joshgoebel March 5, 2025 04:43
@jimtng jimtng force-pushed the ruby-class-underscore branch from 23fc7dd to 0be49c6 Compare March 5, 2025 04:47
@@ -375,7 +375,7 @@ export default function(hljs) {
METHOD_DEFINITION,
{
// swallow namespace qualifiers before symbols
begin: hljs.IDENT_RE + '::'
begin: '::'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think this works.

@jimtng
Copy link
Author

jimtng commented Mar 6, 2025

@joshgoebel can we use a positive lookbehind? It seems to work when I tested it.

@joshgoebel
Copy link
Member

an we use a positive lookbehind?

No. Until v12 we have to support older versions of Safari that don't have this built-in. What issue are we still trying to solve with lookbehind?

@jimtng
Copy link
Author

jimtng commented Mar 7, 2025

What issue are we still trying to solve with lookbehind?

I used a positive lookbehind for title.class.inherited. I'll try again using a different approach.

@jimtng
Copy link
Author

jimtng commented Mar 7, 2025

@joshgoebel I've managed to do the inheritance without the use of a lookbehind

image image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

(Ruby) #{} substitution shouldn't be highlighted in single quotes
2 participants