VS Code语言服务未触发onDidSave/onDidOpenTextDocument事件问题
VS Code LSP 语言服务器:获取已打开文件及监听保存事件解决方案
1. 先解决TextDocuments未填充的核心问题
你的监听事件不触发,大概率是TextDocuments实例没正确绑定到语言服务器连接,或者初始化时没声明正确的文档同步能力。按以下步骤修正:
核心初始化代码示例
import { createConnection, TextDocuments, TextDocument, ProposedFeatures } from 'vscode-languageserver/node'; // 创建带全量特性的服务器连接 const connection = createConnection(ProposedFeatures.all); // 初始化文档管理器,默认管理所有类型文档,后续可通过扩展名过滤 const documents = new TextDocuments(TextDocument); // 关键:在初始化时声明文档同步能力,让VS Code客户端主动同步文档到服务器 connection.onInitialize(() => { return { capabilities: { textDocumentSync: { openClose: true, // 启用文档打开/关闭同步 change: 2, // 采用增量文本同步(可根据需求调整为1全量同步) save: { includeText: false } // 保存事件是否携带完整文本 }, diagnosticProvider: { interFileDependencies: false, workspaceDiagnostics: false } } }; }); // 必须调用这行,把文档管理器绑定到连接,否则无法接收事件 documents.listen(connection);
2. 获取扩展启动时已打开的目标文件
在服务器初始化完成的onInitialized事件中,直接遍历documents.all()并过滤你的小众语言文件即可:
connection.onInitialized(() => { // 替换成你的小众语言扩展名,比如.yourlang const targetDocs = documents.all().filter(doc => doc.uri.endsWith('.yourlang')); // 对每个已打开文件执行检查 targetDocs.forEach(doc => runLint(doc)); });
3. 监听文档保存与打开事件
现在TextDocuments已正常工作,直接绑定对应事件即可:
// 文档保存时触发检查 documents.onDidSave(event => { const doc = event.document; if (doc.uri.endsWith('.yourlang')) { runLint(doc); } }); // 文档打开时立即检查(可选) documents.onDidOpen(event => { const doc = event.document; if (doc.uri.endsWith('.yourlang')) { runLint(doc); } }); // 自定义lint函数,实现你的代码检查逻辑 function runLint(doc: TextDocument) { const diagnostics = []; // 这里编写你的代码检查逻辑,生成Diagnostic对象 // 示例:检查是否包含非法关键字 const lines = doc.getText().split('\n'); lines.forEach((line, lineNum) => { if (line.includes('illegal')) { diagnostics.push({ severity: 1, // 1=Error,2=Warning range: { start: { line: lineNum, character: 0 }, end: { line: lineNum, character: line.length } }, message: '非法关键字', source: 'yourlang-linter' }); } }); // 把诊断结果发送到VS Code客户端 connection.sendDiagnostics({ uri: doc.uri, diagnostics }); }
4. 常见问题排查
- 如果你初始化TextDocuments时指定了筛选器,确保筛选规则匹配你的小众语言文件
- 检查
textDocumentSync的配置是否完整,缺openClose: true会导致客户端不同步已打开的文档 - 确认服务器启动时调用了
documents.listen(connection),这是事件转发的关键
内容的提问来源于stack exchange,提问作者user1024203
相关产品推荐
相关产品推荐

