How do I create a custom Semantic Token for VSCode? - visual-studio-code

I'm creating a color theme and I found out that the only way to target function parameters with italic is by using semantic highlight. The problem is that since semantic highlight overrides some settings, I lost the ability to target support.function.console - the "log" of console.log, for instance.
.log is a member.defaultLibrary, but if I target that by semantic, some other things would also be styled with the same color. That wouldn't be bad if member.defaultLibrary wasn't so inconsistent, some things you would expect to be styled, is not, which leads to inconsistency, which is certainly not desirable.
querySelector() is styled by member.defaultLibrary but not querySelectorAll(), for instance. I also tried to not use anything that can be overridden by semantics but then, it creates too many exceptions and some functions and methods would be let without any style, which is much worse.
I've tried Semantic Token Classification and tried to add a custom semantic token to the package.json file of the extension but I don't know how to "wire" that up:
{
"contributes": {
"semanticTokenTypes": [
{
"id": "consoleSupport",
"description": "console support"
}
],
"semanticTokenScopes": [
{
"scopes": {
"consoleSupport": ["support.function.console"]
}
}
]
}
}
When using development host, it does recognize the "new" consoleSupport when I try to add to "semanticTokenColors", it suggests the auto-complete, so I'm probably half-way there but I don't know how to actually create the new token and how to make it work.

Related

Enable users of github program to configure their own DCMake prefix path

Consider a situation where people work together on the same code base; c++ with cmake. Code base depends on a library, that must be installed separately.
Each user may have the library in a different location. A user may invoke cmake like this:
cmake -DCMAKE_PREFIX_PATH=/path/for/that/user .
However, this is not very easy in all circumstances (e.g. windows and visual studio), and requires retyping. So instead, we have
list(APPEND CMAKE_PREFIX_PATH "/path/for/user")
In the CMakeLists.txt. This works, but requires people to constantly change that path after pulling a branch, which is annoying and easily forgotten. Is it possible to configure in a way that pulling new branches does not override this path, once set on a specific machine?
You can have each of your users create their own CMakeUserPresets.json file, and set it in the cacheVariables field of a configurePresets entry.
// CmakeUserPresets.json
{
"version": , // pick one
"cmakeMinimumRequired": {
"major": , // pick one
"minor": , // pick one
"patch": // pick one
},
"configurePresets": [
{
"name": "starball",
"displayName": "Starball's config",
"description": "Starball's private configuration preset",
"generator": "...",
"binaryDir": "...",
"cacheVariables": {
"CMAKE_PREFIX_PATH": "..."
},
"environment": {}
}
],
// ...
}
Make sure to put CMakeUserPresets.json in your .gitignore file (or whatever else you have to do for your specific VCS so that the user preset file isn't tracked in the VCS).

VS Code extension: setting custom semantic token colors

Is it possible to modify the styling of semantic token modifiers received from LSP
inside an extension without the need to create custom themes?
I am able to use editor.semanticTokenColorCustomizations in my settings.json file and add the custom rules I want, but this setting is not available for configurationDefaults in the package.json file for a VS Code extension.
So the following snippet does work in settings.json, while the same does not work in package.json for an extension under the configurationDefaults field.
"editor.semanticTokenColorCustomizations": {
"enabled": true,
"rules": {
"*.declaration": {
"bold": true
},
"*.definition": {
"italic": true
},
"*.readonly": "#ff0000"
}
}
Is there another way?
Ideally, I would like to change both token types and token modifiers
for the language I introduce with the extension, but I don't want to create custom themes a user would need to use to get proper highlighting.
Note: I am forced to stick with the token types and modifiers supported by the language-client provided by Microsoft. Those are defined in the LSP specification.
Edit: I use LSP with semantic tokens to get the token types and modifiers of a file. This should be similar to using TextMate grammar.
The problem I have, is applying correct styling/highlighting to those tokens. Since the language client limits the usable tokens, I apply a mapping between tokens of my language and the default LSP ones.
Meaning: token modifier declaration is in fact bold in my markup language
You can introduce all your custom semantic tokens without the need to restrict yourself to the built-in ones. Personally I prefer the way proposed in the official sample file:
semantic-tokens-sample.
As for the styling, you can easily modify an extension incl. semantic token colors via the package.json file as follows.
{
...
"editor.semanticHighlighting.enabled": true, // not necessary, just make sure it is not disabled
"contributes": {
"semanticTokenTypes": [ // not necessary if you use own parsing with "DocumentSemanticTokensProvider"
{
"id": "myToken",
"superType": "myToken",
"description": "myToken"
}
],
"configurationDefaults": {
"editor.semanticTokenColorCustomizations": {
"rules": {
"comment": "#969896",
"string": "#B5BD68",
"myToken": "#323232" // custom
}
}
}
}
}
For that I personally introduced myToken in the legend in an extension.ts file.
To check if your semantic token logic is working, you can use the
[view/Command Palette/>Developer: Inspect Editor Tokens ans Scopes] functionality that will reveal what semantic scope is attached to your keyword, if any.
If the provided code is not working for you, check your package.json and make sure the language settings are all correct:
settings that could be of relevance for you:
{
...
"activationEvents": ["onLanguage:myLanguage"], // make sure your extension is activated
"contributes": {"languages": [{"id": "myLanguage", "extensions": [".myLang"], "configuration": "./language-configuration.json"}]}
}
Furthermore check if your User / Workspace settings are interfering with your package.json settings.

CSS syntax highlighting in VSCode: #layer keyword support

As you might know some browsers already support CSS Cascade Layers (https://caniuse.com/?search=%40layer). The main keyword of this feature is #layer. Unfortunately VSCode displays a warning message:
Unknown at rule #layer css(unknownAtRules)
Is there any list of css keywords to include #layer keyword in my VSCode settings?
I tried to use the "css.customData" option. But I didn't manage to get any results. I created a css-data.json file in the same folder as the settings.json file.
What the correct path to the file should look like? I would like to have a relative path but I tried an absolute path as well. Nothing happened. I'm using portable VSCode if it is matter. Here are my attempts:
"css.customData": ["c:\\app\\VSCode\\data\\user-data\\User\\css-data.json"],
"css.customData": ["css-data.json"],
"css.customData": [".\\data\\user-data\\User\\css-data.json"],
"css.customData": ["./data/user-data/User/css-data.json"],
Here is a content of css-data.json:
{
"version": 1.0,
"properties": [],
"atDirectives": [
{
"name": "#layer",
"description": "Declares a cascade layer."
}
],
"pseudoClasses": [],
"pseudoElements": []
}
You probably just need to use
"css.customData": [".vs-code/css-data.json"]
but in case that doesn't work; I fixed this for myself in the following way:
in: .vscode/settings.json
"css.customData": [".vscode/css_custom_data.json"]
and then the .vscode/css_custom_data.json file itself:
{
"atDirectives": [
{
"name": "#layer",
"description": "The #layer CSS at-rule is used to declare a cascade layer and can also used to define the order of precedence in case of multiple cascade layers.",
"references": [
{
"name": "#layer",
"url": "https://developer.mozilla.org/en-US/docs/Web/CSS/#layer"
}
]
}
]
}
This however fails to fully permit the use of the #layer spec as #import rules still can't include a layer() as an example:
#layer reset, pallet, base, layout, local;
#import "style/reset.css" layer(reset); /* unifies / css reset */
#import "style/pallet.css" layer(pallet); /* color pallets */
#import "style/main.css" layer(base); /* primary css*/
now throws 3 errors and 0 warnings whereas without this fix it also throws a warning.
#layer and #property will be supported in vscode v1.72 - due out early October, 2022.
See 1.72 Release Notes:
The CSS language support now also understands the #property and
#layer at-rules.
My guess is that this is just a rule that hasn't been updated in the VSCode internal CSS linters.
Hunting for this warning I came across this stylelint issue #6084 ([at-rule-no-unknown] incorrectly flags #layer). They fixed this through a PR in May 2022.
I was assuming that stylelint is the underlying CSS linter for VS Code but appears it isn't. You can install the stylelint vscode extension (and disable the internal VSCode CSS linters) and this #layer error goes away.

Am I understanding this VS Code API behavior correctly? Non-default *object* settings (when provided) are always merged?

I'm working on a VS Code Extension, and I think maybe I'm missing something in the docs, or else the behavior I'm seeing just isn't specified there, and my assumptions are wrong...?
I've defined some default settings for my extension, like so...
package.json
"contributes": {
"configuration": {
"title": "ToggleSettingsChanges",
"properties": {
"toggleSettingsChanges.settingsToToggle": {
"scope": "resource",
"type": "object",
"default": {
"window.zoomLevel": 2,
"editor.fontSize": 22,
"terminal.integrated.fontSize": 16,
"scm.diffDecorations": "none",
"workbench.statusBar.visible": false,
"editor.cursorBlinking": "solid",
"workbench.activityBar.visible": false
},
"description": "[ snip ]"
}
}
}
},
extension.js
// In the "main" method that runs when a command is activated:
const config = vscode.workspace.getConfiguration("toggleSettingsChanges");
const settingsToToggle = config.get("settingsToToggle");
const inspectedSettingsToToggle = config.inspect("settingsToToggle");
console.log("settingsToToggle:", JSON.stringify(settingsToToggle), "\n\n")
console.log("inspected settingsToToggle:", JSON.stringify(inspectedSettingsToToggle), "\n\n")
return;
In the Extension Host instance, I can tweak and adjust the settings, to include this:
User or Workspace Settings JSON
// ...
"toggleSettingsChanges.settingsToToggle": {
"editor.fontSize": 11,
"pumpkins_are_great": true
},
In the console output, I'm seeing the following:
settingsToToggle: {"window.zoomLevel":2,"editor.fontSize":11,"terminal.integrated.fontSize":16,"scm.diffDecorations":"none","workbench.statusBar.visible":false,"editor.cursorBlinking":"solid","workbench.activityBar.visible":false,"pumpkins_are_great":true}
inspected settingsToToggle: {"key":"toggleSettingsChanges.settingsToToggle","defaultValue":{"window.zoomLevel":2,"editor.fontSize":22,"terminal.integrated.fontSize":16,"scm.diffDecorations":"none","workbench.statusBar.visible":false,"editor.cursorBlinking":"solid","workbench.activityBar.visible":false},"globalValue":{"editor.fontSize":11,"pumpkins_are_great":true}}
For the settingsToToggle line, I expected to see only the following settings:
{"editor.fontSize":11,"pumpkins_are_great":true}
It seems that if you provide an object default, any configuration provided is merged with that object, instead of replacing it entirely.
Is that the case? Have I missed this in the documentation?
It seems to me that a value (even an object) would be overwritten, and not simply merged.
The documentation may have been updated since this question was posted. The way it's written now, seems pretty clear to me. I'm writing because I feel I have found a discrepancy in the API, which may help out the OP.
Reference
Note: Only object value types are merged and all other value types are overridden.
-- VS Code API - WorkspaceConfiguration
Additional information
I want my default values to be merged with the user settings, as is described above. I was confused by seeing my defaults overriden. This question helped me understand what is happening. I'll share my approach since OP may be interested. My observations:
Default values provided in package.json are merged with user settings, as described in the documentation (link above).
Default values passed programmatically with WorkspaceConfiguration.get(section, defaultValue) do not exhibit the merging behavior. It's not clear if this is intentional or not. Update: this behavior is working as intended, reference #105598.

Where are the docs on how to add symbol support for a language to Visual Studio Code?

I would like to add symbol support for PowerShell to VS Code but I'm not finding any docs on the code.visualstudio.com/docs site.
Also, is it possible to do this for a language like PowerShell that, for the moment, will only work on Windows? Is there a way to light up symbol support on Windows only?
BTW I've added a bunch of PowerShell snippets that I'm in the process of trying to get integrated into VS Code. Any help on how to get these snippets into the product would be appreciated as well? I did submit an issue on the snippets, suggesting that the team put these into VS Code.
There is currently no documentation for the plugin API. It's too early for this as the API is still changing with every minor release. The VSCode team is focused on providing a stable plugin API. There will be a documentation about it when it's done.
Nevertheless it is already possible to add a new language plugin or extending an exisiting one. Take a look on this short description on how to add declaration support for a new language: Create Custom Language in Visual Studio Code
You could add symbol support in a similar way. What you need is something like an abstract syntax tree builder for powershell scripts and an application or a javascript module that is able to process a JSON request in order to provide the correct symbols. An example request for outline support is this:
{
"seq":442,
"type":"request",
"command":"navbar",
"arguments":
{
"file":"c:/Users/C/Documents/projects/MyProject/MyFile.xxx"
}
}
A response could look like that:
{
"seq":442,
"type":"response",
"command":"navbar",
"request_seq":442,
"success":true,
"body":[
{
"text":"TObjA",
"kind":"class",
"kindModifiers":"",
"spans":[
{
"start":{
"line":10,
"offset":3
},
"end":{
"line":16,
"offset":4
}
}
],
"childItems":[
]
},
{
"text":"DoSomething",
"kind":"method",
"kindModifiers":"",
"spans":[
{
"start":{
"line":20,
"offset":1
},
"end":{
"line":27,
"offset":4
}
}
],
"childItems":[
]
},
]
}
I'm not sure what do you mean with "symbol support". Is it something like "jump to symbol inside the current file" using CTRL+Shift+O? Then you are looking for outlineSupport.
Is it something like "find a symbol in any file" using CTRL+P, #? Then you are looking for navigateTypesSupport.
Copy the needed .js file from the vs.langauage.csharp.o folder to the vs.langauage.powershell folder and register the support in powershellMain.js as it is done in omnisharpMain.js.
If you want to register the new support only on Windows then you can do it like this:
var isWin = /^win/.test(process.platform);
if(isWin)
monaco.Modes.NavigateTypesSupport.register('powershell', new navigateTypesSupport_1.default(ModelService, server));
I hope this helps for the moment. Don't forget to save your changed plugins in a different folder. VSCode often deletes changes in the plugin folders on update.