LSP / LSIF

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

语言服务器协议规范 - 3.16

基础协议
  • 头部
  • 内容
  • 请求消息
  • 响应消息
  • 通知消息
  • $/cancelRequest
  • $/progress
基本结构
  • URI
  • 正则表达式
  • 文本文档
  • 位置
  • Range
  • 位置
  • 位置链接
  • 诊断
  • 命令
  • 文本编辑
  • 文本文档编辑
  • 文件资源更改
  • 工作区编辑
  • 文本文档标识符
  • 文本文档项
  • 带版本号的文本文档标识符
  • 文本文档位置参数
  • 文档过滤器
  • 静态注册选项
  • 文本文档注册选项
  • 标记内容
  • 工作进度
  • 客户端发起进度
  • 服务器发起进度
  • 部分结果
  • 部分结果参数
  • 追踪值
通用消息
  • 初始化
  • 已初始化
  • 关闭
  • 退出
  • logTrace
  • setTrace
窗口
  • 显示消息
  • 显示消息请求
  • 显示文档
  • 日志消息
  • progress/create
  • progress/cancel
遥测
  • 事件
客户端
  • 注册能力
  • 注销能力
工作区
  • 工作区文件夹
  • didChangeWorkspaceFolders
  • didChangeConfiguration
  • 配置
  • didChangeWatchedFiles
  • 符号
  • 执行命令
  • 应用编辑
  • 文件操作事件
文本同步
  • 通用能力
  • didOpen
  • didChange
  • willSave
  • willSaveWaitUntil
  • didSave
  • didClose
诊断
  • 发布诊断
语言特性
  • 补全
  • 补全解析
  • 悬停
  • 签名帮助
  • 声明
  • 定义
  • 类型定义
  • 实现
  • 引用
  • 文档高亮
  • 文档符号
  • 代码操作
  • 代码操作解析
  • 代码透镜
  • 代码透镜解析
  • 代码透镜刷新
  • 文档链接
  • 文档链接解析
  • 文档颜色
  • 颜色呈现
  • 格式化
  • 范围格式化
  • onTypeFormatting
  • 重命名
  • prepareRename
  • 折叠范围
  • 选择范围
  • prepareCallHierarchy
  • callHierarchy incoming
  • callHierarchy outgoing
  • 语义标记
  • linkedEditingRange
  • 名称
更新日志
  • 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.16.x版本。协议3.16.x版本的Node.js实现可以在这里找到。

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

3.16中的新功能

所有新的3.16功能都带有相应的“自3.16版本”文本标签,或在JSDoc中使用@since 3.16.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 来描述请求、响应和通知。内容部分使用 Content-Type 字段中提供的字符集进行编码。它默认为 utf-8,这是目前唯一支持的编码。如果服务器或客户端收到带有不同于 utf-8 编码的头部,它应该返回一个错误。

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

示例

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

基础协议 JSON 结构

以下 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;

抽象消息

由 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?: string | number | boolean | object | null;

	/**
	 * 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?: string | number | boolean | array | object | null;
}

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 has 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;

	export const ContentModified: integer = -32801;
	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接口来描述这些结构。基于基本JSON结构,描述了实际的请求及其响应以及通知。

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

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

基本 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

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

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

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 的额外补全项类型并由客户端宣布,一个(较旧的)不知道该值的服务器不应该失败,而应该简单地将该值忽略为可用的项类型。

文本文档

目前的协议是为内容可以表示为字符串的文本文档量身定制的。目前不支持二进制文档。文档内的位置(参见下面的位置定义)表示为基于零的行和字符偏移量。偏移量基于 UTF-16 字符串表示。因此,在形式为 a𐐀b 的字符串中,字符 a 的字符偏移量为 0,字符 𐐀 的字符偏移量为 1,字符 b 的字符偏移量为 3,因为 𐐀 在 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). Assuming that
	 * the line is represented as a string, the `character` value represents
	 * the gap between the `character` and `character + 1`.
	 *
	 * If the character value is greater than the line length it defaults back
	 * to the line length.
	 */
	character: uinteger;
}

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

位置

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

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 for example is a symbol
	 * then 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;
}

诊断

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

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

	/**
	 * The diagnostic's severity. Can be omitted. If omitted it is up to the
	 * client to interpret diagnostics as error, warning, info or hint.
	 */
	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.
	 */
	message: string;

	/**
	 * 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?: unknown;
}

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

export namespace DiagnosticSeverity {
	/**
	 * Reports an error.
	 */
	export const Error: 1 = 1;
	/**
	 * Reports a warning.
	 */
	export const Warning: 2 = 2;
	/**
	 * Reports an 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 rendered 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 diagnostics, 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 {
	/**
	 * An URI to open with more information about the diagnostic error.
	 */
	href: URI;
}

命令

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

interface Command {
	/**
	 * Title of the command, like `save`.
	 */
	title: string;
	/**
	 * The identifier of the actual command handler.
	 */
	command: string;
	/**
	 * Arguments that the command handler should be
	 * invoked with.
	 */
	arguments?: any[];
}

TextEdit & AnnotatedTextEdit

3.16 版新增:支持 AnnotatedTextEdit。

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

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 版本起,还引入了带注解的文本编辑(annotated text edit)的概念,它支持为文本编辑添加注解。注解可以添加描述文本编辑更改的信息。

/**
 * 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 prominent 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 prominent 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;
}

TextEdit[]

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

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

TextDocumentEdit

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

描述单个文本文档的文本更改。文本文档被引用为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`
	 */
	edits: (TextEdit | AnnotatedTextEdit)[];
}

文件资源更改

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 {
	/**
	 * A create
	 */
	kind: 'create';

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

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

	/**
	 * An optional annotation identifer 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 {
	/**
	 * A rename
	 */
	kind: 'rename';

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

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

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

	/**
	 * An optional annotation identifer 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 {
	/**
	 * A delete
	 */
	kind: 'delete';

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

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

	/**
	 * An optional annotation identifer 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' 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;
	};
}

/**
 * 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 transactional. 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 transactional. 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';
}

TextDocumentIdentifier

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

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

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
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

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

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 glob pattern, like `*.{ts,js}`.
	 *
	 * Glob patterns can have the following syntax:
	 * - `*` to match one 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`)
	 */
	pattern?: string;
}

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

export type DocumentSelector = DocumentFilter[];

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

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 `$`. This 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 which content is
 * interpreted base 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 return 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;
}

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

解析器 版本 文档
marked 1.1.0 Marked 文档

工作进度

自 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 show 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 in 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 control 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 in 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 to for example indicate 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[]。因此,部分结果也为SymbolInformation[]类型。客户端是否接受请求的部分结果通知由在请求参数中添加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报告部分结果,则整个结果必须通过n个$/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';

实际协议

本节记录了实际的语言服务器协议。它使用以下格式:

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

请求、通知和响应顺序

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

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

服务器生命周期

当前协议规范规定服务器的生命周期由客户端(例如 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?: any;

	/**
	 * 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 {

	synchronization?: TextDocumentSyncClientCapabilities;

	/**
	 * 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` request.
	 */
	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;
}

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

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

	/**
	 * Window specific client capabilities.
	 */
	window?: {
		/**
		 * Whether client supports handling progress notifications. If set
		 * servers are allowed to report in `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 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;
	};

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

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 `InitializeError`;
 */
export namespace InitializeError {
	/**
	 * 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;
}
  • 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 {
	/**
	 * 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;

	/**
	 * 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 workspace symbol support.
	 */
	workspaceSymbolProvider?: boolean | WorkspaceSymbolOptions;

	/**
	 * 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?: any;
}

已初始化通知 (➡️)

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

通知:

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

关闭请求 (↩️)

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

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

请求:

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

Response:

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

退出通知 (➡️)

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

通知:

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

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

设置追踪通知 (➡️)

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

通知:

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

显示消息通知 (: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;
}

export type MessageType = 1 | 2 | 3 | 4;

显示消息请求 (: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 定义如下

Response:

  • 结果:选定的 MessageActionItem | 如果未选择任何项,则为 null。
  • 错误:在显示消息时发生异常时设置的代码和消息。
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;
}

显示文档请求 (:arrow_right_hook:)

版本3.16.0新增

显示文档请求从服务器发送到客户端,要求客户端在用户界面中显示特定文档。

客户端能力:

  • 属性路径(可选):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 document.
 *
 * @since 3.16.0
 */
export interface ShowDocumentParams {
	/**
	 * The document 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 the property if an
	 * external program is started or the file is not a text
	 * file.
	 */
	selection?: Range;
}

Response:

  • 结果:ShowDocumentResult 定义如下
/**
 * The result of an show document request.
 *
 * @since 3.16.0
 */
export interface ShowDocumentResult {
	/**
	 * A boolean indicating if the show was successful.
	 */
	success: boolean;
}
  • 错误:在显示文档时发生异常时设置的代码和消息。

日志消息通知 (: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/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' | 'number' | 'boolean' | 'string';

注册能力 (↪️)

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?: any;
}

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:

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

注销能力 (↪️)

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:

  • 结果:无。
  • 错误:在请求期间发生异常时设置的代码和消息。
工作区文件夹请求 (: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: DocumentUri;

	/**
	 * 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 版本起

3.16.0中的更正

规范曾指出,如果“客户端能力”workspace.workspaceFolders和“服务器能力”workspace.workspaceFolders.supported都为真,则默认发送通知。这是不正确的,正确的方法是使用上面定义的changeNotification属性,该属性也于3.6.0引入。

workspace/didChangeWorkspaceFolders通知从客户端发送到服务器,以告知服务器工作区文件夹配置更改。如果服务器使用服务器功能workspace.workspaceFolders.changeNotification表示对它的兴趣,或者服务器已自行注册以接收此通知,则会自动发送此通知。要注册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 the removed workspace folders
	 */
	removed: WorkspaceFolder[];
}

DidChangeConfiguration 通知 (:arrow_right:)

从客户端发送到服务器的通知,用于指示配置设置的更改。

客户端能力:

  • 属性路径(可选):workspace.didChangeConfiguration
  • 属性类型:DidChangeConfigurationClientCapabilities 定义如下
export interface DidChangeConfigurationClientCapabilities {
	/**
	 * Did change configuration notification supports dynamic registration.
	 */
	dynamicRegistration?: boolean;
}

通知:

  • 方法:'workspace/didChangeConfiguration',
  • 参数:DidChangeConfigurationParams 定义如下
interface DidChangeConfigurationParams {
	/**
	 * The actual changed settings
	 */
	settings: any;
}

配置请求 (:arrow_right_hook:)

自 3.6.0 版本起

workspace/configuration请求从服务器发送到客户端,以从客户端获取配置设置。该请求可以在一次往返中获取多个配置设置。返回的配置设置的顺序与传递的ConfigurationItems的顺序相对应(例如,响应中的第一个项是第一个配置项的结果)。

一个ConfigurationItem包含要查询的配置节和一个附加的范围URI。请求的配置节由服务器定义,不一定需要与客户端使用的配置存储对应。因此,服务器可能会请求配置cpp.formatterOptions,但客户端以不同的XML存储布局存储配置。进行必要的转换由客户端负责。如果提供了范围URI,客户端应返回限定到提供的资源的设置。如果客户端例如使用EditorConfig来管理其设置,则应针对传递的资源URI返回配置。如果客户端无法为给定范围提供配置设置,则返回数组中必须包含null。

客户端能力:

  • 属性路径(可选):workspace.configuration
  • 属性类型:boolean

请求:

  • 方法:'workspace/configuration'
  • 参数:ConfigurationParams 定义如下
export interface ConfigurationParams {
	items: ConfigurationItem[];
}

export interface ConfigurationItem {
	/**
	 * The scope to get the configuration section for.
	 */
	scopeUri?: DocumentUri;

	/**
	 * The configuration section asked for.
	 */
	section?: string;
}

Response:

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

DidChangeWatchedFiles 通知 (:arrow_right:)

当客户端检测到语言客户端监视的文件和文件夹发生更改时,会从客户端向服务器发送监视文件通知(请注意,尽管名称表明只发送文件事件,但它涉及文件系统事件,其中也包括文件夹)。建议服务器使用注册机制注册这些文件系统事件。在以前的实现中,客户端在服务器没有主动请求的情况下推送文件事件。

服务器可以运行自己的文件系统监视机制,而不依赖客户端提供文件系统事件。但是,由于以下原因,不建议这样做:

  • 根据我们的经验,正确实现磁盘文件系统监视具有挑战性,特别是如果它需要在多个操作系统上支持。
  • 文件系统监视并非免费,特别是如果实现使用某种轮询并保持文件系统树在内存中以比较时间戳(例如某些 node 模块那样)
  • 一个客户端通常启动多个服务器。如果每个服务器都运行自己的文件系统监视,可能会导致 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;
}

注册选项: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.
	 *
	 * Glob patterns can have the following syntax:
	 * - `*` to match one 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`)
	 */
	globPattern: string;

	/**
	 * The kind of events of interest. If omitted it defaults
	 * to WatchKind.Create | WatchKind.Change | WatchKind.Delete
	 * which is 7.
	 */
	kind?: uinteger;
}

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

通知:

  • 方法:'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: uinteger;
}

/**
 * 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;
}

工作区符号请求 (:leftwards_arrow_with_hook:)

工作区符号请求从客户端发送到服务器,以列出与查询字符串匹配的项目范围内的符号。

客户端能力:

  • 属性路径(可选):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`.
	 * Clients supporting tags have to handle unknown tags gracefully.
	 *
	 * @since 3.16.0
	 */
	tagSupport?: {
		/**
		 * The tags supported by the client.
		 */
		valueSet: SymbolTag[];
	};
}

服务器能力:

  • 属性路径(可选):workspaceSymbolProvider
  • 属性类型:boolean | WorkspaceSymbolOptions,其中 WorkspaceSymbolOptions 定义如下
export interface WorkspaceSymbolOptions extends WorkDoneProgressOptions {
}

注册选项: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[] | null,定义如上。
  • 部分结果:SymbolInformation[],定义如上。
  • 错误:在工作区符号请求期间发生异常时设置的代码和消息。

执行命令 (: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?: any[];
}

参数通常在服务器向客户端返回命令时指定。返回命令的请求示例包括 textDocument/codeAction 或 textDocument/codeLens。

Response:

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

应用工作区编辑 (: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;
}

Response:

  • 结果:ApplyWorkspaceEditResponse 定义如下
export interface ApplyWorkspaceEditResponse {
	/**
	 * 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;
}
  • 错误:在请求期间发生异常时设置的代码和消息。

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 one 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 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,该 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
  • 错误:在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,该 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
  • 错误:在willDeleteFiles请求期间发生异常时设置的代码和消息。

DidDeleteFiles 通知 (:arrow_right:)

当文件从客户端内部删除时,did delete files 通知从客户端发送到服务器。

客户端能力:

  • 属性名称(可选):workspace.fileOperations.didDelete
  • 属性类型:boolean

此功能表明客户端支持发送 workspace/didDeleteFiles 通知。

服务器能力:

  • 属性名称(可选):workspace.fileOperations.didDelete
  • 属性类型:FileOperationRegistrationOptions

此功能表明服务器对接收 workspace/didDeleteFiles 通知感兴趣。

通知:

  • 方法:'workspace/didDeleteFiles'
  • 参数:DeleteFilesParams

文本文档同步

客户端对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
	 * send.
	 */
	export const Incremental = 2;
}

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

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 中,参数的形状已更改为包含正确的版本号。

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

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

注册选项: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 range and rangeLength are
 * omitted the new text 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:)

文档将保存通知在文档实际保存之前从客户端发送到服务器。

客户端能力:

  • 属性名称(可选):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:)

在文档实际保存之前,将保存请求从客户端发送到服务器。该请求可以返回一个TextEdits数组,这些编辑将在文档保存之前应用到文本文档。请注意,如果计算文本编辑花费太长时间,或者服务器在此请求上持续失败,客户端可能会丢弃结果。这样做是为了保持保存的快速和可靠性。

客户端能力:

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

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

服务器能力:

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

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

注册选项:TextDocumentRegistrationOptions

请求:

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

Response:

  • 结果:TextEdit[] | null
  • 错误:在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;
}

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

/**
 * 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
	 * send.
	 */
	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 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;
}

发布诊断通知 (: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;

	/**
	 * Optional 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[];
}

完成请求 (:leftwards_arrow_with_hook:)

补全请求从客户端发送到服务器,以在给定光标位置计算补全项。补全项显示在IntelliSense用户界面中。如果计算完整补全项开销很大,服务器还可以为补全项解析请求('completionItem/resolve')提供处理程序。当用户界面中选择补全项时,将发送此请求。一个典型的用例如下:'textDocument/completion'请求不填充返回补全项的documentation属性,因为计算成本很高。当用户界面中选择该项时,将发送一个'completionItem/resolve'请求,并将选定的补全项作为参数。返回的补全项应填充documentation属性。默认情况下,该请求只能延迟detail和documentation属性的计算。自3.16.0版本起,客户端可以表明它能够延迟解析更多属性。这通过completionItem#resolveSupport客户端能力实现,该能力列出了所有可以在'completionItem/resolve'请求期间填充的属性。所有其他属性(通常是sortText、filterText、insertText和textEdit)必须在textDocument/completion响应中提供,并且在解析期间不得更改。

客户端能力:

  • 属性名称(可选):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 the following 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.
		 *
		 * @since 3.16.0
		 */
		insertTextModeSupport?: {
			valueSet: InsertTextMode[];
		};
	};

	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 items kinds from `Text` to `Reference` as defined in
		 * the initial version of the protocol.
		 */
		valueSet?: CompletionItemKind[];
	};

	/**
	 * The client supports to send additional context information for a
	 * `textDocument/completion` request.
	 */
	contextSupport?: 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
	 * 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 trigger 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;
}

注册选项: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 (24x7 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 trigger 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;

	/**
	 * 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 is taken as it is. If the
	 * value is multi line 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;

export interface CompletionItem {
	/**
	 * The label of this completion item. By default
	 * also the text that is inserted when selecting
	 * this completion.
	 */
	label: string;

	/**
	 * The kind of this completion item. Based of 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 `falsy` 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 `falsy` 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 `falsy` 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
	 * VS Code when code complete is requested in this example
	 * `con<cursor position>` and a completion item with an `insertText` of
	 * `console` is provided it 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`.
	 */
	insertTextFormat?: InsertTextFormat;

	/**
	 * How whitespace and indentation is handled during completion
	 * item insertion. If not provided the client's default value is used.
	 *
	 * @since 3.16.0
	 */
	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.
	 *
	 * 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.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.
	 * *Note 2:* If an `InsertReplaceEdit` is returned the edit's insert range
	 * must be a prefix of the edit's replace range, that means it must be
	 * contained and starting at the same position.
	 *
	 * @since 3.16.0 additional type `InsertReplaceEdit`
	 */
	textEdit?: TextEdit | InsertReplaceEdit;

	/**
	 * 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?: any;
}

/**
 * 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;
}
  • 部分结果:CompletionItem[] 或 CompletionList 后跟 CompletionItem[]。如果提供的第一个结果项是 CompletionList 类型,则后续的 CompletionItem[] 部分结果会添加到 CompletionList 的 items 属性中。
  • 错误:在补全请求期间发生异常时设置的代码和消息。

补全项支持代码片段(参见 InsertTextFormat.Snippet)。代码片段格式如下:

代码片段语法

代码片段的body可以使用特殊的构造来控制光标和要插入的文本。以下是支持的功能及其语法:

制表符停止点

通过制表符停止点,您可以让编辑器光标在代码片段内移动。使用$1、$2指定光标位置。数字是访问制表符停止点的顺序,而$0表示最终光标位置。多个制表符停止点是链接的并同步更新。

占位符

占位符是带有值的制表符停止点,例如 ${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(扩展巴克斯-诺尔范式)。使用\(反斜杠),您可以转义$、}和\。在选择元素中,反斜杠还转义逗号和竖线字符。

any         ::= tabstop | placeholder | choice | variable | text
tabstop     ::= '$' int | '${' int '}'
placeholder ::= '${' int ':' any '}'
choice      ::= '${' int '|' text (',' text)* '|}'
variable    ::= '$' var | '${' var }'
                | '${' var ':' any '}'
                | '${' var '/' regex '/' (format | text)+ '/' options '}'
format      ::= '$' int | '${' int '}'
                | '${' int ':' '/upcase' | '/downcase' | '/capitalize' '}'
                | '${' int ':+' if '}'
                | '${' int ':?' if ':' else '}'
                | '${' 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        ::= .*

补全项解析请求 (:leftwards_arrow_with_hook:)

该请求从客户端发送到服务器,以解析给定补全项的额外信息。

请求:

  • 方法:'completionItem/resolve'
  • 参数:CompletionItem

Response:

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

悬停请求 (: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.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 to send 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 signature but only one
 * active 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 implementors should make an active decision about
	 * the active signature and shouldn't rely on a default value.
	 *
	 * In future version of the protocol this property might become
	 * mandatory to better express this.
	 */
	activeSignature?: uinteger;

	/**
	 * The active parameter of the active signature. If omitted or the value
	 * lies outside the range of `signatures[activeSignature].parameters`
	 * defaults to 0 if the active signature has parameters. If
	 * the active signature has no parameters it is ignored.
	 * In future version of the protocol this property might become
	 * mandatory to better express the active parameter if the
	 * active signature does have any.
	 */
	activeParameter?: uinteger;
}

/**
 * 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 provided, this is used in place of `SignatureHelp.activeParameter`.
	 *
	 * @since 3.16.0
	 */
	activeParameter?: uinteger;
}

/**
 * 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 offsets within
	 * its containing signature label. (see SignatureInformation.label). The
	 * offsets are based on a UTF-16 string representation as `Position` and
	 * `Range` does.
	 *
	 * *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:)

自 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 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:)

文档高亮请求从客户端发送到服务器,以解析给定文本文档位置的文档高亮。对于编程语言,这通常会高亮显示此文件中符号的所有引用。然而,我们将“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:)

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

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

/**
 * Symbol tags are extra annotations that tweak the rendering of a symbol.
 *
 * @since 3.16.0
 */
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 its definition and one that points to its
 * 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 clients cursor is inside the symbol to reveal it 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.
 */
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:)

代码操作请求从客户端发送到服务器,以计算给定文本文档和范围的命令。这些命令通常是代码修复,用于解决问题或美化/重构代码。 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 字面量以实现以下场景:

  • 能够直接从代码操作请求返回工作区编辑。这避免了另一次服务器往返来执行实际的代码操作。但是,服务器提供者应该注意,如果代码操作计算昂贵或编辑量巨大,那么结果只是一个命令,并且仅在需要时才计算实际编辑可能仍然是有益的。
  • 能够使用种类对代码操作进行分组。客户端可以忽略该信息。但是,它允许客户端更好地对代码操作进行分组,例如将所有重构代码操作分组到相应的菜单(例如,所有重构代码操作到重构菜单)。

客户端需要通过相应的客户端能力 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 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;
}

服务器能力:

  • 属性名称(可选):codeActionProvider
  • 属性类型:boolean | CodeActionOptions,其中 CodeActionOptions 定义如下
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[];

	/**
	 * 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 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 rewrite actions: 'refactor.rewrite'.
	 *
	 * Example rewrite actions:
	 *
	 * - Convert JavaScript function to class
	 * - Add or remove parameter
	 * - Encapsulate field
	 * - Make method static
	 * - Move method to base class
	 * - ...
	 */
	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';
}

/**
 * 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.
	 */
	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[];
}

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?: any;
}
  • 部分结果:(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:)

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

客户端能力:

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

服务器能力:

  • 属性名称(可选):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?: any;
}
  • 部分结果:CodeLens[]
  • 错误:如果在代码镜头请求期间发生异常,则设置代码和消息。

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

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

请求:

  • 方法:'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 detect a project wide
	 * change that requires such a calculation.
	 */
	refreshSupport?: boolean;
}

请求:

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

Response:

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

文档链接请求 (: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?: DocumentUri;

	/**
	 * The tooltip text when you hover over this link.
	 *
	 * If a tooltip is provided, is 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?: any;
}
  • 部分结果:DocumentLink[]
  • 错误:如果在文档链接请求期间发生异常,则设置代码和消息。

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

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

请求:

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

Response:

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

文档颜色请求 (: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 `falsy` 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 format 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:)

文档范围格式化请求从客户端发送到服务器,以格式化文档中的给定范围。

客户端能力:

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

服务器能力:

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

注册选项: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 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 extends TextDocumentPositionParams {
	/**
	 * The character that has been typed.
	 */
	ch: string;

	/**
	 * The format 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 interface RenameClientCapabilities {
	/**
	 * Whether rename supports dynamic registration.
	 */
	dynamicRegistration?: boolean;

	/**
	 * Client supports testing for validity of rename operations
	 * before execution.
	 *
	 * @since 3.12.0
	 */
	prepareSupport?: boolean;

	/**
	 * Client supports the default behavior result
	 * (`{ defaultBehavior: boolean }`).
	 *
	 * The value indicates the default behavior used by the
	 * client.
	 *
	 * @since 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 定义如下

RenameOptions 只有在客户端在其初始 initialize 请求中声明支持 prepareSupport 时才能指定。

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 描述对工作区的修改。
  • 错误:在重命名请求期间发生异常时设置代码和消息。

准备重命名请求 (:leftwards_arrow_with_hook:)

自版本 3.12.0 起

准备重命名请求从客户端发送到服务器,以在给定位置设置和测试重命名操作的有效性。

请求:

  • 方法:‘textDocument/prepareRename’
  • 参数: PrepareRenameParams 定义如下
    export interface PrepareRenameParams extends TextDocumentPositionParams {
    }
    

Response:

  • 结果: Range | { range: Range, placeholder: string } | { defaultBehavior: boolean } | null 描述要重命名的字符串的 Range,以及可选的要重命名的字符串内容的占位符文本。如果返回 { defaultBehavior: boolean }(自 3.16 起),则重命名位置有效,客户端应使用其默认行为来计算重命名范围。如果返回 null,则认为在给定位置“textDocument/rename”请求无效。
  • 错误:在元素无法重命名时设置代码和消息。客户端应在其用户界面中显示此信息。

折叠范围请求 (: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;
}

服务器能力:

  • 属性名称(可选):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 定义如下
/**
 * Enum of known range kinds
 */
export enum FoldingRangeKind {
	/**
	 * Folding range for a comment
	 */
	Comment = 'comment',
	/**
	 * Folding range for imports or includes
	 */
	Imports = 'imports',
	/**
	 * Folding range for a region (e.g. `#region`)
	 */
	Region = 'region'
}

/**
 * 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?: string;
}
  • 部分结果:FoldingRange[]
  • 错误:如果在 ‘textDocument/foldingRange’ 请求期间发生异常,则设置代码和消息

选择范围请求 (:leftwards_arrow_with_hook:)

自 3.15.0 版起

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

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

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

客户端能力:

  • 属性名称(可选):textDocument.selectionRange
  • 属性类型:SelectionRangeClientCapabilities 定义如下
export interface SelectionRangeClientCapabilities {
	/**
	 * Whether 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:)

自 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?: unknown;
}
  • 错误:如果在 ‘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.16.0 版本起

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

一般概念

令牌使用一个令牌类型与 n 个令牌修饰符组合表示。令牌类型类似于 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'
}

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]。由于令牌类型可以有 n 个修饰符,因此可以通过使用位标志设置多个令牌修饰符,所以 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 中查找

令牌是否可以跨多行由客户端功能 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 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 clients 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;
}

服务器能力:

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

  • 属性名称(可选):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 detect a project
	 * wide change that requires such a calculation.
	 */
	refreshSupport?: boolean;
}

请求:

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

Response:

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

链接编辑范围 (: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.16.0 版本起

语言服务器索引格式 (LSIF) 引入了符号别名(moniker)的概念,以帮助关联不同索引中的符号。此请求增加了 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 索引之间正确关联。

实现考量

语言服务器通常在单独的进程中运行,客户端以异步方式与它们通信。此外,客户端通常允许用户与源代码交互,即使请求结果尚待处理。我们建议使用以下实现模式,以避免客户端应用过时的响应结果

  • 如果客户端向服务器发送请求,并且客户端状态发生变化,从而使响应无效,则应执行以下操作
    • 取消服务器请求,如果结果对客户端不再有用,则忽略结果。如有必要,客户端应重新发送请求。
    • 如果客户端仍然可以通过例如将状态更改应用于结果来将其转换为新结果来利用结果,则保持请求运行。
  • 因此,服务器不应仅仅因为队列中检测到状态更改通知而自行决定取消请求。如前所述,结果可能对客户端仍然有用。
  • 如果服务器检测到内部状态更改(例如项目上下文已更改),从而使正在执行的请求结果无效,则服务器可以使用 ContentModified 错误这些请求。如果客户端收到 ContentModified 错误,通常不应在最终用户的 UI 中显示它。如果客户端知道如何操作,则可以重新发送请求。应该注意的是,对于所有基于位置的请求,客户端重新创建请求可能特别困难。
  • 如果服务器最终处于不一致状态,它们应该使用 window/logMessage 请求将其记录到客户端。如果它们无法从中恢复,它们目前能做的最好的事情就是自行退出。我们正在考虑 协议的扩展,允许服务器请求客户端重启。
  • 如果客户端注意到服务器意外退出,它应该尝试重新启动服务器。但是,客户端应该小心,不要无休止地重新启动崩溃的服务器。例如,VS Code 不会重新启动在过去 180 秒内崩溃 5 次的服务器。

服务器通常支持不同的通信通道(例如 stdio、管道等)。为了方便在不同客户端中使用服务器,强烈建议服务器实现支持以下命令行参数来选择通信通道

  • stdio:使用 stdio 作为通信通道。
  • pipe:使用管道(Windows)或套接字文件(Linux、Mac)作为通信通道。管道/套接字文件名作为下一个参数或通过 --pipe= 传递。
  • socket:使用套接字作为通信通道。端口作为下一个参数或通过 --port= 传递。
  • node-ipc:在客户端和服务器之间使用 node IPC 通信。这仅在客户端和服务器都在 node 下运行的情况下受支持。

更新日志

3.16.0 (12/14/2020)

  • 添加对跟踪的支持。
  • 添加语义令牌支持。
  • 添加调用层次结构支持。
  • 添加客户端能力以解析完成项上的文本编辑。
  • 添加对重命名时客户端默认行为的支持。
  • 添加对 CompletionItem 上的插入和替换范围的支持。
  • 添加对诊断代码描述的支持。
  • 添加对文档符号提供程序标签的支持。
  • 添加对 SymbolInformation 和 DocumentSymbol 上的标签的支持。
  • 添加对别名请求方法(moniker request method)的支持。
  • 添加对代码操作 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 支持。
  • 将 trimTrailingWhitespace、insertFinalNewline 和 trimFinalNewlines 添加到 FormattingOptions。
  • 澄清 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 的支持。
  • 删除了旧的“新”和“已更新”标记。

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 请求,并非所有客户端都可能支持。如果在 initialize 请求中发送的客户端能力中禁用了该功能,服务器就不能依赖于接收该请求。
  • 添加支持以试验新功能。新的 ClientCapabilities.experimental 部分以及功能标志允许服务器提供实验性功能,而无需所有客户端立即采用它们。
  • 服务器可以更动态地响应客户端功能。现在可以在 initialize 请求之后使用新的 client/registerCapability 和 client/unregisterCapability 注册和注销能力。例如,这允许服务器在不重启的情况下响应设置或配置更改。
  • 添加对 textDocument/willSave 通知和 textDocument/willSaveWaitUntil 请求的支持。
  • 添加对 textDocument/documentLink 请求的支持。
  • 在 initializeParams 中添加 rootUri 属性,以取代 rootPath 属性。
基础协议
  • 头部
  • 内容
  • 请求消息
  • 响应消息
  • 通知消息
  • $/cancelRequest
  • $/progress
基本结构
  • URI
  • 正则表达式
  • 文本文档
  • 位置
  • Range
  • 位置
  • 位置链接
  • 诊断
  • 命令
  • 文本编辑
  • 文本文档编辑
  • 文件资源更改
  • 工作区编辑
  • 文本文档标识符
  • 文本文档项
  • 带版本号的文本文档标识符
  • 文本文档位置参数
  • 文档过滤器
  • 静态注册选项
  • 文本文档注册选项
  • 标记内容
  • 工作进度
  • 客户端发起进度
  • 服务器发起进度
  • 部分结果
  • 部分结果参数
  • 追踪值
通用消息
  • 初始化
  • 已初始化
  • 关闭
  • 退出
  • logTrace
  • setTrace
窗口
  • 显示消息
  • 显示消息请求
  • 显示文档
  • 日志消息
  • progress/create
  • progress/cancel
遥测
  • 事件
客户端
  • 注册能力
  • 注销能力
工作区
  • 工作区文件夹
  • didChangeWorkspaceFolders
  • didChangeConfiguration
  • 配置
  • didChangeWatchedFiles
  • 符号
  • 执行命令
  • 应用编辑
  • 文件操作事件
文本同步
  • 通用能力
  • didOpen
  • didChange
  • willSave
  • willSaveWaitUntil
  • didSave
  • didClose
诊断
  • 发布诊断
语言特性
  • 补全
  • 补全解析
  • 悬停
  • 签名帮助
  • 声明
  • 定义
  • 类型定义
  • 实现
  • 引用
  • 文档高亮
  • 文档符号
  • 代码操作
  • 代码操作解析
  • 代码透镜
  • 代码透镜解析
  • 代码透镜刷新
  • 文档链接
  • 文档链接解析
  • 文档颜色
  • 颜色呈现
  • 格式化
  • 范围格式化
  • onTypeFormatting
  • 重命名
  • prepareRename
  • 折叠范围
  • 选择范围
  • prepareCallHierarchy
  • callHierarchy incoming
  • callHierarchy outgoing
  • 语义标记
  • linkedEditingRange
  • 名称
更新日志
  • 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