11import { Mutex } from 'async-mutex' ;
2- import { MAIN_MENU_BAR , MenuContribution , MenuModelRegistry , SelectionService , ILogger } from '@theia/core' ;
2+ import { MAIN_MENU_BAR , MenuContribution , MenuModelRegistry , SelectionService , ILogger , DisposableCollection } from '@theia/core' ;
33import {
44 ContextMenuRenderer ,
55 FrontendApplication , FrontendApplicationContribution ,
@@ -12,7 +12,7 @@ import { TabBarToolbarContribution, TabBarToolbarRegistry } from '@theia/core/li
1212import { CommandContribution , CommandRegistry } from '@theia/core/lib/common/command' ;
1313import { MessageService } from '@theia/core/lib/common/message-service' ;
1414import URI from '@theia/core/lib/common/uri' ;
15- import { EditorMainMenu , EditorManager } from '@theia/editor/lib/browser' ;
15+ import { EditorMainMenu , EditorManager , EditorOpenerOptions } from '@theia/editor/lib/browser' ;
1616import { FileDialogService } from '@theia/filesystem/lib/browser/file-dialog' ;
1717import { ProblemContribution } from '@theia/markers/lib/browser/problem/problem-contribution' ;
1818import { MonacoMenus } from '@theia/monaco/lib/browser/monaco-menu' ;
@@ -26,7 +26,7 @@ import { inject, injectable, postConstruct } from 'inversify';
2626import * as React from 'react' ;
2727import { remote } from 'electron' ;
2828import { MainMenuManager } from '../common/main-menu-manager' ;
29- import { BoardsService , CoreService , Port , SketchesService , ExecutableService } from '../common/protocol' ;
29+ import { BoardsService , CoreService , Port , SketchesService , ExecutableService , Sketch } from '../common/protocol' ;
3030import { ArduinoDaemon } from '../common/protocol/arduino-daemon' ;
3131import { ConfigService } from '../common/protocol/config-service' ;
3232import { FileSystemExt } from '../common/protocol/filesystem-ext' ;
@@ -48,6 +48,8 @@ import { OutputService } from '../common/protocol/output-service';
4848import { ArduinoPreferences } from './arduino-preferences' ;
4949import { SketchesServiceClientImpl } from '../common/protocol/sketches-service-client-impl' ;
5050import { SaveAsSketch } from './contributions/save-as-sketch' ;
51+ import { FileChangeType } from '@theia/filesystem/lib/browser' ;
52+ import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state' ;
5153
5254@injectable ( )
5355export class ArduinoFrontendContribution implements FrontendApplicationContribution ,
@@ -81,7 +83,7 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
8183 protected readonly fileDialogService : FileDialogService ;
8284
8385 @inject ( FileService )
84- protected readonly fileSystem : FileService ;
86+ protected readonly fileService : FileService ;
8587
8688 @inject ( SketchesService )
8789 protected readonly sketchService : SketchesService ;
@@ -158,7 +160,11 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
158160 @inject ( SketchesServiceClientImpl )
159161 protected readonly sketchServiceClient : SketchesServiceClientImpl ;
160162
163+ @inject ( FrontendApplicationStateService )
164+ protected readonly appStateService : FrontendApplicationStateService ;
165+
161166 protected invalidConfigPopup : Promise < void | 'No' | 'Yes' | undefined > | undefined ;
167+ protected toDisposeOnStop = new DisposableCollection ( ) ;
162168
163169 @postConstruct ( )
164170 protected async init ( ) : Promise < void > {
@@ -182,6 +188,23 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
182188 }
183189 this . boardsServiceClientImpl . onBoardsConfigChanged ( updateStatusBar ) ;
184190 updateStatusBar ( this . boardsServiceClientImpl . boardsConfig ) ;
191+ this . appStateService . reachedState ( 'ready' ) . then ( async ( ) => {
192+ const sketch = await this . sketchServiceClient . currentSketch ( ) ;
193+ if ( sketch && ( ! await this . sketchService . isTemp ( sketch ) ) ) {
194+ this . toDisposeOnStop . push ( this . fileService . watch ( new URI ( sketch . uri ) ) ) ;
195+ this . toDisposeOnStop . push ( this . fileService . onDidFilesChange ( async event => {
196+ for ( const { type, resource } of event . changes ) {
197+ if ( type === FileChangeType . ADDED && resource . parent . toString ( ) === sketch . uri ) {
198+ const reloadedSketch = await this . sketchService . loadSketch ( sketch . uri )
199+ if ( Sketch . isInSketch ( resource , reloadedSketch ) ) {
200+ this . ensureOpened ( resource . toString ( ) , true , { mode : 'open' } ) ;
201+ }
202+ }
203+ }
204+ } ) ) ;
205+ }
206+ } ) ;
207+
185208 }
186209
187210 onStart ( app : FrontendApplication ) : void {
@@ -225,6 +248,10 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
225248 app . shell . leftPanelHandler . removeMenu ( 'settings-menu' ) ;
226249 }
227250
251+ onStop ( ) : void {
252+ this . toDisposeOnStop . dispose ( ) ;
253+ }
254+
228255 protected languageServerFqbn ?: string ;
229256 protected languageServerStartMutex = new Mutex ( ) ;
230257 protected async startLanguageServer ( fqbn : string , name : string | undefined ) : Promise < void > {
@@ -257,14 +284,14 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
257284 if ( log ) {
258285 const currentSketch = await this . sketchServiceClient . currentSketch ( ) ;
259286 if ( currentSketch ) {
260- currentSketchPath = await this . fileSystem . fsPath ( new URI ( currentSketch . uri ) ) ;
287+ currentSketchPath = await this . fileService . fsPath ( new URI ( currentSketch . uri ) ) ;
261288 }
262289 }
263290 const { clangdUri, cliUri, lsUri } = await this . executableService . list ( ) ;
264291 const [ clangdPath , cliPath , lsPath ] = await Promise . all ( [
265- this . fileSystem . fsPath ( new URI ( clangdUri ) ) ,
266- this . fileSystem . fsPath ( new URI ( cliUri ) ) ,
267- this . fileSystem . fsPath ( new URI ( lsUri ) ) ,
292+ this . fileService . fsPath ( new URI ( clangdUri ) ) ,
293+ this . fileService . fsPath ( new URI ( cliUri ) ) ,
294+ this . fileService . fsPath ( new URI ( lsUri ) ) ,
268295 ] ) ;
269296 this . languageServerFqbn = await Promise . race ( [
270297 new Promise < undefined > ( ( _ , reject ) => setTimeout ( ( ) => reject ( new Error ( `Timeout after ${ 20_000 } ms.` ) ) , 20_000 ) ) ,
@@ -367,10 +394,10 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
367394 }
368395 }
369396
370- protected async ensureOpened ( uri : string , forceOpen : boolean = false ) : Promise < any > {
397+ protected async ensureOpened ( uri : string , forceOpen : boolean = false , options ?: EditorOpenerOptions | undefined ) : Promise < any > {
371398 const widget = this . editorManager . all . find ( widget => widget . editor . uri . toString ( ) === uri ) ;
372399 if ( ! widget || forceOpen ) {
373- return this . editorManager . open ( new URI ( uri ) ) ;
400+ return this . editorManager . open ( new URI ( uri ) , options ) ;
374401 }
375402 }
376403
@@ -420,13 +447,13 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
420447 description : 'Background color of the toolbar items when hovering over them. Such as Upload, Verify, etc.'
421448 } ,
422449 {
423- id : 'arduino.toolbar.toggleBackground' ,
424- defaults : {
425- dark : 'editor.selectionBackground' ,
426- light : 'editor.selectionBackground' ,
427- hc : 'textPreformat.foreground'
428- } ,
429- description : 'Toggle color of the toolbar items when they are currently toggled (the command is in progress)'
450+ id : 'arduino.toolbar.toggleBackground' ,
451+ defaults : {
452+ dark : 'editor.selectionBackground' ,
453+ light : 'editor.selectionBackground' ,
454+ hc : 'textPreformat.foreground'
455+ } ,
456+ description : 'Toggle color of the toolbar items when they are currently toggled (the command is in progress)'
430457 } ,
431458 {
432459 id : 'arduino.output.foreground' ,
0 commit comments