Skip to content

Support for nested/tagged languages #1912

Open

Description

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

Metadata

Assignees

No one assigned

    Labels

    enhancementAccepted suggestions that makes existing features better

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions