开发VS Code扩展:如何检测文件夹点击以实现子文件夹自动折叠?
检测VS Code资源管理器文件夹点击的可行方案
下面是几种基于VS Code官方API的可靠实现思路,避免依赖不稳定的DOM操作:
1. 监听活动元素变化(最简便)
利用window.onDidChangeActiveElement事件捕获资源管理器中选中的元素,判断是否为文件夹后执行折叠逻辑:
import * as vscode from 'vscode'; export function activate(context: vscode.ExtensionContext) { context.subscriptions.push( vscode.window.onDidChangeActiveElement(async (event) => { // 过滤出资源管理器中的文件夹节点 if (event.element instanceof vscode.TreeItem && event.element.resourceUri) { const stat = await vscode.workspace.fs.stat(event.element.resourceUri); if (stat.type === vscode.FileType.Directory) { // 执行折叠子文件夹的内置命令 await vscode.commands.executeCommand( 'workbench.files.action.collapseExplorerFolders', event.element.resourceUri ); } } }) ); }
workbench.files.action.collapseExplorerFolders是VS Code内置命令,可直接针对指定URI的文件夹折叠其子项。
2. 自定义树数据提供者(更灵活)
如果需要区分左键/右键点击等精细控制,可以自定义树数据提供者替换默认资源管理器视图,直接绑定点击事件:
import * as vscode from 'vscode'; class FolderTreeProvider implements vscode.TreeDataProvider<vscode.Uri> { getTreeItem(element: vscode.Uri): vscode.TreeItem { const treeItem = new vscode.TreeItem( element, vscode.TreeItemCollapsibleState.Collapsed ); // 绑定点击触发的自定义命令 treeItem.command = { command: 'extension.folderClicked', title: 'Handle Folder Click', arguments: [element] }; return treeItem; } async getChildren(element?: vscode.Uri): Promise<vscode.Uri[]> { if (!element) { // 返回工作区根文件夹 return vscode.workspace.workspaceFolders?.map(f => f.uri) || []; } // 返回当前文件夹的子文件夹 const entries = await vscode.workspace.fs.readDirectory(element); return entries .filter(([_, type]) => type === vscode.FileType.Directory) .map(([name]) => vscode.Uri.joinPath(element, name)); } // 实现树视图更新所需的事件发射器 private _onDidChangeTreeData = new vscode.EventEmitter<vscode.Uri | undefined>(); readonly onDidChangeTreeData = this._onDidChangeTreeData.event; } export function activate(context: vscode.ExtensionContext) { const provider = new FolderTreeProvider(); // 替换默认资源管理器视图 vscode.window.registerTreeDataProvider('explorer', provider); // 注册处理点击的命令 context.subscriptions.push( vscode.commands.registerCommand('extension.folderClicked', async (uri: vscode.Uri) => { // 执行折叠逻辑 await vscode.commands.executeCommand( 'workbench.files.action.collapseExplorerFolders', uri ); }) ); }
3. 监听选中项变化(兼容旧版本)
部分旧版VS Code可能不支持onDidChangeActiveElement,可以改用window.onDidChangeTextEditorSelection结合资源管理器选中状态判断,但这种方法需要额外校验选中项类型,不如前两种直接。
内容的提问来源于stack exchange,提问作者Mahmoud Ayyash
相关产品推荐
相关产品推荐

