ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Language Server Protocol 文件创建事件通知:workspace/didCreateFiles 消息规范与实现解析

Language Server Protocol 文件创建事件通知:workspace/didCreateFiles 消息规范与实现解析 开发工具【免费下载链接】language-server-protocolDefines a common protocol for language servers.项目地址https://gitcode.com/gh_mirrors/la/language-server-protocol点击查看免费下载导读workspace/didCreateFiles是 Language Server ProtocolLSP3.16 版本引入的通知消息用于在客户端编辑器/IDE内部创建文件后将这一事件告知语言服务器帮助服务器及时更新索引、缓存与依赖关系。本文以 didCreateFiles.md 为骨架结合 3.17 规范完整文档、metaModel.json 机器可读模型及相邻的 willCreateFiles 请求定义深入讲解该通知的语义、两端能力协商、参数结构、注册选项与配套的过滤模式并给出完整的服务端实现示例。读完本文你将掌握 LSP 文件操作事件消息的完整收发链路能够在自己实现的语言服务器中正确注册、解析并响应文件创建事件。消息概览客户端到服务器的单向通知workspace/didCreateFiles是一条notification通知即单向消息——客户端发送后不期望服务器返回任何响应。其核心语义在 didCreateFiles.md 中表述为当文件在客户端内部被创建时客户端向服务器发送 did create files 通知。关键约束是from within the client该通知只覆盖由客户端内部发起的创建操作例如用户在资源管理器中新建文件、重命名对话框中选择新建等而不是服务器通过workspace/applyEdit自行发起的创建。客户端自己触发的创建会走另一条路径workspace/willCreateFiles请求 该通知以便在创建前给服务器一个拦截修改的机会。在 metaModel.json 中该消息被建模为{ method: workspace/didCreateFiles, messageDirection: clientToServer, params: { kind: reference, name: CreateFilesParams }, registrationOptions: { kind: reference, name: FileOperationRegistrationOptions }, documentation: The did create files notification is sent from the client to the server when files were created from within the client., since: 3.16.0 }messageDirection: clientToServer在机器可读层面确认了该消息的方向since: 3.16.0表明它最早在 3.16 版本加入规范并持续保留到 3.17该版本新增了stringValue等类型与 inline completion 等能力但文件操作事件模型保持一致。该消息在 3.17 完整规范 中通过{% include_relative workspace/didCreateFiles.md %}嵌入是全量规范文本的一部分。能力协商Client Capability 与 Server Capability与 LSP 中所有消息一致workspace/didCreateFiles的使用需要两端在初始化阶段协商能力避免不兼容的客户端或服务器间出现静默失败。Client Capability客户端能力属性名可选workspace.fileOperations.didCreate属性类型boolean该能力表明客户端支持发送workspace/didCreateFiles通知。只有当客户端在initialize请求的capabilities中声明该字段为true时服务器才可以期望在文件创建后收到该通知。Server Capability服务器能力属性名可选workspace.fileOperations.didCreate属性类型FileOperationRegistrationOptions该能力表明服务器有兴趣接收workspace/didCreateFiles通知并通过FileOperationRegistrationOptions声明自己关注哪些文件通过过滤器与 glob 模式限定。在 metaModel.json 中服务器侧对应能力点的文档注释也直接写明the server is interested in receiving didCreateFiles notifications见 metaModel.json 附近的 capability 定义客户端侧则对应 the client has support for sending didCreateFiles notifications见 metaModel.json 附近。能力协商的典型流程为客户端在initialize请求中声明capabilities.workspace.fileOperations.didCreate: true服务器在initialize响应中声明capabilities.workspace.fileOperations.didCreate为FileOperationRegistrationOptions即{ filters: [...] }此后客户端在内部创建文件后向服务器发送workspace/didCreateFiles通知。消息参数CreateFilesParams 与 FileCreate通知的参数类型为CreateFilesParams其定义完整继承自 3.16 版本且在 willCreateFiles.md同一创建流程的前置请求中同样被复用说明创建流程的两个消息共享同一组参数结构/** * The parameters sent in notifications/requests for user-initiated creation * of files. * * since 3.16.0 */ export interface CreateFilesParams { /** * An array of all files/folders created in this operation. */ files: FileCreate[]; }其中FileCreate描述单个文件/文件夹的创建信息/** * Represents information on a file/folder create. * * since 3.16.0 */ export interface FileCreate { /** * A file:// URI for the location of the file/folder being created. */ uri: string; }metaModel.json 对这两个类型也有完全一致的机器可读建模CreateFilesParams包含一个files数组属性元素类型引用FileCreate见 metaModel.jsonFileCreate仅含一个uri: string属性文档注明 A file:// URI for the location of the file/folder being created见 metaModel.json。一个真实的创建事件参数示例同时创建两个文件{ files: [ { uri: file:///Users/me/project/src/foo.ts }, { uri: file:///Users/me/project/src/bar.ts } ] }需要注意两点files数组中的条目既可以是文件也可以是文件夹文档原文为 all files/folders created in this operationuri必须使用file://scheme 的绝对 URI字符串形式的 URI 不做百分号编码之外的任何转换。注册选项FileOperationRegistrationOptions 与过滤模式服务器在声明workspace.fileOperations.didCreate能力时携带的FileOperationRegistrationOptions决定了哪些文件的创建事件会被投递给服务器。该类型及配套的过滤/模式类型完整定义在 willCreateFiles.md 中因为 didCreate 与 willCreate 共享同一注册选项类型本节完整继承其定义。FileOperationRegistrationOptions/** * The options to register for file operations. * * since 3.16.0 */ interface FileOperationRegistrationOptions { /** * The actual filters. */ filters: FileOperationFilter[]; }FileOperationFilter/** * A filter to describe in which file operation requests or notifications * the server is interested in. * * since 3.16.0 */ export interface FileOperationFilter { /** * A Uri like file or untitled. */ scheme?: string; /** * The actual file operation pattern. */ pattern: FileOperationPattern; }scheme可选用于限定 URI scheme如file、untitled不设置则匹配所有 scheme。FileOperationPattern/** * A pattern to describe in which file operation requests or notifications * the server is interested in. * * since 3.16.0 */ interface FileOperationPattern { /** * The glob pattern to match. Glob patterns can have the following syntax: * - * to match zero or more characters in a path segment * - ? to match on one character in a path segment * - ** to match any number of path segments, including none * - {} to group sub patterns into an OR expression. (e.g. **​/*.{ts,js} * matches all TypeScript and JavaScript files) * - [] to declare a range of characters to match in a path segment * (e.g., example.[0-9] to match on example.0, example.1, …) * - [!...] to negate a range of characters to match in a path segment * (e.g., example.[!0-9] to match on example.a, example.b, but * not example.0) */ glob: string; /** * Whether to match files or folders with this pattern. * * Matches both if undefined. */ matches?: FileOperationPatternKind; /** * Additional options used during matching. */ options?: FileOperationPatternOptions; }FileOperationPatternKind 与 FileOperationPatternOptionsexport namespace FileOperationPatternKind { /** * The pattern matches a file only. */ export const file: file file; /** * The pattern matches a folder only. */ export const folder: folder folder; } export type FileOperationPatternKind file | folder;export interface FileOperationPatternOptions { /** * The pattern should be matched ignoring casing. */ ignoreCase?: boolean; }glob 语法速查表语法含义示例*匹配路径段内零个或多个字符*.ts匹配a.ts、foo.ts?匹配路径段内的单个字符a?.ts匹配ab.ts不匹配abc.ts**匹配任意数量的路径段含零个**/*.ts匹配任意目录层级下的.ts文件{}子模式分组 OR**/*.{ts,js}匹配所有 TypeScript 与 JavaScript 文件[]路径段内字符范围example.[0-9]匹配example.0、example.1…[!...]路径段内字符范围取反example.[!0-9]匹配example.a不匹配example.0一个完整的注册选项示例{ workspace: { fileOperations: { didCreate: { filters: [ { scheme: file, pattern: { glob: **/*.{ts,tsx}, matches: file } }, { pattern: { glob: **/src/**, matches: folder } } ] } } } }该示例表示服务器只关注filescheme 下所有.ts/.tsx文件的创建以及任意src目录层级下文件夹的创建。服务器端实现示例TypeScript结合上述规范一个使用 Node.js/TypeScript 的语言服务器可以这样接收并处理workspace/didCreateFilesimport { Connection, CreateFilesParams, InitializeParams, InitializeResult, } from vscode-languageserver/node; export function registerFileOperationHandlers(connection: Connection) { // 1. 处理通知文件创建后更新服务器内部索引 connection.onDidCreateFiles(async (params: CreateFilesParams) { for (const created of params.files) { const uri created.uri; // file:///... 形式 console.log([file-ops] created: ${uri}); // 在此处增量更新符号索引、依赖图或缓存 await indexer.addFile(uri); } }); } // 2. 在 initialize 响应中声明服务器能力 export function getServerCapabilities(): InitializeResult[capabilities] { return { workspace: { fileOperations: { didCreate: { filters: [ { pattern: { glob: **/*.{ts,tsx}, matches: file, }, }, ], }, }, }, }; } // 3. 客户端侧在实现 LSP 客户端的代码中发送通知 function sendDidCreateFiles(connection: Connection, uris: string[]) { connection.sendNotification(workspace/didCreateFiles, { files: uris.map((uri) ({ uri })), } satisfies CreateFilesParams); }从源码结构看onDidCreateFiles这类助手 API 会在各主流 LSP SDK如 vscode-languageserver-node、lsp 系列 SDK中将消息名与参数类型绑定从而避免手写sendNotification时的魔法字符串拼写错误。与文件操作家族消息的关系workspace/didCreateFiles并不是孤立存在的它是 LSP 文件操作事件file operations家族中的一员。在 workspace 目录下同族消息还包括消息类型参数注册选项触发时机workspace/willCreateFilesRequestCreateFilesParamsFileOperationRegistrationOptions文件创建之前可返回WorkspaceEdit干预workspace/didCreateFilesNotificationCreateFilesParamsFileOperationRegistrationOptions文件创建之后单向通知workspace/willRenameFilesRequestRenameFilesParams同上重命名之前可返回WorkspaceEditworkspace/didRenameFilesNotificationRenameFilesParams同上重命名之后workspace/willDeleteFilesRequestDeleteFilesParams同上删除之前workspace/didDeleteFilesNotificationDeleteFilesParams同上删除之后六个消息构成三对先 will 后 did的完整生命周期全部沿用FileOperationRegistrationOptions作为注册选项。will*请求允许服务器返回WorkspaceEdit在操作真正发生前对工作区做调整注意不能修改将要创建/删除的文件自身内容did*通知则用于操作完成后的状态同步——这正是workspace/didCreateFiles的定位事后通知用于索引更新与状态同步不参与操作前干预。在 3.17 规范的变更记录 中这三对消息被一并列出Add support forworkspace/didCreateFilesnotifications andworkspace/willCreateFilesrequests.Add support forworkspace/didRenameFilesnotifications andworkspace/willRenameFilesrequests.Add support forworkspace/didDeleteFilesnotifications andworkspace/willDeleteFilesrequests.说明该家族自 3.16 起整体加入规范并在 3.17 中保持稳定。版本演进与文档导航在_data/specification-3-17-toc.yml中didCreateFiles与willCreateFiles等文件操作消息被编排在Workspace章节下3.18、3.19 版本的 workspace 目录 与 3.19 对应目录 均保留该通知的独立文档页说明该消息在后续版本中持续有效未发生破坏性变更。小结workspace/didCreateFiles是 LSP 文件操作事件模型中创建之后的客户端到服务器通知触发条件仅限客户端内部发起的文件/文件夹创建操作能力协商客户端需声明workspace.fileOperations.didCreate: true服务器需声明FileOperationRegistrationOptions形式的对应能力参数结构CreateFilesParams.files: FileCreate[]每条FileCreate仅含一个file://URI注册过滤通过FileOperationFilter glob 模式精确限定关注范围支持*、**、{}、[]、[!...]语法与file/folder匹配类型实现要点服务器在收到通知后应及时增量更新索引、依赖图或缓存保持与客户端文件系统的同步。对于任何依赖文件系统状态的语言服务器补全、跳转、诊断、符号索引等正确处理该通知是保证跨文件引用数据新鲜度的关键一环若需要拦截创建过程本身则应配合workspace/willCreateFiles请求willCreateFiles.md一起使用。赞分享开发工具【免费下载链接】language-server-protocolDefines a common protocol for language servers.项目地址https://gitcode.com/gh_mirrors/la/language-server-protocol点击查看免费下载相关推荐Context7 MCP 服务器安装与使用完全指南为 LLM 与 AI 编程助手注入实时更新的库文档Context7 MCP 服务器安装与使用完全指南为 LLM 与 AI 编程助手注入实时更新的库文档 Context7 是一个面向 LLM 与 AI 编程助手开发工具深入解析Language Server Protocol 3.14版本规范深入解析Language Server Protocol 3.14版本规范 协议概述 Language Server ProtocolLSP是微软开发的一套开发工具Language Server Protocol 终极指南深入解析消息格式与通信机制Language Server Protocol 终极指南深入解析消息格式与通信机制 Language Server Protocol语言服务器协议是现代开发工具上一篇GetQzonehistory一键备份QQ空间历史说说永久珍藏你的青春记忆下一篇如何用M9A智能助手解放你的游戏时间重返未来1999自动化终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表