Skip to content

[Themes] A way to significantly reduce boilerplate #5184

@AmjadHD

Description

@AmjadHD

Problem description

While developing a sublime theme, I realized how repetitive the task is, to make it adaptive I need to duplicate rules for different luminosity attributes.
An example with 3 variables and 2 rules:

{
  "variables": {
    "bg": "var(--background)",
    "fg": "color(var(bg) l(+ 60%))",
    "fg-hover": "color(var(fg) l(+ 20%))",

    "bg-light": "color(var(--background) l(- 4%))",
    "fg-light": "color(var(bg-light) l(- 72%))",
    "fg-hover-light": "color(var(fg-light) l(- 12%))"

    "bg-dark": "color(var(--background) l(+ 8%))",
    "fg-dark": "color(var(bg-dark) l(+ 60%))",
    "fg-hover-dark": "color(var(fg-dark) l(+ 20%))",

    "bg-medium": "color(var(--background) s(* 50%))",
    "fg-medium": "color(var(bg-medium) l(* 20%))"
    "fg-hover-medium": "color(var(fg-medium) l(- 6%))"
  }
  "rules": [
    {
      "class": "label_control",
      "parents": [{"class": "button_control"}],
      "color": "var(fg)"
    },
    {
      "class": "label_control",
      "parents": [{"class": "window", "attributes": ["file_light"]},
                        {"class": "button_control"}],
      "color": "var(fg-light)"
    },
    {
      "class": "label_control",
      "parents": [{"class": "window", "attributes": ["file_medium"]},
                        {"class": "button_control"}],
      "color": "var(fg-medium)"
    },
    {
      "class": "label_control",
      "parents": [{"class": "window", "attributes": ["file_dark"]},
                        {"class": "button_control"}],
      "color": "var(fg-dark)"
    },
    {
      "class": "label_control",
      "parents": [{"class": "button_control", "attributes": ["hover"]}],
      "color": "var(fg-hover)"
    },
    {
      "class": "label_control",
      "parents": [{"class": "window", "attributes": ["file_light"]},
                        {"class": "button_control", "attributes": ["hover"]}],
      "color": "var(fg-hover-light)"
    },
    {
      "class": "label_control",
      "parents": [{"class": "window", "attributes": ["file_light"]},
                        {"class": "button_control", "attributes": ["hover"]}],
      "color": "var(fg-hover-medium)"
    },
    {
      "class": "label_control",
      "parents": [{"class": "window", "attributes": ["file_light"]},
                        {"class": "button_control", "attributes": ["hover"]}],
      "color": "var(fg-hover-dark)"
    },
  ]
}

Now without considering the file_medium attribute and few elements (radio buttons and checkboxes) the Theme I'm developing is already at 3000+ lines.
Most of the repetition is due to the inability to conditionally set a variable's value at declaration time (the variables section). One needs instead to create a different variables for every luminosity attribute.

Preferred solution

Add a way to calculate variables depending on the global color scheme's luminosity.
The previous example becomes:

{
  "variables": {
    "bg": "var(--background)",
    "fg": "color(var(bg) l(+ 60%))",
    "fg-hover": "color(var(fg) l(+ 20%))",

    "!file_light": {
      "bg": "color(var(--background) l(- 4%))",
      "fg": "color(var(bg) l(- 72%))",
      "fg-hover": "color(var(fg) l(- 12%))"
    },

    "!file_dark": {
      "bg": "color(var(--background) l(+ 8%))",
      "fg": "color(var(bg) l(+ 60%))",
      "fg-hover": "color(var(fg) l(+ 20%))",
    },

    "!file_medium": {
      "bg": "color(var(--background) s(* 50%))",
      "fg": "color(var(bg) l(* 20%))"
      "fg-hover": "color(var(fg) l(- 6%))"
    }
  }
  "rules": [
    {
      "class": "label_control",
      "parents": [{"class": "button_control"}],
      "color": "var(fg)"
    },
    {
      "class": "label_control",
      "parents": [{"class": "button_control", "attributes": ["hover"]}],
      "color": "var(fg-hover)"
    },
  ]
}

I believe this will cut down significantly from the number of rules in a theme, and may improve drawing performance (maybe, I'm not sure).
it's backwards compatible and shouldn't introduce breakage (unless the theme author uses !file_* as variable names which is unlikely).
This should allow themes to be more accurate implementing all four luminosity versions for every relevant rule, for otherwise the theme dev would often drop some of the rules (usually file_medium).

Alternatives

?

Additional Information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions