LSP / LSIF

  • 概述
  • 实现
  • 规范
LSP
  • 3.17(当前)
  • 3.18(即将推出)
  • 3.16(之前)
LSIF
  • 0.6.0(当前)
  • 0.5.0(之前)
基础协议
  • 0.9(即将推出)

语言服务器协议规范 - 3.18

基础协议
  • 头部
  • 内容
  • 基础类型
  • 请求消息
  • 响应消息
  • 通知消息
  • 取消支持
  • 进度支持
语言服务器协议
  • 概述
  • 功能
  • 消息排序
  • 消息文档
基本 JSON 结构
  • URI
  • 正则表达式
  • 枚举
  • 文本文档
  • 位置
  • Range
  • 文本文档项
  • 文本文档标识符
  • 带版本号的文本文档标识符
  • 文本文档位置参数
  • 模式
  • 文档过滤器
  • 字符串值
  • 文本编辑
  • 文本编辑数组
  • 文本文档编辑
  • 位置
  • 位置链接
  • 诊断
  • 命令
  • 标记内容
  • 文件资源更改
  • 工作区编辑
  • 工作进度
  • 客户端发起进度
  • 服务器发起进度
  • 部分结果
  • 部分结果参数
  • 追踪值
生命周期消息
  • 概述
  • 初始化
  • 已初始化
  • 注册能力
  • 注销能力
  • 设置追踪
  • 日志追踪
  • 关闭
  • 退出
文档同步
  • 概述 - 文本文档
  • 打开文本文档
  • 更改文本文档
  • 将要保存文本文档
  • 将要保存文档直到
  • 已保存文本文档
  • 已关闭文本文档
  • 重命名文本文档
  • 概述 - 笔记本文档
  • 打开笔记本文档
  • 更改笔记本文档
  • 已保存笔记本文档
  • 已关闭笔记本文档
语言特性
  • 概述
  • 跳转到声明
  • 跳转到定义
  • 转到类型定义
  • 转到实现
  • 查找引用
  • 准备调用层次结构
  • 调用层次结构传入调用
  • 调用层次结构传出调用
  • 准备类型层次结构
  • 类型层次结构超类型
  • 类型层次结构子类型
  • 文档高亮
  • 文档链接
  • 文档链接解析
  • 悬停
  • 代码透镜
  • 代码透镜刷新
  • 折叠范围
  • 折叠范围刷新
  • 选择范围
  • 文档符号
  • 语义令牌
  • 语义令牌刷新
  • 内联值
  • 内联值刷新
  • 内联提示
  • 内联提示解析
  • 内联提示刷新
  • 名称
  • 补全建议
  • 补全项解析
  • 发布诊断
  • 拉取诊断
  • 诊断刷新
  • 签名帮助
  • 代码操作
  • 代码操作解析
  • 文档颜色
  • 颜色呈现
  • 格式化
  • 范围格式化
  • 类型时格式化
  • 重命名
  • 准备重命名
  • 链接编辑范围
工作区特性
  • 工作区符号
  • 工作区符号解析
  • 获取配置
  • 配置已更改
  • 工作区文件夹
  • 工作区文件夹已更改
  • 将要创建文件
  • 已创建文件
  • 将要重命名文件
  • 已重命名文件
  • 将要删除文件
  • 已删除文件
  • 监视文件已更改
  • 执行命令
  • 应用编辑
  • 文本文档内容
窗口特性
  • 显示消息通知
  • 显示消息请求
  • 日志消息
  • 显示文档
  • 创建工作完成进度
  • 取消工作完成进度
  • 发送遥测数据
杂项
  • 实现考量
  • 元模型
更新日志
  • 3.18.0
  • 3.17.0
  • 3.16.0
  • 3.15.0
  • 3.14.0
  • 3.13.0
  • 3.12.0
  • 3.11.0
  • 3.10.0
  • 3.9.0
  • 3.8.0
  • 3.7.0
  • 3.6.0
  • 3.5.0
  • 3.4.0
  • 3.3.0
  • 3.2.0
  • 3.1.0
  • 3.0

本文档描述了即将发布的语言服务器协议 3.18.x 版本,目前正在开发中。协议 3.18.x 版本的 Node.js 实现可以在这里找到。

注意: 对此规范的编辑可以通过针对此 Markdown 文档的拉取请求进行。

3.18 的新功能

所有新的 3.18 功能都标有相应的“自版本 3.18”文本标签,或在 JSDoc 中使用 @since 3.18.0 注解。

可以在更改日志中找到详细的更改列表

规范版本用于将特性分组到新的规范发布中,并指明其首次出现的时间。规范中的特性通过客户端和服务器在初始化期间交换的所谓能力标志保持兼容。

基础协议

基础协议由一个头部和一个内容部分组成(类似于 HTTP)。头部和内容部分由“\r\n”分隔。

头部

头部部分由头部字段组成。每个头部字段由一个名称和一个值组成,两者之间用“: ”(冒号和空格)分隔。头部字段的结构符合 HTTP 语义。每个头部字段以“\r\n”终止。考虑到最后一个头部字段和整个头部本身都以“\r\n”终止,并且至少一个头部是强制性的,这意味着两个“\r\n”序列总是紧接在消息内容部分之前。

目前支持以下头部字段

头部字段名 值类型 描述
Content-Length 数字 内容部分的字节长度。此头部是必需的。
Content-Type 字符串 内容部分的 MIME 类型。默认为 application/vscode-jsonrpc; charset=utf-8

头部使用“ascii”编码。这包括分隔头部和内容部分的“\r\n”。

内容

包含消息的实际内容。消息的内容部分使用 JSON-RPC 2.0 来描述请求、响应和通知。内容部分使用 Content-Type 字段中提供的字符集进行编码。它默认为 utf-8,这是目前唯一支持的编码。如果服务器或客户端收到一个编码与 utf-8 不同的头部,它应该返回一个错误。

(协议的早期版本使用字符串常量 utf8,根据规范,这不是一个正确的编码常量。)为了向后兼容,强烈建议客户端和服务器将字符串 utf8 视为 utf-8。

示例

Content-Length: ...\r\n
\r\n
{
	"jsonrpc": "2.0",
	"id": 1,
	"method": "textDocument/completion",
	"params": {
		...
	}
}

基础协议 JSON 结构

该协议使用 JSON-RPC 协议中指定的请求、响应和通知对象。该协议目前不支持 JSON-RPC 批量消息;协议客户端和服务器不得发送 JSON-RPC 批量请求。

以下 TypeScript 定义描述了基本的 JSON-RPC 协议

基础类型

该协议对整数、无符号整数、十进制数、对象和数组使用以下定义

/**
 * Defines an integer number in the range of -2^31 to 2^31 - 1.
 */
export type integer = number;
/**
 * Defines an unsigned integer number in the range of 0 to 2^31 - 1.
 */
export type uinteger = number;
/**
 * Defines a decimal number. Since decimal numbers are very
 * rare in the language server specification, we denote the
 * exact range with every decimal using the mathematics
 * interval notation (e.g., [0, 1] denotes all decimals d with
 * 0 <= d <= 1.)
 */
export type decimal = number;
/**
 * The LSP any type.
 *
 * @since 3.17.0
 */
export type LSPAny = LSPObject | LSPArray | string | integer | uinteger |
	decimal | boolean | null;
/**
 * LSP object definition.
 *
 * @since 3.17.0
 */
export type LSPObject = { [key: string]: LSPAny };
/**
 * LSP arrays.
 *
 * @since 3.17.0
 */
export type LSPArray = LSPAny[];

抽象消息

由 JSON-RPC 定义的通用消息。语言服务器协议始终使用“2.0”作为 jsonrpc 版本。

interface Message {
	jsonrpc: string;
}

请求消息

用于描述客户端和服务器之间的请求的请求消息。每个已处理的请求都必须向请求发送方发送一个响应。

interface RequestMessage extends Message {

	/**
	 * The request id.
	 */
	id: integer | string;

	/**
	 * The method to be invoked.
	 */
	method: string;

	/**
	 * The method's params.
	 */
	params?: array | object;
}

响应消息

作为请求结果发送的响应消息。如果请求未提供结果值,请求的接收方仍需返回响应消息以符合 JSON-RPC 规范。在这种情况下,ResponseMessage 的 result 属性应设置为 null,以表示请求成功。

interface ResponseMessage extends Message {
	/**
	 * The request id.
	 */
	id: integer | string | null;

	/**
	 * The result of a request. This member is REQUIRED on success.
	 * This member MUST NOT exist if there was an error invoking the method.
	 */
	result?: LSPAny;

	/**
	 * The error object in case a request fails.
	 */
	error?: ResponseError;
}
interface ResponseError {
	/**
	 * A number indicating the error type that occurred.
	 */
	code: integer;

	/**
	 * A string providing a short description of the error.
	 */
	message: string;

	/**
	 * A primitive or structured value that contains additional
	 * information about the error. Can be omitted.
	 */
	data?: LSPAny;
}
export namespace ErrorCodes {
	// Defined by JSON-RPC
	export const ParseError: integer = -32700;
	export const InvalidRequest: integer = -32600;
	export const MethodNotFound: integer = -32601;
	export const InvalidParams: integer = -32602;
	export const InternalError: integer = -32603;

	/**
	 * This is the start range of JSON-RPC reserved error codes.
	 * It doesn't denote a real error code. No LSP error codes should
	 * be defined between the start and end range. For backwards
	 * compatibility the `ServerNotInitialized` and the `UnknownErrorCode`
	 * are left in the range.
	 *
	 * @since 3.16.0
	 */
	export const jsonrpcReservedErrorRangeStart: integer = -32099;
	/** @deprecated use jsonrpcReservedErrorRangeStart */
	export const serverErrorStart: integer = jsonrpcReservedErrorRangeStart;

	/**
	 * Error code indicating that a server received a notification or
	 * request before the server received the `initialize` request.
	 */
	export const ServerNotInitialized: integer = -32002;
	export const UnknownErrorCode: integer = -32001;

	/**
	 * This is the end range of JSON-RPC reserved error codes.
	 * It doesn't denote a real error code.
	 *
	 * @since 3.16.0
	 */
	export const jsonrpcReservedErrorRangeEnd = -32000;
	/** @deprecated use jsonrpcReservedErrorRangeEnd */
	export const serverErrorEnd: integer = jsonrpcReservedErrorRangeEnd;

	/**
	 * This is the start range of LSP reserved error codes.
	 * It doesn't denote a real error code.
	 *
	 * @since 3.16.0
	 */
	export const lspReservedErrorRangeStart: integer = -32899;

	/**
	 * A request failed but it was syntactically correct, e.g the
	 * method name was known and the parameters were valid. The error
	 * message should contain human readable information about why
	 * the request failed.
	 *
	 * @since 3.17.0
	 */
	export const RequestFailed: integer = -32803;

	/**
	 * The server cancelled the request. This error code should
	 * only be used for requests that explicitly support being
	 * server cancellable.
	 *
	 * @since 3.17.0
	 */
	export const ServerCancelled: integer = -32802;

	/**
	 * The server detected that the content of a document got
	 * modified outside normal conditions. A server should
	 * NOT send this error code if it detects a content change
	 * in its unprocessed messages. The result even computed
	 * on an older state might still be useful for the client.
	 *
	 * If a client decides that a result is not of any use anymore
	 * the client should cancel the request.
	 */
	export const ContentModified: integer = -32801;

	/**
	 * The client has canceled a request and a server has detected
	 * the cancel.
	 */
	export const RequestCancelled: integer = -32800;

	/**
	 * This is the end range of LSP reserved error codes.
	 * It doesn't denote a real error code.
	 *
	 * @since 3.16.0
	 */
	export const lspReservedErrorRangeEnd: integer = -32800;
}

通知消息

一个通知消息。已处理的通知消息不得发送响应。它们像事件一样工作。

interface NotificationMessage extends Message {
	/**
	 * The method to be invoked.
	 */
	method: string;

	/**
	 * The notification's params.
	 */
	params?: array | object;
}

$ 通知和请求

方法以“$/”开头的通知和请求是协议实现相关的消息,可能无法在所有客户端或服务器中实现。例如,如果服务器实现使用单线程同步编程语言,那么服务器对 $/cancelRequest 通知几乎无法做出反应。如果服务器或客户端收到以“$/”开头的通知,可以自由地忽略该通知。如果服务器或客户端收到以“$/”开头的请求,则必须以错误代码 MethodNotFound(例如 -32601)报错该请求。

取消支持 (➡️ ⬅️)

基础协议提供请求取消支持。要取消请求,需要发送一个具有以下属性的通知消息

通知:

  • 方法:'$/cancelRequest'
  • 参数:定义如下的 CancelParams
interface CancelParams {
	/**
	 * The request id to cancel.
	 */
	id: integer | string;
}

被取消的请求仍然需要从服务器返回并发送响应。它不能保持开放/挂起。这符合 JSON-RPC 协议,该协议要求每个请求都发送一个响应。此外,它允许在取消时返回部分结果。如果请求在取消时返回错误响应,建议将错误代码设置为 ErrorCodes.RequestCancelled。

进度支持 (➡️ ⬅️)

自 3.15.0 版起

基本协议还支持以通用方式报告进度。此机制可用于报告任何类型的进度,包括工作完成进度(通常用于使用进度条在用户界面中报告进度)和部分结果进度以支持结果流式传输。

进度通知具有以下属性

通知:

  • 方法:'$/progress'
  • 参数:定义如下的 ProgressParams
type ProgressToken = integer | string;
interface ProgressParams<T> {
	/**
	 * The progress token provided by the client or server.
	 */
	token: ProgressToken;

	/**
	 * The progress data.
	 */
	value: T;
}

进度是针对令牌报告的。令牌与请求 ID 不同,这允许带外报告进度,也允许报告通知的进度。

语言服务器协议

语言服务器协议定义了一组 JSON-RPC 请求、响应和通知消息,这些消息使用上述基本协议进行交换。本节开始描述协议中使用的基本 JSON 结构。本文档在严格模式下使用 TypeScript 接口来描述这些结构。这意味着,例如,null 值必须明确列出,并且即使存在虚假值也必须列出强制属性。基于基本的 JSON 结构,描述了实际的请求及其响应以及通知。

一个例子是客户端向服务器发送请求,以在文本文档中的特定位置请求符号的悬停值。请求的方法将是 textDocument/hover,参数如下:

interface HoverParams {
	textDocument: string; /** The text document's URI in string form */
	position: { line: uinteger; character: uinteger; };
}

请求的结果将是要显示的悬停内容。其简单形式可以是字符串。因此结果如下:

interface HoverResult {
	value: string;
}

另请注意,响应返回值为 null 表示没有结果。它不会告诉客户端重新发送请求。

通常,语言服务器协议支持 JSON-RPC 消息,但是这里定义的基础协议使用一种约定,即传递给请求/通知消息的参数应为 object 类型(如果传递的话)。但是,这并不禁止在自定义消息中使用 Array 参数类型。

该协议目前假定一个服务器服务一个工具。目前协议中不支持在不同工具之间共享一个服务器。这种共享将需要额外的协议,例如锁定文档以支持并发编辑。

功能

并非每个语言服务器都能支持协议定义的所有功能。因此,LSP 提供了“能力”。能力将一组语言功能分组。开发工具和语言服务器使用能力宣布它们支持的功能。例如,服务器宣布它可以处理 textDocument/hover 请求,但可能不处理 workspace/symbol 请求。类似地,开发工具宣布它能够在文档保存之前提供 about to save 通知,以便服务器可以在保存之前计算文本编辑以格式化编辑的文档。

能力集在客户端和服务器之间的 初始化 请求期间进行交换。

请求、通知和响应排序

对请求的响应应该大致按照请求在服务器或客户端出现的相同顺序发送。因此,例如,如果服务器收到一个 textDocument/completion 请求,然后收到一个 textDocument/signatureHelp 请求,它通常会首先返回 textDocument/completion 的响应,然后返回 textDocument/signatureHelp 的响应。

但是,服务器可能决定使用并行执行策略,并可能希望以与接收请求不同的顺序返回响应。只要此重新排序不影响响应的正确性,服务器就可以这样做。例如,允许重新排序 textDocument/completion 和 textDocument/signatureHelp 的结果,因为这些请求通常不会影响彼此的输出。另一方面,服务器很可能不应重新排序 textDocument/definition 和 textDocument/rename 请求,因为执行后者可能会影响前者的结果。

消息文档

如上所述,LSP 定义了一组请求、响应和通知。每个都使用以下格式进行文档说明:

  • 描述请求的头部
  • 一个可选的“客户端能力”部分,描述请求的客户端能力。这包括客户端能力属性路径和 JSON 结构。
  • 一个可选的 服务器能力 部分,描述请求的服务器能力。这包括服务器能力属性路径和 JSON 结构。客户端应忽略其不理解的服务器能力(例如,初始化请求在这种情况下不应失败)。
  • 一个可选的 注册选项 部分,描述如果请求或通知支持动态能力注册时的注册选项。有关其工作原理的详细信息,请参阅 注册 和 注销 请求。
  • 一个 请求 部分,描述所发送请求的格式。方法是标识请求的字符串,参数使用 TypeScript 接口进行文档说明。还说明了请求是否支持工作进度和部分结果进度。
  • 一个 响应 部分,描述响应的格式。结果项描述成功时返回的数据。可选的部分结果项描述部分结果通知返回的数据。error.data 描述错误时返回的数据。请记住,在失败情况下,响应已包含 error.code 和 error.message 字段。这些字段仅在协议强制使用特定错误代码或消息时指定。在服务器可以自由决定这些值的情况下,此处未列出。

基本 JSON 结构

有许多 JSON 结构在不同的请求和通知之间共享。它们的结构和功能在本节中进行了记录。

URI

URI 以字符串形式传输。URI 格式在 https://tools.ietf.org/html/rfc3986 中定义

  foo://example.com:8042/over/there?name=ferret#nose
  \_/   \______________/\_________/ \_________/ \__/
   |           |            |            |        |
scheme     authority       path        query   fragment
   |   _____________________|__
  / \ /                        \
  urn:example:animal:ferret:nose

我们还维护一个节点模块,用于将字符串解析为 scheme、authority、path、query 和 fragment URI 组件。GitHub 存储库是 https://github.com/Microsoft/vscode-uri,npm 模块是 https://npmjs.net.cn/package/vscode-uri。

许多接口包含与文档 URI 相对应的字段。为清晰起见,此类字段的类型声明为 DocumentUri。在传输时,它仍将作为字符串传输,但这保证了该字符串的内容可以解析为有效的 URI。

处理 URI 中的编码时应小心。例如,某些客户端(如 VS Code)可能会对驱动器盘符中的冒号进行编码,而其他客户端则不会。下面的 URI 都有效,但客户端和服务器应保持其自身使用的形式一致,以确保另一方不会将其解释为不同的 URI。客户端和服务器不应假设彼此以相同的方式编码(例如,对驱动器盘符中的冒号进行编码的客户端不能假设服务器响应将具有编码的冒号)。驱动器盘符的大小写也是如此——一方不应假设另一方将返回与自身大小写相同的驱动器盘符路径。

file:///c:/project/readme.md
file:///C%3A/project/readme.md
type DocumentUri = string;

还有一个用于普通非文档 URI 的标记接口。它也映射到 string。

type URI = string;

正则表达式

正则表达式是一个强大的工具,在语言服务器协议中确实存在它们的实际用例。然而,它们的缺点是几乎每种编程语言都有自己的一套正则表达式功能,因此规范不能简单地将它们称为正则表达式。因此,LSP 采用两步法来支持正则表达式:

  • 客户端将宣布它将使用的正则表达式引擎。这将允许为特定客户端编写的服务器充分利用该客户端的正则表达式功能。
  • 该规范将定义一组客户端应该支持的正则表达式功能。LSP 不会编写新的规范,而是引用 ECMAScript 正则表达式规范,并从中删除在 LSP 上下文中不必要或对其他客户端难以实现的功能。

客户端能力:

以下客户端能力用于宣布客户端的正则表达式引擎

  • 属性路径(可选):general.regularExpressions
  • 属性类型:RegularExpressionsClientCapabilities 定义如下
/**
 * Client capabilities specific to regular expressions.
 */
export interface RegularExpressionsClientCapabilities {
	/**
	 * The engine's name.
	 */
	engine: string;

	/**
	 * The engine's version.
	 */
	version?: string;
}

下表列出了众所周知的引擎值。请注意,该表应由将 LSP 集成到现有客户端的社区驱动。列出所有可用的正则表达式引擎不是规范的目标。

引擎 版本 文档
ECMAScript ES2020 ECMAScript 2020 & MDN

正则表达式子集:

以下 ECMAScript 2020 正则表达式规范中的功能对客户端来说不是强制性的

  • 断言:先行断言、否定先行断言、后行断言、否定后行断言。
  • 字符类:使用插入符号表示法匹配控制字符(例如 \cX)和匹配 UTF-16 码元(例如 \uhhhh)。
  • 分组和范围:命名捕获组。
  • Unicode 属性转义:不需要支持任何功能。

客户端唯一需要支持的正则表达式标志是 i,用于指定不区分大小写的搜索。

枚举

该协议支持两种枚举:(a) 基于整数的枚举和 (b) 基于字符串的枚举。基于整数的枚举通常以 1 开始。不以 1 开始的是历史原因,为了向后兼容而保留。如果合适,枚举的值集由定义方(例如客户端或服务器)宣布,并在初始化握手期间传输给另一方。一个例子是 CompletionItemKind 枚举。它由客户端使用 textDocument.completion.completionItemKind 客户端属性宣布。

为了支持枚举的演进,枚举的使用方不应因不认识的枚举值而失败。它应该简单地将其忽略为一个可用值,并尽力在往返过程中保留该值。我们再次以 CompletionItemKind 枚举为例:如果在规范的未来版本中添加了一个值为 n 的额外补全项类型并由客户端宣布,那么不认识该值(较旧)的服务器不应失败,而应简单地将该值忽略为可用项类型。

文本文档

当前协议是为内容可以表示为字符串的文本文档定制的。目前不支持二进制文档。文档中的位置(参见下面的位置定义)表示为从零开始的行和字符偏移。

3.17 新功能

在 3.17 之前,偏移量总是基于 UTF-16 字符串表示。因此,在形式为 a𐐀b 的字符串中,字符 a 的字符偏移量为 0,字符 𐐀 的字符偏移量为 1,字符 b 的字符偏移量为 3,因为 𐐀 在 UTF-16 中使用两个代码单元表示。自 3.17 起,客户端和服务器可以约定使用不同的字符串编码表示(例如 UTF-8)。客户端通过客户端能力 general.positionEncodings 宣布其支持的编码。该值是客户端支持的位置编码数组,按偏好递减(例如,索引 0 处的编码是最受偏好的)。为了保持向后兼容,唯一强制的编码是 UTF-16,通过字符串 utf-16 表示。服务器可以从客户端提供的编码中选择一个,并通过初始化结果的属性 capabilities.positionEncoding 将该编码信号回客户端。如果客户端的 general.positionEncodings 能力中缺少字符串值 utf-16,服务器可以安全地假定客户端支持 UTF-16。如果服务器在其初始化结果中省略位置编码,则编码默认为字符串值 utf-16。实现考虑:由于从一种编码转换为另一种编码需要文件/行的内容,因此转换最好在文件被读取的地方完成,这通常在服务器端。

为确保客户端和服务器将字符串分成相同的行表示,协议指定以下行尾序列:“\n”、“\r\n”和“\r”。位置与行尾字符无关,因此您不能指定表示 \r|\n 或 \n| 的位置,其中 | 表示字符偏移量。

export const EOL: string[] = ['\n', '\r\n', '\r'];

位置

文本文档中的位置表示为从零开始的行和从零开始的字符偏移量。位置位于两个字符之间,就像编辑器中的“插入”光标。不支持特殊值,例如 -1 来表示行尾。

interface Position {
	/**
	 * Line position in a document (zero-based).
	 */
	line: uinteger;

	/**
	 * Character offset on a line in a document (zero-based). The meaning of this
	 * offset is determined by the negotiated `PositionEncodingKind`.
	 *
	 * If the character value is greater than the line length it defaults back
	 * to the line length.
	 */
	character: uinteger;
}

在描述位置时,协议需要指定如何解释偏移量(特别是字符偏移量)。相应的 PositionEncodingKind 在初始化期间由客户端和服务器协商。

/**
 * A type indicating how positions are encoded,
 * specifically what column offsets mean.
 *
 * @since 3.17.0
 */
export type PositionEncodingKind = string;

/**
 * A set of predefined position encoding kinds.
 *
 * @since 3.17.0
 */
export namespace PositionEncodingKind {

	/**
	 * Character offsets count UTF-8 code units (i.e. bytes).
	 */
	export const UTF8: PositionEncodingKind = 'utf-8';

	/**
	 * Character offsets count UTF-16 code units.
	 *
	 * This is the default and must always be supported
	 * by servers.
	 */
	export const UTF16: PositionEncodingKind = 'utf-16';

	/**
	 * Character offsets count UTF-32 code units.
	 *
	 * Implementation note: these are the same as Unicode code points,
	 * so this `PositionEncodingKind` may also be used for an
	 * encoding-agnostic representation of character offsets.
	 */
	export const UTF32: PositionEncodingKind = 'utf-32';
}

Range

文本文档中的范围,表示为(从零开始的)起始和结束位置。范围类似于编辑器中的选择。因此,结束位置是排他的。如果您想指定包含一行(包括行尾字符)的范围,请使用表示下一行起始的结束位置。例如:

{
    start: { line: 5, character: 23 },
    end : { line: 6, character: 0 }
}
interface Range {
	/**
	 * The range's start position.
	 */
	start: Position;

	/**
	 * The range's end position.
	 */
	end: Position;
}

TextDocumentItem

用于将文本文档从客户端传输到服务器的项。

interface TextDocumentItem {
	/**
	 * The text document's URI.
	 */
	uri: DocumentUri;

	/**
	 * The text document's language identifier.
	 */
	languageId: string;

	/**
	 * The version number of this document (it will increase after each
	 * change, including undo/redo).
	 */
	version: integer;

	/**
	 * The content of the opened text document.
	 */
	text: string;
}

文本文档具有语言标识符,以便服务器在处理多种语言时能够识别文档,避免重新解释文件扩展名。如果文档涉及下面列出的编程语言之一,建议客户端使用这些 ID。

语言 标识符
ABAP abap
Windows 批处理 bat
BibTeX bibtex
Clojure clojure
Coffeescript coffeescript
C c
C++ cpp
C# csharp
CSS css
Diff diff
Dart dart
Dockerfile dockerfile
Elixir elixir
Erlang erlang
F# fsharp
Git git-commit 和 git-rebase
Go go
Groovy groovy
Handlebars handlebars
Haskell Haskell
HTML html
Ini ini
Java java
JavaScript javascript
JavaScript React javascriptreact
JSON json
LaTeX latex
Less less
Lua lua
Makefile makefile
Markdown markdown
Objective-C objective-c
Objective-C++ objective-cpp
Perl perl
Perl 6 perl6
PHP php
Powershell powershell
Pug jade
Python python
R r
Razor (cshtml) razor
Ruby ruby
锈色 rust
SCSS scss(使用花括号的语法),sass(缩进语法)
Scala scala
ShaderLab shaderlab
Shell 脚本 (Bash) shellscript
SQL sql
Swift swift
TypeScript typescript
TypeScript React typescriptreact
TeX tex
文本 (纯文本) 纯文本
Visual Basic vb
XML xml
XSL xsl
YAML yaml

TextDocumentIdentifier

文本文档使用 URI 进行标识。在协议层,URI 以字符串形式传递。相应的 JSON 结构如下所示

interface TextDocumentIdentifier {
	/**
	 * The text document's URI.
	 */
	uri: DocumentUri;
}

VersionedTextDocumentIdentifier

一个标识符,用于表示文本文档的特定版本。此信息通常从客户端流向服务器。

interface VersionedTextDocumentIdentifier extends TextDocumentIdentifier {
	/**
	 * The version number of this document.
	 *
	 * The version number of a document will increase after each change,
	 * including undo/redo. The number doesn't need to be consecutive.
	 */
	version: integer;
}

一个可选地表示文本文档特定版本的标识符。此信息通常从服务器流向客户端。

interface OptionalVersionedTextDocumentIdentifier extends TextDocumentIdentifier {
	/**
	 * The version number of this document. If an optional versioned text document
	 * identifier is sent from the server to the client and the file is not
	 * open in the editor (the server has not received an open notification
	 * before) the server can send `null` to indicate that the version is
	 * known and the content on disk is the master (as specified with document
	 * content ownership).
	 *
	 * The version number of a document will increase after each change,
	 * including undo/redo. The number doesn't need to be consecutive.
	 */
	version: integer | null;
}

TextDocumentPositionParams

在 1.0 版本中是 TextDocumentPosition,带内联参数。

在请求中使用的参数字面量,用于传递文本文档和文档中的位置。客户端在发出文本文档请求时,如何将选择转换为位置,由客户端决定。例如,客户端可以遵循或忽略选择方向,以使 LSP 请求与内部实现的功能保持一致。

interface TextDocumentPositionParams {
	/**
	 * The text document.
	 */
	textDocument: TextDocumentIdentifier;

	/**
	 * The position inside the text document.
	 */
	position: Position;
}

模式

文件监视器和文档过滤器中使用的模式定义。

/**
 * The pattern to watch relative to the base path. Glob patterns can have
 * the following syntax:
 * - `*` to match zero or more characters in a path segment
 * - `?` to match on one character in a path segment
 * - `**` to match any number of path segments, including none
 * - `{}` to group conditions (e.g. `**​/*.{ts,js}` matches all TypeScript
 *   and JavaScript files)
 * - `[]` to declare a range of characters to match in a path segment
 *   (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)
 * - `[!...]` to negate a range of characters to match in a path segment
 *   (e.g., `example.[!0-9]` to match on `example.a`, `example.b`,
 *   but not `example.0`)
 *
 * @since 3.17.0
 */
export type Pattern = string;
/**
 * A relative pattern is a helper to construct glob patterns that are matched
 * relatively to a base URI. The common value for a `baseUri` is a workspace
 * folder root, but it can be another absolute URI as well.
 *
 * @since 3.17.0
 */
export interface RelativePattern {
	/**
	 * A workspace folder or a base URI to which this pattern will be matched
	 * against relatively.
	 */
	baseUri: WorkspaceFolder | URI;

	/**
	 * The actual pattern;
	 */
	pattern: Pattern;
}
/**
 * The glob pattern. Either a string pattern or a relative pattern.
 *
 * @since 3.17.0
 */
export type GlobPattern = Pattern | RelativePattern;

DocumentFilter

文档过滤器通过 language、scheme 或 pattern 等属性来表示文档。例如,一个过滤器适用于磁盘上的 TypeScript 文件。另一个例子是适用于名为 package.json 的 JSON 文件的过滤器

{ language: 'typescript', scheme: 'file' }
{ language: 'json', pattern: '**/package.json' }
export interface DocumentFilter {
	/**
	 * A language id, like `typescript`.
	 */
	language?: string;

	/**
	 * A Uri scheme, like `file` or `untitled`.
	 */
	scheme?: string;

	/**
	 * A pattern, like `*.{ts,js}` or a pattern relative to a workspace folders.
	 *
	 * See GlobPattern.
	 *
	 * Whether clients support relative patterns depends on the client
	 * capability `textDocuments.filters.relativePatternSupport`.
	 */
	pattern?: GlobPattern;
}

请注意,对于有效的文档过滤器,language、scheme 或 pattern 属性中至少必须设置一个。为了使类型定义简单,所有属性都被标记为可选。

文档选择器是一个或多个文档过滤器的组合。

export type DocumentSelector = DocumentFilter[];

字符串值

用于插入文本和在插入时控制编辑器光标的模板字符串。

/**
 * A string value used as a snippet is a template which allows to insert text
 * and to control the editor cursor when insertion happens.
 *
 * A snippet can define tab stops and placeholders with `$1`, `$2`
 * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
 * the end of the snippet. Variables are defined with `$name` and
 * `${name:default value}`.
 *
 * @since 3.18.0
 */
export interface StringValue {
	/**
	 * The kind of string value.
	 */
	kind: 'snippet';

	/**
	 * The snippet string.
	 */
	value: string;
}

文本编辑、带注释的文本编辑和代码段文本编辑

  • 3.16 版新增:支持 AnnotatedTextEdit。
  • 3.18 版本新增:支持 SnippetTextEdit。

适用于文本文档的文本编辑。

interface TextEdit {
	/**
	 * The range of the text document to be manipulated. To insert
	 * text into a document, create a range where start === end.
	 */
	range: Range;

	/**
	 * The string to be inserted. For delete operations, use an
	 * empty string.
	 */
	newText: string;
}

自 3.16.0 版本以来,还出现了带注释的文本编辑的概念,它支持向文本编辑添加注释。注释可以添加描述文本编辑更改的信息。

/**
 * Additional information that describes document changes.
 *
 * @since 3.16.0
 */
export interface ChangeAnnotation {
	/**
	 * A human-readable string describing the actual change. The string
	 * is rendered prominently in the user interface.
	 */
	label: string;

	/**
	 * A flag which indicates that user confirmation is needed
	 * before applying the change.
	 */
	needsConfirmation?: boolean;

	/**
	 * A human-readable string which is rendered less prominently in
	 * the user interface.
	 */
	description?: string;
}

通常,客户端提供选项以根据关联的注释对更改进行分组。为了在协议中支持这一点,编辑或资源操作使用标识符而不是直接使用更改注释字面量来引用更改注释。这允许服务器在多个编辑或资源操作中使用相同的注释,从而允许客户端在该更改注释下对操作进行分组。实际的更改注释及其标识符由工作区编辑通过新的属性 changeAnnotations 进行管理。

/**
 * An identifier referring to a change annotation managed by a workspace
 * edit.
 *
 * @since 3.16.0.
 */
export type ChangeAnnotationIdentifier = string;
/**
 * A special text edit with an additional change annotation.
 *
 * @since 3.16.0.
 */
export interface AnnotatedTextEdit extends TextEdit {
	/**
	 * The actual annotation identifier.
	 */
	annotationId: ChangeAnnotationIdentifier;
}

自 3.18.0 版起,还引入了代码段文本编辑的概念,它支持插入代码段而不是纯文本。

一些重要提示

  • 交互式片段仅应用于活动编辑器中打开的文件。这避免了不必要的焦点切换或编辑器显示。
  • 对于活动文件,只有一个片段可以指定光标位置。如果存在多个片段为给定的 URI 定义光标位置,则由客户端决定光标的最终位置。
  • 如果代码片段文本编辑对应于当前未在活动编辑器中打开的文件,客户端应将该代码片段降级为非交互式普通文本编辑并将其应用于文件。这确保了工作区编辑不会打开任意文件。
/**
 * An interactive text edit.
 *
 * @since 3.18.0
 */
export interface SnippetTextEdit {
	/**
	 * The range of the text document to be manipulated.
	 */
	range: Range;

	/**
	 * The snippet to be inserted.
	 */
	snippet: StringValue;

	/**
	 * The actual identifier of the snippet edit.
	 */
	annotationId?: ChangeAnnotationIdentifier;
}

TextEdit[]

复杂的文本操作通过 TextEdit 或 AnnotatedTextEdit 数组描述,代表对文档的单个更改。

所有文本编辑范围都指向它们计算时所依据的文档中的位置。因此,它们将文档从状态 S1 移动到 S2,而不描述任何中间状态。文本编辑范围绝不能重叠,这意味着原始文档的任何部分都不能被多个编辑操作。但是,多个编辑可以具有相同的起始位置:多个插入,或任意数量的插入后跟单个删除或替换编辑。如果多个插入具有相同的位置,则数组中的顺序定义了插入字符串在结果文本中出现的顺序。

TextDocumentEdit

  • 3.16 版本新增:支持 AnnotatedTextEdit。此支持由客户端能力 workspace.workspaceEdit.changeAnnotationSupport 守护。如果客户端未发出该能力信号,服务器不应将 AnnotatedTextEdit 文字发送回客户端。

  • 3.18 版本新增:支持 SnippetTextEdit。该支持由客户端能力 workspace.workspaceEdit.snippetEditSupport 保护。如果客户端没有发出该能力信号,服务器不应将 SnippetTextEdit 代码片段发送回客户端。

描述单个文本文档的文本更改。文本文档被称为 OptionalVersionedTextDocumentIdentifier,允许客户端在应用编辑之前检查文本文档版本。TextDocumentEdit 描述版本 Si 上的所有更改,并在应用它们后将文档移动到版本 Si+1。因此,TextDocumentEdit 的创建者不需要对编辑数组进行排序或进行任何排序。但是,编辑必须是非重叠的。

export interface TextDocumentEdit {
	/**
	 * The text document to change.
	 */
	textDocument: OptionalVersionedTextDocumentIdentifier;

	/**
	 * The edits to be applied.
	 *
	 * @since 3.16.0 - support for AnnotatedTextEdit. This is guarded by the
	 * client capability `workspace.workspaceEdit.changeAnnotationSupport`
	 *
	 * @since 3.18.0 - support for SnippetTextEdit. This is guarded by the
	 * client capability `workspace.workspaceEdit.snippetEditSupport`
	 */
	edits: (TextEdit | AnnotatedTextEdit | SnippetTextEdit)[];
}

位置

表示资源内的位置,例如文本文件中的一行。

interface Location {
	uri: DocumentUri;
	range: Range;
}

LocationLink

表示源位置和目标位置之间的链接。

interface LocationLink {

	/**
	 * Span of the origin of this link.
	 *
	 * Used as the underlined span for mouse interaction. Defaults to the word
	 * range at the mouse position.
	 */
	originSelectionRange?: Range;

	/**
	 * The target resource identifier of this link.
	 */
	targetUri: DocumentUri;

	/**
	 * The full target range of this link. If the target is, for example, a
	 * symbol, then the target range is the range enclosing this symbol not
	 * including leading/trailing whitespace but everything else like comments.
	 * This information is typically used to highlight the range in the editor.
	 */
	targetRange: Range;

	/**
	 * The range that should be selected and revealed when this link is being
	 * followed, e.g., the name of a function. Must be contained by the
	 * `targetRange`. See also `DocumentSymbol#range`
	 */
	targetSelectionRange: Range;
}

诊断

  • 3.18 版本新增:支持诊断消息中的标记内容。该支持由客户端能力 textDocument.diagnostic.markupMessageSupport 保护。如果客户端未发出该能力信号,服务器不应将 MarkupContent 诊断消息发送回客户端。

表示诊断信息,例如编译器错误或警告。诊断对象仅在资源范围内有效。

export interface Diagnostic {
	/**
	 * The range at which the message applies.
	 */
	range: Range;

	/**
	 * The diagnostic's severity. To avoid interpretation mismatches when a
	 * server is used with different clients it is highly recommended that
	 * servers always provide a severity value. If omitted, it’s recommended
	 * for the client to interpret it as an Error severity.
	 */
	severity?: DiagnosticSeverity;

	/**
	 * The diagnostic's code, which might appear in the user interface.
	 */
	code?: integer | string;

	/**
	 * An optional property to describe the error code.
	 *
	 * @since 3.16.0
	 */
	codeDescription?: CodeDescription;

	/**
	 * A human-readable string describing the source of this
	 * diagnostic, e.g. 'typescript' or 'super lint'.
	 */
	source?: string;

	/**
	 * The diagnostic's message.
	 *
	 * @since 3.18.0 - support for MarkupContent. This is guarded by the client
	 * capability `textDocument.diagnostic.markupMessageSupport`.
	 */
	message: string | MarkupContent;

	/**
	 * Additional metadata about the diagnostic.
	 *
	 * @since 3.15.0
	 */
	tags?: DiagnosticTag[];

	/**
	 * An array of related diagnostic information, e.g. when symbol-names within
	 * a scope collide all definitions can be marked via this property.
	 */
	relatedInformation?: DiagnosticRelatedInformation[];

	/**
	 * A data entry field that is preserved between a
	 * `textDocument/publishDiagnostics` notification and
	 * `textDocument/codeAction` request.
	 *
	 * @since 3.16.0
	 */
	data?: LSPAny;
}

协议目前支持以下诊断严重性和标签

export namespace DiagnosticSeverity {
	/**
	 * Reports an error.
	 */
	export const Error: 1 = 1;
	/**
	 * Reports a warning.
	 */
	export const Warning: 2 = 2;
	/**
	 * Reports information.
	 */
	export const Information: 3 = 3;
	/**
	 * Reports a hint.
	 */
	export const Hint: 4 = 4;
}

export type DiagnosticSeverity = 1 | 2 | 3 | 4;
/**
 * The diagnostic tags.
 *
 * @since 3.15.0
 */
export namespace DiagnosticTag {
	/**
	 * Unused or unnecessary code.
	 *
	 * Clients are allowed to render diagnostics with this tag faded out
	 * instead of having an error squiggle.
	 */
	export const Unnecessary: 1 = 1;
	/**
	 * Deprecated or obsolete code.
	 *
	 * Clients are allowed to render diagnostics with this tag strike through.
	 */
	export const Deprecated: 2 = 2;
}

export type DiagnosticTag = 1 | 2;

DiagnosticRelatedInformation 定义如下

/**
 * Represents a related message and source code location for a diagnostic.
 * This should be used to point to code locations that cause or are related to
 * a diagnostic, e.g. when duplicating a symbol in a scope.
 */
export interface DiagnosticRelatedInformation {
	/**
	 * The location of this related diagnostic information.
	 */
	location: Location;

	/**
	 * The message of this related diagnostic information.
	 */
	message: string;
}

CodeDescription 定义如下

/**
 * Structure to capture a description for an error code.
 *
 * @since 3.16.0
 */
export interface CodeDescription {
	/**
	 * A URI to open with more information about the diagnostic error.
	 */
	href: URI;
}

命令

表示对命令的引用。提供一个标题,用于在 UI 中表示命令。命令由字符串标识符标识。处理命令的推荐方法是,如果客户端和服务器提供相应的能力,则在服务器端实现其执行。或者,工具扩展代码可以处理该命令。该协议目前未指定一组众所周知的命令。

interface Command {
	/**
	 * Title of the command, like `save`.
	 */
	title: string;

	/**
	 * An optional tooltip.
	 */
	tooltip?: string;

	/**
	 * The identifier of the actual command handler.
	 */
	command: string;

	/**
	 * Arguments that the command handler should be
	 * invoked with.
	 */
	arguments?: LSPAny[];
}

MarkupContent

一个 MarkupContent 字面量表示一个字符串值,其内容可以以不同的格式表示。目前支持 plaintext 和 markdown 格式。MarkupContent 通常用于结果字面量(如 CompletionItem 或 SignatureInformation)的文档属性中。如果格式是 markdown,则内容应遵循 GitHub Flavored Markdown 规范。

/**
 * Describes the content type that a client supports in various
 * result literals like `Hover`, `ParameterInfo` or `CompletionItem`.
 *
 * Please note that `MarkupKinds` must not start with a `$`. These kinds
 * are reserved for internal usage.
 */
export namespace MarkupKind {
	/**
	 * Plain text is supported as a content format.
	 */
	export const PlainText: 'plaintext' = 'plaintext';

	/**
	 * Markdown is supported as a content format.
	 */
	export const Markdown: 'markdown' = 'markdown';
}
export type MarkupKind = 'plaintext' | 'markdown';
/**
 * A `MarkupContent` literal represents a string value whose content is
 * interpreted based on its kind flag. Currently, the protocol supports
 * `plaintext` and `markdown` as markup kinds.
 *
 * If the kind is `markdown` then the value can contain fenced code blocks like
 * in GitHub issues.
 *
 * Here is an example how such a string can be constructed using
 * JavaScript / TypeScript:
 * ```typescript
 * let markdown: MarkdownContent = {
 * 	kind: MarkupKind.Markdown,
 * 	value: [
 * 		'# Header',
 * 		'Some text',
 * 		'```typescript',
 * 		'someCode();',
 * 		'```'
 * 	].join('\n')
 * };
 * ```
 *
 * *Please Note* that clients might sanitize the returned markdown. A client
 * could decide to remove HTML from the markdown to avoid script execution.
 */
export interface MarkupContent {
	/**
	 * The type of the Markup.
	 */
	kind: MarkupKind;

	/**
	 * The content itself.
	 */
	value: string;
}

此外,客户端应通过在 3.16.0 版本中引入的 general.markdown 客户端能力来发出其正在使用的 Markdown 解析器的信号,定义如下:

/**
 * Client capabilities specific to the used markdown parser.
 *
 * @since 3.16.0
 */
export interface MarkdownClientCapabilities {
	/**
	 * The name of the parser.
	 */
	parser: string;

	/**
	 * The version of the parser.
	 */
	version?: string;

	/**
	 * A list of HTML tags that the client allows / supports in
	 * Markdown.
	 *
	 * @since 3.17.0
	 */
	allowedTags?: string[];
}

目前客户端使用的已知 Markdown 解析器有

解析器 版本 文档
marked 1.1.0 Marked 文档
Python-Markdown 3.2.2 Python-Markdown 文档

文件资源更改

3.13 版本新增。自 3.16 版本起,文件资源更改可以携带一个额外的属性 changeAnnotation 来更详细地描述实际更改。客户端是否支持更改注释由客户端能力 workspace.workspaceEdit.changeAnnotationSupport 守护。

文件资源更改允许服务器通过客户端创建、重命名和删除文件和文件夹。请注意,名称提及文件,但操作应适用于文件和文件夹。这与语言服务器协议中其他命名(参见文件观察器,它可以观察文件和文件夹)一致。相应的更改字面量如下所示

/**
 * Options to create a file.
 */
export interface CreateFileOptions {
	/**
	 * Overwrite existing file. Overwrite wins over `ignoreIfExists`.
	 */
	overwrite?: boolean;

	/**
	 * Ignore if exists.
	 */
	ignoreIfExists?: boolean;
}
/**
 * Create file operation
 */
export interface CreateFile {
	/**
	 * This is a create operation.
	 */
	kind: 'create';

	/**
	 * The resource to create.
	 */
	uri: DocumentUri;

	/**
	 * Additional options.
	 */
	options?: CreateFileOptions;

	/**
	 * An optional annotation identifier describing the operation.
	 *
	 * @since 3.16.0
	 */
	annotationId?: ChangeAnnotationIdentifier;
}
/**
 * Rename file options
 */
export interface RenameFileOptions {
	/**
	 * Overwrite target if existing. Overwrite wins over `ignoreIfExists`.
	 */
	overwrite?: boolean;

	/**
	 * Ignores if target exists.
	 */
	ignoreIfExists?: boolean;
}
/**
 * Rename file operation
 */
export interface RenameFile {
	/**
	 * This is a rename operation.
	 */
	kind: 'rename';

	/**
	 * The old (existing) location.
	 */
	oldUri: DocumentUri;

	/**
	 * The new location.
	 */
	newUri: DocumentUri;

	/**
	 * Rename options.
	 */
	options?: RenameFileOptions;

	/**
	 * An optional annotation identifier describing the operation.
	 *
	 * @since 3.16.0
	 */
	annotationId?: ChangeAnnotationIdentifier;
}
/**
 * Delete file options
 */
export interface DeleteFileOptions {
	/**
	 * Delete the content recursively if a folder is denoted.
	 */
	recursive?: boolean;

	/**
	 * Ignore the operation if the file doesn't exist.
	 */
	ignoreIfNotExists?: boolean;
}
/**
 * Delete file operation
 */
export interface DeleteFile {
	/**
	 * This is a delete operation.
	 */
	kind: 'delete';

	/**
	 * The file to delete.
	 */
	uri: DocumentUri;

	/**
	 * Delete options.
	 */
	options?: DeleteFileOptions;

	/**
	 * An optional annotation identifier describing the operation.
	 *
	 * @since 3.16.0
	 */
	annotationId?: ChangeAnnotationIdentifier;
}

工作区编辑

工作区编辑表示对工作区中管理的许多资源的更改。编辑应提供 changes 或 documentChanges。如果客户端可以处理带版本号的文档编辑,并且如果存在 documentChanges,则后者优先于 changes。

自版本 3.13.0 起,工作区编辑也可以包含资源操作(创建、删除或重命名文件和文件夹)。如果存在资源操作,客户端需要按照提供的顺序执行操作。因此,一个工作区编辑可以由以下两个更改组成:(1)创建文件 a.txt 和(2)一个文本文档编辑,将文本插入文件 a.txt。无效的序列(例如(1)删除文件 a.txt 和(2)将文本插入文件 a.txt)将导致操作失败。客户端如何从失败中恢复由客户端能力描述:workspace.workspaceEdit.failureHandling

export interface WorkspaceEdit {
	/**
	 * Holds changes to existing resources.
	 */
	changes?: { [uri: DocumentUri]: TextEdit[]; };

	/**
	 * Depending on the client capability
	 * `workspace.workspaceEdit.resourceOperations` document changes are either
	 * an array of `TextDocumentEdit`s to express changes to n different text
	 * documents where each text document edit addresses a specific version of
	 * a text document. Or it can contain above `TextDocumentEdit`s mixed with
	 * create, rename and delete file / folder operations.
	 *
	 * Whether a client supports versioned document edits is expressed via
	 * `workspace.workspaceEdit.documentChanges` client capability.
	 *
	 * If a client neither supports `documentChanges` nor
	 * `workspace.workspaceEdit.resourceOperations` then only plain `TextEdit`s
	 * using the `changes` property are supported.
	 */
	documentChanges?: (
		TextDocumentEdit[] |
		(TextDocumentEdit | CreateFile | RenameFile | DeleteFile)[]
	);

	/**
	 * A map of change annotations that can be referenced in
	 * `AnnotatedTextEdit`s or create, rename and delete file / folder
	 * operations.
	 *
	 * Whether clients honor this property depends on the client capability
	 * `workspace.changeAnnotationSupport`.
	 *
	 * @since 3.16.0
	 */
	changeAnnotations?: {
		[id: string /* ChangeAnnotationIdentifier */]: ChangeAnnotation;
	};
}
WorkspaceEditClientCapabilities

3.13 版本新增:ResourceOperationKind 和 FailureHandlingKind,以及客户端能力 workspace.workspaceEdit.resourceOperations 和 workspace.workspaceEdit.failureHandling。

工作区编辑的能力随着时间不断发展。客户端可以使用以下客户端能力来描述其支持

客户端能力:

  • 属性路径(可选):workspace.workspaceEdit
  • 属性类型:WorkspaceEditClientCapabilities 定义如下
export interface WorkspaceEditClientCapabilities {
	/**
	 * The client supports versioned document changes in `WorkspaceEdit`s.
	 */
	documentChanges?: boolean;

	/**
	 * The resource operations the client supports. Clients should at least
	 * support 'create', 'rename', and 'delete' for files and folders.
	 *
	 * @since 3.13.0
	 */
	resourceOperations?: ResourceOperationKind[];

	/**
	 * The failure handling strategy of a client if applying the workspace edit
	 * fails.
	 *
	 * @since 3.13.0
	 */
	failureHandling?: FailureHandlingKind;

	/**
	 * Whether the client normalizes line endings to the client specific
	 * setting.
	 * If set to `true`, the client will normalize line ending characters
	 * in a workspace edit to the client specific new line character(s).
	 *
	 * @since 3.16.0
	 */
	normalizesLineEndings?: boolean;

	/**
	 * Whether the client in general supports change annotations on text edits,
	 * create file, rename file, and delete file changes.
	 *
	 * @since 3.16.0
	 */
	changeAnnotationSupport?: {
		/**
		 * Whether the client groups edits with equal labels into tree nodes,
		 * for instance all edits labelled with "Changes in Strings" would
		 * be a tree node.
		 */
		groupsOnLabel?: boolean;
	};

	/**
	 * Whether the client supports `WorkspaceEditMetadata` in `WorkspaceEdit`s.
	 *
	 * @since 3.18.0
	 * @proposed
	 */
	metadataSupport?: boolean;

	/**
	 * Whether the client supports snippets as text edits.
	 *
	 * @since 3.18.0
	 * @proposed
	 */
	snippetEditSupport?: boolean;
}
/**
 * The kind of resource operations supported by the client.
 */
export type ResourceOperationKind = 'create' | 'rename' | 'delete';

export namespace ResourceOperationKind {

	/**
	 * Supports creating new files and folders.
	 */
	export const Create: ResourceOperationKind = 'create';

	/**
	 * Supports renaming existing files and folders.
	 */
	export const Rename: ResourceOperationKind = 'rename';

	/**
	 * Supports deleting existing files and folders.
	 */
	export const Delete: ResourceOperationKind = 'delete';
}
export type FailureHandlingKind = 'abort' | 'transactional' | 'undo'
	| 'textOnlyTransactional';

export namespace FailureHandlingKind {

	/**
	 * Applying the workspace change is simply aborted if one of the changes
	 * provided fails. All operations executed before the failing operation
	 * stay executed.
	 */
	export const Abort: FailureHandlingKind = 'abort';

	/**
	 * All operations are executed transactionally. That means they either all
	 * succeed or no changes at all are applied to the workspace.
	 */
	export const Transactional: FailureHandlingKind = 'transactional';


	/**
	 * If the workspace edit contains only textual file changes they are
	 * executed transactionally. If resource changes (create, rename or delete
	 * file) are part of the change the failure handling strategy is abort.
	 */
	export const TextOnlyTransactional: FailureHandlingKind
		= 'textOnlyTransactional';

	/**
	 * The client tries to undo the operations already executed. But there is no
	 * guarantee that this is succeeding.
	 */
	export const Undo: FailureHandlingKind = 'undo';
}

工作进度

自 3.15.0 版起

工作进度使用通用 $/progress 通知报告。工作进度通知的值负载可以是三种不同形式。

工作进度开始

要开始报告进度,必须发送带有以下负载的 $/progress 通知

export interface WorkDoneProgressBegin {

	kind: 'begin';

	/**
	 * Mandatory title of the progress operation. Used to briefly inform about
	 * the kind of operation being performed.
	 *
	 * Examples: "Indexing" or "Linking dependencies".
	 */
	title: string;

	/**
	 * Controls if a cancel button should be shown to allow the user to cancel
	 * the long running operation. Clients that don't support cancellation are
	 * allowed to ignore the setting.
	 */
	cancellable?: boolean;

	/**
	 * Optional, more detailed associated progress message. Contains
	 * complementary information to the `title`.
	 *
	 * Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
	 * If unset, the previous progress message (if any) is still valid.
	 */
	message?: string;

	/**
	 * Optional progress percentage to display (value 100 is considered 100%).
	 * If not provided infinite progress is assumed and clients are allowed
	 * to ignore the `percentage` value in subsequent report notifications.
	 *
	 * The value should be steadily rising. Clients are free to ignore values
	 * that are not following this rule. The value range is [0, 100].
	 */
	percentage?: uinteger;
}
工作进度报告

报告进度使用以下有效载荷进行

export interface WorkDoneProgressReport {

	kind: 'report';

	/**
	 * Controls enablement state of a cancel button. This property is only valid
	 * if a cancel button got requested in the `WorkDoneProgressBegin` payload.
	 *
	 * Clients that don't support cancellation or don't support controlling the
	 * button's enablement state are allowed to ignore the setting.
	 */
	cancellable?: boolean;

	/**
	 * Optional, more detailed associated progress message. Contains
	 * complementary information to the `title`.
	 *
	 * Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
	 * If unset, the previous progress message (if any) is still valid.
	 */
	message?: string;

	/**
	 * Optional progress percentage to display (value 100 is considered 100%).
	 * If not provided infinite progress is assumed and clients are allowed
	 * to ignore the `percentage` value in subsequent report notifications.
	 *
	 * The value should be steadily rising. Clients are free to ignore values
	 * that are not following this rule. The value range is [0, 100].
	 */
	percentage?: uinteger;
}
工作进度结束

使用以下有效负载表示进度报告的结束

export interface WorkDoneProgressEnd {

	kind: 'end';

	/**
	 * Optional, a final message indicating, for example,
     * the outcome of the operation.
	 */
	message?: string;
}
启动工作进度

工作进度可以通过两种不同的方式启动

  1. 由请求的发送方(主要是客户端)使用请求参数字面量中预定义的 workDoneToken 属性。规范将把这种进度称为客户端发起的进度。
  2. 通过服务器使用请求 window/workDoneProgress/create。规范将这种进度称为服务器发起的进度。
客户端发起进度

假设客户端向服务器发送一个 textDocument/reference 请求,并且客户端接受该请求的工作完成进度报告。为了向服务器发出此信号,客户端会将 workDoneToken 属性添加到引用请求参数中。这可能看起来像这样:

{
	"textDocument": {
		"uri": "file:///folder/file.ts"
	},
	"position": {
		"line": 9,
		"character": 5
	},
	"context": {
		"includeDeclaration": true
	},
	// The token used to report work done progress.
	"workDoneToken": "1d546990-40a3-4b77-b134-46622995f6ae"
}

相应的参数属性类型定义如下

export interface WorkDoneProgressParams {
	/**
	 * An optional token that a server can use to report work done progress.
	 */
	workDoneToken?: ProgressToken;
}

服务器使用 workDoneToken 报告特定 textDocument/reference 的进度。对于上述请求,$/progress 通知参数如下所示:

{
	"token": "1d546990-40a3-4b77-b134-46622995f6ae",
	"value": {
		"kind": "begin",
		"title": "Finding references for A#foo",
		"cancellable": false,
		"message": "Processing file X.ts",
		"percentage": 0
	}
}

通过请求参数字面量中的 workDoneToken 属性收到的令牌仅在请求尚未发送响应之前有效。取消工作完成进度只需取消相应的请求即可。

没有特定的客户端能力信号表明客户端是否会为每个请求发送进度令牌。原因是,在许多客户端中,这不是一个静态的方面,甚至对于同一请求类型的每个请求实例都可能发生变化。因此,能力通过 workDoneToken 属性的存在在每个请求实例上发出信号。

为了避免客户端在发送请求之前设置进度监视用户界面,但服务器实际上不报告任何进度,服务器需要在相应的服务器能力中发出一般工作完成进度报告支持。对于上述“查找引用”示例,服务器将通过如下设置服务器能力中的 referencesProvider 属性来发出此类支持:

{
	"referencesProvider": {
		"workDoneProgress": true
	}
}

相应的服务器能力类型定义如下

export interface WorkDoneProgressOptions {
	workDoneProgress?: boolean;
}
服务器发起进度

服务器也可以使用 window/workDoneProgress/create 请求发起进度报告。这在服务器需要在请求之外报告进度时很有用(例如,如果服务器需要重新索引数据库)。然后,可以使用该令牌使用与客户端发起的进度相同的通知来报告进度。创建请求中提供的令牌只能使用一次(例如,只应发送一个开始、多个报告和一个结束通知)。

为了保持协议向后兼容,只有当客户端通过客户端能力 window.workDoneProgress 发出相应支持时,服务器才允许使用 window/workDoneProgress/create 请求,其定义如下:

	/**
	 * Window specific client capabilities.
	 */
	window?: {
		/**
		 * Whether client supports server initiated progress using the
		 * `window/workDoneProgress/create` request.
		 */
		workDoneProgress?: boolean;
	};

部分结果进度

自 3.15.0 版起

部分结果也通过通用的 $/progress 通知报告。在大多数情况下,部分结果进度通知的值负载与最终结果相同。例如,workspace/symbol 请求的返回类型为 SymbolInformation[] | WorkspaceSymbol[]。因此,部分结果也属于 SymbolInformation[] | WorkspaceSymbol[] 类型。客户端是否接受请求的部分结果通知,通过向请求参数添加 partialResultToken 来表示。例如,支持工作完成和部分结果进度的 textDocument/reference 请求可能如下所示:

{
	"textDocument": {
		"uri": "file:///folder/file.ts"
	},
	"position": {
		"line": 9,
		"character": 5
	},
	"context": {
		"includeDeclaration": true
	},
	// The token used to report work done progress.
	"workDoneToken": "1d546990-40a3-4b77-b134-46622995f6ae",
	// The token used to report partial result progress.
	"partialResultToken": "5f6f349e-4f81-4a3b-afff-ee04bff96804"
}

然后使用 partialResultToken 来报告查找引用请求的部分结果。

如果服务器通过相应的 $/progress 报告部分结果,则整个结果必须通过 $/progress 通知进行报告,每个通知将项目追加到结果中。最终响应必须在结果值方面为空。这避免了对最终结果应如何解释的混淆,例如作为另一个部分结果或作为替换结果。

如果响应错误,所提供的部分结果应按如下方式处理:

  • 如果 code 等于 RequestCancelled:客户端可以自由使用提供的结果,但应明确请求已取消且可能不完整。
  • 在所有其他情况下,不应使用所提供的部分结果。

PartialResultParams

用于传递部分结果令牌的参数文字。

export interface PartialResultParams {
	/**
	 * An optional token that a server can use to report partial results (e.g.
	 * streaming) to the client.
	 */
	partialResultToken?: ProgressToken;
}

TraceValue

TraceValue 表示服务器使用 $/logTrace 通知系统地报告其执行跟踪的详细程度。初始跟踪值由客户端在初始化时设置,之后可以使用 $/setTrace 通知进行修改。

export type TraceValue = 'off' | 'messages' | 'verbose';

服务器生命周期

当前协议规范定义服务器的生命周期由客户端(例如 VS Code 或 Emacs 等工具)管理。何时启动(进程方面)和关闭服务器由客户端决定。

初始化请求 (↩️)

初始化请求是客户端向服务器发送的第一个请求。如果服务器在 initialize 请求之前收到请求或通知,它应按以下方式处理:

  • 对于请求,响应应为 code: -32002 的错误。消息可以由服务器选择。
  • 通知应被丢弃,除了退出通知。这将允许服务器在没有初始化请求的情况下退出。

在服务器以 InitializeResult 响应 initialize 请求之前,客户端不得向服务器发送任何额外的请求或通知。此外,在服务器以 InitializeResult 响应之前,服务器也不得向客户端发送任何请求或通知,例外是在 initialize 请求期间,服务器允许向客户端发送 window/showMessage、window/logMessage 和 telemetry/event 通知以及 window/showMessageRequest 请求。如果客户端在初始化参数中设置了进度令牌(例如属性 workDoneToken),服务器也允许使用该令牌(且仅使用该令牌)通过从服务器发送到客户端的 $/progress 通知。

initiate 请求只能发送一次。

请求:

  • 方法:'initialize'
  • 参数:定义如下的 InitializeParams
interface InitializeParams extends WorkDoneProgressParams {
	/**
	 * The process Id of the parent process that started the server. Is null if
	 * the process has not been started by another process. If the parent
	 * process is not alive then the server should exit (see exit notification)
	 * its process.
	 */
	processId: integer | null;

	/**
	 * Information about the client
	 *
	 * @since 3.15.0
	 */
	clientInfo?: {
		/**
		 * The name of the client as defined by the client.
		 */
		name: string;

		/**
		 * The client's version as defined by the client.
		 */
		version?: string;
	};

	/**
	 * The locale the client is currently showing the user interface
	 * in. This must not necessarily be the locale of the operating
	 * system.
	 *
	 * Uses IETF language tags as the value's syntax
	 * (See https://en.wikipedia.org/wiki/IETF_language_tag)
	 *
	 * @since 3.16.0
	 */
	locale?: string;

	/**
	 * The rootPath of the workspace. Is null
	 * if no folder is open.
	 *
	 * @deprecated in favour of `rootUri`.
	 */
	rootPath?: string | null;

	/**
	 * The rootUri of the workspace. Is null if no
	 * folder is open. If both `rootPath` and `rootUri` are set
	 * `rootUri` wins.
	 *
	 * @deprecated in favour of `workspaceFolders`
	 */
	rootUri: DocumentUri | null;

	/**
	 * User provided initialization options.
	 */
	initializationOptions?: LSPAny;

	/**
	 * The capabilities provided by the client (editor or tool)
	 */
	capabilities: ClientCapabilities;

	/**
	 * The initial trace setting. If omitted trace is disabled ('off').
	 */
	trace?: TraceValue;

	/**
	 * The workspace folders configured in the client when the server starts.
	 * This property is only available if the client supports workspace folders.
	 * It can be `null` if the client supports workspace folders but none are
	 * configured.
	 *
	 * @since 3.6.0
	 */
	workspaceFolders?: WorkspaceFolder[] | null;
}

其中 ClientCapabilities 和 TextDocumentClientCapabilities 定义如下

TextDocumentClientCapabilities

TextDocumentClientCapabilities 定义编辑器/工具在文本文档上提供的能力。

/**
 * Text document specific client capabilities.
 */
export interface TextDocumentClientCapabilities {

	/**
	 * Defines which synchronization capabilities the client supports.
	 */
	synchronization?: TextDocumentSyncClientCapabilities;

	/**
	 * Defines which filters the client supports.
	 *
	 * @since 3.18.0
	 */
	filters?: TextDocumentFilterClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/completion` request.
	 */
	completion?: CompletionClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/hover` request.
	 */
	hover?: HoverClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/signatureHelp` request.
	 */
	signatureHelp?: SignatureHelpClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/declaration` request.
	 *
	 * @since 3.14.0
	 */
	declaration?: DeclarationClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/definition` request.
	 */
	definition?: DefinitionClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/typeDefinition` request.
	 *
	 * @since 3.6.0
	 */
	typeDefinition?: TypeDefinitionClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/implementation` request.
	 *
	 * @since 3.6.0
	 */
	implementation?: ImplementationClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/references` request.
	 */
	references?: ReferenceClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/documentHighlight` request.
	 */
	documentHighlight?: DocumentHighlightClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/documentSymbol` request.
	 */
	documentSymbol?: DocumentSymbolClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/codeAction` request.
	 */
	codeAction?: CodeActionClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/codeLens` request.
	 */
	codeLens?: CodeLensClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/documentLink` request.
	 */
	documentLink?: DocumentLinkClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/documentColor` and the
	 * `textDocument/colorPresentation` request.
	 *
	 * @since 3.6.0
	 */
	colorProvider?: DocumentColorClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/formatting` request.
	 */
	formatting?: DocumentFormattingClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/rangeFormatting` and
	 * `textDocument/rangesFormatting requests.
	 */
	rangeFormatting?: DocumentRangeFormattingClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/onTypeFormatting` request.
	 */
	onTypeFormatting?: DocumentOnTypeFormattingClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/rename` request.
	 */
	rename?: RenameClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/publishDiagnostics`
	 * notification.
	 */
	publishDiagnostics?: PublishDiagnosticsClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/foldingRange` request.
	 *
	 * @since 3.10.0
	 */
	foldingRange?: FoldingRangeClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/selectionRange` request.
	 *
	 * @since 3.15.0
	 */
	selectionRange?: SelectionRangeClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/linkedEditingRange` request.
	 *
	 * @since 3.16.0
	 */
	linkedEditingRange?: LinkedEditingRangeClientCapabilities;

	/**
	 * Capabilities specific to the various call hierarchy requests.
	 *
	 * @since 3.16.0
	 */
	callHierarchy?: CallHierarchyClientCapabilities;

	/**
	 * Capabilities specific to the various semantic token requests.
	 *
	 * @since 3.16.0
	 */
	semanticTokens?: SemanticTokensClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/moniker` request.
	 *
	 * @since 3.16.0
	 */
	moniker?: MonikerClientCapabilities;

	/**
	 * Capabilities specific to the various type hierarchy requests.
	 *
	 * @since 3.17.0
	 */
	typeHierarchy?: TypeHierarchyClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/inlineValue` request.
	 *
	 * @since 3.17.0
	 */
	inlineValue?: InlineValueClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/inlayHint` request.
	 *
	 * @since 3.17.0
	 */
	inlayHint?: InlayHintClientCapabilities;

	/**
	 * Capabilities specific to the diagnostic pull model.
	 *
	 * @since 3.17.0
	 */
	diagnostic?: DiagnosticClientCapabilities;

	/**
	 * Capabilities specific to the `textDocument/inlineCompletion` request.
	 *
	 * @since 3.18.0
	 */
	inlineCompletion?: InlineCompletionClientCapabilities;
}

export interface TextDocumentFilterClientCapabilities {

	/**
	 * The client supports Relative Patterns.
	 *
	 * @since 3.18.0
	 */
	relativePatternSupport?: boolean;
}
笔记本文档客户端能力

NotebookDocumentClientCapabilities 定义了编辑器/工具在笔记本文档上提供的功能。

/**
 * Capabilities specific to the notebook document support.
 *
 * @since 3.17.0
 */
export interface NotebookDocumentClientCapabilities {
	/**
	 * Capabilities specific to notebook document synchronization
	 *
	 * @since 3.17.0
	 */
	synchronization: NotebookDocumentSyncClientCapabilities;
}

ClientCapabilities 定义了客户端支持的动态注册、工作区和文本文档功能的能力。experimental 可用于传递正在开发中的实验性能力。为了将来的兼容性,ClientCapabilities 对象字面量可以设置比当前定义的更多属性。收到带有未知属性的 ClientCapabilities 对象字面量的服务器应忽略这些属性。缺失的属性应解释为缺少该能力。如果缺失的属性通常定义子属性,则所有缺失的子属性都应解释为缺少相应的能力。

客户端功能在协议 3.0 版中引入。因此,它们仅描述在 3.x 或更高版本中引入的功能。协议 2.x 版本中存在的功能对客户端仍然是强制性的。客户端不能选择不提供它们。因此,即使客户端省略了 ClientCapabilities.textDocument.synchronization,客户端仍然需要提供文本文档同步(例如,打开、更改和关闭通知)。

interface ClientCapabilities {
	/**
	 * Workspace specific client capabilities.
	 */
	workspace?: {
		/**
		 * The client supports applying batch edits
		 * to the workspace by supporting the request
		 * 'workspace/applyEdit'
		 */
		applyEdit?: boolean;

		/**
		 * Capabilities specific to `WorkspaceEdit`s
		 */
		workspaceEdit?: WorkspaceEditClientCapabilities;

		/**
		 * Capabilities specific to the `workspace/didChangeConfiguration`
		 * notification.
		 */
		didChangeConfiguration?: DidChangeConfigurationClientCapabilities;

		/**
		 * Capabilities specific to the `workspace/didChangeWatchedFiles`
		 * notification.
		 */
		didChangeWatchedFiles?: DidChangeWatchedFilesClientCapabilities;

		/**
		 * Capabilities specific to the `workspace/symbol` request.
		 */
		symbol?: WorkspaceSymbolClientCapabilities;

		/**
		 * Capabilities specific to the `workspace/executeCommand` request.
		 */
		executeCommand?: ExecuteCommandClientCapabilities;

		/**
		 * The client has support for workspace folders.
		 *
		 * @since 3.6.0
		 */
		workspaceFolders?: boolean;

		/**
		 * The client supports `workspace/configuration` requests.
		 *
		 * @since 3.6.0
		 */
		configuration?: boolean;

		/**
		 * Capabilities specific to the semantic token requests scoped to the
		 * workspace.
		 *
		 * @since 3.16.0
		 */
		 semanticTokens?: SemanticTokensWorkspaceClientCapabilities;

		/**
		 * Capabilities specific to the code lens requests scoped to the
		 * workspace.
		 *
		 * @since 3.16.0
		 */
		codeLens?: CodeLensWorkspaceClientCapabilities;

		/**
		 * The client has support for file requests/notifications.
		 *
		 * @since 3.16.0
		 */
		fileOperations?: {
			/**
			 * Whether the client supports dynamic registration for file
			 * requests/notifications.
			 */
			dynamicRegistration?: boolean;

			/**
			 * The client has support for sending didCreateFiles notifications.
			 */
			didCreate?: boolean;

			/**
			 * The client has support for sending willCreateFiles requests.
			 */
			willCreate?: boolean;

			/**
			 * The client has support for sending didRenameFiles notifications.
			 */
			didRename?: boolean;

			/**
			 * The client has support for sending willRenameFiles requests.
			 */
			willRename?: boolean;

			/**
			 * The client has support for sending didDeleteFiles notifications.
			 */
			didDelete?: boolean;

			/**
			 * The client has support for sending willDeleteFiles requests.
			 */
			willDelete?: boolean;
		};

		/**
		 * Client workspace capabilities specific to inline values.
		 *
		 * @since 3.17.0
		 */
		inlineValue?: InlineValueWorkspaceClientCapabilities;

		/**
		 * Client workspace capabilities specific to inlay hints.
		 *
		 * @since 3.17.0
		 */
		inlayHint?: InlayHintWorkspaceClientCapabilities;

		/**
		 * Client workspace capabilities specific to diagnostics.
		 *
		 * @since 3.17.0.
		 */
		diagnostics?: DiagnosticWorkspaceClientCapabilities;
	};

	/**
	 * Text document specific client capabilities.
	 */
	textDocument?: TextDocumentClientCapabilities;

	/**
	 * Capabilities specific to the notebook document support.
	 *
	 * @since 3.17.0
	 */
	notebookDocument?: NotebookDocumentClientCapabilities;

	/**
	 * Window specific client capabilities.
	 */
	window?: {
		/**
		 * It indicates whether the client supports server initiated
		 * progress using the `window/workDoneProgress/create` request.
		 *
		 * The capability also controls Whether client supports handling
		 * of progress notifications. If set servers are allowed to report a
		 * `workDoneProgress` property in the request specific server
		 * capabilities.
		 *
		 * @since 3.15.0
		 */
		workDoneProgress?: boolean;

		/**
		 * Capabilities specific to the showMessage request
		 *
		 * @since 3.16.0
		 */
		showMessage?: ShowMessageRequestClientCapabilities;

		/**
		 * Client capabilities for the show document request.
		 *
		 * @since 3.16.0
		 */
		showDocument?: ShowDocumentClientCapabilities;
	};

	/**
	 * General client capabilities.
	 *
	 * @since 3.16.0
	 */
	general?: {
		/**
		 * Client capability that signals how the client
		 * handles stale requests (e.g. a request
		 * for which the client will not process the response
		 * anymore since the information is outdated).
		 *
		 * @since 3.17.0
		 */
		staleRequestSupport?: {
			/**
			 * The client will actively cancel the request.
			 */
			cancel: boolean;

			/**
			 * The list of requests for which the client
			 * will retry the request if it receives a
			 * response with error code `ContentModified``
			 */
			 retryOnContentModified: string[];
		}

		/**
		 * Client capabilities specific to regular expressions.
		 *
		 * @since 3.16.0
		 */
		regularExpressions?: RegularExpressionsClientCapabilities;

		/**
		 * Client capabilities specific to the client's markdown parser.
		 *
		 * @since 3.16.0
		 */
		markdown?: MarkdownClientCapabilities;

		/**
		 * The position encodings supported by the client. Client and server
		 * have to agree on the same position encoding to ensure that offsets
		 * (e.g. character position in a line) are interpreted the same on both
		 * side.
		 *
		 * To keep the protocol backwards compatible the following applies: if
		 * the value 'utf-16' is missing from the array of position encodings
		 * servers can assume that the client supports UTF-16. UTF-16 is
		 * therefore a mandatory encoding.
		 *
		 * If omitted it defaults to ['utf-16'].
		 *
		 * Implementation considerations: since the conversion from one encoding
		 * into another requires the content of the file / line the conversion
		 * is best done where the file is read which is usually on the server
		 * side.
		 *
		 * @since 3.17.0
		 */
		positionEncodings?: PositionEncodingKind[];
	};

	/**
	 * Experimental client capabilities.
	 */
	experimental?: LSPAny;
}

Response:

  • 结果:定义如下的 InitializeResult
interface InitializeResult {
	/**
	 * The capabilities the language server provides.
	 */
	capabilities: ServerCapabilities;

	/**
	 * Information about the server.
	 *
	 * @since 3.15.0
	 */
	serverInfo?: {
		/**
		 * The name of the server as defined by the server.
		 */
		name: string;

		/**
		 * The server's version as defined by the server.
		 */
		version?: string;
	};
}
  • error.code
/**
 * Known error codes for an `InitializeErrorCodes`;
 */
export namespace InitializeErrorCodes {

	/**
	 * If the protocol version provided by the client can't be handled by
	 * the server.
	 *
	 * @deprecated This initialize error got replaced by client capabilities.
	 * There is no version handshake in version 3.0x
	 */
	export const unknownProtocolVersion: 1 = 1;
}

export type InitializeErrorCodes = 1;
  • error.data
interface InitializeError {
	/**
	 * Indicates whether the client execute the following retry logic:
	 * (1) show the message provided by the ResponseError to the user
	 * (2) user selects retry or cancel
	 * (3) if user selected retry the initialize method is sent again.
	 */
	retry: boolean;
}

服务器可以发出以下能力信号

interface ServerCapabilities {

	/**
	 * The position encoding the server picked from the encodings offered
	 * by the client via the client capability `general.positionEncodings`.
	 *
	 * If the client didn't provide any position encodings the only valid
	 * value that a server can return is 'utf-16'.
	 *
	 * If omitted it defaults to 'utf-16'.
	 *
	 * @since 3.17.0
	 */
	positionEncoding?: PositionEncodingKind;

	/**
	 * Defines how text documents are synced. Is either a detailed structure
	 * defining each notification or for backwards compatibility the
	 * TextDocumentSyncKind number. If omitted it defaults to
	 * `TextDocumentSyncKind.None`.
	 */
	textDocumentSync?: TextDocumentSyncOptions | TextDocumentSyncKind;

	/**
	 * Defines how notebook documents are synced.
	 *
	 * @since 3.17.0
	 */
	notebookDocumentSync?: NotebookDocumentSyncOptions
		| NotebookDocumentSyncRegistrationOptions;

	/**
	 * The server provides completion support.
	 */
	completionProvider?: CompletionOptions;

	/**
	 * The server provides hover support.
	 */
	hoverProvider?: boolean | HoverOptions;

	/**
	 * The server provides signature help support.
	 */
	signatureHelpProvider?: SignatureHelpOptions;

	/**
	 * The server provides go to declaration support.
	 *
	 * @since 3.14.0
	 */
	declarationProvider?: boolean | DeclarationOptions
		| DeclarationRegistrationOptions;

	/**
	 * The server provides goto definition support.
	 */
	definitionProvider?: boolean | DefinitionOptions;

	/**
	 * The server provides goto type definition support.
	 *
	 * @since 3.6.0
	 */
	typeDefinitionProvider?: boolean | TypeDefinitionOptions
		| TypeDefinitionRegistrationOptions;

	/**
	 * The server provides goto implementation support.
	 *
	 * @since 3.6.0
	 */
	implementationProvider?: boolean | ImplementationOptions
		| ImplementationRegistrationOptions;

	/**
	 * The server provides find references support.
	 */
	referencesProvider?: boolean | ReferenceOptions;

	/**
	 * The server provides document highlight support.
	 */
	documentHighlightProvider?: boolean | DocumentHighlightOptions;

	/**
	 * The server provides document symbol support.
	 */
	documentSymbolProvider?: boolean | DocumentSymbolOptions;

	/**
	 * The server provides code actions. The `CodeActionOptions` return type is
	 * only valid if the client signals code action literal support via the
	 * property `textDocument.codeAction.codeActionLiteralSupport`.
	 */
	codeActionProvider?: boolean | CodeActionOptions;

	/**
	 * The server provides code lens.
	 */
	codeLensProvider?: CodeLensOptions;

	/**
	 * The server provides document link support.
	 */
	documentLinkProvider?: DocumentLinkOptions;

	/**
	 * The server provides color provider support.
	 *
	 * @since 3.6.0
	 */
	colorProvider?: boolean | DocumentColorOptions
		| DocumentColorRegistrationOptions;

	/**
	 * The server provides document formatting.
	 */
	documentFormattingProvider?: boolean | DocumentFormattingOptions;

	/**
	 * The server provides document range formatting.
	 */
	documentRangeFormattingProvider?: boolean | DocumentRangeFormattingOptions;

	/**
	 * The server provides document formatting on typing.
	 */
	documentOnTypeFormattingProvider?: DocumentOnTypeFormattingOptions;

	/**
	 * The server provides rename support. RenameOptions may only be
	 * specified if the client states that it supports
	 * `prepareSupport` in its initial `initialize` request.
	 */
	renameProvider?: boolean | RenameOptions;

	/**
	 * The server provides folding provider support.
	 *
	 * @since 3.10.0
	 */
	foldingRangeProvider?: boolean | FoldingRangeOptions
		| FoldingRangeRegistrationOptions;

	/**
	 * The server provides execute command support.
	 */
	executeCommandProvider?: ExecuteCommandOptions;

	/**
	 * The server provides selection range support.
	 *
	 * @since 3.15.0
	 */
	selectionRangeProvider?: boolean | SelectionRangeOptions
		| SelectionRangeRegistrationOptions;

	/**
	 * The server provides linked editing range support.
	 *
	 * @since 3.16.0
	 */
	linkedEditingRangeProvider?: boolean | LinkedEditingRangeOptions
		| LinkedEditingRangeRegistrationOptions;

	/**
	 * The server provides call hierarchy support.
	 *
	 * @since 3.16.0
	 */
	callHierarchyProvider?: boolean | CallHierarchyOptions
		| CallHierarchyRegistrationOptions;

	/**
	 * The server provides semantic tokens support.
	 *
	 * @since 3.16.0
	 */
	semanticTokensProvider?: SemanticTokensOptions
		| SemanticTokensRegistrationOptions;

	/**
	 * Whether server provides moniker support.
	 *
	 * @since 3.16.0
	 */
	monikerProvider?: boolean | MonikerOptions | MonikerRegistrationOptions;

	/**
	 * The server provides type hierarchy support.
	 *
	 * @since 3.17.0
	 */
	typeHierarchyProvider?: boolean | TypeHierarchyOptions
		 | TypeHierarchyRegistrationOptions;

	/**
	 * The server provides inline values.
	 *
	 * @since 3.17.0
	 */
	inlineValueProvider?: boolean | InlineValueOptions
		 | InlineValueRegistrationOptions;

	/**
	 * The server provides inlay hints.
	 *
	 * @since 3.17.0
	 */
	inlayHintProvider?: boolean | InlayHintOptions
		 | InlayHintRegistrationOptions;

	/**
	 * The server has support for pull model diagnostics.
	 *
	 * @since 3.17.0
	 */
	diagnosticProvider?: DiagnosticOptions | DiagnosticRegistrationOptions;

	/**
	 * The server provides workspace symbol support.
	 */
	workspaceSymbolProvider?: boolean | WorkspaceSymbolOptions;

	/**
	 * The server provides inline completions.
	 *
	 * @since 3.18.0
	 */
	inlineCompletionProvider?: boolean | InlineCompletionOptions;

	/**
	 * Text document specific server capabilities.
	 *
	 * @since 3.18.0
	 */
	textDocument?: {
		/**
		 * Capabilities specific to the diagnostic pull model.
		 *
		 * @since 3.18.0
		 */
		diagnostic?: {
			/**
			 * Whether the server supports `MarkupContent` in diagnostic messages.
			 *
			 * @since 3.18.0
			 * @proposed
			 */
			markupMessageSupport?: boolean;
		};
	};

	/**
	 * Workspace specific server capabilities
	 */
	workspace?: {
		/**
		 * The server supports workspace folder.
		 *
		 * @since 3.6.0
		 */
		workspaceFolders?: WorkspaceFoldersServerCapabilities;

		/**
		 * The server is interested in file notifications/requests.
		 *
		 * @since 3.16.0
		 */
		fileOperations?: {
			/**
			 * The server is interested in receiving didCreateFiles
			 * notifications.
			 */
			didCreate?: FileOperationRegistrationOptions;

			/**
			 * The server is interested in receiving willCreateFiles requests.
			 */
			willCreate?: FileOperationRegistrationOptions;

			/**
			 * The server is interested in receiving didRenameFiles
			 * notifications.
			 */
			didRename?: FileOperationRegistrationOptions;

			/**
			 * The server is interested in receiving willRenameFiles requests.
			 */
			willRename?: FileOperationRegistrationOptions;

			/**
			 * The server is interested in receiving didDeleteFiles file
			 * notifications.
			 */
			didDelete?: FileOperationRegistrationOptions;

			/**
			 * The server is interested in receiving willDeleteFiles file
			 * requests.
			 */
			willDelete?: FileOperationRegistrationOptions;
		};
	};

	/**
	 * Experimental server capabilities.
	 */
	experimental?: LSPAny;
}

已初始化通知 (➡️)

在客户端收到 initialize 请求的结果之后,但在客户端向服务器发送任何其他请求或通知之前,客户端向服务器发送 initialized 通知。服务器可以使用 initialized 通知,例如,动态注册能力。initialized 通知只能发送一次。

通知:

  • 方法:'initialized'
  • 参数:定义如下的 InitializedParams
interface InitializedParams {
}

注册能力 (↪️)

client/registerCapability 请求从服务器发送到客户端,用于在客户端注册新能力。并非所有客户端都需要支持动态能力注册。客户端通过特定客户端能力上的 dynamicRegistration 属性选择加入。客户端甚至可以为能力 A 提供动态注册,但不能为能力 B 提供动态注册(例如,参见 TextDocumentClientCapabilities)。

服务器不得通过初始化结果静态注册相同的功能,也不得为相同的文档选择器动态注册。如果服务器希望同时支持静态和动态注册,它需要检查初始化请求中的客户端功能,并且仅当客户端不支持该功能的动态注册时才静态注册该功能。

请求:

  • 方法:'client/registerCapability'
  • 参数:RegistrationParams

其中 RegistrationParams 定义如下

/**
 * General parameters to register for a capability.
 */
export interface Registration {
	/**
	 * The id used to register the request. The id can be used to deregister
	 * the request again.
	 */
	id: string;

	/**
	 * The method / capability to register for.
	 */
	method: string;

	/**
	 * Options necessary for the registration.
	 */
	registerOptions?: LSPAny;
}
export interface RegistrationParams {
	registrations: Registration[];
}

由于大多数注册选项需要指定文档选择器,因此可以使用一个基础接口。请参见 TextDocumentRegistrationOptions。

在客户端动态注册 textDocument/willSaveWaitUntil 功能的 JSON-RPC 消息示例如下(仅显示详细信息):

{
	"method": "client/registerCapability",
	"params": {
		"registrations": [
			{
				"id": "79eee87c-c409-4664-8102-e03263673f6f",
				"method": "textDocument/willSaveWaitUntil",
				"registerOptions": {
					"documentSelector": [
						{ "language": "javascript" }
					]
				}
			}
		]
	}
}

此消息从服务器发送到客户端,客户端成功执行请求后,针对 JavaScript 文本文档的后续 textDocument/willSaveWaitUntil 请求将从客户端发送到服务器。

Response:

  • 结果:无。
  • 错误:在请求期间发生异常时设置的代码和消息。

StaticRegistrationOptions 可用于在初始化结果中注册具有给定服务器控制 ID 的功能,以便稍后能够注销该功能。

/**
 * Static registration options to be returned in the initialize request.
 */
export interface StaticRegistrationOptions {
	/**
	 * The id used to register the request. The id can be used to deregister
	 * the request again. See also Registration#id.
	 */
	id?: string;
}

TextDocumentRegistrationOptions 可用于为一组文本文档动态注册请求。

/**
 * General text document registration options.
 */
export interface TextDocumentRegistrationOptions {
	/**
	 * A document selector to identify the scope of the registration. If set to
	 * null, the document selector provided on the client side will be used.
	 */
	documentSelector: DocumentSelector | null;
}

注销能力 (↪️)

client/unregisterCapability 请求从服务器发送到客户端,用于注销之前已注册的能力。

请求:

  • 方法:'client/unregisterCapability'
  • 参数:UnregistrationParams

其中 UnregistrationParams 定义如下

/**
 * General parameters to unregister a capability.
 */
export interface Unregistration {
	/**
	 * The id used to unregister the request or notification. Usually an id
	 * provided during the register request.
	 */
	id: string;

	/**
	 * The method / capability to unregister for.
	 */
	method: string;
}
export interface UnregistrationParams {
	// This should correctly be named `unregistrations`. However, changing this
	// is a breaking change and needs to wait until we deliver a 4.x version
	// of the specification.
	unregisterations: Unregistration[];
}

注销上述已注册的 textDocument/willSaveWaitUntil 功能的 JSON-RPC 消息示例如下:

{
	"method": "client/unregisterCapability",
	"params": {
		"unregisterations": [
			{
				"id": "79eee87c-c409-4664-8102-e03263673f6f",
				"method": "textDocument/willSaveWaitUntil"
			}
		]
	}
}

Response:

  • 结果:无。
  • 错误:在请求期间发生异常时设置的代码和消息。

设置追踪通知 (➡️)

一个应由客户端用于修改服务器跟踪设置的通知。

通知:

  • 方法:'$/setTrace'
  • 参数:定义如下的 SetTraceParams
interface SetTraceParams {
	/**
	 * The new value that should be assigned to the trace setting.
	 */
	value: TraceValue;
}

LogTrace 通知 (⬅️)

一个用于记录服务器执行轨迹的通知。这些通知的数量和内容取决于当前的 trace 配置。如果 trace 为 'off',服务器不应发送任何 logTrace 通知。如果 trace 为 'messages',服务器不应在 LogTraceParams 中添加 'verbose' 字段。

$/logTrace 应该用于系统性的跟踪报告。对于单个调试消息,服务器应该发送 window/logMessage 通知。

通知:

  • 方法:'$/logTrace'
  • 参数:定义如下的 LogTraceParams
interface LogTraceParams {
	/**
	 * The message to be logged.
	 */
	message: string;
	/**
	 * Additional information that can be computed if the `trace` configuration
	 * is set to `'verbose'`.
	 */
	verbose?: string;
}

关闭请求 (↩️)

关机请求从客户端发送到服务器。它要求服务器关机,但不要退出(否则响应可能无法正确传递给客户端)。有一个单独的退出通知要求服务器退出。客户端不得向已发送关机请求的服务器发送除 exit 之外的任何请求或通知。客户端也应等到收到 shutdown 请求的响应后才发送 exit 通知。

如果服务器在关闭请求后收到请求,则这些请求应以 InvalidRequest 错误。

请求:

  • 方法:'shutdown'
  • 参数:无

Response:

  • 结果:null
  • 错误:在关闭请求期间发生异常时设置的代码和消息。

退出通知 (➡️)

通知服务器退出其进程。如果之前已收到关闭请求,服务器应以 success 代码 0 退出;否则以 error 代码 1 退出。

通知:

  • 方法:'exit'
  • 参数:无

文本文档同步

客户端对 textDocument/didOpen、textDocument/didChange 和 textDocument/didClose 通知的支持在协议中是强制性的,客户端不能选择不支持它们。这包括 textDocument/didChange 通知中的完整和增量同步。此外,服务器必须同时实现这三者或都不实现。因此,它们的功能通过组合的客户端和服务器能力进行控制。放弃文本文档同步只有在客户端显示的文档是只读时才有意义。否则,服务器可能会收到对文档的请求,而这些文档的内容是由客户端管理的(例如,它们可能已更改)。

客户端能力:

  • 属性路径(可选):textDocument.synchronization.dynamicRegistration
  • 属性类型:boolean

控制文本文档同步是否支持动态注册。

服务器能力:

  • 属性路径(可选):textDocumentSync
  • 属性类型:TextDocumentSyncKind | TextDocumentSyncOptions。下面 TextDocumentSyncOptions 的定义仅涵盖打开、更改和关闭通知的特定属性。涵盖所有属性的完整定义可在此处找到
/**
 * Defines how the host (editor) should sync document changes to the language
 * server.
 */
export namespace TextDocumentSyncKind {
	/**
	 * Documents should not be synced at all.
	 */
	export const None = 0;

	/**
	 * Documents are synced by always sending the full content
	 * of the document.
	 */
	export const Full = 1;

	/**
	 * Documents are synced by sending the full content on open.
	 * After that only incremental updates to the document are
	 * sent.
	 */
	export const Incremental = 2;
}

export type TextDocumentSyncKind = 0 | 1 | 2;
export interface TextDocumentSyncOptions {
	/**
	 * Open and close notifications are sent to the server. If omitted open
	 * close notifications should not be sent.
	 */
	openClose?: boolean;

	/**
	 * Change notifications are sent to the server. See
	 * TextDocumentSyncKind.None, TextDocumentSyncKind.Full and
	 * TextDocumentSyncKind.Incremental. If omitted it defaults to
	 * TextDocumentSyncKind.None.
	 */
	change?: TextDocumentSyncKind;
}

DidOpenTextDocument 通知 (➡️)

文档打开通知从客户端发送到服务器,以指示新打开的文本文档。文档内容现在由客户端管理,服务器不得尝试使用文档的 Uri 读取文档内容。在此意义上的“打开”表示它由客户端管理。这不一定意味着其内容在编辑器中显示。在没有对应的关闭通知之前,打开通知不能发送多次。这意味着打开和关闭通知必须平衡,并且特定 textDocument 的最大打开次数为一次。请注意,服务器满足请求的能力与文本文档是打开还是关闭无关。

DidOpenTextDocumentParams 包含文档关联的语言 ID。如果文档的语言 ID 更改,客户端需要向服务器发送 textDocument/didClose,然后发送 textDocument/didOpen 并附带新的语言 ID,前提是服务器也处理新的语言 ID。

客户端能力:请参阅通用同步客户端能力。

服务器能力:请参阅通用同步服务器能力。

注册选项:TextDocumentRegistrationOptions

通知:

  • 方法:'textDocument/didOpen'
  • 参数:DidOpenTextDocumentParams 定义如下
interface DidOpenTextDocumentParams {
	/**
	 * The document that was opened.
	 */
	textDocument: TextDocumentItem;
}

DidChangeTextDocument 通知 (:arrow_right:)

文档变更通知从客户端发送到服务器,以指示文本文档的变更。在客户端可以更改文本文档之前,它必须使用 textDocument/didOpen 通知声明对其内容的拥有权。在 2.0 中,参数的形状已更改为包含正确的版本号。

在向服务器请求信息(例如,textDocument/completion 或 textDocument/signatureHelp)之前,客户端必须确保文档的状态与服务器同步,以保证可靠的结果。

以下示例展示了当用户连续输入时客户端应如何同步状态,假设用户输入触发了 textDocument/completion

文档版本 用户输入 客户端行为 请求
5 文档变更一 将文档 v5 同步到服务器 textDocument/didChange
5 - 根据文档 v5 从服务器请求 textDocument/completion
6 文档变更二 将文档 v6 同步到服务器 textDocument/didChange

客户端能力:请参阅通用同步客户端能力。

服务器能力:请参阅通用同步服务器能力。

注册选项:TextDocumentChangeRegistrationOptions 定义如下

/**
 * Describe options to be used when registering for text document change events.
 */
export interface TextDocumentChangeRegistrationOptions
	extends TextDocumentRegistrationOptions {
	/**
	 * How documents are synced to the server. See TextDocumentSyncKind.Full
	 * and TextDocumentSyncKind.Incremental.
	 */
	syncKind: TextDocumentSyncKind;
}

通知:

  • 方法:textDocument/didChange
  • 参数:DidChangeTextDocumentParams 定义如下
interface DidChangeTextDocumentParams {
	/**
	 * The document that did change. The version number points
	 * to the version after all provided content changes have
	 * been applied.
	 */
	textDocument: VersionedTextDocumentIdentifier;

	/**
	 * The actual content changes. The content changes describe single state
	 * changes to the document. So if there are two content changes c1 (at
	 * array index 0) and c2 (at array index 1) for a document in state S then
	 * c1 moves the document from S to S' and c2 from S' to S''. So c1 is
	 * computed on the state S and c2 is computed on the state S'.
	 *
	 * To mirror the content of a document using change events use the following
	 * approach:
	 * - start with the same initial content
	 * - apply the 'textDocument/didChange' notifications in the order you
	 *   receive them.
	 * - apply the `TextDocumentContentChangeEvent`s in a single notification
	 *   in the order you receive them.
	 */
	contentChanges: TextDocumentContentChangeEvent[];
}
/**
 * An event describing a change to a text document. If only a text is provided
 * it is considered to be the full content of the document.
 */
export type TextDocumentContentChangeEvent = {
	/**
	 * The range of the document that changed.
	 */
	range: Range;

	/**
	 * The optional length of the range that got replaced.
	 *
	 * @deprecated use range instead.
	 */
	rangeLength?: uinteger;

	/**
	 * The new text for the provided range.
	 */
	text: string;
} | {
	/**
	 * The new text of the whole document.
	 */
	text: string;
};

WillSaveTextDocument 通知 (:arrow_right:)

文档将要保存通知在文档实际保存之前从客户端发送到服务器。如果服务器已注册开放/关闭事件,客户端应确保在发送 willSave 通知之前文档已打开,因为客户端无法在不进行所有权转移的情况下更改文件内容。

客户端能力:

  • 属性名称(可选):textDocument.synchronization.willSave
  • 属性类型:boolean

此功能表示客户端支持 textDocument/willSave 通知。

服务器能力:

  • 属性名称(可选):textDocumentSync.willSave
  • 属性类型:boolean

此功能表示服务器对 textDocument/willSave 通知感兴趣。

注册选项:TextDocumentRegistrationOptions

通知:

  • 方法:‘textDocument/willSave’
  • 参数:WillSaveTextDocumentParams 定义如下
/**
 * The parameters send in a will save text document notification.
 */
export interface WillSaveTextDocumentParams {
	/**
	 * The document that will be saved.
	 */
	textDocument: TextDocumentIdentifier;

	/**
	 * The 'TextDocumentSaveReason'.
	 */
	reason: TextDocumentSaveReason;
}
/**
 * Represents reasons why a text document is saved.
 */
export namespace TextDocumentSaveReason {

	/**
	 * Manually triggered, e.g. by the user pressing save, by starting
	 * debugging, or by an API call.
	 */
	export const Manual = 1;

	/**
	 * Automatic after a delay.
	 */
	export const AfterDelay = 2;

	/**
	 * When the editor lost focus.
	 */
	export const FocusOut = 3;
}

export type TextDocumentSaveReason = 1 | 2 | 3;

WillSaveWaitUntilTextDocument 请求 (:leftwards_arrow_with_hook:)

文档将要保存请求在文档实际保存之前从客户端发送到服务器。该请求可以返回一个 TextEdit 数组,该数组将在文档保存之前应用于文本文档。请注意,如果计算文本编辑花费太长时间或服务器在此请求上持续失败,客户端可能会丢弃结果。这样做是为了使保存快速可靠。如果服务器已注册开放/关闭事件,客户端应确保在发送 willSaveWaitUntil 通知之前文档已打开,因为客户端无法在不进行所有权转移的情况下更改文件内容。

客户端能力:

  • 属性名称(可选):textDocument.synchronization.willSaveWaitUntil
  • 属性类型:boolean

此功能表示客户端支持 textDocument/willSaveWaitUntil 请求。

服务器能力:

  • 属性名称(可选):textDocumentSync.willSaveWaitUntil
  • 属性类型:boolean

此功能表示服务器对 textDocument/willSaveWaitUntil 请求感兴趣。

注册选项:TextDocumentRegistrationOptions

请求:

  • 方法:textDocument/willSaveWaitUntil
  • 参数:WillSaveTextDocumentParams

Response:

  • 结果:TextEdit[] | null
  • 错误:在 textDocument/willSaveWaitUntil 请求期间发生异常时设置的代码和消息。

DidSaveTextDocument 通知 (:arrow_right:)

文档保存通知从客户端发送到服务器,当文档在客户端保存时。

客户端能力:

  • 属性名称(可选):textDocument.synchronization.didSave
  • 属性类型:boolean

此功能表示客户端支持 textDocument/didSave 通知。

服务器能力:

  • 属性名称(可选):textDocumentSync.save
  • 属性类型:boolean | SaveOptions,其中 SaveOptions 定义如下
export interface SaveOptions {
	/**
	 * The client is supposed to include the content on save.
	 */
	includeText?: boolean;
}

此功能表示服务器对 textDocument/didSave 通知感兴趣。

注册选项:TextDocumentSaveRegistrationOptions 定义如下

export interface TextDocumentSaveRegistrationOptions
	extends TextDocumentRegistrationOptions {
	/**
	 * The client is supposed to include the content on save.
	 */
	includeText?: boolean;
}

通知:

  • 方法:textDocument/didSave
  • 参数:DidSaveTextDocumentParams 定义如下
interface DidSaveTextDocumentParams {
	/**
	 * The document that was saved.
	 */
	textDocument: TextDocumentIdentifier;

	/**
	 * Optional the content when saved. Depends on the includeText value
	 * when the save notification was requested.
	 */
	text?: string;
}

DidCloseTextDocument 通知 (:arrow_right:)

文档关闭通知从客户端发送到服务器,当文档在客户端关闭时。文档的主副本现在存在于文档 Uri 指向的位置(例如,如果文档 Uri 是文件 Uri,则主副本现在存在于磁盘上)。与打开通知一样,关闭通知是关于管理文档内容的。收到关闭通知并不意味着文档以前在编辑器中打开过。关闭通知需要先发送打开通知。请注意,服务器执行请求的能力与文本文档是打开还是关闭无关。

客户端能力:请参阅通用同步客户端能力。

服务器能力:请参阅通用同步服务器能力。

注册选项:TextDocumentRegistrationOptions

通知:

  • 方法:textDocument/didClose
  • 参数:DidCloseTextDocumentParams 定义如下
interface DidCloseTextDocumentParams {
	/**
	 * The document that was closed.
	 */
	textDocument: TextDocumentIdentifier;
}

重命名文档

文档重命名应通过向服务器发送带有文档旧名称的关闭通知,然后使用文档的新名称发送打开通知来通知服务器。主要原因是除了名称之外,其他属性也可能发生变化,例如与文档关联的语言。此外,新文档可能不再对服务器感兴趣。

服务器可以通过订阅 workspace/didRenameFiles 通知或 workspace/willRenameFiles 请求来参与文档重命名。

TextDocumentSyncClientCapabilities 和 TextDocumentSyncOptions 服务器选项的最终结构如下所示

export interface TextDocumentSyncClientCapabilities {
	/**
	 * Whether text document synchronization supports dynamic registration.
	 */
	dynamicRegistration?: boolean;

	/**
	 * The client supports sending will save notifications.
	 */
	willSave?: boolean;

	/**
	 * The client supports sending a will save request and
	 * waits for a response providing text edits which will
	 * be applied to the document before it is saved.
	 */
	willSaveWaitUntil?: boolean;

	/**
	 * The client supports did save notifications.
	 */
	didSave?: boolean;
}
export interface TextDocumentSyncOptions {
	/**
	 * Open and close notifications are sent to the server. If omitted open
	 * close notification should not be sent.
	 */
	openClose?: boolean;
	/**
	 * Change notifications are sent to the server. See
	 * TextDocumentSyncKind.None, TextDocumentSyncKind.Full and
	 * TextDocumentSyncKind.Incremental. If omitted it defaults to
	 * TextDocumentSyncKind.None.
	 */
	change?: TextDocumentSyncKind;
	/**
	 * If present will save notifications are sent to the server. If omitted
	 * the notification should not be sent.
	 */
	willSave?: boolean;
	/**
	 * If present will save wait until requests are sent to the server. If
	 * omitted the request should not be sent.
	 */
	willSaveWaitUntil?: boolean;
	/**
	 * If present save notifications are sent to the server. If omitted the
	 * notification should not be sent.
	 */
	save?: boolean | SaveOptions;
}

笔记本文档同步

笔记本越来越受欢迎。将它们的支持添加到语言服务器协议中,允许笔记本编辑器在笔记本或笔记本单元格中分别重用服务器提供的语言智能。为了重用协议部分和服务器实现,笔记本在 LSP 中以以下方式建模:

  • 笔记本文档:通常存储在磁盘文件中的笔记本单元格集合。笔记本文档具有类型,并可以使用资源 URI 唯一标识。
  • 笔记本单元格:包含实际的文本内容。单元格具有类型(代码或 Markdown)。单元格的实际文本内容存储在文本文档中,可以像所有其他文本文档一样同步到服务器。单元格文本文档具有 URI,但服务器不应依赖此 URI 的任何格式,因为如何创建这些 URI 由客户端决定。这些 URI 必须在所有笔记本单元格中都是唯一的,因此可以用于唯一标识笔记本单元格或单元格的文本文档。

这两个概念定义如下:

/**
 * A notebook document.
 *
 * @since 3.17.0
 */
export interface NotebookDocument {

	/**
	 * The notebook document's URI.
	 */
	uri: URI;

	/**
	 * The type of the notebook.
	 */
	notebookType: string;

	/**
	 * The version number of this document (it will increase after each
	 * change, including undo/redo).
	 */
	version: integer;

	/**
	 * Additional metadata stored with the notebook
	 * document.
	 */
	metadata?: LSPObject;

	/**
	 * The cells of a notebook.
	 */
	cells: NotebookCell[];
}
/**
 * A notebook cell.
 *
 * A cell's document URI must be unique across ALL notebook
 * cells and can therefore be used to uniquely identify a
 * notebook cell or the cell's text document.
 *
 * @since 3.17.0
 */
export interface NotebookCell {

	/**
	 * The cell's kind.
	 */
	kind: NotebookCellKind;

	/**
	 * The URI of the cell's text document
	 * content.
	 */
	document: DocumentUri;

	/**
	 * Additional metadata stored with the cell.
	 */
	metadata?: LSPObject;

	/**
	 * Additional execution summary information
	 * if supported by the client.
	 */
	executionSummary?: ExecutionSummary;
}
/**
 * A notebook cell kind.
 *
 * @since 3.17.0
 */
export namespace NotebookCellKind {

	/**
	 * A markup-cell is a formatted source that is used for display.
	 */
	export const Markup: 1 = 1;

	/**
	 * A code-cell is source code.
	 */
	export const Code: 2 = 2;
}
export interface ExecutionSummary {
	/**
	 * A strictly monotonically increasing value
	 * indicating the execution order of a cell
	 * inside a notebook.
	 */
	executionOrder: uinteger;

	/**
	 * Whether the execution was successful or
	 * not if known by the client.
	 */
	success?: boolean;
}

接下来我们描述如何将笔记本、笔记本单元格和笔记本单元格的内容同步到语言服务器。

同步单元格的文本内容相对容易,因为客户端应将其建模为文本文档。然而,由于笔记本单元格的文本文档的 URI 应该是透明的,服务器无法知道其方案或路径。已知的是笔记本文档本身。因此,我们引入了一个特殊的笔记本单元格文档过滤器:

/**
 * A notebook cell text document filter denotes a cell text
 * document by different properties.
 *
 * @since 3.17.0
 */
export interface NotebookCellTextDocumentFilter {
	/**
	 * A filter that matches against the notebook
	 * containing the notebook cell. If a string
	 * value is provided, it matches against the
	 * notebook type. '*' matches every notebook.
	 */
	notebook: string | NotebookDocumentFilter;

	/**
	 * A language ID like `python`.
	 *
	 * Will be matched against the language ID of the
	 * notebook cell document. '*' matches every language.
	 */
	language?: string;
}
/**
 * A notebook document filter denotes a notebook document by
 * different properties.
 *
 * @since 3.17.0
 */
export type NotebookDocumentFilter = {
	/**
	 * The type of the enclosing notebook.
	 */
	notebookType: string;

	/**
	 * A Uri scheme, like `file` or `untitled`.
    */
	scheme?: string;

	/**
	 * A glob pattern.
	 */
	pattern?: GlobPattern;
} | {
	/**
	 * The type of the enclosing notebook.
	 */
	notebookType?: string;

	/**
	 * A Uri scheme, like `file` or `untitled`.
	 */
	scheme: string;

	/**
	 * A glob pattern.
	 */
	pattern?: GlobPattern;
} | {
	/**
	 * The type of the enclosing notebook.
	 */
	notebookType?: string;

	/**
	 * A Uri scheme, like `file` or `untitled`.
	 */
	scheme?: string;

	/**
	 * A glob pattern.
	 */
	pattern: GlobPattern;
};

给定这些结构,存储在磁盘上路径中包含 books1 文件夹的 Jupyter 笔记本中的 Python 单元格文档可以如下标识:

{
	notebook: {
		scheme: 'file',
		pattern: '**/books1/**',
		notebookType: 'jupyter-notebook'
	},
	language: 'python'
}

NotebookCellTextDocumentFilter 可用于注册某些请求(如代码补全或悬停)的提供程序。如果注册了此类提供程序,客户端将使用单元格文本文档的 URI 作为文档 URI,向服务器发送相应的 textDocument/* 请求。

在某些情况下,仅了解单元格的文本内容不足以让服务器理解单元格内容并提供良好的语言智能。有时有必要了解笔记本文档的所有单元格,包括笔记本文档本身。考虑一个包含两个 JavaScript 单元格的笔记本,其内容如下:

单元格一

function add(a, b) {
	return a + b;
}

单元格二

add/*<cursor>*/;

在单元格二标记的光标位置请求代码辅助应该建议函数 add,这只有在服务器知道单元格一和单元格二并知道它们属于同一个笔记本文档时才可能实现。

因此,协议将支持两种同步单元格文本内容的模式:

  • 单元格内容:在此模式下,仅使用标准 textDocument/did* 通知将单元格文本内容同步到服务器。不同步笔记本文档和单元格结构。此模式允许轻松采用笔记本,因为服务器可以重用其大部分实现逻辑。
  • 笔记本:在此模式下,笔记本文档、笔记本单元格和笔记本单元格文本内容都同步到服务器。为了让服务器能够创建笔记本文档的一致视图,单元格文本内容不使用标准的 textDocument/did* 通知进行同步。而是使用特殊的 notebookDocument/did* 通知进行同步。这确保了单元格及其文本内容通过一个打开、更改或关闭事件到达服务器。

要请求单元格内容,只能使用普通的文档选择器。例如,选择器 [{ language: 'python' }] 将 Python 笔记本文档单元格同步到服务器。但是,由于这可能也会同步不需要的文档,因此文档过滤器也可以是 NotebookCellTextDocumentFilter。因此,{ notebook: { scheme: 'file', notebookType: 'jupyter-notebook' }, language: 'python' } 将 Jupyter 笔记本中存储在磁盘上的所有 Python 单元格同步。

要同步整个笔记本文档,服务器在其服务器能力中提供 notebookDocumentSync。例如:

{
	notebookDocumentSync: {
		notebookSelector: [
			{
				notebook: { scheme: 'file', notebookType: 'jupyter-notebook' },
				cells: [{ language: 'python' }]
			}
		]
	}
}

如果笔记本存储在磁盘上,则将笔记本(包括所有 Python 单元格)同步到服务器。

客户端能力:

为笔记本文档定义了以下客户端功能:

  • 属性名称(可选):notebookDocument.synchronization
  • 属性类型:NotebookDocumentSyncClientCapabilities,定义如下:
/**
 * Notebook specific client capabilities.
 *
 * @since 3.17.0
 */
export interface NotebookDocumentSyncClientCapabilities {

	/**
	 * Whether implementation supports dynamic registration. If this is
	 * set to `true`, the client supports the new
	 * `(NotebookDocumentSyncRegistrationOptions & NotebookDocumentSyncOptions)`
	 * return value for the corresponding server capability as well.
	 */
	dynamicRegistration?: boolean;

	/**
	 * The client supports sending execution summary data per cell.
	 */
	executionSummarySupport?: boolean;
}

服务器能力:

为笔记本文档定义了以下服务器功能:

  • 属性名称(可选):notebookDocumentSync
  • 属性类型:NotebookDocumentSyncOptions | NotebookDocumentSyncRegistrationOptions,其中 NotebookDocumentOptions 定义如下:
/**
 * Options specific to a notebook plus its cells
 * to be synced to the server.
 *
 * If a selector provides a notebook document
 * filter but no cell selector, all cells of a
 * matching notebook document will be synced.
 *
 * If a selector provides no notebook document
 * filter but only a cell selector, all notebook
 * documents that contain at least one matching
 * cell will be synced.
 *
 * @since 3.17.0
 */
export interface NotebookDocumentSyncOptions {
	/**
	 * The notebooks to be synced
	 */
	notebookSelector: ({
		/**
		 * The notebook to be synced. If a string
		 * value is provided, it matches against the
		 * notebook type. '*' matches every notebook.
		 */
		notebook: string | NotebookDocumentFilter;

		/**
		 * The cells of the matching notebook to be synced.
		 */
		cells?: { language: string }[];
	} | {
		/**
		 * The notebook to be synced. If a string
		 * value is provided, it matches against the
		 * notebook type. '*' matches every notebook.
		 */
		notebook?: string | NotebookDocumentFilter;

		/**
		 * The cells of the matching notebook to be synced.
		 */
		cells: { language: string }[];
	})[];

	/**
	 * Whether save notifications should be forwarded to
	 * the server. Will only be honored if mode === `notebook`.
	 */
	save?: boolean;
}

注册选项:notebookDocumentSyncRegistrationOptions,定义如下:

/**
 * Registration options specific to a notebook.
 *
 * @since 3.17.0
 */
export interface NotebookDocumentSyncRegistrationOptions extends
	NotebookDocumentSyncOptions, StaticRegistrationOptions {
}

DidOpenNotebookDocument 通知 (:arrow_right:)

当笔记本文档打开时,客户端向服务器发送打开通知。仅当服务器在其 notebookDocumentSync 能力中请求了同步模式 notebook 时,客户端才发送此通知。

通知:

  • 方法:notebookDocument/didOpen
  • 参数:DidOpenNotebookDocumentParams,定义如下:
/**
 * The params sent in an open notebook document notification.
 *
 * @since 3.17.0
 */
export interface DidOpenNotebookDocumentParams {

	/**
	 * The notebook document that got opened.
	 */
	notebookDocument: NotebookDocument;

	/**
	 * The text documents that represent the content
	 * of a notebook cell.
	 */
	cellTextDocuments: TextDocumentItem[];
}

DidChangeNotebookDocument 通知 (:arrow_right:)

当笔记本文档更改时,客户端向服务器发送更改通知。仅当服务器在其 notebookDocumentSync 能力中请求了同步模式 notebook 时,客户端才发送此通知。

通知:

  • 方法:notebookDocument/didChange
  • 参数:DidChangeNotebookDocumentParams,定义如下:
/**
 * The params sent in a change notebook document notification.
 *
 * @since 3.17.0
 */
export interface DidChangeNotebookDocumentParams {

	/**
	 * The notebook document that did change. The version number points
	 * to the version after all provided changes have been applied.
	 */
	notebookDocument: VersionedNotebookDocumentIdentifier;

	/**
	 * The actual changes to the notebook document.
	 *
	 * The change describes a single state change to the notebook document,
	 * so it moves a notebook document, its cells and its cell text document
	 * contents from state S to S'.
	 *
	 * To mirror the content of a notebook using change events use the
	 * following approach:
	 * - start with the same initial content
	 * - apply the 'notebookDocument/didChange' notifications in the order
	 *   you receive them.
	 */
	change: NotebookDocumentChangeEvent;
}
/**
 * A versioned notebook document identifier.
 *
 * @since 3.17.0
 */
export interface VersionedNotebookDocumentIdentifier {

	/**
	 * The version number of this notebook document.
	 */
	version: integer;

	/**
	 * The notebook document's URI.
	 */
	uri: URI;
}
/**
 * A change event for a notebook document.
 *
 * @since 3.17.0
 */
export interface NotebookDocumentChangeEvent {
	/**
	 * The changed meta data if any.
	 */
	metadata?: LSPObject;

	/**
	 * Changes to cells.
	 */
	cells?: {
		/**
		 * Changes to the cell structure to add or
		 * remove cells.
		 */
		structure?: {
			/**
			 * The change to the cell array.
			 */
			array: NotebookCellArrayChange;

			/**
			 * Additional opened cell text documents.
			 */
			didOpen?: TextDocumentItem[];

			/**
			 * Additional closed cell text documents.
			 */
			didClose?: TextDocumentIdentifier[];
		};

		/**
		 * Changes to notebook cells properties like its
		 * kind, execution summary or metadata.
		 */
		data?: NotebookCell[];

		/**
		 * Changes to the text content of notebook cells.
		 */
		textContent?: {
			document: VersionedTextDocumentIdentifier;
			changes: TextDocumentContentChangeEvent[];
		}[];
	};
}
/**
 * A change describing how to move a `NotebookCell`
 * array from state S to S'.
 *
 * @since 3.17.0
 */
export interface NotebookCellArrayChange {
	/**
	 * The start offset of the cell that changed.
	 */
	start: uinteger;

	/**
	 * The number of deleted cells.
	 */
	deleteCount: uinteger;

	/**
	 * The new cells, if any.
	 */
	cells?: NotebookCell[];
}

DidSaveNotebookDocument 通知 (:arrow_right:)

当笔记本文档保存时,客户端向服务器发送保存通知。仅当服务器在其 notebookDocumentSync 能力中请求了同步模式 notebook 时,客户端才发送此通知。

通知:

  • 方法:notebookDocument/didSave
  • 参数:DidSaveNotebookDocumentParams,定义如下:
/**
 * The params sent in a save notebook document notification.
 *
 * @since 3.17.0
 */
export interface DidSaveNotebookDocumentParams {
	/**
	 * The notebook document that got saved.
	 */
	notebookDocument: NotebookDocumentIdentifier;
}

DidCloseNotebookDocument 通知 (:arrow_right:)

当笔记本文档关闭时,客户端向服务器发送关闭通知。仅当服务器在其 notebookDocumentSync 能力中请求了同步模式 notebook 时,客户端才发送此通知。

通知:

  • 方法:notebookDocument/didClose
  • 参数:DidCloseNotebookDocumentParams,定义如下:
/**
 * The params sent in a close notebook document notification.
 *
 * @since 3.17.0
 */
export interface DidCloseNotebookDocumentParams {

	/**
	 * The notebook document that got closed.
	 */
	notebookDocument: NotebookDocumentIdentifier;

	/**
	 * The text documents that represent the content
	 * of a notebook cell that got closed.
	 */
	cellTextDocuments: TextDocumentIdentifier[];
}
/**
 * A literal to identify a notebook document in the client.
 *
 * @since 3.17.0
 */
export interface NotebookDocumentIdentifier {
	/**
	 * The notebook document's URI.
	 */
	uri: URI;
}

语言特性

语言特性提供了语言服务器协议中实际的智能功能。它们通常在 [文本文档,位置] 元组上执行。主要的语言特性类别是:

  • 代码理解功能,如悬停或跳转到定义。
  • 编码功能,如诊断、代码补全或代码操作。

语言特性应在文档的同步状态上计算。

转到声明请求 (:leftwards_arrow_with_hook:)

自 3.14.0 版本起

转到声明请求从客户端发送到服务器,以解析给定文本文档位置处符号的声明位置。

结果类型 LocationLink[] 随 3.14.0 版本引入,并取决于相应的客户端功能 textDocument.declaration.linkSupport。

客户端能力:

  • 属性名称(可选):textDocument.declaration
  • 属性类型:DeclarationClientCapabilities 定义如下
export interface DeclarationClientCapabilities {
	/**
	 * Whether declaration supports dynamic registration. If this is set to
	 * `true`, the client supports the new `DeclarationRegistrationOptions`
	 * return value for the corresponding server capability as well.
	 */
	dynamicRegistration?: boolean;

	/**
	 * The client supports additional metadata in the form of declaration links.
	 */
	linkSupport?: boolean;
}

服务器能力:

  • 属性名称(可选):declarationProvider
  • 属性类型:boolean | DeclarationOptions | DeclarationRegistrationOptions,其中 DeclarationOptions 定义如下
export interface DeclarationOptions extends WorkDoneProgressOptions {
}

注册选项:DeclarationRegistrationOptions 定义如下

export interface DeclarationRegistrationOptions extends DeclarationOptions,
	TextDocumentRegistrationOptions, StaticRegistrationOptions {
}

请求:

  • 方法:textDocument/declaration
  • 参数:DeclarationParams 定义如下
export interface DeclarationParams extends TextDocumentPositionParams,
	WorkDoneProgressParams, PartialResultParams {
}

Response:

  • 结果:Location | Location[] | LocationLink[] |null
  • 部分结果:Location[] | LocationLink[]
  • 错误:如果在声明请求期间发生异常,则设置代码和消息。

转到定义请求 (:leftwards_arrow_with_hook:)

转到定义请求从客户端发送到服务器,以解析给定文本文档位置处符号的定义位置。

结果类型 LocationLink[] 随 3.14.0 版本引入,并取决于相应的客户端功能 textDocument.definition.linkSupport。

客户端能力:

  • 属性名称(可选):textDocument.definition
  • 属性类型:DefinitionClientCapabilities 定义如下
export interface DefinitionClientCapabilities {
	/**
	 * Whether definition supports dynamic registration.
	 */
	dynamicRegistration?: boolean;

	/**
	 * The client supports additional metadata in the form of definition links.
	 *
	 * @since 3.14.0
	 */
	linkSupport?: boolean;
}

服务器能力:

  • 属性名称(可选):definitionProvider
  • 属性类型:boolean | DefinitionOptions,其中 DefinitionOptions 定义如下
export interface DefinitionOptions extends WorkDoneProgressOptions {
}

注册选项:DefinitionRegistrationOptions 定义如下

export interface DefinitionRegistrationOptions extends
	TextDocumentRegistrationOptions, DefinitionOptions {
}

请求:

  • 方法:textDocument/definition
  • 参数:DefinitionParams 定义如下
export interface DefinitionParams extends TextDocumentPositionParams,
	WorkDoneProgressParams, PartialResultParams {
}

Response:

  • 结果:Location | Location[] | LocationLink[] | null
  • 部分结果:Location[] | LocationLink[]
  • 错误:如果在定义请求期间发生异常,则设置代码和消息。

转到类型定义请求 (:leftwards_arrow_with_hook:)

自 3.6.0 版本起

转到类型定义请求从客户端发送到服务器,以解析给定文本文档位置处符号的类型定义位置。

结果类型 LocationLink[] 随 3.14.0 版本引入,并取决于相应的客户端功能 textDocument.typeDefinition.linkSupport。

客户端能力:

  • 属性名称(可选):textDocument.typeDefinition
  • 属性类型:TypeDefinitionClientCapabilities 定义如下
export interface TypeDefinitionClientCapabilities {
	/**
	 * Whether implementation supports dynamic registration. If this is set to
	 * `true`, the client supports the new `TypeDefinitionRegistrationOptions`
	 * return value for the corresponding server capability as well.
	 */
	dynamicRegistration?: boolean;

	/**
	 * The client supports additional metadata in the form of definition links.
	 *
	 * @since 3.14.0
	 */
	linkSupport?: boolean;
}

服务器能力:

  • 属性名称(可选):typeDefinitionProvider
  • 属性类型:boolean | TypeDefinitionOptions | TypeDefinitionRegistrationOptions,其中 TypeDefinitionOptions 定义如下
export interface TypeDefinitionOptions extends WorkDoneProgressOptions {
}

注册选项:TypeDefinitionRegistrationOptions 定义如下

export interface TypeDefinitionRegistrationOptions extends
	TextDocumentRegistrationOptions, TypeDefinitionOptions,
	StaticRegistrationOptions {
}

请求:

  • 方法:textDocument/typeDefinition
  • 参数:TypeDefinitionParams 定义如下
export interface TypeDefinitionParams extends TextDocumentPositionParams,
	WorkDoneProgressParams, PartialResultParams {
}

Response:

  • 结果:Location | Location[] | LocationLink[] | null
  • 部分结果:Location[] | LocationLink[]
  • 错误:如果在定义请求期间发生异常,则设置代码和消息。

转到实现请求 (:leftwards_arrow_with_hook:)

自 3.6.0 版本起

转到实现请求从客户端发送到服务器,以解析给定文本文档位置处符号的实现位置。

结果类型 LocationLink[] 随 3.14.0 版本引入,并取决于相应的客户端功能 textDocument.implementation.linkSupport。

客户端能力:

  • 属性名称(可选):textDocument.implementation
  • 属性类型:ImplementationClientCapabilities 定义如下
export interface ImplementationClientCapabilities {
	/**
	 * Whether the implementation supports dynamic registration. If this is set to
	 * `true`, the client supports the new `ImplementationRegistrationOptions`
	 * return value for the corresponding server capability as well.
	 */
	dynamicRegistration?: boolean;

	/**
	 * The client supports additional metadata in the form of definition links.
	 *
	 * @since 3.14.0
	 */
	linkSupport?: boolean;
}

服务器能力:

  • 属性名称(可选):implementationProvider
  • 属性类型:boolean | ImplementationOptions | ImplementationRegistrationOptions,其中 ImplementationOptions 定义如下
export interface ImplementationOptions extends WorkDoneProgressOptions {
}

注册选项:ImplementationRegistrationOptions 定义如下

export interface ImplementationRegistrationOptions extends
	TextDocumentRegistrationOptions, ImplementationOptions,
	StaticRegistrationOptions {
}

请求:

  • 方法:textDocument/implementation
  • 参数:ImplementationParams 定义如下
export interface ImplementationParams extends TextDocumentPositionParams,
	WorkDoneProgressParams, PartialResultParams {
}

Response:

  • 结果:Location | Location[] | LocationLink[] | null
  • 部分结果:Location[] | LocationLink[]
  • 错误:如果在定义请求期间发生异常,则设置代码和消息。

查找引用请求 (:leftwards_arrow_with_hook:)

引用请求从客户端发送到服务器,以解析给定文本文档位置处符号的项目范围引用。

客户端能力:

  • 属性名称(可选):textDocument.references
  • 属性类型:ReferenceClientCapabilities 定义如下
export interface ReferenceClientCapabilities {
	/**
	 * Whether references supports dynamic registration.
	 */
	dynamicRegistration?: boolean;
}

服务器能力:

  • 属性名称(可选):referencesProvider
  • 属性类型:boolean | ReferenceOptions,其中 ReferenceOptions 定义如下
export interface ReferenceOptions extends WorkDoneProgressOptions {
}

注册选项:ReferenceRegistrationOptions 定义如下

export interface ReferenceRegistrationOptions extends
	TextDocumentRegistrationOptions, ReferenceOptions {
}

请求:

  • 方法:textDocument/references
  • 参数:ReferenceParams 定义如下
export interface ReferenceParams extends TextDocumentPositionParams,
	WorkDoneProgressParams, PartialResultParams {
	context: ReferenceContext;
}
export interface ReferenceContext {
	/**
	 * Include the declaration of the current symbol.
	 */
	includeDeclaration: boolean;
}

Response:

  • 结果:Location[] | null
  • 部分结果:Location[]
  • 错误:如果在引用请求期间发生异常,则设置代码和消息。

准备调用层次结构请求 (:leftwards_arrow_with_hook:)

自 3.16.0 版本起

调用层次结构请求从客户端发送到服务器,以返回给定文本文档位置的语言元素的调用层次结构。调用层次结构请求分两步执行:

  1. 首先,为给定的文本文档位置解析调用层次结构项
  2. 对于一个调用层次项,解析传入或传出的调用层次项。

客户端能力:

  • 属性名称(可选):textDocument.callHierarchy
  • 属性类型:CallHierarchyClientCapabilities 定义如下
interface CallHierarchyClientCapabilities {
	/**
	 * Whether implementation supports dynamic registration. If this is set to
	 * `true` the client supports the new `(TextDocumentRegistrationOptions &
	 * StaticRegistrationOptions)` return value for the corresponding server
	 * capability as well.
	 */
	dynamicRegistration?: boolean;
}

服务器能力:

  • 属性名称(可选):callHierarchyProvider
  • 属性类型:boolean | CallHierarchyOptions | CallHierarchyRegistrationOptions,其中 CallHierarchyOptions 定义如下
export interface CallHierarchyOptions extends WorkDoneProgressOptions {
}

注册选项:CallHierarchyRegistrationOptions 定义如下

export interface CallHierarchyRegistrationOptions extends
	TextDocumentRegistrationOptions, CallHierarchyOptions,
	StaticRegistrationOptions {
}

请求:

  • 方法:textDocument/prepareCallHierarchy
  • 参数:CallHierarchyPrepareParams 定义如下
export interface CallHierarchyPrepareParams extends TextDocumentPositionParams,
	WorkDoneProgressParams {
}

Response:

  • 结果:CallHierarchyItem[] | null 定义如下
export interface CallHierarchyItem {
	/**
	 * The name of this item.
	 */
	name: string;

	/**
	 * The kind of this item.
	 */
	kind: SymbolKind;

	/**
	 * Tags for this item.
	 */
	tags?: SymbolTag[];

	/**
	 * More detail for this item, e.g. the signature of a function.
	 */
	detail?: string;

	/**
	 * The resource identifier of this item.
	 */
	uri: DocumentUri;

	/**
	 * The range enclosing this symbol not including leading/trailing whitespace
	 * but everything else, e.g. comments and code.
	 */
	range: Range;

	/**
	 * The range that should be selected and revealed when this symbol is being
	 * picked, e.g. the name of a function. Must be contained by the
	 * [`range`](#CallHierarchyItem.range).
	 */
	selectionRange: Range;

	/**
	 * A data entry field that is preserved between a call hierarchy prepare and
	 * incoming calls or outgoing calls requests.
	 */
	data?: LSPAny;
}
  • 错误:如果在 ‘textDocument/prepareCallHierarchy’ 请求期间发生异常,则设置代码和消息

调用层次结构传入调用 (:leftwards_arrow_with_hook:)

自 3.16.0 版本起

此请求从客户端发送到服务器,以解析给定调用层次结构项的传入调用。此请求不定义其自己的客户端和服务器功能。仅当服务器注册 textDocument/prepareCallHierarchy 请求时才会发出。

请求:

  • 方法:callHierarchy/incomingCalls
  • 参数:CallHierarchyIncomingCallsParams 定义如下
export interface CallHierarchyIncomingCallsParams extends
	WorkDoneProgressParams, PartialResultParams {
	item: CallHierarchyItem;
}

Response:

  • 结果:CallHierarchyIncomingCall[] | null 定义如下
export interface CallHierarchyIncomingCall {

	/**
	 * The item that makes the call.
	 */
	from: CallHierarchyItem;

	/**
	 * The ranges at which the calls appear. This is relative to the caller
	 * denoted by [`this.from`](#CallHierarchyIncomingCall.from).
	 */
	fromRanges: Range[];
}
  • 部分结果:CallHierarchyIncomingCall[]
  • 错误:如果在 ‘callHierarchy/incomingCalls’ 请求期间发生异常,则设置代码和消息

调用层次结构传出调用 (:leftwards_arrow_with_hook:)

自 3.16.0 版本起

此请求从客户端发送到服务器,以解析给定调用层次结构项的传出调用。此请求不定义其自己的客户端和服务器功能。仅当服务器注册 textDocument/prepareCallHierarchy 请求时才会发出。

请求:

  • 方法:callHierarchy/outgoingCalls
  • 参数:CallHierarchyOutgoingCallsParams 定义如下
export interface CallHierarchyOutgoingCallsParams extends
	WorkDoneProgressParams, PartialResultParams {
	item: CallHierarchyItem;
}

Response:

  • 结果:CallHierarchyOutgoingCall[] | null 定义如下
export interface CallHierarchyOutgoingCall {

	/**
	 * The item that is called.
	 */
	to: CallHierarchyItem;

	/**
	 * The range at which this item is called. This is the range relative to
	 * the caller, e.g., the item passed to `callHierarchy/outgoingCalls` request.
	 */
	fromRanges: Range[];
}
  • 部分结果:CallHierarchyOutgoingCall[]
  • 错误:如果在 ‘callHierarchy/outgoingCalls’ 请求期间发生异常,则设置代码和消息

准备类型层次结构请求 (:leftwards_arrow_with_hook:)

自 3.17.0 版本

类型层次结构请求从客户端发送到服务器,以返回给定文本文档位置的语言元素的类型层次结构。如果服务器无法从该位置推断出有效类型,则返回 null。类型层次结构请求分两步执行:

  1. 首先为给定的文本文档位置准备一个类型层次结构项。
  2. 对于一个类型层次结构项,解析其超类型或子类型层次结构项。

客户端能力:

  • 属性名称(可选):textDocument.typeHierarchy
  • 属性类型:TypeHierarchyClientCapabilities,定义如下:
type TypeHierarchyClientCapabilities = {
	/**
	 * Whether implementation supports dynamic registration. If this is set to
	 * `true` the client supports the new `(TextDocumentRegistrationOptions &
	 * StaticRegistrationOptions)` return value for the corresponding server
	 * capability as well.
	 */
	dynamicRegistration?: boolean;
};

服务器能力:

  • 属性名称(可选):typeHierarchyProvider
  • 属性类型:boolean | TypeHierarchyOptions | TypeHierarchyRegistrationOptions,其中 TypeHierarchyOptions 定义如下:
export interface TypeHierarchyOptions extends WorkDoneProgressOptions {
}

注册选项:TypeHierarchyRegistrationOptions,定义如下:

export interface TypeHierarchyRegistrationOptions extends
	TextDocumentRegistrationOptions, TypeHierarchyOptions,
	StaticRegistrationOptions {
}

请求:

  • 方法:‘textDocument/prepareTypeHierarchy’
  • 参数:TypeHierarchyPrepareParams,定义如下:
export interface TypeHierarchyPrepareParams extends TextDocumentPositionParams,
	WorkDoneProgressParams {
}

Response:

  • 结果:TypeHierarchyItem[] | null,定义如下:
export interface TypeHierarchyItem {
	/**
	 * The name of this item.
	 */
	name: string;

	/**
	 * The kind of this item.
	 */
	kind: SymbolKind;

	/**
	 * Tags for this item.
	 */
	tags?: SymbolTag[];

	/**
	 * More detail for this item, e.g. the signature of a function.
	 */
	detail?: string;

	/**
	 * The resource identifier of this item.
	 */
	uri: DocumentUri;

	/**
	 * The range enclosing this symbol not including leading/trailing whitespace
	 * but everything else, e.g. comments and code.
	 */
	range: Range;

	/**
	 * The range that should be selected and revealed when this symbol is being
	 * picked, e.g. the name of a function. Must be contained by the
	 * [`range`](#TypeHierarchyItem.range).
	 */
	selectionRange: Range;

	/**
	 * A data entry field that is preserved between a type hierarchy prepare and
	 * supertypes or subtypes requests. It could also be used to identify the
	 * type hierarchy in the server, helping improve the performance on
	 * resolving supertypes and subtypes.
	 */
	data?: LSPAny;
}
  • 错误:在“textDocument/prepareTypeHierarchy”请求期间发生异常时设置的代码和消息。

类型层次结构超类型 (:leftwards_arrow_with_hook:)

自 3.17.0 版本

此请求从客户端发送到服务器,以解析给定类型层次结构项的超类型。如果服务器无法从参数中的 item 推断出有效类型,则返回 null。此请求不定义其自己的客户端和服务器功能。仅当服务器注册 textDocument/prepareTypeHierarchy 请求时才会发出此请求。

请求:

  • 方法:‘typeHierarchy/supertypes’
  • 参数:TypeHierarchySupertypesParams,定义如下:
export interface TypeHierarchySupertypesParams extends
	WorkDoneProgressParams, PartialResultParams {
	item: TypeHierarchyItem;
}

Response:

  • 结果:TypeHierarchyItem[] | null
  • 部分结果:TypeHierarchyItem[]
  • 错误:在“typeHierarchy/supertypes”请求期间发生异常时设置的代码和消息。

类型层次结构子类型 (:leftwards_arrow_with_hook:)

自 3.17.0 版本

此请求从客户端发送到服务器,以解析给定类型层次结构项的子类型。如果服务器无法从参数中的 item 推断出有效类型,则返回 null。此请求不定义其自己的客户端和服务器功能。仅当服务器注册 textDocument/prepareTypeHierarchy 请求时才会发出此请求。

请求:

  • 方法:‘typeHierarchy/subtypes’
  • 参数:TypeHierarchySubtypesParams,定义如下:
export interface TypeHierarchySubtypesParams extends
	WorkDoneProgressParams, PartialResultParams {
	item: TypeHierarchyItem;
}

Response:

  • 结果:TypeHierarchyItem[] | null
  • 部分结果:TypeHierarchyItem[]
  • 错误:在“typeHierarchy/subtypes”请求期间发生异常时设置的代码和消息。

文档高亮请求 (:leftwards_arrow_with_hook:)

文档高亮请求从客户端发送到服务器,以解析给定文本文档位置的文档高亮。对于编程语言,这通常会高亮显示作用域为该文件的符号的所有引用。但是,我们将“textDocument/documentHighlight”和“textDocument/references”分开请求,因为前者允许更模糊。符号匹配通常具有 DocumentHighlightKind 的 Read 或 Write,而模糊或文本匹配使用 Text 作为种类。

客户端能力:

  • 属性名称(可选):textDocument.documentHighlight
  • 属性类型:DocumentHighlightClientCapabilities 定义如下
export interface DocumentHighlightClientCapabilities {
	/**
	 * Whether document highlight supports dynamic registration.
	 */
	dynamicRegistration?: boolean;
}

服务器能力:

  • 属性名称(可选):documentHighlightProvider
  • 属性类型:boolean | DocumentHighlightOptions,其中 DocumentHighlightOptions 定义如下
export interface DocumentHighlightOptions extends WorkDoneProgressOptions {
}

注册选项:DocumentHighlightRegistrationOptions 定义如下

export interface DocumentHighlightRegistrationOptions extends
	TextDocumentRegistrationOptions, DocumentHighlightOptions {
}

请求:

  • 方法:textDocument/documentHighlight
  • 参数:DocumentHighlightParams 定义如下
export interface DocumentHighlightParams extends TextDocumentPositionParams,
	WorkDoneProgressParams, PartialResultParams {
}

Response:

  • 结果:DocumentHighlight[] | null 定义如下
/**
 * A document highlight is a range inside a text document which deserves
 * special attention. Usually a document highlight is visualized by changing
 * the background color of its range.
 *
 */
export interface DocumentHighlight {
	/**
	 * The range this highlight applies to.
	 */
	range: Range;

	/**
	 * The highlight kind, default is DocumentHighlightKind.Text.
	 */
	kind?: DocumentHighlightKind;
}
/**
 * A document highlight kind.
 */
export namespace DocumentHighlightKind {
	/**
	 * A textual occurrence.
	 */
	export const Text = 1;

	/**
	 * Read-access of a symbol, like reading a variable.
	 */
	export const Read = 2;

	/**
	 * Write-access of a symbol, like writing to a variable.
	 */
	export const Write = 3;
}

export type DocumentHighlightKind = 1 | 2 | 3;
  • 部分结果:DocumentHighlight[]
  • 错误:如果在文档高亮请求期间发生异常,则设置代码和消息。

文档链接请求 (:leftwards_arrow_with_hook:)

文档链接请求从客户端发送到服务器,以请求文档中链接的位置。

客户端能力:

  • 属性名称(可选):textDocument.documentLink
  • 属性类型:DocumentLinkClientCapabilities 定义如下
export interface DocumentLinkClientCapabilities {
	/**
	 * Whether document link supports dynamic registration.
	 */
	dynamicRegistration?: boolean;

	/**
	 * Whether the client supports the `tooltip` property on `DocumentLink`.
	 *
	 * @since 3.15.0
	 */
	tooltipSupport?: boolean;
}

服务器能力:

  • 属性名称(可选):documentLinkProvider
  • 属性类型:DocumentLinkOptions 定义如下
export interface DocumentLinkOptions extends WorkDoneProgressOptions {
	/**
	 * Document links have a resolve provider as well.
	 */
	resolveProvider?: boolean;
}

注册选项:DocumentLinkRegistrationOptions 定义如下

export interface DocumentLinkRegistrationOptions extends
	TextDocumentRegistrationOptions, DocumentLinkOptions {
}

请求:

  • 方法:textDocument/documentLink
  • 参数:DocumentLinkParams 定义如下
interface DocumentLinkParams extends WorkDoneProgressParams,
	PartialResultParams {
	/**
	 * The document to provide document links for.
	 */
	textDocument: TextDocumentIdentifier;
}

Response:

  • 结果:DocumentLink[] | null。
/**
 * A document link is a range in a text document that links to an internal or
 * external resource, like another text document or a web site.
 */
interface DocumentLink {
	/**
	 * The range this link applies to.
	 */
	range: Range;

	/**
	 * The URI this link points to. If missing, a resolve request is sent later.
	 */
	target?: URI;

	/**
	 * The tooltip text when you hover over this link.
	 *
	 * If a tooltip is provided, it will be displayed in a string that includes
	 * instructions on how to trigger the link, such as `{0} (ctrl + click)`.
	 * The specific instructions vary depending on OS, user settings, and
	 * localization.
	 *
	 * @since 3.15.0
	 */
	tooltip?: string;

	/**
	 * A data entry field that is preserved on a document link between a
	 * DocumentLinkRequest and a DocumentLinkResolveRequest.
	 */
	data?: LSPAny;
}
  • 部分结果:DocumentLink[]
  • 错误:如果在文档链接请求期间发生异常,则设置代码和消息。

文档链接解析请求 (:leftwards_arrow_with_hook:)

文档链接解析请求从客户端发送到服务器,以解析给定文档链接的目标。

请求:

  • 方法:documentLink/resolve
  • 参数:DocumentLink

Response:

  • 结果:DocumentLink
  • 错误:如果在文档链接解析请求期间发生异常,则设置代码和消息。

悬停请求 (:leftwards_arrow_with_hook:)

悬停请求从客户端发送到服务器,以请求给定文本文档位置的悬停信息。

客户端能力:

  • 属性名称(可选):textDocument.hover
  • 属性类型:HoverClientCapabilities 定义如下
export interface HoverClientCapabilities {
	/**
	 * Whether hover supports dynamic registration.
	 */
	dynamicRegistration?: boolean;

	/**
	 * Client supports the following content formats if the content
	 * property refers to a `literal of type MarkupContent`.
	 * The order describes the preferred format of the client.
	 */
	contentFormat?: MarkupKind[];
}

服务器能力:

  • 属性名称(可选):hoverProvider
  • 属性类型:boolean | HoverOptions,其中 HoverOptions 定义如下
export interface HoverOptions extends WorkDoneProgressOptions {
}

注册选项:HoverRegistrationOptions 定义如下

export interface HoverRegistrationOptions
	extends TextDocumentRegistrationOptions, HoverOptions {
}

请求:

  • 方法:textDocument/hover
  • 参数:HoverParams 定义如下
export interface HoverParams extends TextDocumentPositionParams,
	WorkDoneProgressParams {
}

Response:

  • 结果:Hover | null 定义如下
/**
 * The result of a hover request.
 */
export interface Hover {
	/**
	 * The hover's content.
	 */
	contents: MarkedString | MarkedString[] | MarkupContent;

	/**
	 * An optional range is a range inside a text document
	 * that is used to visualize a hover, e.g. by changing the background color.
	 */
	range?: Range;
}

其中 MarkedString 定义如下

/**
 * MarkedString can be used to render human readable text. It is either a
 * markdown string or a code-block that provides a language and a code snippet.
 * The language identifier is semantically equal to the optional language
 * identifier in fenced code blocks in GitHub issues.
 *
 * The pair of a language and a value is an equivalent to markdown:
 * ```${language}
 * ${value}
 * ```
 *
 * Note that markdown strings will be sanitized - that means html will be
 * escaped.
 *
 * @deprecated use MarkupContent instead.
 */
type MarkedString = string | { language: string; value: string };
  • 错误:如果在悬停请求期间发生异常,则设置代码和消息。

代码镜头请求 (:leftwards_arrow_with_hook:)

代码镜头请求从客户端发送到服务器,以计算给定文本文档的代码镜头。

客户端能力:

  • 属性名称(可选):textDocument.codeLens
  • 属性类型:CodeLensClientCapabilities 定义如下
export interface CodeLensClientCapabilities {
	/**
	 * Whether code lens supports dynamic registration.
	 */
	dynamicRegistration?: boolean;

	/**
	 * Whether the client supports resolving additional code lens
	 * properties via a separate `codeLens/resolve` request.
	 *
	 * @since 3.18.0
	 */
	resolveSupport?: ClientCodeLensResolveOptions;
}

/**
 * @since 3.18.0
 */
export type ClientCodeLensResolveOptions = {
	/**
	 * The properties that a client can resolve lazily.
	 */
	properties: string[];
};

服务器能力:

  • 属性名称(可选):codeLensProvider
  • 属性类型:CodeLensOptions 定义如下
export interface CodeLensOptions extends WorkDoneProgressOptions {
	/**
	 * Code lens has a resolve provider as well.
	 */
	resolveProvider?: boolean;
}

注册选项:CodeLensRegistrationOptions 定义如下

export interface CodeLensRegistrationOptions extends
	TextDocumentRegistrationOptions, CodeLensOptions {
}

请求:

  • 方法:textDocument/codeLens
  • 参数:CodeLensParams 定义如下
interface CodeLensParams extends WorkDoneProgressParams, PartialResultParams {
	/**
	 * The document to request code lens for.
	 */
	textDocument: TextDocumentIdentifier;
}

Response:

  • 结果:CodeLens[] | null 定义如下
/**
 * A code lens represents a command that should be shown along with
 * source text, like the number of references, a way to run tests, etc.
 *
 * A code lens is _unresolved_ when no command is associated to it. For
 * performance reasons the creation of a code lens and resolving should be done
 * in two stages.
 */
interface CodeLens {
	/**
	 * The range in which this code lens is valid. Should only span a single
	 * line.
	 */
	range: Range;

	/**
	 * The command this code lens represents.
	 */
	command?: Command;

	/**
	 * A data entry field that is preserved on a code lens item between
	 * a code lens and a code lens resolve request.
	 */
	data?: LSPAny;
}
  • 部分结果:CodeLens[]
  • 错误:如果在代码镜头请求期间发生异常,则设置代码和消息。

代码镜头解析请求 (:leftwards_arrow_with_hook:)

代码镜头解析请求从客户端发送到服务器,以解析给定代码镜头项的命令。

客户端能力:

  • 属性名称(可选):textDocument.codeLens.resolveSupport
  • 属性类型:ClientCodeLensResolveOptions

请求:

  • 方法:codeLens/resolve
  • 参数:CodeLens

Response:

  • 结果:CodeLens
  • 错误:如果在代码镜头解析请求期间发生异常,则设置代码和消息。

代码镜头刷新请求 (:arrow_right_hook:)

自 3.16.0 版本起

workspace/codeLens/refresh 请求从服务器发送到客户端。服务器可以使用它来要求客户端刷新当前在编辑器中显示的代码透镜。结果是客户端应要求服务器重新计算这些编辑器的代码透镜。如果服务器检测到需要重新计算所有代码透镜的配置更改,这将很有用。请注意,客户端仍然有自由权延迟代码透镜的重新计算,例如,如果编辑器当前不可见。

客户端能力:

  • 属性名称(可选):workspace.codeLens
  • 属性类型:CodeLensWorkspaceClientCapabilities 定义如下
export interface CodeLensWorkspaceClientCapabilities {
	/**
	 * Whether the client implementation supports a refresh request sent from the
	 * server to the client.
	 *
	 * Note that this event is global and will force the client to refresh all
	 * code lenses currently shown. It should be used with absolute care and is
	 * useful for situation where a server, for example, detects a project wide
	 * change that requires such a calculation.
	 */
	refreshSupport?: boolean;
}

请求:

  • 方法:workspace/codeLens/refresh
  • 参数:无

Response:

  • 结果:void
  • 错误:如果在 ‘workspace/codeLens/refresh’ 请求期间发生异常,则设置代码和消息

折叠范围请求 (:leftwards_arrow_with_hook:)

自 3.10.0 版本起

折叠范围请求从客户端发送到服务器,以返回给定文本文档中找到的所有折叠范围。

客户端能力:

  • 属性名称(可选):textDocument.foldingRange
  • 属性类型:FoldingRangeClientCapabilities 定义如下
export interface FoldingRangeClientCapabilities {
	/**
	 * Whether implementation supports dynamic registration for folding range
	 * providers. If this is set to `true` the client supports the new
	 * `FoldingRangeRegistrationOptions` return value for the corresponding
	 * server capability as well.
	 */
	dynamicRegistration?: boolean;

	/**
	 * The maximum number of folding ranges that the client prefers to receive
	 * per document. The value serves as a hint, servers are free to follow the
	 * limit.
	 */
	rangeLimit?: uinteger;

	/**
	 * If set, the client signals that it only supports folding complete lines.
	 * If set, client will ignore specified `startCharacter` and `endCharacter`
	 * properties in a FoldingRange.
	 */
	lineFoldingOnly?: boolean;

	/**
	 * Specific options for the folding range kind.
	 *
	 * @since 3.17.0
	 */
	foldingRangeKind? : {
		/**
		 * The folding range kind values the client supports. When this
		 * property exists the client also guarantees that it will
		 * handle values outside its set gracefully and falls back
		 * to a default value when unknown.
		 */
		valueSet?: FoldingRangeKind[];
	};

	/**
	 * Specific options for the folding range.
	 * @since 3.17.0
	 */
	foldingRange?: {
		/**
		* If set, the client signals that it supports setting collapsedText on
		* folding ranges to display custom labels instead of the default text.
		*
		* @since 3.17.0
		*/
		collapsedText?: boolean;
	};
}

服务器能力:

  • 属性名称(可选):foldingRangeProvider
  • 属性类型:boolean | FoldingRangeOptions | FoldingRangeRegistrationOptions,其中 FoldingRangeOptions 定义如下
export interface FoldingRangeOptions extends WorkDoneProgressOptions {
}

注册选项:FoldingRangeRegistrationOptions 定义如下

export interface FoldingRangeRegistrationOptions extends
	TextDocumentRegistrationOptions, FoldingRangeOptions,
	StaticRegistrationOptions {
}

请求:

  • 方法:textDocument/foldingRange
  • 参数:FoldingRangeParams 定义如下
export interface FoldingRangeParams extends WorkDoneProgressParams,
	PartialResultParams {
	/**
	 * The text document.
	 */
	textDocument: TextDocumentIdentifier;
}

Response:

  • 结果:FoldingRange[] | null 定义如下
/**
 * A set of predefined range kinds.
 */
export namespace FoldingRangeKind {
	/**
	 * Folding range for a comment
	 */
	export const Comment = 'comment';

	/**
	 * Folding range for imports or includes
	 */
	export const Imports = 'imports';

	/**
	 * Folding range for a region (e.g. `#region`)
	 */
	export const Region = 'region';
}

/**
 * The type is a string since the value set is extensible
 */
export type FoldingRangeKind = string;
/**
 * Represents a folding range. To be valid, start and end line must be bigger
 * than zero and smaller than the number of lines in the document. Clients
 * are free to ignore invalid ranges.
 */
export interface FoldingRange {

	/**
	 * The zero-based start line of the range to fold. The folded area starts
	 * after the line's last character. To be valid, the end must be zero or
	 * larger and smaller than the number of lines in the document.
	 */
	startLine: uinteger;

	/**
	 * The zero-based character offset from where the folded range starts. If
	 * not defined, defaults to the length of the start line.
	 */
	startCharacter?: uinteger;

	/**
	 * The zero-based end line of the range to fold. The folded area ends with
	 * the line's last character. To be valid, the end must be zero or larger
	 * and smaller than the number of lines in the document.
	 */
	endLine: uinteger;

	/**
	 * The zero-based character offset before the folded range ends. If not
	 * defined, defaults to the length of the end line.
	 */
	endCharacter?: uinteger;

	/**
	 * Describes the kind of the folding range such as `comment` or `region`.
	 * The kind is used to categorize folding ranges and used by commands like
	 * 'Fold all comments'. See [FoldingRangeKind](#FoldingRangeKind) for an
	 * enumeration of standardized kinds.
	 */
	kind?: FoldingRangeKind;

	/**
	 * The text that the client should show when the specified range is
	 * collapsed. If not defined or not supported by the client, a default
	 * will be chosen by the client.
	 *
	 * @since 3.17.0 - proposed
	 */
	collapsedText?: string;
}
  • 部分结果:FoldingRange[]
  • 错误:如果在 ‘textDocument/foldingRange’ 请求期间发生异常,则设置代码和消息

折叠范围刷新请求 (:arrow_right_hook:)

自版本 3.18.0

workspace/foldingRange/refresh 请求从服务器发送到客户端。服务器可以使用它来要求客户端刷新当前在编辑器中显示的折叠范围。结果是客户端应要求服务器重新计算这些编辑器的折叠范围。如果服务器检测到需要重新计算所有折叠范围的配置更改,这将很有用。请注意,客户端仍然有自由权延迟折叠范围的重新计算,例如,如果编辑器当前不可见。

客户端能力:

  • 属性名称(可选):workspace.foldingRange
  • 属性类型:FoldingRangeWorkspaceClientCapabilities,定义如下:
export interface FoldingRangeWorkspaceClientCapabilities {
	/**
	 * Whether the client implementation supports a refresh request sent from the
	 * server to the client.
	 *
	 * Note that this event is global and will force the client to refresh all
	 * folding ranges currently shown. It should be used with absolute care and is
	 * useful for situation where a server, for example, detects a project wide
	 * change that requires such a calculation.
	 *
	 * @since 3.18.0
	 * @proposed
	 */
	refreshSupport?: boolean;
}

请求:

  • 方法:workspace/foldingRange/refresh
  • 参数:无

Response:

  • 结果:void
  • 错误:在“workspace/foldingRange/refresh”请求期间发生异常时设置的代码和消息。

选择范围请求 (:leftwards_arrow_with_hook:)

自 3.15.0 版起

选择范围请求从客户端发送到服务器,以返回给定位置数组的建议选择范围。选择范围是光标位置周围的范围,用户可能对此感兴趣。

返回数组中的选择范围对应于给定参数中相同索引位置。因此,positions[i] 必须包含在 result[i].range 中。为了允许某些位置有选择范围而另一些没有结果,result[i].range 允许在 positions[i] 处为空范围。

通常,但不一定,选择范围对应于语法树的节点。

客户端能力:

  • 属性名称(可选):textDocument.selectionRange
  • 属性类型:SelectionRangeClientCapabilities 定义如下
export interface SelectionRangeClientCapabilities {
	/**
	 * Whether the implementation supports dynamic registration for selection range
	 * providers. If this is set to `true`, the client supports the new
	 * `SelectionRangeRegistrationOptions` return value for the corresponding
	 * server capability as well.
	 */
	dynamicRegistration?: boolean;
}

服务器能力:

  • 属性名称(可选):selectionRangeProvider
  • 属性类型:boolean | SelectionRangeOptions | SelectionRangeRegistrationOptions,其中 SelectionRangeOptions 定义如下
export interface SelectionRangeOptions extends WorkDoneProgressOptions {
}

注册选项:SelectionRangeRegistrationOptions 定义如下

export interface SelectionRangeRegistrationOptions extends
	SelectionRangeOptions, TextDocumentRegistrationOptions,
	StaticRegistrationOptions {
}

请求:

  • 方法:textDocument/selectionRange
  • 参数:SelectionRangeParams 定义如下
export interface SelectionRangeParams extends WorkDoneProgressParams,
	PartialResultParams {
	/**
	 * The text document.
	 */
	textDocument: TextDocumentIdentifier;

	/**
	 * The positions inside the text document.
	 */
	positions: Position[];
}

Response:

  • 结果:SelectionRange[] | null 定义如下
export interface SelectionRange {
	/**
	 * The [range](#Range) of this selection range.
	 */
	range: Range;
	/**
	 * The parent selection range containing this range.
	 * Therefore, `parent.range` must contain `this.range`.
	 */
	parent?: SelectionRange;
}
  • 部分结果:SelectionRange[]
  • 错误:如果在 ‘textDocument/selectionRange’ 请求期间发生异常,则设置代码和消息

文档符号请求 (:leftwards_arrow_with_hook:)

文档符号请求从客户端发送到服务器。返回的结果要么是

  • SymbolInformation[],它是给定文本文档中找到的所有符号的平面列表。此时不应使用符号的位置范围或符号的容器名称来推断层次结构。
  • DocumentSymbol[],它是给定文本文档中找到的符号的层次结构。

服务器应尽可能返回 DocumentSymbol,因为它是更丰富的数据结构。

客户端能力:

  • 属性名称(可选):textDocument.documentSymbol
  • 属性类型:DocumentSymbolClientCapabilities 定义如下
export interface DocumentSymbolClientCapabilities {
	/**
	 * Whether document symbol supports dynamic registration.
	 */
	dynamicRegistration?: boolean;

	/**
	 * Specific capabilities for the `SymbolKind` in the
	 * `textDocument/documentSymbol` request.
	 */
	symbolKind?: {
		/**
		 * The symbol kind values the client supports. When this
		 * property exists the client also guarantees that it will
		 * handle values outside its set gracefully and falls back
		 * to a default value when unknown.
		 *
		 * If this property is not present the client only supports
		 * the symbol kinds from `File` to `Array` as defined in
		 * the initial version of the protocol.
		 */
		valueSet?: SymbolKind[];
	};

	/**
	 * The client supports hierarchical document symbols.
	 */
	hierarchicalDocumentSymbolSupport?: boolean;

	/**
	 * The client supports tags on `SymbolInformation`. Tags are supported on
	 * `DocumentSymbol` if `hierarchicalDocumentSymbolSupport` is set to true.
	 * Clients supporting tags have to handle unknown tags gracefully.
	 *
	 * @since 3.16.0
	 */
	tagSupport?: {
		/**
		 * The tags supported by the client.
		 */
		valueSet: SymbolTag[];
	};

	/**
	 * The client supports an additional label presented in the UI when
	 * registering a document symbol provider.
	 *
	 * @since 3.16.0
	 */
	labelSupport?: boolean;
}

服务器能力:

  • 属性名称(可选):documentSymbolProvider
  • 属性类型:boolean | DocumentSymbolOptions,其中 DocumentSymbolOptions 定义如下
export interface DocumentSymbolOptions extends WorkDoneProgressOptions {
	/**
	 * A human-readable string that is shown when multiple outlines trees
	 * are shown for the same document.
	 *
	 * @since 3.16.0
	 */
	label?: string;
}

注册选项:DocumentSymbolRegistrationOptions 定义如下

export interface DocumentSymbolRegistrationOptions extends
	TextDocumentRegistrationOptions, DocumentSymbolOptions {
}

请求:

  • 方法:textDocument/documentSymbol
  • 参数:DocumentSymbolParams 定义如下
export interface DocumentSymbolParams extends WorkDoneProgressParams,
	PartialResultParams {
	/**
	 * The text document.
	 */
	textDocument: TextDocumentIdentifier;
}

Response:

  • 结果:DocumentSymbol[] | SymbolInformation[] | null 定义如下
/**
 * A symbol kind.
 */
export namespace SymbolKind {
	export const File = 1;
	export const Module = 2;
	export const Namespace = 3;
	export const Package = 4;
	export const Class = 5;
	export const Method = 6;
	export const Property = 7;
	export const Field = 8;
	export const Constructor = 9;
	export const Enum = 10;
	export const Interface = 11;
	export const Function = 12;
	export const Variable = 13;
	export const Constant = 14;
	export const String = 15;
	export const Number = 16;
	export const Boolean = 17;
	export const Array = 18;
	export const Object = 19;
	export const Key = 20;
	export const Null = 21;
	export const EnumMember = 22;
	export const Struct = 23;
	export const Event = 24;
	export const Operator = 25;
	export const TypeParameter = 26;
}

export type SymbolKind = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
	14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26;
/**
 * Symbol tags are extra annotations that tweak the rendering of a symbol.
 *
 * @since 3.16
 */
export namespace SymbolTag {

	/**
	 * Render a symbol as obsolete, usually using a strike-out.
	 */
	export const Deprecated: 1 = 1;
}

export type SymbolTag = 1;
/**
 * Represents programming constructs like variables, classes, interfaces etc.
 * that appear in a document. Document symbols can be hierarchical and they
 * have two ranges: one that encloses their definition and one that points to
 * their most interesting range, e.g. the range of an identifier.
 */
export interface DocumentSymbol {

	/**
	 * The name of this symbol. Will be displayed in the user interface and
	 * therefore must not be an empty string or a string only consisting of
	 * white spaces.
	 */
	name: string;

	/**
	 * More detail for this symbol, e.g. the signature of a function.
	 */
	detail?: string;

	/**
	 * The kind of this symbol.
	 */
	kind: SymbolKind;

	/**
	 * Tags for this document symbol.
	 *
	 * @since 3.16.0
	 */
	tags?: SymbolTag[];

	/**
	 * Indicates if this symbol is deprecated.
	 *
	 * @deprecated Use tags instead
	 */
	deprecated?: boolean;

	/**
	 * The range enclosing this symbol not including leading/trailing whitespace
	 * but everything else, like comments. This information is typically used to
	 * determine if the client's cursor is inside the symbol to reveal the
	 * symbol in the UI.
	 */
	range: Range;

	/**
	 * The range that should be selected and revealed when this symbol is being
	 * picked, e.g. the name of a function. Must be contained by the `range`.
	 */
	selectionRange: Range;

	/**
	 * Children of this symbol, e.g. properties of a class.
	 */
	children?: DocumentSymbol[];
}
/**
 * Represents information about programming constructs like variables, classes,
 * interfaces etc.
 *
 * @deprecated use DocumentSymbol or WorkspaceSymbol instead.
 */
export interface SymbolInformation {
	/**
	 * The name of this symbol.
	 */
	name: string;

	/**
	 * The kind of this symbol.
	 */
	kind: SymbolKind;

	/**
	 * Tags for this symbol.
	 *
	 * @since 3.16.0
	 */
	tags?: SymbolTag[];

	/**
	 * Indicates if this symbol is deprecated.
	 *
	 * @deprecated Use tags instead
	 */
	deprecated?: boolean;

	/**
	 * The location of this symbol. The location's range is used by a tool
	 * to reveal the location in the editor. If the symbol is selected in the
	 * tool the range's start information is used to position the cursor. So
	 * the range usually spans more then the actual symbol's name and does
	 * normally include things like visibility modifiers.
	 *
	 * The range doesn't have to denote a node range in the sense of an abstract
	 * syntax tree. It can therefore not be used to re-construct a hierarchy of
	 * the symbols.
	 */
	location: Location;

	/**
	 * The name of the symbol containing this symbol. This information is for
	 * user interface purposes (e.g. to render a qualifier in the user interface
	 * if necessary). It can't be used to re-infer a hierarchy for the document
	 * symbols.
	 */
	containerName?: string;
}
  • 部分结果:DocumentSymbol[] | SymbolInformation[]。DocumentSymbol[] 和 SymbolInformation[] 不能混合。这意味着第一个块定义了所有其他块的类型。
  • 错误:如果在文档符号请求期间发生异常,则设置代码和消息。

语义令牌 (:leftwards_arrow_with_hook:)

自 3.16.0 版本起

此请求从客户端发送到服务器,以解析给定文件的语义令牌。语义令牌用于向文件添加取决于语言特定符号信息的额外颜色信息。语义令牌请求通常会产生大量结果。因此,协议支持使用数字编码令牌。此外,还提供了对增量的可选支持。

一般概念

令牌使用一个令牌类型结合令牌修饰符表示。令牌类型是类似 class 或 function 的东西,令牌修饰符是类似 static 或 async 的东西。协议定义了一组令牌类型和修饰符,但客户端可以扩展这些并宣布它们在相应客户端能力中支持的值。预定义的值是:

export enum SemanticTokenTypes {
	namespace = 'namespace',
	/**
	 * Represents a generic type. Acts as a fallback for types which
	 * can't be mapped to a specific type like class or enum.
	 */
	type = 'type',
	class = 'class',
	enum = 'enum',
	interface = 'interface',
	struct = 'struct',
	typeParameter = 'typeParameter',
	parameter = 'parameter',
	variable = 'variable',
	property = 'property',
	enumMember = 'enumMember',
	event = 'event',
	function = 'function',
	method = 'method',
	macro = 'macro',
	keyword = 'keyword',
	modifier = 'modifier',
	comment = 'comment',
	string = 'string',
	number = 'number',
	regexp = 'regexp',
	operator = 'operator',
	/**
	 * @since 3.17.0
	 */
	decorator = 'decorator',
	/**
	 * @since 3.18.0
	 */
	label = 'label'
}
export enum SemanticTokenModifiers {
	declaration = 'declaration',
	definition = 'definition',
	readonly = 'readonly',
	static = 'static',
	deprecated = 'deprecated',
	abstract = 'abstract',
	async = 'async',
	modification = 'modification',
	documentation = 'documentation',
	defaultLibrary = 'defaultLibrary'
}

协议定义了一个额外的令牌格式能力,以允许未来对格式进行扩展。目前只指定了 relative 格式,表示令牌使用相对位置描述(参见下面的令牌整数编码)。

export namespace TokenFormat {
	export const Relative: 'relative' = 'relative';
}

export type TokenFormat = 'relative';

令牌的整数编码

在能力层面,类型和修饰符使用字符串定义。然而,实际编码是使用整数进行的。因此,服务器需要让客户端知道它对哪些类型和修饰符使用了哪些数字。它们通过一个图例来完成,定义如下:

export interface SemanticTokensLegend {
	/**
	 * The token types a server uses.
	 */
	tokenTypes: string[];

	/**
	 * The token modifiers a server uses.
	 */
	tokenModifiers: string[];
}

令牌类型通过索引查找,因此 tokenType 值为 1 表示 tokenTypes[1]。由于令牌类型可以有多个修饰符,因此这些令牌修饰符可以使用位标志设置,因此 tokenModifier 值为 3 首先被视为二进制 0b00000011,这意味着 [tokenModifiers[0], tokenModifiers[1]],因为位 0 和 1 被设置。

令牌在文件中表示位置有两种不同的方式:绝对位置或相对位置。令牌格式 relative 的协议使用相对位置,因为当文件进行编辑时,大多数令牌相对于彼此保持稳定。这简化了如果服务器支持增量计算。每个令牌使用 5 个整数表示。文件中的特定令牌 i 由以下数组索引组成:

  • 在索引 5*i 处 - deltaLine:令牌行号,相对于前一个令牌的起始。
  • 在索引 5*i+1 处 - deltaStart:令牌起始字符,相对于前一个令牌的起始(如果它们在同一行,则相对于 0 或前一个令牌的起始)。
  • 在索引 5*i+2 - length:令牌的长度。
  • 在索引 5*i+3 - tokenType:将在 SemanticTokensLegend.tokenTypes 中查找。我们目前要求 tokenType < 65536。
  • 在索引 5*i+4 处 - tokenModifiers:每个设置的位将在 SemanticTokensLegend.tokenModifiers 中查找。

deltaStart 和 length 值必须使用客户端和服务器在 initialize 请求期间约定的编码进行编码(另请参见 TextDocuments)。令牌是否可以跨多行由客户端能力 multilineTokenSupport 定义。如果不支持多行令牌,并且令牌的长度超出行尾,则应将其视为令牌在行尾结束,并且不会换行到下一行。

客户端功能 overlappingTokenSupport 定义令牌是否可以相互重叠。

让我们看一个具体的例子,它使用单行令牌,没有重叠,用于编码一个包含 3 个令牌的文件,采用数字数组形式。我们从绝对位置开始,以演示如何轻松地将它们转换为相对位置:

{ line: 2, startChar:  5, length: 3, tokenType: "property",
	tokenModifiers: ["private", "static"]
},
{ line: 2, startChar: 10, length: 4, tokenType: "type", tokenModifiers: [] },
{ line: 5, startChar:  2, length: 7, tokenType: "class", tokenModifiers: [] }

首先,必须设计一个图例。这个图例必须在注册时预先提供,并捕获所有可能的令牌类型和修饰符。对于示例,我们使用此图例:

{
   tokenTypes: ['property', 'type', 'class'],
   tokenModifiers: ['private', 'static']
}

第一个转换步骤是使用图例将 tokenType 和 tokenModifiers 编码为整数。如前所述,令牌类型通过索引查找,因此 tokenType 值为 1 意味着 tokenTypes[1]。可以使用位标志设置多个令牌修饰符,因此 tokenModifier 值为 3 首先被视为二进制 0b00000011,这意味着 [tokenModifiers[0], tokenModifiers[1]],因为位 0 和 1 被设置。使用此图例,令牌现在是

{ line: 2, startChar:  5, length: 3, tokenType: 0, tokenModifiers: 3 },
{ line: 2, startChar: 10, length: 4, tokenType: 1, tokenModifiers: 0 },
{ line: 5, startChar:  2, length: 7, tokenType: 2, tokenModifiers: 0 }

下一步是将每个令牌相对于文件中的上一个令牌表示。在这种情况下,第二个令牌与第一个令牌在同一行,因此第二个令牌的 startChar 相对于第一个令牌的 startChar,因此它将是 10 - 5。第三个令牌与第二个令牌不在同一行,因此第三个令牌的 startChar 不会改变

{ deltaLine: 2, deltaStartChar: 5, length: 3, tokenType: 0, tokenModifiers: 3 },
{ deltaLine: 0, deltaStartChar: 5, length: 4, tokenType: 1, tokenModifiers: 0 },
{ deltaLine: 3, deltaStartChar: 2, length: 7, tokenType: 2, tokenModifiers: 0 }

最后一步是将令牌的 5 个字段内联到一个数组中,这是一种节省内存的表示。

// 1st token,  2nd token,  3rd token
[  2,5,3,0,3,  0,5,4,1,0,  3,2,7,2,0 ]

现在假设用户在文件开头键入一个新空行,导致文件中的令牌如下

{ line: 3, startChar:  5, length: 3, tokenType: "property",
	tokenModifiers: ["private", "static"]
},
{ line: 3, startChar: 10, length: 4, tokenType: "type", tokenModifiers: [] },
{ line: 6, startChar:  2, length: 7, tokenType: "class", tokenModifiers: [] }

执行与上述相同的转换将得到以下数字数组

// 1st token,  2nd token,  3rd token
[  3,5,3,0,3,  0,5,4,1,0,  3,2,7,2,0]

现在,增量表示在这些数字数组上,没有任何形式的解释这些数字的含义。这与从服务器发送到客户端以修改文件内容的文本文档编辑类似。这些编辑是基于字符的,不对字符的含义做任何假设。因此,[ 2,5,3,0,3, 0,5,4,1,0, 3,2,7,2,0 ] 可以使用以下编辑描述转换为 [ 3,5,3,0,3, 0,5,4,1,0, 3,2,7,2,0]:{ start: 0, deleteCount: 1, data: [3] },它告诉客户端简单地将数组中的第一个数字(例如 2)替换为 3。

语义令牌编辑在概念上类似于文档上的文本编辑:如果一个编辑描述包含 n 个编辑,所有 n 个编辑都基于数字数组的相同状态 Sm。它们将使数字数组从状态 Sm 移动到 Sm+1。应用编辑的客户端不得假定它们已排序。将它们应用于数字数组的简单算法是对编辑进行排序,并从数字数组的背面到前面应用它们。

客户端能力:

为从客户端发送到服务器的语义令牌请求定义了以下客户端功能

  • 属性名称(可选):textDocument.semanticTokens
  • 属性类型:SemanticTokensClientCapabilities 定义如下
interface SemanticTokensClientCapabilities {
	/**
	 * Whether the implementation supports dynamic registration. If this is set to
	 * `true`, the client supports the new `(TextDocumentRegistrationOptions &
	 * StaticRegistrationOptions)` return value for the corresponding server
	 * capability as well.
	 */
	dynamicRegistration?: boolean;

	/**
	 * Which requests the client supports and might send to the server
	 * depending on the server's capability. Please note that clients might not
	 * show semantic tokens or degrade some of the user experience if a range
	 * or full request is advertised by the client but not provided by the
	 * server. If, for example, the client capability `requests.full` and
	 * `request.range` are both set to true but the server only provides a
	 * range provider, the client might not render a minimap correctly or might
	 * even decide to not show any semantic tokens at all.
	 */
	requests: {
		/**
		 * The client will send the `textDocument/semanticTokens/range` request
		 * if the server provides a corresponding handler.
		 */
		range?: boolean | {
		};

		/**
		 * The client will send the `textDocument/semanticTokens/full` request
		 * if the server provides a corresponding handler.
		 */
		full?: boolean | {
			/**
			 * The client will send the `textDocument/semanticTokens/full/delta`
			 * request if the server provides a corresponding handler.
			 */
			delta?: boolean;
		};
	};

	/**
	 * The token types that the client supports.
	 */
	tokenTypes: string[];

	/**
	 * The token modifiers that the client supports.
	 */
	tokenModifiers: string[];

	/**
	 * The formats the client supports.
	 */
	formats: TokenFormat[];

	/**
	 * Whether the client supports tokens that can overlap each other.
	 */
	overlappingTokenSupport?: boolean;

	/**
	 * Whether the client supports tokens that can span multiple lines.
	 */
	multilineTokenSupport?: boolean;

	/**
	 * Whether the client allows the server to actively cancel a
	 * semantic token request, e.g. supports returning
	 * ErrorCodes.ServerCancelled. If a server does so, the client
	 * needs to retrigger the request.
	 *
	 * @since 3.17.0
	 */
	serverCancelSupport?: boolean;

	/**
	 * Whether the client uses semantic tokens to augment existing
	 * syntax tokens. If set to `true`, client side created syntax
	 * tokens and semantic tokens are both used for colorization. If
	 * set to `false`, the client only uses the returned semantic tokens
	 * for colorization.
	 *
	 * If the value is `undefined` then the client behavior is not
	 * specified.
	 *
	 * @since 3.17.0
	 */
	augmentsSyntaxTokens?: boolean;
}

服务器能力:

为语义令牌定义了以下服务器功能

  • 属性名称(可选):semanticTokensProvider
  • 属性类型:SemanticTokensOptions | SemanticTokensRegistrationOptions,其中 SemanticTokensOptions 定义如下
export interface SemanticTokensOptions extends WorkDoneProgressOptions {
	/**
	 * The legend used by the server.
	 */
	legend: SemanticTokensLegend;

	/**
	 * Server supports providing semantic tokens for a specific range
	 * of a document.
	 */
	range?: boolean | {
	};

	/**
	 * Server supports providing semantic tokens for a full document.
	 */
	full?: boolean | {
		/**
		 * The server supports deltas for full documents.
		 */
		delta?: boolean;
	};
}

注册选项:SemanticTokensRegistrationOptions 定义如下

export interface SemanticTokensRegistrationOptions extends
	TextDocumentRegistrationOptions, SemanticTokensOptions,
	StaticRegistrationOptions {
}

由于注册选项处理范围、完整和增量请求,用于注册语义令牌请求的方法是 textDocument/semanticTokens,而不是下面描述的特定方法之一。

请求整个文件的语义令牌

请求:

  • 方法:textDocument/semanticTokens/full
  • 参数:SemanticTokensParams 定义如下
export interface SemanticTokensParams extends WorkDoneProgressParams,
	PartialResultParams {
	/**
	 * The text document.
	 */
	textDocument: TextDocumentIdentifier;
}

Response:

  • 结果:SemanticTokens | null,其中 SemanticTokens 定义如下
export interface SemanticTokens {
	/**
	 * An optional result ID. If provided and clients support delta updating,
	 * the client will include the result ID in the next semantic token request.
	 * A server can then, instead of computing all semantic tokens again, simply
	 * send a delta.
	 */
	resultId?: string;

	/**
	 * The actual tokens.
	 */
	data: uinteger[];
}
  • 部分结果:SemanticTokensPartialResult 定义如下
export interface SemanticTokensPartialResult {
	data: uinteger[];
}
  • 错误:如果在 ‘textDocument/semanticTokens/full’ 请求期间发生异常,则设置代码和消息

请求整个文件的语义令牌增量

请求:

  • 方法:textDocument/semanticTokens/full/delta
  • 参数:SemanticTokensDeltaParams 定义如下
export interface SemanticTokensDeltaParams extends WorkDoneProgressParams,
	PartialResultParams {
	/**
	 * The text document.
	 */
	textDocument: TextDocumentIdentifier;

	/**
	 * The result ID of a previous response. The result ID can either point to
	 * a full response or a delta response, depending on what was received last.
	 */
	previousResultId: string;
}

Response:

  • 结果:SemanticTokens | SemanticTokensDelta | null,其中 SemanticTokensDelta 定义如下
export interface SemanticTokensDelta {
	readonly resultId?: string;
	/**
	 * The semantic token edits to transform a previous result into a new
	 * result.
	 */
	edits: SemanticTokensEdit[];
}
export interface SemanticTokensEdit {
	/**
	 * The start offset of the edit.
	 */
	start: uinteger;

	/**
	 * The count of elements to remove.
	 */
	deleteCount: uinteger;

	/**
	 * The elements to insert.
	 */
	data?: uinteger[];
}
  • 部分结果:SemanticTokensDeltaPartialResult 定义如下
export interface SemanticTokensDeltaPartialResult {
	edits: SemanticTokensEdit[];
}
  • 错误:如果在 ‘textDocument/semanticTokens/full/delta’ 请求期间发生异常,则设置代码和消息

请求某个范围的语义令牌

在以下两种情况下,仅计算可见范围内的语义令牌可能是有益的

  • 为了在用户打开文件时更快地在用户界面中渲染令牌。在此用例中,服务器还应实现 textDocument/semanticTokens/full 请求,以实现无闪烁滚动和迷你地图的语义着色。
  • 如果计算完整文档的语义令牌成本太高,服务器可以只提供范围调用。在这种情况下,客户端可能无法正确渲染迷你地图,甚至可能决定完全不显示任何语义令牌。

服务器允许计算比客户端请求的更广范围的语义令牌。但是,如果服务器这样做,则更广范围的语义令牌必须是完整且正确的。如果开头或结尾处的令牌只与请求范围部分重叠,服务器应将这些令牌包含在响应中。

请求:

  • 方法:textDocument/semanticTokens/range
  • 参数:SemanticTokensRangeParams 定义如下
export interface SemanticTokensRangeParams extends WorkDoneProgressParams,
	PartialResultParams {
	/**
	 * The text document.
	 */
	textDocument: TextDocumentIdentifier;

	/**
	 * The range the semantic tokens are requested for.
	 */
	range: Range;
}

Response:

  • 结果:SemanticTokens | null
  • 部分结果:SemanticTokensPartialResult
  • 错误:如果在 ‘textDocument/semanticTokens/range’ 请求期间发生异常,则设置代码和消息

请求刷新所有语义令牌

workspace/semanticTokens/refresh 请求从服务器发送到客户端。服务器可以使用它来要求客户端刷新此服务器提供语义令牌的编辑器。结果是客户端应要求服务器重新计算这些编辑器的语义令牌。如果服务器检测到需要重新计算所有语义令牌的项目范围配置更改,这将很有用。请注意,客户端仍然有自由权延迟语义令牌的重新计算,例如,如果编辑器当前不可见。

客户端能力:

  • 属性名称(可选):workspace.semanticTokens
  • 属性类型:SemanticTokensWorkspaceClientCapabilities 定义如下
export interface SemanticTokensWorkspaceClientCapabilities {
	/**
	 * Whether the client implementation supports a refresh request sent from
	 * the server to the client.
	 *
	 * Note that this event is global and will force the client to refresh all
	 * semantic tokens currently shown. It should be used with absolute care
	 * and is useful for situation where a server, for example, detects a project
	 * wide change that requires such a calculation.
	 */
	refreshSupport?: boolean;
}

请求:

  • 方法:workspace/semanticTokens/refresh
  • 参数:无

Response:

  • 结果:void
  • 错误:如果在 ‘workspace/semanticTokens/refresh’ 请求期间发生异常,则设置代码和消息

内联提示请求 (:leftwards_arrow_with_hook:)

自 3.17.0 版本

内联提示请求从客户端发送到服务器,以计算给定 [文本文档,范围] 元组的内联提示,这些提示可能会在编辑器中与其他文本一起就地渲染。

客户端能力:

  • 属性名称(可选):textDocument.inlayHint
  • 属性类型:InlayHintClientCapabilities,定义如下:
/**
 * Inlay hint client capabilities.
 *
 * @since 3.17.0
 */
export interface InlayHintClientCapabilities {

	/**
	 * Whether inlay hints support dynamic registration.
	 */
	dynamicRegistration?: boolean;

	/**
	 * Indicates which properties a client can resolve lazily on an inlay
	 * hint.
	 */
	resolveSupport?: {

		/**
		 * The properties that a client can resolve lazily.
		 */
		properties: string[];
	};
}

服务器能力:

  • 属性名称(可选):inlayHintProvider
  • 属性类型:InlayHintOptions,定义如下:
/**
 * Inlay hint options used during static registration.
 *
 * @since 3.17.0
 */
export interface InlayHintOptions extends WorkDoneProgressOptions {
	/**
	 * The server provides support to resolve additional
	 * information for an inlay hint item.
	 */
	resolveProvider?: boolean;
}

注册选项:InlayHintRegistrationOptions,定义如下:

/**
 * Inlay hint options used during static or dynamic registration.
 *
 * @since 3.17.0
 */
export interface InlayHintRegistrationOptions extends InlayHintOptions,
	TextDocumentRegistrationOptions, StaticRegistrationOptions {
}

请求:

  • 方法:textDocument/inlayHint
  • 参数:InlayHintParams,定义如下:
/**
 * A parameter literal used in inlay hint requests.
 *
 * @since 3.17.0
 */
export interface InlayHintParams extends WorkDoneProgressParams {
	/**
	 * The text document.
	 */
	textDocument: TextDocumentIdentifier;

	/**
	 * The visible document range for which inlay hints should be computed.
	 */
	range: Range;
}

Response:

  • 结果:InlayHint[] | null,定义如下:
/**
 * Inlay hint information.
 *
 * @since 3.17.0
 */
export interface InlayHint {

	/**
	 * The position of this hint.
	 *
	 * If multiple hints have the same position, they will be shown in the order
	 * they appear in the response.
	 */
	position: Position;

	/**
	 * The label of this hint. A human readable string or an array of
	 * InlayHintLabelPart label parts.
	 *
	 * *Note* that neither the string nor the label part can be empty.
	 */
	label: string | InlayHintLabelPart[];

	/**
	 * The kind of this hint. Can be omitted in which case the client
	 * should fall back to a reasonable default.
	 */
	kind?: InlayHintKind;

	/**
	 * Optional text edits that are performed when accepting this inlay hint.
	 *
	 * *Note* that edits are expected to change the document so that the inlay
	 * hint (or its nearest variant) is now part of the document and the inlay
	 * hint itself is now obsolete.
	 *
	 * Depending on the client capability `inlayHint.resolveSupport`,
	 * clients might resolve this property late using the resolve request.
	 */
	textEdits?: TextEdit[];

	/**
	 * The tooltip text when you hover over this item.
	 *
	 * Depending on the client capability `inlayHint.resolveSupport` clients
	 * might resolve this property late using the resolve request.
	 */
	tooltip?: string | MarkupContent;

	/**
	 * Render padding before the hint.
	 *
	 * Note: Padding should use the editor's background color, not the
	 * background color of the hint itself. That means padding can be used
	 * to visually align/separate an inlay hint.
	 */
	paddingLeft?: boolean;

	/**
	 * Render padding after the hint.
	 *
	 * Note: Padding should use the editor's background color, not the
	 * background color of the hint itself. That means padding can be used
	 * to visually align/separate an inlay hint.
	 */
	paddingRight?: boolean;


	/**
	 * A data entry field that is preserved on an inlay hint between
	 * a `textDocument/inlayHint` and an `inlayHint/resolve` request.
	 */
	data?: LSPAny;
}
/**
 * An inlay hint label part allows for interactive and composite labels
 * of inlay hints.
 *
 * @since 3.17.0
 */
export interface InlayHintLabelPart {

	/**
	 * The value of this label part.
	 */
	value: string;

	/**
	 * The tooltip text when you hover over this label part. Depending on
	 * the client capability `inlayHint.resolveSupport`, clients might resolve
	 * this property late using the resolve request.
	 */
	tooltip?: string | MarkupContent;

	/**
	 * An optional source code location that represents this
	 * label part.
	 *
	 * The editor will use this location for the hover and for code navigation
	 * features: This part will become a clickable link that resolves to the
	 * definition of the symbol at the given location (not necessarily the
	 * location itself), it shows the hover that shows at the given location,
	 * and it shows a context menu with further code navigation commands.
	 *
	 * Depending on the client capability `inlayHint.resolveSupport` clients
	 * might resolve this property late using the resolve request.
	 */
	location?: Location;

	/**
	 * An optional command for this label part.
	 *
	 * Depending on the client capability `inlayHint.resolveSupport`, clients
	 * might resolve this property late using the resolve request.
	 */
	command?: Command;
}
/**
 * Inlay hint kinds.
 *
 * @since 3.17.0
 */
export namespace InlayHintKind {

	/**
	 * An inlay hint that is for a type annotation.
	 */
	export const Type = 1;

	/**
	 * An inlay hint that is for a parameter.
	 */
	export const Parameter = 2;
}

export type InlayHintKind = 1 | 2;
  • 错误:在内联提示请求期间发生异常时设置的代码和消息。

内联提示解析请求 (:leftwards_arrow_with_hook:)

自 3.17.0 版本

此请求从客户端发送到服务器,以解析给定内联提示的附加信息。这通常用于计算内联提示标签部分的 tooltip、location 或 command 属性,以避免在 textDocument/inlayHint 请求期间不必要的计算。

考虑客户端通过客户端能力声明 label.location 属性可以延迟解析:

textDocument.inlayHint.resolveSupport = { properties: ['label.location'] };

那么,没有位置的内联提示标签部分需要在通过 inlayHint/resolve 请求解析后才能使用。

客户端能力:

  • 属性名称(可选):textDocument.inlayHint.resolveSupport
  • 属性类型:{ properties: string[]; }

请求:

  • 方法:inlayHint/resolve
  • 参数:InlayHint

Response:

  • 结果:InlayHint
  • 错误:如果在完成解析请求期间发生异常,则设置代码和消息。

内联提示刷新请求 (:arrow_right_hook:)

自 3.17.0 版本

workspace/inlayHint/refresh 请求从服务器发送到客户端。服务器可以使用它来要求客户端刷新当前在编辑器中显示的内联提示。结果是客户端应要求服务器重新计算这些编辑器的内联提示。如果服务器检测到需要重新计算所有内联提示的配置更改,这将很有用。请注意,客户端仍然有自由权延迟内联提示的重新计算,例如,如果编辑器当前不可见。

客户端能力:

  • 属性名称(可选):workspace.inlayHint
  • 属性类型:InlayHintWorkspaceClientCapabilities,定义如下:
/**
 * Client workspace capabilities specific to inlay hints.
 *
 * @since 3.17.0
 */
export interface InlayHintWorkspaceClientCapabilities {
	/**
	 * Whether the client implementation supports a refresh request sent from
	 * the server to the client.
	 *
	 * Note that this event is global and will force the client to refresh all
	 * inlay hints currently shown. It should be used with absolute care and
	 * is useful for situations where a server, for example, detects a project wide
	 * change that requires such a calculation.
	 */
	refreshSupport?: boolean;
}

请求:

  • 方法:workspace/inlayHint/refresh
  • 参数:无

Response:

  • 结果:void
  • 错误:在“workspace/inlayHint/refresh”请求期间发生异常时设置的代码和消息。

内联值请求 (:leftwards_arrow_with_hook:)

自 3.17.0 版本

内联值请求从客户端发送到服务器,以计算给定文本文档的内联值,这些值可能会在编辑器中行尾渲染。

客户端能力:

  • 属性名称(可选):textDocument.inlineValue
  • 属性类型:InlineValueClientCapabilities,定义如下:
/**
 * Client capabilities specific to inline values.
 *
 * @since 3.17.0
 */
export interface InlineValueClientCapabilities {
	/**
	 * Whether the implementation supports dynamic registration for inline
	 * value providers.
	 */
	dynamicRegistration?: boolean;
}

服务器能力:

  • 属性名称(可选):inlineValueProvider
  • 属性类型:InlineValueOptions,定义如下:
/**
 * Inline value options used during static registration.
 *
 * @since 3.17.0
 */
export interface InlineValueOptions extends WorkDoneProgressOptions {
}

注册选项:InlineValueRegistrationOptions,定义如下:

/**
 * Inline value options used during static or dynamic registration.
 *
 * @since 3.17.0
 */
export interface InlineValueRegistrationOptions extends InlineValueOptions,
	TextDocumentRegistrationOptions, StaticRegistrationOptions {
}

请求:

  • 方法:textDocument/inlineValue
  • 参数:InlineValueParams,定义如下:
/**
 * A parameter literal used in inline value requests.
 *
 * @since 3.17.0
 */
export interface InlineValueParams extends WorkDoneProgressParams {
	/**
	 * The text document.
	 */
	textDocument: TextDocumentIdentifier;

	/**
	 * The document range for which inline values should be computed.
	 */
	range: Range;

	/**
	 * Additional information about the context in which inline values were
	 * requested.
	 */
	context: InlineValueContext;
}
/**
 * @since 3.17.0
 */
export interface InlineValueContext {
	/**
	 * The stack frame (as a DAP ID) where the execution has stopped.
	 */
	frameId: integer;

	/**
	 * The document range where execution has stopped.
	 * Typically, the end position of the range denotes the line where the
	 * inline values are shown.
	 */
	stoppedLocation: Range;
}

Response:

  • 结果:InlineValue[] | null,定义如下:
/**
 * Provide inline value as text.
 *
 * @since 3.17.0
 */
export interface InlineValueText {
	/**
	 * The document range for which the inline value applies.
	 */
	range: Range;

	/**
	 * The text of the inline value.
	 */
	text: string;
}
/**
 * Provide inline value through a variable lookup.
 *
 * If only a range is specified, the variable name will be extracted from
 * the underlying document.
 *
 * An optional variable name can be used to override the extracted name.
 *
 * @since 3.17.0
 */
export interface InlineValueVariableLookup {
	/**
	 * The document range for which the inline value applies.
	 * The range is used to extract the variable name from the underlying
	 * document.
	 */
	range: Range;

	/**
	 * If specified, the name of the variable to look up.
	 */
	variableName?: string;

	/**
	 * How to perform the lookup.
	 */
	caseSensitiveLookup: boolean;
}
/**
 * Provide an inline value through an expression evaluation.
 *
 * If only a range is specified, the expression will be extracted from the
 * underlying document.
 *
 * An optional expression can be used to override the extracted expression.
 *
 * @since 3.17.0
 */
export interface InlineValueEvaluatableExpression {
	/**
	 * The document range for which the inline value applies.
	 * The range is used to extract the evaluatable expression from the
	 * underlying document.
	 */
	range: Range;

	/**
	 * If specified the expression overrides the extracted expression.
	 */
	expression?: string;
}
/**
 * Inline value information can be provided by different means:
 * - directly as a text value (class InlineValueText).
 * - as a name to use for a variable lookup (class InlineValueVariableLookup)
 * - as an evaluatable expression (class InlineValueEvaluatableExpression)
 * The InlineValue types combines all inline value types into one type.
 *
 * @since 3.17.0
 */
export type InlineValue = InlineValueText | InlineValueVariableLookup
	| InlineValueEvaluatableExpression;
  • 错误:在内联值请求期间发生异常时设置的代码和消息。

内联值刷新请求 (:arrow_right_hook:)

自 3.17.0 版本

workspace/inlineValue/refresh 请求从服务器发送到客户端。服务器可以使用它来要求客户端刷新当前在编辑器中显示的内联值。结果是客户端应要求服务器重新计算这些编辑器的内联值。如果服务器检测到需要重新计算所有内联值的配置更改,这将很有用。请注意,客户端仍然有自由权延迟内联值的重新计算,例如,如果编辑器当前不可见。

客户端能力:

  • 属性名称(可选):workspace.inlineValue
  • 属性类型:InlineValueWorkspaceClientCapabilities 定义如下
/**
 * Client workspace capabilities specific to inline values.
 *
 * @since 3.17.0
 */
export interface InlineValueWorkspaceClientCapabilities {
	/**
	 * Whether the client implementation supports a refresh request sent from
	 * the server to the client.
	 *
	 * Note that this event is global and will force the client to refresh all
	 * inline values currently shown. It should be used with absolute care and
	 * is useful for situations where a server, for example, detects a project
	 * wide change that requires such a calculation.
	 */
	refreshSupport?: boolean;
}

请求:

  • 方法:workspace/inlineValue/refresh
  • 参数:无

Response:

  • 结果:void
  • 错误:如果在“workspace/inlineValue/refresh”请求期间发生异常,则设置代码和消息

标记 (:leftwards_arrow_with_hook:)

自 3.16.0 版本起

语言服务器索引格式 (LSIF) 引入了符号标识符的概念,以帮助关联不同索引中的符号。此请求增加了 LSP 服务器实现的功能,可以在给定文本文档位置的情况下提供相同的符号标识符信息。客户端可以使用此方法获取用户正在编辑的文件中当前位置的标识符,并在依赖 LSIF 索引并链接符号的其他服务中执行进一步的代码导航查询。

textDocument/moniker 请求从客户端发送到服务器,以获取给定文本文档位置的符号标记。返回 Moniker 类型数组作为响应,以指示给定位置可能的标记。如果无法计算标记,则应返回空数组或 null。

客户端功能:

  • 属性名称(可选):textDocument.moniker
  • 属性类型:MonikerClientCapabilities 定义如下
interface MonikerClientCapabilities {
	/**
	 * Whether implementation supports dynamic registration. If this is set to
	 * `true`, the client supports the new `(TextDocumentRegistrationOptions &
	 * StaticRegistrationOptions)` return value for the corresponding server
	 * capability as well.
	 */
	dynamicRegistration?: boolean;
}

服务器能力:

  • 属性名称(可选):monikerProvider
  • 属性类型:boolean | MonikerOptions | MonikerRegistrationOptions 定义如下
export interface MonikerOptions extends WorkDoneProgressOptions {
}

注册选项:MonikerRegistrationOptions 定义如下

export interface MonikerRegistrationOptions extends
	TextDocumentRegistrationOptions, MonikerOptions {
}

请求:

  • 方法:textDocument/moniker
  • 参数:MonikerParams 定义如下
export interface MonikerParams extends TextDocumentPositionParams,
	WorkDoneProgressParams, PartialResultParams {
}

Response:

  • 结果:Moniker[] | null
  • 部分结果:Moniker[]
  • 错误:如果在 ‘textDocument/moniker’ 请求期间发生异常,则设置代码和消息

Moniker 定义如下

/**
 * Moniker uniqueness level to define scope of the moniker.
 */
export enum UniquenessLevel {
	/**
	 * The moniker is only unique inside a document.
	 */
	document = 'document',

	/**
	 * The moniker is unique inside a project for which a dump got created.
	 */
	project = 'project',

	/**
	 * The moniker is unique inside the group to which a project belongs.
	 */
	group = 'group',

	/**
	 * The moniker is unique inside the moniker scheme.
	 */
	scheme = 'scheme',

	/**
	 * The moniker is globally unique.
	 */
	global = 'global'
}
/**
 * The moniker kind.
 */
export enum MonikerKind {
	/**
	 * The moniker represent a symbol that is imported into a project.
	 */
	import = 'import',

	/**
	 * The moniker represents a symbol that is exported from a project.
	 */
	export = 'export',

	/**
	 * The moniker represents a symbol that is local to a project (e.g. a local
	 * variable of a function, a class not visible outside the project, ...)
	 */
	local = 'local'
}
/**
 * Moniker definition to match LSIF 0.5 moniker definition.
 */
export interface Moniker {
	/**
	 * The scheme of the moniker. For example, `tsc` or `.NET`.
	 */
	scheme: string;

	/**
	 * The identifier of the moniker. The value is opaque in LSIF, however
	 * schema owners are allowed to define the structure if they want.
	 */
	identifier: string;

	/**
	 * The scope in which the moniker is unique.
	 */
	unique: UniquenessLevel;

	/**
	 * The moniker kind if known.
	 */
	kind?: MonikerKind;
}
注意事项

此方法的服务器实现应确保标记计算与相应 LSIF 实现中使用的标记计算相匹配,以确保符号可以在 IDE 会话和 LSIF 索引之间正确关联。

完成请求 (:leftwards_arrow_with_hook:)

客户端向服务器发送补全请求,以在给定的光标位置计算补全项。补全项显示在 IntelliSense 用户界面中。如果计算完整补全项开销很大,服务器可以额外提供一个补全项解析请求('completionItem/resolve')的处理程序。此请求在用户界面中选择补全项时发送。一个典型的用例是 textDocument/completion 请求,它不会填充返回的补全项的 documentation 属性,因为计算成本很高。当用户界面中选择该项时,会发送一个“completionItem/resolve”请求,并将选定的补全项作为参数。返回的补全项应填充文档属性。默认情况下,该请求只能延迟 detail 和 documentation 属性的计算。自 3.16.0 起,客户端可以表明它可以延迟解析更多属性。这是通过 completionItem#resolveSupport 客户端功能完成的,该功能列出了在“completionItem/resolve”请求期间可以填充的所有属性。所有其他属性(通常是 sortText、filterText、insertText 和 textEdit)必须在 textDocument/completion 响应中提供,并且在解析期间不得更改。

语言服务器协议围绕补全使用以下模型

  • 为了实现跨语言的一致性并尊重不同的客户端,通常客户端负责过滤和排序。这也有一个优点,即客户端可以尝试不同的过滤和排序模型。但是,服务器可以通过设置 filterText / sortText 来强制执行不同的行为。
  • 为了提高速度,如果用户继续输入,客户端应该能够过滤已收到的补全列表。服务器可以使用 CompletionList 并将其标记为 isIncomplete 来选择退出此功能。

补全项提供了影响过滤和排序的其他方法。它们通过使用 insertText 或 textEdit 创建 CompletionItem 来表达。这两种模式的区别如下

  • 补全项提供不带文本编辑的 insertText / label:在此模型中,客户端应使用语言的单词边界规则(例如,解析光标位置下的单词)过滤用户已输入的内容。此模式的原因是它使服务器实现基本补全列表并在客户端上进行过滤变得非常容易。

  • 带文本编辑的补全项:在此模式下,服务器告诉客户端它实际上知道自己在做什么。如果您在当前光标位置创建带有文本编辑的补全项,则不会进行单词猜测,也不会发生自动过滤(如使用 insertText)。此模式可以与排序文本和过滤文本结合使用以自定义两件事。如果文本编辑是替换编辑,则范围表示用于过滤的单词。如果替换更改了文本,则指定要使用的过滤文本很可能是有意义的。

客户端能力:

  • 属性名称(可选):textDocument.completion
  • 属性类型:CompletionClientCapabilities 定义如下
export interface CompletionClientCapabilities {
	/**
	 * Whether completion supports dynamic registration.
	 */
	dynamicRegistration?: boolean;

	/**
	 * The client supports the following `CompletionItem` specific
	 * capabilities.
	 */
	completionItem?: {
		/**
		 * Client supports snippets as insert text.
		 *
		 * A snippet can define tab stops and placeholders with `$1`, `$2`
		 * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
		 * the end of the snippet. Placeholders with equal identifiers are
		 * linked, that is, typing in one will update others too.
		 */
		snippetSupport?: boolean;

		/**
		 * Client supports commit characters on a completion item.
		 */
		commitCharactersSupport?: boolean;

		/**
		 * Client supports these content formats for the documentation
		 * property. The order describes the preferred format of the client.
		 */
		documentationFormat?: MarkupKind[];

		/**
		 * Client supports the deprecated property on a completion item.
		 */
		deprecatedSupport?: boolean;

		/**
		 * Client supports the preselect property on a completion item.
		 */
		preselectSupport?: boolean;

		/**
		 * Client supports the tag property on a completion item. Clients
		 * supporting tags have to handle unknown tags gracefully. Clients
		 * especially need to preserve unknown tags when sending a completion
		 * item back to the server in a resolve call.
		 *
		 * @since 3.15.0
		 */
		tagSupport?: {
			/**
			 * The tags supported by the client.
			 */
			valueSet: CompletionItemTag[];
		};

		/**
		 * Client supports insert replace edit to control different behavior if
		 * a completion item is inserted in the text or should replace text.
		 *
		 * @since 3.16.0
		 */
		insertReplaceSupport?: boolean;

		/**
		 * Indicates which properties a client can resolve lazily on a
		 * completion item. Before version 3.16.0, only the predefined properties
		 * `documentation` and `detail` could be resolved lazily.
		 *
		 * @since 3.16.0
		 */
		resolveSupport?: {
			/**
			 * The properties that a client can resolve lazily.
			 */
			properties: string[];
		};

		/**
		 * The client supports the `insertTextMode` property on
		 * a completion item to override the whitespace handling mode
		 * as defined by the client (see `insertTextMode`).
		 *
		 * @since 3.16.0
		 */
		insertTextModeSupport?: {
			valueSet: InsertTextMode[];
		};

		/**
		 * The client has support for completion item label
		 * details (see also `CompletionItemLabelDetails`).
		 *
		 * @since 3.17.0
		 */
		labelDetailsSupport?: boolean;
	};

	completionItemKind?: {
		/**
		 * The completion item kind values the client supports. When this
		 * property exists, the client also guarantees that it will
		 * handle values outside its set gracefully and falls back
		 * to a default value when unknown.
		 *
		 * If this property is not present, the client only supports
		 * the completion item kinds from `Text` to `Reference` as defined in
		 * the initial version of the protocol.
		 */
		valueSet?: CompletionItemKind[];
	};

	/**
	 * The client supports sending additional context information for a
	 * `textDocument/completion` request.
	 */
	contextSupport?: boolean;

	/**
	 * The client's default when the completion item doesn't provide an
	 * `insertTextMode` property.
	 *
	 * @since 3.17.0
	 */
	insertTextMode?: InsertTextMode;

	/**
	 * The client supports the following `CompletionList` specific
	 * capabilities.
	 *
	 * @since 3.17.0
	 */
	completionList?: {
		/**
		 * The client supports the following itemDefaults on
		 * a completion list.
		 *
		 * The value lists the supported property names of the
		 * `CompletionList.itemDefaults` object. If omitted,
		 * no properties are supported.
		 *
		 * @since 3.17.0
		 */
		itemDefaults?: string[];

		/**
		 * Specifies whether the client supports `CompletionList.applyKind` to
		 * indicate how supported values from `completionList.itemDefaults`
		 * and `completion` will be combined.
		 *
		 * If a client supports `applyKind` it must support it for all fields
		 * that it supports that are listed in `CompletionList.applyKind`. This
		 * means when clients add support for new/future fields in completion
		 * items the MUST also support merge for them if those fields are
		 * defined in `CompletionList.applyKind`.
		 *
		 * @since 3.18.0
		 */
		applyKindSupport?: boolean;
	}
}

服务器能力:

  • 属性名称(可选):completionProvider
  • 属性类型:定义如下的 CompletionOptions
/**
 * Completion options.
 */
export interface CompletionOptions extends WorkDoneProgressOptions {
	/**
	 * Most tools trigger completion request automatically without explicitly
	 * requesting it using a keyboard shortcut (e.g., Ctrl+Space). Typically they
	 * do so when the user starts to type an identifier. For example, if the user
	 * types `c` in a JavaScript file, code complete will automatically pop up and
	 * present `console` besides others as a completion item. Characters that
	 * make up identifiers don't need to be listed here.
	 *
	 * If code complete should automatically be triggered on characters not being
	 * valid inside an identifier (for example, `.` in JavaScript), list them in
	 * `triggerCharacters`.
	 */
	triggerCharacters?: string[];

	/**
	 * The list of all possible characters that commit a completion. This field
	 * can be used if clients don't support individual commit characters per
	 * completion item. See client capability
	 * `completion.completionItem.commitCharactersSupport`.
	 *
	 * If a server provides both `allCommitCharacters` and commit characters on
	 * an individual completion item, the ones on the completion item win.
	 *
	 * @since 3.2.0
	 */
	allCommitCharacters?: string[];

	/**
	 * The server provides support to resolve additional
	 * information for a completion item.
	 */
	resolveProvider?: boolean;

	/**
	 * The server supports the following `CompletionItem` specific
	 * capabilities.
	 *
	 * @since 3.17.0
	 */
	completionItem?: {
		/**
		 * The server has support for completion item label
		 * details (see also `CompletionItemLabelDetails`) when receiving
		 * a completion item in a resolve call.
		 *
		 * @since 3.17.0
		 */
		labelDetailsSupport?: boolean;
	}
}

注册选项:定义如下的 CompletionRegistrationOptions 选项

export interface CompletionRegistrationOptions
	extends TextDocumentRegistrationOptions, CompletionOptions {
}

请求:

  • 方法:textDocument/completion
  • 参数:定义如下的 CompletionParams
export interface CompletionParams extends TextDocumentPositionParams,
	WorkDoneProgressParams, PartialResultParams {
	/**
	 * The completion context. This is only available if the client specifies
	 * to send this using the client capability
	 * `completion.contextSupport === true`
	 */
	context?: CompletionContext;
}
/**
 * How a completion was triggered.
 */
export namespace CompletionTriggerKind {
	/**
	 * Completion was triggered by typing an identifier (automatic code
	 * complete), manual invocation (e.g. Ctrl+Space) or via API.
	 */
	export const Invoked: 1 = 1;

	/**
	 * Completion was triggered by a trigger character specified by
	 * the `triggerCharacters` properties of the
	 * `CompletionRegistrationOptions`.
	 */
	export const TriggerCharacter: 2 = 2;

	/**
	 * Completion was re-triggered as the current completion list is incomplete.
	 */
	export const TriggerForIncompleteCompletions: 3 = 3;
}
export type CompletionTriggerKind = 1 | 2 | 3;
/**
 * Contains additional information about the context in which a completion
 * request is triggered.
 */
export interface CompletionContext {
	/**
	 * How the completion was triggered.
	 */
	triggerKind: CompletionTriggerKind;

	/**
	 * The trigger character (a single character) that
	 * has triggered code complete. Is undefined if
	 * `triggerKind !== CompletionTriggerKind.TriggerCharacter`
	 */
	triggerCharacter?: string;
}

Response:

  • 结果:CompletionItem[] | CompletionList | null。如果提供了 CompletionItem[],则将其解释为完整,因此它与 { isIncomplete: false, items } 相同
/**
 * Represents a collection of [completion items](#CompletionItem) to be
 * presented in the editor.
 */
export interface CompletionList {
	/**
	 * This list is not complete. Further typing should result in recomputing
	 * this list.
	 *
	 * Recomputed lists have all their items replaced (not appended) in the
	 * incomplete completion sessions.
	 */
	isIncomplete: boolean;

	/**
	 * In many cases, the items of an actual completion result share the same
	 * value for properties like `commitCharacters` or the range of a text
	 * edit. A completion list can therefore define item defaults which will
	 * be used if a completion item itself doesn't specify the value.
	 *
	 * If a completion list specifies a default value and a completion item
	 * also specifies a corresponding value, the rules for combining these are
	 * defined by `applyKinds` (if the client supports it), defaulting to
	 * ApplyKind.Replace.
	 *
	 * Servers are only allowed to return default values if the client
	 * signals support for this via the `completionList.itemDefaults`
	 * capability.
	 *
	 * @since 3.17.0
	 */
	itemDefaults?: {
		/**
		 * A default commit character set.
		 *
		 * @since 3.17.0
		 */
		commitCharacters?: string[];

		/**
		 * A default edit range.
		 *
		 * @since 3.17.0
		 */
		editRange?: Range | {
			insert: Range;
			replace: Range;
		};

		/**
		 * A default insert text format.
		 *
		 * @since 3.17.0
		 */
		insertTextFormat?: InsertTextFormat;

		/**
		 * A default insert text mode.
		 *
		 * @since 3.17.0
		 */
		insertTextMode?: InsertTextMode;

		/**
		 * A default data value.
		 *
		 * @since 3.17.0
		 */
		data?: LSPAny;
	}

	/**
	 * Specifies how fields from a completion item should be combined with those
	 * from `completionList.itemDefaults`.
	 *
	 * If unspecified, all fields will be treated as ApplyKind.Replace.
	 *
	 * If a field's value is ApplyKind.Replace, the value from a completion item
	 * (if provided and not `null`) will always be used instead of the value
	 * from `completionItem.itemDefaults`.
	 *
	 * If a field's value is ApplyKind.Merge, the values will be merged using
	 * the rules defined against each field below.
	 *
	 * Servers are only allowed to return `applyKind` if the client
	 * signals support for this via the `completionList.applyKindSupport`
	 * capability.
	 *
	 * @since 3.18.0
	 */
	applyKind?: {
		/**
		 * Specifies whether commitCharacters on a completion will replace or be
		 * merged with those in `completionList.itemDefaults.commitCharacters`.
		 *
		 * If ApplyKind.Replace, the commit characters from the completion item
		 * will always be used unless not provided, in which case those from
		 * `completionList.itemDefaults.commitCharacters` will be used. An
		 * empty list can be used if a completion item does not have any commit
		 * characters and also should not use those from
		 * `completionList.itemDefaults.commitCharacters`.
		 *
		 * If ApplyKind.Merge the commitCharacters for the completion will be
		 * the union of all values in both
		 * `completionList.itemDefaults.commitCharacters` and the completion's
		 * own `commitCharacters`.
		 *
		 * @since 3.18.0
		 */
		commitCharacters?: ApplyKind;

		/**
		 * Specifies whether the `data` field on a completion will replace or
		 * be merged with data from `completionList.itemDefaults.data`.
		 *
		 * If ApplyKind.Replace, the data from the completion item will be used
		 * if provided (and not `null`), otherwise
		 * `completionList.itemDefaults.data` will be used. An empty object can
		 * be used if a completion item does not have any data but also should
		 * not use the value from `completionList.itemDefaults.data`.
		 *
		 * If ApplyKind.Merge, a shallow merge will be performed between
		 * `completionList.itemDefaults.data` and the completion's own data
		 * using the following rules:
		 *
		 * - If a completion's `data` field is not provided (or `null`), the
		 *   entire `data` field from `completionList.itemDefaults.data` will be
		 *   used as-is.
		 * - If a completion's `data` field is provided, each field will
		 *   overwrite the field of the same name in
		 *   `completionList.itemDefaults.data` but no merging of nested fields
		 *   within that value will occur.
		 *
		 * @since 3.18.0
		 */
		data?: ApplyKind;
	}

	/**
	 * The completion items.
	 */
	items: CompletionItem[];
}
/**
 * Defines whether the insert text in a completion item should be interpreted as
 * plain text or a snippet.
 */
export namespace InsertTextFormat {
	/**
	 * The primary text to be inserted is treated as a plain string.
	 */
	export const PlainText = 1;

	/**
	 * The primary text to be inserted is treated as a snippet.
	 *
	 * A snippet can define tab stops and placeholders with `$1`, `$2`
	 * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
	 * the end of the snippet. Placeholders with equal identifiers are linked,
	 * that is, typing in one will update others too.
	 */
	export const Snippet = 2;
}

export type InsertTextFormat = 1 | 2;
/**
 * Completion item tags are extra annotations that tweak the rendering of a
 * completion item.
 *
 * @since 3.15.0
 */
export namespace CompletionItemTag {
	/**
	 * Render a completion as obsolete, usually using a strike-out.
	 */
	export const Deprecated = 1;
}

export type CompletionItemTag = 1;
/**
 * A special text edit to provide an insert and a replace operation.
 *
 * @since 3.16.0
 */
export interface InsertReplaceEdit {
	/**
	 * The string to be inserted.
	 */
	newText: string;

	/**
	 * The range if the insert is requested.
	 */
	insert: Range;

	/**
	 * The range if the replace is requested.
	 */
	replace: Range;
}
/**
 * How whitespace and indentation is handled during completion
 * item insertion.
 *
 * @since 3.16.0
 */
export namespace InsertTextMode {
	/**
	 * The insertion or replace strings are taken as-is. If the
	 * value is multiline, the lines below the cursor will be
	 * inserted using the indentation defined in the string value.
	 * The client will not apply any kind of adjustments to the
	 * string.
	 */
	export const asIs: 1 = 1;

	/**
	 * The editor adjusts leading whitespace of new lines so that
	 * they match the indentation up to the cursor of the line for
	 * which the item is accepted.
	 *
	 * Consider a line like this: <2tabs><cursor><3tabs>foo. Accepting a
	 * multi line completion item is indented using 2 tabs and all
	 * following lines inserted will be indented using 2 tabs as well.
	 */
	export const adjustIndentation: 2 = 2;
}

export type InsertTextMode = 1 | 2;
/**
 * Additional details for a completion item label.
 *
 * @since 3.17.0
 */
export interface CompletionItemLabelDetails {

	/**
	 * An optional string which is rendered less prominently directly after
	 * {@link CompletionItem.label label}, without any spacing. Should be
	 * used for function signatures or type annotations.
	 */
	detail?: string;

	/**
	 * An optional string which is rendered less prominently after
	 * {@link CompletionItemLabelDetails.detail}. Should be used for fully qualified
	 * names or file paths.
	 */
	description?: string;
}
/**
 * Defines how values from a set of defaults and an individual item will be
 * merged.
 *
 * @since 3.18.0
 */
export namespace ApplyKind {
	/**
	 * The value from the individual item (if provided and not `null`) will be
	 * used instead of the default.
	 */
	export const Replace: 1 = 1;

	/**
	 * The value from the item will be merged with the default.
	 *
	 * The specific rules for mergeing values are defined against each field
	 * that supports merging.
	 */
	export const Merge: 2 = 2;
}

/**
 * Defines how values from a set of defaults and an individual item will be
 * merged.
 *
 * @since 3.18.0
 */
export type ApplyKind = 1 | 2;
export interface CompletionItem {

	/**
	 * The label of this completion item.
	 *
	 * The label property is also by default the text that
	 * is inserted when selecting this completion.
	 *
	 * If label details are provided, the label itself should
	 * be an unqualified name of the completion item.
	 */
	label: string;

	/**
	 * Additional details for the label.
	 *
	 * @since 3.17.0
	 */
	labelDetails?: CompletionItemLabelDetails;

	/**
	 * The kind of this completion item. Based on the kind,
	 * an icon is chosen by the editor. The standardized set
	 * of available values is defined in `CompletionItemKind`.
	 */
	kind?: CompletionItemKind;

	/**
	 * Tags for this completion item.
	 *
	 * @since 3.15.0
	 */
	tags?: CompletionItemTag[];

	/**
	 * A human-readable string with additional information
	 * about this item, like type or symbol information.
	 */
	detail?: string;

	/**
	 * A human-readable string that represents a doc-comment.
	 */
	documentation?: string | MarkupContent;

	/**
	 * Indicates if this item is deprecated.
	 *
	 * @deprecated Use `tags` instead if supported.
	 */
	deprecated?: boolean;

	/**
	 * Select this item when showing.
	 *
	 * *Note* that only one completion item can be selected and that the
	 * tool / client decides which item that is. The rule is that the *first*
	 * item of those that match best is selected.
	 */
	preselect?: boolean;

	/**
	 * A string that should be used when comparing this item
	 * with other items. When omitted, the label is used
	 * as the sort text for this item.
	 */
	sortText?: string;

	/**
	 * A string that should be used when filtering a set of
	 * completion items. When omitted, the label is used as the
	 * filter text for this item.
	 */
	filterText?: string;

	/**
	 * A string that should be inserted into a document when selecting
	 * this completion. When omitted, the label is used as the insert text
	 * for this item.
	 *
	 * The `insertText` is subject to interpretation by the client side.
	 * Some tools might not take the string literally. For example,
	 * when code complete is requested for `con<cursor position>`
	 * and a completion item with an `insertText` of `console` is provided,
	 * VSCode will only insert `sole`. Therefore, it is
	 * recommended to use `textEdit` instead since it avoids additional client
	 * side interpretation.
	 */
	insertText?: string;

	/**
	 * The format of the insert text. The format applies to both the
	 * `insertText` property and the `newText` property of a provided
	 * `textEdit`. If omitted, defaults to `InsertTextFormat.PlainText`.
	 *
	 * Please note that the insertTextFormat doesn't apply to
	 * `additionalTextEdits`.
	 */
	insertTextFormat?: InsertTextFormat;

	/**
	 * How whitespace and indentation is handled during completion
	 * item insertion. If not provided, the client's default value depends on
	 * the `textDocument.completion.insertTextMode` client capability.
	 *
	 * @since 3.16.0
	 * @since 3.17.0 - support for `textDocument.completion.insertTextMode`
	 */
	insertTextMode?: InsertTextMode;

	/**
	 * An edit which is applied to a document when selecting this completion.
	 * When an edit is provided, the value of `insertText` is ignored.
	 *
	 * *Note:* The range of the edit must be a single line range and it must
	 * contain the position at which completion has been requested. Despite this
	 * limitation, your edit can write multiple lines.
	 *
	 * Most editors support two different operations when accepting a completion
	 * item. One is to insert a completion text and the other is to replace an
	 * existing text with a completion text. Since this can usually not be
	 * predetermined by a server it can report both ranges. Clients need to
	 * signal support for `InsertReplaceEdit`s via the
	 * `textDocument.completion.completionItem.insertReplaceSupport` client
	 * capability property.
	 *
	 * *Note 1:* The text edit's range as well as both ranges from an insert
	 * replace edit must be a single line and they must contain the position
	 * at which completion has been requested. In both cases, the new text can
	 * consist of multiple lines.
	 * *Note 2:* If an `InsertReplaceEdit` is returned, the edit's insert range
	 * must be a prefix of the edit's replace range, meaning it must be
	 * contained in and starting at the same position.
	 *
	 * @since 3.16.0 additional type `InsertReplaceEdit`
	 */
	textEdit?: TextEdit | InsertReplaceEdit;

	/**
	 * The edit text used if the completion item is part of a CompletionList and
	 * CompletionList defines an item default for the text edit range.
	 *
	 * Clients will only honor this property if they opt into completion list
	 * item defaults using the capability `completionList.itemDefaults`.
	 *
	 * If not provided and a list's default range is provided, the label
	 * property is used as a text.
	 *
	 * @since 3.17.0
	 */
	textEditText?: string;

	/**
	 * An optional array of additional text edits that are applied when
	 * selecting this completion. Edits must not overlap (including the same
	 * insert position) with the main edit nor with themselves.
	 *
	 * Additional text edits should be used to change text unrelated to the
	 * current cursor position (for example adding an import statement at the
	 * top of the file if the completion item will insert an unqualified type).
	 */
	additionalTextEdits?: TextEdit[];

	/**
	 * An optional set of characters that, when pressed while this completion is
	 * active, will accept it first and then type that character. *Note* that all
	 * commit characters should have `length=1` and that superfluous characters
	 * will be ignored.
	 */
	commitCharacters?: string[];

	/**
	 * An optional command that is executed *after* inserting this completion.
	 * *Note* that additional modifications to the current document should be
	 * described with the additionalTextEdits-property.
	 */
	command?: Command;

	/**
	 * A data entry field that is preserved on a completion item between
	 * a completion and a completion resolve request.
	 */
	data?: LSPAny;
}
/**
 * The kind of a completion entry.
 */
export namespace CompletionItemKind {
	export const Text = 1;
	export const Method = 2;
	export const Function = 3;
	export const Constructor = 4;
	export const Field = 5;
	export const Variable = 6;
	export const Class = 7;
	export const Interface = 8;
	export const Module = 9;
	export const Property = 10;
	export const Unit = 11;
	export const Value = 12;
	export const Enum = 13;
	export const Keyword = 14;
	export const Snippet = 15;
	export const Color = 16;
	export const File = 17;
	export const Reference = 18;
	export const Folder = 19;
	export const EnumMember = 20;
	export const Constant = 21;
	export const Struct = 22;
	export const Event = 23;
	export const Operator = 24;
	export const TypeParameter = 25;
}

export type CompletionItemKind = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25;
  • 部分结果:CompletionItem[] 或 CompletionList,后跟 CompletionItem[]。如果提供的第一个结果项的类型为 CompletionList,则 CompletionItem[] 的后续部分结果将添加到 CompletionList 的 items 属性中。
  • 错误:如果在完成请求期间发生异常,则设置代码和消息。

完成项支持代码片段(参见 InsertTextFormat.Snippet)。代码片段格式如下

代码片段语法

代码片段的 body 可以使用特殊构造来控制光标和插入的文本。支持以下功能及其语法

制表位

使用制表符停止位,您可以让编辑器光标在代码片段内移动。使用 $1、$2 等来指定光标位置。数字是访问制表符停止位的顺序。多个制表符停止位相互链接并同步更新。

占位符

占位符是带值的制表位,例如 ${1:foo}。占位符文本将被插入并选中,以便可以轻松更改。占位符可以嵌套,例如 ${1:another ${2:placeholder}}。

选择

占位符可以有选择作为值。语法是用竖线字符括起来的逗号分隔的值枚举,例如 ${1|one,two,three|}。插入代码片段并选中占位符时,选择将提示用户选择其中一个值。

变量

使用 $name 或 ${name:default} 可以插入变量的值。如果未设置变量,则插入其 *默认值* 或空字符串。如果变量未知(即未定义其名称),则插入变量的名称并将其转换为占位符。

可以使用以下变量

  • TM_SELECTED_TEXT 当前选定的文本或空字符串
  • TM_CURRENT_LINE 当前行的内容
  • TM_CURRENT_WORD 光标下的单词内容或空字符串
  • TM_LINE_INDEX 基于零的行号
  • TM_LINE_NUMBER 基于一的行号
  • TM_FILENAME 当前文档的文件名
  • TM_FILENAME_BASE 不带扩展名的当前文档的文件名
  • TM_DIRECTORY 当前文档的目录
  • TM_FILEPATH 当前文档的完整文件路径
变量转换

转换允许您在插入变量之前修改变量的值。转换的定义由三部分组成

  1. 一个 正则表达式,用于匹配变量的值,如果变量无法解析,则匹配空字符串。
  2. 一个“格式字符串”,允许引用正则表达式中的匹配组。格式字符串允许条件插入和简单修改。
  3. 传递给正则表达式的选项。

以下示例插入当前文件的名称,不带其结尾,因此它将 foo.txt 转换为 foo。

${TM_FILENAME/(.*)\..+$/$1/}
  |           |         | |
  |           |         | |-> no options
  |           |         |
  |           |         |-> references the contents of the first
  |           |             capture group
  |           |
  |           |-> regex to capture everything before
  |               the final `.suffix`
  |
  |-> resolves to the filename
语法

以下是 EBNF(扩展巴科斯范式,XML 变体)中代码片段的语法。使用 \(反斜杠),您可以转义 $、} 和 \。在选择元素内,反斜杠还转义逗号和管道字符。只能转义需要转义的字符,因此在这些构造中不应转义 $,在选择构造内也不应转义 $ 或 }。

any         ::= tabstop | placeholder | choice | variable | text
tabstop     ::= '$' int | '${' int '}'
placeholder ::= '${' int ':' any '}'
choice      ::= '${' int '|' choicetext (',' choicetext)* '|}'
variable    ::= '$' var | '${' var }'
                | '${' var ':' any '}'
                | '${' var '/' regex '/' (format | formattext)* '/' options '}'
format      ::= '$' int | '${' int '}'
                /* Transforms the text to be uppercase, lowercase, or capitalized, respectively. */
                | '${' int ':' ('/upcase' | '/downcase' | '/capitalize') '}'
                /* Inserts the 'ifOnly' text if the match is non-empty. */
                | '${' int ':+' ifOnly '}'
                /* Inserts the 'if' text if the match is non-empty,
                   otherwise the 'else' text will be inserted. */
                | '${' int ':?' if ':' else '}'
                /* Inserts the 'else' text if the match is empty. */
                | '${' int ':-' else '}' | '${' int ':' else '}'
regex       ::= Regular Expression value (ctor-string)
options     ::= Regular Expression option (ctor-options)
var         ::= [_a-zA-Z] [_a-zA-Z0-9]*
int         ::= [0-9]+
text        ::= ([^$}\] | '\$' | '\}' | '\\')*
choicetext  ::= ([^,|\] | '\,' | '\|' | '\\')*
formattext  ::= ([^$/\] | '\$' | '\/' | '\\')*
ifOnly      ::= text
if          ::= ([^:\] | '\:' | '\\')*
else        ::= text

完成项解析请求 (:leftwards_arrow_with_hook:)

该请求从客户端发送到服务器,以解析给定完成项的附加信息。

请求:

  • 方法:completionItem/resolve
  • 参数:CompletionItem

Response:

  • 结果:CompletionItem
  • 错误:如果在完成解析请求期间发生异常,则设置代码和消息。

发布诊断通知 (:arrow_left:)

诊断通知从服务器发送到客户端,以表示验证运行的结果。

诊断由服务器“拥有”,因此在必要时清除它们是服务器的责任。以下规则用于生成诊断的 VS Code 服务器

  • 如果一种语言只包含一个文件(例如 HTML),则当文件关闭时,服务器会清除诊断。请注意,打开/关闭事件不一定反映用户在用户界面中看到的内容。这些事件是所有权事件。因此,在当前版本的规范中,即使文件在用户界面中不可见,也可能不会清除问题,因为客户端尚未关闭文件。
  • 如果一种语言具有项目系统(例如 C#),则在文件关闭时不会清除诊断。当项目打开时,所有文件的所有诊断都会重新计算(或从缓存中读取)。

当文件更改时,服务器负责重新计算诊断并将其推送到客户端。如果计算出的集合为空,则服务器必须推送空数组以清除以前的诊断。新推送的诊断始终替换以前推送的诊断。客户端不会发生合并。

另请参阅 诊断 部分。

客户端能力:

  • 属性名称(可选):textDocument.publishDiagnostics
  • 属性类型:定义如下的 PublishDiagnosticsClientCapabilities
export interface PublishDiagnosticsClientCapabilities {
	/**
	 * Whether the clients accepts diagnostics with related information.
	 */
	relatedInformation?: boolean;

	/**
	 * Client supports the tag property to provide meta data about a diagnostic.
	 * Clients supporting tags have to handle unknown tags gracefully.
	 *
	 * @since 3.15.0
	 */
	tagSupport?: {
		/**
		 * The tags supported by the client.
		 */
		valueSet: DiagnosticTag[];
	};

	/**
	 * Whether the client interprets the version property of the
	 * `textDocument/publishDiagnostics` notification's parameter.
	 *
	 * @since 3.15.0
	 */
	versionSupport?: boolean;

	/**
	 * Client supports a codeDescription property.
	 *
	 * @since 3.16.0
	 */
	codeDescriptionSupport?: boolean;

	/**
	 * Whether code action supports the `data` property which is
	 * preserved between a `textDocument/publishDiagnostics` and
	 * `textDocument/codeAction` request.
	 *
	 * @since 3.16.0
	 */
	dataSupport?: boolean;
}

通知:

  • 方法:textDocument/publishDiagnostics
  • 参数:定义如下的 PublishDiagnosticsParams
interface PublishDiagnosticsParams {
	/**
	 * The URI for which diagnostic information is reported.
	 */
	uri: DocumentUri;

	/**
	 * Optionally, the version number of the document the diagnostics are
	 * published for.
	 *
	 * @since 3.15.0
	 */
	version?: integer;

	/**
	 * An array of diagnostic information items.
	 */
	diagnostics: Diagnostic[];
}

拉取诊断

诊断目前通过通知从服务器发布到客户端。此模型的优点是,对于工作区范围的诊断,服务器可以自由地在服务器首选的时间点计算它们。另一方面,此方法的缺点是服务器无法优先计算用户正在输入的文件或编辑器中可见的文件。从 textDocument/didOpen 和 textDocument/didChange 通知推断客户端的 UI 状态可能会导致误报,因为这些通知是所有权转移通知。

因此,规范引入了诊断拉取请求的概念,以赋予客户端对应计算诊断的文档以及计算时间点的更大控制权。

客户端能力:

  • 属性名称(可选):textDocument.diagnostic
  • 属性类型:DiagnosticClientCapabilities 定义如下
/**
 * Client capabilities specific to diagnostic pull requests.
 *
 * @since 3.17.0
 */
export interface DiagnosticClientCapabilities {
	/**
	 * Whether implementation supports dynamic registration. If this is set to
	 * `true`, the client supports the new
	 * `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`
	 * return value for the corresponding server capability as well.
	 */
	dynamicRegistration?: boolean;

	/**
	 * Whether the clients supports related documents for document diagnostic
	 * pulls.
	 */
	relatedDocumentSupport?: boolean;

	/**
	 * Whether the client supports `MarkupContent` in diagnostic messages.
	 *
	 * @since 3.18.0
	 * @proposed
	 */
	markupMessageSupport?: boolean;
}

服务器能力:

  • 属性名称(可选):diagnosticProvider
  • 属性类型:DiagnosticOptions 定义如下
/**
 * Diagnostic options.
 *
 * @since 3.17.0
 */
export interface DiagnosticOptions extends WorkDoneProgressOptions {
	/**
	 * An optional identifier under which the diagnostics are
	 * managed by the client.
	 */
	identifier?: string;

	/**
	 * Whether the language has inter file dependencies, meaning that
	 * editing code in one file can result in a different diagnostic
	 * set in another file. Inter file dependencies are common for
	 * most programming languages and typically uncommon for linters.
	 */
	interFileDependencies: boolean;

	/**
	 * The server provides support for workspace diagnostics as well.
	 */
	workspaceDiagnostics: boolean;
}

注册选项:DiagnosticRegistrationOptions 选项定义如下

/**
 * Diagnostic registration options.
 *
 * @since 3.17.0
 */
export interface DiagnosticRegistrationOptions extends
	TextDocumentRegistrationOptions, DiagnosticOptions,
	StaticRegistrationOptions {
}
文档诊断(:leftwards_arrow_with_hook:)

文本文档诊断请求从客户端发送到服务器,以要求服务器计算给定文档的诊断。与其他的拉取请求一样,服务器被要求计算文档当前同步版本的诊断。

请求:

  • 方法:'textDocument/diagnostic'。
  • 参数:DocumentDiagnosticParams 定义如下
/**
 * Parameters of the document diagnostic request.
 *
 * @since 3.17.0
 */
export interface DocumentDiagnosticParams extends WorkDoneProgressParams,
	PartialResultParams {
	/**
	 * The text document.
	 */
	textDocument: TextDocumentIdentifier;

	/**
	 * The additional identifier  provided during registration.
	 */
	identifier?: string;

	/**
	 * The result ID of a previous response, if provided.
	 */
	previousResultId?: string;
}

Response:

  • 结果:DocumentDiagnosticReport 定义如下
/**
 * The result of a document diagnostic pull request. A report can
 * either be a full report, containing all diagnostics for the
 * requested document, or an unchanged report, indicating that nothing
 * has changed in terms of diagnostics in comparison to the last
 * pull request.
 *
 * @since 3.17.0
 */
export type DocumentDiagnosticReport = RelatedFullDocumentDiagnosticReport
	| RelatedUnchangedDocumentDiagnosticReport;
/**
 * The document diagnostic report kinds.
 *
 * @since 3.17.0
 */
export namespace DocumentDiagnosticReportKind {
	/**
	 * A diagnostic report with a full
	 * set of problems.
	 */
	export const Full = 'full';

	/**
	 * A report indicating that the last
	 * returned report is still accurate.
	 */
	export const Unchanged = 'unchanged';
}

export type DocumentDiagnosticReportKind = 'full' | 'unchanged';
/**
 * A diagnostic report with a full set of problems.
 *
 * @since 3.17.0
 */
export interface FullDocumentDiagnosticReport {
	/**
	 * A full document diagnostic report.
	 */
	kind: DocumentDiagnosticReportKind.Full;

	/**
	 * An optional result ID. If provided, it will
	 * be sent on the next diagnostic request for the
	 * same document.
	 */
	resultId?: string;

	/**
	 * The actual items.
	 */
	items: Diagnostic[];
}
/**
 * A diagnostic report indicating that the last returned
 * report is still accurate.
 *
 * @since 3.17.0
 */
export interface UnchangedDocumentDiagnosticReport {
	/**
	 * A document diagnostic report indicating
	 * no changes to the last result. A server can
	 * only return `unchanged` if result IDs are
	 * provided.
	 */
	kind: DocumentDiagnosticReportKind.Unchanged;

	/**
	 * A result ID which will be sent on the next
	 * diagnostic request for the same document.
	 */
	resultId: string;
}
/**
 * A full diagnostic report with a set of related documents.
 *
 * @since 3.17.0
 */
export interface RelatedFullDocumentDiagnosticReport extends
	FullDocumentDiagnosticReport {
	/**
	 * Diagnostics of related documents. This information is useful
	 * in programming languages where code in a file A can generate
	 * diagnostics in a file B which A depends on. An example of
	 * such a language is C/C++, where macro definitions in a file
	 * a.cpp can result in errors in a header file b.hpp.
	 *
	 * @since 3.17.0
	 */
	relatedDocuments?: {
		[uri: string /** DocumentUri */]:
			FullDocumentDiagnosticReport | UnchangedDocumentDiagnosticReport;
	};
}
/**
 * An unchanged diagnostic report with a set of related documents.
 *
 * @since 3.17.0
 */
export interface RelatedUnchangedDocumentDiagnosticReport extends
	UnchangedDocumentDiagnosticReport {
	/**
	 * Diagnostics of related documents. This information is useful
	 * in programming languages where code in a file A can generate
	 * diagnostics in a file B which A depends on. An example of
	 * such a language is C/C++, where macro definitions in a file
	 * a.cpp can result in errors in a header file b.hpp.
	 *
	 * @since 3.17.0
	 */
	relatedDocuments?: {
		[uri: string /** DocumentUri */]:
			FullDocumentDiagnosticReport | UnchangedDocumentDiagnosticReport;
	};
}
  • 部分结果:发送的第一个字面量必须是 DocumentDiagnosticReport,后跟 n 个 DocumentDiagnosticReportPartialResult 字面量,定义如下
/**
 * A partial result for a document diagnostic report.
 *
 * @since 3.17.0
 */
export interface DocumentDiagnosticReportPartialResult {
	relatedDocuments: {
		[uri: string /** DocumentUri */]:
			FullDocumentDiagnosticReport | UnchangedDocumentDiagnosticReport;
	};
}
  • 错误:如果在诊断请求期间发生异常,则设置代码和消息。服务器也允许返回带有代码 ServerCancelled 的错误,表示服务器目前无法计算结果。服务器可以返回 DiagnosticServerCancellationData 以指示客户端是否应重新触发请求。如果没有提供数据,则默认为 { retriggerRequest: true }
/**
 * Cancellation data returned from a diagnostic request.
 *
 * @since 3.17.0
 */
export interface DiagnosticServerCancellationData {
	retriggerRequest: boolean;
}
工作区诊断(:leftwards_arrow_with_hook:)

工作区诊断请求从客户端发送到服务器,以要求服务器计算先前从服务器推送到客户端的工作区范围诊断。与文档诊断请求相反,工作区请求可能长时间运行,并且不受特定工作区或文档状态的限制。如果客户端支持工作区诊断拉取的流式传输,则允许为同一文档 URI 多次提供文档诊断报告。最后报告的将覆盖以前的报告。

如果客户端在工作区诊断请求中收到针对某个文档的诊断报告,并且客户端也针对该文档发出了单独的文档诊断拉取请求,则客户端需要决定哪些诊断获胜并应显示。通常

  • 更高文档版本的诊断应优先于较低文档版本的诊断(例如,请注意文档版本正在稳步增加)
  • 文档拉取中的诊断应优先于工作区拉取中的诊断。

请求:

  • 方法:'workspace/diagnostic'。
  • 参数:WorkspaceDiagnosticParams 定义如下
/**
 * Parameters of the workspace diagnostic request.
 *
 * @since 3.17.0
 */
export interface WorkspaceDiagnosticParams extends WorkDoneProgressParams,
	PartialResultParams {
	/**
	 * The additional identifier provided during registration.
	 */
	identifier?: string;

	/**
	 * The currently known diagnostic reports with their
	 * previous result IDs.
	 */
	previousResultIds: PreviousResultId[];
}
/**
 * A previous result ID in a workspace pull request.
 *
 * @since 3.17.0
 */
export interface PreviousResultId {
	/**
	 * The URI for which the client knows a
	 * result ID.
	 */
	uri: DocumentUri;

	/**
	 * The value of the previous result ID.
	 */
	value: string;
}

Response:

  • 结果:WorkspaceDiagnosticReport 定义如下
/**
 * A workspace diagnostic report.
 *
 * @since 3.17.0
 */
export interface WorkspaceDiagnosticReport {
	items: WorkspaceDocumentDiagnosticReport[];
}
/**
 * A full document diagnostic report for a workspace diagnostic result.
 *
 * @since 3.17.0
 */
export interface WorkspaceFullDocumentDiagnosticReport extends
	FullDocumentDiagnosticReport {

	/**
	 * The URI for which diagnostic information is reported.
	 */
	uri: DocumentUri;

	/**
	 * The version number for which the diagnostics are reported.
	 * If the document is not marked as open, `null` can be provided.
	 */
	version: integer | null;
}
/**
 * An unchanged document diagnostic report for a workspace diagnostic result.
 *
 * @since 3.17.0
 */
export interface WorkspaceUnchangedDocumentDiagnosticReport extends
	UnchangedDocumentDiagnosticReport {

	/**
	 * The URI for which diagnostic information is reported.
	 */
	uri: DocumentUri;

	/**
	 * The version number for which the diagnostics are reported.
	 * If the document is not marked as open, `null` can be provided.
	 */
	version: integer | null;
};
/**
 * A workspace diagnostic document report.
 *
 * @since 3.17.0
 */
export type WorkspaceDocumentDiagnosticReport =
	WorkspaceFullDocumentDiagnosticReport
	| WorkspaceUnchangedDocumentDiagnosticReport;
  • 部分结果:发送的第一个字面量必须是 WorkspaceDiagnosticReport,后跟 n 个 WorkspaceDiagnosticReportPartialResult 字面量,定义如下
/**
 * A partial result for a workspace diagnostic report.
 *
 * @since 3.17.0
 */
export interface WorkspaceDiagnosticReportPartialResult {
	items: WorkspaceDocumentDiagnosticReport[];
}
  • 错误:如果在诊断请求期间发生异常,则设置代码和消息。服务器也允许返回带有代码 ServerCancelled 的错误,表示服务器目前无法计算结果。服务器可以返回 DiagnosticServerCancellationData 以指示客户端是否应重新触发请求。如果没有提供数据,则默认为 { retriggerRequest: true }
诊断刷新(:arrow_right_hook:)

从服务器向客户端发送 workspace/diagnostic/refresh 请求。服务器可以使用它来要求客户端刷新所有必要的文档和工作区诊断。如果服务器检测到需要重新计算所有诊断的项目范围配置更改,这将很有用。

客户端能力:

  • 属性名称(可选):workspace.diagnostics
  • 属性类型:DiagnosticWorkspaceClientCapabilities 定义如下
/**
 * Workspace client capabilities specific to diagnostic pull requests.
 *
 * @since 3.17.0
 */
export interface DiagnosticWorkspaceClientCapabilities {
	/**
	 * Whether the client implementation supports a refresh request sent from
	 * the server to the client.
	 *
	 * Note that this event is global and will force the client to refresh all
	 * pulled diagnostics currently shown. It should be used with absolute care
	 * and is useful for situation where a server, for example, detects a project
	 * wide change that requires such a calculation.
	 */
	refreshSupport?: boolean;
}

请求:

  • 方法:workspace/diagnostic/refresh
  • 参数:无

Response:

  • 结果:void
  • 错误:如果在“workspace/diagnostic/refresh”请求期间发生异常,则设置代码和消息
实现考量

通常,语言服务器规范不强制任何特定的客户端实现,因为这些通常取决于客户端 UI 的行为。但是,由于诊断可以在文档和工作区级别提供,这里有一些提示

  • 客户端应积极拉取用户正在键入的文档。
  • 如果服务器发出文件间依赖关系信号,客户端还应拉取可见文档以确保准确诊断。但是,拉取频率应较低。
  • 如果服务器发出工作区拉取支持信号,客户端也应拉取工作区诊断。建议客户端实现工作区拉取的部分结果进度,以允许服务器长时间保持请求打开。如果服务器关闭工作区诊断拉取请求,客户端应重新触发该请求。

签名帮助请求 (:leftwards_arrow_with_hook:)

签名帮助请求从客户端发送到服务器,以在给定光标位置请求签名信息。

客户端能力:

  • 属性名称(可选):textDocument.signatureHelp
  • 属性类型:定义如下的 SignatureHelpClientCapabilities
export interface SignatureHelpClientCapabilities {
	/**
	 * Whether signature help supports dynamic registration.
	 */
	dynamicRegistration?: boolean;

	/**
	 * The client supports the following `SignatureInformation`
	 * specific properties.
	 */
	signatureInformation?: {
		/**
		 * Client supports the following content formats for the documentation
		 * property. The order describes the preferred format of the client.
		 */
		documentationFormat?: MarkupKind[];

		/**
		 * Client capabilities specific to parameter information.
		 */
		parameterInformation?: {
			/**
			 * The client supports processing label offsets instead of a
			 * simple label string.
			 *
			 * @since 3.14.0
			 */
			labelOffsetSupport?: boolean;
		};

		/**
		 * The client supports the `activeParameter` property on
		 * `SignatureInformation` literal.
		 *
		 * @since 3.16.0
		 */
		activeParameterSupport?: boolean;

		/**
		 * The client supports the `activeParameter` property on
		 * `SignatureHelp`/`SignatureInformation` being set to `null` to
		 * indicate that no parameter should be active.
		 *
		 * @since 3.18.0
		 */
		noActiveParameterSupport?: boolean;

	};

	/**
	 * The client supports sending additional context information for a
	 * `textDocument/signatureHelp` request. A client that opts into
	 * contextSupport will also support the `retriggerCharacters` on
	 * `SignatureHelpOptions`.
	 *
	 * @since 3.15.0
	 */
	contextSupport?: boolean;
}

服务器能力:

  • 属性名称(可选):signatureHelpProvider
  • 属性类型:定义如下的 SignatureHelpOptions
export interface SignatureHelpOptions extends WorkDoneProgressOptions {
	/**
	 * The characters that trigger signature help
	 * automatically.
	 */
	triggerCharacters?: string[];

	/**
	 * List of characters that re-trigger signature help.
	 *
	 * These trigger characters are only active when signature help is already
	 * showing. All trigger characters are also counted as re-trigger
	 * characters.
	 *
	 * @since 3.15.0
	 */
	retriggerCharacters?: string[];
}

注册选项:定义如下的 SignatureHelpRegistrationOptions

export interface SignatureHelpRegistrationOptions
	extends TextDocumentRegistrationOptions, SignatureHelpOptions {
}

请求:

  • 方法:textDocument/signatureHelp
  • 参数:定义如下的 SignatureHelpParams
export interface SignatureHelpParams extends TextDocumentPositionParams,
	WorkDoneProgressParams {
	/**
	 * The signature help context. This is only available if the client
	 * specifies to send this using the client capability
	 * `textDocument.signatureHelp.contextSupport === true`
	 *
	 * @since 3.15.0
	 */
	context?: SignatureHelpContext;
}
/**
 * How a signature help was triggered.
 *
 * @since 3.15.0
 */
export namespace SignatureHelpTriggerKind {
	/**
	 * Signature help was invoked manually by the user or by a command.
	 */
	export const Invoked: 1 = 1;
	/**
	 * Signature help was triggered by a trigger character.
	 */
	export const TriggerCharacter: 2 = 2;
	/**
	 * Signature help was triggered by the cursor moving or by the document
	 * content changing.
	 */
	export const ContentChange: 3 = 3;
}
export type SignatureHelpTriggerKind = 1 | 2 | 3;
/**
 * Additional information about the context in which a signature help request
 * was triggered.
 *
 * @since 3.15.0
 */
export interface SignatureHelpContext {
	/**
	 * Action that caused signature help to be triggered.
	 */
	triggerKind: SignatureHelpTriggerKind;

	/**
	 * Character that caused signature help to be triggered.
	 *
	 * This is undefined when triggerKind !==
	 * SignatureHelpTriggerKind.TriggerCharacter
	 */
	triggerCharacter?: string;

	/**
	 * `true` if signature help was already showing when it was triggered.
	 *
	 * Retriggers occur when the signature help is already active and can be
	 * caused by actions such as typing a trigger character, a cursor move, or
	 * document content changes.
	 */
	isRetrigger: boolean;

	/**
	 * The currently active `SignatureHelp`.
	 *
	 * The `activeSignatureHelp` has its `SignatureHelp.activeSignature` field
	 * updated based on the user navigating through available signatures.
	 */
	activeSignatureHelp?: SignatureHelp;
}

Response:

  • 结果:定义如下的 SignatureHelp | null
/**
 * Signature help represents the signature of something
 * callable. There can be multiple signatures,
 * but only one active one and only one active parameter.
 */
export interface SignatureHelp {
	/**
	 * One or more signatures. If no signatures are available,
	 * the signature help request should return `null`.
	 */
	signatures: SignatureInformation[];

	/**
	 * The active signature. If omitted or the value lies outside the
	 * range of `signatures`, the value defaults to zero or is ignored if
	 * the `SignatureHelp` has no signatures.
	 *
	 * Whenever possible, implementers should make an active decision about
	 * the active signature and shouldn't rely on a default value.
	 *
	 * In future versions of the protocol, this property might become
	 * mandatory to better express this.
	 */
	activeSignature?: uinteger;

	/**
	 * The active parameter of the active signature.
	 *
	 * If `null`, no parameter of the signature is active (for example, a named
	 * argument that does not match any declared parameters). This is only valid
	 * since 3.18.0 and if the client specifies the client capability
	 * `textDocument.signatureHelp.noActiveParameterSupport === true`.
	 *
	 * If omitted or the value lies outside the range of
	 * `signatures[activeSignature].parameters`, it defaults to 0 if the active
	 * signature has parameters.
	 *
	 * If the active signature has no parameters, it is ignored.
	 *
	 * In future versions of the protocol this property might become
	 * mandatory (but still nullable) to better express the active parameter if
	 * the active signature does have any.
	 */
	activeParameter?: uinteger | null;
}
/**
 * Represents the signature of something callable. A signature
 * can have a label, like a function-name, a doc-comment, and
 * a set of parameters.
 */
export interface SignatureInformation {
	/**
	 * The label of this signature. Will be shown in the UI.
	 */
	label: string;

	/**
	 * The human-readable doc-comment of this signature.
     * Will be shown in the UI but can be omitted.
	 */
	documentation?: string | MarkupContent;

	/**
	 * The parameters of this signature.
	 */
	parameters?: ParameterInformation[];

	/**
	 * The index of the active parameter.
	 *
	 * If `null`, no parameter of the signature is active (for example, a named
	 * argument that does not match any declared parameters). This is only valid
	 * since 3.18.0 and if the client specifies the client capability
	 * `textDocument.signatureHelp.noActiveParameterSupport === true`.
	 *
	 * If provided (or `null`), this is used in place of
	 * `SignatureHelp.activeParameter`.
	 *
	 * @since 3.16.0
	 */
	activeParameter?: uinteger | null;
}
/**
 * Represents a parameter of a callable-signature. A parameter can
 * have a label and a doc-comment.
 */
export interface ParameterInformation {

	/**
	 * The label of this parameter information.
	 *
	 * Either a string or an inclusive start and exclusive end offset within
	 * its containing signature label (see SignatureInformation.label). The
	 * offsets are based on a UTF-16 string representation, as `Position` and
	 * `Range` do.
	 *
	 * To avoid ambiguities, a server should use the [start, end] offset value
	 * instead of using a substring. Whether a client support this is
	 * controlled via `labelOffsetSupport` client capability.
	 *
	 * *Note*: a label of type string should be a substring of its containing
	 * signature label. Its intended use case is to highlight the parameter
	 * label part in the `SignatureInformation.label`.
	 */
	label: string | [uinteger, uinteger];

	/**
	 * The human-readable doc-comment of this parameter. Will be shown
	 * in the UI but can be omitted.
	 */
	documentation?: string | MarkupContent;
}
  • 错误:如果在签名帮助请求期间发生异常,则设置代码和消息。

代码操作请求 (:leftwards_arrow_with_hook:)

代码操作请求从客户端发送到服务器,以计算给定文本文档和范围的相关命令。这些命令通常是用于修复问题或美化/重构代码的代码修复。 textDocument/codeAction 请求的结果是 Command 字面量数组,通常显示在用户界面中。服务器应仅返回相关命令,避免返回大量代码操作,这可能会让用户不知所措,并使他们更难找到所需的代码操作。

为了确保服务器在许多客户端中都很有用,代码操作中指定的命令应由服务器而不是客户端处理(请参阅 workspace/executeCommand 和 ServerCapabilities.executeCommandProvider)。如果客户端支持通过代码操作提供编辑,则应使用该模式。

自版本 3.16.0 起: 客户端可以向服务器提供在“textDocument/codeAction”请求期间延迟计算代码操作属性的功能

这对于计算属性值(例如,edit 属性)成本很高的情况很有用。客户端通过 codeAction.resolveSupport 功能发出信号,该功能列出了客户端可以延迟解析的所有属性。服务器功能 codeActionProvider.resolveProvider 发出信号,表明服务器将提供 codeAction/resolve 路由。为了帮助服务器在解析请求中唯一标识代码操作,代码操作字面量可以选择携带数据属性。这还受附加客户端功能 codeAction.dataSupport 的保护。通常,如果客户端提供解析支持,它应该提供数据支持。还应注意,服务器不应在 codeAction/resolve 请求中更改代码操作的现有属性。

自版本 3.8.0 起: 支持 CodeAction 字面量以启用以下场景

  • 能够直接从代码操作请求返回工作区编辑。这避免了另一个服务器往返以执行实际的代码操作。但是,服务器提供者应该意识到,如果代码操作的计算成本很高或编辑量很大,那么如果结果只是一个命令并且实际编辑仅在需要时才计算,可能仍然有益。
  • 能够使用类型对代码操作进行分组。客户端可以忽略该信息。但是,它允许他们更好地分组代码操作,例如,将所有重构代码操作分组到重构菜单中。

在协议的 1.0 版本中,没有源或重构代码操作。代码操作仅用于(快速)修复代码,而不是编写/重写代码。因此,如果客户端请求不带任何类型的代码操作,则应返回标准快速修复代码操作。

客户端需要通过相应的客户端功能 codeAction.codeActionLiteralSupport 宣布对代码操作字面量(即 CodeAction 类型的字面量)和代码操作种类的支持。

客户端能力:

  • 属性名称(可选):textDocument.codeAction
  • 属性类型:定义如下的 CodeActionClientCapabilities
export interface CodeActionClientCapabilities {
	/**
	 * Whether code action supports dynamic registration.
	 */
	dynamicRegistration?: boolean;

	/**
	 * The client supports code action literals as a valid
	 * response of the `textDocument/codeAction` request.
	 *
	 * @since 3.8.0
	 */
	codeActionLiteralSupport?: {
		/**
		 * The code action kind is supported with the following value
		 * set.
		 */
		codeActionKind: {

			/**
			 * The code action kind values that the client supports. When this
			 * property exists, the client also guarantees that it will
			 * handle values outside its set gracefully and falls back
			 * to a default value when unknown.
			 */
			valueSet: CodeActionKind[];
		};
	};

	/**
	 * Whether code action supports the `isPreferred` property.
	 *
	 * @since 3.15.0
	 */
	isPreferredSupport?: boolean;

	/**
	 * Whether code action supports the `disabled` property.
	 *
	 * @since 3.16.0
	 */
	disabledSupport?: boolean;

	/**
	 * Whether code action supports the `data` property which is
	 * preserved between a `textDocument/codeAction` and a
	 * `codeAction/resolve` request.
	 *
	 * @since 3.16.0
	 */
	dataSupport?: boolean;

	/**
	 * Whether the client supports resolving additional code action
	 * properties via a separate `codeAction/resolve` request.
	 *
	 * @since 3.16.0
	 */
	resolveSupport?: {
		/**
		 * The properties that a client can resolve lazily.
		 */
		properties: string[];
	};

	/**
	 * Whether the client honors the change annotations in
	 * text edits and resource operations returned via the
	 * `CodeAction#edit` property by, for example, presenting
	 * the workspace edit in the user interface and asking
	 * for confirmation.
	 *
	 * @since 3.16.0
	 */
	honorsChangeAnnotations?: boolean;

	/**
	 * Whether the client supports documentation for a class of code actions.
	 *
	 * @since 3.18.0
	 * @proposed
	 */
	 documentationSupport?: boolean;

	/**
	 * Client supports the tag property on a code action. Clients
	 * supporting tags have to handle unknown tags gracefully.
	 *
	 * @since 3.18.0 - proposed
	 */
	tagSupport?: {
		/**
		 * The tags supported by the client.
		 */
		valueSet: CodeActionTag[];
	};
}

服务器能力:

  • 属性名称(可选):codeActionProvider
  • 属性类型:boolean | CodeActionOptions,其中 CodeActionOptions 定义如下
/**
 * Documentation for a class of code actions.
 *
 * @since 3.18.0
 * @proposed
 */
export interface CodeActionKindDocumentation {
	/**
	 * The kind of the code action being documented.
	 *
	 * If the kind is generic, such as `CodeActionKind.Refactor`, the
	 * documentation will be shown whenever any refactorings are returned. If
	 * the kind is more specific, such as `CodeActionKind.RefactorExtract`, the
	 * documentation will only be shown when extract refactoring code actions
	 * are returned.
	 */
	kind: CodeActionKind;

	/**
	 * Command that is used to display the documentation to the user.
	 *
	 * The title of this documentation code action is taken
	 * from {@linkcode Command.title}
	 */
	command: Command;
}

export interface CodeActionOptions extends WorkDoneProgressOptions {
	/**
	 * CodeActionKinds that this server may return.
	 *
	 * The list of kinds may be generic, such as `CodeActionKind.Refactor`,
	 * or the server may list out every specific kind they provide.
	 */
	codeActionKinds?: CodeActionKind[];

	/**
	 * Static documentation for a class of code actions.
	 *
	 * Documentation from the provider should be shown in the code actions
	 * menu if either:
	 *
	 * - Code actions of `kind` are requested by the editor. In this case,
	 *   the editor will show the documentation that most closely matches the
	 *   requested code action kind. For example, if a provider has
	 *   documentation for both `Refactor` and `RefactorExtract`, when the
	 *   user requests code actions for `RefactorExtract`, the editor will use
	 *   the documentation for `RefactorExtract` instead of the documentation
	 *   for `Refactor`.
	 *
	 * - Any code actions of `kind` are returned by the provider.
	 *
	 * At most one documentation entry should be shown per provider.
	 *
	 * @since 3.18.0
	 * @proposed
	 */
	documentation?: CodeActionKindDocumentation[];

	/**
	 * The server provides support to resolve additional
	 * information for a code action.
	 *
	 * @since 3.16.0
	 */
	resolveProvider?: boolean;
}

注册选项:定义如下的 CodeActionRegistrationOptions

export interface CodeActionRegistrationOptions extends
	TextDocumentRegistrationOptions, CodeActionOptions {
}

请求:

  • 方法:textDocument/codeAction
  • 参数:定义如下的 CodeActionParams
/**
 * Params for the CodeActionRequest.
 */
export interface CodeActionParams extends WorkDoneProgressParams,
	PartialResultParams {
	/**
	 * The document in which the command was invoked.
	 */
	textDocument: TextDocumentIdentifier;

	/**
	 * The range for which the command was invoked.
	 */
	range: Range;

	/**
	 * Context carrying additional information.
	 */
	context: CodeActionContext;
}
/**
 * The kind of a code action.
 *
 * Kinds are a hierarchical list of identifiers separated by `.`,
 * e.g. `"refactor.extract.function"`.
 *
 * The set of kinds is open and the client needs to announce
 * the kinds it supports to the server during initialization.
 */
export type CodeActionKind = string;

/**
 * A set of predefined code action kinds.
 */
export namespace CodeActionKind {

	/**
	 * Empty kind.
	 */
	export const Empty: CodeActionKind = '';

	/**
	 * Base kind for quickfix actions: 'quickfix'.
	 */
	export const QuickFix: CodeActionKind = 'quickfix';

	/**
	 * Base kind for refactoring actions: 'refactor'.
	 */
	export const Refactor: CodeActionKind = 'refactor';

	/**
	 * Base kind for refactoring extraction actions: 'refactor.extract'.
	 *
	 * Example extract actions:
	 *
	 * - Extract method
	 * - Extract function
	 * - Extract variable
	 * - Extract interface from class
	 * - ...
	 */
	export const RefactorExtract: CodeActionKind = 'refactor.extract';

	/**
	 * Base kind for refactoring inline actions: 'refactor.inline'.
	 *
	 * Example inline actions:
	 *
	 * - Inline function
	 * - Inline variable
	 * - Inline constant
	 * - ...
	 */
	export const RefactorInline: CodeActionKind = 'refactor.inline';

	/**
	 * Base kind for refactoring move actions: 'refactor.move'
	 *
	 * Example move actions:
	 *
	 * - Move a function to a new file
	 * - Move a property between classes
	 * - Move method to base class
	 * - ...
	 *
	 * @since 3.18.0 - proposed
	 */
	export const RefactorMove: CodeActionKind = 'refactor.move';

	/**
	 * Base kind for refactoring rewrite actions: 'refactor.rewrite'.
	 *
	 * Example rewrite actions:
	 *
	 * - Convert JavaScript function to class
	 * - Add or remove parameter
	 * - Encapsulate field
	 * - Make method static
	 * - ...
	 */
	export const RefactorRewrite: CodeActionKind = 'refactor.rewrite';

	/**
	 * Base kind for source actions: `source`.
	 *
	 * Source code actions apply to the entire file.
	 */
	export const Source: CodeActionKind = 'source';

	/**
	 * Base kind for an organize imports source action:
	 * `source.organizeImports`.
	 */
	export const SourceOrganizeImports: CodeActionKind =
		'source.organizeImports';

	/**
	 * Base kind for a 'fix all' source action: `source.fixAll`.
	 *
	 * 'Fix all' actions automatically fix errors that have a clear fix that
	 * do not require user input. They should not suppress errors or perform
	 * unsafe fixes such as generating new types or classes.
	 *
	 * @since 3.17.0
	 */
	export const SourceFixAll: CodeActionKind = 'source.fixAll';

	/**
	 * Base kind for all code actions applying to the entire notebook's scope. CodeActionKinds using
	 * this should always begin with `notebook.`
	 *
	 * @since 3.18.0
	 */
	export const Notebook: CodeActionKind = 'notebook';
}
/**
 * Contains additional diagnostic information about the context in which
 * a code action is run.
 */
export interface CodeActionContext {
	/**
	 * An array of diagnostics known on the client side overlapping the range
	 * provided to the `textDocument/codeAction` request. They are provided so
	 * that the server knows which errors are currently presented to the user
	 * for the given range. There is no guarantee that these accurately reflect
	 * the error state of the resource. The primary parameter
	 * to compute code actions is the provided range.
	 *
	 * Note that the client should check the `textDocument.diagnostic.markupMessageSupport`
	 * server capability before sending diagnostics with markup messages to a server.
	 * Diagnostics with markup messages should be excluded for servers that don't support
	 * them.
	 */
	diagnostics: Diagnostic[];

	/**
	 * Requested kind of actions to return.
	 *
	 * Actions not of this kind are filtered out by the client before being
	 * shown, so servers can omit computing them.
	 */
	only?: CodeActionKind[];

	/**
	 * The reason why code actions were requested.
	 *
	 * @since 3.17.0
	 */
	triggerKind?: CodeActionTriggerKind;
}
/**
 * The reason why code actions were requested.
 *
 * @since 3.17.0
 */
export namespace CodeActionTriggerKind {
	/**
	 * Code actions were explicitly requested by the user or by an extension.
	 */
	export const Invoked: 1 = 1;

	/**
	 * Code actions were requested automatically.
	 *
	 * This typically happens when the current selection in a file changes,
	 * but can also be triggered when file content changes.
	 */
	export const Automatic: 2 = 2;
}

export type CodeActionTriggerKind = 1 | 2;
/**
 * Code action tags are extra annotations that tweak the behavior of a code action.
 *
 * @since 3.18.0 - proposed
 */
export namespace CodeActionTag {
	/**
	 * Marks the code action as LLM-generated.
	 */
	export const LLMGenerated = 1;
}
export type CodeActionTag = 1;

Response:

  • 结果:(Command | CodeAction)[] | null,其中 CodeAction 定义如下
/**
 * A code action represents a change that can be performed in code, e.g. to fix
 * a problem or to refactor code.
 *
 * A CodeAction must set either `edit` and/or a `command`. If both are supplied,
 * the `edit` is applied first, then the `command` is executed.
 */
export interface CodeAction {

	/**
	 * A short, human-readable title for this code action.
	 */
	title: string;

	/**
	 * The kind of the code action.
	 *
	 * Used to filter code actions.
	 */
	kind?: CodeActionKind;

	/**
	 * The diagnostics that this code action resolves.
	 */
	diagnostics?: Diagnostic[];

	/**
	 * Marks this as a preferred action. Preferred actions are used by the
	 * `auto fix` command and can be targeted by keybindings.
	 *
	 * A quick fix should be marked preferred if it properly addresses the
	 * underlying error. A refactoring should be marked preferred if it is the
	 * most reasonable choice of actions to take.
	 *
	 * @since 3.15.0
	 */
	isPreferred?: boolean;

	/**
	 * Marks that the code action cannot currently be applied.
	 *
	 * Clients should follow the following guidelines regarding disabled code
	 * actions:
	 *
	 * - Disabled code actions are not shown in automatic lightbulbs code
	 *   action menus.
	 *
	 * - Disabled actions are shown as faded out in the code action menu when
	 *   the user request a more specific type of code action, such as
	 *   refactorings.
	 *
	 * - If the user has a keybinding that auto applies a code action and only
	 *   a disabled code actions are returned, the client should show the user
	 *   an error message with `reason` in the editor.
	 *
	 * @since 3.16.0
	 */
	disabled?: {

		/**
		 * Human readable description of why the code action is currently
		 * disabled.
		 *
		 * This is displayed in the code actions UI.
		 */
		reason: string;
	};

	/**
	 * The workspace edit this code action performs.
	 */
	edit?: WorkspaceEdit;

	/**
	 * A command this code action executes. If a code action
	 * provides an edit and a command, first the edit is
	 * executed and then the command.
	 */
	command?: Command;

	/**
	 * A data entry field that is preserved on a code action between
	 * a `textDocument/codeAction` and a `codeAction/resolve` request.
	 *
	 * @since 3.16.0
	 */
	data?: LSPAny;

	/**
 	 * Tags for this code action.
	 *
	 * @since 3.18.0 - proposed
	 */
	tags?: CodeActionTag[];
}
  • 部分结果:(Command | CodeAction)[]
  • 错误:如果在代码操作请求期间发生异常,则设置代码和消息。

代码操作解析请求 (:leftwards_arrow_with_hook:)

自 3.16.0 版本起

该请求从客户端发送到服务器,以解析给定代码操作的附加信息。这通常用于计算代码操作的 edit 属性,以避免在 textDocument/codeAction 请求期间进行不必要的计算。

假设客户端宣布 edit 属性是一个可以使用客户端功能延迟解析的属性

textDocument.codeAction.resolveSupport = { properties: ['edit'] };

那么一个代码操作

{
    "title": "Do Foo"
}

需要在应用之前使用 codeAction/resolve 请求进行解析。

客户端能力:

  • 属性名称(可选):textDocument.codeAction.resolveSupport
  • 属性类型:{ properties: string[]; }

请求:

  • 方法:codeAction/resolve
  • 参数:CodeAction

Response:

  • 结果:CodeAction
  • 错误:如果在代码操作解析请求期间发生异常,则设置代码和消息。

文档颜色请求 (:leftwards_arrow_with_hook:)

自 3.6.0 版本起

文档颜色请求从客户端发送到服务器,以列出在给定文本文档中找到的所有颜色引用。除了范围,还会返回一个 RGB 颜色值。

客户端可以使用结果在编辑器中装饰颜色引用。例如

  • 显示实际颜色的颜色框,紧邻引用
  • 编辑颜色引用时显示颜色选择器

客户端能力:

  • 属性名称(可选):textDocument.colorProvider
  • 属性类型:定义如下的 DocumentColorClientCapabilities
export interface DocumentColorClientCapabilities {
	/**
	 * Whether document color supports dynamic registration.
	 */
	dynamicRegistration?: boolean;
}

服务器能力:

  • 属性名称(可选):colorProvider
  • 属性类型:boolean | DocumentColorOptions | DocumentColorRegistrationOptions,其中 DocumentColorOptions 定义如下
export interface DocumentColorOptions extends WorkDoneProgressOptions {
}

注册选项:定义如下的 DocumentColorRegistrationOptions

export interface DocumentColorRegistrationOptions extends
	TextDocumentRegistrationOptions, StaticRegistrationOptions,
	DocumentColorOptions {
}

请求:

  • 方法:textDocument/documentColor
  • 参数:定义如下的 DocumentColorParams
interface DocumentColorParams extends WorkDoneProgressParams,
	PartialResultParams {
	/**
	 * The text document.
	 */
	textDocument: TextDocumentIdentifier;
}

Response:

  • 结果:定义如下的 ColorInformation[]
interface ColorInformation {
	/**
	 * The range in the document where this color appears.
	 */
	range: Range;

	/**
	 * The actual color value for this color range.
	 */
	color: Color;
}
/**
 * Represents a color in RGBA space.
 */
interface Color {

	/**
	 * The red component of this color in the range [0-1].
	 */
	readonly red: decimal;

	/**
	 * The green component of this color in the range [0-1].
	 */
	readonly green: decimal;

	/**
	 * The blue component of this color in the range [0-1].
	 */
	readonly blue: decimal;

	/**
	 * The alpha component of this color in the range [0-1].
	 */
	readonly alpha: decimal;
}
  • 部分结果:ColorInformation[]
  • 错误:如果在“textDocument/documentColor”请求期间发生异常,则设置代码和消息

颜色呈现请求 (:leftwards_arrow_with_hook:)

自 3.6.0 版本起

颜色呈现请求从客户端发送到服务器,以获取给定位置的颜色值的呈现列表。客户端可以使用结果来

  • 修改颜色引用。
  • 显示颜色选择器,让用户选择其中一个呈现。

此请求没有特殊功能和注册选项,因为它作为 textDocument/documentColor 请求的解析请求发送。

请求:

  • 方法:textDocument/colorPresentation
  • 参数:定义如下的 ColorPresentationParams
interface ColorPresentationParams extends WorkDoneProgressParams,
	PartialResultParams {
	/**
	 * The text document.
	 */
	textDocument: TextDocumentIdentifier;

	/**
	 * The color information to request presentations for.
	 */
	color: Color;

	/**
	 * The range where the color would be inserted. Serves as a context.
	 */
	range: Range;
}

Response:

  • 结果:定义如下的 ColorPresentation[]
interface ColorPresentation {
	/**
	 * The label of this color presentation. It will be shown on the color
	 * picker header. By default, this is also the text that is inserted when
	 * selecting this color presentation.
	 */
	label: string;
	/**
	 * An [edit](#TextEdit) which is applied to a document when selecting
	 * this presentation for the color. When omitted, the
	 * [label](#ColorPresentation.label) is used.
	 */
	textEdit?: TextEdit;
	/**
	 * An optional array of additional [text edits](#TextEdit) that are applied
	 * when selecting this color presentation. Edits must not overlap with the
	 * main [edit](#ColorPresentation.textEdit) nor with themselves.
	 */
	additionalTextEdits?: TextEdit[];
}
  • 部分结果:ColorPresentation[]
  • 错误:如果在“textDocument/colorPresentation”请求期间发生异常,则设置代码和消息

文档格式化请求 (:leftwards_arrow_with_hook:)

文档格式化请求从客户端发送到服务器,以格式化整个文档。

客户端能力:

  • 属性名称(可选):textDocument.formatting
  • 属性类型:定义如下的 DocumentFormattingClientCapabilities
export interface DocumentFormattingClientCapabilities {
	/**
	 * Whether formatting supports dynamic registration.
	 */
	dynamicRegistration?: boolean;
}

服务器能力:

  • 属性名称(可选):documentFormattingProvider
  • 属性类型:boolean | DocumentFormattingOptions,其中 DocumentFormattingOptions 定义如下
export interface DocumentFormattingOptions extends WorkDoneProgressOptions {
}

注册选项:定义如下的 DocumentFormattingRegistrationOptions

export interface DocumentFormattingRegistrationOptions extends
	TextDocumentRegistrationOptions, DocumentFormattingOptions {
}

请求:

  • 方法:textDocument/formatting
  • 参数:定义如下的 DocumentFormattingParams
interface DocumentFormattingParams extends WorkDoneProgressParams {
	/**
	 * The document to format.
	 */
	textDocument: TextDocumentIdentifier;

	/**
	 * The formatting options.
	 */
	options: FormattingOptions;
}
/**
 * Value-object describing what options formatting should use.
 */
interface FormattingOptions {
	/**
	 * Size of a tab in spaces.
	 */
	tabSize: uinteger;

	/**
	 * Prefer spaces over tabs.
	 */
	insertSpaces: boolean;

	/**
	 * Trim trailing whitespace on a line.
	 *
	 * @since 3.15.0
	 */
	trimTrailingWhitespace?: boolean;

	/**
	 * Insert a newline character at the end of the file if one does not exist.
	 *
	 * @since 3.15.0
	 */
	insertFinalNewline?: boolean;

	/**
	 * Trim all newlines after the final newline at the end of the file.
	 *
	 * @since 3.15.0
	 */
	trimFinalNewlines?: boolean;

	/**
	 * Signature for further properties.
	 */
	[key: string]: boolean | integer | string;
}

Response:

  • 结果:TextEdit[] | null,描述要格式化的文档的修改。
  • 错误:如果在格式化请求期间发生异常,则设置代码和消息。

文档范围格式化请求 (:leftwards_arrow_with_hook:)

文档范围格式化请求从客户端发送到服务器,以格式化文档中的给定范围。

自版本 3.18.0

如果支持,客户端可以通过 textDocument/rangesFormatting 方法一次性发送多个范围进行格式化。

客户端能力:

  • 属性名称(可选):textDocument.rangeFormatting
  • 属性类型:定义如下的 DocumentRangeFormattingClientCapabilities
export interface DocumentRangeFormattingClientCapabilities {
	/**
	 * Whether formatting supports dynamic registration.
	 */
	dynamicRegistration?: boolean;

	/**
	 * Whether the client supports formatting multiple ranges at once.
	 *
	 * @since 3.18.0
 	 * @proposed
	 */
	rangesSupport?: boolean;
}

服务器能力:

  • 属性名称(可选):documentRangeFormattingProvider
  • 属性类型:boolean | DocumentRangeFormattingOptions,其中 DocumentRangeFormattingOptions 定义如下
export interface DocumentRangeFormattingOptions extends
	WorkDoneProgressOptions {
	/**
	 * Whether the server supports formatting multiple ranges at once.
	 *
	 * @since 3.18.0
	 * @proposed
	 */
	rangesSupport?: boolean;
}

注册选项:定义如下的 DocumentFormattingRegistrationOptions

export interface DocumentRangeFormattingRegistrationOptions extends
	TextDocumentRegistrationOptions, DocumentRangeFormattingOptions {
}

请求:

  • 方法:textDocument/rangeFormatting,
  • 参数:定义如下的 DocumentRangeFormattingParams
interface DocumentRangeFormattingParams extends WorkDoneProgressParams {
	/**
	 * The document to format.
	 */
	textDocument: TextDocumentIdentifier;

	/**
	 * The range to format.
	 */
	range: Range;

	/**
	 * The formatting options.
	 */
	options: FormattingOptions;
}

Response:

  • 结果:TextEdit[] | null,描述要格式化的文档的修改。
  • 错误:如果在范围格式化请求期间发生异常,则设置代码和消息。

自版本 3.18.0

请求:

  • 方法:textDocument/rangesFormatting,
  • 参数:DocumentRangesFormattingParams 定义如下
interface DocumentRangesFormattingParams extends WorkDoneProgressParams {
	/**
	 * The document to format.
	 */
	textDocument: TextDocumentIdentifier;

	/**
	 * The ranges to format.
	 */
	ranges: Range[];

	/**
	 * The format options.
	 */
	options: FormattingOptions;
}

Response:

  • 结果:TextEdit[] | null,描述要格式化的文档的修改。
  • 错误:如果在范围格式化请求期间发生异常,则设置代码和消息。

文档键入时格式化请求 (:leftwards_arrow_with_hook:)

文档键入时格式化请求从客户端发送到服务器,以在键入期间格式化文档的某些部分。

客户端能力:

  • 属性名称(可选):textDocument.onTypeFormatting
  • 属性类型:定义如下的 DocumentOnTypeFormattingClientCapabilities
export interface DocumentOnTypeFormattingClientCapabilities {
	/**
	 * Whether on type formatting supports dynamic registration.
	 */
	dynamicRegistration?: boolean;
}

服务器能力:

  • 属性名称(可选):documentOnTypeFormattingProvider
  • 属性类型:定义如下的 DocumentOnTypeFormattingOptions
export interface DocumentOnTypeFormattingOptions {
	/**
	 * A character on which formatting should be triggered, like `{`.
	 */
	firstTriggerCharacter: string;

	/**
	 * More trigger characters.
	 */
	moreTriggerCharacter?: string[];
}

注册选项:定义如下的 DocumentOnTypeFormattingRegistrationOptions

export interface DocumentOnTypeFormattingRegistrationOptions extends
	TextDocumentRegistrationOptions, DocumentOnTypeFormattingOptions {
}

请求:

  • 方法:textDocument/onTypeFormatting
  • 参数:定义如下的 DocumentOnTypeFormattingParams
interface DocumentOnTypeFormattingParams {

	/**
	 * The document to format.
	 */
	textDocument: TextDocumentIdentifier;

	/**
	 * The position around which the on type formatting should happen.
	 * This is not necessarily the exact position where the character denoted
	 * by the property `ch` got typed.
	 */
	position: Position;

	/**
	 * The character that has been typed that triggered the formatting
	 * on type request. That is not necessarily the last character that
	 * got inserted into the document since the client could auto insert
	 * characters as well (e.g. automatic brace completion).
	 */
	ch: string;

	/**
	 * The formatting options.
	 */
	options: FormattingOptions;
}

Response:

  • 结果:TextEdit[] | null,描述对文档的修改。
  • 错误:如果在范围格式化请求期间发生异常,则设置代码和消息。

重命名请求 (:leftwards_arrow_with_hook:)

重命名请求从客户端发送到服务器,要求服务器计算工作区更改,以便客户端可以对符号执行工作区范围的重命名。

客户端能力:

  • 属性名称(可选):textDocument.rename
  • 属性类型:定义如下的 RenameClientCapabilities
export namespace PrepareSupportDefaultBehavior {
	/**
	 * The client's default behavior is to select the identifier
	 * according to the language's syntax rule.
	 */
	 export const Identifier: 1 = 1;
}

export type PrepareSupportDefaultBehavior = 1;
export interface RenameClientCapabilities {
	/**
	 * Whether rename supports dynamic registration.
	 */
	dynamicRegistration?: boolean;

	/**
	 * Client supports testing for validity of rename operations
	 * before execution.
	 *
	 * @since version 3.12.0
	 */
	prepareSupport?: boolean;

	/**
	 * Client supports the default behavior result
	 * (`{ defaultBehavior: boolean }`).
	 *
	 * The value indicates the default behavior used by the
	 * client.
	 *
	 * @since version 3.16.0
	 */
	prepareSupportDefaultBehavior?: PrepareSupportDefaultBehavior;

	/**
	 * Whether the client honors the change annotations in
	 * text edits and resource operations returned via the
	 * rename request's workspace edit by, for example, presenting
	 * the workspace edit in the user interface and asking
	 * for confirmation.
	 *
	 * @since 3.16.0
	 */
	honorsChangeAnnotations?: boolean;
}

服务器能力:

  • 属性名称(可选):renameProvider
  • 属性类型:boolean | RenameOptions,其中 RenameOptions 定义如下

只有当客户端在其初始 initialize 请求中声明支持 prepareSupport 时,才能指定 RenameOptions。

export interface RenameOptions extends WorkDoneProgressOptions {
	/**
	 * Renames should be checked and tested before being executed.
	 */
	prepareProvider?: boolean;
}

注册选项:定义如下的 RenameRegistrationOptions

export interface RenameRegistrationOptions extends
	TextDocumentRegistrationOptions, RenameOptions {
}

请求:

  • 方法:textDocument/rename
  • 参数:定义如下的 RenameParams
interface RenameParams extends TextDocumentPositionParams,
	WorkDoneProgressParams {
	/**
	 * The new name of the symbol. If the given name is not valid, the
	 * request must return a [ResponseError](#ResponseError) with an
	 * appropriate message set.
	 */
	newName: string;
}

Response:

  • 结果:WorkspaceEdit | null 描述对工作区的修改。null 应被视为与没有更改的 WorkspaceEdit 相同(不需要更改)。
  • 错误:如果在任何原因下无法执行重命名时设置代码和消息。示例包括:给定 position 处没有要重命名的内容(如空格),给定符号不支持服务器重命名或代码无效(例如,无法编译)。

准备重命名请求 (:leftwards_arrow_with_hook:)

自 3.12.0 版起

准备重命名请求从客户端发送到服务器,以设置和测试给定位置的重命名操作的有效性。

请求:

  • 方法:textDocument/prepareRename
  • 参数:定义如下的 PrepareRenameParams
export interface PrepareRenameParams extends TextDocumentPositionParams, WorkDoneProgressParams {
}

Response:

  • 结果:Range | { range: Range, placeholder: string } | { defaultBehavior: boolean } | null 描述要重命名的字符串的 Range,以及可选的字符串内容的占位符文本。如果返回 { defaultBehavior: boolean }(自 3.16 起),则重命名位置有效,并且客户端应使用其默认行为来计算重命名范围。如果返回 null,则认为在给定位置的“textDocument/rename”请求无效。
  • 错误:如果无法重命名元素,则设置代码和消息。客户端应在其用户界面中显示此信息。

链接编辑范围 (:leftwards_arrow_with_hook:)

自 3.16.0 版本起

链接编辑请求从客户端发送到服务器,以返回文档中给定位置的符号范围以及所有内容相同的范围。可以选择返回一个单词模式来描述有效内容。如果新内容有效,则可以将一个范围的重命名应用于所有其他范围。如果没有提供特定于结果的单词模式,则使用客户端语言配置中的单词模式。

客户端功能:

  • 属性名称(可选):textDocument.linkedEditingRange
  • 属性类型:定义如下的 LinkedEditingRangeClientCapabilities
export interface LinkedEditingRangeClientCapabilities {
	/**
	 * Whether the implementation supports dynamic registration.
	 * If this is set to `true` the client supports the new
	 * `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`
	 * return value for the corresponding server capability as well.
	 */
	dynamicRegistration?: boolean;
}

服务器能力:

  • 属性名称(可选):linkedEditingRangeProvider
  • 属性类型:boolean | LinkedEditingRangeOptions | LinkedEditingRangeRegistrationOptions,定义如下
export interface LinkedEditingRangeOptions extends WorkDoneProgressOptions {
}

注册选项:定义如下的 LinkedEditingRangeRegistrationOptions

export interface LinkedEditingRangeRegistrationOptions extends
	TextDocumentRegistrationOptions, LinkedEditingRangeOptions,
	StaticRegistrationOptions {
}

请求:

  • 方法:textDocument/linkedEditingRange
  • 参数:定义如下的 LinkedEditingRangeParams
export interface LinkedEditingRangeParams extends TextDocumentPositionParams,
	WorkDoneProgressParams {
}

Response:

  • 结果:定义如下的 LinkedEditingRanges | null
export interface LinkedEditingRanges {
	/**
	 * A list of ranges that can be renamed together. The ranges must have
	 * identical length and contain identical text content. The ranges cannot
	 * overlap.
	 */
	ranges: Range[];

	/**
	 * An optional word pattern (regular expression) that describes valid
	 * contents for the given ranges. If no pattern is provided, the client
	 * configuration's word pattern will be used.
	 */
	wordPattern?: string;
}
  • 错误:如果在“textDocument/linkedEditingRange”请求期间发生异常,则设置代码和消息

内联补全请求(:leftwards_arrow_with_hook:)

自版本 3.18.0

内联补全请求从客户端发送到服务器,以计算给定文本文档的内联补全,无论是通过用户手势显式触发,还是在键入时隐式触发。

内联补全项通常补全大部分文本(例如,整个方法),与补全不同,项可以补全语法或语义上可能不正确的代码。

因此,内联补全项通常不适合以列表形式在普通代码补全小部件中呈现。一种可能的方法是在编辑器中以较低对比度内联呈现信息。

当返回多个内联补全项时,客户端可以决定用户是否可以在它们之间循环,或者它们及其 filterText 是否仅用于在用户继续键入但尚未接受内联补全项时进行过滤。

如果补全项同时可见,客户端可以选择通过上下文发送有关用户当前补全选择的信息。在这种情况下,返回的内联补全应扩展提供的补全的文本。

客户端能力:

  • 属性名称(可选):textDocument.inlineCompletion
  • 属性类型:InlineCompletionClientCapabilities 定义如下
/**
 * Client capabilities specific to inline completions.
 *
 * @since 3.18.0
 */
export interface InlineCompletionClientCapabilities {
	/**
	 * Whether implementation supports dynamic registration for inline
	 * completion providers.
	 */
	dynamicRegistration?: boolean;
}

服务器能力:

  • 属性名称(可选):inlineCompletionProvider
  • 属性类型:InlineCompletionOptions 定义如下
/**
 * Inline completion options used during static registration.
 *
 * @since 3.18.0
 */
export interface InlineCompletionOptions extends WorkDoneProgressOptions {
}

注册选项:InlineCompletionRegistrationOptions 定义如下

/**
 * Inline completion options used during static or dynamic registration.
 *
 * @since 3.18.0
 */
export interface InlineCompletionRegistrationOptions extends
	InlineCompletionOptions, TextDocumentRegistrationOptions,
	StaticRegistrationOptions {
}

请求:

  • 方法:textDocument/inlineCompletion
  • 参数:InlineCompletionParams 定义如下
/**
 * A parameter literal used in inline completion requests.
 *
 * @since 3.18.0
 */
export interface InlineCompletionParams extends TextDocumentPositionParams,
	WorkDoneProgressParams {
	/**
	 * Additional information about the context in which inline completions
	 * were requested.
	 */
	context: InlineCompletionContext;
}
/**
 * Provides information about the context in which an inline completion was
 * requested.
 *
 * @since 3.18.0
 */
export interface InlineCompletionContext {
	/**
	 * Describes how the inline completion was triggered.
	 */
	triggerKind: InlineCompletionTriggerKind;

	/**
	 * Provides information about the currently selected item in the
	 * autocomplete widget if it is visible.
	 *
	 * If set, provided inline completions must extend the text of the
	 * selected item and use the same range, otherwise they are not shown as
	 * preview.
	 * As an example, if the document text is `console.` and the selected item
	 * is `.log` replacing the `.` in the document, the inline completion must
	 * also replace `.` and start with `.log`, for example `.log()`.
	 *
	 * Inline completion providers are requested again whenever the selected
	 * item changes.
	 */
	selectedCompletionInfo?: SelectedCompletionInfo;
}
/**
 * Describes how an {@link InlineCompletionItemProvider inline completion
 * provider} was triggered.
 *
 * @since 3.18.0
 */
export namespace InlineCompletionTriggerKind {
	/**
	 * Completion was triggered explicitly by a user gesture.
	 * Return multiple completion items to enable cycling through them.
	 */
	export const Invoked: 1 = 1;

	/**
	 * Completion was triggered automatically while editing.
	 * It is sufficient to return a single completion item in this case.
	 */
	export const Automatic: 2 = 2;
}

export type InlineCompletionTriggerKind = 1 | 2;
/**
 * Describes the currently selected completion item.
 *
 * @since 3.18.0
 */
export interface SelectedCompletionInfo {
	/**
	 * The range that will be replaced if this completion item is accepted.
	 */
	range: Range;

	/**
	 * The text the range will be replaced with if this completion is
	 * accepted.
	 */
	text: string;
}

Response:

  • 结果:InlineCompletionItem[] | InlineCompletionList | null 定义如下
/**
 * Represents a collection of {@link InlineCompletionItem inline completion
 * items} to be presented in the editor.
 *
 * @since 3.18.0
 */
export interface InlineCompletionList {
	/**
	 * The inline completion items.
	 */
	items: InlineCompletionItem[];
}
/**
 * An inline completion item represents a text snippet that is proposed inline
 * to complete text that is being typed.
 *
 * @since 3.18.0
 */
export interface InlineCompletionItem {
	/**
	 * The text to replace the range with. Must be set.
	 * Is used both for the preview and the accept operation.
	 */
	insertText: string | StringValue;

	/**
	 * A text that is used to decide if this inline completion should be
	 * shown. When `falsy`, the {@link InlineCompletionItem.insertText} is
	 * used.
	 *
	 * An inline completion is shown if the text to replace is a prefix of the
	 * filter text.
	 */
	filterText?: string;

	/**
	 * The range to replace.
	 * Must begin and end on the same line.
	 *
	 * Prefer replacements over insertions to provide a better experience when
	 * the user deletes typed text.
	 */
	range?: Range;

	/**
	 * An optional {@link Command} that is executed *after* inserting this
	 * completion.
	 */
	command?: Command;
}
  • 错误:如果在内联补全请求期间发生异常,则设置代码和消息。

工作区特性

工作区符号请求 (:leftwards_arrow_with_hook:)

工作区符号请求从客户端发送到服务器,以列出与查询字符串匹配的项目范围符号。自 3.17.0 起,服务器还可以为 workspaceSymbol/resolve 请求提供处理程序。这允许服务器在 workspace/symbol 请求中返回没有范围的工作区符号。客户端随后需要在使用 workspaceSymbol/resolve 请求时解析范围。服务器只有在客户端通过 workspace.symbol.resolveSupport 功能宣传支持时才能使用此新模型。

客户端能力:

  • 属性路径(可选):workspace.symbol
  • 属性类型:定义如下的 WorkspaceSymbolClientCapabilities
interface WorkspaceSymbolClientCapabilities {
	/**
	 * Symbol request supports dynamic registration.
	 */
	dynamicRegistration?: boolean;

	/**
	 * Specific capabilities for the `SymbolKind` in the `workspace/symbol`
	 * request.
	 */
	symbolKind?: {
		/**
		 * The symbol kind values the client supports. When this
		 * property exists, the client also guarantees that it will
		 * handle values outside its set gracefully and falls back
		 * to a default value when unknown.
		 *
		 * If this property is not present, the client only supports
		 * the symbol kinds from `File` to `Array` as defined in
		 * the initial version of the protocol.
		 */
		valueSet?: SymbolKind[];
	};

	/**
	 * The client supports tags on `SymbolInformation` and `WorkspaceSymbol`.
	 * Clients supporting tags have to handle unknown tags gracefully.
	 *
	 * @since 3.16.0
	 */
	tagSupport?: {
		/**
		 * The tags supported by the client.
		 */
		valueSet: SymbolTag[];
	};

	/**
	 * The client supports partial workspace symbols. The client will send the
	 * request `workspaceSymbol/resolve` to the server to resolve additional
	 * properties.
	 *
	 * @since 3.17.0 - proposedState
	 */
	resolveSupport?: {
		/**
		 * The properties that a client can resolve lazily. Usually consists of
		 * `location.range`.
		 */
		properties: string[];
	};
}

服务器能力:

  • 属性路径(可选):workspaceSymbolProvider
  • 属性类型:boolean | WorkspaceSymbolOptions,其中 WorkspaceSymbolOptions 定义如下
export interface WorkspaceSymbolOptions extends WorkDoneProgressOptions {
	/**
	 * The server provides support to resolve additional
	 * information for a workspace symbol.
	 *
	 * @since 3.17.0
	 */
	resolveProvider?: boolean;
}

注册选项:定义如下的 WorkspaceSymbolRegistrationOptions

export interface WorkspaceSymbolRegistrationOptions
	extends WorkspaceSymbolOptions {
}

请求:

  • 方法:“workspace/symbol”
  • 参数:定义如下的 WorkspaceSymbolParams
/**
 * The parameters of a Workspace Symbol Request.
 */
interface WorkspaceSymbolParams extends WorkDoneProgressParams,
	PartialResultParams {
	/**
	 * A query string to filter symbols by. Clients may send an empty
	 * string here to request all symbols.
	 *
	 * The `query`-parameter should be interpreted in a *relaxed way* as editors
	 * will apply their own highlighting and scoring on the results. A good rule
	 * of thumb is to match case-insensitive and to simply check that the
	 * characters of *query* appear in their order in a candidate symbol.
	 * Servers shouldn't use prefix, substring, or similar strict matching.
	 */
	query: string;
}

Response:

  • 结果:SymbolInformation[] | WorkspaceSymbol[] | null。有关 SymbolInformation 的定义,请参见上文。建议您使用新的 WorkspaceSymbol。但是,工作区符号是否可以返回没有范围的位置取决于客户端功能 workspace.symbol.resolveSupport。WorkspaceSymbol 定义如下
/**
 * A special workspace symbol that supports locations without a range.
 *
 * @since 3.17.0
 */
export interface WorkspaceSymbol {
	/**
	 * The name of this symbol.
	 */
	name: string;

	/**
	 * The kind of this symbol.
	 */
	kind: SymbolKind;

	/**
	 * Tags for this completion item.
	 */
	tags?: SymbolTag[];

	/**
	 * The name of the symbol containing this symbol. This information is for
	 * user interface purposes (e.g. to render a qualifier in the user interface
	 * if necessary). It can't be used to re-infer a hierarchy for the document
	 * symbols.
	 */
	containerName?: string;

	/**
	 * The location of this symbol. Whether a server is allowed to
	 * return a location without a range depends on the client
	 * capability `workspace.symbol.resolveSupport`.
	 *
	 * See also `SymbolInformation.location`.
	 */
	location: Location | { uri: DocumentUri };

	/**
	 * A data entry field that is preserved on a workspace symbol between a
	 * workspace symbol request and a workspace symbol resolve request.
	 */
	data?: LSPAny;
}
  • 部分结果:SymbolInformation[] | WorkspaceSymbol[],如上定义。
  • 错误:如果在工作区符号请求期间发生异常,则设置代码和消息。

工作区符号解析请求(:leftwards_arrow_with_hook:)

该请求从客户端发送到服务器,以解析给定工作区符号的附加信息。

请求:

  • 方法:'workspaceSymbol/resolve'
  • 参数:WorkspaceSymbol

Response:

  • 结果:WorkspaceSymbol
  • 错误:如果在工作区符号解析请求期间发生异常,则设置代码和消息。

配置请求 (:arrow_right_hook:)

自 3.6.0 版本起

workspace/configuration 请求从服务器发送到客户端,以从客户端获取配置设置。该请求可以在一个往返中获取多个配置设置。返回的配置设置的顺序与传入的 ConfigurationItems 的顺序相对应(例如,响应中的第一个项是第一个配置项的结果)。

一个 ConfigurationItem 由要请求的配置节和一个附加的作用域 URI 组成。请求的配置节由服务器定义,不一定需要与客户端使用的配置存储对应。因此,服务器可能请求配置 cpp.formatterOptions,但客户端以不同的 XML 存储布局存储配置。由客户端进行必要的转换。如果提供了作用域 URI,客户端应返回作用域到所提供资源的设置。例如,如果客户端使用 EditorConfig 来管理其设置,则应针对传入的资源 URI 返回配置。如果客户端无法为给定作用域提供配置设置,则返回数组中必须包含 null。

此拉取模型取代了旧的推送模型,在该模型中,客户端通过事件发出配置更改信号。如果服务器仍然需要对配置更改做出反应(因为服务器缓存了 workspace/configuration 请求的结果),则服务器应使用以下注册模式注册空配置更改

connection.client.register(DidChangeConfigurationNotification.type, undefined);

客户端能力:

  • 属性路径(可选):workspace.configuration
  • 属性类型:boolean

请求:

  • 方法:“workspace/configuration”
  • 参数:定义如下的 ConfigurationParams
export interface ConfigurationParams {
	items: ConfigurationItem[];
}
export interface ConfigurationItem {
	/**
	 * The scope to get the configuration section for.
	 */
	scopeUri?: URI;

	/**
	 * The configuration section asked for.
	 */
	section?: string;
}

Response:

  • 结果:LSPAny[]
  • 错误:如果在“workspace/configuration”请求期间发生异常,则设置代码和消息

DidChangeConfiguration 通知 (:arrow_right:)

从客户端发送到服务器的通知,用于通知配置设置的更改。

客户端能力:

  • 属性路径(可选):workspace.didChangeConfiguration
  • 属性类型:定义如下的 DidChangeConfigurationClientCapabilities
export interface DidChangeConfigurationClientCapabilities {
	/**
	 * Did change configuration notification supports dynamic registration.
	 *
	 * @since 3.6.0 to support the new pull model.
	 */
	dynamicRegistration?: boolean;
}

通知:

  • 方法:“workspace/didChangeConfiguration”,
  • 参数:定义如下的 DidChangeConfigurationParams
interface DidChangeConfigurationParams {
	/**
	 * The actual changed settings.
	 */
	settings: LSPAny;
}

工作区文件夹请求 (:arrow_right_hook:)

自 3.6.0 版本起

许多工具支持每个工作区多个根文件夹。这方面的例子有 VS Code 的多根支持、Atom 的项目文件夹支持或 Sublime 的项目支持。如果客户端工作区由多个根组成,那么服务器通常需要知道这一点。到目前为止,协议假设一个根文件夹,由 InitializeParams 的 rootUri 属性通知服务器。如果客户端支持工作区文件夹并通过相应的 workspaceFolders 客户端功能宣布它们,则 InitializeParams 在服务器启动时包含一个附加属性 workspaceFolders,其中包含已配置的工作区文件夹。

workspace/workspaceFolders 请求从服务器发送到客户端,以获取当前打开的工作区文件夹列表。如果工具中只打开一个文件,则响应返回 null。如果工作区已打开但未配置任何文件夹,则返回空数组。

客户端能力:

  • 属性路径(可选):workspace.workspaceFolders
  • 属性类型:boolean

服务器能力:

  • 属性路径(可选):workspace.workspaceFolders
  • 属性类型:定义如下的 WorkspaceFoldersServerCapabilities
export interface WorkspaceFoldersServerCapabilities {
	/**
	 * The server has support for workspace folders.
	 */
	supported?: boolean;

	/**
	 * Whether the server wants to receive workspace folder
	 * change notifications.
	 *
	 * If a string is provided, the string is treated as an ID
	 * under which the notification is registered on the client
	 * side. The ID can be used to unregister for these events
	 * using the `client/unregisterCapability` request.
	 */
	changeNotifications?: string | boolean;
}

请求:

  • 方法:workspace/workspaceFolders
  • 参数:无

Response:

  • 结果:定义如下的 WorkspaceFolder[] | null
export interface WorkspaceFolder {
	/**
	 * The associated URI for this workspace folder.
	 */
	uri: URI;

	/**
	 * The name of the workspace folder. Used to refer to this
	 * workspace folder in the user interface.
	 */
	name: string;
}
  • 错误:如果在“workspace/workspaceFolders”请求期间发生异常,则设置代码和消息

DidChangeWorkspaceFolders 通知 (:arrow_right:)

自 3.6.0 版本起

客户端向服务器发送 workspace/didChangeWorkspaceFolders 通知,以告知服务器工作区文件夹配置更改。服务器可以通过使用服务器功能 workspace.workspaceFolders.changeNotifications 或使用动态功能注册机制来注册此通知。要动态注册 workspace/didChangeWorkspaceFolders,请从服务器向客户端发送 client/registerCapability 请求。注册参数必须具有以下形式的 registrations 项,其中 id 是用于取消注册功能的唯一 ID(示例使用 UUID)

{
	id: "28c6150c-bd7b-11e7-abc4-cec278b6b50a",
	method: "workspace/didChangeWorkspaceFolders"
}

通知:

  • 方法:“workspace/didChangeWorkspaceFolders”
  • 参数:定义如下的 DidChangeWorkspaceFoldersParams
export interface DidChangeWorkspaceFoldersParams {
	/**
	 * The actual workspace folder change event.
	 */
	event: WorkspaceFoldersChangeEvent;
}
/**
 * The workspace folder change event.
 */
export interface WorkspaceFoldersChangeEvent {
	/**
	 * The array of added workspace folders.
	 */
	added: WorkspaceFolder[];

	/**
	 * The array of removed workspace folders.
	 */
	removed: WorkspaceFolder[];
}

WillCreateFiles 请求 (:leftwards_arrow_with_hook:)

只要创建操作由客户端内部触发,无论是通过用户操作还是通过应用工作区编辑,创建文件请求就会在文件实际创建之前从客户端发送到服务器。该请求可以返回一个 WorkspaceEdit,该编辑将在文件创建之前应用于工作区。因此,WorkspaceEdit 不能操纵要创建的文件内容。请注意,如果计算编辑花费的时间过长,或者服务器在此请求上持续失败,客户端可能会丢弃结果。这样做是为了保持创建的快速和可靠。

客户端能力:

  • 属性名称(可选):workspace.fileOperations.willCreate
  • 属性类型:boolean

此功能表示客户端支持发送 workspace/willCreateFiles 请求。

服务器能力:

  • 属性名称(可选):workspace.fileOperations.willCreate
  • 属性类型:FileOperationRegistrationOptions,其中 FileOperationRegistrationOptions 定义如下
/**
 * The options to register for file operations.
 *
 * @since 3.16.0
 */
interface FileOperationRegistrationOptions {
	/**
	 * The actual filters.
	 */
	filters: FileOperationFilter[];
}
/**
 * A pattern kind describing if a glob pattern matches a file,
 * a folder, or both.
 *
 * @since 3.16.0
 */
export namespace FileOperationPatternKind {
	/**
	 * The pattern matches a file only.
	 */
	export const file: 'file' = 'file';

	/**
	 * The pattern matches a folder only.
	 */
	export const folder: 'folder' = 'folder';
}

export type FileOperationPatternKind = 'file' | 'folder';
/**
 * Matching options for the file operation pattern.
 *
 * @since 3.16.0
 */
export interface FileOperationPatternOptions {

	/**
	 * The pattern should be matched ignoring casing.
	 */
	ignoreCase?: boolean;
}
/**
 * A pattern to describe in which file operation requests or notifications
 * the server is interested in.
 *
 * @since 3.16.0
 */
interface FileOperationPattern {
	/**
	 * The glob pattern to match. Glob patterns can have the following syntax:
	 * - `*` to match zero or more characters in a path segment
	 * - `?` to match on one character in a path segment
	 * - `**` to match any number of path segments, including none
	 * - `{}` to group sub patterns into an OR expression. (e.g. `**​/*.{ts,js}`
	 *   matches all TypeScript and JavaScript files)
	 * - `[]` to declare a range of characters to match in a path segment
	 *   (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)
	 * - `[!...]` to negate a range of characters to match in a path segment
	 *   (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but
	 *   not `example.0`)
	 */
	glob: string;

	/**
	 * Whether to match files or folders with this pattern.
	 *
	 * Matches both if undefined.
	 */
	matches?: FileOperationPatternKind;

	/**
	 * Additional options used during matching.
	 */
	options?: FileOperationPatternOptions;
}
/**
 * A filter to describe in which file operation requests or notifications
 * the server is interested in.
 *
 * @since 3.16.0
 */
export interface FileOperationFilter {

	/**
	 * A URI scheme, like `file` or `untitled`.
	 */
	scheme?: string;

	/**
	 * The actual file operation pattern.
	 */
	pattern: FileOperationPattern;
}

此功能表示服务器对接收 workspace/willCreateFiles 请求感兴趣。

注册选项:无

请求:

  • 方法:“workspace/willCreateFiles”
  • 参数:定义如下的 CreateFilesParams
/**
 * The parameters sent in notifications/requests for user-initiated creation
 * of files.
 *
 * @since 3.16.0
 */
export interface CreateFilesParams {

	/**
	 * An array of all files/folders created in this operation.
	 */
	files: FileCreate[];
}
/**
 * Represents information on a file/folder create.
 *
 * @since 3.16.0
 */
export interface FileCreate {

	/**
	 * A file:// URI for the location of the file/folder being created.
	 */
	uri: string;
}

Response:

  • 结果:WorkspaceEdit | null
  • 错误:如果在 willCreateFiles 请求期间发生异常,则设置代码和消息。

DidCreateFiles 通知 (:arrow_right:)

当客户端内部创建文件时,did create files 通知从客户端发送到服务器。

客户端能力:

  • 属性名称(可选):workspace.fileOperations.didCreate
  • 属性类型:boolean

此功能表示客户端支持发送 workspace/didCreateFiles 通知。

服务器能力:

  • 属性名称(可选):workspace.fileOperations.didCreate
  • 属性类型:FileOperationRegistrationOptions

此功能表示服务器对接收 workspace/didCreateFiles 通知感兴趣。

通知:

  • 方法:“workspace/didCreateFiles”
  • 参数:CreateFilesParams

WillRenameFiles 请求 (:leftwards_arrow_with_hook:)

只要重命名操作由客户端内部触发,无论是通过用户操作还是通过应用工作区编辑,重命名文件请求就会在文件实际重命名之前从客户端发送到服务器。该请求可以返回一个 WorkspaceEdit,该编辑将在文件重命名之前应用于工作区。请注意,如果计算编辑花费的时间过长,或者服务器在此请求上持续失败,客户端可能会丢弃结果。这样做是为了保持重命名的快速和可靠。

客户端能力:

  • 属性名称(可选):workspace.fileOperations.willRename
  • 属性类型:boolean

此功能表示客户端支持发送 workspace/willRenameFiles 请求。

服务器能力:

  • 属性名称(可选):workspace.fileOperations.willRename
  • 属性类型:FileOperationRegistrationOptions

此功能表示服务器对接收 workspace/willRenameFiles 请求感兴趣。

注册选项:无

请求:

  • 方法:“workspace/willRenameFiles”
  • 参数:定义如下的 RenameFilesParams
/**
 * The parameters sent in notifications/requests for user-initiated renames
 * of files.
 *
 * @since 3.16.0
 */
export interface RenameFilesParams {

	/**
	 * An array of all files/folders renamed in this operation. When a folder
	 * is renamed, only the folder will be included, and not its children.
	 */
	files: FileRename[];
}
/**
 * Represents information on a file/folder rename.
 *
 * @since 3.16.0
 */
export interface FileRename {

	/**
	 * A file:// URI for the original location of the file/folder being renamed.
	 */
	oldUri: string;

	/**
	 * A file:// URI for the new location of the file/folder being renamed.
	 */
	newUri: string;
}

Response:

  • 结果:WorkspaceEdit | null
  • 错误:如果在 workspace/willRenameFiles 请求期间发生异常,则设置代码和消息。

DidRenameFiles 通知 (:arrow_right:)

当文件在客户端内部被重命名时,did rename files 通知从客户端发送到服务器。

客户端能力:

  • 属性名称(可选):workspace.fileOperations.didRename
  • 属性类型:boolean

此功能表示客户端支持发送 workspace/didRenameFiles 通知。

服务器能力:

  • 属性名称(可选):workspace.fileOperations.didRename
  • 属性类型:FileOperationRegistrationOptions

此功能表示服务器对接收 workspace/didRenameFiles 通知感兴趣。

通知:

  • 方法:“workspace/didRenameFiles”
  • 参数:RenameFilesParams

WillDeleteFiles 请求 (:leftwards_arrow_with_hook:)

只要删除操作由客户端内部触发,无论是通过用户操作还是通过应用工作区编辑,删除文件请求就会在文件实际删除之前从客户端发送到服务器。该请求可以返回一个 WorkspaceEdit,该编辑将在文件删除之前应用于工作区。请注意,如果计算编辑花费的时间过长,或者服务器在此请求上持续失败,客户端可能会丢弃结果。这样做是为了保持删除的快速和可靠。

客户端能力:

  • 属性名称(可选):workspace.fileOperations.willDelete
  • 属性类型:boolean

此功能表示客户端支持发送 workspace/willDeleteFiles 请求。

服务器能力:

  • 属性名称(可选):workspace.fileOperations.willDelete
  • 属性类型:FileOperationRegistrationOptions

此功能表示服务器对接收 workspace/willDeleteFiles 请求感兴趣。

注册选项:无

请求:

  • 方法:workspace/willDeleteFiles
  • 参数:定义如下的 DeleteFilesParams
/**
 * The parameters sent in notifications/requests for user-initiated deletes
 * of files.
 *
 * @since 3.16.0
 */
export interface DeleteFilesParams {

	/**
	 * An array of all files/folders deleted in this operation.
	 */
	files: FileDelete[];
}
/**
 * Represents information on a file/folder delete.
 *
 * @since 3.16.0
 */
export interface FileDelete {

	/**
	 * A file:// URI for the location of the file/folder being deleted.
	 */
	uri: string;
}

Response:

  • 结果:WorkspaceEdit | null
  • 错误:如果在 workspace/willDeleteFiles 请求期间发生异常,则设置代码和消息。

DidDeleteFiles 通知 (:arrow_right:)

当文件在客户端内部被删除时,did delete files 通知从客户端发送到服务器。

客户端能力:

  • 属性名称(可选):workspace.fileOperations.didDelete
  • 属性类型:boolean

此功能表示客户端支持发送 workspace/didDeleteFiles 通知。

服务器能力:

  • 属性名称(可选):workspace.fileOperations.didDelete
  • 属性类型:FileOperationRegistrationOptions

此功能表示服务器对接收 workspace/didDeleteFiles 通知感兴趣。

通知:

  • 方法:“workspace/didDeleteFiles”
  • 参数:DeleteFilesParams

DidChangeWatchedFiles 通知 (:arrow_right:)

当客户端检测到语言客户端监视的文件和文件夹发生更改时,客户端会向服务器发送监视文件通知(请注意,尽管名称暗示只发送文件事件,但它指的是文件系统事件,其中也包括文件夹)。建议服务器使用注册机制注册这些文件系统事件。在以前的实现中,客户端在服务器没有主动请求的情况下推送文件事件。

服务器可以运行自己的文件系统监视机制,而不依赖客户端提供文件系统事件。但是,由于以下原因,不建议这样做

  • 根据我们的经验,在磁盘上正确地进行文件系统监视具有挑战性,尤其是当它需要在多个操作系统上支持时。
  • 文件系统监视不是免费的,尤其是当实现使用某种轮询并在内存中保留文件系统树以比较时间戳时(例如某些节点模块所做的那样)
  • 客户端通常会启动多个服务器。如果每个服务器都运行自己的文件系统监视,这可能会导致 CPU 或内存问题。
  • 一般来说,服务器实现多于客户端实现。因此,这个问题最好在客户端解决。

客户端能力:

  • 属性路径(可选):workspace.didChangeWatchedFiles
  • 属性类型:定义如下的 DidChangeWatchedFilesClientCapabilities
export interface DidChangeWatchedFilesClientCapabilities {
	/**
	 * Did change watched files notification supports dynamic registration.
	 * Please note that the current protocol doesn't support static
	 * configuration for file changes from the server side.
	 */
	dynamicRegistration?: boolean;

	/**
	 * Whether the client has support for relative patterns
	 * or not.
	 *
	 * @since 3.17.0
	 */
	relativePatternSupport?: boolean;
}

注册选项:定义如下的 DidChangeWatchedFilesRegistrationOptions

/**
 * Describe options to be used when registering for file system change events.
 */
export interface DidChangeWatchedFilesRegistrationOptions {
	/**
	 * The watchers to register.
	 */
	watchers: FileSystemWatcher[];
}
export interface FileSystemWatcher {
	/**
	 * The glob pattern to watch. See {@link GlobPattern glob pattern}
	 * for more detail.
	 *
 	 * @since 3.17.0 support for relative patterns.
	 */
	globPattern: GlobPattern;

	/**
	 * The kind of events of interest. If omitted, it defaults
	 * to WatchKind.Create | WatchKind.Change | WatchKind.Delete
	 * which is 7.
	 */
	kind?: WatchKind;
}
export namespace WatchKind {
	/**
	 * Interested in create events.
	 */
	export const Create = 1;

	/**
	 * Interested in change events.
	 */
	export const Change = 2;

	/**
	 * Interested in delete events.
	 */
	export const Delete = 4;
}
export type WatchKind = uinteger;

通知:

  • 方法:“workspace/didChangeWatchedFiles”
  • 参数:定义如下的 DidChangeWatchedFilesParams
interface DidChangeWatchedFilesParams {
	/**
	 * The actual file events.
	 */
	changes: FileEvent[];
}

其中 FileEvents 描述如下

/**
 * An event describing a file change.
 */
interface FileEvent {
	/**
	 * The file's URI.
	 */
	uri: DocumentUri;
	/**
	 * The change type.
	 */
	type: FileChangeType;
}
/**
 * The file event type.
 */
export namespace FileChangeType {
	/**
	 * The file got created.
	 */
	export const Created = 1;
	/**
	 * The file got changed.
	 */
	export const Changed = 2;
	/**
	 * The file got deleted.
	 */
	export const Deleted = 3;
}

export type FileChangeType = 1 | 2 | 3;

执行命令 (:leftwards_arrow_with_hook:)

客户端向服务器发送 workspace/executeCommand 请求,以触发服务器上的命令执行。在大多数情况下,服务器会创建 WorkspaceEdit 结构,并使用从服务器发送到客户端的 workspace/applyEdit 请求将更改应用于工作区。

客户端能力:

  • 属性路径(可选):workspace.executeCommand
  • 属性类型:定义如下的 ExecuteCommandClientCapabilities
export interface ExecuteCommandClientCapabilities {
	/**
	 * Execute command supports dynamic registration.
	 */
	dynamicRegistration?: boolean;
}

服务器能力:

  • 属性路径(可选):executeCommandProvider
  • 属性类型:定义如下的 ExecuteCommandOptions
export interface ExecuteCommandOptions extends WorkDoneProgressOptions {
	/**
	 * The commands to be executed on the server.
	 */
	commands: string[];
}

注册选项:定义如下的 ExecuteCommandRegistrationOptions

/**
 * Execute command registration options.
 */
export interface ExecuteCommandRegistrationOptions
	extends ExecuteCommandOptions {
}

请求:

  • 方法:“workspace/executeCommand”
  • 参数:定义如下的 ExecuteCommandParams
export interface ExecuteCommandParams extends WorkDoneProgressParams {

	/**
	 * The identifier of the actual command handler.
	 */
	command: string;
	/**
	 * Arguments that the command should be invoked with.
	 */
	arguments?: LSPAny[];
}

通常在服务器将命令返回给客户端时指定参数。返回命令的请求示例有 textDocument/codeAction 或 textDocument/codeLens。

Response:

  • 结果:LSPAny
  • 错误:在请求期间发生异常时设置的代码和消息。

应用工作区编辑 (:arrow_right_hook:)

workspace/applyEdit 请求从服务器发送到客户端,以在客户端修改资源。

客户端能力:

  • 属性路径(可选):workspace.applyEdit
  • 属性类型:boolean

另请参阅 WorkspaceEditClientCapabilities,了解工作区编辑支持的功能。

请求:

  • 方法:“workspace/applyEdit”
  • 参数:定义如下的 ApplyWorkspaceEditParams
export interface ApplyWorkspaceEditParams {
	/**
	 * An optional label of the workspace edit. This label is
	 * presented in the user interface, for example, on an undo
	 * stack to undo the workspace edit.
	 */
	label?: string;

	/**
	 * The edits to apply.
	 */
	edit: WorkspaceEdit;

	/**
	 * Additional data about the edit.
	 *
	 * @since 3.18.0
	 * @proposed
	 */
	metadata?: WorkspaceEditMetadata;
}
/**
 * Additional data about a workspace edit.
 *
 * @since 3.18.0
 * @proposed
 */
export interface WorkspaceEditMetadata {
	/**
	 * Signal to the editor that this edit is a refactoring.
	 */
	isRefactoring?: boolean;
}

Response:

  • 结果:ApplyWorkspaceEditResult 定义如下
export interface ApplyWorkspaceEditResult {
	/**
	 * Indicates whether the edit was applied or not.
	 */
	applied: boolean;

	/**
	 * An optional textual description for why the edit was not applied.
	 * This may be used by the server for diagnostic logging or to provide
	 * a suitable error for a request that triggered the edit.
	 */
	failureReason?: string;

	/**
	 * Depending on the client's failure handling strategy, `failedChange`
	 * might contain the index of the change that failed. This property is
	 * only available if the client signals a `failureHandling` strategy
	 * in its client capabilities.
	 */
	failedChange?: uinteger;
}
  • 错误:在请求期间发生异常时设置的代码和消息。

文本文档内容请求(:leftwards_arrow_with_hook:)

客户端向服务器发送 workspace/textDocumentContent 请求,以动态获取文本文档的内容。客户端应将此请求返回的内容视为只读。

客户端能力:

  • 属性路径(可选):workspace.textDocumentContent
  • 属性类型:TextDocumentContentClientCapabilities 定义如下
/**
 * Client capabilities for a text document content provider.
 *
 * @since 3.18.0
 */
export type TextDocumentContentClientCapabilities = {
	/**
	 * Text document content provider supports dynamic registration.
	 */
	dynamicRegistration?: boolean;
};

服务器能力:

  • 属性路径(可选):workspace.textDocumentContent
  • 属性类型:TextDocumentContentOptions,其中 TextDocumentContentOptions 定义如下
/**
 * Text document content provider options.
 *
 * @since 3.18.0
 */
export type TextDocumentContentOptions = {
	/**
	 * The schemes for which the server provides content.
	 */
	schemes: string[];
};

注册选项:TextDocumentContentRegistrationOptions 定义如下

/**
 * Text document content provider registration options.
 *
 * @since 3.18.0
 */
export type TextDocumentContentRegistrationOptions = TextDocumentContentOptions &
	StaticRegistrationOptions;

请求:

  • 方法:'workspace/textDocumentContent'
  • 参数:TextDocumentContentParams 定义如下
/**
 * Parameters for the `workspace/textDocumentContent` request.
 *
 * @since 3.18.0
 */
export interface TextDocumentContentParams {
	/**
	 * The uri of the text document.
	 */
	uri: DocumentUri;
}

Response:

  • 结果:TextDocumentContentResult 定义如下
/**
 * Result of the `workspace/textDocumentContent` request.
 *
 * @since 3.18.0
 * @proposed
 */
export interface TextDocumentContentResult {
	/**
	 * The text content of the text document. Please note, that the content of
	 * any subsequent open notifications for the text document might differ
	 * from the returned content due to whitespace and line ending
	 * normalizations done on the client
	 */
	text: string;
}

文本文档的内容。

  • 错误:如果在文本文档内容请求期间发生异常,则设置代码和消息。

文本文档内容刷新请求(:arrow_right_hook:)

从服务器向客户端发送 workspace/textDocumentContent/refresh 请求,以刷新特定文本文档的内容。

请求:

  • 方法:'workspace/textDocumentContent/refresh'
  • 参数:TextDocumentContentRefreshParams 定义如下
/**
 * Parameters for the `workspace/textDocumentContent/refresh` request.
 *
 * @since 3.18.0
 */
export interface TextDocumentContentRefreshParams {
	/**
	 * The uri of the text document to refresh.
	 */
	uri: DocumentUri;
}

Response:

  • 结果:void
  • 错误:如果在工作区符号解析请求期间发生异常,则设置代码和消息。

窗口特性

显示消息通知 (:arrow_left:)

显示消息通知从服务器发送到客户端,要求客户端在用户界面中显示特定消息。

通知:

  • 方法:“window/showMessage”
  • 参数:定义如下的 ShowMessageParams
interface ShowMessageParams {
	/**
	 * The message type. See {@link MessageType}.
	 */
	type: MessageType;

	/**
	 * The actual message.
	 */
	message: string;
}

其中类型定义如下

export namespace MessageType {
	/**
	 * An error message.
	 */
	export const Error = 1;
	/**
	 * A warning message.
	 */
	export const Warning = 2;
	/**
	 * An information message.
	 */
	export const Info = 3;
	/**
	 * A log message.
	 */
	export const Log = 4;
	/**
	 * A debug message.
	 *
	 * @since 3.18.0
	 */
	export const Debug = 5;
}

export type MessageType = 1 | 2 | 3 | 4 | 5;

显示消息请求 (:arrow_right_hook:)

显示消息请求从服务器发送到客户端,要求客户端在用户界面中显示特定消息。除了显示消息通知外,该请求还允许传递操作并等待客户端的回答。

客户端能力:

  • 属性路径(可选):window.showMessage
  • 属性类型:定义如下的 ShowMessageRequestClientCapabilities
/**
 * Show message request client capabilities
 */
export interface ShowMessageRequestClientCapabilities {
	/**
	 * Capabilities specific to the `MessageActionItem` type.
	 */
	messageActionItem?: {
		/**
		 * Whether the client supports additional attributes which
		 * are preserved and sent back to the server in the
		 * request's response.
		 */
		additionalPropertiesSupport?: boolean;
	};
}

请求:

  • 方法:“window/showMessageRequest”
  • 参数:定义如下的 ShowMessageRequestParams
interface ShowMessageRequestParams {
	/**
	 * The message type. See {@link MessageType}.
	 */
	type: MessageType;

	/**
	 * The actual message.
	 */
	message: string;

	/**
	 * The message action items to present.
	 */
	actions?: MessageActionItem[];
}

其中 MessageActionItem 定义如下

interface MessageActionItem {
	/**
	 * A short title like 'Retry', 'Open Log' etc.
	 */
	title: string;
}

Response:

  • 结果:选定的 MessageActionItem | 如果未选择,则为 null。
  • 错误:如果在显示消息期间发生异常,则设置代码和消息。

显示文档请求 (:arrow_right_hook:)

版本 3.16.0 新增

显示文档请求从服务器发送到客户端,要求客户端在用户界面中显示由 URI 引用的特定资源。

客户端能力:

  • 属性路径(可选):window.showDocument
  • 属性类型:定义如下的 ShowDocumentClientCapabilities
/**
 * Client capabilities for the show document request.
 *
 * @since 3.16.0
 */
export interface ShowDocumentClientCapabilities {
	/**
	 * The client has support for the show document
	 * request.
	 */
	support: boolean;
}

请求:

  • 方法:“window/showDocument”
  • 参数:定义如下的 ShowDocumentParams
/**
 * Params to show a resource.
 *
 * @since 3.16.0
 */
export interface ShowDocumentParams {
	/**
	 * The URI to show.
	 */
	uri: URI;

	/**
	 * Indicates to show the resource in an external program.
	 * To show, for example, `https://vscode.js.cn/`
	 * in the default web browser, set `external` to `true`.
	 */
	external?: boolean;

	/**
	 * An optional property to indicate whether the editor
	 * showing the document should take focus or not.
	 * Clients might ignore this property if an external
	 * program is started.
	 */
	takeFocus?: boolean;

	/**
	 * An optional selection range if the document is a text
	 * document. Clients might ignore this property if an
	 * external program is started or the file is not a text
	 * file.
	 */
	selection?: Range;
}

Response:

  • 结果:定义如下的 ShowDocumentResult
/**
 * The result of a show document request.
 *
 * @since 3.16.0
 */
export interface ShowDocumentResult {
	/**
	 * A boolean indicating if the show was successful.
	 */
	success: boolean;
}
  • 错误:如果在显示文档期间发生异常,则设置代码和消息。

LogMessage 通知 (:arrow_left:)

日志消息通知从服务器发送到客户端,要求客户端记录特定消息。

通知:

  • 方法:“window/logMessage”
  • 参数:定义如下的 LogMessageParams
interface LogMessageParams {
	/**
	 * The message type. See {@link MessageType}.
	 */
	type: MessageType;

	/**
	 * The actual message.
	 */
	message: string;
}

创建工作完成进度(:arrow_right_hook:)

window/workDoneProgress/create 请求从服务器发送到客户端,要求客户端创建工作完成进度。

客户端能力:

  • 属性名称(可选):window.workDoneProgress
  • 属性类型:boolean

请求:

  • 方法:“window/workDoneProgress/create”
  • 参数:定义如下的 WorkDoneProgressCreateParams
export interface WorkDoneProgressCreateParams {
	/**
	 * The token to be used to report progress.
	 */
	token: ProgressToken;
}

Response:

  • 结果:void
  • 错误:如果在“window/workDoneProgress/create”请求期间发生异常,则设置代码和消息。如果发生错误,服务器不得使用 WorkDoneProgressCreateParams 中提供的令牌发送任何进度通知。

取消工作完成进度(:arrow_right:)

客户端向服务器发送 window/workDoneProgress/cancel 通知,以取消使用 window/workDoneProgress/create 在服务器端启动的进度。进度无需标记为 cancellable 即可取消,客户端可以出于多种原因取消进度:发生错误、重新加载工作区等。

通知:

  • 方法:“window/workDoneProgress/cancel”
  • 参数:定义如下的 WorkDoneProgressCancelParams
export interface WorkDoneProgressCancelParams {
	/**
	 * The token to be used to report progress.
	 */
	token: ProgressToken;
}

遥测通知 (:arrow_left:)

遥测通知从服务器发送到客户端,要求客户端记录遥测事件。协议不指定负载,因为协议中不会对数据进行解释。大多数客户端甚至不直接处理事件,而是将其转发给拥有发出事件的相应服务器的扩展。

通知:

  • 方法:“telemetry/event”
  • 参数:“object” | “array”;

杂项

实现考量

语言服务器通常在单独的进程中运行,客户端以异步方式与它们通信。此外,客户端通常允许用户与源代码交互,即使请求结果处于挂起状态。我们建议使用以下实现模式,以避免客户端应用过时的响应结果

  • 如果客户端向服务器发送请求,并且客户端状态以使响应失效的方式发生更改,则客户端应执行以下操作
    • 如果结果对客户端不再有用,则取消服务器请求并忽略结果。如有必要,客户端应重新发送请求。
    • 如果客户端仍然可以使用结果,例如通过将状态更改应用于结果将其转换为新结果,则保持请求运行。
  • 因此,服务器不应仅仅因为队列中检测到状态更改通知而自行决定取消请求。如前所述,结果可能仍然对客户端有用。
  • 如果服务器检测到内部状态更改(例如,项目上下文更改)导致正在执行的请求结果失效,则服务器可以使用 ContentModified 错误这些请求。如果客户端收到 ContentModified 错误,通常不应在 UI 中向最终用户显示。如果客户端知道如何操作,可以重新发送请求。需要注意的是,对于所有基于位置的请求,客户端可能尤其难以重新构建请求。
  • 客户端不应为过时的对象(例如,代码透镜)发送解析请求。如果服务器收到针对过时对象的解析请求,服务器可以使用 ContentModified 错误这些请求。
  • 如果客户端注意到服务器意外退出,它应该尝试重新启动服务器。但是,客户端应注意不要无休止地重新启动崩溃的服务器。例如,VS Code 不会重新启动在过去 180 秒内崩溃 5 次的服务器。

服务器通常支持不同的通信通道(例如 stdio、管道等)。为了方便在不同客户端中使用服务器,强烈建议服务器实现支持以下命令行参数来选择通信通道

  • stdio:使用 stdio 作为通信通道。
  • pipe:使用管道(Windows)或套接字文件(Linux,Mac)作为通信通道。管道/套接字文件名作为下一个参数或通过 --pipe= 传递。
  • socket:使用套接字作为通信通道。端口作为下一个参数或通过 --port= 传递。
  • node-ipc:在客户端和服务器之间使用 Node IPC 通信。仅当客户端和服务器都运行在 Node 环境下时才支持。

为了支持启动服务器的编辑器崩溃的情况,编辑器还应该将其进程 ID 传递给服务器。这允许服务器监视编辑器进程,并在编辑器进程死亡时自行关闭。命令行上传递的进程 ID 应该与初始化参数中传递的进程 ID 相同。要使用的命令行参数是 --clientProcessId。

元模型

自 3.17 版以来,有一个描述 LSP 协议的元模型

  • metaModel.json:LSP 3.18 规范的实际元模型
  • metaModel.ts:一个 TypeScript 文件,定义构成元模型的数据类型。
  • metaModel.schema.json:一个 JSON 模式文件,定义构成元模型的数据类型。可用于生成读取元模型 JSON 文件的代码。

更新日志

3.18.0 (mm/dd/yyyy)

  • 添加了内联补全支持。
  • 添加了动态文本文档内容支持。
  • 添加了折叠范围的刷新支持。
  • 支持一次格式化多个范围。
  • 支持工作区编辑中的代码片段。
  • 文档过滤器和笔记本文档过滤器的相对模式支持。
  • 支持代码操作类型文档。
  • 为 SignatureHelp 和 SignatureInformation 上的 activeParameter 添加了 null 支持。
  • 支持 Command 的工具提示。
  • 支持工作区编辑中的元数据信息。
  • 支持文本文档编辑中的代码片段。
  • 支持调试消息类型。
  • 客户端功能,用于枚举代码透镜可以解析的属性。
  • 添加了对 completionList.applyKind 的支持,以确定如何组合 completionList.itemDefaults 和 completion 中的值。

3.17.0 (05/10/2022)

  • 指定客户端如何处理过时的请求。
  • 添加了对补全项标签详细信息的支持。
  • 添加了对工作区符号解析请求的支持。
  • 添加了对补全项上的标签详细信息和插入文本模式的支持。
  • 添加了对 CompletionItemList 上共享值的支持。
  • 添加了对 Markdown 中 HTML 标签的支持。
  • 添加了对折叠中折叠文本的支持。
  • 添加了对代码操作请求上的触发器类型的支持。
  • 为语义令牌添加了以下支持
    • 服务器可取消
    • 语法令牌的增强
  • 添加了对协商位置编码的支持。
  • 添加了对文件监视器中相对模式的支持。
  • 添加了对类型层次结构的支持
  • 添加了对内联值的支持。
  • 添加了对嵌入提示的支持。
  • 添加了对笔记本文档的支持。
  • 添加了对诊断拉取模型的支持。

3.16.0 (12/14/2020)

  • 添加了对跟踪的支持。
  • 添加了语义令牌支持。
  • 添加了调用层次结构支持。
  • 添加了用于解析补全项上的文本编辑的客户端功能。
  • 添加了对重命名时客户端默认行为的支持。
  • 添加了对 CompletionItem 上插入和替换范围的支持。
  • 添加了对诊断代码描述的支持。
  • 添加了对文档符号提供程序标签的支持。
  • 添加了对 SymbolInformation 和 DocumentSymbol 上标签的支持。
  • 添加了对标识符请求方法的支持。
  • 添加了对代码操作 data 属性的支持。
  • 添加了对代码操作 disabled 属性的支持。
  • 添加了对代码操作解析请求的支持。
  • 添加了对诊断 data 属性的支持。
  • 添加了对签名信息 activeParameter 属性的支持。
  • 添加了对 workspace/didCreateFiles 通知和 workspace/willCreateFiles 请求的支持。
  • 添加了对 workspace/didRenameFiles 通知和 workspace/willRenameFiles 请求的支持。
  • 添加了对 workspace/didDeleteFiles 通知和 workspace/willDeleteFiles 请求的支持。
  • 添加了客户端功能,用于指示客户端是否规范化行尾。
  • 添加了对在 MessageActionItem 上保留附加属性的支持。
  • 添加了在初始化调用中提供客户端区域设置的支持。
  • 添加了在客户端用户界面中打开和显示文档的支持。
  • 添加了对链接编辑的支持。
  • 添加了对文本编辑以及创建文件、重命名文件和删除文件操作中的更改注释的支持。

3.15.0 (01/14/2020)

  • 添加了通用进度报告支持。
  • 在适用的请求中添加了特定的工作完成进度报告支持。
  • 在适用的请求中添加了特定的部分结果进度支持。
  • 添加了对 textDocument/selectionRange 的支持。
  • 添加了对服务器和客户端信息的支持。
  • 添加了签名帮助上下文。
  • 将 Erlang 和 Elixir 添加到支持的编程语言列表
  • 在 PublishDiagnosticsParams 上添加了 version
  • 添加了 CodeAction#isPreferred 支持。
  • 添加了 CompletionItem#tag 支持。
  • 添加了 Diagnostic#tag 支持。
  • 添加了 DocumentLink#tooltip 支持。
  • 在 FormattingOptions 中添加了 trimTrailingWhitespace、insertFinalNewline 和 trimFinalNewlines。
  • 澄清了 WorkspaceSymbolParams#query 参数。

3.14.0 (12/13/2018)

  • 添加了对签名标签偏移量的支持。
  • 添加了对位置链接的支持。
  • 添加了对 textDocument/declaration 请求的支持。

3.13.0 (9/11/2018)

  • 添加了对文件和文件夹操作(创建、重命名、移动)到工作区编辑的支持。

3.12.0 (8/23/2018)

  • 添加了对 textDocument/prepareRename 请求的支持。

3.11.0 (8/21/2018)

  • 添加了对 CodeActionOptions 的支持,以允许服务器提供其支持的代码操作列表。

3.10.0 (7/23/2018)

  • 添加了对分层文档符号的支持,作为 textDocument/documentSymbol 请求的有效响应。
  • 添加了对折叠范围的支持,作为 textDocument/foldingRange 请求的有效响应。

3.9.0 (7/10/2018)

  • 添加了对 CompletionItem 中 preselect 属性的支持

3.8.0 (6/11/2018)

  • 在 textDocument/codeAction 请求中添加了对 CodeAction 字面量的支持。
  • ColorServerCapabilities.colorProvider 也可以是布尔值。
  • 更正了 ColorPresentationParams.colorInfo 为 color(与 d.ts 和实现中一致)。

3.7.0 (4/5/2018)

  • 添加了对诊断中相关信息的支持。

3.6.0 (2/22/2018)

将关于工作区文件夹、配置、转到类型定义、转到实现和文档颜色提供程序的拟议协议合并到规范的主分支。详情请参阅

  • 获取工作区文件夹
  • DidChangeWorkspaceFolders 通知
  • 获取配置
  • 转到类型定义
  • 转到实现
  • 文档颜色
  • 颜色呈现

此外,我们增强了 CompletionTriggerKind,新增了一个值 TriggerForIncompleteCompletions: 3 = 3,以表示由于上次结果不完整而触发了完成请求。

3.5.0

决定跳过此版本,以使协议版本号与 npm 模块 vscode-languageserver-protocol 同步。

3.4.0 (11/27/2017)

  • 可扩展的完成项和符号类型。

3.3.0 (11/24/2017)

  • 添加了对 CompletionContext 的支持。
  • 添加了对 MarkupContent 的支持。
  • 移除了旧的“New”和“Updated”标记。

3.2.0 (09/26/2017)

  • 为 CompletionItem 添加了可选的 commitCharacters 属性。

3.1.0 (02/28/2017)

  • 使 WorkspaceEdit 更改向后兼容。
  • 更新了规范,以正确描述 2.x 到 3.x 版本中关于 WorkspaceEdit 和 TextDocumentEdit 的破坏性更改。

3.0 版本

  • 添加了对客户端功能标志的支持,以支持服务器适应不同的客户端功能。例如,新的 textDocument/willSaveWaitUntil 请求并非所有客户端都可能支持。如果在初始化请求中发送的客户端功能中禁用了该功能,则服务器无法依赖接收该请求。
  • 添加了对试验新功能的支持。新的 ClientCapabilities.experimental 部分以及功能标志允许服务器提供实验性功能,而无需所有客户端立即采用它们。
  • 服务器可以更动态地响应客户端功能。现在可以使用新的 client/registerCapability 和 client/unregisterCapability 在初始化请求之后注册和取消注册功能。例如,这允许服务器在不重新启动的情况下响应设置或配置更改。
  • 添加了对 textDocument/willSave 通知和 textDocument/willSaveWaitUntil 请求的支持。
  • 添加了对 textDocument/documentLink 请求的支持。
  • 在 initializeParams 中添加了 rootUri 属性,以取代 rootPath 属性。
基础协议
  • 头部
  • 内容
  • 基础类型
  • 请求消息
  • 响应消息
  • 通知消息
  • 取消支持
  • 进度支持
语言服务器协议
  • 概述
  • 功能
  • 消息排序
  • 消息文档
基本 JSON 结构
  • URI
  • 正则表达式
  • 枚举
  • 文本文档
  • 位置
  • Range
  • 文本文档项
  • 文本文档标识符
  • 带版本号的文本文档标识符
  • 文本文档位置参数
  • 模式
  • 文档过滤器
  • 字符串值
  • 文本编辑
  • 文本编辑数组
  • 文本文档编辑
  • 位置
  • 位置链接
  • 诊断
  • 命令
  • 标记内容
  • 文件资源更改
  • 工作区编辑
  • 工作进度
  • 客户端发起进度
  • 服务器发起进度
  • 部分结果
  • 部分结果参数
  • 追踪值
生命周期消息
  • 概述
  • 初始化
  • 已初始化
  • 注册能力
  • 注销能力
  • 设置追踪
  • 日志追踪
  • 关闭
  • 退出
文档同步
  • 概述 - 文本文档
  • 打开文本文档
  • 更改文本文档
  • 将要保存文本文档
  • 将要保存文档直到
  • 已保存文本文档
  • 已关闭文本文档
  • 重命名文本文档
  • 概述 - 笔记本文档
  • 打开笔记本文档
  • 更改笔记本文档
  • 已保存笔记本文档
  • 已关闭笔记本文档
语言特性
  • 概述
  • 跳转到声明
  • 跳转到定义
  • 转到类型定义
  • 转到实现
  • 查找引用
  • 准备调用层次结构
  • 调用层次结构传入调用
  • 调用层次结构传出调用
  • 准备类型层次结构
  • 类型层次结构超类型
  • 类型层次结构子类型
  • 文档高亮
  • 文档链接
  • 文档链接解析
  • 悬停
  • 代码透镜
  • 代码透镜刷新
  • 折叠范围
  • 折叠范围刷新
  • 选择范围
  • 文档符号
  • 语义令牌
  • 语义令牌刷新
  • 内联值
  • 内联值刷新
  • 内联提示
  • 内联提示解析
  • 内联提示刷新
  • 名称
  • 补全建议
  • 补全项解析
  • 发布诊断
  • 拉取诊断
  • 诊断刷新
  • 签名帮助
  • 代码操作
  • 代码操作解析
  • 文档颜色
  • 颜色呈现
  • 格式化
  • 范围格式化
  • 类型时格式化
  • 重命名
  • 准备重命名
  • 链接编辑范围
工作区特性
  • 工作区符号
  • 工作区符号解析
  • 获取配置
  • 配置已更改
  • 工作区文件夹
  • 工作区文件夹已更改
  • 将要创建文件
  • 已创建文件
  • 将要重命名文件
  • 已重命名文件
  • 将要删除文件
  • 已删除文件
  • 监视文件已更改
  • 执行命令
  • 应用编辑
  • 文本文档内容
窗口特性
  • 显示消息通知
  • 显示消息请求
  • 日志消息
  • 显示文档
  • 创建工作完成进度
  • 取消工作完成进度
  • 发送遥测数据
杂项
  • 实现考量
  • 元模型
更新日志
  • 3.18.0
  • 3.17.0
  • 3.16.0
  • 3.15.0
  • 3.14.0
  • 3.13.0
  • 3.12.0
  • 3.11.0
  • 3.10.0
  • 3.9.0
  • 3.8.0
  • 3.7.0
  • 3.6.0
  • 3.5.0
  • 3.4.0
  • 3.3.0
  • 3.2.0
  • 3.1.0
  • 3.0
  • 来自西雅图和苏黎世的问候。
  • 点赞
  • 观看
  • 管理 Cookie
  • Microsoft © 2025 Microsoft