编程语言功能
编程语言功能是一组由 vscode.languages.*
API 提供支持的智能编辑功能。有两种常见的方法可以在 Visual Studio Code 中提供动态语言功能。让我们以 悬停 为例
vscode.languages.registerHoverProvider('javascript', {
provideHover(document, position, token) {
return {
contents: ['Hover Content']
};
}
});
如上所示,vscode.languages.registerHoverProvider
API 提供了一种简单的方法来为 JavaScript 文件提供悬停内容。此扩展激活后,当您将鼠标悬停在一些 JavaScript 代码上时,VS Code 会查询 JavaScript 的所有 HoverProvider
,并在悬停小部件中显示结果。下面的 语言功能列表 和示例 GIF 提供了一种简单的方法来查找您的扩展需要哪个 VS Code API / LSP 方法。
另一种方法是实现一个使用 语言服务器协议 的语言服务器。它的工作原理是
- 扩展提供了一个 JavaScript 语言客户端和语言服务器。
- 语言客户端就像任何其他 VS Code 扩展一样,在 Node.js 扩展宿主上下文中运行。激活后,它将在另一个进程中生成语言服务器,并通过 语言服务器协议 与其通信。
- 您将鼠标悬停在 VS Code 中的 JavaScript 代码上
- VS Code 通知语言客户端悬停
- 语言客户端查询语言服务器以获取悬停结果,并将结果发送回 VS Code
- VS Code 在悬停小部件中显示悬停结果
此过程看起来更加复杂,但它提供了两个主要优势
- 语言服务器可以用任何语言编写
- 语言服务器可以重复使用,为多个编辑器提供智能编辑功能
有关更深入的指南,请转到 语言服务器扩展指南。
语言功能列表
此列表包含每个语言功能的以下项目
- VS Code 中语言功能的示例
- 相关的 VS Code API
- 相关的 LSP 方法
提供诊断信息
诊断信息是指示代码中问题的
语言服务器协议
您的语言服务器向语言客户端发送
注意:客户端不会向服务器请求诊断信息。服务器将诊断信息推送到客户端。
直接实现
let diagnosticCollection: vscode.DiagnosticCollection;
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(getDisposable());
diagnosticCollection = vscode.languages.createDiagnosticCollection('go');
ctx.subscriptions.push(diagnosticCollection);
...
}
function onChange() {
let uri = document.uri;
check(uri.fsPath, goConfig).then(errors => {
diagnosticCollection.clear();
let diagnosticMap: Map<string, vscode.Diagnostic[]> = new Map();
errors.forEach(error => {
let canonicalFile = vscode.Uri.file(error.file).toString();
let range = new vscode.Range(error.line-1, error.startColumn, error.line-1, error.endColumn);
let diagnostics = diagnosticMap.get(canonicalFile);
if (!diagnostics) { diagnostics = []; }
diagnostics.push(new vscode.Diagnostic(range, error.msg, error.severity));
diagnosticMap.set(canonicalFile, diagnostics);
});
diagnosticMap.forEach((diags, file) => {
diagnosticCollection.set(vscode.Uri.parse(file), diags);
});
})
}
基本
报告打开编辑器的诊断信息。
高级
不仅报告打开编辑器的诊断信息,
显示代码完成建议
代码完成为用户提供了
语言服务器协议
在 initialize
方法的响应中,
{
...
"capabilities" : {
"completionProvider" : {
"resolveProvider": "true",
"triggerCharacters": [ '.' ]
}
...
}
}
直接实现
class GoCompletionItemProvider implements vscode.CompletionItemProvider {
public provideCompletionItems(
document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken):
Thenable<vscode.CompletionItem[]> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(getDisposable());
ctx.subscriptions.push(
vscode.languages.registerCompletionItemProvider(
GO_MODE, new GoCompletionItemProvider(), '.', '\"'));
...
}
基本
您不支持解析提供者。
高级
您支持解析提供者,
显示悬停
悬停显示有关鼠标光标下
语言服务器协议
在 initialize
方法的响应中,
{
...
"capabilities" : {
"hoverProvider" : "true",
...
}
}
此外,您的语言服务器需要响应
直接实现
class GoHoverProvider implements HoverProvider {
public provideHover(
document: TextDocument, position: Position, token: CancellationToken):
Thenable<Hover> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerHoverProvider(
GO_MODE, new GoHoverProvider()));
...
}
基本
显示类型信息,如果可用,
高级
以与您对代码进行颜色化的
帮助使用函数和方法签名
当用户进入函数或方法时,
语言服务器协议
在 initialize
方法的响应中,
{
...
"capabilities" : {
"signatureHelpProvider" : {
"triggerCharacters": [ '(' ]
}
...
}
}
此外,您的语言服务器需要响应
直接实现
class GoSignatureHelpProvider implements SignatureHelpProvider {
public provideSignatureHelp(
document: TextDocument, position: Position, token: CancellationToken):
Promise<SignatureHelp> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerSignatureHelpProvider(
GO_MODE, new GoSignatureHelpProvider(), '(', ','));
...
}
基本
确保签名帮助包含函数或方法
高级
无其他信息。
显示符号的定义
允许用户在使用变量/函数/方法/符号
语言服务器协议
在 initialize
方法的响应中,
{
...
"capabilities" : {
"definitionProvider" : "true"
...
}
}
此外,您的语言服务器需要响应
直接实现
class GoDefinitionProvider implements vscode.DefinitionProvider {
public provideDefinition(
document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken):
Thenable<vscode.Location> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerDefinitionProvider(
GO_MODE, new GoDefinitionProvider()));
...
}
基本
如果符号是模棱两可的,
高级
无其他信息。
查找符号的所有引用
允许用户查看某个变量/函数/方法/符号
语言服务器协议
在 initialize
方法的响应中,
{
...
"capabilities" : {
"referencesProvider" : "true"
...
}
}
此外,您的语言服务器需要响应
直接实现
class GoReferenceProvider implements vscode.ReferenceProvider {
public provideReferences(
document: vscode.TextDocument, position: vscode.Position,
options: { includeDeclaration: boolean }, token: vscode.CancellationToken):
Thenable<vscode.Location[]> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerReferenceProvider(
GO_MODE, new GoReferenceProvider()));
...
}
基本
返回所有引用的位置
高级
无其他信息。
突出显示文档中符号的所有出现
允许用户查看打开的编辑器中
语言服务器协议
在 initialize
方法的响应中,
{
...
"capabilities" : {
"documentHighlightProvider" : "true"
...
}
}
此外,您的语言服务器需要响应
直接实现
class GoDocumentHighlightProvider implements vscode.DocumentHighlightProvider {
public provideDocumentHighlights(
document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken):
vscode.DocumentHighlight[] | Thenable<vscode.DocumentHighlight[]>;
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerDocumentHighlightProvider(
GO_MODE, new GoDocumentHighlightProvider()));
...
}
基本
您返回编辑器文档中找到引用的范围。
高级
无其他信息。
显示文档内的所有符号定义
允许用户快速导航到打开的编辑器中
语言服务器协议
在 initialize
方法的响应中,
{
...
"capabilities" : {
"documentSymbolProvider" : "true"
...
}
}
此外,您的语言服务器需要响应
直接实现
class GoDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
public provideDocumentSymbols(
document: vscode.TextDocument, token: vscode.CancellationToken):
Thenable<vscode.SymbolInformation[]> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerDocumentSymbolProvider(
GO_MODE, new GoDocumentSymbolProvider()));
...
}
基本
返回文档中的所有符号。
高级
无其他信息。
显示文件夹内的所有符号定义
允许用户快速导航到 VS Code
语言服务器协议
在 initialize
方法的响应中,
{
...
"capabilities" : {
"workspaceSymbolProvider" : "true"
...
}
}
此外,您的语言服务器需要响应
直接实现
class GoWorkspaceSymbolProvider implements vscode.WorkspaceSymbolProvider {
public provideWorkspaceSymbols(
query: string, token: vscode.CancellationToken):
Thenable<vscode.SymbolInformation[]> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerWorkspaceSymbolProvider(
new GoWorkspaceSymbolProvider()));
...
}
基本
返回打开文件夹中源代码定义的所有符号。
高级
无其他信息。
错误或警告的可能操作
为用户提供可能的纠正操作,
语言服务器协议
在 initialize
方法的响应中,
{
...
"capabilities" : {
"codeActionProvider" : "true"
...
}
}
此外,您的语言服务器需要响应
直接实现
class GoCodeActionProvider implements vscode.CodeActionProvider<vscode.CodeAction> {
public provideCodeActions(
document: vscode.TextDocument, range: vscode.Range | vscode.Selection,
context: vscode.CodeActionContext, token: vscode.CancellationToken):
Thenable<vscode.CodeAction[]> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerCodeActionsProvider(
GO_MODE, new GoCodeActionProvider()));
...
}
基本
为错误/警告纠正操作提供代码操作。
高级
此外,提供源代码操作,如重构。
CodeLens - 在源代码中显示可操作的上下文信息
为用户提供可操作的上下文信息,
语言服务器协议
在对initialize
方法的响应中,您的语言服务器需要宣布它提供 CodeLens 结果,以及它是否支持codeLens\resolve
方法将 CodeLens 绑定到其命令。
{
...
"capabilities" : {
"codeLensProvider" : {
"resolveProvider": "true"
}
...
}
}
此外,您的语言服务器需要响应textDocument/codeLens
请求。
直接实现
class GoCodeLensProvider implements vscode.CodeLensProvider {
public provideCodeLenses(document: TextDocument, token: CancellationToken):
CodeLens[] | Thenable<CodeLens[]> {
...
}
public resolveCodeLens?(codeLens: CodeLens, token: CancellationToken):
CodeLens | Thenable<CodeLens> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerCodeLensProvider(
GO_MODE, new GoCodeLensProvider()));
...
}
基本
定义可用于文档的 CodeLens 结果。
高级
通过响应
codeLens/resolve
将 CodeLens 结果绑定到命令。
显示颜色装饰器
允许用户预览和修改文档中的颜色。
语言服务器协议
在对initialize
方法的响应中,您的语言服务器需要宣布它提供颜色信息。
{
...
"capabilities" : {
"colorProvider" : "true"
...
}
}
此外,您的语言服务器需要响应textDocument/documentColor
和textDocument/colorPresentation
请求。
直接实现
class GoColorProvider implements vscode.DocumentColorProvider {
public provideDocumentColors(
document: vscode.TextDocument, token: vscode.CancellationToken):
Thenable<vscode.ColorInformation[]> {
...
}
public provideColorPresentations(
color: Color, context: { document: TextDocument, range: Range }, token: vscode.CancellationToken):
Thenable<vscode.ColorPresentation[]> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerColorProvider(
GO_MODE, new GoColorProvider()));
...
}
基本
返回文档中的所有颜色引用。为支持的颜色格式提供颜色表示(例如 rgb(...), hsl(...))。
高级
无其他信息。
格式化编辑器中的源代码
为用户提供对格式化整个文档的支持。
语言服务器协议
在对initialize
方法的响应中,您的语言服务器需要宣布它提供文档格式化。
{
...
"capabilities" : {
"documentFormattingProvider" : "true"
...
}
}
此外,您的语言服务器需要响应textDocument/formatting
请求。
直接实现
class GoDocumentFormatter implements vscode.DocumentFormattingEditProvider {
provideDocumentFormattingEdits(
document: vscode.TextDocument, options: vscode.FormattingOptions, token: vscode.CancellationToken)
: vscode.ProviderResult<vscode.TextEdit[]> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerDocumentFormattingEditProvider(
GO_MODE, new GoDocumentFormatter()));
...
}
基本
不要提供格式化支持。
高级
您应始终返回导致源代码被格式化的最小文本编辑。这对于确保诊断结果等标记被正确调整并且不会丢失至关重要。
格式化编辑器中的选定行
为用户提供对格式化文档中选定行范围的支持。
语言服务器协议
在对initialize
方法的响应中,您的语言服务器需要宣布它提供对行范围的格式化支持。
{
...
"capabilities" : {
"documentRangeFormattingProvider" : "true"
...
}
}
此外,您的语言服务器需要响应textDocument/rangeFormatting
请求。
直接实现
class GoDocumentRangeFormatter implements vscode.DocumentRangeFormattingEditProvider{
public provideDocumentRangeFormattingEdits(
document: vscode.TextDocument, range: vscode.Range,
options: vscode.FormattingOptions, token: vscode.CancellationToken):
vscode.ProviderResult<vscode.TextEdit[]> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerDocumentRangeFormattingEditProvider(
GO_MODE, new GoDocumentRangeFormatter()));
...
}
基本
不要提供格式化支持。
高级
您应始终返回导致源代码被格式化的最小文本编辑。这对于确保诊断结果等标记被正确调整并且不会丢失至关重要。
在用户键入时增量格式化代码
为用户提供对边输入文本格式化的支持。
注意: 用户的 设置 editor.formatOnType
控制用户输入时源代码是否被格式化。
语言服务器协议
在对initialize
方法的响应中,您的语言服务器需要宣布它提供用户输入时的格式化。它还需要告诉客户端在哪些字符上触发格式化。moreTriggerCharacters
是可选的。
{
...
"capabilities" : {
"documentOnTypeFormattingProvider" : {
"firstTriggerCharacter": "}",
"moreTriggerCharacter": [";", ","]
}
...
}
}
此外,您的语言服务器需要响应textDocument/onTypeFormatting
请求。
直接实现
class GoOnTypingFormatter implements vscode.OnTypeFormattingEditProvider{
public provideOnTypeFormattingEdits(
document: vscode.TextDocument, position: vscode.Position,
ch: string, options: vscode.FormattingOptions, token: vscode.CancellationToken):
vscode.ProviderResult<vscode.TextEdit[]> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerOnTypeFormattingEditProvider(
GO_MODE, new GoOnTypingFormatter()));
...
}
基本
不要提供格式化支持。
高级
您应始终返回导致源代码被格式化的最小文本编辑。这对于确保诊断结果等标记被正确调整并且不会丢失至关重要。
重命名符号
允许用户重命名符号并更新对符号的所有引用。
语言服务器协议
在对initialize
方法的响应中,您的语言服务器需要宣布它提供重命名功能。
{
...
"capabilities" : {
"renameProvider" : "true"
...
}
}
此外,您的语言服务器需要响应textDocument/rename
请求。
直接实现
class GoRenameProvider implements vscode.RenameProvider {
public provideRenameEdits(
document: vscode.TextDocument, position: vscode.Position,
newName: string, token: vscode.CancellationToken):
Thenable<vscode.WorkspaceEdit> {
...
}
}
export function activate(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerRenameProvider(
GO_MODE, new GoRenameProvider()));
...
}
基本
不要提供重命名支持。
高级
返回需要执行的所有工作区编辑列表,例如包含对符号引用的所有文件的所有编辑。