Update currentSketch when files change.

Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
This commit is contained in:
Akos Kitta 2022-08-25 13:32:47 +02:00 committed by Akos Kitta
parent 5b79320302
commit 0c87fa9877
3 changed files with 84 additions and 9 deletions

View File

@ -30,10 +30,7 @@ export class SketchFilesTracker extends SketchContribution {
override onReady(): void { override onReady(): void {
this.sketchServiceClient.currentSketch().then(async (sketch) => { this.sketchServiceClient.currentSketch().then(async (sketch) => {
if ( if (CurrentSketch.isValid(sketch)) {
CurrentSketch.isValid(sketch) &&
!(await this.sketchService.isTemp(sketch))
) {
this.toDisposeOnStop.push(this.fileService.watch(new URI(sketch.uri))); this.toDisposeOnStop.push(this.fileService.watch(new URI(sketch.uri)));
this.toDisposeOnStop.push( this.toDisposeOnStop.push(
this.fileService.onDidFilesChange(async (event) => { this.fileService.onDidFilesChange(async (event) => {

View File

@ -1,11 +1,41 @@
import type { MaybePromise } from '@theia/core'; import type { MaybePromise } from '@theia/core';
import type { Widget } from '@theia/core/lib/browser'; import type { Widget } from '@theia/core/lib/browser';
import { WidgetManager as TheiaWidgetManager } from '@theia/core/lib/browser/widget-manager'; import { WidgetManager as TheiaWidgetManager } from '@theia/core/lib/browser/widget-manager';
import { injectable } from '@theia/core/shared/inversify'; import {
inject,
injectable,
postConstruct,
} from '@theia/core/shared/inversify';
import { EditorWidget } from '@theia/editor/lib/browser';
import deepEqual = require('deep-equal'); import deepEqual = require('deep-equal');
import {
CurrentSketch,
SketchesServiceClientImpl,
} from '../../../common/protocol/sketches-service-client-impl';
import { Sketch } from '../../contributions/contribution';
@injectable() @injectable()
export class WidgetManager extends TheiaWidgetManager { export class WidgetManager extends TheiaWidgetManager {
@inject(SketchesServiceClientImpl)
private readonly sketchesServiceClient: SketchesServiceClientImpl;
@postConstruct()
protected init(): void {
this.sketchesServiceClient.onCurrentSketchDidChange((currentSketch) => {
if (CurrentSketch.isValid(currentSketch)) {
const sketchFileUris = new Set(Sketch.uris(currentSketch));
for (const widget of this.widgets.values()) {
if (widget instanceof EditorWidget) {
const uri = widget.editor.uri.toString();
if (sketchFileUris.has(uri)) {
widget.title.closable = false;
}
}
}
}
});
}
/** /**
* Customized to find any existing widget based on `options` deepEquals instead of string equals. * Customized to find any existing widget based on `options` deepEquals instead of string equals.
* See https://github.com/eclipse-theia/theia/issues/11309. * See https://github.com/eclipse-theia/theia/issues/11309.

View File

@ -10,7 +10,7 @@ import { DisposableCollection } from '@theia/core/lib/common/disposable';
import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application'; import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application';
import { Sketch, SketchesService } from '../../common/protocol'; import { Sketch, SketchesService } from '../../common/protocol';
import { ConfigService } from './config-service'; import { ConfigService } from './config-service';
import { SketchContainer, SketchRef } from './sketches-service'; import { SketchContainer, SketchesError, SketchRef } from './sketches-service';
import { import {
ARDUINO_CLOUD_FOLDER, ARDUINO_CLOUD_FOLDER,
REMOTE_SKETCHBOOK_FOLDER, REMOTE_SKETCHBOOK_FOLDER,
@ -79,6 +79,7 @@ export class SketchesServiceClientImpl
this.sketches.set(sketch.uri, sketch); this.sketches.set(sketch.uri, sketch);
} }
this.toDispose.push( this.toDispose.push(
// Watch changes in the sketchbook to update `File` > `Sketchbook` menu items.
this.fileService.watch(new URI(sketchDirUri), { this.fileService.watch(new URI(sketchDirUri), {
recursive: true, recursive: true,
excludes: [], excludes: [],
@ -87,6 +88,34 @@ export class SketchesServiceClientImpl
this.toDispose.push( this.toDispose.push(
this.fileService.onDidFilesChange(async (event) => { this.fileService.onDidFilesChange(async (event) => {
for (const { type, resource } of event.changes) { for (const { type, resource } of event.changes) {
// The file change events have higher precedence in the current sketch over the sketchbook.
if (
CurrentSketch.isValid(this._currentSketch) &&
new URI(this._currentSketch.uri).isEqualOrParent(resource)
) {
if (type === FileChangeType.UPDATED) {
return;
}
let reloadedSketch: Sketch | undefined = undefined;
try {
reloadedSketch = await this.sketchService.loadSketch(
this._currentSketch.uri
);
} catch (err) {
if (!SketchesError.NotFound.is(err)) {
throw err;
}
}
if (!reloadedSketch) {
return;
}
// TODO: check if current is the same as reloaded?
this.useCurrentSketch(reloadedSketch, true);
return;
}
// We track main sketch files changes only. // TODO: check sketch folder changes. One can rename the folder without renaming the `.ino` file. // We track main sketch files changes only. // TODO: check sketch folder changes. One can rename the folder without renaming the `.ino` file.
if (sketchbookUri.isEqualOrParent(resource)) { if (sketchbookUri.isEqualOrParent(resource)) {
if (Sketch.isSketchFile(resource)) { if (Sketch.isSketchFile(resource)) {
@ -125,12 +154,31 @@ export class SketchesServiceClientImpl
.reachedState('started_contributions') .reachedState('started_contributions')
.then(async () => { .then(async () => {
const currentSketch = await this.loadCurrentSketch(); const currentSketch = await this.loadCurrentSketch();
this._currentSketch = currentSketch; if (CurrentSketch.isValid(currentSketch)) {
this.currentSketchDidChangeEmitter.fire(this._currentSketch); this.toDispose.pushAll([
this.currentSketchLoaded.resolve(this._currentSketch); // Watch the file changes of the current sketch
this.fileService.watch(new URI(currentSketch.uri), {
recursive: true,
excludes: [],
}),
]);
}
this.useCurrentSketch(currentSketch);
}); });
} }
private useCurrentSketch(
currentSketch: CurrentSketch,
reassignPromise = false
) {
this._currentSketch = currentSketch;
if (reassignPromise) {
this.currentSketchLoaded = new Deferred();
}
this.currentSketchLoaded.resolve(this._currentSketch);
this.currentSketchDidChangeEmitter.fire(this._currentSketch);
}
onStop(): void { onStop(): void {
this.toDispose.dispose(); this.toDispose.dispose();
} }