diff --git a/arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx b/arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx index 5c175982..a615ab44 100644 --- a/arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx +++ b/arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx @@ -12,14 +12,14 @@ import { ConnectedBoards } from './components/connected-boards'; import { CoreService } from '../common/protocol/core-service'; import { WorkspaceServiceExt } from './workspace-service-ext'; import { ToolOutputServiceClient } from '../common/protocol/tool-output-service'; -import { ConfirmDialog, OpenerService } from '@theia/core/lib/browser'; +import { ConfirmDialog } from '@theia/core/lib/browser'; import { QuickPickService } from '@theia/core/lib/common/quick-pick-service'; import { BoardsListWidgetFrontendContribution } from './boards/boards-widget-frontend-contribution'; import { BoardsNotificationService } from './boards-notification-service'; -import { FileSystem, FileStat } from '@theia/filesystem/lib/common'; import { WorkspaceRootUriAwareCommandHandler } from '@theia/workspace/lib/browser/workspace-commands'; import { SelectionService } from '@theia/core'; import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service'; +import { SketchFactory } from './sketch-factory'; @injectable() export class ArduinoFrontendContribution extends DefaultFrontendApplicationContribution implements TabBarToolbarContribution, CommandContribution { @@ -48,18 +48,15 @@ export class ArduinoFrontendContribution extends DefaultFrontendApplicationContr @inject(BoardsNotificationService) protected readonly boardsNotificationService: BoardsNotificationService; - @inject(FileSystem) - protected readonly fileSystem: FileSystem; - - @inject(OpenerService) - protected readonly openerService: OpenerService; - @inject(WorkspaceService) protected readonly workspaceService: WorkspaceService; @inject(SelectionService) protected readonly selectionService: SelectionService; + @inject(SketchFactory) + protected readonly sketchFactory: SketchFactory; + @postConstruct() protected async init(): Promise { @@ -132,64 +129,15 @@ export class ArduinoFrontendContribution extends DefaultFrontendApplicationContr }); registry.registerCommand(ArduinoCommands.NEW_SKETCH, new WorkspaceRootUriAwareCommandHandler(this.workspaceService, this.selectionService, { execute: async uri => { - const parent = await this.getDirectory(uri) - if (!parent) { - return; - } - - const parentUri = new URI(parent.uri); - const monthNames = ["january", "february", "march", "april", "may", "june", - "july", "august", "september", "october", "november", "december" - ]; - const today = new Date(); - - const sketchBaseName = `sketch_${monthNames[today.getMonth()]}${today.getDay()}`; - let sketchName: string | undefined; - for (let i = 97; i < 97 + 26; i++) { - let sketchNameCandidate = `${sketchBaseName}${String.fromCharCode(i)}`; - if (await this.fileSystem.exists(parentUri.resolve(sketchNameCandidate).toString())) { - continue; - } - - sketchName = sketchNameCandidate; - break; - } - - if (!sketchName) { - new ConfirmDialog({ title: "New sketch", msg: "Cannot create a unique sketch name", ok: "Ok" }).open(); - return; - } - try { - const sketchDir = parentUri.resolve(sketchName); - const sketchFile = sketchDir.resolve(`${sketchName}.ino`); - this.fileSystem.createFolder(sketchDir.toString()); - this.fileSystem.createFile(sketchFile.toString(), { content: ` -void setup() { - -} - -void loop() { - -} -` }); - const opener = await this.openerService.getOpener(sketchFile) - opener.open(sketchFile, { reveal: true }); + await this.sketchFactory.createNewSketch(uri); } catch (e) { - new ConfirmDialog({ title: "New sketch", msg: "Cannot create new sketch: " + e, ok: "Ok" }).open(); - } + new ConfirmDialog({ title: "Cannot create new sketch", msg: e.toString(), ok: "Ok" }).open(); + } } })) } - protected async getDirectory(candidate: URI): Promise { - const stat = await this.fileSystem.getFileStat(candidate.toString()); - if (stat && stat.isDirectory) { - return stat; - } - return this.fileSystem.getFileStat(candidate.parent.toString()); - } - private async onNoBoardsInstalled() { const action = await this.messageService.info("You have no boards installed. Use the boards mangager to install one.", "Open Boards Manager"); if (!action) { diff --git a/arduino-ide-extension/src/browser/arduino-frontend-module.ts b/arduino-ide-extension/src/browser/arduino-frontend-module.ts index 3aa571c0..fe1b5391 100644 --- a/arduino-ide-extension/src/browser/arduino-frontend-module.ts +++ b/arduino-ide-extension/src/browser/arduino-frontend-module.ts @@ -28,6 +28,7 @@ import { ThemeService } from '@theia/core/lib/browser/theming'; import { ArduinoTheme } from './arduino-theme'; import { ArduinoFileMenuContribution } from './arduino-file-menu'; import { MenuContribution } from '@theia/core'; +import { SketchFactory } from './sketch-factory'; export default new ContainerModule((bind: interfaces.Bind, unbind: interfaces.Unbind, isBound: interfaces.IsBound, rebind: interfaces.Rebind) => { // Commands and toolbar items @@ -91,6 +92,7 @@ export default new ContainerModule((bind: interfaces.Bind, unbind: interfaces.Un }); rebind(WorkspaceService).to(AWorkspaceService).inSingletonScope(); + bind(SketchFactory).toSelf().inSingletonScope(); const themeService = ThemeService.get(); themeService.register(...ArduinoTheme.themes); diff --git a/arduino-ide-extension/src/browser/arduino-workspace-service.ts b/arduino-ide-extension/src/browser/arduino-workspace-service.ts index 3fd22e63..304a33e8 100644 --- a/arduino-ide-extension/src/browser/arduino-workspace-service.ts +++ b/arduino-ide-extension/src/browser/arduino-workspace-service.ts @@ -1,8 +1,9 @@ import { WorkspaceService } from "@theia/workspace/lib/browser/workspace-service"; import { injectable, inject } from "inversify"; import { WorkspaceServer } from "@theia/workspace/lib/common"; -import { FileSystem } from "@theia/filesystem/lib/common"; +import { FileSystem, FileStat } from "@theia/filesystem/lib/common"; import URI from "@theia/core/lib/common/uri"; +import { SketchFactory } from "./sketch-factory"; /** * This is workaround to have custom frontend binding for the default workspace, although we @@ -17,17 +18,33 @@ export class AWorkspaceService extends WorkspaceService { @inject(FileSystem) protected readonly fileSystem: FileSystem; + @inject(SketchFactory) + protected readonly sketchFactory: SketchFactory; + protected async getDefaultWorkspacePath(): Promise { - const result = await super.getDefaultWorkspacePath(); - if (result) { - return result; - } - const userHome = await this.fileSystem.getCurrentUserHome(); - if (userHome) { + let result = await super.getDefaultWorkspacePath(); + if (!result) { + const userHome = await this.fileSystem.getCurrentUserHome(); + if (!userHome) { + return; + } + // The backend has created this location if it was missing. - return new URI(userHome.uri).resolve('Arduino-PoC').resolve('workspace').toString(); + result = new URI(userHome.uri).resolve('Arduino-PoC').resolve('Sketches').toString(); } - return undefined; + + const stat = await this.fileSystem.getFileStat(result); + if (!stat) { + // workspace does not exist yet, create it + await this.fileSystem.createFolder(result); + await this.sketchFactory.createNewSketch(new URI(result)); + } + + return result; + } + + protected async setWorkspace(workspaceStat: FileStat | undefined): Promise { + await super.setWorkspace(workspaceStat); } } \ No newline at end of file diff --git a/arduino-ide-extension/src/browser/sketch-factory.ts b/arduino-ide-extension/src/browser/sketch-factory.ts new file mode 100644 index 00000000..eafdd289 --- /dev/null +++ b/arduino-ide-extension/src/browser/sketch-factory.ts @@ -0,0 +1,57 @@ +import { injectable, inject } from "inversify"; +import URI from "@theia/core/lib/common/uri"; +import { OpenerService } from "@theia/core/lib/browser"; +import { FileSystem } from "@theia/filesystem/lib/common"; + +@injectable() +export class SketchFactory { + + @inject(FileSystem) + protected readonly fileSystem: FileSystem; + + @inject(OpenerService) + protected readonly openerService: OpenerService; + + public async createNewSketch(parent: URI): Promise { + const monthNames = ["january", "february", "march", "april", "may", "june", + "july", "august", "september", "october", "november", "december" + ]; + const today = new Date(); + + const sketchBaseName = `sketch_${monthNames[today.getMonth()]}${today.getDay()}`; + let sketchName: string | undefined; + for (let i = 97; i < 97 + 26; i++) { + let sketchNameCandidate = `${sketchBaseName}${String.fromCharCode(i)}`; + if (await this.fileSystem.exists(parent.resolve(sketchNameCandidate).toString())) { + continue; + } + + sketchName = sketchNameCandidate; + break; + } + + if (!sketchName) { + throw new Error("Cannot create a unique sketch name"); + } + + try { + const sketchDir = parent.resolve(sketchName); + const sketchFile = sketchDir.resolve(`${sketchName}.ino`); + this.fileSystem.createFolder(sketchDir.toString()); + this.fileSystem.createFile(sketchFile.toString(), { content: ` +void setup() { + +} + +void loop() { + +} +` }); + const opener = await this.openerService.getOpener(sketchFile) + opener.open(sketchFile, { reveal: true }); + } catch (e) { + throw new Error("Cannot create new sketch: " + e); + } + } + +} \ No newline at end of file diff --git a/arduino-ide-extension/src/node/default-workspace-server-ext.ts b/arduino-ide-extension/src/node/default-workspace-server-ext.ts index c992726c..c747408e 100644 --- a/arduino-ide-extension/src/node/default-workspace-server-ext.ts +++ b/arduino-ide-extension/src/node/default-workspace-server-ext.ts @@ -1,6 +1,5 @@ import * as os from 'os'; import * as path from 'path'; -import * as fs from 'fs-extra'; import { injectable } from 'inversify'; import { FileUri } from '@theia/core/lib/node/file-uri'; import { DefaultWorkspaceServer } from '@theia/workspace/lib/node/default-workspace-server'; @@ -8,30 +7,8 @@ import { DefaultWorkspaceServer } from '@theia/workspace/lib/node/default-worksp @injectable() export class DefaultWorkspaceServerExt extends DefaultWorkspaceServer { - /** - * Reads the most recently used workspace root from the user's home directory. - */ - // tslint:disable-next-line:no-any - protected async readRecentWorkspacePathsFromUserHome(): Promise { - const paths = await super.readRecentWorkspacePathsFromUserHome(); - if (!paths || paths.recentRoots.length === 0) { - const defaultWorkspacePath = path.resolve(os.homedir(), 'Arduino-PoC', 'workspace'); - if (!fs.existsSync(defaultWorkspacePath)) { - fs.mkdirpSync(defaultWorkspacePath); - } - return { - recentRoots: [ - FileUri.create(defaultWorkspacePath) - ] - }; - } - return paths; - } - - async getMostRecentlyUsedWorkspace(): Promise { - const result = await super.getMostRecentlyUsedWorkspace(); - console.log(result); - return result; + protected async getWorkspaceURIFromCli(): Promise { + return FileUri.create(path.join(os.homedir(), 'Arduino-PoC', 'Sketches')).toString(); } } \ No newline at end of file