文本文档和磁盘文件有什么差别?
结论
TextDocument 是编辑器里的内存缓冲区,包含未保存的修改。磁盘文件是文件系统上的字节。两边可以不一致。要看用户正在编辑的内容,读文档,不要读磁盘。
展开
用户改完还没保存时:
document.getText()、document.lineAt是最新草稿。document.isDirty为 true,document.version每改一次增加。workspace.fs.readFile(document.uri)或 Nodefs读到的仍是上次保存的内容。
所以诊断、补全、格式化的输入都应该是 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会漏掉未保存编辑,语言功能会看起来「慢一拍」或「完全不更新」。