在VS Code插件开发中调用编辑器的内置搜索功能,并且获取到它的搜索结果

在VS Code插件开发中调用编辑器的内置搜索功能,并且获取到它的搜索结果,这个需求很明确,也是插件开发中比较实用的场景。

实现思路

VS Code的API并没有直接提供"获取搜索结果"的现成方法,但我们可以通过两种方式实现:

  1. 调用VS Code的搜索命令并监听结果 (推荐):通过vscode.commands.executeCommand调用内置搜索命令,结合vscode.window.onDidChangeActiveTextEditor或自定义面板来捕获结果。
  2. 手动实现搜索逻辑 :使用VS Code的vscode.workspace.findFiles和文本匹配逻辑,完全自定义搜索过程,这种方式能完全掌控搜索结果。

下面提供完整的可运行插件代码示例(基于第二种方式,更稳定且可控):

完整插件代码

1. package.json(插件配置)
json 复制代码
{
  "name": "search-result-demo",
  "displayName": "Search Result Demo",
  "version": "0.0.1",
  "engines": {
    "vscode": "^1.80.0"
  },
  "categories": [
    "Other"
  ],
  "activationEvents": [
    "onCommand:search-result-demo.searchFiles"
  ],
  "main": "./extension.js",
  "contributes": {
    "commands": [
      {
        "command": "search-result-demo.searchFiles",
        "title": "Search Files and Get Results"
      }
    ]
  }
}
2. extension.js(核心逻辑)
javascript 复制代码
const vscode = require('vscode');

/**
 * @param {vscode.ExtensionContext} context
 */
function activate(context) {
    // 注册命令:触发搜索并获取结果
    let disposable = vscode.commands.registerCommand('search-result-demo.searchFiles', async function () {
        try {
            // 1. 弹出输入框让用户输入搜索关键词
            const searchText = await vscode.window.showInputBox({
                prompt: '请输入要搜索的关键词',
                placeHolder: '例如:console.log',
                validateInput: (value) => {
                    return value.trim() ? null : '关键词不能为空';
                }
            });

            if (!searchText) { return; } // 用户取消输入

            // 2. 定义搜索范围(可自定义,这里是工作区所有文件)
            const searchPattern = new vscode.RelativePattern(vscode.workspace.workspaceFolders[0], '**/*');
            
            // 3. 第一步:查找符合条件的文件(先过滤文件,再匹配内容)
            const files = await vscode.workspace.findFiles(
                searchPattern, 
                '**/node_modules/**', // 排除node_modules
                100 // 最多返回100个文件
            );

            if (files.length === 0) {
                vscode.window.showInformationMessage('未找到任何文件');
                return;
            }

            // 4. 第二步:读取文件内容并匹配关键词
            const searchResults = [];
            for (const file of files) {
                try {
                    // 读取文件内容(UTF-8编码)
                    const document = await vscode.workspace.openTextDocument(file);
                    const text = document.getText();
                    
                    // 匹配关键词(支持正则)
                    const regex = new RegExp(searchText, 'gi');
                    let match;
                    const lines = text.split('\n');
                    
                    // 遍历所有匹配项,记录行号和内容
                    while ((match = regex.exec(text)) !== null) {
                        // 计算匹配位置所在的行号
                        const charIndex = match.index;
                        let lineNumber = 0;
                        let charCount = 0;
                        
                        for (const line of lines) {
                            charCount += line.length + 1; // +1 是换行符
                            if (charCount > charIndex) {
                                break;
                            }
                            lineNumber++;
                        }

                        // 收集结果
                        searchResults.push({
                            filePath: file.fsPath,
                            lineNumber: lineNumber + 1, // VS Code行号从1开始
                            lineContent: lines[lineNumber]?.trim() || '',
                            matchText: match[0]
                        });
                    }
                } catch (error) {
                    console.error(`读取文件失败: ${file.fsPath}`, error);
                }
            }

            // 5. 处理并展示搜索结果
            if (searchResults.length === 0) {
                vscode.window.showInformationMessage(`未找到包含"${searchText}"的内容`);
                return;
            }

            // 打印结果到控制台(你可以根据需求处理这些结果)
            console.log('搜索结果:', JSON.stringify(searchResults, null, 2));
            
            // 向用户展示结果数量
            vscode.window.showInformationMessage(
                `找到 ${searchResults.length} 个匹配项(详见开发者控制台)`
            );

            // 可选:在VS Code中展示结果列表
            const items = searchResults.map(result => ({
                label: `${result.filePath} (第${result.lineNumber}行)`,
                description: result.matchText,
                detail: result.lineContent,
                data: result
            }));

            // 展示结果选择面板
            const selected = await vscode.window.showQuickPick(items, {
                matchOnDescription: true,
                matchOnDetail: true,
                placeHolder: `共${items.length}个匹配项,选择查看`
            });

            // 打开选中的文件并定位到对应行
            if (selected) {
                const uri = vscode.Uri.file(selected.data.filePath);
                const document = await vscode.workspace.openTextDocument(uri);
                await vscode.window.showTextDocument(document);
                
                // 定位到匹配行
                const position = new vscode.Position(selected.data.lineNumber - 1, 0);
                vscode.window.activeTextEditor.selection = new vscode.Selection(position, position);
                vscode.window.activeTextEditor.revealRange(
                    new vscode.Range(position, position),
                    vscode.TextEditorRevealType.InCenter
                );
            }

        } catch (error) {
            console.error('搜索失败:', error);
            vscode.window.showErrorMessage(`搜索出错:${error.message}`);
        }
    });

    context.subscriptions.push(disposable);
}

function deactivate() {}

module.exports = {
    activate,
    deactivate
};

代码关键部分解释

  1. 输入处理 :通过vscode.window.showInputBox获取用户输入的搜索关键词,包含输入验证。
  2. 文件查找 :使用vscode.workspace.findFiles查找工作区内的文件,支持排除指定目录(如node_modules)。
  3. 内容匹配
    • 读取文件内容并按行分割
    • 使用正则表达式匹配关键词
    • 计算匹配位置对应的行号(VS Code行号从1开始)
  4. 结果处理
    • 收集所有匹配结果(文件路径、行号、行内容、匹配文本)
    • 打印到控制台供后续处理
    • 展示交互式列表,支持点击跳转到对应位置

运行插件的前置条件

  1. 确保已安装Node.js(v14+)和VS Code

  2. 安装VS Code插件开发工具:

    bash 复制代码
    npm install -g yo generator-code
  3. 创建插件项目:yo code → 选择New Extension (JavaScript)

  4. 替换生成的package.jsonextension.js为上面的代码

  5. 按F5启动扩展开发宿主窗口,在新窗口中按Ctrl+Shift+P,执行命令Search Files and Get Results

总结

  1. 核心方法 :通过vscode.workspace.findFiles查找文件,结合文件内容读取和正则匹配,实现可控的搜索并获取结果。
  2. 结果格式:搜索结果包含文件路径、行号、匹配行内容和匹配文本,可直接用于后续处理(如展示、过滤、导出等)。
  3. 扩展方向:你可以基于这个基础逻辑,添加正则搜索、大小写敏感、文件类型过滤等功能,或把结果展示在自定义Webview面板中。

这种方式相比直接调用内置搜索命令,优势在于完全掌控搜索过程和结果格式,更适合插件开发中的定制化需求。

相关推荐
1024小神1 天前
Vscode/Cursor中的Prettier插件格式化降级操作
ide·vscode·编辑器
ONLYOFFICE1 天前
树莓派办公套件:ONLYOFFICE 桌面编辑器安装教程
编辑器·github·onlyoffice
网络安全研发随想1 天前
AI Code编辑器到底是怎么做出来的?
人工智能·编辑器
傅科摆 _ py1 天前
Vim 常用命令简要总结
linux·编辑器·vim
山峰哥2 天前
数据库工程核心:SQL调优让查询效率飙升的实战密码
网络·汇编·数据库·sql·编辑器
好好学习啊天天向上2 天前
VSCODE, mermaid subgraph 示例
ide·vscode·编辑器
好好学习啊天天向上2 天前
VSCODE, mermaid 示例
ide·vscode·编辑器
zz_Lambda2 天前
TeXstudio 等 (La)TeX 编辑器在没有发行版时不能运行 (La)TeX 命令
编辑器
向上的车轮2 天前
VS Code在AI编辑器关键问题上处理如何?
人工智能·编辑器