You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Visual Studio Code语言服务器:如何验证工作区所有文件

解决LSP-Sample仅验证已打开/修改文件的问题

我刚梳理了这个场景——你提到的lsp-sample默认只处理已打开或修改的文件,核心原因是它依赖的documents.onDidChangeContent事件,只会对加载到VS Code编辑器内存的文件触发。要实现全工作区文件的验证,咱们可以从三个方向调整逻辑:

1. 服务器初始化时扫描所有目标文件

在服务器的initialize回调里,添加工作区全量文件扫描逻辑。假设你的服务针对.myext后缀的文件,代码可以这么写:

connection.onInitialize(async (params) => {
    const capabilities = params.capabilities;

    // 保留原有初始化逻辑...

    // 扫描工作区所有目标文件
    if (params.workspaceFolders) {
        for (const folder of params.workspaceFolders) {
            const uri = folder.uri;
            // 使用LSP的workspace API查找匹配文件
            const files = await connection.workspace.findFiles(`${uri}/**/*.myext`);
            for (const file of files) {
                const docUri = file.toString();
                const document = await documents.get(docUri);
                if (document) {
                    validateTextDocument(document);
                }
            }
        }
    }

    return {
        capabilities: {
            // 确保声明支持工作区相关能力
            workspace: {
                fileOperations: {
                    didCreate: true,
                    didDelete: true,
                    didRename: true
                }
            },
            // 其他原有能力配置...
        }
    };
});

2. 监听工作区文件的新增/删除/重命名事件

除了初始化扫描,还要实时响应工作区的文件变更,确保新添加的文件也能被验证:

// 处理文件创建事件
connection.workspace.onDidCreateFiles(async (event) => {
    for (const file of event.files) {
        if (file.uri.endsWith('.myext')) {
            const document = await documents.get(file.uri);
            if (document) {
                validateTextDocument(document);
            }
        }
    }
});

// 处理文件删除事件(清理旧的诊断结果)
connection.workspace.onDidDeleteFiles((event) => {
    for (const file of event.files) {
        connection.sendDiagnostics({ uri: file.uri, diagnostics: [] });
    }
});

// 处理文件重命名事件(迁移诊断结果)
connection.workspace.onDidRenameFiles(async (event) => {
    for (const rename of event.files) {
        // 清除旧文件的诊断
        connection.sendDiagnostics({ uri: rename.oldUri, diagnostics: [] });
        // 验证新文件
        const document = await documents.get(rename.newUri);
        if (document) {
            validateTextDocument(document);
        }
    }
});

3. 保留原有实时修改验证逻辑

原有的documents.onDidChangeContent回调继续保留,用于处理已打开文件的实时修改验证:

// 处理已打开/修改文件的实时验证
documents.onDidChangeContent((change) => {
    validateTextDocument(change.document);
});

关键注意点

  • 必须在服务器能力声明里开启workspace.fileOperations,否则VS Code不会推送文件变更事件。
  • 大量文件扫描时建议做异步分批处理,避免阻塞服务器初始化流程。
  • 注意URI格式的统一处理,确保documents.get()能正确识别文件路径。

调整后,你的语言服务器就能在启动时自动验证工作区所有目标文件,同时实时响应文件的新增、修改和删除操作了。

内容的提问来源于stack exchange,提问作者Ricardo Ferreira da Silva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:34:54