LSP / LSIF

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

基本协议规范 - 0.9

基础协议
  • 头部
  • 内容
  • 功能
  • 消息排序
  • 消息文档
JSON 结构
  • 基础类型
  • URI
  • 正则表达式
  • 枚举
  • 抽象消息
  • 请求消息
  • 响应消息
  • 通知消息
  • 取消支持
  • 进度支持
  • 追踪值
生命周期消息
  • 初始化
  • 已初始化
  • 注册能力
  • 注销能力
  • 设置追踪
  • 日志追踪
  • 关闭
  • 退出
窗口特性
  • 显示消息通知
  • 显示消息请求
  • 日志消息
  • 已发送的遥测数据

基础协议

基本协议的目的是将常见的编辑器可扩展性模式抽象为自己的规范,而与支持此类扩展的语言服务器是否存在无关。特别是,诸如服务器和客户端功能、初始化和关闭请求以及请求和通知的结构等概念最初是语言服务器协议的一部分,但它们不应仅限于语言服务扩展。

一个激励性示例是 构建服务器协议。正如其规范所描述的,所有通知和请求都使用 LSP 的基本定义来定义,并且诸如 InitializeBuild、OnBuildInitialized 和 OnBuildExit 等消息几乎与其 LSP 对应项完全匹配。通过实现基本协议,服务器可以支持多个协议规范,而无需重新实现它们共享的“常见样板”。

请注意,基本协议目前处于实验性构建阶段,并且可能会发生重大更改。其未来的发展将取决于社区和协议初始实施者的反馈。

头部

基础协议由一个头部和一个内容部分组成(类似于 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 编码的头部,它应该返回一个错误。

示例

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

功能

并非所有服务器都能支持协议定义的所有功能。因此,基本协议提供了“功能”。一个功能组包含一组特性。开发工具和服务器使用功能来宣布它们支持的特性。例如,开发工具可以宣布支持文档创建通知,以便服务器可以执行相应的文档同步任务。

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

请注意,以下功能标识符列表已被语言服务器协议使用,因此不能在其他协议中使用

  • callHierarchyProvider
  • codeActionProvider
  • codeLensProvider
  • colorProvider
  • completionProvider
  • declarationProvider
  • definitionProvider
  • diagnosticProvider
  • documentFormattingProvider
  • documentHighlightProvider
  • documentLinkProvider
  • documentOnTypeFormattingProvider
  • documentRangeFormattingProvider
  • documentSymbolProvider
  • executeCommandProvider
  • experimental
  • foldingRangeProvider
  • general
  • hoverProvider
  • implementationProvider
  • inlayHintProvider
  • inlineValueProvider
  • linkedEditingRangeProvider
  • monikerProvider
  • notebookDocument
  • notebookDocumentSync
  • positionEncoding
  • referencesProvider
  • renameProvider
  • selectionRangeProvider
  • semanticTokensProvider
  • signatureHelpProvider
  • textDocument
  • textDocumentSync
  • typeDefinitionProvider
  • typeHierarchyProvider
  • window
  • workspace
  • workspaceSymbolProvider

请求、通知和响应排序

对请求的响应应大致按照请求在服务器或客户端出现的相同顺序发送。因此,例如,如果提供单元测试功能的服务器收到 testing/configureFramework 请求,然后收到 testing/configureProject 请求,它通常会首先返回 testing/configureFramework 的响应,然后返回 testing/configureProject 的响应。

然而,服务器可能决定使用并行执行策略,并希望以与收到请求不同的顺序返回响应。只要这种重新排序不影响响应的正确性,服务器就可以这样做。例如,允许重新排序 testing/configureFramework 和 testing/configureProject 的结果,因为这些请求通常不会影响彼此的输出。另一方面,服务器很可能不应该重新排序 testing/testCreated 和 testing/executeTest 请求,因为测试创建应该在执行之前发生。

消息文档

如前所述,基本协议定义了一组请求、响应和通知。这些都使用以下格式进行文档化

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

JSON 结构

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

基础类型

基本协议对整数、无符号整数、小数、对象和数组使用以下定义

/**
 * Defines an integer number in the range of -2^31 to 2^31 - 1.
 */
export type integer = number;
/**
 * Defines an unsigned integer number in the range of 0 to 2^31 - 1.
 */
export type uinteger = number;
/**
 * Defines a decimal number. Since decimal numbers are very
 * rare in the base protocol specification, we denote the
 * exact range with every decimal using the mathematics
 * interval notation (e.g. [0, 1] denotes all decimals d with
 * 0 <= d <= 1).
 */
export type decimal = number;
/**
 * Base Protocol any type.
 */
export type BaseAny = BaseObject | BaseArray | string | integer | uinteger |
	decimal | boolean | null;
/**
 * Base Protocol object definition.
 */
export type BaseObject = { [key: string]: BaseAny };
/**
 * Base Protocol arrays.
 */
export type BaseArray = BaseAny[];

URI

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

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

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

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

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

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

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

type URI = string;

正则表达式

正则表达式是一个强大的工具,在像 LSP 这样的协议中确实有实际的应用场景。然而,它们的缺点是几乎每种编程语言都有自己的一套正则表达式功能,因此基本规范不能简单地将它们称为正则表达式。

例如,LSP 使用两步法支持正则表达式

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

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

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

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

枚举

基本协议支持两种枚举:(a) 基于整数的枚举和 (b) 基于字符串的枚举。基于整数的枚举通常以 1 开头。如果合适,枚举的值集由定义方(例如,客户端或服务器)宣布,并在初始化握手期间传输到另一方。例如,考虑使用 PrintFormat 枚举的 printSymbol 请求。客户端可以通过 printing.format 属性宣布其支持的打印格式

/**
 * Capabilities specific to the `printSymbol` request.
 */
print: {
    format: [ "json", "compact", "checkstyle" ]
    ...
}

为了支持枚举的演进,枚举的使用方不应该因为不认识枚举值而失败。它应该简单地将其忽略为一个可用值,并尽力在往返过程中保留该值。我们再次以 PrintFormat 枚举为例:如果在协议的未来版本中添加了额外的 "html" 格式并由客户端宣布,一个(较旧的)服务器如果不知道该值,不应该失败,而只是将其忽略为可用的打印格式。

抽象消息

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

interface Message {
	jsonrpc: string;
}

请求消息

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

interface RequestMessage extends Message {

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

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

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

响应消息

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

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

	/**
	 * The result of a request. This member is REQUIRED on success.
	 * This member MUST NOT exist if there was an error invoking the method.
	 */
	result?: string | number | boolean | array | object | null;

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

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

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

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

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

	/**
	 * This is the end range of JSON-RPC reserved error codes.
	 * It doesn't denote a real error code.
	 */
	export const jsonrpcReservedErrorRangeEnd = -32000;

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

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

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

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

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

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

为了避免与语言服务协议采用的错误代码发生冲突,基本协议的其他实现者必须使用 lspReservedErrorRangeStart 和 lspReservedErrorRangeEnd 定义范围之外的错误代码。

通知消息

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

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

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

$ 通知和请求

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

取消支持 (➡️ ⬅️)

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

通知:

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

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

进度支持 (➡️ ⬅️)

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

进度通知具有以下属性

通知:

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

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

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

工作进度

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

工作进度开始

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

export interface WorkDoneProgressBegin {
	kind: 'begin';

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

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

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

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

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

export interface WorkDoneProgressReport {
	kind: 'report';

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

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

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

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

export interface WorkDoneProgressEnd {
	kind: 'end';

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

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

  1. 由请求发送方(通常是客户端)使用请求参数文字中预定义的 workDoneToken 属性。本文档将此类进度称为客户端发起进度。
  2. 通过服务器使用 window/workDoneProgress/create 请求。本文档将此类进度称为服务器发起进度。
客户端发起进度

考虑客户端向可以编译和构建应用程序的服务器发送 build/deploy 请求,并且客户端接受该请求上的工作完成进度报告。为了向服务器发出此信号,客户端将向引用请求参数添加一个 workDoneToken 属性

{
	"project": {
		"guid": "A083-41A9-A0E8"
	},
	"context": {
		"destinationDirectory": "/prod"
	},
	// 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 报告特定 build/deploy 的进度。对于上述请求,$/progress 通知参数如下所示

{
	"token": "1d546990-40a3-4b77-b134-46622995f6ae",
	"value": {
		"kind": "begin",
		"title": "Deploying project#A083-41A9-A0E8",
		"cancellable": false,
		"message": "Processing projectConfig.json",
		"percentage": 0
	}
}

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

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

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

{
	"build.deployProvider": {
		"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;
	};

TraceValue

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

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

生命周期消息

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

初始化请求 (↩️)

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

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

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

initiate 请求只能发送一次。

请求:

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

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

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

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

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

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

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

Response:

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

	/**
	 * Information about the server.
	 */
	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.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;
}

请注意,capabilities 在 InitializeParams 和 InitializeResult 中都指定为空对象,并留给基本协议的每个实现相应地定义。但是,为了避免与 LSP 使用的属性发生冲突,这些属性不能包含上述功能部分中列出的任何属性名称。

已初始化通知 (➡️)

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

通知:

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

注册能力 (↪️)

服务器向客户端发送 client/registerCapability 请求,以在客户端注册新功能。并非所有客户端都需要支持动态功能注册。客户端通过特定客户端功能上的 dynamicRegistration 属性选择加入。客户端甚至可以为功能 A 提供动态注册,但不能为功能 B 提供。

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

请求:

  • 方法:'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?: BaseAny;
}
export interface RegistrationParams {
	registrations: Registration[];
}

Response:

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

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

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

注销能力 (↪️)

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 {
	unregistrations: Unregistration[];
}

Response:

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

设置追踪通知 (➡️)

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

通知:

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

LogTrace 通知 (⬅️)

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

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

通知:

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

关闭请求 (↩️)

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

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

请求:

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

Response:

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

退出通知 (➡️)

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

通知:

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

窗口特性

显示消息通知 (:arrow_left:)

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

通知:

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

	/**
	 * The actual message.
	 */
	message: string;
}

其中类型定义如下

export namespace MessageType {
	/**
	 * An error message.
	 */
	export const Error = 1;
	/**
	 * A warning message.
	 */
	export const Warning = 2;
	/**
	 * An information message.
	 */
	export const Info = 3;
	/**
	 * A log message.
	 */
	export const Log = 4;
	/**
	 * A debug message.
	 *
	 * @since 3.18.0
	 * @proposed
	 */
	export const Debug = 5;
}

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

显示消息请求 (:arrow_right_hook:)

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

客户端能力:

  • 属性路径(可选):window.showMessage
  • 属性类型:定义如下的 ShowMessageRequestClientCapabilities
/**
 * Show message request client capabilities
 */
export interface ShowMessageRequestClientCapabilities {
	/**
	 * Capabilities specific to the `MessageActionItem` type.
	 */
	messageActionItem?: {
		/**
		 * Whether the client supports additional attributes which
		 * are preserved and sent back to the server in the
		 * request's response.
		 */
		additionalPropertiesSupport?: boolean;
	};
}

请求:

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

	/**
	 * The actual message
	 */
	message: string;

	/**
	 * The message action items to present.
	 */
	actions?: MessageActionItem[];
}

其中 MessageActionItem 定义如下

interface MessageActionItem {
	/**
	 * A short title like 'Retry', 'Open Log' etc.
	 */
	title: string;
}

Response:

  • 结果:选定的 MessageActionItem | 如果未选择,则为 null。
  • 错误:如果在显示消息期间发生异常,则设置代码和消息。

LogMessage 通知 (:arrow_left:)

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

通知:

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

	/**
	 * The actual message
	 */
	message: string;
}

遥测通知 (:arrow_left:)

遥测通知从服务器发送到客户端,要求客户端记录遥测事件。协议不指定有效负载,因为协议中不会对数据进行解释。大多数客户端甚至不直接处理事件,而是将其转发给拥有相应发出事件的服务器的扩展。

通知:

  • 方法:“telemetry/event”
  • 参数:“object” | “array”;
基础协议
  • 头部
  • 内容
  • 功能
  • 消息排序
  • 消息文档
JSON 结构
  • 基础类型
  • URI
  • 正则表达式
  • 枚举
  • 抽象消息
  • 请求消息
  • 响应消息
  • 通知消息
  • 取消支持
  • 进度支持
  • 追踪值
生命周期消息
  • 初始化
  • 已初始化
  • 注册能力
  • 注销能力
  • 设置追踪
  • 日志追踪
  • 关闭
  • 退出
窗口特性
  • 显示消息通知
  • 显示消息请求
  • 日志消息
  • 已发送的遥测数据
  • 来自西雅图和苏黎世的问候。
  • 点赞
  • 观看
  • 管理 Cookie
  • Microsoft © 2025 Microsoft