LSP / LSIF

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

语言服务器协议规范 - 3.15

基础协议
  • 头部
  • 内容
  • 请求消息
  • 响应消息
  • 通知消息
  • $/cancelRequest
  • $/progress
基本结构
  • URI
  • 文本文档
  • 位置
  • Range
  • 位置
  • 位置链接
  • 诊断
  • 命令
  • 文本编辑
  • 文本文档编辑
  • 文件资源更改
  • 工作区编辑
  • 文本文档标识符
  • 文本文档项
  • 带版本号的文本文档标识符
  • 文本文档位置参数
  • 文档过滤器
  • 静态注册选项
  • 文本文档注册选项
  • 标记内容
  • 工作进度
  • 客户端发起进度
  • 服务器发起进度
  • 部分结果
  • 部分结果参数
通用消息
  • initialize
  • initialized
  • shutdown
  • exit
窗口
  • showMessage
  • showMessageRequest
  • logMessage
  • progress/create
  • progress/cancel
遥测
  • event
客户端
  • registerCapability
  • unregisterCapability
工作区
  • workspaceFolders
  • didChangeWorkspaceFolders
  • didChangeConfiguration
  • configuration
  • didChangeWatchedFiles
  • symbol
  • executeCommand
  • applyEdit
文本同步
  • 通用功能
  • didOpen
  • didChange
  • willSave
  • willSaveWaitUntil
  • didSave
  • didClose
诊断
  • publishDiagnostics
语言特性
  • completion
  • completion resolve
  • 悬停
  • signatureHelp
  • 声明
  • 定义
  • 类型定义
  • 实现
  • 引用
  • documentHighlight
  • 文档符号
  • codeAction
  • codeLens
  • codeLens resolve
  • 文档链接
  • documentLink resolve
  • documentColor
  • colorPresentation
  • 格式化
  • rangeFormatting
  • onTypeFormatting
  • rename
  • prepareRename
  • 折叠范围
  • selectionRange
更新日志
  • 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.15.x 版本。该协议 3.15.x 版本的 Node.js 实现可在此处找到。

注意: 对本规范的编辑可以通过向此 Markdown 文档发送拉取请求来完成。

3.15 新增功能

所有新的 3.15 功能都带有相应的“自 3.15 版本以来”文本标签,或在 JSDoc 中使用 @since 3.15.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 协议

抽象消息

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

interface Message {
	jsonrpc: string;
}

请求消息

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

interface RequestMessage extends Message {

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

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

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

响应消息

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

interface ResponseMessage extends Message {
	/**
	 * The request id.
	 */
	id: number | 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: number;

	/**
	 * 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: number = -32700;
	export const InvalidRequest: number = -32600;
	export const MethodNotFound: number = -32601;
	export const InvalidParams: number = -32602;
	export const InternalError: number = -32603;
	export const serverErrorStart: number = -32099;
	export const serverErrorEnd: number = -32000;
	export const ServerNotInitialized: number = -32002;
	export const UnknownErrorCode: number = -32001;

	// Defined by the protocol.
	export const RequestCancelled: number = -32800;
	export const ContentModified: number = -32801;
}

通知消息

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

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: number | string;
}

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

进度支持 (➡️ ⬅️)

自 3.15.0 版起

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

进度通知具有以下属性

通知:

  • 方法:'$/progress'
  • 参数:定义如下的 ProgressParams
type ProgressToken = number | 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 格式在 http://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 模块,用于将字符串解析为 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;

文本文档

当前协议专为内容可表示为字符串的文本文档量身定制。目前不支持二进制文档。文档中的位置(参见下面的 Position 定义)表示为零基行和字符偏移。偏移基于 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: number;

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

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.
	 * For example, if the target 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, for example, 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?: number | string;

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

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

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, for example, 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;
}

命令

表示对命令的引用。提供一个标题,用于在 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

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

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

TextEdit[]

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

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

TextDocumentEdit

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

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

	/**
	 * The edits to be applied.
	 */
	edits: TextEdit[];
}

文件资源更改

3.13 版本新增

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

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

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

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

工作区编辑

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

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

	/**
	 * The client capability `workspace.workspaceEdit.resourceOperations`
	 * determines whether document changes are either an array of
	 * `TextDocumentEdit`s to express changes to different text documents,
	 * where each text document edit addresses a specific version
	 * of a text document, or it can contains the 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 doesn't support `documentChanges` or
	 * `workspace.workspaceEdit.resourceOperations`, then only plain
	 * `TextEdit`s using the `changes` property are supported.
	 */
	documentChanges?: (
		TextDocumentEdit[] |
		(TextDocumentEdit | CreateFile | RenameFile | DeleteFile)[]
	);
}
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;
}

/**
 * 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 transactionally.
	 * If resource changes (create, rename or delete file) are part of the
	 * change, the failure handling strategy is abort.
	 */
	export const TextOnlyTransactional: FailureHandlingKind
		= 'textOnlyTransactional';

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

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: number;

	/**
	 * 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.
	 * If a 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: number | null;
}

TextDocumentPositionParams

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

请求中使用的参数字面量,用于传递文本文档及其内部的位置。

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 conditions
	 *   (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files)
	 * - `[]` to declare a range of characters to match in a path segment
	 *   (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)
	 * - `[!...]` to negate a range of characters to match in a path segment
	 *   (e.g., `example.[!0-9]` to match on `example.a`, `example.b`,
	 *    but not `example.0`)
	 */
	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 问题中那样。

/**
 * 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.
 *
 * An example how such a string is constructed using JavaScript / TypeScript:
 * ```typescript
 * let markdown: MarkdownContent = {
 *  kind: MarkupKind.Markdown,
 *	value: [
 *		'# Header',
 *		'Some text',
 *		'```typescript',
 *		'someCode();',
 *		'```'
 *	].join('\n')
 * };
 * ```
 *
 * *Please Note* that clients might sanitize the returned Markdown.
 * A client could decide to remove HTML from the Markdown to avoid
 * script execution.
 */
export interface MarkupContent {
	/**
	 * The type of the Markup
	 */
	kind: MarkupKind;

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

工作进度

自 3.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 can 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.
	 */
	percentage?: number;
}
工作进度报告

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

export interface WorkDoneProgressReport {

	kind: 'report';

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

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

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

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

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 属性的存在,在每个请求实例上都会发出能力信号。

为避免客户端在发送请求之前设置进度监视用户界面,但服务器实际不报告任何进度,服务器需要通过相应的服务器能力来表明一般工作完成进度报告支持。对于上述查找引用示例,服务器将通过如下设置服务器能力中的 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
	 * (for example, streaming) to the client.
	 */
	partialResultToken?: ProgressToken;
}

实际协议

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

  • 描述请求的头部
  • 一个可选的 客户端能力 部分,描述请求的客户端能力。这包括客户端能力属性路径和 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: number | 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 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.
	 */
	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?: 'off' | 'messages' | 'verbose';

	/**
	 * 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 定义编辑器/工具在文本文档上提供的能力。
/**
 * 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;

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

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

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

	/**
	 * 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 was replaced by client capabilities.
	 * There is no version handshake in version 3.0x
	 */
	export const unknownProtocolVersion: number = 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 | number;

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

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

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

已初始化通知 (➡️)

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

通知:

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

关闭请求 (↩️)

shutdown 请求从客户端发送到服务器。它要求服务器关闭,但不要退出(否则响应可能无法正确传递给客户端)。有一个单独的 exit 通知要求服务器退出。客户端不得向已发送 shutdown 请求的服务器发送除 exit 之外的任何通知或请求。如果服务器在 shutdown 请求后收到请求,这些请求应以 InvalidRequest 错误代码报错。

请求:

  • 方法:'shutdown'
  • params: void

Response:

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

退出通知 (➡️)

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

通知:

  • 方法:'exit'
  • params: void

显示消息通知 (:arrow_left:)

显示消息通知从服务器发送到客户端,要求客户端在用户界面中显示特定消息。

通知:

  • 方法:“window/showMessage”
  • 参数:定义如下的 ShowMessageParams
interface ShowMessageParams {
	/**
	 * The message type. See {@link MessageType}.
	 */
	type: number;

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

显示消息请求 (:arrow_right_hook:)

显示消息请求从服务器发送到客户端,要求客户端在用户界面中显示特定消息。除了显示消息通知外,该请求还允许传递操作并等待客户端的回复。

请求:

  • 方法:“window/showMessageRequest”
  • 参数:定义如下的 ShowMessageRequestParams

Response:

  • 结果:选定的 MessageActionItem | 如果未选择,则为 null。
  • 错误:如果在显示消息期间发生异常,则设置代码和消息。
interface ShowMessageRequestParams {
	/**
	 * The message type. See {@link MessageType}
	 */
	type: number;

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

LogMessage 通知 (:arrow_left:)

日志消息通知从服务器发送到客户端,要求客户端记录特定消息。

通知:

  • 方法:“window/logMessage”
  • 参数:定义如下的 LogMessageParams
interface LogMessageParams {
	/**
	 * The message type. See {@link MessageType}
	 */
	type: number;

	/**
	 * 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 在服务器端启动的进度。

通知:

  • 方法:“window/workDoneProgress/cancel”
  • 参数:定义如下的 WorkDoneProgressCancelParams
export interface WorkDoneProgressCancelParams {
	/**
	 * The token to be used to report progress.
	 */
	token: ProgressToken;
}

遥测通知 (:arrow_left:)

遥测通知从服务器发送到客户端,要求客户端记录遥测事件。

通知:

  • 方法:“telemetry/event”
  • params: 'any'

注册能力 (↪️)

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

请求:

  • method: '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 版本起

workspace/didChangeWorkspaceFolders 通知从客户端发送到服务器,以告知服务器工作区文件夹配置更改。如果 客户端能力 workspace.workspaceFolders 和 服务器能力 workspace.workspaceFolders.supported 都为真,或者服务器已注册接收此通知,则默认发送此通知。要注册 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:

  • result: 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 conditions (e.g. `**​/*.{ts,js}` matches all TypeScript
	 *   and JavaScript files)
	 * - `[]` to declare a range of characters to match in a path segment
	 *   (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)
	 * - `[!...]` to negate a range of characters to match in a path segment
	 *   (e.g., `example.[!0-9]` to match on `example.a`, `example.b`,
	 *    but not `example.0`)
	 */
	globPattern: string;

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

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

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

服务器能力:

  • 属性路径(可选):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.
	 */
	query: string;
}

Response:

  • result: SymbolInformation[] | null 如上定义。
  • partial result: 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:

  • result: 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:

  • result: 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 may be used by the server for diagnostic
	 * logging or to provide a suitable error for a request that
	 * triggered the edit.
	 */
	failureReason?: string;
}
  • 错误:在请求期间发生异常时设置的代码和消息。

文本文档同步

协议中强制要求客户端支持 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 发生更改,如果服务器也处理新的语言 ID,客户端需要向服务器发送 textDocument/didClose,然后发送带有新语言 ID 的 textDocument/didOpen。

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

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

注册选项:TextDocumentRegistrationOptions

通知:

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

DidChangeTextDocument 通知 (:arrow_right:)

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

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

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

注册选项: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;
}

通知:

  • method: '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.
	 * 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?: number;

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

/**
 * Represents reasons why a text document is saved.
 */
export namespace TextDocumentSaveReason {

	/**
	 * Manually triggered, for example, 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;
}

WillSaveWaitUntilTextDocument 请求 (:leftwards_arrow_with_hook:)

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

客户端能力:

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

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

服务器能力:

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

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

注册选项:TextDocumentRegistrationOptions

请求:

  • method: 'textDocument/willSaveWaitUntil'
  • 参数:WillSaveTextDocumentParams

Response:

  • result:TextEdit[] | null
  • error: 在 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;
}

通知:

  • method: '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

通知:

  • method: '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 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?: number;
	/**
	 * 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;
}

通知:

  • method: 'textDocument/publishDiagnostics'
  • 参数:定义如下的 PublishDiagnosticsParams
interface PublishDiagnosticsParams {
	/**
	 * The URI for which diagnostic information is reported.
	 */
	uri: DocumentUri;

	/**
	 * The version number of the document the diagnostics are published for.
	 * Optional.
	 * @since 3.15.0
	 */
	version?: number;

	/**
	 * An array of diagnostic information items.
	 */
	diagnostics: Diagnostic[];
}

完成请求 (:leftwards_arrow_with_hook:)

补全请求从客户端发送到服务器,以计算给定光标位置的补全项。补全项在 IntelliSense 中显示。如果计算完整的补全项开销很大,服务器可以额外提供一个补全项解析请求('completionItem/resolve')的处理程序。此请求在用户界面中选择补全项时发送。一个典型的用例是:'textDocument/completion' 请求不填充返回补全项的 documentation 属性,因为计算成本很高。当在用户界面中选择该项时,会发送一个 'completionItem/resolve' 请求,并将选定的补全项作为参数。返回的补全项应填充文档属性。该请求只能延迟 detail 和 documentation 属性的计算。其他属性,如 sortText、filterText、insertText、textEdit 和 additionalTextEdits 必须在 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, so that typing in
		 * one will update others as well.
		 */
		snippetSupport?: boolean;

		/**
		 * Client supports commit characters on a completion item.
		 */
		commitCharactersSupport?: boolean

		/**
		 * Client supports the follow 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[]
		}
	};

	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 (for example 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 display `console` along with others as a
	 * completion item.
	 * Characters that make up identifiers don't need to be listed here.
	 *
	 * If code complete should automatically be triggered on characters
	 * not being valid inside an identifier (for example `.` in JavaScript),
	 * list them in `triggerCharacters`.
	 */
	triggerCharacters?: string[];

	/**
	 * The list of all possible characters that commit a completion.
	 * This field can be used if clients don't support individual commit
	 * characters per completion item. See `ClientCapabilities.`
	 * `textDocument.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 {
}

请求:

  • method: '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
	 * `ClientCapabilities.textDocument.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 `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 (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;

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?: number;

	/**
	 * 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.
	 */
	sortText?: string;

	/**
	 * A string that should be used when filtering a set of
	 * completion items. When `falsy` the label is used.
	 */
	filterText?: string;

	/**
	 * A string that should be inserted into a document when selecting
	 * this completion. When `falsy` the label is used.
	 *
	 * 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;

	/**
	 * An edit that 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.
	 */
	textEdit?: TextEdit;

	/**
	 * 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       ::= JavaScript Regular Expression value (ctor-string)
options     ::= JavaScript Regular Expression option (ctor-options)
var         ::= [_a-zA-Z] [_a-zA-Z0-9]*
int         ::= [0-9]+
text        ::= .*

完成项解析请求 (:leftwards_arrow_with_hook:)

该请求从客户端发送到服务器,以解析给定完成项的附加信息。

请求:

  • method: '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 follow content formats for the content
	 * property. 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 {
}

请求:

  • method: '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, meaning 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 follow 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 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 {
}

请求:

  • method: '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 ignore if
	 * the `SignatureHelp` as 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?: number;

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

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

/**
 * 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 | [number, number];

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

请求:

  • method: '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 {
}

请求:

  • method: '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 {
}

请求:

  • method: '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 {
}

请求:

  • method: '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 {
}

请求:

  • method: '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 {
}

请求:

  • method: '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?: number;
}

/**
 * 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;
}
  • 部分结果:DocumentHighlight[]
  • 错误:如果在文档高亮请求期间发生异常,则设置代码和消息。

文档符号请求 (:leftwards_arrow_with_hook:)

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

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

服务器能力:

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

注册选项:DocumentSymbolRegistrationOptions 定义如下

export interface DocumentSymbolRegistrationOptions
	extends TextDocumentRegistrationOptions, DocumentSymbolOptions {
}

请求:

  • method: '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;
}

/**
 * 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, for example, 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;

	/**
	 * Indicates if this symbol is deprecated.
	 */
	deprecated?: boolean;

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

	/**
	 * The range that should be selected and revealed when this symbol
	 * is being picked, for example, 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;

	/**
	 * Indicates if this symbol is deprecated.
	 */
	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)。如果客户端支持提供带有代码操作的编辑,则应使用该模式。

当命令被选中时,应该再次联系服务器(通过 workspace/executeCommand)请求来执行命令。

自版本 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;
}

服务器能力:

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

注册选项:定义如下的 CodeActionRegistrationOptions

export interface CodeActionRegistrationOptions
	extends TextDocumentRegistrationOptions, CodeActionOptions {
}

请求:

  • method: 'textDocument/codeAction'
  • 参数:定义如下的 CodeActionParams
/**
 * Params for the CodeActionRequest
 */
export interface CodeActionParams
	extends WorkDoneProgressParams, PartialResultParams {
	/**
	 * The document in which the command was invoked.
	 */
	textDocument: TextDocumentIdentifier;

	/**
	 * The range for which the command was invoked.
	 */
	range: Range;

	/**
	 * Context carrying additional information.
	 */
	context: CodeActionContext;
}

/**
 * The kind of a code action.
 *
 * Kinds are a hierarchical list of identifiers separated by `.`,
 * e.g. `"refactor.extract.function"`.
 *
 * The set of kinds is open and the client needs to announce the kinds it
 * supports to the server during initialization.
 */
export type CodeActionKind = string;

/**
 * A set of predefined code action kinds.
 */
export namespace CodeActionKind {

	/**
	 * Empty kind.
	 */
	export const Empty: CodeActionKind = '';

	/**
	 * Base kind for quickfix actions: 'quickfix'.
	 */
	export const QuickFix: CodeActionKind = 'quickfix';

	/**
	 * Base kind for refactoring actions: 'refactor'.
	 */
	export const Refactor: CodeActionKind = 'refactor';

	/**
	 * Base kind for refactoring extraction actions: 'refactor.extract'.
	 *
	 * Example extract actions:
	 *
	 * - Extract method
	 * - Extract function
	 * - Extract variable
	 * - Extract interface from class
	 * - ...
	 */
	export const RefactorExtract: CodeActionKind = 'refactor.extract';

	/**
	 * Base kind for refactoring inline actions: 'refactor.inline'.
	 *
	 * Example inline actions:
	 *
	 * - Inline function
	 * - Inline variable
	 * - Inline constant
	 * - ...
	 */
	export const RefactorInline: CodeActionKind = 'refactor.inline';

	/**
	 * Base kind for refactoring 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.
 * For example, 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;

	/**
	 * 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;
}
  • 部分结果:(Command | CodeAction)[]
  • 错误:如果在代码操作请求期间发生异常,则设置代码和消息。

代码镜头请求 (:leftwards_arrow_with_hook:)

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

客户端能力:

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

请求:

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

Response:

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

	/**
	 * The command this CodeLens represents.
	 */
	command?: Command;

	/**
	 * A data entry field that is preserved on a CodeLens item between
	 * a CodeLens and a CodeLens resolve request.
	 */
	data?: any
}
  • 部分结果:CodeLens[]
  • error: 在 CodeLens 请求期间发生异常时设置的代码和消息。

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

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

请求:

  • method: 'codeLens/resolve'
  • 参数:CodeLens

Response:

  • 结果:CodeLens
  • error: 在 CodeLens 解析请求期间发生异常时设置的代码和消息。

文档链接请求 (: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 {
}

请求:

  • method: '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, it will be displayed in a string that
	 * includes instructions on how to trigger the link,
	 * such as `{0} (ctrl + click)`.
	 * The specific instructions vary depending on OS, user settings,
	 * and localization.
	 *
	 * @since 3.15.0
	 */
	tooltip?: string;

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

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

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

请求:

  • method: '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 {
}

请求:

  • method: '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: number;

	/**
	 * The green component of this color in the range [0-1].
	 */
	readonly green: number;

	/**
	 * The blue component of this color in the range [0-1].
	 */
	readonly blue: number;

	/**
	 * The alpha component of this color in the range [0-1].
	 */
	readonly alpha: number;
}
  • 部分结果:ColorInformation[]
  • 错误:如果在“textDocument/documentColor”请求期间发生异常,则设置代码和消息

颜色呈现请求 (:leftwards_arrow_with_hook:)

自 3.6.0 版本起

颜色呈现请求从客户端发送到服务器,以获取给定位置的颜色值的呈现列表。客户端可以使用结果来

  • 修改颜色引用。
  • 在颜色选择器中显示,让用户选择其中一个呈现方式

此请求没有特殊的Capabilities和注册选项,因为它作为 textDocument/documentColor 请求的解析请求发送。

请求:

  • method: '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 {
}

请求:

  • method: '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: number;

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

请求:

  • method: '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 {
}

请求:

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

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

服务器能力:

  • 属性名称(可选):renameProvider
  • 属性类型:boolean | RenameOptions,其中 RenameOptions 定义如下

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

export interface RenameOptions extends WorkDoneProgressOptions {
	/**
	 * Renames should be checked and tested before being executed.
	 */
	prepareProvider?: boolean;
}

注册选项:定义如下的 RenameRegistrationOptions

export interface RenameRegistrationOptions
	extends TextDocumentRegistrationOptions, RenameOptions {
}

请求:

  • method: '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:

  • result: WorkspaceEdit | null 描述对工作区的修改。
  • error: 在重命名请求期间发生异常时设置的代码和消息。

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

自 3.12.0 版起

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

请求:

  • method: 'textDocument/prepareRename'
  • 参数:定义如下的 PrepareRenameParams
    export interface PrepareRenameParams extends TextDocumentPositionParams {
    }
    

Response:

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

折叠范围请求 (:leftwards_arrow_with_hook:)

自 3.10.0 版本起

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

客户端能力:

  • 属性名称(可选):textDocument.foldingRange
  • 属性类型:FoldingRangeClientCapabilities 定义如下
export interface FoldingRangeClientCapabilities {
	/**
	 * Whether the 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?: number;
	/**
	 * If set, the client signals that it only supports folding complete lines.
	 * If set, the 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 {
}

请求:

  • method: '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.
 */
export interface FoldingRange {

	/**
	 * The zero-based line number from where the folded range starts.
	 */
	startLine: number;

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

	/**
	 * The zero-based line number where the folded range ends.
	 */
	endLine: number;

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

	/**
	 * 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 中。

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

客户端能力:

  • 属性名称(可选):textDocument.selectionRange
  • 属性类型:SelectionRangeClientCapabilities 定义如下
export interface SelectionRangeClientCapabilities {
	/**
	 * Whether implementation supports dynamic registration for selection
	 * range providers.
	 * If 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 {
}

请求:

  • method: '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’ 请求期间发生异常,则设置代码和消息

实施注意事项

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

  • 如果客户端向服务器发送请求,并且客户端状态发生变化导致结果无效,则应取消服务器请求并忽略结果。如有必要,可以重新发送请求以接收最新结果。
  • 如果服务器检测到状态更改导致正在执行的请求结果无效,服务器可以使用 ContentModified 报错这些请求。如果客户端收到 ContentModified 错误,通常不应在用户界面中显示给最终用户。如果合适,客户端可以重新发送请求。
  • 如果服务器最终进入不一致状态,它们应该使用 window/logMessage 请求将其记录到客户端。如果它们无法从中恢复,目前最好的办法是自行退出。我们正在考虑 协议扩展,允许服务器请求客户端重启。
  • 如果客户端发现服务器意外退出,应尝试重新启动服务器。但是,客户端应注意不要无休止地重新启动崩溃的服务器。例如,VS Code 不会在过去 180 秒内崩溃 5 次的服务器。

更新日志

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 的支持。
  • 移除了旧的“New”和“Updated”标记。

3.2.0 (09/26/2017)

  • 为 CompletionItem 添加了可选的 commitCharacters 属性。

3.1.0 (02/28/2017)

  • 使 WorkspaceEdit 更改向后兼容。
  • 更新了规范,以正确描述 2.x 到 3.x 版本中关于 WorkspaceEdit 和 TextDocumentEdit 的破坏性更改。

3.0 版本

  • 添加对客户端功能标志的支持,以使服务器能够适应不同的客户端能力。一个例子是新的 textDocument/willSaveWaitUntil 请求,并非所有客户端都可能支持。如果在初始化请求中发送的客户端能力中禁用了该功能,服务器就不能依赖接收该请求。
  • 添加对新功能实验的支持。新的 ClientCapabilities.experimental 部分与功能标志结合使用,允许服务器提供实验性功能,而无需所有客户端立即采用。
  • 服务器可以更动态地响应客户端功能。现在可以使用新的 client/registerCapability 和 client/unregisterCapability 在初始化请求之后注册和注销功能。例如,这允许服务器在不重新启动的情况下响应设置或配置更改。
  • 添加对 textDocument/willSave 通知和 textDocument/willSaveWaitUntil 请求的支持。
  • 添加对 textDocument/documentLink 请求的支持。
  • 在 initializeParams 中添加 rootUri 属性,以取代 rootPath 属性。
基础协议
  • 头部
  • 内容
  • 请求消息
  • 响应消息
  • 通知消息
  • $/cancelRequest
  • $/progress
基本结构
  • URI
  • 文本文档
  • 位置
  • Range
  • 位置
  • 位置链接
  • 诊断
  • 命令
  • 文本编辑
  • 文本文档编辑
  • 文件资源更改
  • 工作区编辑
  • 文本文档标识符
  • 文本文档项
  • 带版本号的文本文档标识符
  • 文本文档位置参数
  • 文档过滤器
  • 静态注册选项
  • 文本文档注册选项
  • 标记内容
  • 工作进度
  • 客户端发起进度
  • 服务器发起进度
  • 部分结果
  • 部分结果参数
通用消息
  • initialize
  • initialized
  • shutdown
  • exit
窗口
  • showMessage
  • showMessageRequest
  • logMessage
  • progress/create
  • progress/cancel
遥测
  • event
客户端
  • registerCapability
  • unregisterCapability
工作区
  • workspaceFolders
  • didChangeWorkspaceFolders
  • didChangeConfiguration
  • configuration
  • didChangeWatchedFiles
  • symbol
  • executeCommand
  • applyEdit
文本同步
  • 通用功能
  • didOpen
  • didChange
  • willSave
  • willSaveWaitUntil
  • didSave
  • didClose
诊断
  • publishDiagnostics
语言特性
  • completion
  • completion resolve
  • 悬停
  • signatureHelp
  • 声明
  • 定义
  • 类型定义
  • 实现
  • 引用
  • documentHighlight
  • 文档符号
  • codeAction
  • codeLens
  • codeLens resolve
  • 文档链接
  • documentLink resolve
  • documentColor
  • colorPresentation
  • 格式化
  • rangeFormatting
  • onTypeFormatting
  • rename
  • prepareRename
  • 折叠范围
  • selectionRange
更新日志
  • 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