跳到主要内容

文本文档和磁盘文件有什么差别?

结论​

TextDocument 是编辑器里的内存缓冲区,包含未保存的修改。磁盘文件是文件系统上的字节。两边可以不一致。要看用户正在编辑的内容,读文档,不要读磁盘。

展开​

用户改完还没保存时:

  • document.getText()、document.lineAt 是最新草稿。
  • document.isDirty 为 true,document.version 每改一次增加。
  • workspace.fs.readFile(document.uri) 或 Node fs 读到的仍是上次保存的内容。

所以诊断、补全、格式化的输入都应该是 TextDocument。语言服务器也是靠 didOpen / didChange 接收这份内存文本,而不是自己再读一遍盘。

document.uri 也不保证是本地文件。untitled:、vscode-vfs:、git: 都可能出现。对这些 scheme 用磁盘路径会直接失败。

保存相关:

  • document.save() 把缓冲区写回去。
  • onDidSaveTextDocument 之后,磁盘和内存才重新对齐。
  • onDidChangeTextDocument 发生在保存之前,事件里带 contentChanges。

已经打开的文件,用 workspace.textDocuments 或 workspace.openTextDocument(uri) 拿文档。不要为了「读最新」先强制保存。

容易讲错的点​

  • openTextDocument 打开的是文档模型,不一定会弹出标签。要显示给用户用 window.showTextDocument。
  • 大文件不要在每次按键时 getText() 复制整份字符串。能用增量就用 contentChanges。
  • 只监听文件系统 onDidChange 会漏掉未保存编辑,语言功能会看起来「慢一拍」或「完全不更新」。