What's the risk of not-defining standard syntax variables?


#1

The template file syntax-variables.less contains the following statement:

// This defines all syntax variables that syntax themes must implement when they
// include a syntax-variables.less file.
  • What are the risks one runs if one creates a syntax theme that does not contain some (or any) of these variable definitions?
  • Whether or not those variables need to be defined, does a file named syntax-variables.less have to exist at all? For example, could these definitions be “inlined” into base.less without any problem?

Background: I’m curious about dynamically adjusting a theme (e.g. in response to settings), and I think that might mean that what has to be done is to build up a CSS style sheet in code, rather than using a static .less file at all. And since once it’s in the DOM there’s no concept of a CSS variable — that’s just a thing implemented in LESS during its compilation step, right? — I’m wondering which particular world of hurt I’m about to be asking for.


#2

Package authors, like myself, depend on the syntax-variables.less and its counterpart, the ui-variables.less files being available so that they can make their packages blend into your theme. For example, in my soft-wrap-indicator package:

https://github.com/lee-dohm/soft-wrap-indicator/blob/master/stylesheets/soft-wrap-indicator.less#L1-L10

Notice the use of the @text-color and @text-color-highlight variables. This means that my package doesn’t have to guess at how to make a new status bar indicator look like it belongs or one-off configure for every possible theme out there.

Here’s an example of what can happen:


#3

Gotcha. To be clear, this means that that comment has a false implication, right?: It seems to say if you have syntax-variables then you need to define such-and-such, but not that you definitely have to have that file.

And as a follow-up, then: Let’s say I want to make @text-color-highlight depend in a nontrivial way on settings in my syntax theme (e.g., maybe it’s a blend of a base text color and a base highlight color, each of which is individually settable). How does one make that sort of thing work? Is it possible at all?


#4

That’s correct. Syntax themes should (or must) have this file available, any other package can ignore this file. You could @import 'syntax-variables.less'; from the ui-variables.less, if you want to make colors from a ui theme “match” the colors from a syntax theme. It may not always work the way you expect/hope it to, though, because some syntax themes behave differently than others…


#5

Personally, I wouldn’t read it the way you’re inferring. I kind of feel like you’re saying that “Come to a full and complete stop when arriving at a four-way intersection,” means that it is optional if you never arrive at the intersection but keep on driving through :wink:

But seriously, here is where it mentions the ui-variables.less:

Interface themes must provide a ui-variables.less file which contains all of the variables provided by the core themes.

I know that the recently added syntax-variables.less was intended to be a mirror of the ui-variables.less. Yes, the documentation hasn’t caught up with where the application is yet. But as you can see in this comment:

the Atom team is actively working on that.

As for your other questions, I don’t have an answer. I’m not a CSS guy.™


#6

I also think that

Interface themes must provide a ui-variables.less file which contains all of the variables provided by the core themes.

is true for syntax-variables.less. So the file must exist as well as all the variables.

Now let’s say you don’t add the syntax-variables.less file or remove some of its variables. When a package tries to use your theme’s variables, but can’t be find it, it will just use the fallback value that is provided by Atom’s core:

Sometimes maybe ok, but sometimes it would look wrong and wouldn’t match your theme.

Background: I’m curious about dynamically adjusting a theme (e.g. in response to settings)

There has been some experimenting going on about letting themes be customizable from the settings. https://github.com/atom/settings-view/pull/275 and the newer https://github.com/atom/settings-view/pull/325 Hopefully it will fit your needs.


#7

Thanks for the links to the theme settings PRs (and thanks to others for their replies as well).

Hopefully [theme settings] will fit your needs.

I’m not sure. It looks to me like this enables core Atom to offer variables to be made available in the context of LESS. However, what I think I’d be looking for is a way to have my own syntax theme offer such variables, which would be an alternative to having a syntax-variables.less file.

With the caveat that — while I am an experienced API designer — I am not very experienced with the Atom code base, having to have a required file in this manner strikes me as a major rough edge in the existing Atom API, on at least a couple fronts: (a) Nearly everything else in the API is directly accessible from CS/JS. (b) This brings all of LESS more deeply into the API compared to it being just one choice for CSS generation.


#8

[Warning: Off-topic linguistics digression, written by a trained, though rusty, linguist.]

The implication of your sentence is that, in fact, there are times that you are driving when you are not at a four-way intersection, which I think is a reasonable implication. Likewise, the text I originally quoted (softly) implies that there are times that you are writing a syntax theme where a syntax-variables.less isn’t included.

For the full TLDR on this look up “Gricean implicature.” In this case, it would have been just as easy to state that the file is required, which is why the way the text as currently written effectively implies the opposite.


#9

In the first PR the idea was to have the settings globally, but in the second one (and I think that’s the direction where it’s going), each theme will have their own settings, just like packages. That way themes are more free to use what they need.

There needs to be “some kind” of convention, otherwise package creators that want to use variables from themes have no idea how the variables are called. With a set of agreed variables, you can switch themes and packages will adapt to the selected theme.

If you’re not happy with the variable names from syntax-variables.less, you could do this:

  1. Create your theme however you like. Use your own variables/structure etc.
  2. But then still include the syntax-variables.less file and map all its variables to the ones that your theme is using.
// my-vars.less
@my-background-color: red;

// syntax-variables.less
@import "my-vars";
@syntax-background-color: @my-background-color;

That extra step would make your theme compatible with all other Atom packages.

ps. I do agree that the docs could be more clear about it. Let’s improve them, once they’re split out.


#10

No argument on that point. What I figured was that maybe it was possible to have a syntax theme define and export the variables purely in CS/JS code, instead of having to always get them defined by a LESS format file with a particular name.

How would that work if my-background-color is defined dynamically in CS/JS code? Going back to my original example, let’s say I want to have two different color / style settings which, when combined, are to become one of the standard exported syntax variables.


#11

As discussed in this topic:

you could write from a CS file to the syntax-variables.less file. I use it in one of my packages so the user can define custom colors:

https://github.com/olmokramer/atom-block-cursor/blob/master/lib/block-cursor.coffee#L64-L69


#12

In LESS there is a mix color function that you could use.

@syntax-background-color: mix(@settings-color-a, @settings-color-b, 50%);

But maybe that’s not enough and you like to use your own mixing algorithm.

@olmokramer’s suggestion above might work. I guess in the end, you would also need to write all your theme’s styles that are done “dynamically in CS/JS code” to a CSS/LESS file, no? AFAIK, when picking a theme in Atom, it looks for a theme/index.less or theme/index.css file and injects that. Or would you try to inject/inline it yourself?


#13

As a practical matter, I bet LESS has enough built-in functions for anything I’d actually wanted to do, but yes what I’m trying to understand here are the limits.

LESS’s mixing functionality aside, I’m more concerned about actually getting the variables transported from CS/JS code into the scope of LESS. That is, per below, how would my two colors even become variables that could be mixed by LESS?

On the one hand, it’s nice to know that there is a workaround, which apparently works for now. On the other, this cements my view that we’re looking at a major deficiency in the Atom API: I mean, self-modifying code getting written to disk just in order to pass a style variable between packages really strikes me as (a) very unlike most of the rest of the API, (b) error-prone to implement, and © extremely fragile.

For me, at least, this solution gives me enough heebie-jeebies that I don’t think I’ll end up using it.

FWIW (and again with the caveat that I’m no Atom internals expert), if I were running the show, I’d add (something like) an observable property to syntax themes which stores the map of its exported style variables. In the default syntax theme implementation, the property would get initialized from the theme’s syntax-variables.less and never updated once loaded, but that could be overridden by syntax themes that wanted to be fancier. Rather than making style-using packages @import 'syntax-variables.less', these variables would just be made generally available anywhere LESS is being used. Alternatively and more backwards-compatibly, it might be up to the core Atom code to write out the “active” syntax-variables.less file (e.g. into Atom’s /tmp) whenever it loads a new syntax theme and keep it updated if/when the active theme happens to change its exports; that would be the file that would be used by inter-package @imports.

Thanks again for bearing with me in this discussion.


#14

I like how stylesheets are being handled in Atom. It’s not a rethink of how stylesheets should work and doesn’t solve the inherent static nature of them, but it’s proven technology that thousands of developers and designers will be able to use and come up with stuff.

If you need dynamic variables in your stylesheets it seems you’re breaking away from what the default implementation can provide. As the settings-view pull requests indicate, there is no framework for passing variables to stylesheets yet, but there will be. Until that time, perhaps the pr’s have code you can already use. You could go as far as writing something that uses your own Less compiler and inserts the output somewhere in the DOM. Just more hacking required.