All files / views/trees/workspace-tree workspace-node-provider.ts

94.28% Statements 33/35
100% Branches 18/18
77.77% Functions 7/9
94.11% Lines 32/34

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                            13x   13x     20x         13x           1x       3x   3x                 6x 2x     4x 3x     4x   4x   1x   1x 3x   1x   1x     2x 2x   2x 1x         4x       2x 2x   2x 2x 2x 2x   2x 1x             2x            
import * as vscode from 'vscode';
import { Utils } from 'vscode-uri';
import { container } from 'tsyringe';
import { ServiceToken } from '@src/services/tokens';
import { IWorkspaceFileService } from '@src/services/core';
 
// For a complete implementation of the FileSystemProvider API, see:
// https://github.com/boltex/revealRangeTest/blob/main/src/fileExplorer.ts#L185
 
/**
 * A tree node provider for RDF files in the Visual Studio Code workspace.
 */
export class WorkspaceNodeProvider implements vscode.TreeDataProvider<string> {
 
	private _onDidChangeTreeData = new vscode.EventEmitter<string | undefined>();
 
	readonly onDidChangeTreeData = this._onDidChangeTreeData.event;
 
	private get workspaceFileService() {
		return container.resolve<IWorkspaceFileService>(ServiceToken.WorkspaceFileService);
	}
 
	constructor() {
		// Monitor for changes in the workspace folders.
		this.workspaceFileService.onDidChangeFiles((e) => {
			this._onDidChangeTreeData.fire(e.uri.toString());
		});
	}
 
	refresh(): void {
		this._onDidChangeTreeData.fire(undefined);
	}
 
	getParent(uri: string): string | undefined {
		let resourceUri = vscode.Uri.parse(uri);
 
		return uri ? Utils.dirname(resourceUri).toString() : undefined;
	}
 
	/**
	 * Get the children of a folder.
	 * @param uri The URI of the folder to get children for or `undefined` for the root.
	 * @returns An array of child URIs, sorted by folders first and then by name.
	 */
	async getChildren(uri?: string): Promise<string[]> {
		if (!vscode.workspace.name || !vscode.workspace.workspaceFolders?.length) {
			return [];
		}
 
		if (!uri) {
			await this.workspaceFileService.waitForDiscovery();
		}
 
		const result = [];
 
		if (uri) {
			// If the URI is provided, get the contents of the specified folder.
			const folder = vscode.Uri.parse(uri);
 
			result.push(...(await this.workspaceFileService.getFolderContents(folder)));
		} else if (!vscode.workspace.workspaceFile) {
			// If this is not a workspace, then return the contents of the first folder.
			const folder = vscode.workspace.workspaceFolders[0].uri;
 
			result.push(...(await this.workspaceFileService.getFolderContents(folder)));
		} else {
			// Iterate the workspace folders and push only the ones that have contents.
			for (const folder of vscode.workspace.workspaceFolders) {
				const contents = await this.workspaceFileService.getFolderContents(folder.uri);
 
				if (contents.length > 0) {
					result.push(folder.uri);
				}
			}
		}
 
		return result.map((resource) => resource.toString());
	}
 
	getTreeItem(uri: string): vscode.TreeItem {
		const resourceUri = vscode.Uri.parse(uri);
		const isDirectory = Utils.extname(resourceUri) == '';
 
		const item = new vscode.TreeItem(uri);
		item.resourceUri = resourceUri;
		item.label = Utils.basename(resourceUri);
		item.collapsibleState = isDirectory ? vscode.TreeItemCollapsibleState.Collapsed : vscode.TreeItemCollapsibleState.None;
 
		if (!isDirectory) {
			item.command = {
				command: 'vscode.open',
				arguments: [uri],
				title: 'Open File'
			};
		}
 
		return item;
	}
 
	getTotalItemCount(): number {
		return 0;
	}
}