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

[theming] Access theme's colors programmatically #32813

Open
fabiospampinato opened this issue Aug 19, 2017 · 70 comments
Open

[theming] Access theme's colors programmatically #32813

fabiospampinato opened this issue Aug 19, 2017 · 70 comments
Assignees
Labels
api-proposal feature-request themes
Milestone

Comments

@fabiospampinato
Copy link
Contributor

@fabiospampinato fabiospampinato commented Aug 19, 2017

I think we should add support for accessing theme's colors programmatically.

For instance let's take as an example the popular OneDark Pro theme, I'd like to access colors defined under tokenColors.

My use case: I'm making an extension that decorates some tokens, and I'd like them to have the same color that comments have in my theme, the problem is that the regex I use to find those tokens depends on some configurable value, so I cannot pre-compute it in advance and just put it in a .tmLanguage file.

It's already possible to somehow access colors defined under the colors key, via something like new vscode.ThemeColor ( 'activityBar.background' ), adding support for this sounds like a useful generalization to me.

What do you think?

@vscodebot vscodebot bot added the workbench label Aug 19, 2017
@aeschli
Copy link
Contributor

@aeschli aeschli commented Aug 21, 2017

I'd rather avoid API that gives out the actual color, but hope that all can be done with color references. That way extensions don't need to worry about listening to theme changes. Yes, sounds like a useful idea but is not an easy addition as token colors are based on text mate theme rules and the text mate scope hierarchy.
If there are more requests, we can certainly look at it. Until then I recommend you to use one of the regular workbench colors, or - added to 1.16 - define a new color in your extension.

@aeschli aeschli self-assigned this Aug 21, 2017
@aeschli aeschli added themes feature-request labels Aug 21, 2017
@aeschli aeschli added this to the Backlog milestone Aug 21, 2017
@aeschli aeschli changed the title Access theme's colors programmatically [themeing] Access theme's colors programmatically Aug 21, 2017
@aeschli aeschli changed the title [themeing] Access theme's colors programmatically [theming] Access theme's colors programmatically Sep 15, 2017
@bpasero bpasero removed the workbench label Nov 16, 2017
@eamodio
Copy link
Contributor

@eamodio eamodio commented Mar 1, 2018

@aeschli while I still think an API for this would be valuable (or at the least an API that tells you if the current theme is light or dark), another alternative that might work in certain scenarios would be to expose the set of theme colors as css variables. This would allow the scenario here: #34411 (comment)

In theory I could use an SVG image, with colors pulled from the css variables, allowing me to get theme adaptable icons into the hovers.

Thoughts?

FYI, this is similar to this request #41785, but not just for the webview, for the editor itself.

@aeschli
Copy link
Contributor

@aeschli aeschli commented Mar 2, 2018

@eamodio Great idea. If using css variables in SVG images works then we should definitely do this. Let's track this in a separate issue!

@DanTup
Copy link
Contributor

@DanTup DanTup commented Apr 3, 2018

#46940 was closed as a dupe of this, but I'm not sure it's the same request. I have remotely-hosted SVGs I want to include in my markdown tooltips. I need to decide between the black and white versions so need to know whether VS Code considers the current theme light or dark. I don't need access to colours and I cannot modify the SVG.

@eamodio
Copy link
Contributor

@eamodio eamodio commented Jun 20, 2018

This issue has come up again. In GitLens, I would like to expose 2 colors (hot and cold versions) for the heatmap that GitLens generates, but I am unable to use theme colors, because I need access to the real color values to generate the full palette of colors required.

@vviikk
Copy link

@vviikk vviikk commented Jun 26, 2018

A lot of extensions would benefit from this. Bracket colorizer, jumpy, gitlens and a zillion others. Would be good to implement this.

@aeschli
Copy link
Contributor

@aeschli aeschli commented Jun 26, 2018

@piggyslasher Please explain how/where these extension could profit from this.

There is already a story that extensions can declare a new color (by id) and use it in decorations. Users can redefine these colors in themes.

@fabiospampinato
Copy link
Contributor Author

@fabiospampinato fabiospampinato commented Jun 26, 2018

My use case: I'm making an extension that decorates some tokens, and I'd like them to have the same color that comments have in my theme, the problem is that the regex I use to find those tokens depends on some configurable value, so I cannot pre-compute it in advance and just put it in a .tmLanguage file

@aeschli that's my use case. Sure, I'm already exporting these colors via the settings and users can override them already. But I can't just pick the colors for them automatically depending on what theme they are currently using. Also if someone uses one of those extensions for rotating themes I can't just expect them to update their settings every time.

@vviikk
Copy link

@vviikk vviikk commented Aug 17, 2018

@aeschli A use case in my scenario is I use the extension called "Bracket pair colorizer" with adds colors to matching brackets, like so:
image
Now, in order for the extension to render the brackets to match my theme, I have to hard code the colors into my settings:

image

Without this, I would end up with something that looks like this out of the box:
image

Notice the color of the brackets. They're from the extension's default preferences because the developer can't access the colors. I hope I'm on the right track.

@aeschli
Copy link
Contributor

@aeschli aeschli commented Aug 20, 2018

@piggyslasher Did you see that you can define new colors in the extension's package.json?

"contributes": {
  "colors": [{
      "id": "bracketPairColorizer.bracket1",
      "description": "Color for the outermost bracket",
      "defaults": {
          "dark": "#112233",
          "light": "#ddeeff",
          "highContrast": "foreground"
      }
  }]
}

Users can then customize the color in the workspace.colorCustomization setting and even themes can add a default color.

Color default values can be defined for light, dark and high contrast theme and can either be a reference to an existing color or a color hex value.

@tamuratak
Copy link
Contributor

@tamuratak tamuratak commented Oct 13, 2018

Hi,
I am working on a PR for LaTeX-Workshop, a VSCode extension for LaTeX editing. In the PR, I make a latex preview in hover available rendering math equations in SVG format with MathJax and embedding the dataurl of generated SVG into a markdown text as an image source.

When rendering math equations, I have to tell MathJax which color to use for each rendering. Otherwise rendered equations are invisible on a certain theme. To work around the lack of color API in VSCode, I have to render equations in a WebView process, not in an extension process because we can know colors form css variables in the WebView process, as suggested by @eamodio. So when LaTeX-Workshop users close a WebView pane, my PR does not work. For LaTeX-Workshop users, opening a WebView pane as a pdf viewer is a usual thing. So the lack of color api seems to be a minor thing.

However, the same can be said for other documents having TeX-like equations. Docstring in python, for example. Let's think about API documents with math equations written in docstring. Python libraries should have tons of such API documents. If we want to render equations in them with MathJax, and to display them with API documents in hover, the same problem happens. And, for python programmers while coding, opening a WebView pane is an unusual thing.

Please notice that, for this purpose, extensions don't have to listen to theme changes. Equations are dynamically rendered each time. MathJax is enough fast to do that.

Regards,

On a light theme.

oct-13-2018 10-46-17

On a dark theme.

oct-13-2018 10-48-16

@AllanOricil
Copy link

@AllanOricil AllanOricil commented Mar 13, 2021

I created a solution/hack for grabbing the theme colors.

Create a webview with this html

<script>
  const vscode = acquireVsCodeApi();
  vscode.postMessage(Object.values(document.getElementsByTagName('html')[0].style).map(
    (rv) => {
      return {
        [rv]: document
          .getElementsByTagName('html')[0]
          .style.getPropertyValue(rv),
      }
    }
  ));
</script>

Then listen to theme changes to spawn that webview every time the user changes his theme. The webview is automatically closed after posting a message with all the theme colors.

vscode.window.onDidChangeActiveColorTheme( () => {
  //create an empty webview
  myEmptyWebview.onDidReceiveMessage((colors)=>{
    //do something with the css root colors
    webviewpanel.dispose();//dispose this webview as we are not using it.
  })
})

this is the colors array

image

@AllanOricil
Copy link

@AllanOricil AllanOricil commented Mar 13, 2021

I would like to get access to these css variables that are added to the Webview. Is there anybody who could point me out where the css variables are injected to the webview?

@sunnypav
Copy link

@sunnypav sunnypav commented Jul 1, 2021

This is really useful enhancement for us. We are building a Language server for our Programming language where in the server returns the tokens in standard format. There are themes which provide coloring information for the tokens and some dont. We wanted to access the current theme information through VSCode API and apply coloring for those tokens using the same. If no information found in the theme we would like to apply our own syntax coloring based on the kind of theme (Dark/Light/High Contrast).

But it is disappointing to see this enhancement still open despite many number of votes and many requests. May be i am missing something.

@aeschli
Copy link
Contributor

@aeschli aeschli commented Jul 1, 2021

@sunnypav Have you looked at the semantic highlighting API? This allows you to return tokens with a semantic token type, and we do all the coloring based on the current theme.

We don't want to surface TextMate scopes in our API, that's why this an API that returns all syntax colors is not on the radar.
We can give out some base colors ('comments', 'strings'...) or maybe colors for semantic tokens

@Oblongmana
Copy link

@Oblongmana Oblongmana commented Jul 11, 2021

Any chance we could grab the current theme name in this event? So far as I can tell, there's no way to grab it that's actually synced with onDidChangeActiveColorTheme.

We can get the workbench color theme Name from vscode.workspace.getConfiguration().get("workbench.colorTheme"); - but that lags behind the onDidChangeActiveColorTheme - it doesn't update when the user is looking at different themes in the Quick Pick, and only changes if the user "locks in" the setting.

@aeschli
Copy link
Contributor

@aeschli aeschli commented Jul 12, 2021

@Oblongmana What would you do with the theme name?

@pokey
Copy link

@pokey pokey commented Sep 2, 2021

Just to chime in here, our main use case is to be able to access theme colors from within svg's specified in a contentIconPath. I think there are two issues that would need to be solved here somehow:

  • The css variables mentioned in the docs would need to be enabled in the main editor, not just in a webview
  • Even if they were accessible, svg's specified by a uri in the content of a css :after can't access css variables, so we'd need some fix there. Looks like maybe using mask could work?

@banacorn
Copy link

@banacorn banacorn commented Sep 10, 2021

@aeschli I don't think the semantic highlighting API is mature enough yet. For example, DocumentSemanticTokensProvider would keep asking for new tokens even though not much has happened to the file, and if you refuse to provide new tokens, all previous highlighting would be removed (wtf?). And it's almost impossible to calculate the diff and devise new tokens (see #115038).

JUST GIVE US THOSE COLORS!!!

@slhsxcmy
Copy link

@slhsxcmy slhsxcmy commented Oct 4, 2021

@AllanOricil does the webview workaround still work? It seems style properties have empty properties on my test host

@AllanOricil
Copy link

@AllanOricil AllanOricil commented Oct 4, 2021

@AllanOricil does the webview workaround still work? It seems style properties have empty properties on my test host

Well, I hope it still works, because there is no other way to do it. I will test it again and share the results with you later

@AllanOricil
Copy link

@AllanOricil AllanOricil commented Oct 4, 2021

My extension is still working. Maybe you are using that new webview approach which spawns inside an iframe?

@slhsxcmy
Copy link

@slhsxcmy slhsxcmy commented Oct 5, 2021

My extension is still working. Maybe you are using that new webview approach which spawns inside an iframe?

Maybe :) I'm new to webview so I'll look into that more. Do you have an example of your extension using the webview approach? Thanks!

@AllanOricil
Copy link

@AllanOricil AllanOricil commented Oct 5, 2021

My extension is still working. Maybe you are using that new webview approach which spawns inside an iframe?

Maybe :) I'm new to webview so I'll look into that more. Do you have an example of your extension using the webview approach? Thanks!

You can study what I did to get the colors in this link

@memeplex
Copy link

@memeplex memeplex commented Oct 27, 2021

Please correct me if I'm wrong, but this thread is focusing in the problem from an extension developer perspective, now isn't it the same for the end user? AFAIK in editor.tokenColorCustomizations there is no way to say something like "the current fg color for keyworks" or any of the colors defined in https://code.visualstudio.com/api/references/theme-color. It was mentioned above a number of times that an extension developer can define colors that then the user may customize, but the user can't customize even base colors without hardcoding them in a way that's not relative to the current theme (which may and often changes during a session). Some months ago the ability to define customizations for several themes at once (including a new wildcard syntax) was added, but the underlying problem of not being able to reference theme attributes (mostly but not only colors) by symbolic names still makes it very hard to maintain customizations beyond two or three themes.

@aeschli
Copy link
Contributor

@aeschli aeschli commented Oct 27, 2021

Users can customize editor token colors, workspace colors, including colors contributed by extension. It can be done for all themes, per theme or now also using wildcards. See https://code.visualstudio.com/docs/getstarted/themes#_customizing-a-color-theme
There's no syntax for deriving colors or use variables
@memeplex Please file a separate issue if that doesn't work or you have a feature request on customizing colors in user settings.

@AllanOricil
Copy link

@AllanOricil AllanOricil commented Oct 27, 2021

@memeplex depending on the problem, there are some ways to support multiple themes. My extension, for example, has a Monaco Editor where the User can type some SQL. The Token Colors (colors for each SQL word the user types in) are hardcoded based on Light and Dark themes. To determine if a Theme is Dark or Light, I get the background color for the current theme, calculate its Hue value, then depending on the result I switch the Token Colors. Of course the ideal scenario would be to get the Token Colors for the current theme, but since this is not available, this solution "kind" works. I tested with lots of themes and it looks acceptable.
I could also let the user manually customize the Token Colors applied to Monaco, but this would bring a lot of overhead to the code, which is not really necessary. Hopefully one day vscode team will give us these tokens :D
OBS: To get the background color of the current theme, I'm using the approach I mentioned above.

@AllanOricil
Copy link

@AllanOricil AllanOricil commented Oct 27, 2021

Does anybody know where the Token Colors are saved on the User computer? Im thought about another hack that might work

@znorman-harris
Copy link

@znorman-harris znorman-harris commented May 23, 2022

Any thoughts or updates about being able to access this information for extension developers?

Edit: This is the API I'm looking for but not seeing (getColor that is): #32813 (comment)

For my use case, I'm interested in getting access to the theme colors in order to adjust content that I'm writing to the debug console. I want to be able to match/replicate some of the debug colors (i.e. debugConsole.infoForeground) that there's currently no way to access.

I feel like I'm going to have to borrow from the hacky method mentioned above using a webview in order to get these, but that seems clunky and not a great user-experience having a webview panel open every time you open VSCode.

@AllanOricil
Copy link

@AllanOricil AllanOricil commented May 23, 2022

@znorman-harris that hack is horrible, but it was the only way I found. I forgot to mention that on Windows machines it takes a lot more time to retrieve colors. Users can see the webview opening and closing :/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-proposal feature-request themes
Projects
None yet
Development

No branches or pull requests