现已发布!阅读 10 月份的新功能和修复。

编程语言功能

编程语言功能是一组由 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 方法
VS Code API LSP 方法
createDiagnosticCollection PublishDiagnostics
registerCompletionItemProvider 完成 & 完成解析
registerHoverProvider Hover
registerSignatureHelpProvider SignatureHelp
registerDefinitionProvider Definition
registerTypeDefinitionProvider TypeDefinition
registerImplementationProvider Implementation
registerReferenceProvider 参考
registerDocumentHighlightProvider DocumentHighlight
registerDocumentSymbolProvider DocumentSymbol
registerCodeActionsProvider CodeAction
registerCodeLensProvider CodeLens & CodeLens 解析
registerDocumentLinkProvider DocumentLink & DocumentLink 解析
registerColorProvider DocumentColor & 颜色演示
registerDocumentFormattingEditProvider Formatting
registerDocumentRangeFormattingEditProvider RangeFormatting
registerOnTypeFormattingEditProvider OnTypeFormatting
registerRenameProvider 重命名 & 准备重命名
registerFoldingRangeProvider FoldingRange

提供诊断信息

诊断信息是指示代码中问题的

Diagnostics indicating a misspelled method name

语言服务器协议

您的语言服务器向语言客户端发送

注意:客户端不会向服务器请求诊断信息。服务器将诊断信息推送到客户端。

直接实现

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);
    });
  })
}

基本

报告打开编辑器的诊断信息。

高级

不仅报告打开编辑器的诊断信息,

显示代码完成建议

代码完成为用户提供了

Code Completion prompting variable, method, and parameter names while writing code

语言服务器协议

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(), '.', '\"'));
    ...
}

基本

您不支持解析提供者。

高级

您支持解析提供者,

显示悬停

悬停显示有关鼠标光标下

Showing details about a workspace and a method when hovering over them

语言服务器协议

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()));
    ...
}

基本

显示类型信息,如果可用,

高级

以与您对代码进行颜色化的

帮助使用函数和方法签名

当用户进入函数或方法时,

Showing information about the getPackageInfo method including the necessary parameters

语言服务器协议

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(), '(', ','));
    ...
}

基本

确保签名帮助包含函数或方法

高级

无其他信息。

显示符号的定义

允许用户在使用变量/函数/方法/符号

Right click a variable, function, or method and select "Go to Definition" to jump to the definition

语言服务器协议

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()));
    ...
}

基本

如果符号是模棱两可的,

高级

无其他信息。

查找符号的所有引用

允许用户查看某个变量/函数/方法/符号

Right clicking and selecting "Find All References" to highlight all the locations where that symbol is used

语言服务器协议

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()));
    ...
}

基本

返回所有引用的位置

高级

无其他信息。

突出显示文档中符号的所有出现

允许用户查看打开的编辑器中

Select a symbol to highlight all occurrences

语言服务器协议

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()));
    ...
}

基本

您返回编辑器文档中找到引用的范围。

高级

无其他信息。

显示文档内的所有符号定义

允许用户快速导航到打开的编辑器中

Navigate to a symbol definition in the open editor using @

语言服务器协议

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

Navigate to symbol definitions in the workspace using #

语言服务器协议

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()));
    ...
}

基本

返回打开文件夹中源代码定义的所有符号。

高级

无其他信息。

错误或警告的可能操作

为用户提供可能的纠正操作,

Selecting a light bulb to view a list of available Code Actions

语言服务器协议

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 - 在源代码中显示可操作的上下文信息

为用户提供可操作的上下文信息,

CodeLens providing context

语言服务器协议

在对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 结果绑定到命令。

显示颜色装饰器

允许用户预览和修改文档中的颜色。

Showing the color picker

语言服务器协议

在对initialize方法的响应中,您的语言服务器需要宣布它提供颜色信息。

{
    ...
    "capabilities" : {
        "colorProvider" : "true"
        ...
    }
}

此外,您的语言服务器需要响应textDocument/documentColortextDocument/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(...))。

高级

无其他信息。

格式化编辑器中的源代码

为用户提供对格式化整个文档的支持。

Right click and select format code

语言服务器协议

在对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()));
    ...
}

基本

不要提供格式化支持。

高级

您应始终返回导致源代码被格式化的最小文本编辑。这对于确保诊断结果等标记被正确调整并且不会丢失至关重要。

格式化编辑器中的选定行

为用户提供对格式化文档中选定行范围的支持。

Select lines, right click, and select format code

语言服务器协议

在对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 控制用户输入时源代码是否被格式化。

Visual indicators for formatting as code is typed

语言服务器协议

在对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()));
    ...
}

基本

不要提供格式化支持。

高级

您应始终返回导致源代码被格式化的最小文本编辑。这对于确保诊断结果等标记被正确调整并且不会丢失至关重要。

重命名符号

允许用户重命名符号并更新对符号的所有引用。

Rename a symbol and update all references to the new name

语言服务器协议

在对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()));
    ...
}

基本

不要提供重命名支持。

高级

返回需要执行的所有工作区编辑列表,例如包含对符号引用的所有文件的所有编辑。