Open
Description
openedon Aug 21, 2023
Feature Proposal
I've been thinking a bit about how to support tagged languages (like the html, sql, etc that we've seen people do with format strings) from FSAC itself (so that Ionide could handle them without needing a bunch of location-specific code). Here's the broad strokes that I've come up with:
- FSAC learns a new API (
fsharp/textDocument/nestedLanguageRanges
?) that reports an array of 'nested documents' for any given VersionedTextDocument with a return type something like:{| TextDocument: VersionedTextDocumentIdentifer; NestedLanguages: {| language: string; range: LspRange |}[] |}
- meaning - FSAC does some magic to inspect the symbols in a file and returns all of the locations for syntax-specific highlighting in that file
- Ionide (or any client that wants to support this) keeps client-side state to track this data in the node layer, associating each nested document with a 'virtual document' with a custom language identifier that Ionide registers for
- For ease of location/position translation, the content of this document would be the same as the content if the 'parent document', but all locations except the location specified in the language-specific range would be replaced by whitespace. This keeps Ionide or other clients from having to map FSAC-sent positions to inside-the-sublanguage positions
- Ionide (or any client that wants to support this) provides a 'content provider' for these virtual documents. This content provider would be the 'hook' that would detect if a function was being called on a subdocument and forward to the language-specific VSCode functionality for that provider.
- initially we would only support highlighting, but for each piece of functionality we do support (e.g. completions, go to def, etc) we'd:
- add a middleware for that function that checks if the invocation location was inside the range of any nested documents in the given TextDocument
- if yes, forward the request to vscode, but for the the appropriate virtual document URI. this will effectively delegate to whatever extensions are already applied to this language
- initially we would only support highlighting, but for each piece of functionality we do support (e.g. completions, go to def, etc) we'd:
Language Discovery
How should FSAC determine the language for an nested document? Probably a number of approaches:
- if the string is a parameter to a member, we can check if the member has the
StringSyntaxAttribute
and use the language from that attribute- this is great because it makes us data-driven and automatically enables support as more framework methods start adding this
- perhaps a few well-known function names for the popular libraries today?
sql
,html
, etc?
Considerations
The downside to this is that this 'mapping' approach would require each editor to implement state/forwarding independently. but I think that's preferable to having to embed language-specific knowledge into FSAC (which is the other approach they recommend) in the docs: https://code.visualstudio.com/api/language-extensions/embedded-languages#request-forwarding-sample
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment