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

Support for nested/tagged languages #1912

Open
baronfel opened this issue Aug 21, 2023 · 0 comments · May be fixed by #1973
Open

Support for nested/tagged languages #1912

baronfel opened this issue Aug 21, 2023 · 0 comments · May be fixed by #1973
Labels
enhancement Accepted suggestions that makes existing features better

Comments

@baronfel
Copy link
Contributor

baronfel commented 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

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
Labels
enhancement Accepted suggestions that makes existing features better
Development

Successfully merging a pull request may close this issue.

1 participant