Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | 45x 45x 7x 18x 5x 19x 19x 19x 19x 19x 1x 18x 18x 15x 15x 15x 15x 15x 15x 15x 15x 18x 18x 18x 15x 3x 3x 3x 15x 15x 14x 14x 2x 43x 43x 43x 13x 13x 38x 38x 38x 38x 38x 38x | import * as vscode from 'vscode';
import { Utils } from 'vscode-uri';
import { WorkspaceDescriptor, IWorkspaceService } from './workspace-service.interface';
/**
* Service for discovering VS Code workspace files in the project directory
* and providing fast access to their identifiers and paths.
*/
export class WorkspaceService implements IWorkspaceService {
private _workspaces: WorkspaceDescriptor[] = [];
private readonly _workspaceMap = new Map<string, WorkspaceDescriptor>();
private _activeRootUri: vscode.Uri | undefined;
get activeRootUri(): vscode.Uri | undefined {
return this._activeRootUri;
}
get workspaces(): ReadonlyArray<WorkspaceDescriptor> {
return this._workspaces;
}
getWorkspaceById(id: string): WorkspaceDescriptor | undefined {
return this._workspaceMap.get(id);
}
async discoverWorkspaces(): Promise<void> {
this._workspaces = [];
this._workspaceMap.clear();
this._activeRootUri = undefined;
const folders = vscode.workspace.workspaceFolders;
if (!folders || folders.length === 0) {
return;
}
const files = await vscode.workspace.findFiles('**/*.code-workspace');
for (const fileUri of files) {
for (const folder of folders) {
const folderPath = folder.uri.path.endsWith('/')
? folder.uri.path
: folder.uri.path + '/';
Eif (fileUri.path.startsWith(folderPath)) {
const content = await WorkspaceService.readWorkspaceFile(fileUri);
const descriptor = WorkspaceService.createDescriptor(fileUri, folder.uri, content);
this._workspaces.push(descriptor);
this._workspaceMap.set(descriptor.id, descriptor);
break;
}
}
}
// Determine the active root URI from the currently-open workspace file.
this._activeRootUri = this._resolveActiveRootUri();
}
/**
* Determines the monorepo root URI for the currently active workspace.
* Uses `vscode.workspace.workspaceFile` to find the active `.code-workspace` descriptor.
*/
private _resolveActiveRootUri(): vscode.Uri | undefined {
const workspaceFile = vscode.workspace.workspaceFile;
if (!workspaceFile) {
return undefined;
}
const activeId = WorkspaceService.getIdFromFilename(workspaceFile.path);
const descriptor = this._workspaceMap.get(activeId);
return descriptor?.rootUri;
}
/**
* Reads and parses a `.code-workspace` JSON file.
* Returns `undefined` if the file cannot be read or parsed.
*/
static async readWorkspaceFile(fileUri: vscode.Uri): Promise<WorkspaceFileContent | undefined> {
try {
const bytes = await vscode.workspace.fs.readFile(fileUri);
const text = new TextDecoder().decode(bytes);
return JSON.parse(text);
} catch {
return undefined;
}
}
/**
* Extracts the workspace ID from a filename path.
*/
static getIdFromFilename(path: string): string {
const parts = path.split('/');
const fileName = parts[parts.length - 1];
return fileName.replace(/\.code-workspace$/, '');
}
/**
* Resolves the monorepo root URI from a `.code-workspace` file location and a root offset.
* @param workspaceFileUri The URI of the `.code-workspace` file.
* @param rootOffset A relative path from the workspace file's directory to the monorepo root (e.g. `"."` or `".."`).
* @returns The resolved root URI, with a normalised path (no trailing segments like `/..`).
*/
static resolveRootUri(workspaceFileUri: vscode.Uri, rootOffset: string): vscode.Uri {
const workspaceDir = Utils.dirname(workspaceFileUri);
return Utils.resolvePath(workspaceDir, rootOffset);
}
/**
* Creates a workspace descriptor from a file URI, workspace root URI, and parsed file content.
* @param fileUri The URI of the `.code-workspace` file.
* @param folderUri The URI of the workspace folder containing the file.
* @param content Parsed content of the `.code-workspace` file, if available.
*/
static createDescriptor(fileUri: vscode.Uri, folderUri: vscode.Uri, content?: WorkspaceFileContent): WorkspaceDescriptor {
const rootPath = folderUri.path.endsWith('/')
? folderUri.path
: folderUri.path + '/';
const relativePath = fileUri.path.startsWith(rootPath)
? fileUri.path.substring(rootPath.length)
: fileUri.path;
const id = WorkspaceService.getIdFromFilename(fileUri.path);
const rootOffset = content?.settings?.['mentor.workspace.rootOffset'];
const rootUri = rootOffset ? WorkspaceService.resolveRootUri(fileUri, rootOffset) : undefined;
return {
id,
uri: fileUri,
absolutePath: fileUri.fsPath,
relativePath,
rootOffset,
rootUri,
};
}
}
/**
* Minimal shape of a `.code-workspace` JSON file, covering only the fields we need.
*/
export interface WorkspaceFileContent {
folders?: { path: string }[];
settings?: { [key: string]: any };
}
|