mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-10-27 03:58:33 +00:00
ATL-1064: Support for nested sketchbook structure
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
This commit is contained in:
@@ -1,14 +1,10 @@
|
||||
import { Sketch } from './sketches-service';
|
||||
import { SketchContainer } from './sketches-service';
|
||||
|
||||
export const ExamplesServicePath = '/services/example-service';
|
||||
export const ExamplesService = Symbol('ExamplesService');
|
||||
export interface ExamplesService {
|
||||
builtIns(): Promise<ExampleContainer[]>;
|
||||
installed(options: { fqbn: string }): Promise<{ user: ExampleContainer[], current: ExampleContainer[], any: ExampleContainer[] }>;
|
||||
builtIns(): Promise<SketchContainer[]>;
|
||||
installed(options: { fqbn: string }): Promise<{ user: SketchContainer[], current: SketchContainer[], any: SketchContainer[] }>;
|
||||
}
|
||||
|
||||
export interface ExampleContainer {
|
||||
readonly label: string;
|
||||
readonly children: ExampleContainer[];
|
||||
readonly sketches: Sketch[];
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import { FrontendApplicationContribution } from '@theia/core/lib/browser';
|
||||
import { ConfigService } from './config-service';
|
||||
import { DisposableCollection, Emitter } from '@theia/core';
|
||||
import { FileChangeType } from '@theia/filesystem/lib/browser';
|
||||
import { SketchContainer } from './sketches-service';
|
||||
|
||||
@injectable()
|
||||
export class SketchesServiceClientImpl implements FrontendApplicationContribution {
|
||||
@@ -35,9 +36,9 @@ export class SketchesServiceClientImpl implements FrontendApplicationContributio
|
||||
|
||||
onStart(): void {
|
||||
this.configService.getConfiguration().then(({ sketchDirUri }) => {
|
||||
this.sketchService.getSketches(sketchDirUri).then(sketches => {
|
||||
this.sketchService.getSketches({ uri: sketchDirUri }).then(container => {
|
||||
const sketchbookUri = new URI(sketchDirUri);
|
||||
for (const sketch of sketches) {
|
||||
for (const sketch of SketchContainer.toArray(container)) {
|
||||
this.sketches.set(sketch.uri, sketch);
|
||||
}
|
||||
this.toDispose.push(this.fileService.watch(new URI(sketchDirUri), { recursive: true, excludes: [] }));
|
||||
|
||||
@@ -5,10 +5,11 @@ export const SketchesService = Symbol('SketchesService');
|
||||
export interface SketchesService {
|
||||
|
||||
/**
|
||||
* Returns with the direct sketch folders from the location of the `fileStat`.
|
||||
* The sketches returns with inverse-chronological order, the first item is the most recent one.
|
||||
* Resolves to a sketch container representing the hierarchical structure of the sketches.
|
||||
* If `uri` is not given, `directories.user` will be user instead. Specify `exclude` global patterns to filter folders from the sketch container.
|
||||
* If `exclude` is not set `['**\/libraries\/**', '**\/hardware\/**']` will be used instead.
|
||||
*/
|
||||
getSketches(uri?: string): Promise<Sketch[]>;
|
||||
getSketches({ uri, exclude }: { uri?: string, exclude?: string[] }): Promise<SketchContainer>;
|
||||
|
||||
/**
|
||||
* This is the TS implementation of `SketchLoad` from the CLI and should be replaced with a gRPC call eventually.
|
||||
@@ -100,3 +101,51 @@ export namespace Sketch {
|
||||
return Extensions.MAIN.some(ext => arg.endsWith(ext));
|
||||
}
|
||||
}
|
||||
|
||||
export interface SketchContainer {
|
||||
readonly label: string;
|
||||
readonly children: SketchContainer[];
|
||||
readonly sketches: Sketch[];
|
||||
}
|
||||
export namespace SketchContainer {
|
||||
|
||||
export function is(arg: any): arg is SketchContainer {
|
||||
return !!arg
|
||||
&& 'label' in arg && typeof arg.label === 'string'
|
||||
&& 'children' in arg && Array.isArray(arg.children)
|
||||
&& 'sketches' in arg && Array.isArray(arg.sketches);
|
||||
}
|
||||
|
||||
/**
|
||||
* `false` if the `container` recursively contains at least one sketch. Otherwise, `true`.
|
||||
*/
|
||||
export function isEmpty(container: SketchContainer): boolean {
|
||||
const hasSketch = (parent: SketchContainer) => {
|
||||
if (parent.sketches.length || parent.children.some(child => hasSketch(child))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return !hasSketch(container);
|
||||
}
|
||||
|
||||
export function prune<T extends SketchContainer>(container: T): T {
|
||||
for (let i = container.children.length - 1; i >= 0; i--) {
|
||||
if (isEmpty(container.children[i])) {
|
||||
container.children.splice(i, 1);
|
||||
}
|
||||
}
|
||||
return container;
|
||||
}
|
||||
|
||||
export function toArray(container: SketchContainer): Sketch[] {
|
||||
const visit = (parent: SketchContainer, toPushSketch: Sketch[]) => {
|
||||
toPushSketch.push(...parent.sketches);
|
||||
parent.children.map(child => visit(child, toPushSketch));
|
||||
}
|
||||
const sketches: Sketch[] = [];
|
||||
visit(container, sketches);
|
||||
return sketches;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user