microsoft / VSExtensibility

A repo for upcoming changes to extensibility in Visual Studio, the new extensibility model, and language server protocol.
MIT License
367 stars 46 forks source link

How to get current Microsoft.VisualStudio.Package.ExpansionProvider class instance? #206

Open cfognom opened 1 year ago

cfognom commented 1 year ago

I'm making an extension to automatically insert snippets from the completion list without the need of double tapping tab. I can already intercept when a completion item is committed and inserted into the document with IAsyncCompletionCommitManager.TryCommit() (https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.language.intellisense.asynccompletion.iasynccompletioncommitmanager?view=visualstudiosdk-2022). There I get the snippet shortcut. Now I'm just missing a way to insert the snippet from its shortcut.

I discovered the ExpansionProvider class (https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.package.expansionprovider?view=visualstudiosdk-2022) which seem to have the methods I need: FindExpansionByShortcut() and InsertNamedExpansion(). Problem is; I don't know how to get the currently active ExpansionProvider. All examples suggest to inherit it, but then I don't get the current one.

How can I get the currently active ExpansionProvider class? Or alternatively the currently active LanguageService/Source class, and then I can use GetSource() and/or GetExpansionProvider() on that.

I'm new to using the VS SDK so any help is appreciated.

olegtk commented 1 year ago

@cfognom, please check this doc, it shows how to expand a snippet by shortcut: https://learn.microsoft.com/en-us/visualstudio/extensibility/walkthrough-implementing-code-snippets?view=vs-2022&tabs=csharp#implement-snippet-expansion-in-the-snippet-picker-ui

You can also look at how Roslyn does it: https://github.com/dotnet/roslyn/blob/ee6e99b318218d61f4ab7d7a219877fa2aaff4c0/src/VisualStudio/Core/Def/Snippets/AbstractSnippetCommandHandler.cs#L302

Unfortunately it's a very old API... We are working on a new, much simpler Visual Studio code snippets API, but nothing is available yet.

cfognom commented 1 year ago

please check this doc, it shows how to expand a snippet by shortcut: https://learn.microsoft.com/en-us/visualstudio/extensibility/walkthrough-implementing-code-snippets?view=vs-2022&tabs=csharp#implement-snippet-expansion-in-the-snippet-picker-ui

I tried to use InsertExpansion(TextSpan, TextSpan, IVsExpansionClient, Guid, IVsExpansionSession) before, but I need to supply an IVsExpansionClient and an IVsExpansionSession. The docs say I can pass null for the IVsExpansionClient but I get a null reference exception when I do, so I think the docs are wrong. Unfortunately I don't see a way to pass the IVsExpansionClient and IVsExpansionSession to the "currently active handlers" in any way. I would have to supply my own implementations, which I don't want.

You can also look at how Roslyn does it: https://github.com/dotnet/roslyn/blob/ee6e99b318218d61f4ab7d7a219877fa2aaff4c0/src/VisualStudio/Core/Def/Snippets/AbstractSnippetCommandHandler.cs#L302

From my quick glance at how Roslyn does it, It seems to use the same interfaces as previously mentioned.

In conclusion, I can not see a way where I can request from the "currently active snippet handler/manager/client" to insert a snippet. Hopefully the new API will have such a feature.