Language Server Protocol TextDocumentItem 详解:客户端向服务器传输文档的四大字段与语言标识符规范
开发工具【免费下载链接】language-server-protocolDefines a common protocol for language servers.项目地址https://gitcode.com/gh_mirrors/la/language-server-protocol点击查看免费下载TextDocumentItem是 Language Server ProtocolLSP中客户端向服务器传输文本文档内容的核心数据结构承载文档的 URI、语言标识符、版本号与完整文本内容。本文基于本仓库_specifications/lsp/3.19/types/textDocumentItem.md的完整定义结合textDocument/didOpen、notebookDocument同步等协议用法与 metaModel 机器可读定义讲解该类型的字段语义、语言标识符取值规范以及实际传输场景读完即可准确实现 LSP 客户端的文档打开与同步逻辑。TextDocumentItem文本文档传输的最小载体在 LSP 的文本同步机制中客户端负责管理已打开文档的内容所有权而服务器则需要通过一种统一的结构接收文档的完整快照。TextDocumentItem正是为此而生的数据传输对象协议原文对其定位只有一句话An item to transfer a text document from the client to the server.一个用于把文本文档从客户端传输到服务器的数据项但它承载了服务器理解文档所需的全部信息。其 TypeScript 定义如下见 textDocumentItem.mdinterface TextDocumentItem { /** * The text documents URI. */ uri: DocumentUri; /** * The text documents language identifier. */ languageId: string; /** * The version number of this document (it will increase after each * change, including undo/redo). */ version: integer; /** * The content of the opened text document. */ text: string; }该结构一共只有四个必填字段却构成了服务器端文档模型的完整骨架字段类型语义uriDocumentUri文档在客户端中的唯一资源标识服务器据此索引与管理文档languageIdstring文档的语言标识符如python、typescript用于多语言场景下避免重新解析文件扩展名versioninteger文档版本号每次内容变化包括撤销/重做后递增textstring文档被打开时的完整文本内容uri文档的唯一身份标识uri的类型是DocumentUri。在本仓库的 uri.md 中有关于 URI 的专门说明文档的 URI 在 LSP 中通常使用file:之类的 scheme服务器需要把它当作文档的全局唯一标识来缓存状态。值得注意的是与TextDocumentItem不同某些场景如 notebook 单元格文档中协议刻意让 URI 保持不透明——服务器不应依赖其 scheme 或路径格式这一点在 notebook 同步章节中会进一步展开。version版本号驱动的增量同步基础version字段是 LSP 文档状态机同步的关键。协议明确规定版本号在每次变更后递增包括撤销undo与重做redo但版本号并不要求连续见 versionedTextDocumentIdentifier.md 中 The number doesnt need to be consecutive 的说明。TextDocumentItem中的version与VersionedTextDocumentIdentifier中的version语义一致区别仅在于前者在文档打开时随完整内容一并送达服务器而后者用于textDocument/didChange通知中标记变更之后的文档版本。在 didChange.md 给出的同步示例中可以看到这套版本机制的实际协作方式文档版本用户输入客户端行为请求5文档变更一将文档v5同步给服务器textDocument/didChange5-基于文档v5向服务器发起请求textDocument/completion6文档变更二将文档v6同步给服务器textDocument/didChange即客户端在发起请求如补全、签名帮助之前必须先把文档的最新版本同步给服务器而TextDocumentItem正是文档打开这个同步起点的数据载体。languageId语言标识符的作用与推荐取值表languageId字段的协议原意是当服务器同时处理多种语言时用它来识别文档属于哪种语言从而避免对文件扩展名进行二次推断。也就是说语言判断的第一依据是客户端显式声明的languageId而不是文件后缀。协议建议当文档属于下列编程语言之一时客户端应使用下表推荐的标识符该表为协议正式规范的一部分完整继承自 textDocumentItem.md语言标识符ABAPabapWindows BatbatBibTeXbibtexClojureclojureCoffeescriptcoffeescriptCcCcppC#csharpCSScssDdsince 3.18.0Delphipascalsince 3.18.0DiffdiffDartdartDockerfiledockerfileElixirelixirErlangerlangF#fsharpGitgit-commit和git-rebaseGogoGroovygroovyHandlebarshandlebarsHaskellhaskellHTMLhtmlIniiniJavajavaJavaScriptjavascriptJavaScript ReactjavascriptreactJSONjsonLaTeXlatexLesslessLualuaMakefilemakefileMarkdownmarkdownObjective-Cobjective-cObjective-Cobjective-cppPascalpascalsince 3.18.0PerlperlPerl 6perl6PHPphpPlaintextplaintextPowershellpowershellPugjadePythonpythonRrRazor (cshtml)razorRubyrubyRustrustSCSSscss花括号语法、sass缩进语法ScalascalaShaderLabshaderlabShell Script (Bash)shellscriptSQLsqlSwiftswiftTypeScripttypescriptTypeScript ReacttypescriptreactTeXtexText (plain)plaintextVisual BasicvbXMLxmlXSLxslYAMLyaml几点值得注意的细节一语言多标识符SCSS 区分了scss花括号语法与sass缩进语法Git 相关文档则使用git-commit和git-rebase两个标识符。同标识符复用Delphi 与 Pascal 都使用pascalPlaintext 与 Text (plain) 都使用plaintext。版本演进d、pascal三个条目是 3.18.0 版本才补充进规范表的表中以since 3.18.0标注说明语言标识符表会随协议版本持续扩充。该表是建议而非强制协议原文用 it is recommended that clients use those ids 表述客户端可以按自身需求使用表外的自定义标识符但服务器在实现多语言支持时应以该表为基准。TextDocumentItem 的两个关键使用场景场景一textDocument/didOpen 通知——文档打开即快照TextDocumentItem最典型的使用场景是textDocument/didOpen通知。该通知由客户端发给服务器用于宣告新打开的文本文档其参数结构如下见 didOpen.mdinterface DidOpenTextDocumentParams { /** * The document that was opened. */ textDocument: TextDocumentItem; }协议对 didOpen 语义有几点严格约定理解这些约定有助于正确构造TextDocumentItem内容所有权归客户端文档一旦 open其内容就由客户端管理服务器不得再尝试用文档 URI 去磁盘读取内容。因此textDocument/didOpen中必须携带完整的text快照这是服务器获得文档内容的唯一途径。open/close 必须配对同一文档在未发送对应 close 通知前不允许重复发送 open同一时刻每个文档的 open 计数最多为 1。语言变更需重开如果文档的语言标识符发生变化且服务器支持新语言客户端必须先发送textDocument/didClose再以新languageId重新发送textDocument/didOpen。这正是languageId字段在协议流程中的具体作用点。open 不等于编辑器展示open 仅表示文档内容由客户端管理并不要求其内容一定显示在编辑器中。在 2.0 版本之后didChange 参数中也引入了规范的版本号见 didChange.mdTextDocumentItem.version与后续VersionedTextDocumentIdentifier.version构成了打开即定版本、变更则递增的连续同步链路。场景二Notebook 单元格同步——TextDocumentItem 复用自 3.17.0 起LSP 增加了 notebook 文档同步能力TextDocumentItem被复用于同步 notebook 单元格的文本内容。在 notebook.md 中可以看到DidOpenNotebookDocumentParams通过cellTextDocuments: TextDocumentItem[]数组一次性把所有已打开单元格的文本文档快照发给服务器notebook 单元格的文本文档 URI 是不透明的由客户端自行生成服务器不应依赖其格式——因此TextDocumentItem.uri在单元格场景下只作为唯一标识不承载路径语义单元格文本文档被视为普通文本文档始终以增量同步incremental sync方式与服务器保持同步。这体现了TextDocumentItem作为协议基础类型的通用性无论普通文档还是 notebook 单元格客户端向服务器交底文档内容时使用的都是同一结构。从 metaModel 验证结构定义的机器可读形态本仓库在_specifications/lsp/3.19/metaModel/目录下提供了协议的机器可读元模型其中 metaModel.json 对TextDocumentItem做了与文档一致的 JSON 描述{ name: TextDocumentItem, properties: [ { name: uri, type: { kind: base, name: DocumentUri }, documentation: The text documents uri. }, { name: languageId, type: { kind: reference, name: LanguageKind }, documentation: The text documents language identifier. }, { name: version, type: { kind: base, name: integer }, documentation: The version number of this document (it will increase after each change, including undo/redo). }, { name: text, type: { kind: base, name: string }, documentation: The content of the opened text document. } ], documentation: An item to transfer a text document from the client to the server. }从该元模型可以看出languageId在元模型中被引用为LanguageKind类型对应文档中的语言标识符表uri被定义为DocumentUri基础类型version为integertext为string四个字段均为必填无optional标记。对应的 TypeScript 类型定义见 metaModel.ts其中声明了DocumentUri、integer、string等基础类型BaseTypes可作为实现代码生成器或协议校验器的直接依据。实现要点与常见误区结合以上协议细节客户端与服务器在实现TextDocumentItem时应注意以下几点必填字段不可省略uri、languageId、version、text四字段全部必填缺少任一字段都会导致服务器无法建立完整的文档快照。首次打开必须携带全量文本didOpen是一次性的全量传输服务器不会也不会去磁盘读取文档所以text必须是打开时刻的完整内容。languageId 优先于扩展名服务器做语言分派时应优先信任languageId不要为每个请求重新根据 URI 后缀推断语言多语言场景下这正是该字段的设计初衷。版本号只增不减version在每次变更含撤销/重做后递增不需要连续但必须单调递增服务器可用它做请求与内容快照的匹配。Notebook 单元格 URI 保持不透明当TextDocumentItem用于 notebook 单元格时不要对 URI 的 scheme 或路径做任何假设。相关文档导航类型定义原文textDocumentItem.md本文核心依据3.18 版本定义见 3.18 版本使用场景didOpen.md、didChange.md、notebook.md关联类型versionedTextDocumentIdentifier.md、uri.md机器可读定义metaModel.json、metaModel.ts赞分享开发工具【免费下载链接】language-server-protocolDefines a common protocol for language servers.项目地址https://gitcode.com/gh_mirrors/la/language-server-protocol点击查看免费下载相关推荐Language Server Protocol 3.17 TextDocumentItem 详解客户端到服务器的文本文档传输载体Language Server Protocol 3.17 TextDocumentItem 详解客户端到服务器的文本文档传输载体 TextDocumentI开发工具Language Server Protocol 3.18 window/logMessage 通知详解从服务器向客户端传递日志消息Language Server Protocol 3.18 window/logMessage 通知详解从服务器向客户端传递日志消息 window/logMe开发工具language-server-protocol 3.17 规范精读TextDocumentIdentifier 与文本文档 URI 标识机制language server protocol 3.17 规范精读TextDocumentIdentifier 与文本文档 URI 标识机制 导读 Text开发工具上一篇Elsa.Diagnostics.StructuredLogs 模块重构与结构化日志能力完整落地指南tasks.md 全解析下一篇V8 回归测试实战指南从零手写高质量 mjsunit 复现程序创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考