mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-05-05 20:48:43 +00:00
69 lines
2.8 KiB
TypeScript
69 lines
2.8 KiB
TypeScript
import { URI } from '@theia/core/shared/vscode-uri';
|
|
import { isWindows } from '@theia/core/lib/common/os';
|
|
import { notEmpty } from '@theia/core/lib/common/objects';
|
|
import { MaybePromise } from '@theia/core/lib/common/types';
|
|
|
|
/**
|
|
* Class for determining the default workspace location from the
|
|
* `location.hash`, the historical workspace locations, and recent sketch files.
|
|
*
|
|
* The following logic is used for determining the default workspace location:
|
|
* - `hash` points to an existing location?
|
|
* - Yes
|
|
* - `validate location`. Is valid sketch location?
|
|
* - Yes
|
|
* - Done.
|
|
* - No
|
|
* - `try open recent workspace roots`, then `try open last modified sketches`, finally `create new sketch`.
|
|
* - No
|
|
* - `try open recent workspace roots`, then `try open last modified sketches`, finally `create new sketch`.
|
|
*/
|
|
namespace ArduinoWorkspaceRootResolver {
|
|
export interface InitOptions {
|
|
readonly isValid: (uri: string) => MaybePromise<boolean>;
|
|
}
|
|
export interface ResolveOptions {
|
|
readonly hash?: string;
|
|
readonly recentWorkspaces: string[];
|
|
// Gathered from the default sketch folder. The default sketch folder is defined by the CLI.
|
|
readonly recentSketches: string[];
|
|
}
|
|
}
|
|
export class ArduinoWorkspaceRootResolver {
|
|
constructor(protected options: ArduinoWorkspaceRootResolver.InitOptions) {}
|
|
|
|
async resolve(
|
|
options: ArduinoWorkspaceRootResolver.ResolveOptions
|
|
): Promise<{ uri: string } | undefined> {
|
|
const { hash, recentWorkspaces, recentSketches } = options;
|
|
for (const uri of [
|
|
this.hashToUri(hash),
|
|
...recentWorkspaces,
|
|
...recentSketches,
|
|
].filter(notEmpty)) {
|
|
const valid = await this.isValid(uri);
|
|
if (valid) {
|
|
return { uri };
|
|
}
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
protected isValid(uri: string): MaybePromise<boolean> {
|
|
return this.options.isValid(uri);
|
|
}
|
|
|
|
// Note: here, the `hash` was defined as new `URI(yourValidFsPath).path` so we have to map it to a valid FS path first.
|
|
// This is important for Windows only and a NOOP on POSIX.
|
|
// Note: we set the `new URI(myValidUri).path.toString()` as the `hash`. See:
|
|
// - https://github.com/eclipse-theia/theia/blob/8196e9dcf9c8de8ea0910efeb5334a974f426966/packages/workspace/src/browser/workspace-service.ts#L143 and
|
|
// - https://github.com/eclipse-theia/theia/blob/8196e9dcf9c8de8ea0910efeb5334a974f426966/packages/workspace/src/browser/workspace-service.ts#L423
|
|
protected hashToUri(hash: string | undefined): string | undefined {
|
|
if (hash && hash.length > 1 && hash.startsWith('#')) {
|
|
const path = decodeURI(hash.slice(1)).replace(/\\/g, '/'); // Trim the leading `#`, decode the URI and replace Windows separators
|
|
return URI.file(path.slice(isWindows && hash.startsWith('/') ? 1 : 0)).toString();
|
|
}
|
|
return undefined;
|
|
}
|
|
}
|