Hinzufügen einer Language Server-Protokollerweiterung
Das Language Server Protocol (LSP) ist ein gängiges Protokoll in Form von JSON RPC v2.0, das verwendet wird, um Sprachdienstfunktionen für verschiedene Code-Editoren bereitzustellen. Mithilfe des Protokolls können Entwickler einen einzigen Sprachserver schreiben, um Sprachdienstfunktionen wie IntelliSense, Fehlerdiagnosen, das Auffinden sämtlicher Verweise und mehr für verschiedene Code-Editoren bereitzustellen, die das LSP unterstützen. Traditionell können Sprachdienste in Visual Studio mithilfe von TextMate-Grammatikdateien hinzugefügt werden, um grundlegende Funktionen wie Syntaxmarkierung oder durch Schreiben von benutzerdefinierten Sprachdiensten bereitzustellen, die den vollständigen Satz von Visual Studio-Erweiterbarkeits-APIs verwenden, um umfangreichere Daten bereitzustellen. Mit der Visual Studio-Unterstützung für LSP gibt es eine dritte Option.
Um die bestmögliche Benutzererfahrung zu gewährleisten, sollten Sie auch Sprachkonfigurationimplementieren, die die lokale Verarbeitung vieler derselben Vorgänge bereitstellt, und kann daher die Leistung vieler sprachspezifischer Editorvorgänge verbessern, die vom LSP unterstützt werden.
Language Server-Protokoll
In diesem Artikel wird beschrieben, wie Sie eine Visual Studio-Erweiterung erstellen, die einen LSP-basierten Sprachserver verwendet. Es wird davon ausgegangen, dass Sie bereits einen LSP-basierten Sprachserver entwickelt haben und es einfach in Visual Studio integrieren möchten.
Zur Unterstützung in Visual Studio können Sprachserver über einen beliebigen streambasierten Übertragungsmechanismus mit dem Client (Visual Studio) kommunizieren, z. B.:
- Standardeingabe-/Ausgabedatenströme
- Benannte Pipes
- Sockets (nur TCP)
Die Absicht des LSP und dessen Unterstützung in Visual Studio besteht darin, Sprachdienste zu integrieren, die nicht Teil des Visual Studio-Produkts sind. Es ist nicht vorgesehen, vorhandene Sprachdienste (z. B. C#) in Visual Studio zu erweitern. Informationen zum Erweitern vorhandener Sprachen finden Sie im Erweiterbarkeitshandbuch des Sprachdiensts (z. B. die "Roslyn" .NET Compiler Platform) oder lesen Sie Erweitern des Editors und der Sprachdienste.
Weitere Informationen zum Protokoll selbst finden Sie in der Dokumentation hier.
Weitere Informationen zum Erstellen eines Beispielsprachenservers oder zum Integrieren eines vorhandenen Sprachservers in Visual Studio Code finden Sie in der Dokumentation hier.
Unterstützte Features des Language Server-Protokolls
Die folgenden Tabellen zeigen, welche LSP-Features in Visual Studio unterstützt werden:
Nachricht | Hat Unterstützung in Visual Studio |
---|---|
initialisieren | ja |
initialisiert | ja |
shutdown | ja |
exit | ja |
$/cancelRequest | ja |
window/showMessage | ja |
window/showMessageRequest | ja |
window/logMessage | ja |
Telemetrie/Ereignis | |
client/registerCapability | |
client/unregisterCapability | |
workspace/didChangeConfiguration | ja |
workspace/didChangeWatchedFiles | ja |
Arbeitsbereich/Symbol | ja |
workspace/executeCommand | ja |
workspace/applyEdit | ja |
textDocument/publishDiagnostics | ja |
textDocument/didOpen | ja |
textDocument/didChange | ja |
textDocument/willSave | |
textDocument/willSaveWaitUntil | |
textDocument/didSave | ja |
textDocument/didClose | ja |
textDocument/completion | ja |
completion/resolve | ja |
textDocument/hover | ja |
textDocument/signatureHelp | ja |
textDocument/references | ja |
textDocument/documentHighlight | ja |
textDocument/documentSymbol | ja |
textDocument/formatting | ja |
textDocument/rangeFormatting | ja |
textDocument/onTypeFormatting | |
textDocument/definition | ja |
textDocument/codeAction | ja |
textDocument/codeLens | |
codeLens/resolve | |
Textdokument/Dokumentverknüpfung | |
documentLink/resolve | |
textDocument/umbenennen | ja |
Loslegen
Anmerkung
Ab Visual Studio 2017, Version 15.8, ist die Unterstützung für das common Language Server Protocol in Visual Studio integriert. Wenn Sie LSP-Erweiterungen mithilfe der Vorschau-Language Server Client VSIX Version erstellt haben, funktionieren sie nicht mehr, sobald Sie ein Upgrade auf Version 15.8 oder höher durchführen. Sie müssen die folgenden Schritte ausführen, damit Ihre LSP-Erweiterungen wieder funktionieren:
Deinstallieren Sie die Microsoft Visual Studio Language Server Protocol Preview VSIX.
Ab Version 15.8 wird jedes Mal, wenn Sie ein Upgrade in Visual Studio durchführen, automatisch die VsIX-Vorschau erkannt und entfernt.
Aktualisieren Sie Ihre NuGet-Referenz auf die neueste Nicht-Vorschau-Version für die LSP-Pakete .
Entfernen Sie die Abhängigkeit von microsoft Visual Studio Language Server Protocol Preview VSIX in Ihrem VSIX-Manifest.
Stellen Sie sicher, dass Ihr VSIX Visual Studio 2017, Version 15.8 Preview 3, als untere Grenze für das Installationsziel angibt.
Erstellen und erneut bereitstellen
Erstellen eines VSIX-Projekts
Um eine Sprachdiensterweiterung mit einem LSP-basierten Sprachserver zu erstellen, stellen Sie zunächst sicher, dass die Visual Studio-Erweiterungsentwicklung Workload für Ihre Instanz von VS installiert ist.
Erstellen Sie als Nächstes ein neues VSIX-Projekt, indem Sie zu Datei>Neues Projekt>Visual C#>Erweiterbarkeit>VSIX-Projektnavigieren:
Sprachserver- und Laufzeitinstallation
Standardmäßig enthalten die Erweiterungen, die zur Unterstützung von LSP-basierten Sprachservern in Visual Studio erstellt wurden, nicht die Sprachserver selbst oder die Laufzeiten, die zum Ausführen erforderlich sind. Erweiterungsentwickler sind für die Verteilung der Sprachserver und der benötigten Laufzeiten verantwortlich. Es gibt mehrere Möglichkeiten, dies zu tun:
- Sprachserver können in VSIX als Inhaltsdateien eingebettet werden.
- Erstellen Sie eine MSI-Datei, um den Sprachserver und/oder die erforderlichen Laufzeiten zu installieren.
- Geben Sie auf dem Marketplace Anweisungen, um die Benutzer darüber zu informieren, wie sie Laufzeiten und Sprachserver erhalten können.
TextMate-Grammatikdateien
Der LSP enthält keine Spezifikation zum Bereitstellen von Textfarbisierung für Sprachen. Um benutzerdefinierte Farbgebung für Sprachen in Visual Studio bereitzustellen, können Erweiterungsentwickler eine TextMate-Grammatikdatei verwenden. Gehen Sie folgendermaßen vor, um benutzerdefinierte TextMate-Grammatik- oder Designdateien hinzuzufügen:
Erstellen Sie einen Ordner mit dem Namen „Grammars“ in Ihrer Erweiterung (oder einen anderen Namen Ihrer Wahl).
Schließen Sie im Ordner Grammatik alle *.tmlanguage, *.plist, *.tmthemeoder *.json Dateien ein, die Sie für die benutzerdefinierte Farbgebung bereitstellen möchten.
Tipp
Eine .tmtheme--Datei definiert, wie die Bereiche Visual Studio-Klassifizierungen (benannte Farbschlüssel) zugeordnet werden. Für einen Leitfaden können Sie auf die globale Datei .tmtheme im Verzeichnis %ProgramFiles(x86)%\Microsoft Visual Studio\<Version>\<SKU>\Common7\IDE\CommonExtensions\Microsoft\TextMate\Starterkit\Themesg verweisen.
Erstellen Sie eine .pkgdef--Datei, und fügen Sie eine Ähnliche Zeile hinzu:
[$RootKey$\TextMate\Repositories] "MyLang"="$PackageFolder$\Grammars"
Klicken Sie mit der rechten Maustaste auf die Dateien, und wählen Sie Eigenschaftenaus. Ändern Sie die Aktion Erstellen in Inhalt, und ändern Sie die Eigenschaft In VSIX einschließen in true.
Nach Abschluss der vorherigen Schritte wird dem Installationsverzeichnis des Pakets ein Grammatikordner als Repositoryquelle namens "MyLang" hinzugefügt (MyLang ist nur ein Name für Mehrdeutigkeit und kann eine beliebige eindeutige Zeichenfolge sein). Alle Grammatiken (.tmlanguage Dateien) und Designdateien (.tmtheme Dateien) in diesem Verzeichnis werden als Potenzielle aufgenommen und ersetzen die integrierten Grammatiken, die mit TextMate bereitgestellt werden. Wenn die deklarierten Erweiterungen der Grammatikdatei mit der Erweiterung der geöffneten Datei übereinstimmen, tritt TextMate ein.
Erstellen eines einfachen Sprachclients
Hauptschnittstelle - ILanguageClient-
Fügen Sie nach dem Erstellen Ihres VSIX-Projekts dem Projekt die folgenden NuGet-Pakete hinzu:
Anmerkung
Wenn Sie eine NuGet-Paketabhängigkeit eingehen, nachdem Sie die vorherigen Schritte abgeschlossen haben, werden die Pakete Newtonsoft.Json und StreamJsonRpc ebenfalls zu Ihrem Projekt hinzugefügt. Aktualisieren Sie diese Pakete nur, wenn Sie sicher sind, dass diese neuen Versionen in der Version von Visual Studio installiert werden, auf die Ihre Erweiterungausgerichtet ist. Die Assemblys werden nicht in Ihrem VSIX enthalten sein; Stattdessen werden sie aus dem Visual Studio-Installationsverzeichnis abgerufen. Wenn Sie auf eine neuere Version der Assemblys verweisen, als auf dem Computer eines Benutzers installiert ist, funktioniert die Erweiterung nicht.
Anschließend können Sie eine neue Klasse erstellen, die die ILanguageClient--Schnittstelle implementiert. Dies ist die Hauptschnittstelle, die für Sprachclients erforderlich ist, die eine Verbindung mit einem LSP-basierten Sprachserver herstellen.
Es folgt ein Beispiel:
namespace MockLanguageExtension
{
[ContentType("bar")]
[Export(typeof(ILanguageClient))]
public class BarLanguageClient : ILanguageClient
{
public string Name => "Bar Language Extension";
public IEnumerable<string> ConfigurationSections => null;
public object InitializationOptions => null;
public IEnumerable<string> FilesToWatch => null;
public event AsyncEventHandler<EventArgs> StartAsync;
public event AsyncEventHandler<EventArgs> StopAsync;
public async Task<Connection> ActivateAsync(CancellationToken token)
{
await Task.Yield();
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Server", @"MockLanguageServer.exe");
info.Arguments = "bar";
info.RedirectStandardInput = true;
info.RedirectStandardOutput = true;
info.UseShellExecute = false;
info.CreateNoWindow = true;
Process process = new Process();
process.StartInfo = info;
if (process.Start())
{
return new Connection(process.StandardOutput.BaseStream, process.StandardInput.BaseStream);
}
return null;
}
public async Task OnLoadedAsync()
{
await StartAsync.InvokeAsync(this, EventArgs.Empty);
}
public Task OnServerInitializeFailedAsync(Exception e)
{
return Task.CompletedTask;
}
public Task OnServerInitializedAsync()
{
return Task.CompletedTask;
}
}
}
Die wichtigsten Methoden, die implementiert werden müssen, sind OnLoadedAsync- und ActivateAsync-. "OnLoadedAsync"- wird aufgerufen, wenn Visual Studio Ihre Erweiterung geladen hat und Ihr Sprachserver startbereit ist. In dieser Methode können Sie den StartAsync- Delegat sofort aufrufen, um zu signalisieren, dass der Sprachserver gestartet werden soll, oder Sie können zusätzliche Logik ausführen und StartAsync- später aufrufen. Um Ihren Sprachserver zu aktivieren, müssen Sie StartAsync zu einem bestimmten Zeitpunkt aufrufen.
ActivateAsync ist die Methode, die schließlich aufgerufen wird, indem der StartAsync-Delegat aufgerufen wird. Sie enthält die Logik, um den Sprachserver zu starten und eine Verbindung damit herzustellen. Ein Verbindungsobjekt, das Datenströme zum Schreiben auf den Server und das Lesen vom Server enthält, muss zurückgegeben werden. Alle hier ausgelösten Ausnahmen werden abgefangen und benutzern über eine Infoleistennachricht in Visual Studio angezeigt.
Aktivierung
Nachdem Ihre Sprachclientklasse implementiert wurde, müssen Sie zwei Attribute definieren, um zu definieren, wie sie in Visual Studio geladen und aktiviert wird:
[Export(typeof(ILanguageClient))]
[ContentType("bar")]
MEF
Visual Studio verwendet MEF- (Managed Extensibility Framework), um seine Erweiterbarkeitspunkte zu verwalten. Das attribut Export gibt visual Studio an, dass diese Klasse als Erweiterungspunkt aufgenommen und zur entsprechenden Zeit geladen werden soll.
Um MEF zu verwenden, müssen Sie MEF auch als Asset im VSIX-Manifest definieren.
Öffnen Sie Ihren VSIX-Manifest-Designer, und navigieren Sie zur Registerkarte Assets:
hinzufügen
** Klicken Sie auf Neu, um ein neues Asset zu erstellen:
- Typ: Microsoft.VisualStudio.MefComponent
- Quelle: Ein Projekt in der aktuellen Projektmappe
- Project: [Ihr Projekt]
Inhaltstypdefinition
Derzeit ist die einzige Möglichkeit zum Laden der LSP-basierten Sprachservererweiterung der Dateiinhaltstyp. Das heißt, beim Definieren der Sprach-Client-Klasse (die ILanguageClientimplementiert) müssen Sie die Dateitypen festlegen, die beim Öffnen dazu führen, dass Ihre Erweiterung geladen wird. Wenn keine Dateien geöffnet werden, die Ihrem definierten Inhaltstyp entsprechen, wird die Erweiterung nicht geladen.
Dies erfolgt durch Definieren einer oder mehrerer ContentTypeDefinition
Klassen:
namespace MockLanguageExtension
{
public class BarContentDefinition
{
[Export]
[Name("bar")]
[BaseDefinition(CodeRemoteContentDefinition.CodeRemoteContentTypeName)]
internal static ContentTypeDefinition BarContentTypeDefinition;
[Export]
[FileExtension(".bar")]
[ContentType("bar")]
internal static FileExtensionToContentTypeDefinition BarFileExtensionDefinition;
}
}
Im vorherigen Beispiel wird eine Inhaltstypdefinition für Dateien erstellt, die in .bar Dateierweiterung enden. Die Inhaltstypdefinition erhält den Namen "bar" und muss von CodeRemoteContentTypeNameabgeleitet werden.
Nachdem Sie eine Inhaltstypdefinition hinzugefügt haben, können Sie definieren, wann die Sprachclient-Erweiterung in der Sprachclient-Klasse geladen werden soll.
[ContentType("bar")]
[Export(typeof(ILanguageClient))]
public class BarLanguageClient : ILanguageClient
{
}
Wenn Sie Unterstützung für LSP-Sprachserver hinzufügen, müssen Sie kein eigenes Projektsystem in Visual Studio implementieren. Kunden können eine einzelne Datei oder einen Ordner in Visual Studio öffnen, um mit der Verwendung Ihres Sprachdiensts zu beginnen. Tatsächlich ist die Unterstützung für LSP-Sprachserver so konzipiert, dass sie nur in geöffneten Ordner-/Dateiszenarien funktionieren. Wenn ein benutzerdefiniertes Projektsystem implementiert ist, funktionieren einige Features (z. B. Einstellungen) nicht.
Erweiterte Features
Einstellungen
Die Unterstützung für benutzerdefinierte sprachserverspezifische Einstellungen ist verfügbar, wird jedoch noch verbessert. Die Einstellungen sind spezifisch für die Unterstützung des Sprachservers und steuern in der Regel, wie der Sprachserver Daten ausgibt. Ein Sprachserver kann z. B. eine Einstellung für die maximale Anzahl gemeldeter Fehler aufweisen. Erweiterungsautoren würden einen Standardwert definieren, der von Benutzern für bestimmte Projekte geändert werden kann.
Führen Sie die folgenden Schritte aus, um Ihrer LSP-Sprachdiensterweiterung Unterstützung hinzuzufügen:
Fügen Sie ihrem Projekt eine JSON-Datei (z. B. MockLanguageExtensionSettings.json) hinzu, die die Einstellungen und deren Standardwerte enthält. Zum Beispiel:
{ "foo.maxNumberOfProblems": -1 }
Klicken Sie mit der rechten Maustaste auf die JSON-Datei, und wählen Sie Eigenschaftenaus. Ändern Sie die Aktion Erstellen in „Inhalt“, und ändern Sie die Eigenschaft „In VSIX einschließen“ auf true.
Implementieren von ConfigurationSections und Zurückgeben der Liste der Präfixe für die in der JSON-Datei definierten Einstellungen (In Visual Studio Code würde dies dem Namen des Konfigurationsabschnitts in package.jsonzugeordnet):
public IEnumerable<string> ConfigurationSections { get { yield return "foo"; } }
Fügen Sie dem Projekt eine .pkgdef-Datei hinzu (fügen Sie eine neue Textdatei hinzu, und ändern Sie die Dateierweiterung in .pkgdef). Die Datei "pkgdef" sollte diese Informationen enthalten:
[$RootKey$\OpenFolder\Settings\VSWorkspaceSettings\[settings-name]] @="$PackageFolder$\[settings-file-name].json"
Beispiel:
[$RootKey$\OpenFolder\Settings\VSWorkspaceSettings\MockLanguageExtension] @="$PackageFolder$\MockLanguageExtensionSettings.json"
Klicken Sie mit der rechten Maustaste auf die PKGDEF-Datei, und wählen Sie Eigenschaftenaus. Ändern Sie die Aktion Erstellen in Inhalt und die Eigenschaft In VSIX einschließen in true.
Öffnen Sie die datei source.extension.vsixmanifest, und fügen Sie eine Ressource auf der Registerkarte Asset hinzu:
- Typ: Microsoft.VisualStudio.VsPackage
- Quell-: Datei im Dateisystem
- Pfad: [Pfad zu Ihrer .pkgdef Datei]
Benutzerbearbeitung von Einstellungen für einen Arbeitsbereich
Der Benutzer öffnet einen Arbeitsbereich mit Dateien, die Ihr Server besitzt.
Der Benutzer fügt eine Datei im Ordner .vs namens VSWorkspaceSettings.jsonhinzu.
Der Benutzer fügt der datei VSWorkspaceSettings.json eine Zeile für eine Einstellung hinzu, die der Server bereitstellt. Zum Beispiel:
{ "foo.maxNumberOfProblems": 10 }
Aktivieren der Diagnoseablaufverfolgung
Die Diagnoseablaufverfolgung kann aktiviert werden, um alle Nachrichten zwischen dem Client und dem Server auszugeben, was beim Debuggen von Problemen hilfreich sein kann. Gehen Sie wie folgt vor, um die Diagnoseablaufverfolgung zu aktivieren:
- Öffnen oder erstellen Sie die Arbeitsbereichseinstellungsdatei VSWorkspaceSettings.json (siehe "Benutzerbearbeitung von Einstellungen für einen Arbeitsbereich").
- Fügen Sie die folgende Zeile in der JSON-Datei "Einstellungen" hinzu:
{
"foo.trace.server": "Off"
}
Es gibt drei mögliche Werte für die Ausführlichkeit der Ablaufverfolgung:
- „Aus“: Die Ablaufverfolgung wurde vollständig deaktiviert.
- „Nachrichten“: Die Ablaufverfolgung ist aktiviert, aber nur Methodenname und Antwort-ID werden nachverfolgt.
- „Ausführlich“: Ablaufverfolgung aktiviert; die gesamte RPC-Nachricht wird nachverfolgt
Wenn die Ablaufverfolgung aktiviert ist, wird der Inhalt in eine Datei im Verzeichnis %temp%\VisualStudio\LSP geschrieben. Das Protokoll folgt dem Benennungsformat [LanguageClientName]-[Datetime Stamp].log. Derzeit kann die Ablaufverfolgung nur für offene Ordnerszenarios aktiviert werden. Beim Öffnen einer einzelnen Datei zum Aktivieren eines Sprachservers wird die Diagnoseablaufverfolgung nicht unterstützt.
Benutzerdefinierte Nachrichten
Es gibt APIs, um das Übergeben von Nachrichten an und empfangen von Nachrichten vom Sprachserver zu erleichtern, die nicht Teil des Standard language Server Protocol sind. Um benutzerdefinierte Nachrichten zu verarbeiten, implementieren Sie ILanguageClientCustomMessage2 Schnittstelle in Ihrer Sprachclientklasse. VS-StreamJsonRpc-Bibliothek wird verwendet, um benutzerdefinierte Nachrichten zwischen Ihrem Sprachclient und Dem Sprachserver zu übertragen. Da Ihre LSP-Sprachclienterweiterung ähnlich wie jede andere Visual Studio-Erweiterung ist, können Sie über benutzerdefinierte Nachrichten zusätzliche Funktionen, die vom LSP nicht unterstützt werden, mit anderen Visual Studio-APIs in Ihrer Erweiterung zu Visual Studio hinzufügen.
Empfangen benutzerdefinierter Nachrichten
Um benutzerdefinierte Nachrichten vom Sprachserver zu empfangen, implementieren Sie die [CustomMessageTarget]((/dotnet/api/microsoft.visualstudio.languageserver.client.ilanguageclientcustommessage.custommessage.custommessagetarget)-Eigenschaft für ILanguageClientCustomMessage2 und geben ein Objekt zurück, das weiß, wie Ihre benutzerdefinierten Nachrichten behandelt werden. Beispiel unten:
Die Eigenschaft (/dotnet/api/microsoft.visualstudio.languageserver.client.ilanguageclientcustommessage.custommessagetarget) für ILanguageClientCustomMessage2 gibt ein Objekt zurück, das weiß, wie Ihre benutzerdefinierten Nachrichten behandelt werden. Beispiel unten:
internal class MockCustomLanguageClient : MockLanguageClient, ILanguageClientCustomMessage2
{
private JsonRpc customMessageRpc;
public MockCustomLanguageClient() : base()
{
CustomMessageTarget = new CustomTarget();
}
public object CustomMessageTarget
{
get;
set;
}
public class CustomTarget
{
public void OnCustomNotification(JToken arg)
{
// Provide logic on what happens OnCustomNotification is called from the language server
}
public string OnCustomRequest(string test)
{
// Provide logic on what happens OnCustomRequest is called from the language server
}
}
}
Senden von benutzerdefinierten Nachrichten
Um benutzerdefinierte Nachrichten an den Sprachserver zu senden, implementieren Sie die methode AttachForCustomMessageAsync für ILanguageClientCustomMessage2. Diese Methode wird aufgerufen, wenn Ihr Sprachserver gestartet und zum Empfangen von Nachrichten bereit ist. Ein JsonRpc--Objekt wird als Parameter übergeben, den Sie dann beibehalten können, um Nachrichten mithilfe VS-StreamJsonRpc APIs an den Sprachserver zu senden. Beispiel unten:
internal class MockCustomLanguageClient : MockLanguageClient, ILanguageClientCustomMessage2
{
private JsonRpc customMessageRpc;
public MockCustomLanguageClient() : base()
{
CustomMessageTarget = new CustomTarget();
}
public async Task AttachForCustomMessageAsync(JsonRpc rpc)
{
await Task.Yield();
this.customMessageRpc = rpc;
}
public async Task SendServerCustomNotification(object arg)
{
await this.customMessageRpc.NotifyWithParameterObjectAsync("OnCustomNotification", arg);
}
public async Task<string> SendServerCustomMessage(string test)
{
return await this.customMessageRpc.InvokeAsync<string>("OnCustomRequest", test);
}
}
Mittlere Ebene
Manchmal möchte ein Erweiterungsentwickler LSP-Nachrichten abfangen, die an den Sprachserver gesendet und empfangen werden. Beispielsweise kann ein Erweiterungsentwickler den für eine bestimmte LSP-Nachricht gesendeten Nachrichtenparameter ändern oder die vom Sprachserver für ein LSP-Feature zurückgegebenen Ergebnisse ändern (z. B. Fertigstellungen). Wenn dies erforderlich ist, können Erweiterungsentwickler die MiddleLayer-API verwenden, um LSP-Nachrichten abzufangen.
Um eine bestimmte Nachricht abzufangen, erstellen Sie eine Klasse, die die ILanguageClientMiddleLayer Schnittstelle implementiert. Implementieren Sie dann die ILanguageClientCustomMessage2 Schnittstelle in Ihrer Sprachclientklasse, und geben Sie eine Instanz Ihres Objekts in der MiddleLayer--Eigenschaft zurück. Beispiel unten:
public class MockLanguageClient : ILanguageClient, ILanguageClientCustomMessage2
{
public object MiddleLayer => DiagnosticsFilterMiddleLayer.Instance;
private class DiagnosticsFilterMiddleLayer : ILanguageClientMiddleLayer
{
internal readonly static DiagnosticsFilterMiddleLayer Instance = new DiagnosticsFilterMiddleLayer();
private DiagnosticsFilterMiddleLayer() { }
public bool CanHandle(string methodName)
{
return methodName == "textDocument/publishDiagnostics";
}
public async Task HandleNotificationAsync(string methodName, JToken methodParam, Func<JToken, Task> sendNotification)
{
if (methodName == "textDocument/publishDiagnostics")
{
var diagnosticsToFilter = (JArray)methodParam["diagnostics"];
// ony show diagnostics of severity 1 (error)
methodParam["diagnostics"] = new JArray(diagnosticsToFilter.Where(diagnostic => diagnostic.Value<int?>("severity") == 1));
}
await sendNotification(methodParam);
}
public async Task<JToken> HandleRequestAsync(string methodName, JToken methodParam, Func<JToken, Task<JToken>> sendRequest)
{
return await sendRequest(methodParam);
}
}
}
Das Feature der mittleren Ebene befindet sich noch in der Entwicklung und ist noch nicht umfassend.
Beispiel für eine LSP-Sprachservererweiterung
Informationen zum Quellcode einer Beispielerweiterung mithilfe der LSP-Client-API in Visual Studio finden Sie unter VSSDK-Extensibility-Samples LSP-Beispiel-.
Häufig gestellte Fragen
möchte ich ein benutzerdefiniertes Projektsystem erstellen, um meinen LSP-Sprachserver zu ergänzen, um eine umfassendere Featureunterstützung in Visual Studio bereitzustellen, wie gehe ich dazu vor?
Die Unterstützung für LSP-basierte Sprachserver in Visual Studio basiert auf der Open Folder-Funktion und ist so konzipiert, dass kein benutzerdefiniertes Projektsystem erforderlich ist. Sie können Ihr eigenes benutzerdefiniertes Projektsystem erstellen, indem Sie den Anweisungen hier folgen, aber einige Features, zum Beispiel Einstellungen, funktionieren möglicherweise nicht. Die Standardinitialisierungslogik für LSP-Sprachserver besteht darin, den Stammordnerspeicherort des aktuell geöffneten Ordners zu übergeben. Wenn Sie also ein benutzerdefiniertes Projektsystem verwenden, müssen Sie möglicherweise während der Initialisierung benutzerdefinierte Logik bereitstellen, um sicherzustellen, dass der Sprachserver ordnungsgemäß gestartet werden kann.
Wie füge ich die Debuggerunterstützung hinzu?
Wir werden Unterstützung für das allgemeine Debugprotokoll in einer zukünftigen Version bereitstellen.
Wenn bereits ein von VS unterstützter Sprachdienst installiert ist (z. B. JavaScript), kann ich weiterhin eine LSP-Sprachservererweiterung installieren, die zusätzliche Features (z. B. Linting) bietet?
Ja, aber nicht alle Features funktionieren ordnungsgemäß. Das ultimative Ziel für LSP-Sprachservererweiterungen ist die Aktivierung von Sprachdiensten, die von Visual Studio nicht nativ unterstützt werden. Sie können Erweiterungen erstellen, die zusätzliche Unterstützung mithilfe von LSP-Sprachservern bieten, aber einige Features (z. B. IntelliSense) sind keine reibungslose Erfahrung. Im Allgemeinen wird empfohlen, dass LSP-Sprachservererweiterungen für die Bereitstellung neuer Sprachoberflächen verwendet werden, ohne vorhandene zu erweitern.
Wo veröffent ich meinen abgeschlossenen LSP-Sprachserver VSIX?
Weitere Informationen finden Sie in den Marketplace-Anweisungen hier.