编程语言特性
程序化语言特性是一组由智能编辑驱动的功能。vscode.languages.* API。在 Visual Studio Code 中提供动态语言功能有两种常见方式。让我们以 悬停 为例:
vscode.languages.registerHoverProvider('javascript', {
provideHover(document, position, token) {
return {
contents: [' Hover Content ']
};
}
});
如你所见,上述vscode.languages.registerHoverProviderAPI 提供了一种简便的方法来为 JavaScript 文件提供悬停内容。此扩展激活后,每当您悬停在某些 JavaScript 代码上时,VS Code 会查询所有悬停提供者 用于JavaScript并在悬停控件中显示结果。 语言特性列表 以及下面的示意图提供了简单的方法,帮助你找到你的扩展需要的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 方法 |
|---|---|
创建诊断集合 |
发布诊断 |
注册完成项提供程序 |
完成 & 完成解析 |
注册内联完成项提供程序 |
|
注册悬停提供者 |
悬停 |
注册签名帮助提供者 |
签名帮助 |
注册定义提供者 |
定义 |
注册类型定义提供程序 |
类型定义 |
注册实现提供者 |
实施 |
注册引用提供程序 |
参考文献 |
注册文档高亮提供程序 |
文档高亮 |
注册文档符号提供程序 |
文档符号 |
注册代码操作提供者 |
代码行动 |
注册代码感知提供者 |
代码洞察 & 代码洞察解析 |
注册文档链接提供程序 |
文档链接 & 文档链接解析 |
注册颜色提供者 |
文档颜色 & 颜色展示 |
注册文档格式编辑提供者 |
格式化 |
注册文档范围格式化编辑提供程序 |
范围格式化 |
注册类型格式化编辑提供者 |
自动格式化 |
注册重命名提供者 |
重命名 & 准备重命名 |
注册折叠范围提供程序 |
折叠范围 |
提供诊断
诊断是一种指示代码问题的方法。

语言服务器协议
您的语言服务器发送文本文档/发布诊断消息发送给语言客户端。消息携带了资源URI的诊断项数组。
注意:客户端不向服务器请求诊断信息。服务器将诊断信息推送给客户端。
直接实施
让 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);
});
})
}
基础
报告打开编辑器的诊断信息。至少,这需要在每次保存时进行。更好的方法是根据编辑器的未保存内容来计算诊断。
高级
报告诊断不仅针对打开的编辑器,还针对打开文件夹中的所有资源,无论它们是否曾经在编辑器中打开过。
显示代码完成建议
代码补全为用户提供上下文相关的建议。

语言服务器协议
在对初始化方法,你的语言服务器需要宣布它提供完成建议以及是否支持完成项\解析提供额外信息以补充计算完成项的方法。
{
...
"capabilities" : {
"completionProvider" : {
"resolveProvider": "true",
"triggerCharacters": [ '.' ]
}
...
}
}
直接实施
class GoCompletionItemProvider implements vscode.CompletionItemProvider {
public provideCompletionItems(
document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken):
Thenable<vscode.CompletionItem[]> {
...
}
}
导出 函数 激活(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(getDisposable());
ctx.subscriptions.push(
vscode.languages.registerCompletionItemProvider(
GO_MODE, new GoCompletionItemProvider(), '.', '"')); ...
}
基础
您不支持解析提供者。
高级
您支持解析提供者,这些提供者为用户选择的完成建议计算附加信息。此信息将与所选项目一起显示。
显示内联完成
内联完成直接在编辑器中(幽灵文本)呈现多词建议。

直接实施
vscode.languages.registerInlineCompletionItemProvider({ language: 'javascript' }, {
provideInlineCompletionItems(document, position, context, token) {
const result: vscode.InlineCompletionList = {
items: [],
commands: [],
};
...
返回 结果;
}
});
你可以在内联完成示例扩展中探索一个完整的示例。
基础
仅针对当前行内容和特定语言返回基于知名模式列表的内联完成建议。
高级
根据整个文档或工作区内容以及更复杂的模式返回内联完成。
显示悬停
悬停显示鼠标指针下方的符号/对象的信息。这通常是符号的类型和描述。

语言服务器协议
在对初始化方法,你的语言服务器需要宣布它提供悬停功能。
{
...
"capabilities" : {
"hoverProvider" : "true",
...
}
}
此外,您的语言服务器需要响应文本文档/悬停请求。
直接实施
class GoHoverProvider implements HoverProvider {
public provideHover(
document: TextDocument, position: Position, token: CancellationToken):
Thenable<Hover> {
...
}
}
导出 函数 激活(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerHoverProvider(
GO_MODE, new GoHoverProvider()));
...
}
基础
显示类型信息,并在有可用文档时包含文档。
高级
将方法签名以与您编译代码相同的方式进行编译。
函数和方法签名帮助
当用户输入一个函数或方法时,显示正在调用的函数/方法的信息。

语言服务器协议
在对初始化方法,你的语言服务器需要宣布它提供签名帮助。
{
...
"capabilities" : {
"signatureHelpProvider" : {
"triggerCharacters": [ '(' ]
}
...
}
}
此外,您的语言服务器需要响应文本文档/签名帮助请求。
直接实施
class GoSignatureHelpProvider implements SignatureHelpProvider {
public provideSignatureHelp(
document: TextDocument, position: Position, token: CancellationToken):
Promise<SignatureHelp> {
...
}
}
导出 函数 激活(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerSignatureHelpProvider(
GO_MODE, new GoSignatureHelpProvider(), '(', '.');
...
}
基础
确保签名帮助包含函数或方法的参数文档。
高级
没有其他内容。
显示符号的定义
允许用户在变量/函数/方法被使用的位置查看变量/函数/方法的定义。

语言服务器协议
在对初始化方法,你的语言服务器需要宣布它提供跳转到定义位置。
{
...
"capabilities" : {
"definitionProvider" : "true"
...
}
}
此外,您的语言服务器需要响应文本文档/定义请求。
直接实施
class GoDefinitionProvider implements vscode.DefinitionProvider {
public provideDefinition(
document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken):
Thenable<vscode.Location> {
...
}
}
导出 函数 激活(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerDefinitionProvider(
GO_MODE, new GoDefinitionProvider()));
...
}
基础
如果一个符号是模棱两可的,你可以显示多个定义。
高级
没有其他内容。
查找符号的所有引用
允许用户查看所有使用某个变量/函数/方法/符号的位置。

语言服务器协议
在对初始化方法,你的语言服务器需要宣布它提供符号引用位置。
{
...
"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[]> {
...
}
}
导出 函数 激活(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerReferenceProvider(
GO_MODE, new GoReferenceProvider()));
...
}
基础
返回所有引用的位置(资源URI和范围)。
高级
没有其他内容。
在文档中突出显示所有符号的出现
允许用户在打开的编辑器中查看符号的所有出现位置。

语言服务器协议
在对初始化方法,你的语言服务器需要宣布它提供符号文档位置。
{
...
"capabilities" : {
"documentHighlightProvider" : "true"
...
}
}
此外,您的语言服务器需要响应文本文档/文档高亮请求。
直接实施
class GoDocumentHighlightProvider implements vscode.DocumentHighlightProvider {
public provideDocumentHighlights(
document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken):
vscode.DocumentHighlight[] | Thenable<vscode.DocumentHighlight[]>;
...
}
}
导出 函数 激活(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerDocumentHighlightProvider(
GO_MODE, new GoDocumentHighlightProvider()));
...
}
基础
您返回编辑器文档中引用的位置。
高级
没有其他内容。
显示文档中所有的符号定义
允许用户快速导航到打开编辑器中的任何符号定义。

语言服务器协议
在对初始化方法,你的语言服务器需要宣布它提供符号文档位置。
{
...
"capabilities" : {
"documentSymbolProvider" : "true"
...
}
}
此外,您的语言服务器需要响应文本文档/文档符号请求。
直接实施
class GoDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
public provideDocumentSymbols(
document: vscode.TextDocument, token: vscode.CancellationToken):
Thenable<vscode.SymbolInformation[]> {
...
}
}
导出 函数 激活(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerDocumentSymbolProvider(
GO_MODE, new GoDocumentSymbolProvider()));
...
}
基础
返回文档中的所有符号。定义符号的种类,如变量、函数、类、方法等。
高级
没有其他内容。
显示文件夹中所有符号定义
允许用户快速导航到 VS Code 打开的文件夹(工作区)中任何位置的符号定义。

语言服务器协议
在对初始化方法,你的语言服务器需要宣布它提供全局符号位置。
{
...
"capabilities" : {
"workspaceSymbolProvider" : "true"
...
}
}
此外,您的语言服务器需要响应工作区/符号请求。
直接实施
class GoWorkspaceSymbolProvider implements vscode.WorkspaceSymbolProvider {
public provideWorkspaceSymbols(
query: string, token: vscode.CancellationToken):
Thenable<vscode.SymbolInformation[]> {
...
}
}
导出 函数 激活(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerWorkspaceSymbolProvider(
new GoWorkspaceSymbolProvider()));
...
}
基础
返回源代码在打开的文件夹中定义的所有符号。定义符号的种类,如变量、函数、类、方法等。
高级
没有其他内容。
对错误或警告的可能操作
在错误或警告旁边为用户提供可能的更正操作。如果存在操作,错误或警告旁边会显示一个灯泡。当用户点击灯泡时,会显示可用的代码操作列表。

语言服务器协议
在对初始化方法,你的语言服务器需要宣布它提供代码行动。
{
...
"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[]> {
...
}
}
导出 函数 激活(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerCodeActionsProvider(
GO_MODE, new GoCodeActionProvider()));
...
}
基础
提供代码操作以进行错误/警告更正操作。
高级
此外,提供源代码操作动作,如代码重构。例如,提取方法。
CodeLens - 在源代码中显示可操作的上下文信息
为用户提供可操作的、上下文相关的信息,这些信息会穿插在源代码中显示。

语言服务器协议
在对初始化方法,你的语言服务器需要宣布它提供CodeLens结果以及它是否支持代码洞察\解析将 CodeLens 绑定到其命令的方法。
{
...
"capabilities" : {
"codeLensProvider" : {
"resolveProvider": "true"
}
...
}
}
此外,您的语言服务器需要响应文本文档/代码感知请求。
直接实施
类 GoCodeLensProvider 实现 vscode.CodeLensProvider {
公共 provideCodeLenses(文档: TextDocument, 令牌: CancellationToken):
CodeLens[] | Thenable<CodeLens[]> {
...
}
public resolveCodeLens?(codeLens: CodeLens, token: CancellationToken):
CodeLens | Thenable<CodeLens> {
...
}
}
导出 函数 激活(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerCodeLensProvider(
GO_MODE, new GoCodeLensProvider()));
...
}
基础
定义可用于文档的 CodeLens 结果。
高级
将代码分析结果绑定到一个命令中,通过响应
代码洞察/解析输入:.
显示颜色装饰器
允许用户预览和修改文档中的颜色。

语言服务器协议
在对初始化方法,你的语言服务器需要宣布它提供颜色信息。
{
...
"capabilities" : {
"colorProvider" : "true"
...
}
}
此外,您的语言服务器需要响应文本文档/文档颜色和文本文档/颜色呈现请求。
直接实施
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[]> {
...
}
}
导出 函数 激活(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerColorProvider(
GO_MODE, new GoColorProvider()));
...
}
基础
返回文档中所有的颜色引用。为支持的颜色格式提供颜色表示(例如rgb(...),hsl(...))。
高级
没有其他内容。
在编辑器中格式化源代码
为用户提供整个文档格式化的支持。

语言服务器协议
在对初始化方法,你的语言服务器需要宣布它提供文档格式化。
{
...
"capabilities" : {
"documentFormattingProvider" : "true"
...
}
}
此外,您的语言服务器需要响应文本文档/格式化请求。
直接实施
class GoDocumentFormatter implements vscode.DocumentFormattingEditProvider {
provideDocumentFormattingEdits(
document: vscode.TextDocument, options: vscode.FormattingOptions, token: vscode.CancellationToken)
: vscode.ProviderResult<vscode.TextEdit[]> {
...
}
}
导出 函数 激活(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerDocumentFormattingEditProvider(
GO_MODE, new GoDocumentFormatter()));
...
}
基础
不提供格式支持。
高级
你应该始终返回最小的文本编辑,以使源代码格式化。这对于确保诊断结果等标记能够正确调整且不丢失至关重要。
在编辑器中格式化所选行
为用户提供支持,以格式化文档中选定的行范围。

语言服务器协议
在对初始化方法,你的语言服务器需要宣布它为多行范围提供格式化支持。
{
...
"capabilities" : {
"documentRangeFormattingProvider" : "true"
...
}
}
此外,您的语言服务器需要响应文本文档/范围格式化请求。
直接实施
class GoDocumentRangeFormatter implements vscode.DocumentRangeFormattingEditProvider{
public provideDocumentRangeFormattingEdits(
document: vscode.TextDocument, range: vscode.Range,
options: vscode.FormattingOptions, token: vscode.CancellationToken):
vscode.ProviderResult<vscode.TextEdit[]> {
...
}
}
导出 函数 激活(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerDocumentRangeFormattingEditProvider(
GO_MODE, new GoDocumentRangeFormatter()));
...
}
基础
不提供格式支持。
高级
你应该始终返回最小的文本编辑,以使源代码格式化。这对于确保诊断结果等标记被调整、更正且不丢失至关重要。
用户输入时增量格式化代码
为用户在输入时提供文本格式化的支持。
注意:用户设置 编辑器.格式化输入控制用户在输入时源代码是否被格式化。

语言服务器协议
在对初始化方法,你的语言服务器需要宣布它在用户输入时提供格式化。它还需要告诉客户端在哪些字符上触发格式化。更多触发字符是可选的。
{
...
"capabilities" : {
"documentOnTypeFormattingProvider" : {
"firstTriggerCharacter": ""},
"moreTriggerCharacter": [";", ","]
}
...
}
}
此外,您的语言服务器需要响应文本文档/按类型格式化请求。
直接实施
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[]> {
...
}
}
导出 函数 激活(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerOnTypeFormattingEditProvider(
GO_MODE, new GoOnTypingFormatter()));
...
}
基础
不提供格式支持。
高级
你应该始终返回最小的文本编辑,以使源代码格式化。这对于确保诊断结果等标记被调整、更正且不丢失至关重要。
重命名符号
允许用户重命名一个符号并更新所有对该符号的引用。

语言服务器协议
在对初始化方法,你的语言服务器需要宣布它提供重命名功能。
{
...
"capabilities" : {
"renameProvider" : "true"
...
}
}
此外,您的语言服务器需要响应文本文档/重命名请求。
直接实施
class GoRenameProvider implements vscode.RenameProvider {
public provideRenameEdits(
document: vscode.TextDocument, position: vscode.Position,
newName: string, token: vscode.CancellationToken):
Thenable<vscode.WorkspaceEdit> {
...
}
}
导出 函数 激活(ctx: vscode.ExtensionContext): void {
...
ctx.subscriptions.push(
vscode.languages.registerRenameProvider(
GO_MODE, new GoRenameProvider()));
...
}
基础
不提供重命名支持。
高级
返回所有需要执行的工作区编辑列表,例如所有包含符号引用的文件的所有编辑。