vscode插件快餐教程(6) - LSP协议的初始化参数
在前面的教程中,我们已经完成了LSP代码补全的基本实现,现在可以尝试搭建一套真正能跑起来的LSP系统了。不过在那之前,让我们先夯实一些基础细节,以便更顺利地推进后续开发。
第4节中我们已经探讨过LSP初始化时的握手过程。具体来说,在connection的onInitialize函数里,我们可以接收到客户端发送的初始化参数——例如客户端具备哪些能力。代码大致是这样的:
connection.onInitialize((params: InitializeParams) => {
let capabilities = params.capabilities;
return {
capabilities: {
textDocumentSync: documents.syncKind,
// 告诉客户端,服务端支持代码补全
completionProvider: {
resolveProvider: true
}
}
};
});
下面这张图展示了LSP初始化参数所包含的整体内容:

接下来,我们逐一解读这些参数的定义:
interface InitializeParams {
/** 启动服务端的父进程ID。
* 如果服务端不是由另一个进程启动的,则为null。
* 如果父进程挂了,服务端就应该退出(参见退出通知)。
*/
processId: number | null;
/** 工作区的根路径。
* 如果没有打开任何文件夹,则为null。
* @deprecated 建议改用rootUri。
*/
rootPath?: string | null;
/** 工作区的根URI。
* 如果没有打开任何文件夹,则为null。
* 如果同时设置了rootPath和rootUri,rootUri优先。
*/
rootUri: DocumentUri | null;
/** 用户提供的初始化选项。 */
initializationOptions?: any;
/** 客户端(编辑器或工具)提供的能力。 */
capabilities: ClientCapabilities;
/** 初始的跟踪设置。如果省略,默认关闭跟踪('off')。 */
trace?: 'off' | 'messages' | 'verbose';
/** 服务端启动时,客户端已配置的工作区文件夹列表。
* 仅在客户端支持工作区文件夹时可用。
* 如果客户端支持但没有任何文件夹被配置,则为null。
* @since 3.6.0
*/
workspaceFolders?: WorkspaceFolder[] | null;
}
将这些信息分类整理后,大致形成下面这张图的结构:

主要可分为三大类别:
第一类是运行环境相关的信息,比如进程ID和各类路径。第二类是客户端能力信息。第三类是一些辅助设定,例如trace开关和用户自定义的初始化选项。
需要特别注意的是,路径信息只有在VSCode中确实打开了一个目录时才能获取到。例如,假设我打开的目录是 /Users/ziyingliuziying/working/gitlab/cafmode/server,那么 rootPath 返回的就是 /Users/ziyingliuziying/working/gitlab/cafmode/server。而 rootUri 返回的是 file:///Users/ziyingliuziying/working/gitlab/cafmode/server。至于 workspaceFolders,它是一个由 WorkspaceFolder 组成的数组,每个 WorkspaceFolder 包含 name 和 uri 两个属性。还是用上面这个例子,name 就是 server,而 uri 同样是 file:///Users/ziyingliuziying/working/gitlab/cafmode/server。
