UNPKG

@sussudio/platform

Version:

Internal APIs for VS Code's service injection the base services.

224 lines (223 loc) 6.88 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { localize } from 'vscode-nls.mjs'; import { basename, extname } from '@sussudio/base/common/path.mjs'; import { TernarySearchTree } from '@sussudio/base/common/ternarySearchTree.mjs'; import { extname as resourceExtname, basenameOrAuthority, joinPath, extUriBiasedIgnorePathCase, } from '@sussudio/base/common/resources.mjs'; import { URI } from '@sussudio/base/common/uri.mjs'; import { createDecorator } from '../../instantiation/common/instantiation.mjs'; import { Schemas } from '@sussudio/base/common/network.mjs'; export const IWorkspaceContextService = createDecorator('contextService'); export function isSingleFolderWorkspaceIdentifier(obj) { const singleFolderIdentifier = obj; return typeof singleFolderIdentifier?.id === 'string' && URI.isUri(singleFolderIdentifier.uri); } export function isEmptyWorkspaceIdentifier(obj) { const emptyWorkspaceIdentifier = obj; return ( typeof emptyWorkspaceIdentifier?.id === 'string' && !isSingleFolderWorkspaceIdentifier(obj) && !isWorkspaceIdentifier(obj) ); } export const EXTENSION_DEVELOPMENT_EMPTY_WINDOW_WORKSPACE = { id: 'ext-dev' }; export const UNKNOWN_EMPTY_WINDOW_WORKSPACE = { id: 'empty-window' }; export function toWorkspaceIdentifier(arg0, isExtensionDevelopment) { // Empty workspace if (typeof arg0 === 'string' || typeof arg0 === 'undefined') { // With a backupPath, the basename is the empty workspace identifier if (typeof arg0 === 'string') { return { id: basename(arg0), }; } // Extension development empty windows have backups disabled // so we return a constant workspace identifier for extension // authors to allow to restore their workspace state even then. if (isExtensionDevelopment) { return EXTENSION_DEVELOPMENT_EMPTY_WINDOW_WORKSPACE; } return UNKNOWN_EMPTY_WINDOW_WORKSPACE; } // Multi root const workspace = arg0; if (workspace.configuration) { return { id: workspace.id, configPath: workspace.configuration, }; } // Single folder if (workspace.folders.length === 1) { return { id: workspace.id, uri: workspace.folders[0].uri, }; } // Empty window return { id: workspace.id, }; } export function isWorkspaceIdentifier(obj) { const workspaceIdentifier = obj; return typeof workspaceIdentifier?.id === 'string' && URI.isUri(workspaceIdentifier.configPath); } export function reviveIdentifier(identifier) { // Single Folder const singleFolderIdentifierCandidate = identifier; if (singleFolderIdentifierCandidate?.uri) { return { id: singleFolderIdentifierCandidate.id, uri: URI.revive(singleFolderIdentifierCandidate.uri) }; } // Multi folder const workspaceIdentifierCandidate = identifier; if (workspaceIdentifierCandidate?.configPath) { return { id: workspaceIdentifierCandidate.id, configPath: URI.revive(workspaceIdentifierCandidate.configPath) }; } // Empty if (identifier?.id) { return { id: identifier.id }; } return undefined; } export function isWorkspace(thing) { const candidate = thing; return !!( candidate && typeof candidate === 'object' && typeof candidate.id === 'string' && Array.isArray(candidate.folders) ); } export function isWorkspaceFolder(thing) { const candidate = thing; return !!( candidate && typeof candidate === 'object' && URI.isUri(candidate.uri) && typeof candidate.name === 'string' && typeof candidate.toResource === 'function' ); } export class Workspace { _id; _transient; _configuration; _ignorePathCasing; _foldersMap = TernarySearchTree.forUris(this._ignorePathCasing, () => true); _folders; constructor(_id, folders, _transient, _configuration, _ignorePathCasing) { this._id = _id; this._transient = _transient; this._configuration = _configuration; this._ignorePathCasing = _ignorePathCasing; this.folders = folders; } update(workspace) { this._id = workspace.id; this._configuration = workspace.configuration; this._transient = workspace.transient; this._ignorePathCasing = workspace._ignorePathCasing; this.folders = workspace.folders; } get folders() { return this._folders; } set folders(folders) { this._folders = folders; this.updateFoldersMap(); } get id() { return this._id; } get transient() { return this._transient; } get configuration() { return this._configuration; } set configuration(configuration) { this._configuration = configuration; } getFolder(resource) { if (!resource) { return null; } return this._foldersMap.findSubstr(resource) || null; } updateFoldersMap() { this._foldersMap = TernarySearchTree.forUris(this._ignorePathCasing, () => true); for (const folder of this.folders) { this._foldersMap.set(folder.uri, folder); } } toJSON() { return { id: this.id, folders: this.folders, transient: this.transient, configuration: this.configuration }; } } export class WorkspaceFolder { raw; uri; name; index; constructor( data, /** * Provides access to the original metadata for this workspace * folder. This can be different from the metadata provided in * this class: * - raw paths can be relative * - raw paths are not normalized */ raw, ) { this.raw = raw; this.uri = data.uri; this.index = data.index; this.name = data.name; } toResource(relativePath) { return joinPath(this.uri, relativePath); } toJSON() { return { uri: this.uri, name: this.name, index: this.index }; } } export function toWorkspaceFolder(resource) { return new WorkspaceFolder( { uri: resource, index: 0, name: basenameOrAuthority(resource) }, { uri: resource.toString() }, ); } export const WORKSPACE_EXTENSION = 'code-workspace'; export const WORKSPACE_SUFFIX = `.${WORKSPACE_EXTENSION}`; export const WORKSPACE_FILTER = [ { name: localize('codeWorkspace', 'Code Workspace'), extensions: [WORKSPACE_EXTENSION] }, ]; export const UNTITLED_WORKSPACE_NAME = 'workspace.json'; export function isUntitledWorkspace(path, environmentService) { return extUriBiasedIgnorePathCase.isEqualOrParent(path, environmentService.untitledWorkspacesHome); } export function isTemporaryWorkspace(arg1) { let path; if (URI.isUri(arg1)) { path = arg1; } else { path = arg1.configuration; } return path?.scheme === Schemas.tmp; } export function isSavedWorkspace(path, environmentService) { return !isUntitledWorkspace(path, environmentService) && !isTemporaryWorkspace(path); } export function hasWorkspaceFileExtension(path) { const ext = typeof path === 'string' ? extname(path) : resourceExtname(path); return ext === WORKSPACE_SUFFIX; }