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

Visual Studio Code扩展开发:自定义搜索结果展示及搜索触发命令实现方案咨询

How to Trigger a Custom Command on VS Code Search and Display Results by Module

I've worked on similar VS Code extension scenarios, so here's a step-by-step solution to achieve your goal of capturing search results, grouping them by user-defined modules (folders), and displaying them in a custom view:

Core Approach

Instead of relying on menu contribution points (which only add commands to UI menus), we'll use VS Code's search API and event listeners to:

  1. Catch when a search completes and fetch the results
  2. Pass those results to a custom command for grouping
  3. Render the grouped results in a dedicated custom view

Step 1: Register Your Custom Command & Listen for Search Events

First, in your extension's entry file (extension.ts), register a command to process search results, and set up a listener for when search results change:

import * as vscode from 'vscode';

let treeDataProvider: ModuleResultTreeDataProvider;

export function activate(context: vscode.ExtensionContext) {
    // Initialize the tree view provider for our custom results
    treeDataProvider = new ModuleResultTreeDataProvider();
    const treeView = vscode.window.createTreeView('moduleSearchResults', {
        treeDataProvider,
        title: 'Module-Based Search Results'
    });

    // Register command to process and display grouped results
    const processResultsCmd = vscode.commands.registerCommand('moduleSearch.processResults', (searchResults) => {
        const grouped = groupResultsByModule(searchResults);
        treeDataProvider.updateResults(grouped);
    });

    // Listen for search result updates
    const searchListener = vscode.workspace.onDidChangeSearchResults(async (event) => {
        // Fetch the full search results using the query and options from the event
        const results = await vscode.workspace.search(event.query, event.options);
        // Execute our custom command with the results
        await vscode.commands.executeCommand('moduleSearch.processResults', results);
    });

    context.subscriptions.push(processResultsCmd, searchListener, treeView);
}

// Helper: Group results by parent folder (module)
function groupResultsByModule(results: vscode.SearchResult[]): Record<string, number> {
    const groups: Record<string, number> = {};

    results.forEach(result => {
        // Get the relative path of the file's parent folder
        const relativePath = vscode.workspace.asRelativePath(result.uri);
        const modulePath = relativePath.split('/').slice(0, -1).join('/') || 'src/';
        const normalizedModule = modulePath.endsWith('/') ? modulePath : `${modulePath}/`;
        
        groups[normalizedModule] = (groups[normalizedModule] || 0) + 1;
    });

    return groups;
}

Step 2: Implement the Custom Tree View

To display the grouped results, create a Tree Data Provider that will populate your custom view:

// Tree item class for module results
class ModuleResultItem extends vscode.TreeItem {
    constructor(public readonly modulePath: string, public readonly count: number) {
        super(modulePath);
        this.description = `${count}个结果`;
        this.collapsibleState = vscode.TreeItemCollapsibleState.None;
    }
}

// Tree data provider implementation
class ModuleResultTreeDataProvider implements vscode.TreeDataProvider<ModuleResultItem> {
    private _onDidChangeTreeData = new vscode.EventEmitter<ModuleResultItem | undefined>();
    readonly onDidChangeTreeData = this._onDidChangeTreeData.event;

    private groupedResults: Record<string, number> = {};

    updateResults(results: Record<string, number>) {
        this.groupedResults = results;
        this._onDidChangeTreeData.fire();
    }

    getTreeItem(element: ModuleResultItem): vscode.TreeItem {
        return element;
    }

    getChildren(element?: ModuleResultItem): Thenable<ModuleResultItem[]> {
        if (!element) {
            // Convert grouped results into tree items
            return Promise.resolve(
                Object.entries(this.groupedResults).map(([module, count]) => 
                    new ModuleResultItem(module, count)
                )
            );
        }
        // No child items for modules
        return Promise.resolve([]);
    }
}

Step 3: Update package.json for Contributions

Add the necessary entries to your package.json to register the command and custom view:

{
    "contributes": {
        "views": {
            "explorer": [
                {
                    "id": "moduleSearchResults",
                    "name": "Module Search Results"
                }
            ]
        },
        "commands": [
            {
                "command": "moduleSearch.processResults",
                "title": "Process Search Results by Module"
            }
        ]
    }
}

How It Works

  • Whenever a user runs a search (via the search panel, keyboard shortcut, etc.), the onDidChangeSearchResults event fires.
  • We fetch the full search results using the query and options from the event.
  • Our custom command processes these results, grouping them by parent folder (your "modules").
  • The Tree View automatically updates to show the grouped results, formatted exactly as you described:
    4个结果,分布在2个模块中
    src/(2个结果)
    folder2/(2个结果)
    

Notes

  • If you want to let users manually trigger the command (e.g., from a menu), you can add it to the search view's context menu using the search/results/context menu location in your package.json contributes.
  • You can customize the Tree View further (add icons, enable clicking to navigate to files, etc.) by extending the ModuleResultItem class.

内容的提问来源于stack exchange,提问作者Spook

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 19:19:08