Like I was trying to say, and others have said, the language specific bits should be subordinate to the generic. Color schemes are generally dialed into the generic level of specification, but more detailed schemes, language specific, could dial into the deeper level.
Hide function calls from Go To Symbol
I know you want generic scopes and I want them too, all I am asking is some documents that shows code snippets for each language and the scopes that we should expect, for example:
javascript:
function someFunction({a,b,c}) {}
// ^^^^^^^^ storage.type
// ^^^^^^^^^^^^ variable.function
mql:
void someFunction(int a, bool b) {}
// ^^^^ some.scope
// ^^^^^^^^^^^^ variable.function
It could be a expansion of your docs, basically code examples and the expected tokens. It would be easier not only to external syntaxes to sync with the core scopes but also serve as guideline for anyone creating a color scheme.
A markdown document broken into sections, variables, functions, classes, etc⌠thatâs why I said some sort of âscope specificationâ, a plan that people can see, follow and suggest changes. Sorry for any misunderstanding, english is not my first language.
Isnât that what the scope naming guidelines basically are, or am I missing part of what you are looking for?
The guidelines sometimes are too vague, other times it doesnât cover specific language features. Having snippets would be easier, it would remove any doubt like in the case of destructuring, decorators, etc⌠we could check that a specific feature is actually covered already by looking at the snippet as it might just be using a different name because of the problems you mentioned before.
I think that what @borela is looking for is a document written âbackwardâ from the scope naming guidelines. The guidelines enumerate the standard scopes and describe what each is used for. It could be useful to have a supplementary document that lists common language features and suggests ways to scope them, with examples. It would mostly be a different way of organizing the same information.
For example, suppose Iâm writing a JavaScript syntax and I want to know how to highlight functions. I should use all of the following scopes:
meta.function
meta.function.parameters
-
storage.type.function
(for thefunction
keyword) entity.name.function
variable.parameter
-
punctuation.section.group
andpunctuation.separator
(for the parameters) -
punctuation.section.block
(for the function body)
The scope naming guidelines are organized by scope, not by application. This makes sense for a definitive reference, and itâs probably what youâd want to see when writing a color scheme. But another document organized by language feature and filled with examples from the core syntaxes could be an invaluable reference when writing a syntax definition. Myself, I donât think that this would interfere with or substitute for the scope naming guidelines. This could be purely a community project using the scope naming guidelines and core syntaxes as its source.
Separately and additionally, it may be that the community converges on more-specific scopes for some common language features, and when that happens such scopes might be worthwhile additions to the scope naming guidelines as well as to any supplemental document. I think that this is an orthogonal concern.
It could certainly drive some discussion. While writing the VHDL syntax definition, I definitely scratched my head about the right scope for various situations. And in some places the scope documentation was valuable, and in a couple of place I punted.
And still I realized from this discussion that Iâd scoped the language subprogram calls as meta.statement.procedure.vhdl
and the preferred flavor began with meta.function-call
. So I fix these things as they come up.
It is definitely a non-trivial documentation task though. Documenting the scopes is up there with writing a summary of the language spec itself.
I considered this when writing the guidelines, but one of my concerns was people reading the âminimalâ example and then getting a bunch of scopes wrong because they didnât understand the full list of scopes and how they should be applied.
Iâm wouldnât be opposed to someone starting this. Right now Iâm not working on documentation, but there is no reason I would need to be the one writing this document. It could live as a gist, or a repo under https://github.com/SublimeText for now.
I would favor a repo under https://github.com/SublimeText to allow pull requests and issues. Also openning up sublimeâs documentation for pull requests is a great idea.
Something that hasnât been mentioned so far is that syntax tests in the Packages repo can be used as a backwards reference point, at least for the more mature syntax definitions. They all receive varying amounts of attention based on preferences of core contributors (and their (lack of) knowledge about certain languages), so you probably shouldnât just pick any languageâs syntax tests, but those for JavaScript should be pretty much up there.
I can create a repo on the SublimeText org that could be used to work on this backwards syntax development guide. Just give me a name. And maybe an owner that would handle general maintenance of the repo.
It could also be added to the unofficial docs at a later point, depending on how it turns out, or at the very least referenced.
While the tests do help to some degree we would need a document broken by language features, e.g. in the case of javascript: decorator, destructuring, class, function, operator, etc⌠so that people can easily search if there are any scopes for a feature already just with a different name.
I could help specially with syntaxes not covered by the core like MQL and FlowType.
Hereâs an example of why I think the reverse document would be necessary, I synced a lot of scopes based on the unit tests but then issues started to appear, which scope to give to decorators? I used the same as annotations from C# as it has similar semantics, another one is array literals, while the core syntax uses a combination of meta.sequence
with punctuation.section.brackets
, lots of color schemes support punctuation.definition.array
.
Should the meta scopes âbleedâ? Consider the following example:
let a = [b[1], c[1]]
If we allow meta.sequence
to envelop b[1]
and c[1]
, it would be next to impossible to give different colors to array literals and the property accessor []
, limiting the meta scopes to the punctuation only would allow color schemes to differentiate them both easily.
Bleed is probably not the word you are looking for. I would generally think bleed would mean going beyond the edges of something, as it is used in the printing industry.
Without you specifying test assertions for the code, Iâm not 100% what you are referring to. However, your statement as the end:
Meta scopes are generally intended to cover an entire construct, that is semantically a unit at some level, but that wonât be highlighted all the same color because it is made up of smaller individual tokens.
For instance, here is an example of how I would write assertions for your example:
let a = [b[1], c[1]]
//<- storage.type
//<- storage.type
//^ storage.type
// ^ variable.other
// ^ keyword.operator
// ^^^^^^^^^^^^ meta.sequence
// ^ punctionation.section.brackets.begin
// ^ variable.other.readwrite
// ^^^ meta.item-access
// ^ punctuation.section.brackets.begin
// ^ constant.numeric
// ^ punctuation.section.brackets.end
// ^ punctuation.separator
// ^ variable.other.readwrite
// ^^^ meta.item-access
// ^ punctuation.section.brackets.begin
// ^ constant.numeric
// ^ punctuation.section.brackets.end
// ^ punctuation.section.brackets.end
You can target the property accessor by targeting meta.item-access punctuation.section.brackets
. General brackets can be targeted by punctuation.section.brackets
.
You are right, I didnât quite knew which word to use, I meant marking expressions with meta.sequence
vs only the punctuation. The problem is that the meta scopes stack, consider this:
let a = [ b [ [1,2,3][0] ] ]
The example is absurd I know but following that logic, the [1,2,3] would have both meta.sequence
and meta.item-access
(from a parent meta scope). The same issue would happen if you try to give a different color to {} for function and class bodies.
If in a color scheme you apply one color to meta.sequence punctuation.section.brackets
and another to meta.item-access punctuation.section.brackets
, wonât the one with the highest score be applied? And in meta.sequence meta.item-access punctuation.section brackets
, wonât the latter selector score higher?
A more realistic example:
class MyClass {
myMethod() {
}
}
I canât set a different color for the classâs body {} and the methodâs body {} because the meta.class
is being applied to the methodâs {} too.
The example was bad, I looked at the scopes, the error is in the core syntax, itâs not generating the meta.item-access scope. But the class example is still validâŚ
That is fine though. The more specific a scope name in the color scheme, the higher precedence it has. That is why I suggested a two scope specified for item access and a single scope specifier for generic brackets.
Your proposal for adding meta scopes to the brackets only would effectively make them not meta scopes, but just an extra scope added to brackets when they are part of item access. If you want to support this, probably the most compatible way would be to use the scopes:
punctuation.section.brackets.begin.item-access
punctuation.section.brackets.end.item-access
I use the term âspecializationâ to refer to this sort of scope. This would allow color scheme authors to target a specific bracket, if they also wanted to color another type of bracket, even when it was used inside of item access (e.g. b[c['foo']()]
). At least I think that is valid JS (but an obtuse way) to call the foo
function on c
and use the return value as the property name to access on b
.
The only other way I think we could improve this would be to support something like a child operator a la CSS: meta.brackets > punctuation.section.brackets
where we would only match when meta.brackets
was the direct parent of the punctuation.section
scope. Currently we support the &
, |
and -
operators, for compatibility with TextMate color schemes.