Skip to content

Extension API Request: Send Custom Requests To TypeScript Language Service Plugins #43893

Closed

Description

Context

Some advanced VS Code extensions need access to the TypeScript AST or type/symbol information.
This includes advanced code actions that require parameters (e.g. reorder parameters), inline type information rendering or code map extensions.

Technically, such extensions could parse/typecheck TypeScript on their own. However, this is not only redundant work and very slow, but also has issues if the TypeScript version does not match the version the user uses.

Problem

To avoid these problems, the already running TS language service can be made use of by implementing a TS language service plugin.
However, language service plugins can only extend specific functionality, like completion, hover information or diagnostics.
They do not have access to webviews or cursor positions of VS Code.

Vice versa, VS Code extensions have access to webviews and much more, but they can only send completion/hover/diagnostics requests to the TS language service and not interact with wustom TS language service plugins.

It would be very helpful if third party VS Code extension <-> TS language service plugin communication is officially supported.

Workaround

Currently, you can hijack the command executeCompletionItemProvider for a magic position (for example 10^10), JSON serialize your request and use it as triggerCharacter and override the corresponding handler in the typescript language service plugin to handle that custom request (given the magic position matches).
You can send a response back by encoding it as a CompletionList entry.
It works, but is a very hacky approach.

Proposed Solution

Extend the API returned by the TypeScript language features extension (or alternatively provide a new command typescript.invokeCustomCommand with corresponding parameters):

class ApiV0 {
  // ...
  invokeCustomCommand(customCommandId: string, uris: Uri[], payload: /* JSON serializable */ unknown): Promise<unknown> { ... }
}

Extend the LanguageService interface of the TypeScript project:

export interface LanguageService {
  // ...
  handleCustomCommand(customCommandId: string, fileNames: string[], payload: /* JSON serializable */ unknown): Promise<unknown>;
}

Uris are automatically translated to file names.

The default implementation just throws an error. Language service plugins can override this method and handle receiving requests.

Activity

  1. paulshen commented on Apr 29, 2021

    @paulshen

    This feature would unlock a lot of my personal extension ideas (eg semantic code visualization)! I'd love to query the TS service like typescript-language-features does. I've spent a lot of time looking at typescript-language-features and I was going down the rabbit hole of replicating its behavior (spawning another TS server). Didn't think of Henning Dieterichs (@hediet)'s clever hack but it'd be great to have a blessed way of accomplishing this!

  2. swissmanu commented on May 3, 2021

    @swissmanu

    My work-in-progress extension for RxJS debugging would benefit from this a lot. If I would have actual type information at hand without an additional compile, recommending debugging actions to my users for a specific code fragment would become much more reliable.

  3. removed their assignment
    on May 5, 2021
  4. mjbvz commented on May 12, 2021

    @mjbvz
    Contributor

    For the TS side, Sheetal Nandi (@sheetalkamat) mentioned there may already be a way for a plugin to register for a new command if the plugin has access to the session: #43449 (comment)

  5. andrewbranch commented on Sep 1, 2021

    @andrewbranch
    Member

    Fixed by #44291

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    In DiscussionNot yet reached consensusSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions