microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
163.76k stars 29.1k forks source link

[json] colorize string literals based on language information coming from schemas #224581

Open voxpelli opened 2 months ago

voxpelli commented 2 months ago

The built in json-language-features extension provides plenty of nice features for JSON Schemas, such as markdownDescription and defaultSnippets.

I would love for it to also enable indicating that the value of a property is an embedded language.

Specifically I would love for the built in npm extension to be able to indicate that values within the "scripts" property of package.json files are shellscript values.

Would make it easier to interpret and author complex npm-scripts setup such as this:

Skärmavbild 2024-08-02 kl  14 19 11

Implementation brainstorming

The current schema that the npm extension uses is json.schemastore.org/package:

https://github.com/microsoft/vscode/blob/444d7a4b35745ed7733c700a8008f55cd659eb1d/extensions/npm/package.json#L314-L318

It actually already contains something similar that's aimed at IntelliJ – "x-intellij-language-injection": "Shell Script", which IntelliJ added in https://github.com/JetBrains/intellij-community/commit/2e490cee9ea05967ebaa5084ae42fe58ffc5800a

Here's how it looks in the package.json schema:

"scriptsInstallAfter": {
  "description": "Run AFTER the package is installed.",
  "type": "string",
  "x-intellij-language-injection": "Shell Script"
},

Maybe something similar, such as "x-vscode-language-injection": "shellscript" could work? Or, considering that Shell Script is an alias of shellscript, consume x-intellij-language-injection wherever it is available?

Related discussions

Mostly stumbled upon people requesting this for yaml:

voxpelli commented 2 months ago

Here's the PR that added the "x-vscode-language-injection": "shellscript" to the package.json JSON Schema: https://github.com/SchemaStore/schemastore/pull/2195

hyperupcall commented 2 months ago

This would be a great addition! As someone that co-maintains SchemaStore, I lean towards the shared use of the x-intellij-language-injection property, assuming languages have aliases that generally include the Intellij ids. Otherwise, all schemas that have properties of x-intellij-language-injection will also need to add an extra x-vscode-language-injection, and we'd have to check to ensure the values are in sync.

aeschli commented 2 months ago

Annotating the schema is only a first, small step, the challenge is how to do the coloring.

Syntax highlighting happens on the renderer, through TextMate grammars and grammar injections. It has no access to the JSON schema which is loaded and evaluated from the JSON language extension, running in a process on the extension host. We don't have a way to dynamically inject rules on runtime.

What could be done is to use semantic highlighting, in the JSON language extension, but that would mean implementing a parser for shell script.

Help is welcome...

vs-code-engineering[bot] commented 2 months ago

This feature request is now a candidate for our backlog. The community has 60 days to upvote the issue. If it receives 20 upvotes we will move it to our backlog. If not, we will close it. To learn more about how we handle feature requests, please see our documentation.

Happy Coding!

voxpelli commented 2 months ago

@aeschli I'm thinking it would work similarly to how CSS and JS can be embedded in HTML, is that a lot different?

aeschli commented 2 months ago

With HTML, the HTML grammar includes the CSS and TypeScript grammars. when ever it sees <style> is starts using the rules for CSS.

The difference is that the coloring that you want is only for certain files and properties and only at runtime (once we have loaded and evaluated the schema) we know which ones. We have no mechanism to redefine/customize grammars at runtime. We can do this with semantic highlighting, which goes on top of syntax highlighting.

vs-code-engineering[bot] commented 2 months ago

:slightly_smiling_face: This feature request received a sufficient number of community upvotes and we moved it to our backlog. To learn more about how we handle feature requests, please see our documentation.

Happy Coding!

RedCMD commented 2 months ago

I could make an extension to do this but does the JSON language extension provide any api for other extensions to use? location of strings/objects and the current schema in use it would nice to not have to re-compute the entire schema and JSON document

I could then provide semantic syntax highlighting using TextMate or tree-sitter

I don't see how it could be possible to provide a JSON TextMate grammar to do it perfectly (built-in TextMate syntax highlighting) as its impossible for TextMate to lookahead multiple lines (which could be required by some schemas) however, it would allow for extra language features like bracket highlighting etc

aeschli commented 2 months ago

@RedCMD No the JSON language extension does not have such an API. It's unclear to me how such an API would look like. Also I'd rather avoid dependencies between extensions. Maintaining APIs is a lot of work.

I would recommend not to worry about schema support first, but just look at e.g. syntax highlighting in package.json script tags. Its already challenging enough.

RedCMD commented 2 months ago

I've created up a mock extension https://marketplace.visualstudio.com/items?itemName=RedCMD.json-embedded-languages Simply just a TextMate injection to target a root level "scripts" object

image