Skip to content

工作区 API

工作区 API 提供了管理和操作 VS Code 工作区的功能,包括文件夹管理、工作区配置、文件系统操作等。

概述

工作区是 VS Code 中的核心概念,代表用户当前正在处理的项目或文件夹集合。工作区 API 允许扩展程序:

  • 访问和修改工作区文件夹
  • 监听工作区变化事件
  • 管理工作区配置
  • 执行文件系统操作
  • 处理工作区状态

主要接口

WorkspaceFolder

typescript
interface WorkspaceFolder {
    /**
     * 工作区文件夹的 URI
     */
    readonly uri: Uri;

    /**
     * 工作区文件夹的名称
     */
    readonly name: string;

    /**
     * 工作区文件夹的索引
     */
    readonly index: number;
}

WorkspaceConfiguration

typescript
interface WorkspaceConfiguration {
    /**
     * 获取配置值
     */
    get<T>(section: string): T | undefined;
    get<T>(section: string, defaultValue: T): T;

    /**
     * 检查配置是否存在
     */
    has(section: string): boolean;

    /**
     * 检查配置的详细信息
     */
    inspect<T>(section: string): {
        key: string;
        defaultValue?: T;
        globalValue?: T;
        workspaceValue?: T;
        workspaceFolderValue?: T;
    } | undefined;

    /**
     * 更新配置
     */
    update(section: string, value: any, configurationTarget?: ConfigurationTarget): Thenable<void>;
}

工作区管理

获取工作区文件夹

typescript
import * as vscode from 'vscode';

// 获取所有工作区文件夹
const workspaceFolders = vscode.workspace.workspaceFolders;

if (workspaceFolders) {
    workspaceFolders.forEach(folder => {
        console.log(`文件夹: ${folder.name}, 路径: ${folder.uri.fsPath}`);
    });
}

// 获取特定文件的工作区文件夹
const document = vscode.window.activeTextEditor?.document;
if (document) {
    const workspaceFolder = vscode.workspace.getWorkspaceFolder(document.uri);
    if (workspaceFolder) {
        console.log(`当前文件属于工作区: ${workspaceFolder.name}`);
    }
}

监听工作区变化

typescript
// 监听工作区文件夹变化
vscode.workspace.onDidChangeWorkspaceFolders(event => {
    event.added.forEach(folder => {
        console.log(`添加了工作区文件夹: ${folder.name}`);
    });

    event.removed.forEach(folder => {
        console.log(`移除了工作区文件夹: ${folder.name}`);
    });
});

文件系统操作

文件监听

typescript
// 创建文件系统监听器
const watcher = vscode.workspace.createFileSystemWatcher('**/*.{js,ts}');

// 监听文件创建
watcher.onDidCreate(uri => {
    console.log(`文件已创建: ${uri.fsPath}`);
});

// 监听文件修改
watcher.onDidChange(uri => {
    console.log(`文件已修改: ${uri.fsPath}`);
});

// 监听文件删除
watcher.onDidDelete(uri => {
    console.log(`文件已删除: ${uri.fsPath}`);
});

// 清理监听器
context.subscriptions.push(watcher);

文件搜索

typescript
// 在工作区中搜索文件
const files = await vscode.workspace.findFiles(
    '**/*.ts',           // 包含模式
    '**/node_modules/**', // 排除模式
    100                  // 最大结果数
);

files.forEach(file => {
    console.log(`找到文件: ${file.fsPath}`);
});

// 搜索文本内容
const textSearchOptions: vscode.TextSearchOptions = {
    includes: ['**/*.ts'],
    excludes: ['**/node_modules/**'],
    maxResults: 50,
    previewOptions: {
        matchLines: 1,
        charsPerLine: 100
    }
};

await vscode.workspace.findTextInFiles(
    { pattern: 'function' },
    textSearchOptions,
    (result) => {
        console.log(`在 ${result.uri.fsPath} 中找到匹配`);
    }
);

配置管理

读取配置

typescript
// 获取工作区配置
const config = vscode.workspace.getConfiguration();

// 获取特定配置节
const editorConfig = vscode.workspace.getConfiguration('editor');
const fontSize = editorConfig.get<number>('fontSize', 14);

// 获取特定文件的配置
const document = vscode.window.activeTextEditor?.document;
if (document) {
    const fileConfig = vscode.workspace.getConfiguration('editor', document.uri);
    const tabSize = fileConfig.get<number>('tabSize', 4);
}

更新配置

typescript
// 更新全局配置
const config = vscode.workspace.getConfiguration('editor');
await config.update('fontSize', 16, vscode.ConfigurationTarget.Global);

// 更新工作区配置
await config.update('tabSize', 2, vscode.ConfigurationTarget.Workspace);

// 更新工作区文件夹配置
const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
if (workspaceFolder) {
    await config.update('insertSpaces', true, vscode.ConfigurationTarget.WorkspaceFolder);
}

实用示例

工作区状态管理器

typescript
class WorkspaceManager {
    private disposables: vscode.Disposable[] = [];

    constructor() {
        this.setupEventListeners();
    }

    private setupEventListeners() {
        // 监听工作区变化
        this.disposables.push(
            vscode.workspace.onDidChangeWorkspaceFolders(this.onWorkspaceFoldersChanged.bind(this))
        );

        // 监听配置变化
        this.disposables.push(
            vscode.workspace.onDidChangeConfiguration(this.onConfigurationChanged.bind(this))
        );
    }

    private onWorkspaceFoldersChanged(event: vscode.WorkspaceFoldersChangeEvent) {
        // 处理工作区文件夹变化
        event.added.forEach(folder => {
            this.initializeWorkspaceFolder(folder);
        });

        event.removed.forEach(folder => {
            this.cleanupWorkspaceFolder(folder);
        });
    }

    private onConfigurationChanged(event: vscode.ConfigurationChangeEvent) {
        if (event.affectsConfiguration('myExtension')) {
            this.reloadConfiguration();
        }
    }

    private initializeWorkspaceFolder(folder: vscode.WorkspaceFolder) {
        console.log(`初始化工作区文件夹: ${folder.name}`);
        // 执行初始化逻辑
    }

    private cleanupWorkspaceFolder(folder: vscode.WorkspaceFolder) {
        console.log(`清理工作区文件夹: ${folder.name}`);
        // 执行清理逻辑
    }

    private reloadConfiguration() {
        const config = vscode.workspace.getConfiguration('myExtension');
        // 重新加载配置
    }

    dispose() {
        this.disposables.forEach(d => d.dispose());
    }
}

项目文件分析器

typescript
class ProjectAnalyzer {
    async analyzeProject(): Promise<ProjectInfo> {
        const workspaceFolders = vscode.workspace.workspaceFolders;
        if (!workspaceFolders) {
            throw new Error('没有打开的工作区');
        }

        const projectInfo: ProjectInfo = {
            folders: [],
            totalFiles: 0,
            fileTypes: new Map()
        };

        for (const folder of workspaceFolders) {
            const folderInfo = await this.analyzeFolderInfo(folder);
            projectInfo.folders.push(folderInfo);
            projectInfo.totalFiles += folderInfo.fileCount;

            // 合并文件类型统计
            folderInfo.fileTypes.forEach((count, type) => {
                const currentCount = projectInfo.fileTypes.get(type) || 0;
                projectInfo.fileTypes.set(type, currentCount + count);
            });
        }

        return projectInfo;
    }

    private async analyzeFolderInfo(folder: vscode.WorkspaceFolder): Promise<FolderInfo> {
        const files = await vscode.workspace.findFiles(
            new vscode.RelativePattern(folder, '**/*'),
            new vscode.RelativePattern(folder, '**/node_modules/**')
        );

        const fileTypes = new Map<string, number>();
        
        files.forEach(file => {
            const ext = path.extname(file.fsPath).toLowerCase();
            const count = fileTypes.get(ext) || 0;
            fileTypes.set(ext, count + 1);
        });

        return {
            name: folder.name,
            uri: folder.uri,
            fileCount: files.length,
            fileTypes
        };
    }
}

interface ProjectInfo {
    folders: FolderInfo[];
    totalFiles: number;
    fileTypes: Map<string, number>;
}

interface FolderInfo {
    name: string;
    uri: vscode.Uri;
    fileCount: number;
    fileTypes: Map<string, number>;
}

最佳实践

1. 资源管理

typescript
// 正确管理监听器和资源
const disposables: vscode.Disposable[] = [];

// 添加监听器
disposables.push(vscode.workspace.onDidChangeWorkspaceFolders(handler));

// 在扩展停用时清理
export function deactivate() {
    disposables.forEach(d => d.dispose());
}

2. 错误处理

typescript
// 安全地访问工作区
function getActiveWorkspaceFolder(): vscode.WorkspaceFolder | undefined {
    const workspaceFolders = vscode.workspace.workspaceFolders;
    if (!workspaceFolders || workspaceFolders.length === 0) {
        vscode.window.showWarningMessage('没有打开的工作区文件夹');
        return undefined;
    }
    return workspaceFolders[0];
}

3. 性能优化

typescript
// 使用适当的文件搜索模式
const files = await vscode.workspace.findFiles(
    '**/*.{ts,js}',      // 具体的文件类型
    '**/node_modules/**', // 排除大型目录
    1000                 // 限制结果数量
);

相关 API

您的终极 AI 驱动 IDE 学习指南