Zprostředkovatel rozšiřitelnosti jazykového serveru
Poskytovatel jazykového serveru zahrnuje proces hostovaný mimo Visual Studio a poskytuje funkce jazyka, které nejsou v sadě Visual Studio.
Tyto servery musí dodržovat protokol jazykového serveru, vytvořený projektem rozšíření a implementovat LanguageServerProvider
.
Práce se zprostředkovateli jazykových serverů
Tento přehled popisuje tyto hlavní scénáře práce s poskytovateli jazykových serverů:
- Vytvoření poskytovatele jazykového serveru
- Odeslání dalších dat při spuštění jazykového serveru
- Definování vlastních typů dokumentů
- Povolení nebo zakázání jazykového serveru
- Použití lokalizovaných prostředků
Vytvoření poskytovatele jazykového serveru
Vytvoření poskytovatele jazykového serveru zahrnuje přidání nové třídy, která rozšiřuje Microsoft.VisualStudio.Extensibility.LanguageServer.LanguageServerProvider
a aplikuje na VisualStudioContribution
něj atribut.
[VisualStudioContribution]
public class MyLanguageServerProvider : LanguageServerProvider
{
public MyLanguageServerProvider(ExtensionCore container, VisualStudioExtensibility extensibilityObject, TraceSource traceSource)
: base(container, extensibilityObject)
{
}
}
Po definování poskytovatele potřebujete:
Nakonfigurujte zprostředkovatele přepsáním
LanguageServerProviderConfiguration
vlastnosti. Tato vlastnost konfigurace definuje zobrazovaný název serveru a příslušné typy dokumentů.LanguageServerBaseDocumentType
je k dispozici pro všechny servery a triggery pro všechny typy dokumentů. Viz Definice vlastního typu dokumentu.public override LanguageServerProviderConfiguration LanguageServerProviderConfiguration => new("My Language Server", new[] { DocumentFilter.FromDocumentType(LanguageServerBaseDocumentType), });
Přepište metodu
CreateServerConnectionAsync
, která je volána sadou Visual Studio, aby oznámila rozšíření, že má být spuštěn server LSP.// Activate the language server and return a duplex pipe that communicates with the server. public override Task<IDuplexPipe?> CreateServerConnectionAsync(CancellationToken cancellationToken) { (Stream PipeToServer, Stream PipeToVS) = FullDuplexStream.CreatePair(); // Connect "PipeToServer" to the language server return Task.FromResult<IDuplexPipe?>(new DuplexPipe(PipeToVS.UsePipeReader(), PipeToVS.UsePipeWriter())); }
Přepište metodu
OnServerInitializationResultAsync
, která je volána sadou Visual Studio po dokončení spouštěcího a konfiguračního postupu serveru LSP.ServerInitializationResult
poskytuje výsledný stav serveru aLanguageServerInitializationFailureInfo
poskytuje výjimku, pokud existuje.public override Task OnServerInitializationResultAsync(ServerInitializationResult startState,LanguageServerInitializationFailureInfo? initializationFailureInfo, CancellationToken cancellationToken) { // Method called when server activation was completed successfully or failed, denoted by "startState". return Task.CompletedTask; }
Po dokončení všechkrokůch
[VisualStudioContribution]
public class MyLanguageServerProvider : LanguageServerProvider
{
public MyLanguageServerProvider(ExtensionCore container, VisualStudioExtensibility extensibilityObject, TraceSource traceSource)
: base(container, extensibilityObject)
{
}
public override LanguageServerProviderConfiguration LanguageServerProviderConfiguration =>
new("My Language Server",
new[]
{
DocumentFilter.FromDocumentType(LanguageServerBaseDocumentType),
});
// Activate the language server and return a duplex pipe that communicates with the server.
public override Task<IDuplexPipe?> CreateServerConnectionAsync(CancellationToken cancellationToken)
{
(Stream PipeToServer, Stream PipeToVS) = FullDuplexStream.CreatePair();
// Connect "PipeToServer" to the language server
return Task.FromResult<IDuplexPipe?>(new DuplexPipe(PipeToVS.UsePipeReader(), PipeToVS.UsePipeWriter()));
}
public override Task OnServerInitializationResultAsync(ServerInitializationResult startState, LanguageServerInitializationFailureInfo? initializationFailureInfo, CancellationToken cancellationToken)
{
// Method called when server activation was completed successfully or failed, denoted by "startState".
return Task.CompletedTask;
}
}
Odeslání dalších dat při spuštění jazykového serveru
LanguageServerOptions.InitializationOptions
lze nastavit v konstruktoru pro LanguageServerProvider
odesílání dalších dat na server se zprávou "initialize" protokolu.
public MyLanguageServerProvider(ExtensionCore container, VisualStudioExtensibility extensibilityObject, TraceSource traceSource)
: base(container, extensibilityObject)
{
this.LanguageServerOptions.InitializationOptions = JToken.Parse(@"[{""server"":""initialize""}]");
}
Definování vlastních typů dokumentů
Pokud přípona podporuje typy souborů, které nejsou nativně podporovány sadou Visual Studio, můžou autoři rozšíření implementovat vlastní typy dokumentů. Tyto typy lze použít při definování LanguageServerProviderConfiguration
k určení podporovaných typů dokumentů.
[VisualStudioContribution]
internal static DocumentTypeConfiguration RustDocumentType => new("rust")
{
FileExtensions = new[] { ".rs", ".rust" },
BaseDocumentType = LanguageServerBaseDocumentType,
};
[VisualStudioContribution]
internal static DocumentTypeConfiguration MarkdownDocumentType => new("markdown")
{
FileExtensions = new[] { ".md" },
BaseDocumentType = LanguageServerBaseDocumentType,
};
Tento fragment kódu definuje dva nové typy dokumentů: rust
a markdown
. Tyto typy obsahují seznam přípon souborů a základní typ, který může zahrnovat LanguageServerBaseDocumentType
všechny typy.
Tyto typy slouží LanguageServerProviderConfiguration
k aktivaci serveru při otevření těchto typů dokumentů:
public override LanguageServerProviderConfiguration LanguageServerProviderConfiguration =>
new("My Language Server",
new[]
{
DocumentFilter.FromDocumentType(RustDocumentType),
DocumentFilter.FromDocumentType(MarkdownDocumentType),
});
Povolení nebo zakázání jazykového serveru
Po otevření příslušného typu dokumentu je povolený server jazyka aktivovat. Pokud je tato možnost zakázaná, odešle se zpráva stop na jakýkoli použitelný aktivní jazykový server a zabrání dalším aktivací.
[VisualStudioContribution]
public class MyLanguageServerProvider : LanguageServerProvider
{
...
public override Task OnServerInitializationResultAsync(ServerInitializationResult startState, LanguageServerInitializationException? initializationFailureInfo, CancellationToken cancellationToken)
{
if (startState == ServerInitializationResult.Failed)
{
Telemetry.LogEvent(initializationFailureInfo.StatusMessage, initializationFailureInfo.Exception)
// Disable the language server.
this.Enabled = false;
}
}
}
Tento fragment kódu zakáže server jazyka nastavením this.Enabled
false
, pokud ServerInitializationResult
se nastaví na Failed
po selhání inicializace.
Poznámka:
Tento příznak je veřejný a pokud je nastavený na false, zastaví se všechny spuštěné servery.
Použití lokalizovaných prostředků
Lokalizaci podporujeme definováním string-resources.json
souboru a určením %tokens%
lokalizovaného obsahu.
string-resources.json
{
{ "LocalizedResource": "LangaugeServerLocalized" }
}
Přístup k lokalizovaným prostředkům
[VisualStudioContribution]
public class MyLanguageServer : LanguageServerProvider
{
...
/// <inheritdoc/>
public override LanguageServerProviderConfiguration LanguageServerProviderConfiguration =>
new("%LocalizedResource%",
new[]
{
DocumentFilter.FromDocumentType(LanguageServerBaseDocumentType)
});
}
Další kroky
- Pokud chcete začít vytvářet rozšíření, postupujte podle pokynů k vytvoření prvního kurzu rozšíření .
- Úplný příklad vytvoření rozšíření s poskytovatelem jazykového serveru najdete v ukázce poskytovatele serveru Rust Language Server.