-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
More nuance for match classes (class title? function title? etc.) #2521
Comments
Option 2 also leaves a lot of runway for expanding other classes:
This allows grammars to start slowly becoming more expressive while also still thinking in terms of our initial list of classes to avoid all our existing themes from suddenly becoming invalid overnight. Some of these would even come for "free" to existing grammars simply by our upgrading the mode library to be more explicit, such as "comment.block"... |
I should note that technically it's possible to do this today in a grammar: { // ES6 class
className: 'class', beginKeywords: 'class', ...,
contains: [
{ skipBefore:/extends\s+/, begin: IDENT_RE, className: "title title-class title-class-super" },
hljs.inherit(hljs.UNDERSCORE_TITLE_MODE, {className: "title title-class"})
]
}, Ok, scratch that ALMOST possible (or possible if you want to hack the CSS a bit)... we only add the
If someone called this a bug though I'm not sure I'd disagree. But I'd like to formalize this and come up with naming guidance so that over time we can see themes start to taken advantage of these things. |
I get tripped up on things like So filing them all under |
Nice idea. |
Yes, meta is the only thing we have broken up like that. It's a very good idea. TextMate goes a little overboard with it... going 3-5 levels deep - you can get VERY nuanced. :-) And if we did it the way I'm suggesting above we could technically switch those to |
Oh Actually we have |
I'm not sure you really need that level of details in highlighting, especially given that you can't 100% correctly parse source code with regexps... But consistency in classes naming (and usage) certainly won't hurt us (: |
Oh I wasn't suggesting we go that crazy, but it is easily possible for us to do things like contextually detect differences (in many cases) from a class name and say a function name, etc. So those are the easy wins. |
Being more precise is a good idea! |
Just how it's always been done? OTTOMH I think your logic sounds right. It's also still a class though, just not the one being defined... that might make it different than say |
The
Spending some time thinking about this... and it seems "variable.property" and "name.function" would add a lot of fidelity (often requested) and also be fairly easy to pattern recognize for at least most C-like languages. So instead of adding these and no themes having support, and then perhaps waiting forever (or living with only a very few themes that are "enhanced")... I think we could try our best to reuse the existing styling (even if it's not perfect)... so then immediately existing styles pick up the new highlighting and if someone wants to tweak them... I think this might cause some slight pain in the immediate future but have the best long-term result. So here is what I'm currently thinking:
All existing themes would receive the new styles via programatic updates during the build process, ie these new styles will simply be added when missing. If a theme wants to opt-out (or override the defaults) they need only add the missing selector to the style to prevent the auto-upgrade from adding a selector. The "hierarchy" here would be handled by the build process... for example a CSS rule for
The alternative (for hierarchy) is generating a bunch of extra HTML which doesn't seem like a good idea to me. Rather a few additional selectors than a bunch of new HTML. Thoughts? @allejo @egor-rogov |
At this point I think we could also perhaps consider allowing enhanced grammars to define their own semantic subgroups... Ie we dictate the top-level domain space "name" but then might allow |
One final note about what I mean when I say:
I worry that some (not all) of our themes may have skewed towards being optimized for "scarcity"... ie perhaps "title" pops more than it should because this class was handed out more rarely in the past. That some themes may not handle the sudden flood of color as well as others... but again I think this could be dealt with on a case by case basis - even using the auto-generation logic to purposely "tune" or "exclude" some themes that got flagged as doing very poorly. This isn't an entirely new problem though, I noticed this a bit with the recent change to start highlighting class functions, etc. |
I'm not sure what language that is meant to be... in many languages there isn't enough absolutely information in such a snippet to know WithContext is a constructor vs just any old function... |
It was a subset of a larger code. Since higlight.js clearly detects function definitions and classes, it aught to be able to detect the initation/calls to those definitions? And by doing so add more nuance and highlight to the initiation calls. class WithContext():
def __init__(self):
self.value = 5
def __enter__(self):
return self
def __exit__(self, *args, **kwargs):
if args and args[1] == KeyError:
pass
return True
def multiply(self):
return self.value * 2
def crash(self):
raise KeyError("crashed")
for i in range(100000000):
handle = WithContext()
handle.multiply()
|
We are not a full language parser and we therefore (with small exceptions) do not track any context or parsing state. Once we highlight Now some languages you have "immediate" context such as JS: let x = new Widget(); It's possible for us to understand what But that's not possible in all languages. |
I've mentioned elsewhere that I'd be curious to see how we might allow 3rd party grammars to integrate a full parser of their own and pair that parser with our own output engine - but that is not a desire for the core library. |
I understand, I just started using highlight.js and came across this issue when I wanted to highlight the classes/functions in the code, not just the definition. I get that the parsing might be hell so I fully understand if that might never be implemented. It's fine the way it is :) |
If all the classes in Python are camel case by STRONG convention it's still possible with just patten matching, and I think we'd be open to such a PR. |
See #3078. We already have classes with
Since Right now I'm using
|
These classes will still have the leading |
This may still change again because of the discussion happening over in PrismJS/prism#2849. |
Removed the builtin-name replacing it with built_in in the few (4-5) grammars it was used. Also only 4 themes made any distinction between built_in and builtin-name, the rest choosing to style these exactly the same - so it's never been clear what the difference is or there is none. If more nuance is needed here it should be addressed via #2500 and #2521. In only one grammar was both built_in and builtin-name used side by side so other than that (in combo with very particular themes) this should be a quiet change.
Progress has been made on this with v11 (see all the new advanced scopes, etc) and I'm closing this and considering it folded into #2500 which will remain open. |
Table of some specific suggestions:
Is your request related to a specific problem you're having?
Yes, I'd like to have a way to label/highlight names of a given type outside of their original context.
For example:
Turns into
<class><title>Cat</title><keyword>extends</keyword><title>Pet</title>
. And if we wanted to style it a certain way we could target.hljs-class .hljs-title
. Although Pet is semantically different here and that's not indicated at all.The same is true for functions:
Turns into
<function><title>cleanMyRoom</title...
and hence could be targeted by a theme with.hljs-function .hljs-title
... but now we have the usage of these things outside of their definition:In both cases [re:
Cat
] we can easily figure out this is a "class" object and we could applytitle
to it... but is it a class? a namespace? a function name? We've lost all context.And for functions:
Technically
launchTheRockets
is a name/title here (and we could easily detect that and highlight)... but it's not the function itself (which is() => {...}
... so again we have a name without context... and we're forced to fall back to the generictitle
.And this problem get worse for languages that also have namespaces that could also be syntactically inferred... all we have is
title
and perhaps context at the definition site - although we have nonamespace
class...The solution you'd prefer / feature you'd like to see added...
I think we may need to consider some new classes, or expanding existing ones with sub classes:
class_name
,function_name
,namespace_name
title.function
,title.class
,title.namespace
...The way alternative 2 would unfolding during rendering CSS might look something like:
IE, the existing "broader" class is preserved. This would require no changes to any existing styles, while allowing new themes (or upgrades) to target items with more specificity. I'm a little more attached to system 2 as it seems more easily "backwards compatible".
Any alternative solutions you considered...
Nope, I outlined my two thoughts above.
Additional context...
I spent some time reviewing how Prism handles this and it has a lot more named options for tracking what "kind of thing" a given identifier might be:
constant
class-name
function-name
(though most grammars usefunction
)namespace
This allows it to make some really nice distinctions when highlighting (like treating classes differently than function name, etc).
The text was updated successfully, but these errors were encountered: