擴充性語言伺服器提供者
語言伺服器提供者牽涉到裝載於Visual Studio外部的程式,並提供Visual Studio中不存在的語言功能。
這些伺服器必須遵守 語言伺服器通訊協定,由 延伸模組專案撰寫,並實作 LanguageServerProvider
。
使用語言伺服器提供者
本概觀涵蓋使用語言伺服器提供者的下列熱門案例:
建立語言伺服器提供者
建立語言伺服器提供者牽涉到新增可擴充 Microsoft.VisualStudio.Extensibility.LanguageServer.LanguageServerProvider
和套用 VisualStudioContribution
屬性的新類別。
[VisualStudioContribution]
public class MyLanguageServerProvider : LanguageServerProvider
{
public MyLanguageServerProvider(ExtensionCore container, VisualStudioExtensibility extensibilityObject, TraceSource traceSource)
: base(container, extensibilityObject)
{
}
}
定義提供者之後,您必須:
覆寫 屬性來
LanguageServerProviderConfiguration
設定提供者。 此組態屬性會定義伺服器顯示名稱和適用的檔案類型。LanguageServerBaseDocumentType
適用於所有伺服器和所有檔類型的觸發程式。 請參閱 定義自定義檔案類型。public override LanguageServerProviderConfiguration LanguageServerProviderConfiguration => new("My Language Server", new[] { DocumentFilter.FromDocumentType(LanguageServerBaseDocumentType), });
CreateServerConnectionAsync
覆寫 Visual Studio 呼叫的方法,以通知延伸模組應該啟動 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())); }
OnServerInitializationResultAsync
覆寫 方法,在 LSP 伺服器完成其啟動和設定步驟之後,Visual Studio 會呼叫此方法。ServerInitializationResult
會提供伺服器的結果狀態,並提供LanguageServerInitializationFailureInfo
例外狀況。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; }
以下是完成所有步驟之後,範例語言伺服器提供者的外觀:
[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;
}
}
啟動語言伺服器時傳送其他數據
LanguageServerOptions.InitializationOptions
您可以在 建構函 LanguageServerProvider
式中設定 ,以使用 「初始化」通訊協定訊息將其他數據傳送至伺服器。
public MyLanguageServerProvider(ExtensionCore container, VisualStudioExtensibility extensibilityObject, TraceSource traceSource)
: base(container, extensibilityObject)
{
this.LanguageServerOptions.InitializationOptions = JToken.Parse(@"[{""server"":""initialize""}]");
}
定義自訂檔案類型
當延伸模組支援Visual Studio原生支援的文件類型時,延伸模組作者可以實作自定義檔類型。 定義 以指定支援的檔案類型時 LanguageServerProviderConfiguration
,可以使用這些類型。
[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,
};
這個代碼段會定義兩個新的檔案類型: rust
和 markdown
。 這些類型包含擴展名清單和基底類型,可 LanguageServerBaseDocumentType
涵蓋所有類型。
在 中 LanguageServerProviderConfiguration
使用這些類型,在開啟這些檔案類型時啟動您的伺服器:
public override LanguageServerProviderConfiguration LanguageServerProviderConfiguration =>
new("My Language Server",
new[]
{
DocumentFilter.FromDocumentType(RustDocumentType),
DocumentFilter.FromDocumentType(MarkdownDocumentType),
});
啟用或停用語言伺服器
開啟適用的檔案類型後,允許啟用的語言伺服器「啟動」。 停用時,停止訊息會傳送至任何適用的使用中語言伺服器,並防止進一步啟用。
[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;
}
}
}
此代碼段會藉由將 設定為 在無法初始化之後設定 this.Enabled
false
ServerInitializationResult
Failed
為 ,來停用語言伺服器。
注意
此旗標是公用的,如果設定為 false,則會停止任何執行中的伺服器。
使用本地化的資源
我們支援使用當地語系化,方法是定義 string-resources.json
檔案,並使用 %tokens%
來指定當地語系化的內容。
string-resources.json
{
{ "LocalizedResource": "LangaugeServerLocalized" }
}
存取本地化的資源
[VisualStudioContribution]
public class MyLanguageServer : LanguageServerProvider
{
...
/// <inheritdoc/>
public override LanguageServerProviderConfiguration LanguageServerProviderConfiguration =>
new("%LocalizedResource%",
new[]
{
DocumentFilter.FromDocumentType(LanguageServerBaseDocumentType)
});
}
下一步
- 請遵循建立您的第一個擴充功能教學課程,開始建立延伸模組。
- 如需使用語言伺服器提供者建立延伸模組的完整範例,請參閱 Rust 語言伺服器提供者範例。