Speed up IDE startup time.

Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
This commit is contained in:
Akos Kitta 2022-05-20 12:11:23 +02:00 committed by Akos Kitta
parent cb50d3a70d
commit 4c55807392
179 changed files with 2692 additions and 2022 deletions

2
.gitignore vendored
View File

@ -21,3 +21,5 @@ arduino-ide-extension/data/cli/config
scripts/themes/tokens scripts/themes/tokens
# environment variables # environment variables
.env .env
# content trace files for electron
electron-app/traces

View File

@ -2,5 +2,6 @@
"singleQuote": true, "singleQuote": true,
"tabWidth": 2, "tabWidth": 2,
"useTabs": false, "useTabs": false,
"printWidth": 80 "printWidth": 80,
"endOfLine": "auto"
} }

40
.vscode/launch.json vendored
View File

@ -1,6 +1,44 @@
{ {
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{
"type": "node",
"request": "launch",
"name": "App (Electron) [Dev]",
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron",
"windows": {
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd",
},
"cwd": "${workspaceFolder}/electron-app",
"args": [
".",
"--log-level=debug",
"--hostname=localhost",
"--no-cluster",
"--app-project-path=${workspaceRoot}/electron-app",
"--remote-debugging-port=9222",
"--no-app-auto-install",
"--plugins=local-dir:../plugins",
"--hosted-plugin-inspect=9339",
"--nosplash",
"--content-trace",
"--open-devtools"
],
"env": {
"NODE_ENV": "development"
},
"sourceMaps": true,
"outFiles": [
"${workspaceRoot}/electron-app/src-gen/backend/*.js",
"${workspaceRoot}/electron-app/src-gen/frontend/*.js",
"${workspaceRoot}/electron-app/lib/**/*.js",
"${workspaceRoot}/arduino-ide-extension/lib/**/*.js",
"${workspaceRoot}/node_modules/@theia/**/*.js"
],
"smartStep": true,
"internalConsoleOptions": "openOnSessionStart",
"outputCapture": "std"
},
{ {
"type": "node", "type": "node",
"request": "launch", "request": "launch",
@ -10,7 +48,6 @@
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd", "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd",
}, },
"cwd": "${workspaceFolder}/electron-app", "cwd": "${workspaceFolder}/electron-app",
"protocol": "inspector",
"args": [ "args": [
".", ".",
"--log-level=debug", "--log-level=debug",
@ -78,7 +115,6 @@
{ {
"type": "node", "type": "node",
"request": "launch", "request": "launch",
"protocol": "inspector",
"name": "Run Test [current]", "name": "Run Test [current]",
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha", "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
"args": [ "args": [

View File

@ -21,14 +21,13 @@
"test:watch": "mocha --watch --watch-files lib \"./lib/test/**/*.test.js\"" "test:watch": "mocha --watch --watch-files lib \"./lib/test/**/*.test.js\""
}, },
"dependencies": { "dependencies": {
"@grpc/grpc-js": "^1.3.7", "@grpc/grpc-js": "^1.6.7",
"@theia/application-package": "1.25.0", "@theia/application-package": "1.25.0",
"@theia/core": "1.25.0", "@theia/core": "1.25.0",
"@theia/editor": "1.25.0", "@theia/editor": "1.25.0",
"@theia/editor-preview": "1.25.0", "@theia/editor-preview": "1.25.0",
"@theia/electron": "1.25.0", "@theia/electron": "1.25.0",
"@theia/filesystem": "1.25.0", "@theia/filesystem": "1.25.0",
"@theia/git": "1.25.0",
"@theia/keymaps": "1.25.0", "@theia/keymaps": "1.25.0",
"@theia/markers": "1.25.0", "@theia/markers": "1.25.0",
"@theia/monaco": "1.25.0", "@theia/monaco": "1.25.0",
@ -45,7 +44,7 @@
"@types/btoa": "^1.2.3", "@types/btoa": "^1.2.3",
"@types/dateformat": "^3.0.1", "@types/dateformat": "^3.0.1",
"@types/deepmerge": "^2.2.0", "@types/deepmerge": "^2.2.0",
"@types/glob": "^5.0.35", "@types/glob": "^7.2.0",
"@types/google-protobuf": "^3.7.2", "@types/google-protobuf": "^3.7.2",
"@types/js-yaml": "^3.12.2", "@types/js-yaml": "^3.12.2",
"@types/keytar": "^4.4.0", "@types/keytar": "^4.4.0",
@ -63,14 +62,12 @@
"atob": "^2.1.2", "atob": "^2.1.2",
"auth0-js": "^9.14.0", "auth0-js": "^9.14.0",
"btoa": "^1.2.1", "btoa": "^1.2.1",
"css-element-queries": "^1.2.0",
"dateformat": "^3.0.3", "dateformat": "^3.0.3",
"deepmerge": "2.0.1", "deepmerge": "2.0.1",
"electron-updater": "^4.6.5", "electron-updater": "^4.6.5",
"fuzzy": "^0.1.3", "fast-safe-stringify": "^2.1.1",
"glob": "^7.1.6", "glob": "^7.1.6",
"google-protobuf": "^3.11.4", "google-protobuf": "^3.20.1",
"grpc": "^1.24.11",
"hash.js": "^1.1.7", "hash.js": "^1.1.7",
"is-valid-path": "^0.1.1", "is-valid-path": "^0.1.1",
"js-yaml": "^3.13.1", "js-yaml": "^3.13.1",
@ -91,6 +88,7 @@
"semver": "^7.3.2", "semver": "^7.3.2",
"string-natural-compare": "^2.0.3", "string-natural-compare": "^2.0.3",
"temp": "^0.9.1", "temp": "^0.9.1",
"temp-dir": "^2.0.0",
"tree-kill": "^1.2.1", "tree-kill": "^1.2.1",
"upath": "^1.1.2", "upath": "^1.1.2",
"url": "^0.11.0", "url": "^0.11.0",
@ -157,10 +155,10 @@
], ],
"arduino": { "arduino": {
"cli": { "cli": {
"version": "0.21.0" "version": "0.23.0"
}, },
"fwuploader": { "fwuploader": {
"version": "2.0.0" "version": "2.2.0"
}, },
"clangd": { "clangd": {
"version": "14.0.0" "version": "14.0.0"

View File

@ -4,8 +4,8 @@
const version = '1.9.1'; const version = '1.9.1';
(async () => { (async () => {
const os = require('os'); const os = require('os');
const { promises: fs } = require('fs');
const path = require('path'); const path = require('path');
const shell = require('shelljs'); const shell = require('shelljs');
const { v4 } = require('uuid'); const { v4 } = require('uuid');
@ -13,21 +13,84 @@ const version = '1.9.1';
const repository = path.join(os.tmpdir(), `${v4()}-arduino-examples`); const repository = path.join(os.tmpdir(), `${v4()}-arduino-examples`);
if (shell.mkdir('-p', repository).code !== 0) { if (shell.mkdir('-p', repository).code !== 0) {
shell.exit(1); shell.exit(1);
process.exit(1);
} }
if (shell.exec(`git clone https://github.com/arduino/arduino-examples.git ${repository}`).code !== 0) { if (
shell.exec(
`git clone https://github.com/arduino/arduino-examples.git ${repository}`
).code !== 0
) {
shell.exit(1); shell.exit(1);
process.exit(1);
} }
if (shell.exec(`git -C ${repository} checkout tags/${version} -b ${version}`).code !== 0) { if (
shell.exec(`git -C ${repository} checkout tags/${version} -b ${version}`)
.code !== 0
) {
shell.exit(1); shell.exit(1);
process.exit(1);
} }
const destination = path.join(__dirname, '..', 'Examples'); const destination = path.join(__dirname, '..', 'Examples');
shell.mkdir('-p', destination); shell.mkdir('-p', destination);
shell.cp('-fR', path.join(repository, 'examples', '*'), destination); shell.cp('-fR', path.join(repository, 'examples', '*'), destination);
const isSketch = async (pathLike) => {
try {
const names = await fs.readdir(pathLike);
const dirName = path.basename(pathLike);
return names.indexOf(`${dirName}.ino`) !== -1;
} catch (e) {
if (e.code === 'ENOTDIR') {
return false;
}
throw e;
}
};
const examples = [];
const categories = await fs.readdir(destination);
const visit = async (pathLike, container) => {
const stat = await fs.lstat(pathLike);
if (stat.isDirectory()) {
if (await isSketch(pathLike)) {
container.sketches.push({
name: path.basename(pathLike),
relativePath: path.relative(destination, pathLike),
});
} else {
const names = await fs.readdir(pathLike);
for (const name of names) {
const childPath = path.join(pathLike, name);
if (await isSketch(childPath)) {
container.sketches.push({
name,
relativePath: path.relative(destination, childPath),
});
} else {
const child = {
label: name,
children: [],
sketches: [],
};
container.children.push(child);
await visit(childPath, child);
}
}
}
}
};
for (const category of categories) {
const example = {
label: category,
children: [],
sketches: [],
};
await visit(path.join(destination, category), example);
examples.push(example);
}
await fs.writeFile(
path.join(destination, 'examples.json'),
JSON.stringify(examples, null, 2),
{ encoding: 'utf8' }
);
shell.echo(`Generated output to ${path.join(destination, 'examples.json')}`);
})(); })();

View File

@ -1,4 +1,8 @@
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify'; import {
inject,
injectable,
postConstruct,
} from '@theia/core/shared/inversify';
import * as React from '@theia/core/shared/react'; import * as React from '@theia/core/shared/react';
import * as remote from '@theia/core/electron-shared/@electron/remote'; import * as remote from '@theia/core/electron-shared/@electron/remote';
import { import {
@ -7,6 +11,7 @@ import {
ExecutableService, ExecutableService,
Sketch, Sketch,
LibraryService, LibraryService,
ArduinoDaemon,
} from '../common/protocol'; } from '../common/protocol';
import { Mutex } from 'async-mutex'; import { Mutex } from 'async-mutex';
import { import {
@ -46,18 +51,12 @@ import {
EditorManager, EditorManager,
EditorOpenerOptions, EditorOpenerOptions,
} from '@theia/editor/lib/browser'; } from '@theia/editor/lib/browser';
import { ProblemContribution } from '@theia/markers/lib/browser/problem/problem-contribution';
import { MonacoMenus } from '@theia/monaco/lib/browser/monaco-menu'; import { MonacoMenus } from '@theia/monaco/lib/browser/monaco-menu';
import { FileNavigatorCommands, FileNavigatorContribution } from '@theia/navigator/lib/browser/navigator-contribution'; import { FileNavigatorCommands } from '@theia/navigator/lib/browser/navigator-contribution';
import { OutlineViewContribution } from '@theia/outline-view/lib/browser/outline-view-contribution';
import { OutputContribution } from '@theia/output/lib/browser/output-contribution';
import { ScmContribution } from '@theia/scm/lib/browser/scm-contribution';
import { SearchInWorkspaceFrontendContribution } from '@theia/search-in-workspace/lib/browser/search-in-workspace-frontend-contribution';
import { TerminalMenus } from '@theia/terminal/lib/browser/terminal-frontend-contribution'; import { TerminalMenus } from '@theia/terminal/lib/browser/terminal-frontend-contribution';
import { FileService } from '@theia/filesystem/lib/browser/file-service'; import { FileService } from '@theia/filesystem/lib/browser/file-service';
import { FileChangeType } from '@theia/filesystem/lib/browser'; import { FileChangeType } from '@theia/filesystem/lib/browser';
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state'; import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
import { ConfigService } from '../common/protocol/config-service';
import { ArduinoCommands } from './arduino-commands'; import { ArduinoCommands } from './arduino-commands';
import { BoardsConfig } from './boards/boards-config'; import { BoardsConfig } from './boards/boards-config';
import { BoardsConfigDialog } from './boards/boards-config-dialog'; import { BoardsConfigDialog } from './boards/boards-config-dialog';
@ -68,9 +67,11 @@ import { ArduinoMenus } from './menu/arduino-menus';
import { MonitorViewContribution } from './serial/monitor/monitor-view-contribution'; import { MonitorViewContribution } from './serial/monitor/monitor-view-contribution';
import { ArduinoToolbar } from './toolbar/arduino-toolbar'; import { ArduinoToolbar } from './toolbar/arduino-toolbar';
import { ArduinoPreferences } from './arduino-preferences'; import { ArduinoPreferences } from './arduino-preferences';
import { SketchesServiceClientImpl } from '../common/protocol/sketches-service-client-impl'; import {
CurrentSketch,
SketchesServiceClientImpl,
} from '../common/protocol/sketches-service-client-impl';
import { SaveAsSketch } from './contributions/save-as-sketch'; import { SaveAsSketch } from './contributions/save-as-sketch';
import { SketchbookWidgetContribution } from './widgets/sketchbook/sketchbook-widget-contribution';
import { IDEUpdaterDialog } from './dialogs/ide-updater/ide-updater-dialog'; import { IDEUpdaterDialog } from './dialogs/ide-updater/ide-updater-dialog';
import { IDEUpdater } from '../common/protocol/ide-updater'; import { IDEUpdater } from '../common/protocol/ide-updater';
import { FileSystemFrontendContribution } from '@theia/filesystem/lib/browser/filesystem-frontend-contribution'; import { FileSystemFrontendContribution } from '@theia/filesystem/lib/browser/filesystem-frontend-contribution';
@ -86,93 +87,73 @@ export class ArduinoFrontendContribution
TabBarToolbarContribution, TabBarToolbarContribution,
CommandContribution, CommandContribution,
MenuContribution, MenuContribution,
ColorContribution { ColorContribution
{
@inject(ILogger) @inject(ILogger)
protected logger: ILogger; private readonly logger: ILogger;
@inject(MessageService) @inject(MessageService)
protected readonly messageService: MessageService; private readonly messageService: MessageService;
@inject(BoardsService) @inject(BoardsService)
protected readonly boardsService: BoardsService; private readonly boardsService: BoardsService;
@inject(LibraryService) @inject(LibraryService)
protected readonly libraryService: LibraryService; private readonly libraryService: LibraryService;
@inject(BoardsServiceProvider) @inject(BoardsServiceProvider)
protected readonly boardsServiceClientImpl: BoardsServiceProvider; private readonly boardsServiceClientImpl: BoardsServiceProvider;
@inject(EditorManager) @inject(EditorManager)
protected readonly editorManager: EditorManager; private readonly editorManager: EditorManager;
@inject(FileService) @inject(FileService)
protected readonly fileService: FileService; private readonly fileService: FileService;
@inject(SketchesService) @inject(SketchesService)
protected readonly sketchService: SketchesService; private readonly sketchService: SketchesService;
@inject(BoardsConfigDialog) @inject(BoardsConfigDialog)
protected readonly boardsConfigDialog: BoardsConfigDialog; private readonly boardsConfigDialog: BoardsConfigDialog;
@inject(CommandRegistry) @inject(CommandRegistry)
protected readonly commandRegistry: CommandRegistry; private readonly commandRegistry: CommandRegistry;
@inject(StatusBar) @inject(StatusBar)
protected readonly statusBar: StatusBar; private readonly statusBar: StatusBar;
@inject(FileNavigatorContribution)
protected readonly fileNavigatorContributions: FileNavigatorContribution;
@inject(OutputContribution)
protected readonly outputContribution: OutputContribution;
@inject(OutlineViewContribution)
protected readonly outlineContribution: OutlineViewContribution;
@inject(ProblemContribution)
protected readonly problemContribution: ProblemContribution;
@inject(ScmContribution)
protected readonly scmContribution: ScmContribution;
@inject(SearchInWorkspaceFrontendContribution)
protected readonly siwContribution: SearchInWorkspaceFrontendContribution;
@inject(SketchbookWidgetContribution)
protected readonly sketchbookWidgetContribution: SketchbookWidgetContribution;
@inject(EditorMode) @inject(EditorMode)
protected readonly editorMode: EditorMode; private readonly editorMode: EditorMode;
@inject(ConfigService)
protected readonly configService: ConfigService;
@inject(HostedPluginEvents) @inject(HostedPluginEvents)
protected hostedPluginEvents: HostedPluginEvents; private readonly hostedPluginEvents: HostedPluginEvents;
@inject(ExecutableService) @inject(ExecutableService)
protected executableService: ExecutableService; private readonly executableService: ExecutableService;
@inject(ArduinoPreferences) @inject(ArduinoPreferences)
protected readonly arduinoPreferences: ArduinoPreferences; private readonly arduinoPreferences: ArduinoPreferences;
@inject(SketchesServiceClientImpl) @inject(SketchesServiceClientImpl)
protected readonly sketchServiceClient: SketchesServiceClientImpl; private readonly sketchServiceClient: SketchesServiceClientImpl;
@inject(FrontendApplicationStateService) @inject(FrontendApplicationStateService)
protected readonly appStateService: FrontendApplicationStateService; private readonly appStateService: FrontendApplicationStateService;
@inject(LocalStorageService) @inject(LocalStorageService)
protected readonly localStorageService: LocalStorageService; private readonly localStorageService: LocalStorageService;
@inject(FileSystemFrontendContribution) @inject(FileSystemFrontendContribution)
protected readonly fileSystemFrontendContribution: FileSystemFrontendContribution; private readonly fileSystemFrontendContribution: FileSystemFrontendContribution;
@inject(IDEUpdater) @inject(IDEUpdater)
protected readonly updater: IDEUpdater; private readonly updater: IDEUpdater;
@inject(IDEUpdaterDialog) @inject(IDEUpdaterDialog)
protected readonly updaterDialog: IDEUpdaterDialog; private readonly updaterDialog: IDEUpdaterDialog;
@inject(ArduinoDaemon)
private readonly daemon: ArduinoDaemon;
protected invalidConfigPopup: protected invalidConfigPopup:
| Promise<void | 'No' | 'Yes' | undefined> | Promise<void | 'No' | 'Yes' | undefined>
@ -243,7 +224,10 @@ export class ArduinoFrontendContribution
updateStatusBar(this.boardsServiceClientImpl.boardsConfig); updateStatusBar(this.boardsServiceClientImpl.boardsConfig);
this.appStateService.reachedState('ready').then(async () => { this.appStateService.reachedState('ready').then(async () => {
const sketch = await this.sketchServiceClient.currentSketch(); const sketch = await this.sketchServiceClient.currentSketch();
if (sketch && !(await this.sketchService.isTemp(sketch))) { if (
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) => {
@ -269,21 +253,6 @@ export class ArduinoFrontendContribution
} }
async onStart(app: FrontendApplication): Promise<void> { async onStart(app: FrontendApplication): Promise<void> {
// Initialize all `pro-mode` widgets. This is a NOOP if in normal mode.
for (const viewContribution of [
this.fileNavigatorContributions,
this.outputContribution,
this.outlineContribution,
this.problemContribution,
this.scmContribution,
this.siwContribution,
this.sketchbookWidgetContribution,
] as Array<FrontendApplicationContribution>) {
if (viewContribution.initializeLayout) {
viewContribution.initializeLayout(app);
}
}
this.updater this.updater
.init( .init(
this.arduinoPreferences.get('arduino.ide.updateChannel'), this.arduinoPreferences.get('arduino.ide.updateChannel'),
@ -353,16 +322,18 @@ export class ArduinoFrontendContribution
app.shell.leftPanelHandler.removeBottomMenu('settings-menu'); app.shell.leftPanelHandler.removeBottomMenu('settings-menu');
this.fileSystemFrontendContribution.onDidChangeEditorFile(e => { this.fileSystemFrontendContribution.onDidChangeEditorFile(
if (e.type === FileChangeType.DELETED) { ({ type, editor }) => {
const editorWidget = e.editor; if (type === FileChangeType.DELETED) {
const editorWidget = editor;
if (SaveableWidget.is(editorWidget)) { if (SaveableWidget.is(editorWidget)) {
editorWidget.closeWithoutSaving(); editorWidget.closeWithoutSaving();
} else { } else {
editorWidget.close(); editorWidget.close();
} }
} }
}); }
);
} }
onStop(): void { onStop(): void {
@ -375,6 +346,10 @@ export class ArduinoFrontendContribution
fqbn: string, fqbn: string,
name: string | undefined name: string | undefined
): Promise<void> { ): Promise<void> {
const port = await this.daemon.tryGetPort();
if (!port) {
return;
}
const release = await this.languageServerStartMutex.acquire(); const release = await this.languageServerStartMutex.acquire();
try { try {
await this.hostedPluginEvents.didStart; await this.hostedPluginEvents.didStart;
@ -412,7 +387,7 @@ export class ArduinoFrontendContribution
let currentSketchPath: string | undefined = undefined; let currentSketchPath: string | undefined = undefined;
if (log) { if (log) {
const currentSketch = await this.sketchServiceClient.currentSketch(); const currentSketch = await this.sketchServiceClient.currentSketch();
if (currentSketch) { if (CurrentSketch.isValid(currentSketch)) {
currentSketchPath = await this.fileService.fsPath( currentSketchPath = await this.fileService.fsPath(
new URI(currentSketch.uri) new URI(currentSketch.uri)
); );
@ -424,8 +399,6 @@ export class ArduinoFrontendContribution
this.fileService.fsPath(new URI(lsUri)), this.fileService.fsPath(new URI(lsUri)),
]); ]);
const config = await this.configService.getConfiguration();
this.languageServerFqbn = await Promise.race([ this.languageServerFqbn = await Promise.race([
new Promise<undefined>((_, reject) => new Promise<undefined>((_, reject) =>
setTimeout( setTimeout(
@ -437,7 +410,7 @@ export class ArduinoFrontendContribution
'arduino.languageserver.start', 'arduino.languageserver.start',
{ {
lsPath, lsPath,
cliDaemonAddr: `localhost:${config.daemon.port}`, // TODO: verify if this port is coming from the BE cliDaemonAddr: `localhost:${port}`,
clangdPath, clangdPath,
log: currentSketchPath ? currentSketchPath : log, log: currentSketchPath ? currentSketchPath : log,
cliDaemonInstance: '1', cliDaemonInstance: '1',
@ -503,13 +476,13 @@ export class ArduinoFrontendContribution
EditorCommands.SPLIT_EDITOR_UP, EditorCommands.SPLIT_EDITOR_UP,
EditorCommands.SPLIT_EDITOR_VERTICAL, EditorCommands.SPLIT_EDITOR_VERTICAL,
EditorCommands.SPLIT_EDITOR_HORIZONTAL, EditorCommands.SPLIT_EDITOR_HORIZONTAL,
FileNavigatorCommands.REVEAL_IN_NAVIGATOR FileNavigatorCommands.REVEAL_IN_NAVIGATOR,
]) { ]) {
registry.unregisterCommand(command); registry.unregisterCommand(command);
} }
} }
registerMenus(registry: MenuModelRegistry) { registerMenus(registry: MenuModelRegistry): void {
const menuId = (menuPath: string[]): string => { const menuId = (menuPath: string[]): string => {
const index = menuPath.length - 1; const index = menuPath.length - 1;
const menuId = menuPath[index]; const menuId = menuPath[index];
@ -578,16 +551,19 @@ export class ArduinoFrontendContribution
uri: string, uri: string,
forceOpen = false, forceOpen = false,
options?: EditorOpenerOptions | undefined options?: EditorOpenerOptions | undefined
): Promise<any> { ): Promise<unknown> {
const widget = this.editorManager.all.find( const widget = this.editorManager.all.find(
(widget) => widget.editor.uri.toString() === uri (widget) => widget.editor.uri.toString() === uri
); );
if (!widget || forceOpen) { if (!widget || forceOpen) {
return this.editorManager.open(new URI(uri), options ?? { return this.editorManager.open(
new URI(uri),
options ?? {
mode: 'reveal', mode: 'reveal',
preview: false, preview: false,
counter: 0 counter: 0,
}); }
);
} }
} }
@ -677,13 +653,13 @@ export class ArduinoFrontendContribution
reason: 'temp-sketch', reason: 'temp-sketch',
action: () => { action: () => {
return this.showTempSketchDialog(); return this.showTempSketchDialog();
} },
} };
} }
private async showTempSketchDialog(): Promise<boolean> { private async showTempSketchDialog(): Promise<boolean> {
const sketch = await this.sketchServiceClient.currentSketch(); const sketch = await this.sketchServiceClient.currentSketch();
if (!sketch) { if (!CurrentSketch.isValid(sketch)) {
return true; return true;
} }
const isTemp = await this.sketchService.isTemp(sketch); const isTemp = await this.sketchService.isTemp(sketch);
@ -693,8 +669,14 @@ export class ArduinoFrontendContribution
const messageBoxResult = await remote.dialog.showMessageBox( const messageBoxResult = await remote.dialog.showMessageBox(
remote.getCurrentWindow(), remote.getCurrentWindow(),
{ {
message: nls.localize('arduino/sketch/saveTempSketch', 'Save your sketch to open it again later.'), message: nls.localize(
title: nls.localize('theia/core/quitTitle', 'Are you sure you want to quit?'), 'arduino/sketch/saveTempSketch',
'Save your sketch to open it again later.'
),
title: nls.localize(
'theia/core/quitTitle',
'Are you sure you want to quit?'
),
type: 'question', type: 'question',
buttons: [ buttons: [
Dialog.CANCEL, Dialog.CANCEL,
@ -702,7 +684,7 @@ export class ArduinoFrontendContribution
nls.localizeByDefault("Don't Save"), nls.localizeByDefault("Don't Save"),
], ],
} }
) );
const result = messageBoxResult.response; const result = messageBoxResult.response;
if (result === 2) { if (result === 2) {
return true; return true;
@ -712,10 +694,10 @@ export class ArduinoFrontendContribution
{ {
execOnlyIfTemp: false, execOnlyIfTemp: false,
openAfterMove: false, openAfterMove: false,
wipeOriginal: true wipeOriginal: true,
} }
)); ));
} }
return false return false;
} }
} }

View File

@ -50,7 +50,6 @@ import {
ApplicationShell as TheiaApplicationShell, ApplicationShell as TheiaApplicationShell,
ShellLayoutRestorer as TheiaShellLayoutRestorer, ShellLayoutRestorer as TheiaShellLayoutRestorer,
CommonFrontendContribution as TheiaCommonFrontendContribution, CommonFrontendContribution as TheiaCommonFrontendContribution,
KeybindingRegistry as TheiaKeybindingRegistry,
TabBarRendererFactory, TabBarRendererFactory,
ContextMenuRenderer, ContextMenuRenderer,
createTreeContainer, createTreeContainer,
@ -138,7 +137,6 @@ import { PreferencesContribution } from './theia/preferences/preferences-contrib
import { QuitApp } from './contributions/quit-app'; import { QuitApp } from './contributions/quit-app';
import { SketchControl } from './contributions/sketch-control'; import { SketchControl } from './contributions/sketch-control';
import { Settings } from './contributions/settings'; import { Settings } from './contributions/settings';
import { KeybindingRegistry } from './theia/core/keybindings';
import { WorkspaceCommandContribution } from './theia/workspace/workspace-commands'; import { WorkspaceCommandContribution } from './theia/workspace/workspace-commands';
import { WorkspaceDeleteHandler as TheiaWorkspaceDeleteHandler } from '@theia/workspace/lib/browser/workspace-delete-handler'; import { WorkspaceDeleteHandler as TheiaWorkspaceDeleteHandler } from '@theia/workspace/lib/browser/workspace-delete-handler';
import { WorkspaceDeleteHandler } from './theia/workspace/workspace-delete-handler'; import { WorkspaceDeleteHandler } from './theia/workspace/workspace-delete-handler';
@ -284,8 +282,14 @@ import { Formatter, FormatterPath } from '../common/protocol/formatter';
import { Format } from './contributions/format'; import { Format } from './contributions/format';
import { MonacoFormattingConflictsContribution } from './theia/monaco/monaco-formatting-conflicts'; import { MonacoFormattingConflictsContribution } from './theia/monaco/monaco-formatting-conflicts';
import { MonacoFormattingConflictsContribution as TheiaMonacoFormattingConflictsContribution } from '@theia/monaco/lib/browser/monaco-formatting-conflicts'; import { MonacoFormattingConflictsContribution as TheiaMonacoFormattingConflictsContribution } from '@theia/monaco/lib/browser/monaco-formatting-conflicts';
import { DefaultJsonSchemaContribution } from './theia/core/json-schema-store';
const ElementQueries = require('css-element-queries/src/ElementQueries'); import { DefaultJsonSchemaContribution as TheiaDefaultJsonSchemaContribution } from '@theia/core/lib/browser/json-schema-store';
import { EditorNavigationContribution } from './theia/editor/editor-navigation-contribution';
import { EditorNavigationContribution as TheiaEditorNavigationContribution } from '@theia/editor/lib/browser/editor-navigation-contribution';
import { PreferenceTreeGenerator } from './theia/preferences/preference-tree-generator';
import { PreferenceTreeGenerator as TheiaPreferenceTreeGenerator } from '@theia/preferences/lib/browser/util/preference-tree-generator';
import { AboutDialog } from './theia/core/about-dialog';
import { AboutDialog as TheiaAboutDialog } from '@theia/core/lib/browser/about-dialog';
MonacoThemingService.register({ MonacoThemingService.register({
id: 'arduino-theme', id: 'arduino-theme',
@ -302,9 +306,6 @@ MonacoThemingService.register({
}); });
export default new ContainerModule((bind, unbind, isBound, rebind) => { export default new ContainerModule((bind, unbind, isBound, rebind) => {
ElementQueries.listen();
ElementQueries.init();
// Commands and toolbar items // Commands and toolbar items
bind(ArduinoFrontendContribution).toSelf().inSingletonScope(); bind(ArduinoFrontendContribution).toSelf().inSingletonScope();
bind(CommandContribution).toService(ArduinoFrontendContribution); bind(CommandContribution).toService(ArduinoFrontendContribution);
@ -493,7 +494,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
rebind(TheiaPreferencesContribution) rebind(TheiaPreferencesContribution)
.to(PreferencesContribution) .to(PreferencesContribution)
.inSingletonScope(); .inSingletonScope();
rebind(TheiaKeybindingRegistry).to(KeybindingRegistry).inSingletonScope();
rebind(TheiaWorkspaceCommandContribution) rebind(TheiaWorkspaceCommandContribution)
.to(WorkspaceCommandContribution) .to(WorkspaceCommandContribution)
.inSingletonScope(); .inSingletonScope();
@ -714,6 +714,26 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
bind(NavigatorTabBarDecorator).toSelf().inSingletonScope(); bind(NavigatorTabBarDecorator).toSelf().inSingletonScope();
rebind(TheiaNavigatorTabBarDecorator).toService(NavigatorTabBarDecorator); rebind(TheiaNavigatorTabBarDecorator).toService(NavigatorTabBarDecorator);
// Do not fetch the `catalog.json` from Azure on FE load.
bind(DefaultJsonSchemaContribution).toSelf().inSingletonScope();
rebind(TheiaDefaultJsonSchemaContribution).toService(
DefaultJsonSchemaContribution
);
// Do not block the app startup when initializing the editor navigation history.
bind(EditorNavigationContribution).toSelf().inSingletonScope();
rebind(TheiaEditorNavigationContribution).toService(
EditorNavigationContribution
);
// IDE2 does not use the Theia preferences widget, no need to create and sync the underlying tree model.
bind(PreferenceTreeGenerator).toSelf().inSingletonScope();
rebind(TheiaPreferenceTreeGenerator).toService(PreferenceTreeGenerator);
// IDE2 has a custom about dialog, so there is no need to load the Theia extensions on FE load
bind(AboutDialog).toSelf().inSingletonScope();
rebind(TheiaAboutDialog).toService(AboutDialog);
// To avoid running `Save All` when there are no dirty editors before starting the debug session. // To avoid running `Save All` when there are no dirty editors before starting the debug session.
bind(DebugSessionManager).toSelf().inSingletonScope(); bind(DebugSessionManager).toSelf().inSingletonScope();
rebind(TheiaDebugSessionManager).toService(DebugSessionManager); rebind(TheiaDebugSessionManager).toService(DebugSessionManager);

View File

@ -55,12 +55,13 @@ export class BoardsConfigDialogWidget extends ReactWidget {
onConfigChange={this.fireConfigChanged} onConfigChange={this.fireConfigChanged}
onFocusNodeSet={this.setFocusNode} onFocusNodeSet={this.setFocusNode}
onFilteredTextDidChangeEvent={this.onFilterTextDidChangeEmitter.event} onFilteredTextDidChangeEvent={this.onFilterTextDidChangeEmitter.event}
onAppStateDidChange={this.notificationCenter.onAppStateDidChange}
/> />
</div> </div>
); );
} }
protected onActivateRequest(msg: Message): void { protected override onActivateRequest(msg: Message): void {
super.onActivateRequest(msg); super.onActivateRequest(msg);
if (this.focusNode instanceof HTMLInputElement) { if (this.focusNode instanceof HTMLInputElement) {
this.focusNode.select(); this.focusNode.select();

View File

@ -26,7 +26,7 @@ export class BoardsConfigDialog extends AbstractDialog<BoardsConfig.Config> {
constructor( constructor(
@inject(BoardsConfigDialogProps) @inject(BoardsConfigDialogProps)
protected readonly props: BoardsConfigDialogProps protected override readonly props: BoardsConfigDialogProps
) { ) {
super(props); super(props);
@ -52,7 +52,7 @@ export class BoardsConfigDialog extends AbstractDialog<BoardsConfig.Config> {
/** /**
* Pass in an empty string if you want to reset the search term. Using `undefined` has no effect. * Pass in an empty string if you want to reset the search term. Using `undefined` has no effect.
*/ */
async open( override async open(
query: string | undefined = undefined query: string | undefined = undefined
): Promise<BoardsConfig.Config | undefined> { ): Promise<BoardsConfig.Config | undefined> {
if (typeof query === 'string') { if (typeof query === 'string') {
@ -95,7 +95,7 @@ export class BoardsConfigDialog extends AbstractDialog<BoardsConfig.Config> {
return head; return head;
} }
protected onAfterAttach(msg: Message): void { protected override onAfterAttach(msg: Message): void {
if (this.widget.isAttached) { if (this.widget.isAttached) {
Widget.detach(this.widget); Widget.detach(this.widget);
} }
@ -110,23 +110,23 @@ export class BoardsConfigDialog extends AbstractDialog<BoardsConfig.Config> {
this.update(); this.update();
} }
protected onUpdateRequest(msg: Message) { protected override onUpdateRequest(msg: Message): void {
super.onUpdateRequest(msg); super.onUpdateRequest(msg);
this.widget.update(); this.widget.update();
} }
protected onActivateRequest(msg: Message): void { protected override onActivateRequest(msg: Message): void {
super.onActivateRequest(msg); super.onActivateRequest(msg);
this.widget.activate(); this.widget.activate();
} }
protected handleEnter(event: KeyboardEvent): boolean | void { protected override handleEnter(event: KeyboardEvent): boolean | void {
if (event.target instanceof HTMLTextAreaElement) { if (event.target instanceof HTMLTextAreaElement) {
return false; return false;
} }
} }
protected isValid(value: BoardsConfig.Config): DialogError { protected override isValid(value: BoardsConfig.Config): DialogError {
if (!value.selectedBoard) { if (!value.selectedBoard) {
if (value.selectedPort) { if (value.selectedPort) {
return nls.localize( return nls.localize(

View File

@ -16,6 +16,7 @@ import {
} from './boards-service-provider'; } from './boards-service-provider';
import { naturalCompare } from '../../common/utils'; import { naturalCompare } from '../../common/utils';
import { nls } from '@theia/core/lib/common'; import { nls } from '@theia/core/lib/common';
import { FrontendApplicationState } from '@theia/core/lib/common/frontend-application-state';
export namespace BoardsConfig { export namespace BoardsConfig {
export interface Config { export interface Config {
@ -29,6 +30,7 @@ export namespace BoardsConfig {
readonly onConfigChange: (config: Config) => void; readonly onConfigChange: (config: Config) => void;
readonly onFocusNodeSet: (element: HTMLElement | undefined) => void; readonly onFocusNodeSet: (element: HTMLElement | undefined) => void;
readonly onFilteredTextDidChangeEvent: Event<string>; readonly onFilteredTextDidChangeEvent: Event<string>;
readonly onAppStateDidChange: Event<FrontendApplicationState>;
} }
export interface State extends Config { export interface State extends Config {
@ -47,7 +49,7 @@ export abstract class Item<T> extends React.Component<{
missing?: boolean; missing?: boolean;
details?: string; details?: string;
}> { }> {
render(): React.ReactNode { override render(): React.ReactNode {
const { selected, label, missing, details } = this.props; const { selected, label, missing, details } = this.props;
const classNames = ['item']; const classNames = ['item'];
if (selected) { if (selected) {
@ -99,14 +101,18 @@ export class BoardsConfig extends React.Component<
}; };
} }
componentDidMount() { override componentDidMount(): void {
this.toDispose.pushAll([
this.props.onAppStateDidChange((state) => {
if (state === 'ready') {
this.updateBoards(); this.updateBoards();
this.updatePorts( this.updatePorts(
this.props.boardsServiceProvider.availableBoards this.props.boardsServiceProvider.availableBoards
.map(({ port }) => port) .map(({ port }) => port)
.filter(notEmpty) .filter(notEmpty)
); );
this.toDispose.pushAll([ }
}),
this.props.notificationCenter.onAttachedBoardsChanged((event) => this.props.notificationCenter.onAttachedBoardsChanged((event) =>
this.updatePorts( this.updatePorts(
event.newState.ports, event.newState.ports,
@ -141,11 +147,11 @@ export class BoardsConfig extends React.Component<
]); ]);
} }
componentWillUnmount(): void { override componentWillUnmount(): void {
this.toDispose.dispose(); this.toDispose.dispose();
} }
protected fireConfigChanged() { protected fireConfigChanged(): void {
const { selectedBoard, selectedPort } = this.state; const { selectedBoard, selectedPort } = this.state;
this.props.onConfigChange({ selectedBoard, selectedPort }); this.props.onConfigChange({ selectedBoard, selectedPort });
} }
@ -250,7 +256,7 @@ export class BoardsConfig extends React.Component<
this.props.onFocusNodeSet(element || undefined); this.props.onFocusNodeSet(element || undefined);
}; };
render(): React.ReactNode { override render(): React.ReactNode {
return ( return (
<div className="body"> <div className="body">
{this.renderContainer('boards', this.renderBoards.bind(this))} {this.renderContainer('boards', this.renderBoards.bind(this))}

View File

@ -13,6 +13,7 @@ import { BoardsDataStore } from './boards-data-store';
import { MainMenuManager } from '../../common/main-menu-manager'; import { MainMenuManager } from '../../common/main-menu-manager';
import { ArduinoMenus, unregisterSubmenu } from '../menu/arduino-menus'; import { ArduinoMenus, unregisterSubmenu } from '../menu/arduino-menus';
import { nls } from '@theia/core/lib/common'; import { nls } from '@theia/core/lib/common';
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
@injectable() @injectable()
export class BoardsDataMenuUpdater implements FrontendApplicationContribution { export class BoardsDataMenuUpdater implements FrontendApplicationContribution {
@ -31,11 +32,20 @@ export class BoardsDataMenuUpdater implements FrontendApplicationContribution {
@inject(BoardsServiceProvider) @inject(BoardsServiceProvider)
protected readonly boardsServiceClient: BoardsServiceProvider; protected readonly boardsServiceClient: BoardsServiceProvider;
@inject(FrontendApplicationStateService)
private readonly appStateService: FrontendApplicationStateService;
protected readonly queue = new PQueue({ autoStart: true, concurrency: 1 }); protected readonly queue = new PQueue({ autoStart: true, concurrency: 1 });
protected readonly toDisposeOnBoardChange = new DisposableCollection(); protected readonly toDisposeOnBoardChange = new DisposableCollection();
async onStart(): Promise<void> { async onStart(): Promise<void> {
this.updateMenuActions(this.boardsServiceClient.boardsConfig.selectedBoard); this.appStateService
.reachedState('ready')
.then(() =>
this.updateMenuActions(
this.boardsServiceClient.boardsConfig.selectedBoard
)
);
this.boardsDataStore.onChanged(() => this.boardsDataStore.onChanged(() =>
this.updateMenuActions( this.updateMenuActions(
this.boardsServiceClient.boardsConfig.selectedBoard this.boardsServiceClient.boardsConfig.selectedBoard

View File

@ -30,7 +30,7 @@ export class BoardsListWidget extends ListWidget<BoardsPackage> {
} }
@postConstruct() @postConstruct()
protected init(): void { protected override init(): void {
super.init(); super.init();
this.toDispose.pushAll([ this.toDispose.pushAll([
this.notificationCenter.onPlatformInstalled(() => this.notificationCenter.onPlatformInstalled(() =>
@ -42,7 +42,7 @@ export class BoardsListWidget extends ListWidget<BoardsPackage> {
]); ]);
} }
protected async install({ protected override async install({
item, item,
progressId, progressId,
version, version,
@ -63,7 +63,7 @@ export class BoardsListWidget extends ListWidget<BoardsPackage> {
); );
} }
protected async uninstall({ protected override async uninstall({
item, item,
progressId, progressId,
}: { }: {

View File

@ -41,7 +41,7 @@ export class BoardsDropDown extends React.Component<BoardsDropDown.Props> {
} }
} }
render(): React.ReactNode { override render(): React.ReactNode {
return ReactDOM.createPortal(this.renderNode(), this.dropdownElement); return ReactDOM.createPortal(this.renderNode(), this.dropdownElement);
} }
@ -130,13 +130,13 @@ export class BoardsToolBarItem extends React.Component<
}); });
} }
componentDidMount() { override componentDidMount(): void {
this.props.boardsServiceClient.onAvailableBoardsChanged((availableBoards) => this.props.boardsServiceClient.onAvailableBoardsChanged((availableBoards) =>
this.setState({ availableBoards }) this.setState({ availableBoards })
); );
} }
componentWillUnmount(): void { override componentWillUnmount(): void {
this.toDispose.dispose(); this.toDispose.dispose();
} }
@ -161,7 +161,7 @@ export class BoardsToolBarItem extends React.Component<
event.nativeEvent.stopImmediatePropagation(); event.nativeEvent.stopImmediatePropagation();
}; };
render(): React.ReactNode { override render(): React.ReactNode {
const { coords, availableBoards } = this.state; const { coords, availableBoards } = this.state;
const boardsConfig = this.props.boardsServiceClient.boardsConfig; const boardsConfig = this.props.boardsServiceClient.boardsConfig;
const title = BoardsConfig.Config.toString(boardsConfig, { const title = BoardsConfig.Config.toString(boardsConfig, {

View File

@ -18,7 +18,7 @@ export class BoardsListWidgetFrontendContribution extends ListWidgetFrontendCont
}); });
} }
async initializeLayout(): Promise<void> { override async initializeLayout(): Promise<void> {
this.openView(); this.openView();
} }
} }

View File

@ -22,13 +22,13 @@ export class About extends Contribution {
@inject(ConfigService) @inject(ConfigService)
protected readonly configService: ConfigService; protected readonly configService: ConfigService;
registerCommands(registry: CommandRegistry): void { override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(About.Commands.ABOUT_APP, { registry.registerCommand(About.Commands.ABOUT_APP, {
execute: () => this.showAbout(), execute: () => this.showAbout(),
}); });
} }
registerMenus(registry: MenuModelRegistry): void { override registerMenus(registry: MenuModelRegistry): void {
registry.registerMenuAction(ArduinoMenus.HELP__ABOUT_GROUP, { registry.registerMenuAction(ArduinoMenus.HELP__ABOUT_GROUP, {
commandId: About.Commands.ABOUT_APP.id, commandId: About.Commands.ABOUT_APP.id,
label: nls.localize( label: nls.localize(

View File

@ -10,19 +10,20 @@ import {
} from './contribution'; } from './contribution';
import { FileDialogService } from '@theia/filesystem/lib/browser'; import { FileDialogService } from '@theia/filesystem/lib/browser';
import { nls } from '@theia/core/lib/common'; import { nls } from '@theia/core/lib/common';
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
@injectable() @injectable()
export class AddFile extends SketchContribution { export class AddFile extends SketchContribution {
@inject(FileDialogService) @inject(FileDialogService)
protected readonly fileDialogService: FileDialogService; protected readonly fileDialogService: FileDialogService;
registerCommands(registry: CommandRegistry): void { override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(AddFile.Commands.ADD_FILE, { registry.registerCommand(AddFile.Commands.ADD_FILE, {
execute: () => this.addFile(), execute: () => this.addFile(),
}); });
} }
registerMenus(registry: MenuModelRegistry): void { override registerMenus(registry: MenuModelRegistry): void {
registry.registerMenuAction(ArduinoMenus.SKETCH__UTILS_GROUP, { registry.registerMenuAction(ArduinoMenus.SKETCH__UTILS_GROUP, {
commandId: AddFile.Commands.ADD_FILE.id, commandId: AddFile.Commands.ADD_FILE.id,
label: nls.localize('arduino/contributions/addFile', 'Add File') + '...', label: nls.localize('arduino/contributions/addFile', 'Add File') + '...',
@ -32,7 +33,7 @@ export class AddFile extends SketchContribution {
protected async addFile(): Promise<void> { protected async addFile(): Promise<void> {
const sketch = await this.sketchServiceClient.currentSketch(); const sketch = await this.sketchServiceClient.currentSketch();
if (!sketch) { if (!CurrentSketch.isValid(sketch)) {
return; return;
} }
const toAddUri = await this.fileDialogService.showOpenDialog({ const toAddUri = await this.fileDialogService.showOpenDialog({

View File

@ -28,13 +28,13 @@ export class AddZipLibrary extends SketchContribution {
@inject(LibraryService) @inject(LibraryService)
protected readonly libraryService: LibraryService; protected readonly libraryService: LibraryService;
registerCommands(registry: CommandRegistry): void { override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(AddZipLibrary.Commands.ADD_ZIP_LIBRARY, { registry.registerCommand(AddZipLibrary.Commands.ADD_ZIP_LIBRARY, {
execute: () => this.addZipLibrary(), execute: () => this.addZipLibrary(),
}); });
} }
registerMenus(registry: MenuModelRegistry): void { override registerMenus(registry: MenuModelRegistry): void {
const includeLibMenuPath = [ const includeLibMenuPath = [
...ArduinoMenus.SKETCH__UTILS_GROUP, ...ArduinoMenus.SKETCH__UTILS_GROUP,
'0_include', '0_include',

View File

@ -10,16 +10,17 @@ import {
MenuModelRegistry, MenuModelRegistry,
} from './contribution'; } from './contribution';
import { nls } from '@theia/core/lib/common'; import { nls } from '@theia/core/lib/common';
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
@injectable() @injectable()
export class ArchiveSketch extends SketchContribution { export class ArchiveSketch extends SketchContribution {
registerCommands(registry: CommandRegistry): void { override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(ArchiveSketch.Commands.ARCHIVE_SKETCH, { registry.registerCommand(ArchiveSketch.Commands.ARCHIVE_SKETCH, {
execute: () => this.archiveSketch(), execute: () => this.archiveSketch(),
}); });
} }
registerMenus(registry: MenuModelRegistry): void { override registerMenus(registry: MenuModelRegistry): void {
registry.registerMenuAction(ArduinoMenus.TOOLS__MAIN_GROUP, { registry.registerMenuAction(ArduinoMenus.TOOLS__MAIN_GROUP, {
commandId: ArchiveSketch.Commands.ARCHIVE_SKETCH.id, commandId: ArchiveSketch.Commands.ARCHIVE_SKETCH.id,
label: nls.localize('arduino/sketch/archiveSketch', 'Archive Sketch'), label: nls.localize('arduino/sketch/archiveSketch', 'Archive Sketch'),
@ -32,7 +33,7 @@ export class ArchiveSketch extends SketchContribution {
this.sketchServiceClient.currentSketch(), this.sketchServiceClient.currentSketch(),
this.configService.getConfiguration(), this.configService.getConfiguration(),
]); ]);
if (!sketch) { if (!CurrentSketch.isValid(sketch)) {
return; return;
} }
const archiveBasename = `${sketch.name}-${dateFormat( const archiveBasename = `${sketch.name}-${dateFormat(

View File

@ -47,7 +47,7 @@ export class BoardSelection extends SketchContribution {
protected readonly toDisposeBeforeMenuRebuild = new DisposableCollection(); protected readonly toDisposeBeforeMenuRebuild = new DisposableCollection();
registerCommands(registry: CommandRegistry): void { override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(BoardSelection.Commands.GET_BOARD_INFO, { registry.registerCommand(BoardSelection.Commands.GET_BOARD_INFO, {
execute: async () => { execute: async () => {
const { selectedBoard, selectedPort } = const { selectedBoard, selectedPort } =
@ -100,19 +100,20 @@ PID: ${PID}`;
}); });
} }
onStart(): void { override onStart(): void {
this.notificationCenter.onPlatformInstalled(() => this.updateMenus());
this.notificationCenter.onPlatformUninstalled(() => this.updateMenus());
this.boardsServiceProvider.onBoardsConfigChanged(() => this.updateMenus());
this.boardsServiceProvider.onAvailableBoardsChanged(() =>
this.updateMenus()
);
this.boardsServiceProvider.onAvailablePortsChanged(() =>
this.updateMenus()
);
}
override async onReady(): Promise<void> {
this.updateMenus(); this.updateMenus();
this.notificationCenter.onPlatformInstalled(this.updateMenus.bind(this));
this.notificationCenter.onPlatformUninstalled(this.updateMenus.bind(this));
this.boardsServiceProvider.onBoardsConfigChanged(
this.updateMenus.bind(this)
);
this.boardsServiceProvider.onAvailableBoardsChanged(
this.updateMenus.bind(this)
);
this.boardsServiceProvider.onAvailablePortsChanged(
this.updateMenus.bind(this)
);
} }
protected async updateMenus(): Promise<void> { protected async updateMenus(): Promise<void> {

View File

@ -28,15 +28,15 @@ export class BurnBootloader extends SketchContribution {
protected readonly boardsServiceClientImpl: BoardsServiceProvider; protected readonly boardsServiceClientImpl: BoardsServiceProvider;
@inject(OutputChannelManager) @inject(OutputChannelManager)
protected readonly outputChannelManager: OutputChannelManager; protected override readonly outputChannelManager: OutputChannelManager;
registerCommands(registry: CommandRegistry): void { override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(BurnBootloader.Commands.BURN_BOOTLOADER, { registry.registerCommand(BurnBootloader.Commands.BURN_BOOTLOADER, {
execute: () => this.burnBootloader(), execute: () => this.burnBootloader(),
}); });
} }
registerMenus(registry: MenuModelRegistry): void { override registerMenus(registry: MenuModelRegistry): void {
registry.registerMenuAction(ArduinoMenus.TOOLS__BOARD_SETTINGS_GROUP, { registry.registerMenuAction(ArduinoMenus.TOOLS__BOARD_SETTINGS_GROUP, {
commandId: BurnBootloader.Commands.BURN_BOOTLOADER.id, commandId: BurnBootloader.Commands.BURN_BOOTLOADER.id,
label: nls.localize( label: nls.localize(

View File

@ -21,21 +21,21 @@ import { nls } from '@theia/core/lib/common';
@injectable() @injectable()
export class Close extends SketchContribution { export class Close extends SketchContribution {
@inject(EditorManager) @inject(EditorManager)
protected readonly editorManager: EditorManager; protected override readonly editorManager: EditorManager;
protected shell: ApplicationShell; protected shell: ApplicationShell;
onStart(app: FrontendApplication): void { override onStart(app: FrontendApplication): void {
this.shell = app.shell; this.shell = app.shell;
} }
registerCommands(registry: CommandRegistry): void { override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(Close.Commands.CLOSE, { registry.registerCommand(Close.Commands.CLOSE, {
execute: () => remote.getCurrentWindow().close() execute: () => remote.getCurrentWindow().close()
}); });
} }
registerMenus(registry: MenuModelRegistry): void { override registerMenus(registry: MenuModelRegistry): void {
registry.registerMenuAction(ArduinoMenus.FILE__SKETCH_GROUP, { registry.registerMenuAction(ArduinoMenus.FILE__SKETCH_GROUP, {
commandId: Close.Commands.CLOSE.id, commandId: Close.Commands.CLOSE.id,
label: nls.localize('vscode/editor.contribution/close', 'Close'), label: nls.localize('vscode/editor.contribution/close', 'Close'),
@ -43,7 +43,7 @@ export class Close extends SketchContribution {
}); });
} }
registerKeybindings(registry: KeybindingRegistry): void { override registerKeybindings(registry: KeybindingRegistry): void {
registry.registerKeybinding({ registry.registerKeybinding({
command: Close.Commands.CLOSE.id, command: Close.Commands.CLOSE.id,
keybinding: 'CtrlCmd+W', keybinding: 'CtrlCmd+W',

View File

@ -1,4 +1,9 @@
import { inject, injectable, interfaces } from '@theia/core/shared/inversify'; import {
inject,
injectable,
interfaces,
postConstruct,
} from '@theia/core/shared/inversify';
import URI from '@theia/core/lib/common/uri'; import URI from '@theia/core/lib/common/uri';
import { ILogger } from '@theia/core/lib/common/logger'; import { ILogger } from '@theia/core/lib/common/logger';
import { Saveable } from '@theia/core/lib/browser/saveable'; import { Saveable } from '@theia/core/lib/browser/saveable';
@ -34,7 +39,10 @@ import {
} from '@theia/core/lib/common/command'; } from '@theia/core/lib/common/command';
import { EditorMode } from '../editor-mode'; import { EditorMode } from '../editor-mode';
import { SettingsService } from '../dialogs/settings/settings'; import { SettingsService } from '../dialogs/settings/settings';
import { SketchesServiceClientImpl } from '../../common/protocol/sketches-service-client-impl'; import {
CurrentSketch,
SketchesServiceClientImpl,
} from '../../common/protocol/sketches-service-client-impl';
import { import {
SketchesService, SketchesService,
ConfigService, ConfigService,
@ -42,6 +50,7 @@ import {
Sketch, Sketch,
} from '../../common/protocol'; } from '../../common/protocol';
import { ArduinoPreferences } from '../arduino-preferences'; import { ArduinoPreferences } from '../arduino-preferences';
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
export { export {
Command, Command,
@ -84,15 +93,31 @@ export abstract class Contribution
@inject(SettingsService) @inject(SettingsService)
protected readonly settingsService: SettingsService; protected readonly settingsService: SettingsService;
@inject(FrontendApplicationStateService)
protected readonly appStateService: FrontendApplicationStateService;
@postConstruct()
protected init(): void {
this.appStateService.reachedState('ready').then(() => this.onReady());
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function, unused-imports/no-unused-vars
onStart(app: FrontendApplication): MaybePromise<void> {} onStart(app: FrontendApplication): MaybePromise<void> {}
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function, unused-imports/no-unused-vars
registerCommands(registry: CommandRegistry): void {} registerCommands(registry: CommandRegistry): void {}
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function, unused-imports/no-unused-vars
registerMenus(registry: MenuModelRegistry): void {} registerMenus(registry: MenuModelRegistry): void {}
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function, unused-imports/no-unused-vars
registerKeybindings(registry: KeybindingRegistry): void {} registerKeybindings(registry: KeybindingRegistry): void {}
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function, unused-imports/no-unused-vars
registerToolbarItems(registry: TabBarToolbarRegistry): void {} registerToolbarItems(registry: TabBarToolbarRegistry): void {}
// eslint-disable-next-line @typescript-eslint/no-empty-function
onReady(): MaybePromise<void> {}
} }
@injectable() @injectable()
@ -127,7 +152,7 @@ export abstract class SketchContribution extends Contribution {
protected async sourceOverride(): Promise<Record<string, string>> { protected async sourceOverride(): Promise<Record<string, string>> {
const override: Record<string, string> = {}; const override: Record<string, string> = {};
const sketch = await this.sketchServiceClient.currentSketch(); const sketch = await this.sketchServiceClient.currentSketch();
if (sketch) { if (CurrentSketch.isValid(sketch)) {
for (const editor of this.editorManager.all) { for (const editor of this.editorManager.all) {
const uri = editor.editor.uri; const uri = editor.editor.uri;
if (Saveable.isDirty(editor) && Sketch.isInSketch(uri, sketch)) { if (Saveable.isDirty(editor) && Sketch.isInSketch(uri, sketch)) {
@ -140,7 +165,7 @@ export abstract class SketchContribution extends Contribution {
} }
export namespace Contribution { export namespace Contribution {
export function configure<T>( export function configure(
bind: interfaces.Bind, bind: interfaces.Bind,
serviceIdentifier: typeof Contribution serviceIdentifier: typeof Contribution
): void { ): void {

View File

@ -12,7 +12,8 @@ import {
SketchContribution, SketchContribution,
TabBarToolbarRegistry, TabBarToolbarRegistry,
} from './contribution'; } from './contribution';
import { nls } from '@theia/core/lib/common'; import { MaybePromise, nls } from '@theia/core/lib/common';
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
@injectable() @injectable()
export class Debug extends SketchContribution { export class Debug extends SketchContribution {
@ -66,7 +67,7 @@ export class Debug extends SketchContribution {
onDidChange: this.onDisabledMessageDidChange as Event<void>, onDidChange: this.onDisabledMessageDidChange as Event<void>,
}; };
onStart(): void { override onStart(): void {
this.onDisabledMessageDidChange( this.onDisabledMessageDidChange(
() => () =>
(this.debugToolbarItem.tooltip = `${ (this.debugToolbarItem.tooltip = `${
@ -79,10 +80,34 @@ export class Debug extends SketchContribution {
: Debug.Commands.START_DEBUGGING.label : Debug.Commands.START_DEBUGGING.label
}`) }`)
); );
const refreshState = async ( this.boardsServiceProvider.onBoardsConfigChanged(({ selectedBoard }) =>
this.refreshState(selectedBoard)
);
this.notificationCenter.onPlatformInstalled(() => this.refreshState());
this.notificationCenter.onPlatformUninstalled(() => this.refreshState());
}
override onReady(): MaybePromise<void> {
this.refreshState();
}
override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(Debug.Commands.START_DEBUGGING, {
execute: () => this.startDebug(),
isVisible: (widget) =>
ArduinoToolbar.is(widget) && widget.side === 'left',
isEnabled: () => !this.disabledMessage,
});
}
override registerToolbarItems(registry: TabBarToolbarRegistry): void {
registry.registerItem(this.debugToolbarItem);
}
private async refreshState(
board: Board | undefined = this.boardsServiceProvider.boardsConfig board: Board | undefined = this.boardsServiceProvider.boardsConfig
.selectedBoard .selectedBoard
) => { ): Promise<void> {
if (!board) { if (!board) {
this.disabledMessage = nls.localize( this.disabledMessage = nls.localize(
'arduino/common/noBoardSelected', 'arduino/common/noBoardSelected',
@ -118,26 +143,6 @@ export class Debug extends SketchContribution {
} else { } else {
this.disabledMessage = undefined; this.disabledMessage = undefined;
} }
};
this.boardsServiceProvider.onBoardsConfigChanged(({ selectedBoard }) =>
refreshState(selectedBoard)
);
this.notificationCenter.onPlatformInstalled(() => refreshState());
this.notificationCenter.onPlatformUninstalled(() => refreshState());
refreshState();
}
registerCommands(registry: CommandRegistry): void {
registry.registerCommand(Debug.Commands.START_DEBUGGING, {
execute: () => this.startDebug(),
isVisible: (widget) =>
ArduinoToolbar.is(widget) && widget.side === 'left',
isEnabled: () => !this.disabledMessage,
});
}
registerToolbarItems(registry: TabBarToolbarRegistry): void {
registry.registerItem(this.debugToolbarItem);
} }
protected async startDebug( protected async startDebug(
@ -156,7 +161,7 @@ export class Debug extends SketchContribution {
this.sketchServiceClient.currentSketch(), this.sketchServiceClient.currentSketch(),
this.executableService.list(), this.executableService.list(),
]); ]);
if (!sketch) { if (!CurrentSketch.isValid(sketch)) {
return; return;
} }
const ideTempFolderUri = await this.sketchService.getIdeTempFolderUri( const ideTempFolderUri = await this.sketchService.getIdeTempFolderUri(

View File

@ -28,7 +28,7 @@ export class EditContributions extends Contribution {
@inject(PreferenceService) @inject(PreferenceService)
protected readonly preferences: PreferenceService; protected readonly preferences: PreferenceService;
registerCommands(registry: CommandRegistry): void { override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(EditContributions.Commands.GO_TO_LINE, { registry.registerCommand(EditContributions.Commands.GO_TO_LINE, {
execute: () => this.run('editor.action.gotoLine'), execute: () => this.run('editor.action.gotoLine'),
}); });
@ -93,7 +93,7 @@ ${value}
}); });
} }
registerMenus(registry: MenuModelRegistry): void { override registerMenus(registry: MenuModelRegistry): void {
registry.registerMenuAction(ArduinoMenus.EDIT__TEXT_CONTROL_GROUP, { registry.registerMenuAction(ArduinoMenus.EDIT__TEXT_CONTROL_GROUP, {
commandId: CommonCommands.CUT.id, commandId: CommonCommands.CUT.id,
order: '0', order: '0',
@ -201,7 +201,7 @@ ${value}
}); });
} }
registerKeybindings(registry: KeybindingRegistry): void { override registerKeybindings(registry: KeybindingRegistry): void {
registry.registerKeybinding({ registry.registerKeybinding({
command: EditContributions.Commands.COPY_FOR_FORUM.id, command: EditContributions.Commands.COPY_FOR_FORUM.id,
keybinding: 'CtrlCmd+Shift+C', keybinding: 'CtrlCmd+Shift+C',

View File

@ -1,5 +1,5 @@
import * as PQueue from 'p-queue'; import * as PQueue from 'p-queue';
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify'; import { inject, injectable } from '@theia/core/shared/inversify';
import { CommandHandler } from '@theia/core/lib/common/command'; import { CommandHandler } from '@theia/core/lib/common/command';
import { import {
MenuPath, MenuPath,
@ -21,7 +21,7 @@ import {
MenuModelRegistry, MenuModelRegistry,
} from './contribution'; } from './contribution';
import { NotificationCenter } from '../notification-center'; import { NotificationCenter } from '../notification-center';
import { Board, Sketch, SketchContainer } from '../../common/protocol'; import { Board, SketchRef, SketchContainer } from '../../common/protocol';
import { nls } from '@theia/core/lib/common'; import { nls } from '@theia/core/lib/common';
@injectable() @injectable()
@ -43,8 +43,8 @@ export abstract class Examples extends SketchContribution {
protected readonly toDispose = new DisposableCollection(); protected readonly toDispose = new DisposableCollection();
@postConstruct() protected override init(): void {
init(): void { super.init();
this.boardsServiceClient.onBoardsConfigChanged(({ selectedBoard }) => this.boardsServiceClient.onBoardsConfigChanged(({ selectedBoard }) =>
this.handleBoardChanged(selectedBoard) this.handleBoardChanged(selectedBoard)
); );
@ -54,7 +54,7 @@ export abstract class Examples extends SketchContribution {
// NOOP // NOOP
} }
registerMenus(registry: MenuModelRegistry): void { override registerMenus(registry: MenuModelRegistry): void {
try { try {
// This is a hack the ensures the desired menu ordering! We cannot use https://github.com/eclipse-theia/theia/pull/8377 due to ATL-222. // This is a hack the ensures the desired menu ordering! We cannot use https://github.com/eclipse-theia/theia/pull/8377 due to ATL-222.
const index = ArduinoMenus.FILE__EXAMPLES_SUBMENU.length - 1; const index = ArduinoMenus.FILE__EXAMPLES_SUBMENU.length - 1;
@ -82,7 +82,7 @@ export abstract class Examples extends SketchContribution {
registerRecursively( registerRecursively(
sketchContainerOrPlaceholder: sketchContainerOrPlaceholder:
| SketchContainer | SketchContainer
| (Sketch | SketchContainer)[] | (SketchRef | SketchContainer)[]
| string, | string,
menuPath: MenuPath, menuPath: MenuPath,
pushToDispose: DisposableCollection = new DisposableCollection(), pushToDispose: DisposableCollection = new DisposableCollection(),
@ -100,7 +100,7 @@ export abstract class Examples extends SketchContribution {
) )
); );
} else { } else {
const sketches: Sketch[] = []; const sketches: SketchRef[] = [];
const children: SketchContainer[] = []; const children: SketchContainer[] = [];
let submenuPath = menuPath; let submenuPath = menuPath;
@ -161,7 +161,7 @@ export abstract class Examples extends SketchContribution {
@injectable() @injectable()
export class BuiltInExamples extends Examples { export class BuiltInExamples extends Examples {
onStart(): void { override async onReady(): Promise<void> {
this.register(); // no `await` this.register(); // no `await`
} }
@ -201,13 +201,16 @@ export class LibraryExamples extends Examples {
protected readonly queue = new PQueue({ autoStart: true, concurrency: 1 }); protected readonly queue = new PQueue({ autoStart: true, concurrency: 1 });
onStart(): void { override onStart(): void {
this.register(); // no `await`
this.notificationCenter.onLibraryInstalled(() => this.register()); this.notificationCenter.onLibraryInstalled(() => this.register());
this.notificationCenter.onLibraryUninstalled(() => this.register()); this.notificationCenter.onLibraryUninstalled(() => this.register());
} }
protected handleBoardChanged(board: Board | undefined): void { override async onReady(): Promise<void> {
this.register(); // no `await`
}
protected override handleBoardChanged(board: Board | undefined): void {
this.register(board); this.register(board);
} }

View File

@ -28,7 +28,7 @@ export class Help extends Contribution {
@inject(QuickInputService) @inject(QuickInputService)
protected readonly quickInputService: QuickInputService; protected readonly quickInputService: QuickInputService;
registerCommands(registry: CommandRegistry): void { override registerCommands(registry: CommandRegistry): void {
const open = (url: string) => const open = (url: string) =>
this.windowService.openNewWindow(url, { external: true }); this.windowService.openNewWindow(url, { external: true });
const createOpenHandler = (url: string) => const createOpenHandler = (url: string) =>
@ -92,7 +92,7 @@ export class Help extends Contribution {
); );
} }
registerMenus(registry: MenuModelRegistry): void { override registerMenus(registry: MenuModelRegistry): void {
registry.unregisterMenuAction({ registry.unregisterMenuAction({
commandId: ElectronCommands.TOGGLE_DEVELOPER_TOOLS.id, commandId: ElectronCommands.TOGGLE_DEVELOPER_TOOLS.id,
}); });
@ -136,7 +136,7 @@ export class Help extends Contribution {
}); });
} }
registerKeybindings(registry: KeybindingRegistry): void { override registerKeybindings(registry: KeybindingRegistry): void {
registry.registerKeybinding({ registry.registerKeybinding({
command: Help.Commands.FIND_IN_REFERENCE.id, command: Help.Commands.FIND_IN_REFERENCE.id,
keybinding: 'CtrlCmd+Shift+F', keybinding: 'CtrlCmd+Shift+F',

View File

@ -17,6 +17,7 @@ import { SketchContribution, Command, CommandRegistry } from './contribution';
import { NotificationCenter } from '../notification-center'; import { NotificationCenter } from '../notification-center';
import { nls } from '@theia/core/lib/common'; import { nls } from '@theia/core/lib/common';
import * as monaco from '@theia/monaco-editor-core'; import * as monaco from '@theia/monaco-editor-core';
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
@injectable() @injectable()
export class IncludeLibrary extends SketchContribution { export class IncludeLibrary extends SketchContribution {
@ -30,7 +31,7 @@ export class IncludeLibrary extends SketchContribution {
protected readonly mainMenuManager: MainMenuManager; protected readonly mainMenuManager: MainMenuManager;
@inject(EditorManager) @inject(EditorManager)
protected readonly editorManager: EditorManager; protected override readonly editorManager: EditorManager;
@inject(NotificationCenter) @inject(NotificationCenter)
protected readonly notificationCenter: NotificationCenter; protected readonly notificationCenter: NotificationCenter;
@ -44,8 +45,7 @@ export class IncludeLibrary extends SketchContribution {
protected readonly queue = new PQueue({ autoStart: true, concurrency: 1 }); protected readonly queue = new PQueue({ autoStart: true, concurrency: 1 });
protected readonly toDispose = new DisposableCollection(); protected readonly toDispose = new DisposableCollection();
onStart(): void { override onStart(): void {
this.updateMenuActions();
this.boardsServiceClient.onBoardsConfigChanged(() => this.boardsServiceClient.onBoardsConfigChanged(() =>
this.updateMenuActions() this.updateMenuActions()
); );
@ -55,7 +55,11 @@ export class IncludeLibrary extends SketchContribution {
); );
} }
registerMenus(registry: MenuModelRegistry): void { override async onReady(): Promise<void> {
this.updateMenuActions();
}
override registerMenus(registry: MenuModelRegistry): void {
// `Include Library` submenu // `Include Library` submenu
const includeLibMenuPath = [ const includeLibMenuPath = [
...ArduinoMenus.SKETCH__UTILS_GROUP, ...ArduinoMenus.SKETCH__UTILS_GROUP,
@ -78,7 +82,7 @@ export class IncludeLibrary extends SketchContribution {
}); });
} }
registerCommands(registry: CommandRegistry): void { override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(IncludeLibrary.Commands.INCLUDE_LIBRARY, { registry.registerCommand(IncludeLibrary.Commands.INCLUDE_LIBRARY, {
execute: async (arg) => { execute: async (arg) => {
if (LibraryPackage.is(arg)) { if (LibraryPackage.is(arg)) {
@ -169,7 +173,7 @@ export class IncludeLibrary extends SketchContribution {
protected async includeLibrary(library: LibraryPackage): Promise<void> { protected async includeLibrary(library: LibraryPackage): Promise<void> {
const sketch = await this.sketchServiceClient.currentSketch(); const sketch = await this.sketchServiceClient.currentSketch();
if (!sketch) { if (!CurrentSketch.isValid(sketch)) {
return; return;
} }
// If the current editor is one of the additional files from the sketch, we use that. // If the current editor is one of the additional files from the sketch, we use that.

View File

@ -14,7 +14,7 @@ import {
@injectable() @injectable()
export class NewSketch extends SketchContribution { export class NewSketch extends SketchContribution {
registerCommands(registry: CommandRegistry): void { override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(NewSketch.Commands.NEW_SKETCH, { registry.registerCommand(NewSketch.Commands.NEW_SKETCH, {
execute: () => this.newSketch(), execute: () => this.newSketch(),
}); });
@ -25,7 +25,7 @@ export class NewSketch extends SketchContribution {
}); });
} }
registerMenus(registry: MenuModelRegistry): void { override registerMenus(registry: MenuModelRegistry): void {
registry.registerMenuAction(ArduinoMenus.FILE__SKETCH_GROUP, { registry.registerMenuAction(ArduinoMenus.FILE__SKETCH_GROUP, {
commandId: NewSketch.Commands.NEW_SKETCH.id, commandId: NewSketch.Commands.NEW_SKETCH.id,
label: nls.localize('arduino/sketch/new', 'New'), label: nls.localize('arduino/sketch/new', 'New'),
@ -33,14 +33,14 @@ export class NewSketch extends SketchContribution {
}); });
} }
registerKeybindings(registry: KeybindingRegistry): void { override registerKeybindings(registry: KeybindingRegistry): void {
registry.registerKeybinding({ registry.registerKeybinding({
command: NewSketch.Commands.NEW_SKETCH.id, command: NewSketch.Commands.NEW_SKETCH.id,
keybinding: 'CtrlCmd+N', keybinding: 'CtrlCmd+N',
}); });
} }
registerToolbarItems(registry: TabBarToolbarRegistry): void { override registerToolbarItems(registry: TabBarToolbarRegistry): void {
registry.registerItem({ registry.registerItem({
id: NewSketch.Commands.NEW_SKETCH__TOOLBAR.id, id: NewSketch.Commands.NEW_SKETCH__TOOLBAR.id,
command: NewSketch.Commands.NEW_SKETCH__TOOLBAR.id, command: NewSketch.Commands.NEW_SKETCH__TOOLBAR.id,

View File

@ -35,18 +35,19 @@ export class OpenRecentSketch extends SketchContribution {
protected toDisposeBeforeRegister = new Map<string, DisposableCollection>(); protected toDisposeBeforeRegister = new Map<string, DisposableCollection>();
onStart(): void { override onStart(): void {
const refreshMenu = (sketches: Sketch[]) => {
this.register(sketches);
this.mainMenuManager.update();
};
this.notificationCenter.onRecentSketchesChanged(({ sketches }) => this.notificationCenter.onRecentSketchesChanged(({ sketches }) =>
refreshMenu(sketches) this.refreshMenu(sketches)
); );
this.sketchService.recentlyOpenedSketches().then(refreshMenu);
} }
registerMenus(registry: MenuModelRegistry): void { override async onReady(): Promise<void> {
this.sketchService
.recentlyOpenedSketches()
.then((sketches) => this.refreshMenu(sketches));
}
override registerMenus(registry: MenuModelRegistry): void {
registry.registerSubmenu( registry.registerSubmenu(
ArduinoMenus.FILE__OPEN_RECENT_SUBMENU, ArduinoMenus.FILE__OPEN_RECENT_SUBMENU,
nls.localize('arduino/sketch/openRecent', 'Open Recent'), nls.localize('arduino/sketch/openRecent', 'Open Recent'),
@ -54,6 +55,11 @@ export class OpenRecentSketch extends SketchContribution {
); );
} }
private refreshMenu(sketches: Sketch[]): void {
this.register(sketches);
this.mainMenuManager.update();
}
protected register(sketches: Sketch[]): void { protected register(sketches: Sketch[]): void {
const order = 0; const order = 0;
for (const sketch of sketches) { for (const sketch of sketches) {

View File

@ -13,13 +13,13 @@ import { nls } from '@theia/core/lib/common';
@injectable() @injectable()
export class OpenSketchExternal extends SketchContribution { export class OpenSketchExternal extends SketchContribution {
registerCommands(registry: CommandRegistry): void { override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(OpenSketchExternal.Commands.OPEN_EXTERNAL, { registry.registerCommand(OpenSketchExternal.Commands.OPEN_EXTERNAL, {
execute: () => this.openExternal(), execute: () => this.openExternal(),
}); });
} }
registerMenus(registry: MenuModelRegistry): void { override registerMenus(registry: MenuModelRegistry): void {
registry.registerMenuAction(ArduinoMenus.SKETCH__UTILS_GROUP, { registry.registerMenuAction(ArduinoMenus.SKETCH__UTILS_GROUP, {
commandId: OpenSketchExternal.Commands.OPEN_EXTERNAL.id, commandId: OpenSketchExternal.Commands.OPEN_EXTERNAL.id,
label: nls.localize('arduino/sketch/showFolder', 'Show Sketch Folder'), label: nls.localize('arduino/sketch/showFolder', 'Show Sketch Folder'),
@ -27,7 +27,7 @@ export class OpenSketchExternal extends SketchContribution {
}); });
} }
registerKeybindings(registry: KeybindingRegistry): void { override registerKeybindings(registry: KeybindingRegistry): void {
registry.registerKeybinding({ registry.registerKeybinding({
command: OpenSketchExternal.Commands.OPEN_EXTERNAL.id, command: OpenSketchExternal.Commands.OPEN_EXTERNAL.id,
keybinding: 'CtrlCmd+Alt+K', keybinding: 'CtrlCmd+Alt+K',

View File

@ -43,7 +43,7 @@ export class OpenSketch extends SketchContribution {
protected readonly toDispose = new DisposableCollection(); protected readonly toDispose = new DisposableCollection();
registerCommands(registry: CommandRegistry): void { override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(OpenSketch.Commands.OPEN_SKETCH, { registry.registerCommand(OpenSketch.Commands.OPEN_SKETCH, {
execute: (arg) => execute: (arg) =>
Sketch.is(arg) ? this.openSketch(arg) : this.openSketch(), Sketch.is(arg) ? this.openSketch(arg) : this.openSketch(),
@ -116,7 +116,7 @@ export class OpenSketch extends SketchContribution {
}); });
} }
registerMenus(registry: MenuModelRegistry): void { override registerMenus(registry: MenuModelRegistry): void {
registry.registerMenuAction(ArduinoMenus.FILE__SKETCH_GROUP, { registry.registerMenuAction(ArduinoMenus.FILE__SKETCH_GROUP, {
commandId: OpenSketch.Commands.OPEN_SKETCH.id, commandId: OpenSketch.Commands.OPEN_SKETCH.id,
label: nls.localize('vscode/workspaceActions/openFileFolder', 'Open...'), label: nls.localize('vscode/workspaceActions/openFileFolder', 'Open...'),
@ -124,14 +124,14 @@ export class OpenSketch extends SketchContribution {
}); });
} }
registerKeybindings(registry: KeybindingRegistry): void { override registerKeybindings(registry: KeybindingRegistry): void {
registry.registerKeybinding({ registry.registerKeybinding({
command: OpenSketch.Commands.OPEN_SKETCH.id, command: OpenSketch.Commands.OPEN_SKETCH.id,
keybinding: 'CtrlCmd+O', keybinding: 'CtrlCmd+O',
}); });
} }
registerToolbarItems(registry: TabBarToolbarRegistry): void { override registerToolbarItems(registry: TabBarToolbarRegistry): void {
registry.registerItem({ registry.registerItem({
id: OpenSketch.Commands.OPEN_SKETCH__TOOLBAR.id, id: OpenSketch.Commands.OPEN_SKETCH__TOOLBAR.id,
command: OpenSketch.Commands.OPEN_SKETCH__TOOLBAR.id, command: OpenSketch.Commands.OPEN_SKETCH__TOOLBAR.id,

View File

@ -13,7 +13,7 @@ import { nls } from '@theia/core/lib/common';
@injectable() @injectable()
export class QuitApp extends Contribution { export class QuitApp extends Contribution {
registerCommands(registry: CommandRegistry): void { override registerCommands(registry: CommandRegistry): void {
if (!isOSX) { if (!isOSX) {
registry.registerCommand(QuitApp.Commands.QUIT_APP, { registry.registerCommand(QuitApp.Commands.QUIT_APP, {
execute: () => remote.app.quit(), execute: () => remote.app.quit(),
@ -21,7 +21,7 @@ export class QuitApp extends Contribution {
} }
} }
registerMenus(registry: MenuModelRegistry): void { override registerMenus(registry: MenuModelRegistry): void {
// On macOS we will get the `Quit ${YOUR_APP_NAME}` menu item natively, no need to duplicate it. // On macOS we will get the `Quit ${YOUR_APP_NAME}` menu item natively, no need to duplicate it.
if (!isOSX) { if (!isOSX) {
registry.registerMenuAction(ArduinoMenus.FILE__QUIT_GROUP, { registry.registerMenuAction(ArduinoMenus.FILE__QUIT_GROUP, {
@ -32,7 +32,7 @@ export class QuitApp extends Contribution {
} }
} }
registerKeybindings(registry: KeybindingRegistry): void { override registerKeybindings(registry: KeybindingRegistry): void {
if (!isOSX) { if (!isOSX) {
registry.registerKeybinding({ registry.registerKeybinding({
command: QuitApp.Commands.QUIT_APP.id, command: QuitApp.Commands.QUIT_APP.id,

View File

@ -14,6 +14,7 @@ import { nls } from '@theia/core/lib/common';
import { ApplicationShell, NavigatableWidget, Saveable } from '@theia/core/lib/browser'; import { ApplicationShell, NavigatableWidget, Saveable } from '@theia/core/lib/browser';
import { EditorManager } from '@theia/editor/lib/browser'; import { EditorManager } from '@theia/editor/lib/browser';
import { WindowService } from '@theia/core/lib/browser/window/window-service'; import { WindowService } from '@theia/core/lib/browser/window/window-service';
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
@injectable() @injectable()
export class SaveAsSketch extends SketchContribution { export class SaveAsSketch extends SketchContribution {
@ -22,18 +23,18 @@ export class SaveAsSketch extends SketchContribution {
protected readonly applicationShell: ApplicationShell; protected readonly applicationShell: ApplicationShell;
@inject(EditorManager) @inject(EditorManager)
protected readonly editorManager: EditorManager; protected override readonly editorManager: EditorManager;
@inject(WindowService) @inject(WindowService)
protected readonly windowService: WindowService; protected readonly windowService: WindowService;
registerCommands(registry: CommandRegistry): void { override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(SaveAsSketch.Commands.SAVE_AS_SKETCH, { registry.registerCommand(SaveAsSketch.Commands.SAVE_AS_SKETCH, {
execute: (args) => this.saveAs(args), execute: (args) => this.saveAs(args),
}); });
} }
registerMenus(registry: MenuModelRegistry): void { override registerMenus(registry: MenuModelRegistry): void {
registry.registerMenuAction(ArduinoMenus.FILE__SKETCH_GROUP, { registry.registerMenuAction(ArduinoMenus.FILE__SKETCH_GROUP, {
commandId: SaveAsSketch.Commands.SAVE_AS_SKETCH.id, commandId: SaveAsSketch.Commands.SAVE_AS_SKETCH.id,
label: nls.localize('vscode/fileCommands/saveAs', 'Save As...'), label: nls.localize('vscode/fileCommands/saveAs', 'Save As...'),
@ -41,7 +42,7 @@ export class SaveAsSketch extends SketchContribution {
}); });
} }
registerKeybindings(registry: KeybindingRegistry): void { override registerKeybindings(registry: KeybindingRegistry): void {
registry.registerKeybinding({ registry.registerKeybinding({
command: SaveAsSketch.Commands.SAVE_AS_SKETCH.id, command: SaveAsSketch.Commands.SAVE_AS_SKETCH.id,
keybinding: 'CtrlCmd+Shift+S', keybinding: 'CtrlCmd+Shift+S',
@ -59,7 +60,7 @@ export class SaveAsSketch extends SketchContribution {
}: SaveAsSketch.Options = SaveAsSketch.Options.DEFAULT }: SaveAsSketch.Options = SaveAsSketch.Options.DEFAULT
): Promise<boolean> { ): Promise<boolean> {
const sketch = await this.sketchServiceClient.currentSketch(); const sketch = await this.sketchServiceClient.currentSketch();
if (!sketch) { if (!CurrentSketch.isValid(sketch)) {
return false; return false;
} }

View File

@ -12,10 +12,11 @@ import {
TabBarToolbarRegistry, TabBarToolbarRegistry,
} from './contribution'; } from './contribution';
import { nls } from '@theia/core/lib/common'; import { nls } from '@theia/core/lib/common';
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
@injectable() @injectable()
export class SaveSketch extends SketchContribution { export class SaveSketch extends SketchContribution {
registerCommands(registry: CommandRegistry): void { override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(SaveSketch.Commands.SAVE_SKETCH, { registry.registerCommand(SaveSketch.Commands.SAVE_SKETCH, {
execute: () => this.saveSketch(), execute: () => this.saveSketch(),
}); });
@ -27,7 +28,7 @@ export class SaveSketch extends SketchContribution {
}); });
} }
registerMenus(registry: MenuModelRegistry): void { override registerMenus(registry: MenuModelRegistry): void {
registry.registerMenuAction(ArduinoMenus.FILE__SKETCH_GROUP, { registry.registerMenuAction(ArduinoMenus.FILE__SKETCH_GROUP, {
commandId: SaveSketch.Commands.SAVE_SKETCH.id, commandId: SaveSketch.Commands.SAVE_SKETCH.id,
label: nls.localize('vscode/fileCommands/save', 'Save'), label: nls.localize('vscode/fileCommands/save', 'Save'),
@ -35,14 +36,14 @@ export class SaveSketch extends SketchContribution {
}); });
} }
registerKeybindings(registry: KeybindingRegistry): void { override registerKeybindings(registry: KeybindingRegistry): void {
registry.registerKeybinding({ registry.registerKeybinding({
command: SaveSketch.Commands.SAVE_SKETCH.id, command: SaveSketch.Commands.SAVE_SKETCH.id,
keybinding: 'CtrlCmd+S', keybinding: 'CtrlCmd+S',
}); });
} }
registerToolbarItems(registry: TabBarToolbarRegistry): void { override registerToolbarItems(registry: TabBarToolbarRegistry): void {
registry.registerItem({ registry.registerItem({
id: SaveSketch.Commands.SAVE_SKETCH__TOOLBAR.id, id: SaveSketch.Commands.SAVE_SKETCH__TOOLBAR.id,
command: SaveSketch.Commands.SAVE_SKETCH__TOOLBAR.id, command: SaveSketch.Commands.SAVE_SKETCH__TOOLBAR.id,
@ -53,7 +54,7 @@ export class SaveSketch extends SketchContribution {
async saveSketch(): Promise<void> { async saveSketch(): Promise<void> {
const sketch = await this.sketchServiceClient.currentSketch(); const sketch = await this.sketchServiceClient.currentSketch();
if (!sketch) { if (!CurrentSketch.isValid(sketch)) {
return; return;
} }
const isTemp = await this.sketchService.isTemp(sketch); const isTemp = await this.sketchService.isTemp(sketch);

View File

@ -18,7 +18,7 @@ export class Settings extends SketchContribution {
protected settingsOpened = false; protected settingsOpened = false;
registerCommands(registry: CommandRegistry): void { override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(Settings.Commands.OPEN, { registry.registerCommand(Settings.Commands.OPEN, {
execute: async () => { execute: async () => {
let settings: Preferences | undefined = undefined; let settings: Preferences | undefined = undefined;
@ -39,7 +39,7 @@ export class Settings extends SketchContribution {
}); });
} }
registerMenus(registry: MenuModelRegistry): void { override registerMenus(registry: MenuModelRegistry): void {
registry.registerMenuAction(ArduinoMenus.FILE__PREFERENCES_GROUP, { registry.registerMenuAction(ArduinoMenus.FILE__PREFERENCES_GROUP, {
commandId: Settings.Commands.OPEN.id, commandId: Settings.Commands.OPEN.id,
label: label:
@ -52,7 +52,7 @@ export class Settings extends SketchContribution {
registry.registerSubmenu(ArduinoMenus.FILE__ADVANCED_SUBMENU, 'Advanced'); registry.registerSubmenu(ArduinoMenus.FILE__ADVANCED_SUBMENU, 'Advanced');
} }
registerKeybindings(registry: KeybindingRegistry): void { override registerKeybindings(registry: KeybindingRegistry): void {
registry.registerKeybinding({ registry.registerKeybinding({
command: Settings.Commands.OPEN.id, command: Settings.Commands.OPEN.id,
keybinding: 'CtrlCmd+,', keybinding: 'CtrlCmd+,',

View File

@ -19,7 +19,10 @@ import {
} from './contribution'; } from './contribution';
import { ArduinoMenus, PlaceholderMenuNode } from '../menu/arduino-menus'; import { ArduinoMenus, PlaceholderMenuNode } from '../menu/arduino-menus';
import { EditorManager } from '@theia/editor/lib/browser/editor-manager'; import { EditorManager } from '@theia/editor/lib/browser/editor-manager';
import { SketchesServiceClientImpl } from '../../common/protocol/sketches-service-client-impl'; import {
CurrentSketch,
SketchesServiceClientImpl,
} from '../../common/protocol/sketches-service-client-impl';
import { LocalCacheFsProvider } from '../local-cache/local-cache-fs-provider'; import { LocalCacheFsProvider } from '../local-cache/local-cache-fs-provider';
import { nls } from '@theia/core/lib/common'; import { nls } from '@theia/core/lib/common';
@ -35,7 +38,7 @@ export class SketchControl extends SketchContribution {
protected readonly contextMenuRenderer: ContextMenuRenderer; protected readonly contextMenuRenderer: ContextMenuRenderer;
@inject(EditorManager) @inject(EditorManager)
protected readonly editorManager: EditorManager; protected override readonly editorManager: EditorManager;
@inject(SketchesServiceClientImpl) @inject(SketchesServiceClientImpl)
protected readonly sketchesServiceClient: SketchesServiceClientImpl; protected readonly sketchesServiceClient: SketchesServiceClientImpl;
@ -46,7 +49,7 @@ export class SketchControl extends SketchContribution {
protected readonly toDisposeBeforeCreateNewContextMenu = protected readonly toDisposeBeforeCreateNewContextMenu =
new DisposableCollection(); new DisposableCollection();
registerCommands(registry: CommandRegistry): void { override registerCommands(registry: CommandRegistry): void {
registry.registerCommand( registry.registerCommand(
SketchControl.Commands.OPEN_SKETCH_CONTROL__TOOLBAR, SketchControl.Commands.OPEN_SKETCH_CONTROL__TOOLBAR,
{ {
@ -55,7 +58,7 @@ export class SketchControl extends SketchContribution {
execute: async () => { execute: async () => {
this.toDisposeBeforeCreateNewContextMenu.dispose(); this.toDisposeBeforeCreateNewContextMenu.dispose();
const sketch = await this.sketchServiceClient.currentSketch(); const sketch = await this.sketchServiceClient.currentSketch();
if (!sketch) { if (!CurrentSketch.isValid(sketch)) {
return; return;
} }
@ -70,25 +73,22 @@ export class SketchControl extends SketchContribution {
return; return;
} }
const { mainFileUri, rootFolderFileUris } = const { mainFileUri, rootFolderFileUris } = sketch;
await this.sketchService.loadSketch(sketch.uri);
const uris = [mainFileUri, ...rootFolderFileUris]; const uris = [mainFileUri, ...rootFolderFileUris];
const currentSketch = const parentSketchUri = this.editorManager.currentEditor
await this.sketchesServiceClient.currentSketch();
const parentsketchUri = this.editorManager.currentEditor
?.getResourceUri() ?.getResourceUri()
?.toString(); ?.toString();
const parentsketch = await this.sketchService.getSketchFolder( const parentSketch = await this.sketchService.getSketchFolder(
parentsketchUri || '' parentSketchUri || ''
); );
// if the current file is in the current opened sketch, show extra menus // if the current file is in the current opened sketch, show extra menus
if ( if (
currentSketch && sketch &&
parentsketch && parentSketch &&
parentsketch.uri === currentSketch.uri && parentSketch.uri === sketch.uri &&
this.allowRename(parentsketch.uri) this.allowRename(parentSketch.uri)
) { ) {
this.menuRegistry.registerMenuAction( this.menuRegistry.registerMenuAction(
ArduinoMenus.SKETCH_CONTROL__CONTEXT__MAIN_GROUP, ArduinoMenus.SKETCH_CONTROL__CONTEXT__MAIN_GROUP,
@ -122,10 +122,10 @@ export class SketchControl extends SketchContribution {
} }
if ( if (
currentSketch && sketch &&
parentsketch && parentSketch &&
parentsketch.uri === currentSketch.uri && parentSketch.uri === sketch.uri &&
this.allowDelete(parentsketch.uri) this.allowDelete(parentSketch.uri)
) { ) {
this.menuRegistry.registerMenuAction( this.menuRegistry.registerMenuAction(
ArduinoMenus.SKETCH_CONTROL__CONTEXT__MAIN_GROUP, ArduinoMenus.SKETCH_CONTROL__CONTEXT__MAIN_GROUP,
@ -200,7 +200,7 @@ export class SketchControl extends SketchContribution {
); );
} }
registerMenus(registry: MenuModelRegistry): void { override registerMenus(registry: MenuModelRegistry): void {
registry.registerMenuAction( registry.registerMenuAction(
ArduinoMenus.SKETCH_CONTROL__CONTEXT__MAIN_GROUP, ArduinoMenus.SKETCH_CONTROL__CONTEXT__MAIN_GROUP,
{ {
@ -228,7 +228,7 @@ export class SketchControl extends SketchContribution {
); );
} }
registerKeybindings(registry: KeybindingRegistry): void { override registerKeybindings(registry: KeybindingRegistry): void {
registry.registerKeybinding({ registry.registerKeybinding({
command: WorkspaceCommands.NEW_FILE.id, command: WorkspaceCommands.NEW_FILE.id,
keybinding: 'CtrlCmd+Shift+N', keybinding: 'CtrlCmd+Shift+N',
@ -243,7 +243,7 @@ export class SketchControl extends SketchContribution {
}); });
} }
registerToolbarItems(registry: TabBarToolbarRegistry): void { override registerToolbarItems(registry: TabBarToolbarRegistry): void {
registry.registerItem({ registry.registerItem({
id: SketchControl.Commands.OPEN_SKETCH_CONTROL__TOOLBAR.id, id: SketchControl.Commands.OPEN_SKETCH_CONTROL__TOOLBAR.id,
command: SketchControl.Commands.OPEN_SKETCH_CONTROL__TOOLBAR.id, command: SketchControl.Commands.OPEN_SKETCH_CONTROL__TOOLBAR.id,

View File

@ -12,10 +12,10 @@ import { nls } from '@theia/core/lib/common';
@injectable() @injectable()
export class Sketchbook extends Examples { export class Sketchbook extends Examples {
@inject(CommandRegistry) @inject(CommandRegistry)
protected readonly commandRegistry: CommandRegistry; protected override readonly commandRegistry: CommandRegistry;
@inject(MenuModelRegistry) @inject(MenuModelRegistry)
protected readonly menuRegistry: MenuModelRegistry; protected override readonly menuRegistry: MenuModelRegistry;
@inject(MainMenuManager) @inject(MainMenuManager)
protected readonly mainMenuManager: MainMenuManager; protected readonly mainMenuManager: MainMenuManager;
@ -23,11 +23,7 @@ export class Sketchbook extends Examples {
@inject(NotificationCenter) @inject(NotificationCenter)
protected readonly notificationCenter: NotificationCenter; protected readonly notificationCenter: NotificationCenter;
onStart(): void { override onStart(): void {
this.sketchService.getSketches({}).then((container) => {
this.register(container);
this.mainMenuManager.update();
});
this.sketchServiceClient.onSketchbookDidChange(() => { this.sketchServiceClient.onSketchbookDidChange(() => {
this.sketchService.getSketches({}).then((container) => { this.sketchService.getSketches({}).then((container) => {
this.register(container); this.register(container);
@ -36,7 +32,14 @@ export class Sketchbook extends Examples {
}); });
} }
registerMenus(registry: MenuModelRegistry): void { override async onReady(): Promise<void> {
this.sketchService.getSketches({}).then((container) => {
this.register(container);
this.mainMenuManager.update();
});
}
override registerMenus(registry: MenuModelRegistry): void {
registry.registerSubmenu( registry.registerSubmenu(
ArduinoMenus.FILE__SKETCHBOOK_SUBMENU, ArduinoMenus.FILE__SKETCHBOOK_SUBMENU,
nls.localize('arduino/sketch/sketchbook', 'Sketchbook'), nls.localize('arduino/sketch/sketchbook', 'Sketchbook'),
@ -53,7 +56,7 @@ export class Sketchbook extends Examples {
); );
} }
protected createHandler(uri: string): CommandHandler { protected override createHandler(uri: string): CommandHandler {
return { return {
execute: async () => { execute: async () => {
const sketch = await this.sketchService.loadSketch(uri); const sketch = await this.sketchService.loadSketch(uri);

View File

@ -39,7 +39,7 @@ export class UploadCertificate extends Contribution {
protected dialogOpened = false; protected dialogOpened = false;
registerCommands(registry: CommandRegistry): void { override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(UploadCertificate.Commands.OPEN, { registry.registerCommand(UploadCertificate.Commands.OPEN, {
execute: async () => { execute: async () => {
try { try {
@ -93,7 +93,7 @@ export class UploadCertificate extends Contribution {
}); });
} }
registerMenus(registry: MenuModelRegistry): void { override registerMenus(registry: MenuModelRegistry): void {
registry.registerMenuAction(ArduinoMenus.TOOLS__FIRMWARE_UPLOADER_GROUP, { registry.registerMenuAction(ArduinoMenus.TOOLS__FIRMWARE_UPLOADER_GROUP, {
commandId: UploadCertificate.Commands.OPEN.id, commandId: UploadCertificate.Commands.OPEN.id,
label: UploadCertificate.Commands.OPEN.label, label: UploadCertificate.Commands.OPEN.label,

View File

@ -16,7 +16,7 @@ export class UploadFirmware extends Contribution {
protected dialogOpened = false; protected dialogOpened = false;
registerCommands(registry: CommandRegistry): void { override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(UploadFirmware.Commands.OPEN, { registry.registerCommand(UploadFirmware.Commands.OPEN, {
execute: async () => { execute: async () => {
try { try {
@ -30,7 +30,7 @@ export class UploadFirmware extends Contribution {
}); });
} }
registerMenus(registry: MenuModelRegistry): void { override registerMenus(registry: MenuModelRegistry): void {
registry.registerMenuAction(ArduinoMenus.TOOLS__FIRMWARE_UPLOADER_GROUP, { registry.registerMenuAction(ArduinoMenus.TOOLS__FIRMWARE_UPLOADER_GROUP, {
commandId: UploadFirmware.Commands.OPEN.id, commandId: UploadFirmware.Commands.OPEN.id,
label: UploadFirmware.Commands.OPEN.label, label: UploadFirmware.Commands.OPEN.label,

View File

@ -1,4 +1,4 @@
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify'; import { inject, injectable } from '@theia/core/shared/inversify';
import { Emitter } from '@theia/core/lib/common/event'; import { Emitter } from '@theia/core/lib/common/event';
import { BoardUserField, CoreService } from '../../common/protocol'; import { BoardUserField, CoreService } from '../../common/protocol';
import { ArduinoMenus, PlaceholderMenuNode } from '../menu/arduino-menus'; import { ArduinoMenus, PlaceholderMenuNode } from '../menu/arduino-menus';
@ -16,6 +16,7 @@ import {
} from './contribution'; } from './contribution';
import { UserFieldsDialog } from '../dialogs/user-fields/user-fields-dialog'; import { UserFieldsDialog } from '../dialogs/user-fields/user-fields-dialog';
import { DisposableCollection, nls } from '@theia/core/lib/common'; import { DisposableCollection, nls } from '@theia/core/lib/common';
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
@injectable() @injectable()
export class UploadSketch extends SketchContribution { export class UploadSketch extends SketchContribution {
@ -47,8 +48,8 @@ export class UploadSketch extends SketchContribution {
protected readonly menuActionsDisposables = new DisposableCollection(); protected readonly menuActionsDisposables = new DisposableCollection();
@postConstruct() protected override init(): void {
protected init(): void { super.init();
this.boardsServiceClientImpl.onBoardsConfigChanged(async () => { this.boardsServiceClientImpl.onBoardsConfigChanged(async () => {
const userFields = const userFields =
await this.boardsServiceClientImpl.selectedBoardUserFields(); await this.boardsServiceClientImpl.selectedBoardUserFields();
@ -72,7 +73,7 @@ export class UploadSketch extends SketchContribution {
return fqbn + '|' + address; return fqbn + '|' + address;
} }
registerCommands(registry: CommandRegistry): void { override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(UploadSketch.Commands.UPLOAD_SKETCH, { registry.registerCommand(UploadSketch.Commands.UPLOAD_SKETCH, {
execute: async () => { execute: async () => {
const key = this.selectedFqbnAddress(); const key = this.selectedFqbnAddress();
@ -134,7 +135,7 @@ export class UploadSketch extends SketchContribution {
}); });
} }
registerMenus(registry: MenuModelRegistry): void { override registerMenus(registry: MenuModelRegistry): void {
this.menuActionsDisposables.dispose(); this.menuActionsDisposables.dispose();
this.menuActionsDisposables.push( this.menuActionsDisposables.push(
@ -177,7 +178,7 @@ export class UploadSketch extends SketchContribution {
); );
} }
registerKeybindings(registry: KeybindingRegistry): void { override registerKeybindings(registry: KeybindingRegistry): void {
registry.registerKeybinding({ registry.registerKeybinding({
command: UploadSketch.Commands.UPLOAD_SKETCH.id, command: UploadSketch.Commands.UPLOAD_SKETCH.id,
keybinding: 'CtrlCmd+U', keybinding: 'CtrlCmd+U',
@ -188,7 +189,7 @@ export class UploadSketch extends SketchContribution {
}); });
} }
registerToolbarItems(registry: TabBarToolbarRegistry): void { override registerToolbarItems(registry: TabBarToolbarRegistry): void {
registry.registerItem({ registry.registerItem({
id: UploadSketch.Commands.UPLOAD_SKETCH_TOOLBAR.id, id: UploadSketch.Commands.UPLOAD_SKETCH_TOOLBAR.id,
command: UploadSketch.Commands.UPLOAD_SKETCH_TOOLBAR.id, command: UploadSketch.Commands.UPLOAD_SKETCH_TOOLBAR.id,
@ -209,7 +210,7 @@ export class UploadSketch extends SketchContribution {
this.uploadInProgress = true; this.uploadInProgress = true;
this.onDidChangeEmitter.fire(); this.onDidChangeEmitter.fire();
const sketch = await this.sketchServiceClient.currentSketch(); const sketch = await this.sketchServiceClient.currentSketch();
if (!sketch) { if (!CurrentSketch.isValid(sketch)) {
return; return;
} }

View File

@ -14,6 +14,7 @@ import {
TabBarToolbarRegistry, TabBarToolbarRegistry,
} from './contribution'; } from './contribution';
import { nls } from '@theia/core/lib/common'; import { nls } from '@theia/core/lib/common';
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
@injectable() @injectable()
export class VerifySketch extends SketchContribution { export class VerifySketch extends SketchContribution {
@ -31,7 +32,7 @@ export class VerifySketch extends SketchContribution {
protected verifyInProgress = false; protected verifyInProgress = false;
registerCommands(registry: CommandRegistry): void { override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(VerifySketch.Commands.VERIFY_SKETCH, { registry.registerCommand(VerifySketch.Commands.VERIFY_SKETCH, {
execute: () => this.verifySketch(), execute: () => this.verifySketch(),
isEnabled: () => !this.verifyInProgress, isEnabled: () => !this.verifyInProgress,
@ -50,7 +51,7 @@ export class VerifySketch extends SketchContribution {
}); });
} }
registerMenus(registry: MenuModelRegistry): void { override registerMenus(registry: MenuModelRegistry): void {
registry.registerMenuAction(ArduinoMenus.SKETCH__MAIN_GROUP, { registry.registerMenuAction(ArduinoMenus.SKETCH__MAIN_GROUP, {
commandId: VerifySketch.Commands.VERIFY_SKETCH.id, commandId: VerifySketch.Commands.VERIFY_SKETCH.id,
label: nls.localize('arduino/sketch/verifyOrCompile', 'Verify/Compile'), label: nls.localize('arduino/sketch/verifyOrCompile', 'Verify/Compile'),
@ -66,7 +67,7 @@ export class VerifySketch extends SketchContribution {
}); });
} }
registerKeybindings(registry: KeybindingRegistry): void { override registerKeybindings(registry: KeybindingRegistry): void {
registry.registerKeybinding({ registry.registerKeybinding({
command: VerifySketch.Commands.VERIFY_SKETCH.id, command: VerifySketch.Commands.VERIFY_SKETCH.id,
keybinding: 'CtrlCmd+R', keybinding: 'CtrlCmd+R',
@ -77,7 +78,7 @@ export class VerifySketch extends SketchContribution {
}); });
} }
registerToolbarItems(registry: TabBarToolbarRegistry): void { override registerToolbarItems(registry: TabBarToolbarRegistry): void {
registry.registerItem({ registry.registerItem({
id: VerifySketch.Commands.VERIFY_SKETCH_TOOLBAR.id, id: VerifySketch.Commands.VERIFY_SKETCH_TOOLBAR.id,
command: VerifySketch.Commands.VERIFY_SKETCH_TOOLBAR.id, command: VerifySketch.Commands.VERIFY_SKETCH_TOOLBAR.id,
@ -99,7 +100,7 @@ export class VerifySketch extends SketchContribution {
this.onDidChangeEmitter.fire(); this.onDidChangeEmitter.fire();
const sketch = await this.sketchServiceClient.currentSketch(); const sketch = await this.sketchServiceClient.currentSketch();
if (!sketch) { if (!CurrentSketch.isValid(sketch)) {
return; return;
} }
try { try {

View File

@ -117,11 +117,11 @@ export class CreateApi {
headers, headers,
}) })
).sketches; ).sketches;
if (partialSketches.length != 0) { if (partialSketches.length !== 0) {
result.sketches = result.sketches.concat(partialSketches); result.sketches = result.sketches.concat(partialSketches);
} }
currentOffset = currentOffset + limit; currentOffset = currentOffset + limit;
} while (partialSketches.length != 0); } while (partialSketches.length !== 0);
result.sketches.forEach((sketch) => this.sketchCache.addSketch(sketch)); result.sketches.forEach((sketch) => this.sketchCache.addSketch(sketch));
return result.sketches; return result.sketches;

View File

@ -139,7 +139,7 @@ export class UploadCertificateDialog extends AbstractDialog<void> {
constructor( constructor(
@inject(UploadCertificateDialogProps) @inject(UploadCertificateDialogProps)
protected readonly props: UploadCertificateDialogProps protected override readonly props: UploadCertificateDialogProps
) { ) {
super({ super({
title: nls.localize( title: nls.localize(
@ -155,7 +155,7 @@ export class UploadCertificateDialog extends AbstractDialog<void> {
return; return;
} }
protected onAfterAttach(msg: Message): void { protected override onAfterAttach(msg: Message): void {
if (this.widget.isAttached) { if (this.widget.isAttached) {
Widget.detach(this.widget); Widget.detach(this.widget);
} }
@ -165,21 +165,21 @@ export class UploadCertificateDialog extends AbstractDialog<void> {
this.update(); this.update();
} }
protected onUpdateRequest(msg: Message): void { protected override onUpdateRequest(msg: Message): void {
super.onUpdateRequest(msg); super.onUpdateRequest(msg);
this.widget.update(); this.widget.update();
} }
protected onActivateRequest(msg: Message): void { protected override onActivateRequest(msg: Message): void {
super.onActivateRequest(msg); super.onActivateRequest(msg);
this.widget.activate(); this.widget.activate();
} }
protected handleEnter(event: KeyboardEvent): boolean | void { protected override handleEnter(event: KeyboardEvent): boolean | void {
return false; return false;
} }
close(): void { override close(): void {
if (this.busy) { if (this.busy) {
return; return;
} }

View File

@ -149,7 +149,7 @@ export class ShareSketchDialog extends AbstractDialog<void> {
constructor( constructor(
@inject(ShareSketchDialogProps) @inject(ShareSketchDialogProps)
protected readonly props: ShareSketchDialogProps protected override readonly props: ShareSketchDialogProps
) { ) {
super({ title: props.title }); super({ title: props.title });
this.contentNode.classList.add('arduino-share-sketch-dialog'); this.contentNode.classList.add('arduino-share-sketch-dialog');
@ -159,7 +159,7 @@ export class ShareSketchDialog extends AbstractDialog<void> {
get value(): void { get value(): void {
return; return;
} }
protected onAfterAttach(msg: Message): void { protected override onAfterAttach(msg: Message): void {
if (this.widget.isAttached) { if (this.widget.isAttached) {
Widget.detach(this.widget); Widget.detach(this.widget);
} }
@ -168,12 +168,12 @@ export class ShareSketchDialog extends AbstractDialog<void> {
this.update(); this.update();
} }
protected onUpdateRequest(msg: Message): void { protected override onUpdateRequest(msg: Message): void {
super.onUpdateRequest(msg); super.onUpdateRequest(msg);
this.widget.update(); this.widget.update();
} }
protected onActivateRequest(msg: Message): void { protected override onActivateRequest(msg: Message): void {
super.onActivateRequest(msg); super.onActivateRequest(msg);
this.widget.activate(); this.widget.activate();
} }

View File

@ -19,7 +19,7 @@ export class DoNotAskAgainConfirmDialog extends ConfirmDialog {
constructor( constructor(
@inject(DoNotAskAgainDialogProps) @inject(DoNotAskAgainDialogProps)
protected readonly props: DoNotAskAgainDialogProps protected override readonly props: DoNotAskAgainDialogProps
) { ) {
super(props); super(props);
this.controlPanel.removeChild(this.errorMessageNode); this.controlPanel.removeChild(this.errorMessageNode);
@ -42,7 +42,7 @@ export class DoNotAskAgainConfirmDialog extends ConfirmDialog {
this.doNotAskAgainCheckbox.type = 'checkbox'; this.doNotAskAgainCheckbox.type = 'checkbox';
} }
protected async accept(): Promise<void> { protected override async accept(): Promise<void> {
if (!this.resolve) { if (!this.resolve) {
return; return;
} }
@ -65,7 +65,7 @@ export class DoNotAskAgainConfirmDialog extends ConfirmDialog {
} }
} }
protected setErrorMessage(error: DialogError): void { protected override setErrorMessage(error: DialogError): void {
if (this.acceptButton) { if (this.acceptButton) {
this.acceptButton.disabled = !DialogError.getResult(error); this.acceptButton.disabled = !DialogError.getResult(error);
} }

View File

@ -15,6 +15,7 @@ import {
} from '../../../common/protocol/arduino-firmware-uploader'; } from '../../../common/protocol/arduino-firmware-uploader';
import { FirmwareUploaderComponent } from './firmware-uploader-component'; import { FirmwareUploaderComponent } from './firmware-uploader-component';
import { UploadFirmware } from '../../contributions/upload-firmware'; import { UploadFirmware } from '../../contributions/upload-firmware';
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
@injectable() @injectable()
export class UploadFirmwareDialogWidget extends ReactWidget { export class UploadFirmwareDialogWidget extends ReactWidget {
@ -24,6 +25,9 @@ export class UploadFirmwareDialogWidget extends ReactWidget {
@inject(ArduinoFirmwareUploader) @inject(ArduinoFirmwareUploader)
protected readonly arduinoFirmwareUploader: ArduinoFirmwareUploader; protected readonly arduinoFirmwareUploader: ArduinoFirmwareUploader;
@inject(FrontendApplicationStateService)
private readonly appStatusService: FrontendApplicationStateService;
protected updatableFqbns: string[] = []; protected updatableFqbns: string[] = [];
protected availableBoards: AvailableBoard[] = []; protected availableBoards: AvailableBoard[] = [];
protected isOpen = new Object(); protected isOpen = new Object();
@ -38,7 +42,8 @@ export class UploadFirmwareDialogWidget extends ReactWidget {
@postConstruct() @postConstruct()
protected init(): void { protected init(): void {
this.arduinoFirmwareUploader.updatableBoards().then((fqbns) => { this.appStatusService.reachedState('ready').then(async () => {
const fqbns = await this.arduinoFirmwareUploader.updatableBoards();
this.updatableFqbns = fqbns; this.updatableFqbns = fqbns;
this.update(); this.update();
}); });
@ -56,7 +61,7 @@ export class UploadFirmwareDialogWidget extends ReactWidget {
.finally(() => this.busyCallback(false)); .finally(() => this.busyCallback(false));
} }
onCloseRequest(msg: Message): void { protected override onCloseRequest(msg: Message): void {
super.onCloseRequest(msg); super.onCloseRequest(msg);
this.isOpen = new Object(); this.isOpen = new Object();
} }
@ -88,7 +93,7 @@ export class UploadFirmwareDialog extends AbstractDialog<void> {
constructor( constructor(
@inject(UploadFirmwareDialogProps) @inject(UploadFirmwareDialogProps)
protected readonly props: UploadFirmwareDialogProps protected override readonly props: UploadFirmwareDialogProps
) { ) {
super({ title: UploadFirmware.Commands.OPEN.label || '' }); super({ title: UploadFirmware.Commands.OPEN.label || '' });
this.contentNode.classList.add('firmware-uploader-dialog'); this.contentNode.classList.add('firmware-uploader-dialog');
@ -99,7 +104,7 @@ export class UploadFirmwareDialog extends AbstractDialog<void> {
return; return;
} }
protected onAfterAttach(msg: Message): void { protected override onAfterAttach(msg: Message): void {
if (this.widget.isAttached) { if (this.widget.isAttached) {
Widget.detach(this.widget); Widget.detach(this.widget);
} }
@ -109,21 +114,21 @@ export class UploadFirmwareDialog extends AbstractDialog<void> {
this.update(); this.update();
} }
protected onUpdateRequest(msg: Message): void { protected override onUpdateRequest(msg: Message): void {
super.onUpdateRequest(msg); super.onUpdateRequest(msg);
this.widget.update(); this.widget.update();
} }
protected onActivateRequest(msg: Message): void { protected override onActivateRequest(msg: Message): void {
super.onActivateRequest(msg); super.onActivateRequest(msg);
this.widget.activate(); this.widget.activate();
} }
protected handleEnter(event: KeyboardEvent): boolean | void { protected override handleEnter(event: KeyboardEvent): boolean | void {
return false; return false;
} }
close(): void { override close(): void {
if (this.busy) { if (this.busy) {
return; return;
} }

View File

@ -70,7 +70,7 @@ export class IDEUpdaterDialogWidget extends ReactWidget {
this.close(); this.close();
} }
close(): void { override close(): void {
super.close(); super.close();
this.onClose(); this.onClose();
} }
@ -122,7 +122,7 @@ export class IDEUpdaterDialog extends AbstractDialog<UpdateInfo> {
constructor( constructor(
@inject(IDEUpdaterDialogProps) @inject(IDEUpdaterDialogProps)
protected readonly props: IDEUpdaterDialogProps protected override readonly props: IDEUpdaterDialogProps
) { ) {
super({ super({
title: nls.localize( title: nls.localize(
@ -138,7 +138,7 @@ export class IDEUpdaterDialog extends AbstractDialog<UpdateInfo> {
return this.widget.updateInfo; return this.widget.updateInfo;
} }
protected onAfterAttach(msg: Message): void { protected override onAfterAttach(msg: Message): void {
if (this.widget.isAttached) { if (this.widget.isAttached) {
Widget.detach(this.widget); Widget.detach(this.widget);
} }
@ -147,7 +147,7 @@ export class IDEUpdaterDialog extends AbstractDialog<UpdateInfo> {
this.update(); this.update();
} }
async open( override async open(
data: UpdateInfo | undefined = undefined data: UpdateInfo | undefined = undefined
): Promise<UpdateInfo | undefined> { ): Promise<UpdateInfo | undefined> {
if (data && data.version) { if (data && data.version) {
@ -156,17 +156,17 @@ export class IDEUpdaterDialog extends AbstractDialog<UpdateInfo> {
} }
} }
protected onUpdateRequest(msg: Message): void { protected override onUpdateRequest(msg: Message): void {
super.onUpdateRequest(msg); super.onUpdateRequest(msg);
this.widget.update(); this.widget.update();
} }
protected onActivateRequest(msg: Message): void { protected override onActivateRequest(msg: Message): void {
super.onActivateRequest(msg); super.onActivateRequest(msg);
this.widget.activate(); this.widget.activate();
} }
close(): void { override close(): void {
this.widget.dispose(); this.widget.dispose();
super.close(); super.close();
} }

View File

@ -32,7 +32,7 @@ export class SettingsComponent extends React.Component<
super(props); super(props);
} }
componentDidUpdate( override componentDidUpdate(
_: SettingsComponent.Props, _: SettingsComponent.Props,
prevState: SettingsComponent.State prevState: SettingsComponent.State
): void { ): void {
@ -49,7 +49,7 @@ export class SettingsComponent extends React.Component<
} }
} }
componentDidMount(): void { override componentDidMount(): void {
this.props.settingsService this.props.settingsService
.settings() .settings()
.then((settings) => .then((settings) =>
@ -67,11 +67,11 @@ export class SettingsComponent extends React.Component<
]); ]);
} }
componentWillUnmount(): void { override componentWillUnmount(): void {
this.toDispose.dispose(); this.toDispose.dispose();
} }
render(): React.ReactNode { override render(): React.ReactNode {
if (!this.state) { if (!this.state) {
return <div />; return <div />;
} }

View File

@ -56,7 +56,7 @@ export class SettingsDialog extends AbstractDialog<Promise<Settings>> {
constructor( constructor(
@inject(SettingsDialogProps) @inject(SettingsDialogProps)
protected readonly props: SettingsDialogProps protected override readonly props: SettingsDialogProps
) { ) {
super(props); super(props);
this.contentNode.classList.add('arduino-settings-dialog'); this.contentNode.classList.add('arduino-settings-dialog');
@ -73,7 +73,7 @@ export class SettingsDialog extends AbstractDialog<Promise<Settings>> {
); );
} }
protected async isValid(settings: Promise<Settings>): Promise<DialogError> { protected override async isValid(settings: Promise<Settings>): Promise<DialogError> {
const result = await this.settingsService.validate(settings); const result = await this.settingsService.validate(settings);
if (typeof result === 'string') { if (typeof result === 'string') {
return result; return result;
@ -85,7 +85,7 @@ export class SettingsDialog extends AbstractDialog<Promise<Settings>> {
return this.settingsService.settings(); return this.settingsService.settings();
} }
protected onAfterAttach(msg: Message): void { protected override onAfterAttach(msg: Message): void {
if (this.widget.isAttached) { if (this.widget.isAttached) {
Widget.detach(this.widget); Widget.detach(this.widget);
} }
@ -97,12 +97,12 @@ export class SettingsDialog extends AbstractDialog<Promise<Settings>> {
this.update(); this.update();
} }
protected onUpdateRequest(msg: Message): void { protected override onUpdateRequest(msg: Message): void {
super.onUpdateRequest(msg); super.onUpdateRequest(msg);
this.widget.update(); this.widget.update();
} }
protected onActivateRequest(msg: Message): void { protected override onActivateRequest(msg: Message): void {
super.onActivateRequest(msg); super.onActivateRequest(msg);
// calling settingsService.reset() in order to reload the settings from the preferenceService // calling settingsService.reset() in order to reload the settings from the preferenceService
@ -172,17 +172,17 @@ export class AdditionalUrlsDialog extends AbstractDialog<string[]> {
return AdditionalUrls.parse(this.textArea.value, 'newline'); return AdditionalUrls.parse(this.textArea.value, 'newline');
} }
protected onAfterAttach(message: Message): void { protected override onAfterAttach(message: Message): void {
super.onAfterAttach(message); super.onAfterAttach(message);
this.addUpdateListener(this.textArea, 'input'); this.addUpdateListener(this.textArea, 'input');
} }
protected onActivateRequest(message: Message): void { protected override onActivateRequest(message: Message): void {
super.onActivateRequest(message); super.onActivateRequest(message);
this.textArea.focus(); this.textArea.focus();
} }
protected handleEnter(event: KeyboardEvent): boolean | void { protected override handleEnter(event: KeyboardEvent): boolean | void {
if (event.target instanceof HTMLInputElement) { if (event.target instanceof HTMLInputElement) {
return super.handleEnter(event); return super.handleEnter(event);
} }

View File

@ -61,7 +61,7 @@ export class UserFieldsDialog extends AbstractDialog<BoardUserField[]> {
constructor( constructor(
@inject(UserFieldsDialogProps) @inject(UserFieldsDialogProps)
protected readonly props: UserFieldsDialogProps protected override readonly props: UserFieldsDialogProps
) { ) {
super({ super({
title: UploadSketch.Commands.UPLOAD_WITH_CONFIGURATION.label || '', title: UploadSketch.Commands.UPLOAD_WITH_CONFIGURATION.label || '',
@ -83,7 +83,7 @@ export class UserFieldsDialog extends AbstractDialog<BoardUserField[]> {
return this.widget.currentUserFields; return this.widget.currentUserFields;
} }
protected onAfterAttach(msg: Message): void { protected override onAfterAttach(msg: Message): void {
if (this.widget.isAttached) { if (this.widget.isAttached) {
Widget.detach(this.widget); Widget.detach(this.widget);
} }
@ -92,17 +92,17 @@ export class UserFieldsDialog extends AbstractDialog<BoardUserField[]> {
this.update(); this.update();
} }
protected onUpdateRequest(msg: Message): void { protected override onUpdateRequest(msg: Message): void {
super.onUpdateRequest(msg); super.onUpdateRequest(msg);
this.widget.update(); this.widget.update();
} }
protected onActivateRequest(msg: Message): void { protected override onActivateRequest(msg: Message): void {
super.onActivateRequest(msg); super.onActivateRequest(msg);
this.widget.activate(); this.widget.activate();
} }
protected async accept(): Promise<void> { protected override async accept(): Promise<void> {
// If the user presses enter and at least // If the user presses enter and at least
// a field is empty don't accept the input // a field is empty don't accept the input
for (const field of this.value) { for (const field of this.value) {
@ -113,7 +113,7 @@ export class UserFieldsDialog extends AbstractDialog<BoardUserField[]> {
return super.accept(); return super.accept();
} }
close(): void { override close(): void {
this.widget.resetUserFieldsValue(); this.widget.resetUserFieldsValue();
this.widget.close(); this.widget.close();
super.close(); super.close();

View File

@ -38,7 +38,7 @@ export class LibraryListWidget extends ListWidget<LibraryPackage> {
} }
@postConstruct() @postConstruct()
protected init(): void { protected override init(): void {
super.init(); super.init();
this.toDispose.pushAll([ this.toDispose.pushAll([
this.notificationCenter.onLibraryInstalled(() => this.refresh(undefined)), this.notificationCenter.onLibraryInstalled(() => this.refresh(undefined)),
@ -48,7 +48,7 @@ export class LibraryListWidget extends ListWidget<LibraryPackage> {
]); ]);
} }
protected async install({ protected override async install({
item, item,
progressId, progressId,
version, version,
@ -158,7 +158,7 @@ export class LibraryListWidget extends ListWidget<LibraryPackage> {
} }
} }
protected async uninstall({ protected override async uninstall({
item, item,
progressId, progressId,
}: { }: {
@ -199,7 +199,7 @@ class MessageBoxDialog extends AbstractDialog<MessageBoxDialog.Result> {
}); });
} }
protected onCloseRequest(message: Message): void { protected override onCloseRequest(message: Message): void {
super.onCloseRequest(message); super.onCloseRequest(message);
this.accept(); this.accept();
} }
@ -217,7 +217,7 @@ class MessageBoxDialog extends AbstractDialog<MessageBoxDialog.Result> {
return message; return message;
} }
protected handleEnter(event: KeyboardEvent): boolean | void { protected override handleEnter(event: KeyboardEvent): boolean | void {
this.response = 0; this.response = 0;
super.handleEnter(event); super.handleEnter(event);
} }

View File

@ -28,7 +28,7 @@ export class LibraryListWidgetFrontendContribution
this.openView(); this.openView();
} }
registerMenus(menus: MenuModelRegistry): void { override registerMenus(menus: MenuModelRegistry): void {
if (this.toggleCommand) { if (this.toggleCommand) {
menus.registerMenuAction(ArduinoMenus.TOOLS__MAIN_GROUP, { menus.registerMenuAction(ArduinoMenus.TOOLS__MAIN_GROUP, {
commandId: this.toggleCommand.id, commandId: this.toggleCommand.id,

View File

@ -1,4 +1,8 @@
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify'; import {
inject,
injectable,
postConstruct,
} from '@theia/core/shared/inversify';
import { Emitter } from '@theia/core/lib/common/event'; import { Emitter } from '@theia/core/lib/common/event';
import { JsonRpcProxy } from '@theia/core/lib/common/messaging/proxy-factory'; import { JsonRpcProxy } from '@theia/core/lib/common/messaging/proxy-factory';
import { DisposableCollection } from '@theia/core/lib/common/disposable'; import { DisposableCollection } from '@theia/core/lib/common/disposable';
@ -14,6 +18,10 @@ import {
Config, Config,
Sketch, Sketch,
} from '../common/protocol'; } from '../common/protocol';
import {
FrontendApplicationStateService,
FrontendApplicationState,
} from '@theia/core/lib/browser/frontend-application-state';
@injectable() @injectable()
export class NotificationCenter export class NotificationCenter
@ -22,8 +30,11 @@ export class NotificationCenter
@inject(NotificationServiceServer) @inject(NotificationServiceServer)
protected readonly server: JsonRpcProxy<NotificationServiceServer>; protected readonly server: JsonRpcProxy<NotificationServiceServer>;
@inject(FrontendApplicationStateService)
private readonly appStateService: FrontendApplicationStateService;
protected readonly indexUpdatedEmitter = new Emitter<void>(); protected readonly indexUpdatedEmitter = new Emitter<void>();
protected readonly daemonStartedEmitter = new Emitter<void>(); protected readonly daemonStartedEmitter = new Emitter<string>();
protected readonly daemonStoppedEmitter = new Emitter<void>(); protected readonly daemonStoppedEmitter = new Emitter<void>();
protected readonly configChangedEmitter = new Emitter<{ protected readonly configChangedEmitter = new Emitter<{
config: Config | undefined; config: Config | undefined;
@ -45,6 +56,8 @@ export class NotificationCenter
protected readonly recentSketchesChangedEmitter = new Emitter<{ protected readonly recentSketchesChangedEmitter = new Emitter<{
sketches: Sketch[]; sketches: Sketch[];
}>(); }>();
private readonly onAppStateDidChangeEmitter =
new Emitter<FrontendApplicationState>();
protected readonly toDispose = new DisposableCollection( protected readonly toDispose = new DisposableCollection(
this.indexUpdatedEmitter, this.indexUpdatedEmitter,
@ -68,10 +81,16 @@ export class NotificationCenter
readonly onLibraryUninstalled = this.libraryUninstalledEmitter.event; readonly onLibraryUninstalled = this.libraryUninstalledEmitter.event;
readonly onAttachedBoardsChanged = this.attachedBoardsChangedEmitter.event; readonly onAttachedBoardsChanged = this.attachedBoardsChangedEmitter.event;
readonly onRecentSketchesChanged = this.recentSketchesChangedEmitter.event; readonly onRecentSketchesChanged = this.recentSketchesChangedEmitter.event;
readonly onAppStateDidChange = this.onAppStateDidChangeEmitter.event;
@postConstruct() @postConstruct()
protected init(): void { protected init(): void {
this.server.setClient(this); this.server.setClient(this);
this.toDispose.push(
this.appStateService.onStateChanged((state) =>
this.onAppStateDidChangeEmitter.fire(state)
)
);
} }
onStop(): void { onStop(): void {
@ -82,8 +101,8 @@ export class NotificationCenter
this.indexUpdatedEmitter.fire(); this.indexUpdatedEmitter.fire();
} }
notifyDaemonStarted(): void { notifyDaemonStarted(port: string): void {
this.daemonStartedEmitter.fire(); this.daemonStartedEmitter.fire(port);
} }
notifyDaemonStopped(): void { notifyDaemonStopped(): void {

View File

@ -62,7 +62,7 @@ export class MonitorViewContribution
}); });
} }
registerMenus(menus: MenuModelRegistry): void { override registerMenus(menus: MenuModelRegistry): void {
if (this.toggleCommand) { if (this.toggleCommand) {
menus.registerMenuAction(ArduinoMenus.TOOLS__MAIN_GROUP, { menus.registerMenuAction(ArduinoMenus.TOOLS__MAIN_GROUP, {
commandId: this.toggleCommand.id, commandId: this.toggleCommand.id,
@ -95,7 +95,7 @@ export class MonitorViewContribution
}); });
} }
registerCommands(commands: CommandRegistry): void { override registerCommands(commands: CommandRegistry): void {
commands.registerCommand(SerialMonitor.Commands.CLEAR_OUTPUT, { commands.registerCommand(SerialMonitor.Commands.CLEAR_OUTPUT, {
isEnabled: (widget) => widget instanceof MonitorWidget, isEnabled: (widget) => widget instanceof MonitorWidget,
isVisible: (widget) => widget instanceof MonitorWidget, isVisible: (widget) => widget instanceof MonitorWidget,

View File

@ -75,21 +75,21 @@ export class MonitorWidget extends ReactWidget {
this.update(); this.update();
} }
dispose(): void { override dispose(): void {
super.dispose(); super.dispose();
} }
protected onAfterAttach(msg: Message): void { protected override onAfterAttach(msg: Message): void {
super.onAfterAttach(msg); super.onAfterAttach(msg);
this.serialConnection.openWSToBE(); this.serialConnection.openWSToBE();
} }
onCloseRequest(msg: Message): void { protected override onCloseRequest(msg: Message): void {
this.closing = true; this.closing = true;
super.onCloseRequest(msg); super.onCloseRequest(msg);
} }
protected onUpdateRequest(msg: Message): void { protected override onUpdateRequest(msg: Message): void {
// TODO: `this.isAttached` // TODO: `this.isAttached`
// See: https://github.com/eclipse-theia/theia/issues/6704#issuecomment-562574713 // See: https://github.com/eclipse-theia/theia/issues/6704#issuecomment-562574713
if (!this.closing && this.isAttached) { if (!this.closing && this.isAttached) {
@ -97,13 +97,13 @@ export class MonitorWidget extends ReactWidget {
} }
} }
protected onResize(msg: Widget.ResizeMessage): void { protected override onResize(msg: Widget.ResizeMessage): void {
super.onResize(msg); super.onResize(msg);
this.widgetHeight = msg.height; this.widgetHeight = msg.height;
this.update(); this.update();
} }
protected onActivateRequest(msg: Message): void { protected override onActivateRequest(msg: Message): void {
super.onActivateRequest(msg); super.onActivateRequest(msg);
(this.focusNode || this.node).focus(); (this.focusNode || this.node).focus();
} }

View File

@ -32,7 +32,7 @@ export class SerialMonitorSendInput extends React.Component<
this.onKeyDown = this.onKeyDown.bind(this); this.onKeyDown = this.onKeyDown.bind(this);
} }
componentDidMount(): void { override componentDidMount(): void {
this.props.serialConnection.isBESerialConnected().then((connected) => { this.props.serialConnection.isBESerialConnected().then((connected) => {
this.setState({ connected }); this.setState({ connected });
}); });
@ -50,12 +50,12 @@ export class SerialMonitorSendInput extends React.Component<
]); ]);
} }
componentWillUnmount(): void { override componentWillUnmount(): void {
// TODO: "Your preferred browser's local storage is almost full." Discard `content` before saving layout? // TODO: "Your preferred browser's local storage is almost full." Discard `content` before saving layout?
this.toDisposeBeforeUnmount.dispose(); this.toDisposeBeforeUnmount.dispose();
} }
render(): React.ReactNode { override render(): React.ReactNode {
return ( return (
<input <input
ref={this.setRef} ref={this.setRef}

View File

@ -29,7 +29,7 @@ export class SerialMonitorOutput extends React.Component<
}; };
} }
render(): React.ReactNode { override render(): React.ReactNode {
return ( return (
<List <List
className="serial-monitor-messages" className="serial-monitor-messages"
@ -51,11 +51,11 @@ export class SerialMonitorOutput extends React.Component<
); );
} }
shouldComponentUpdate(): boolean { override shouldComponentUpdate(): boolean {
return true; return true;
} }
componentDidMount(): void { override componentDidMount(): void {
this.scrollToBottom(); this.scrollToBottom();
this.toDisposeBeforeUnmount.pushAll([ this.toDisposeBeforeUnmount.pushAll([
this.props.serialConnection.onRead(({ messages }) => { this.props.serialConnection.onRead(({ messages }) => {
@ -87,7 +87,7 @@ export class SerialMonitorOutput extends React.Component<
]); ]);
} }
componentWillUnmount(): void { override componentWillUnmount(): void {
// TODO: "Your preferred browser's local storage is almost full." Discard `content` before saving layout? // TODO: "Your preferred browser's local storage is almost full." Discard `content` before saving layout?
this.toDisposeBeforeUnmount.dispose(); this.toDisposeBeforeUnmount.dispose();
} }

View File

@ -45,7 +45,7 @@ export class PlotterFrontendContribution extends Contribution {
@inject(BoardsServiceProvider) @inject(BoardsServiceProvider)
protected readonly boardsServiceProvider: BoardsServiceProvider; protected readonly boardsServiceProvider: BoardsServiceProvider;
onStart(app: FrontendApplication): MaybePromise<void> { override onStart(app: FrontendApplication): MaybePromise<void> {
this.url = new Endpoint({ path: '/plotter' }).getRestUrl().toString(); this.url = new Endpoint({ path: '/plotter' }).getRestUrl().toString();
ipcRenderer.on('CLOSE_CHILD_WINDOW', async () => { ipcRenderer.on('CLOSE_CHILD_WINDOW', async () => {
@ -56,13 +56,13 @@ export class PlotterFrontendContribution extends Contribution {
return super.onStart(app); return super.onStart(app);
} }
registerCommands(registry: CommandRegistry): void { override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(SerialPlotterContribution.Commands.OPEN, { registry.registerCommand(SerialPlotterContribution.Commands.OPEN, {
execute: this.connect.bind(this), execute: this.connect.bind(this),
}); });
} }
registerMenus(menus: MenuModelRegistry): void { override registerMenus(menus: MenuModelRegistry): void {
menus.registerMenuAction(ArduinoMenus.TOOLS__MAIN_GROUP, { menus.registerMenuAction(ArduinoMenus.TOOLS__MAIN_GROUP, {
commandId: SerialPlotterContribution.Commands.OPEN.id, commandId: SerialPlotterContribution.Commands.OPEN.id,
label: SerialPlotterContribution.Commands.OPEN.label, label: SerialPlotterContribution.Commands.OPEN.label,

View File

@ -0,0 +1,10 @@
import { AboutDialog as TheiaAboutDialog } from '@theia/core/lib/browser/about-dialog';
import { duration } from '../../../common/decorators';
export class AboutDialog extends TheiaAboutDialog {
@duration({ name: 'theia-about#init' })
protected override async init(): Promise<void> {
// NOOP
// IDE2 has a custom about dialog, so it does not make sense to collect Theia extensions at startup time.
}
}

View File

@ -15,7 +15,7 @@ import {
} from '@theia/core/lib/browser'; } from '@theia/core/lib/browser';
import { Sketch } from '../../../common/protocol'; import { Sketch } from '../../../common/protocol';
import { SaveAsSketch } from '../../contributions/save-as-sketch'; import { SaveAsSketch } from '../../contributions/save-as-sketch';
import { SketchesServiceClientImpl } from '../../../common/protocol/sketches-service-client-impl'; import { CurrentSketch, SketchesServiceClientImpl } from '../../../common/protocol/sketches-service-client-impl';
import { nls } from '@theia/core/lib/common'; import { nls } from '@theia/core/lib/common';
import URI from '@theia/core/lib/common/uri'; import URI from '@theia/core/lib/common/uri';
@ -33,7 +33,7 @@ export class ApplicationShell extends TheiaApplicationShell {
@inject(ConnectionStatusService) @inject(ConnectionStatusService)
protected readonly connectionStatusService: ConnectionStatusService; protected readonly connectionStatusService: ConnectionStatusService;
protected track(widget: Widget): void { protected override track(widget: Widget): void {
super.track(widget); super.track(widget);
if (widget instanceof OutputWidget) { if (widget instanceof OutputWidget) {
widget.title.closable = false; // TODO: https://arduino.slack.com/archives/C01698YT7S4/p1598011990133700 widget.title.closable = false; // TODO: https://arduino.slack.com/archives/C01698YT7S4/p1598011990133700
@ -41,7 +41,7 @@ export class ApplicationShell extends TheiaApplicationShell {
if (widget instanceof EditorWidget) { if (widget instanceof EditorWidget) {
// Make the editor un-closeable asynchronously. // Make the editor un-closeable asynchronously.
this.sketchesServiceClient.currentSketch().then((sketch) => { this.sketchesServiceClient.currentSketch().then((sketch) => {
if (sketch) { if (CurrentSketch.isValid(sketch)) {
if (!this.isSketchFile(widget.editor.uri, sketch.uri)) { if (!this.isSketchFile(widget.editor.uri, sketch.uri)) {
return; return;
} }
@ -61,7 +61,7 @@ export class ApplicationShell extends TheiaApplicationShell {
return false; return false;
} }
async addWidget( override async addWidget(
widget: Widget, widget: Widget,
options: Readonly<TheiaApplicationShell.WidgetOptions> = {} options: Readonly<TheiaApplicationShell.WidgetOptions> = {}
): Promise<void> { ): Promise<void> {
@ -87,19 +87,19 @@ export class ApplicationShell extends TheiaApplicationShell {
return super.addWidget(widget, { ...options, ref }); return super.addWidget(widget, { ...options, ref });
} }
handleEvent(): boolean { override handleEvent(): boolean {
// NOOP, dragging has been disabled // NOOP, dragging has been disabled
return false return false;
} }
// Avoid hiding top panel as we use it for arduino toolbar // Avoid hiding top panel as we use it for arduino toolbar
protected createTopPanel(): Panel { protected override createTopPanel(): Panel {
const topPanel = super.createTopPanel(); const topPanel = super.createTopPanel();
topPanel.show(); topPanel.show();
return topPanel; return topPanel;
} }
async saveAll(): Promise<void> { override async saveAll(): Promise<void> {
if ( if (
this.connectionStatusService.currentStatus === ConnectionStatus.OFFLINE this.connectionStatusService.currentStatus === ConnectionStatus.OFFLINE
) { ) {

View File

@ -12,12 +12,12 @@ export class BrowserMainMenuFactory
{ {
protected menuBar: MenuBarWidget | undefined; protected menuBar: MenuBarWidget | undefined;
createMenuBar(): MenuBarWidget { override createMenuBar(): MenuBarWidget {
this.menuBar = super.createMenuBar(); this.menuBar = super.createMenuBar();
return this.menuBar; return this.menuBar;
} }
update() { update(): void {
if (this.menuBar) { if (this.menuBar) {
this.menuBar.clearMenus(); this.menuBar.clearMenus();
this.fillMenuBar(this.menuBar); this.fillMenuBar(this.menuBar);

View File

@ -4,7 +4,7 @@ import { BrowserMenuBarContribution } from '@theia/core/lib/browser/menu/browser
@injectable() @injectable()
export class ArduinoMenuContribution extends BrowserMenuBarContribution { export class ArduinoMenuContribution extends BrowserMenuBarContribution {
onStart(app: FrontendApplication): void { override onStart(app: FrontendApplication): void {
const menu = this.factory.createMenuBar(); const menu = this.factory.createMenuBar();
app.shell.addWidget(menu, { area: 'top' }); app.shell.addWidget(menu, { area: 'top' });
} }

View File

@ -8,7 +8,7 @@ import { CommandRegistry } from '@theia/core/lib/common/command';
@injectable() @injectable()
export class CommonFrontendContribution extends TheiaCommonFrontendContribution { export class CommonFrontendContribution extends TheiaCommonFrontendContribution {
registerCommands(commandRegistry: CommandRegistry): void { override registerCommands(commandRegistry: CommandRegistry): void {
super.registerCommands(commandRegistry); super.registerCommands(commandRegistry);
for (const command of [ for (const command of [
@ -26,7 +26,7 @@ export class CommonFrontendContribution extends TheiaCommonFrontendContribution
} }
} }
registerMenus(registry: MenuModelRegistry): void { override registerMenus(registry: MenuModelRegistry): void {
super.registerMenus(registry); super.registerMenus(registry);
for (const command of [ for (const command of [
CommonCommands.SAVE, CommonCommands.SAVE,

View File

@ -1,4 +1,8 @@
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify'; import {
inject,
injectable,
postConstruct,
} from '@theia/core/shared/inversify';
import { Disposable } from '@theia/core/lib/common/disposable'; import { Disposable } from '@theia/core/lib/common/disposable';
import { StatusBarAlignment } from '@theia/core/lib/browser/status-bar/status-bar'; import { StatusBarAlignment } from '@theia/core/lib/browser/status-bar/status-bar';
import { import {
@ -18,18 +22,22 @@ export class FrontendConnectionStatusService extends TheiaFrontendConnectionStat
@inject(NotificationCenter) @inject(NotificationCenter)
protected readonly notificationCenter: NotificationCenter; protected readonly notificationCenter: NotificationCenter;
protected isRunning = false; protected connectedPort: string | undefined;
@postConstruct() @postConstruct()
protected async init(): Promise<void> { protected override async init(): Promise<void> {
this.schedulePing(); this.schedulePing();
try { try {
this.isRunning = await this.daemon.isRunning(); this.connectedPort = await this.daemon.tryGetPort();
} catch {} } catch {}
this.notificationCenter.onDaemonStarted(() => (this.isRunning = true)); this.notificationCenter.onDaemonStarted(
this.notificationCenter.onDaemonStopped(() => (this.isRunning = false)); (port) => (this.connectedPort = port)
);
this.notificationCenter.onDaemonStopped(
() => (this.connectedPort = undefined)
);
this.wsConnectionProvider.onIncomingMessageActivity(() => { this.wsConnectionProvider.onIncomingMessageActivity(() => {
this.updateStatus(this.isRunning); this.updateStatus(!!this.connectedPort);
this.schedulePing(); this.schedulePing();
}); });
} }
@ -43,32 +51,36 @@ export class ApplicationConnectionStatusContribution extends TheiaApplicationCon
@inject(NotificationCenter) @inject(NotificationCenter)
protected readonly notificationCenter: NotificationCenter; protected readonly notificationCenter: NotificationCenter;
protected isRunning = false; protected connectedPort: string | undefined;
@postConstruct() @postConstruct()
protected async init(): Promise<void> { protected async init(): Promise<void> {
try { try {
this.isRunning = await this.daemon.isRunning(); this.connectedPort = await this.daemon.tryGetPort();
} catch {} } catch {}
this.notificationCenter.onDaemonStarted(() => (this.isRunning = true)); this.notificationCenter.onDaemonStarted(
this.notificationCenter.onDaemonStopped(() => (this.isRunning = false)); (port) => (this.connectedPort = port)
);
this.notificationCenter.onDaemonStopped(
() => (this.connectedPort = undefined)
);
} }
protected onStateChange(state: ConnectionStatus): void { protected override onStateChange(state: ConnectionStatus): void {
if (!this.isRunning && state === ConnectionStatus.ONLINE) { if (!this.connectedPort && state === ConnectionStatus.ONLINE) {
return; return;
} }
super.onStateChange(state); super.onStateChange(state);
} }
protected handleOffline(): void { protected override handleOffline(): void {
this.statusBar.setElement('connection-status', { this.statusBar.setElement('connection-status', {
alignment: StatusBarAlignment.LEFT, alignment: StatusBarAlignment.LEFT,
text: this.isRunning text: this.connectedPort
? nls.localize('theia/core/offline', 'Offline') ? nls.localize('theia/core/offline', 'Offline')
: '$(bolt) ' + : '$(bolt) ' +
nls.localize('theia/core/daemonOffline', 'CLI Daemon Offline'), nls.localize('theia/core/daemonOffline', 'CLI Daemon Offline'),
tooltip: this.isRunning tooltip: this.connectedPort
? nls.localize( ? nls.localize(
'theia/core/cannotConnectBackend', 'theia/core/cannotConnectBackend',
'Cannot connect to the backend.' 'Cannot connect to the backend.'

View File

@ -20,22 +20,22 @@ export class FrontendApplication extends TheiaFrontendApplication {
@inject(SketchesService) @inject(SketchesService)
protected readonly sketchesService: SketchesService; protected readonly sketchesService: SketchesService;
protected async initializeLayout(): Promise<void> { protected override async initializeLayout(): Promise<void> {
await super.initializeLayout(); await super.initializeLayout();
const roots = await this.workspaceService.roots; this.workspaceService.roots.then(async (roots) => {
for (const root of roots) { for (const root of roots) {
const exists = await this.fileService.exists(root.resource);
if (exists) {
this.sketchesService.markAsRecentlyOpened(root.resource.toString()); // no await, will get the notification later and rebuild the menu
await this.commandService.executeCommand( await this.commandService.executeCommand(
ArduinoCommands.OPEN_SKETCH_FILES.id, ArduinoCommands.OPEN_SKETCH_FILES.id,
root.resource root.resource
); );
this.sketchesService.markAsRecentlyOpened(root.resource.toString()); // no await, will get the notification later and rebuild the menu
} }
} });
} }
protected getStartupIndicator(host: HTMLElement): HTMLElement | undefined { protected override getStartupIndicator(
host: HTMLElement
): HTMLElement | undefined {
let startupElement = this.doGetStartupIndicator(host, 'old-theia-preload'); // https://github.com/eclipse-theia/theia/pull/10761#issuecomment-1131476318 let startupElement = this.doGetStartupIndicator(host, 'old-theia-preload'); // https://github.com/eclipse-theia/theia/pull/10761#issuecomment-1131476318
if (!startupElement) { if (!startupElement) {
startupElement = this.doGetStartupIndicator(host, 'theia-preload'); // We show the new Theia spinner in dev mode. startupElement = this.doGetStartupIndicator(host, 'theia-preload'); // We show the new Theia spinner in dev mode.

View File

@ -0,0 +1,11 @@
import { injectable } from '@theia/core/shared/inversify';
import { DefaultJsonSchemaContribution as TheiaDefaultJsonSchemaContribution } from '@theia/core/lib/browser/json-schema-store';
@injectable()
export class DefaultJsonSchemaContribution extends TheiaDefaultJsonSchemaContribution {
override async registerSchemas(): Promise<void> {
// NOOP
// Do not fetch the https://www.schemastore.org/api/json/catalog.json on every single browser window load.
// If the schemas are required in the future, we should fetch the `catalog.json` on build time and load it.
}
}

View File

@ -1,30 +0,0 @@
import { injectable } from '@theia/core/shared/inversify';
import { Command } from '@theia/core/lib/common/command';
import { Keybinding } from '@theia/core/lib/common/keybinding';
import {
KeybindingRegistry as TheiaKeybindingRegistry,
KeybindingScope,
} from '@theia/core/lib/browser/keybinding';
@injectable()
export class KeybindingRegistry extends TheiaKeybindingRegistry {
// https://github.com/eclipse-theia/theia/issues/8209
unregisterKeybinding(key: string): void;
unregisterKeybinding(keybinding: Keybinding): void;
unregisterKeybinding(command: Command): void;
unregisterKeybinding(arg: string | Keybinding | Command): void {
const keymap = this.keymaps[KeybindingScope.DEFAULT];
const filter = Command.is(arg)
? ({ command }: Keybinding) => command === arg.id
: ({ keybinding }: Keybinding) =>
Keybinding.is(arg)
? keybinding === arg.keybinding
: keybinding === arg;
for (const binding of keymap.filter(filter)) {
const idx = keymap.indexOf(binding);
if (idx !== -1) {
keymap.splice(idx, 1);
}
}
}
}

View File

@ -23,7 +23,7 @@ export class ShellLayoutRestorer extends TheiaShellLayoutRestorer {
} }
} }
async restoreLayout(app: FrontendApplication): Promise<boolean> { override async restoreLayout(app: FrontendApplication): Promise<boolean> {
this.logger.info('>>> Restoring the layout state...'); this.logger.info('>>> Restoring the layout state...');
const serializedLayoutData = await this.storageService.getData<string>( const serializedLayoutData = await this.storageService.getData<string>(
this.storageKey this.storageKey

View File

@ -27,7 +27,7 @@ export class TabBarDecoratorService extends TheiaTabBarDecoratorService {
); );
} }
getDecorations(title: Title<Widget>): WidgetDecoration.Data[] { override getDecorations(title: Title<Widget>): WidgetDecoration.Data[] {
if (title.owner instanceof EditorWidget) { if (title.owner instanceof EditorWidget) {
const editor = title.owner.editor; const editor = title.owner.editor;
if (this.dataDirUri && this.dataDirUri.isEqualOrParent(editor.uri)) { if (this.dataDirUri && this.dataDirUri.isEqualOrParent(editor.uri)) {

View File

@ -12,7 +12,7 @@ export class TabBarToolbar extends TheiaTabBarToolbar {
* Copied over from Theia. Added an ID to the parent of the toolbar item (`--container`). * Copied over from Theia. Added an ID to the parent of the toolbar item (`--container`).
* CSS3 does not support parent selectors but we want to style the parent of the toolbar item. * CSS3 does not support parent selectors but we want to style the parent of the toolbar item.
*/ */
protected renderItem(item: TabBarToolbarItem): React.ReactNode { protected override renderItem(item: TabBarToolbarItem): React.ReactNode {
let innerText = ''; let innerText = '';
const classNames = []; const classNames = [];
if (item.text) { if (item.text) {

View File

@ -3,7 +3,7 @@ import { Saveable } from '@theia/core/lib/browser/saveable';
import { TabBarRenderer as TheiaTabBarRenderer } from '@theia/core/lib/browser/shell/tab-bars'; import { TabBarRenderer as TheiaTabBarRenderer } from '@theia/core/lib/browser/shell/tab-bars';
export class TabBarRenderer extends TheiaTabBarRenderer { export class TabBarRenderer extends TheiaTabBarRenderer {
createTabClass(data: TabBar.IRenderData<any>): string { override createTabClass(data: TabBar.IRenderData<any>): string {
let className = super.createTabClass(data); let className = super.createTabClass(data);
if (!data.title.closable && Saveable.isDirty(data.title.owner)) { if (!data.title.closable && Saveable.isDirty(data.title.owner)) {
className += ' p-mod-closable'; className += ' p-mod-closable';

View File

@ -7,7 +7,10 @@ import { DebugConfiguration } from '@theia/debug/lib/common/debug-common';
import { DebugConfigurationModel as TheiaDebugConfigurationModel } from '@theia/debug/lib/browser/debug-configuration-model'; import { DebugConfigurationModel as TheiaDebugConfigurationModel } from '@theia/debug/lib/browser/debug-configuration-model';
import { DebugConfigurationManager as TheiaDebugConfigurationManager } from '@theia/debug/lib/browser/debug-configuration-manager'; import { DebugConfigurationManager as TheiaDebugConfigurationManager } from '@theia/debug/lib/browser/debug-configuration-manager';
import { SketchesService } from '../../../common/protocol'; import { SketchesService } from '../../../common/protocol';
import { SketchesServiceClientImpl } from '../../../common/protocol/sketches-service-client-impl'; import {
CurrentSketch,
SketchesServiceClientImpl,
} from '../../../common/protocol/sketches-service-client-impl';
import { DebugConfigurationModel } from './debug-configuration-model'; import { DebugConfigurationModel } from './debug-configuration-model';
import { import {
FileOperationError, FileOperationError,
@ -36,7 +39,7 @@ export class DebugConfigurationManager extends TheiaDebugConfigurationManager {
} }
@postConstruct() @postConstruct()
protected async init(): Promise<void> { protected override async init(): Promise<void> {
super.init(); super.init();
this.appStateService.reachedState('ready').then(async () => { this.appStateService.reachedState('ready').then(async () => {
const tempContent = await this.getTempLaunchJsonContent(); const tempContent = await this.getTempLaunchJsonContent();
@ -73,7 +76,7 @@ export class DebugConfigurationManager extends TheiaDebugConfigurationManager {
}); });
} }
protected updateModels = debounce(async () => { protected override updateModels = debounce(async () => {
await this.appStateService.reachedState('ready'); await this.appStateService.reachedState('ready');
const roots = await this.workspaceService.roots; const roots = await this.workspaceService.roots;
const toDelete = new Set(this.models.keys()); const toDelete = new Set(this.models.keys());
@ -113,7 +116,7 @@ export class DebugConfigurationManager extends TheiaDebugConfigurationManager {
(TheiaDebugConfigurationModel.JsonContent & { uri: URI }) | URI | undefined (TheiaDebugConfigurationModel.JsonContent & { uri: URI }) | URI | undefined
> { > {
const sketch = await this.sketchesServiceClient.currentSketch(); const sketch = await this.sketchesServiceClient.currentSketch();
if (!sketch) { if (!CurrentSketch.isValid(sketch)) {
return undefined; return undefined;
} }
const uri = await this.sketchesService.getIdeTempFolderUri(sketch); const uri = await this.sketchesService.getIdeTempFolderUri(sketch);

View File

@ -6,8 +6,8 @@ import { DebugConfigurationModel as TheiaDebugConfigurationModel } from '@theia/
export class DebugConfigurationModel extends TheiaDebugConfigurationModel { export class DebugConfigurationModel extends TheiaDebugConfigurationModel {
constructor( constructor(
readonly workspaceFolderUri: string, override readonly workspaceFolderUri: string,
protected readonly preferences: PreferenceService, protected override readonly preferences: PreferenceService,
protected readonly config: DebugConfiguration[], protected readonly config: DebugConfiguration[],
protected configUri: URI | undefined, protected configUri: URI | undefined,
protected readonly onConfigDidChange: Event<TheiaDebugConfigurationModel.JsonContent> protected readonly onConfigDidChange: Event<TheiaDebugConfigurationModel.JsonContent>
@ -25,7 +25,7 @@ export class DebugConfigurationModel extends TheiaDebugConfigurationModel {
this.reconcile(); this.reconcile();
} }
protected parseConfigurations(): TheiaDebugConfigurationModel.JsonContent { protected override parseConfigurations(): TheiaDebugConfigurationModel.JsonContent {
return { return {
uri: this.configUri, uri: this.configUri,
configurations: this.config, configurations: this.config,

View File

@ -13,7 +13,7 @@ export class DebugFrontendApplicationContribution extends TheiaDebugFrontendAppl
this.options.defaultWidgetOptions.rank = 4; this.options.defaultWidgetOptions.rank = 4;
} }
registerMenus(registry: MenuModelRegistry): void { override registerMenus(registry: MenuModelRegistry): void {
super.registerMenus(registry); super.registerMenus(registry);
unregisterSubmenu(DebugMenus.DEBUG, registry); unregisterSubmenu(DebugMenus.DEBUG, registry);
} }

View File

@ -1,21 +0,0 @@
import { injectable } from '@theia/core/shared/inversify';
import {
ExpressionItem,
DebugVariable,
} from '@theia/debug/lib/browser/console/debug-console-items';
import { DebugHoverSource as TheiaDebugHoverSource } from '@theia/debug/lib/browser/editor/debug-hover-source';
// TODO: remove after https://github.com/eclipse-theia/theia/pull/9256/.
@injectable()
export class DebugHoverSource extends TheiaDebugHoverSource {
async evaluate2(
expression: string
): Promise<ExpressionItem | DebugVariable | undefined> {
const evaluated = await this.doEvaluate(expression);
const elements = evaluated && (await evaluated.getElements());
this._expression = evaluated;
this.elements = elements ? [...elements] : [];
this.fireDidChange();
return evaluated;
}
}

View File

@ -1,119 +0,0 @@
import { injectable, interfaces, Container } from '@theia/core/shared/inversify';
import { Widget } from '@theia/core/shared/@phosphor/widgets';
import { SourceTreeWidget } from '@theia/core/lib/browser/source-tree';
import { DisposableCollection } from '@theia/core/lib/common/disposable';
import { DebugEditor } from '@theia/debug/lib/browser/editor/debug-editor';
import { DebugVariable } from '@theia/debug/lib/browser/console/debug-console-items';
import { DebugExpressionProvider } from '@theia/debug/lib/browser/editor/debug-expression-provider';
import { DebugHoverSource as TheiaDebugHoverSource } from '@theia/debug/lib/browser/editor/debug-hover-source';
import {
DebugHoverWidget as TheiaDebugHoverWidget,
ShowDebugHoverOptions,
} from '@theia/debug/lib/browser/editor/debug-hover-widget';
import { DebugHoverSource } from './debug-hover-source';
export function createDebugHoverWidgetContainer(
parent: interfaces.Container,
editor: DebugEditor
): Container {
const child = SourceTreeWidget.createContainer(parent, {
virtualized: false,
});
child.bind(DebugEditor).toConstantValue(editor);
child.bind(TheiaDebugHoverSource).toSelf();
child.bind(DebugHoverSource).toSelf();
child.rebind(TheiaDebugHoverSource).to(DebugHoverSource);
child.unbind(SourceTreeWidget);
child.bind(DebugExpressionProvider).toSelf();
child.bind(TheiaDebugHoverWidget).toSelf();
child.bind(DebugHoverWidget).toSelf();
child.rebind(TheiaDebugHoverWidget).to(DebugHoverWidget);
return child;
}
// TODO: remove patch after https://github.com/eclipse-theia/theia/pull/9256/
@injectable()
export class DebugHoverWidget extends TheiaDebugHoverWidget {
protected async doShow(
options: ShowDebugHoverOptions | undefined = this.options
): Promise<void> {
if (!this.isEditorFrame()) {
this.hide();
return;
}
if (!options) {
this.hide();
return;
}
if (this.options && this.options.selection.equalsRange(options.selection)) {
return;
}
if (!this.isAttached) {
Widget.attach(this, this.contentNode);
}
this.options = options;
const matchingExpression = this.expressionProvider.get(
this.editor.getControl().getModel()!,
options.selection
);
if (!matchingExpression) {
this.hide();
return;
}
const toFocus = new DisposableCollection();
if (this.options.focus === true) {
toFocus.push(
this.model.onNodeRefreshed(() => {
toFocus.dispose();
this.activate();
})
);
}
const expression = await (this.hoverSource as DebugHoverSource).evaluate2(
matchingExpression
);
if (!expression || !expression.value) {
toFocus.dispose();
this.hide();
return;
}
this.contentNode.hidden = false;
['number', 'boolean', 'string'].forEach((token) =>
this.titleNode.classList.remove(token)
);
this.domNode.classList.remove('complex-value');
if (expression.hasElements) {
this.domNode.classList.add('complex-value');
} else {
this.contentNode.hidden = true;
if (
expression.type === 'number' ||
expression.type === 'boolean' ||
expression.type === 'string'
) {
this.titleNode.classList.add(expression.type);
} else if (!isNaN(+expression.value)) {
this.titleNode.classList.add('number');
} else if (DebugVariable.booleanRegex.test(expression.value)) {
this.titleNode.classList.add('boolean');
} else if (DebugVariable.stringRegex.test(expression.value)) {
this.titleNode.classList.add('string');
}
}
// super.show(); // Here we cannot call `super.show()` but have to call `show` on the `Widget` prototype.
Widget.prototype.show.call(this);
await new Promise<void>((resolve) => {
setTimeout(
() =>
window.requestAnimationFrame(() => {
this.editor.getControl().layoutContentWidget(this);
resolve();
}),
0
);
});
}
}

View File

@ -7,7 +7,7 @@ import { nls } from '@theia/core/lib/common';
@injectable() @injectable()
export class DebugSessionManager extends TheiaDebugSessionManager { export class DebugSessionManager extends TheiaDebugSessionManager {
async start(options: DebugSessionOptions): Promise<DebugSession | undefined> { override async start(options: DebugSessionOptions): Promise<DebugSession | undefined> {
return this.progressService.withProgress( return this.progressService.withProgress(
nls.localize('theia/debug/start', 'Start...'), nls.localize('theia/debug/start', 'Start...'),
'debug', 'debug',
@ -76,7 +76,7 @@ export class DebugSessionManager extends TheiaDebugSessionManager {
} }
); );
} }
async terminateSession(session?: DebugSession): Promise<void> { override async terminateSession(session?: DebugSession): Promise<void> {
if (!session) { if (!session) {
this.updateCurrentSession(this._currentSession); this.updateCurrentSession(this._currentSession);
session = this._currentSession; session = this._currentSession;

View File

@ -8,7 +8,7 @@ import {
@injectable() @injectable()
export abstract class AbstractDialog<T> extends TheiaAbstractDialog<T> { export abstract class AbstractDialog<T> extends TheiaAbstractDialog<T> {
constructor(@inject(DialogProps) protected readonly props: DialogProps) { constructor(@inject(DialogProps) protected override readonly props: DialogProps) {
super(props); super(props);
this.closeCrossNode.classList.remove(...codiconArray('close')); this.closeCrossNode.classList.remove(...codiconArray('close'));

View File

@ -4,7 +4,7 @@ import { EditorCommandContribution as TheiaEditorCommandContribution } from '@th
@injectable() @injectable()
export class EditorCommandContribution extends TheiaEditorCommandContribution { export class EditorCommandContribution extends TheiaEditorCommandContribution {
@postConstruct() @postConstruct()
protected init(): void { protected override init(): void {
// Workaround for https://github.com/eclipse-theia/theia/issues/8722. // Workaround for https://github.com/eclipse-theia/theia/issues/8722.
this.editorPreferences.onPreferenceChanged( this.editorPreferences.onPreferenceChanged(
({ preferenceName, newValue, oldValue }) => { ({ preferenceName, newValue, oldValue }) => {

View File

@ -1,9 +1,7 @@
import { EditorManager as TheiaEditorManager } from '@theia/editor/lib/browser/editor-manager'; import { EditorManager as TheiaEditorManager } from '@theia/editor/lib/browser/editor-manager';
export class EditorManager extends TheiaEditorManager { export class EditorManager extends TheiaEditorManager {
protected override getOrCreateCounterForUri(): number {
protected getOrCreateCounterForUri(): number {
return 0; return 0;
} }
} }

View File

@ -0,0 +1,11 @@
import { injectable } from '@theia/core/shared/inversify';
import { EditorNavigationContribution as TheiaEditorNavigationContribution } from '@theia/editor/lib/browser/editor-navigation-contribution';
@injectable()
export class EditorNavigationContribution extends TheiaEditorNavigationContribution {
override async onStart(): Promise<void> {
// No await.
// Restore the navigation history asynchronously.
super.onStart();
}
}

View File

@ -3,7 +3,10 @@ import URI from '@theia/core/lib/common/uri';
import { EditorWidget } from '@theia/editor/lib/browser'; import { EditorWidget } from '@theia/editor/lib/browser';
import { LabelProvider } from '@theia/core/lib/browser'; import { LabelProvider } from '@theia/core/lib/browser';
import { EditorWidgetFactory as TheiaEditorWidgetFactory } from '@theia/editor/lib/browser/editor-widget-factory'; import { EditorWidgetFactory as TheiaEditorWidgetFactory } from '@theia/editor/lib/browser/editor-widget-factory';
import { SketchesServiceClientImpl } from '../../../common/protocol/sketches-service-client-impl'; import {
CurrentSketch,
SketchesServiceClientImpl,
} from '../../../common/protocol/sketches-service-client-impl';
import { SketchesService, Sketch } from '../../../common/protocol'; import { SketchesService, Sketch } from '../../../common/protocol';
import { nls } from '@theia/core/lib/common'; import { nls } from '@theia/core/lib/common';
@ -16,9 +19,9 @@ export class EditorWidgetFactory extends TheiaEditorWidgetFactory {
protected readonly sketchesServiceClient: SketchesServiceClientImpl; protected readonly sketchesServiceClient: SketchesServiceClientImpl;
@inject(LabelProvider) @inject(LabelProvider)
protected readonly labelProvider: LabelProvider; protected override readonly labelProvider: LabelProvider;
protected async createEditor(uri: URI): Promise<EditorWidget> { protected override async createEditor(uri: URI): Promise<EditorWidget> {
const widget = await super.createEditor(uri); const widget = await super.createEditor(uri);
return this.maybeUpdateCaption(widget); return this.maybeUpdateCaption(widget);
} }
@ -28,7 +31,7 @@ export class EditorWidgetFactory extends TheiaEditorWidgetFactory {
): Promise<EditorWidget> { ): Promise<EditorWidget> {
const sketch = await this.sketchesServiceClient.currentSketch(); const sketch = await this.sketchesServiceClient.currentSketch();
const { uri } = widget.editor; const { uri } = widget.editor;
if (sketch && Sketch.isInSketch(uri, sketch)) { if (CurrentSketch.isValid(sketch) && Sketch.isInSketch(uri, sketch)) {
const isTemp = await this.sketchesService.isTemp(sketch); const isTemp = await this.sketchesService.isTemp(sketch);
if (isTemp) { if (isTemp) {
widget.title.caption = nls.localize( widget.title.caption = nls.localize(

View File

@ -9,7 +9,7 @@ import { nls } from '@theia/core/lib/common';
@injectable() @injectable()
export class KeymapsFrontendContribution extends TheiaKeymapsFrontendContribution { export class KeymapsFrontendContribution extends TheiaKeymapsFrontendContribution {
registerMenus(menus: MenuModelRegistry): void { override registerMenus(menus: MenuModelRegistry): void {
menus.registerMenuAction(ArduinoMenus.FILE__ADVANCED_SUBMENU, { menus.registerMenuAction(ArduinoMenus.FILE__ADVANCED_SUBMENU, {
commandId: KeymapsCommands.OPEN_KEYMAPS.id, commandId: KeymapsCommands.OPEN_KEYMAPS.id,
label: nls.localize( label: nls.localize(

View File

@ -6,15 +6,15 @@ import { ProblemContribution as TheiaProblemContribution } from '@theia/markers/
@injectable() @injectable()
export class ProblemContribution extends TheiaProblemContribution { export class ProblemContribution extends TheiaProblemContribution {
async initializeLayout(app: FrontendApplication): Promise<void> { override async initializeLayout(app: FrontendApplication): Promise<void> {
// NOOP // NOOP
} }
protected setStatusBarElement(problemStat: ProblemStat): void { protected override setStatusBarElement(problemStat: ProblemStat): void {
// NOOP // NOOP
} }
registerKeybindings(keybindings: KeybindingRegistry): void { override registerKeybindings(keybindings: KeybindingRegistry): void {
if (this.toggleCommand) { if (this.toggleCommand) {
keybindings.registerKeybinding({ keybindings.registerKeybinding({
command: this.toggleCommand.id, command: this.toggleCommand.id,

View File

@ -17,7 +17,7 @@ export class ProblemManager extends TheiaProblemManager {
protected dataDirUri: URI | undefined; protected dataDirUri: URI | undefined;
@postConstruct() @postConstruct()
protected init(): void { protected override init(): void {
super.init(); super.init();
this.configService this.configService
.getConfiguration() .getConfiguration()
@ -27,7 +27,7 @@ export class ProblemManager extends TheiaProblemManager {
); );
} }
setMarkers( override setMarkers(
uri: URI, uri: URI,
owner: string, owner: string,
data: Diagnostic[] data: Diagnostic[]

View File

@ -7,7 +7,7 @@ import { codicon } from '@theia/core/lib/browser';
const PerfectScrollbar = require('react-perfect-scrollbar'); const PerfectScrollbar = require('react-perfect-scrollbar');
export class NotificationCenterComponent extends TheiaNotificationCenterComponent { export class NotificationCenterComponent extends TheiaNotificationCenterComponent {
render(): React.ReactNode { override render(): React.ReactNode {
const empty = this.state.notifications.length === 0; const empty = this.state.notifications.length === 0;
const title = empty const title = empty
? nls.localize( ? nls.localize(

View File

@ -4,7 +4,7 @@ import { nls } from '@theia/core/lib/common';
import { codicon } from '@theia/core/lib/browser'; import { codicon } from '@theia/core/lib/browser';
export class NotificationComponent extends TheiaNotificationComponent { export class NotificationComponent extends TheiaNotificationComponent {
render(): React.ReactNode { override render(): React.ReactNode {
const { messageId, message, type, collapsed, expandable, source, actions } = const { messageId, message, type, collapsed, expandable, source, actions } =
this.props.notification; this.props.notification;
return ( return (

View File

@ -3,7 +3,7 @@ import { NotificationComponent } from './notification-component';
import { NotificationToastsComponent as TheiaNotificationToastsComponent } from '@theia/messages/lib/browser/notification-toasts-component'; import { NotificationToastsComponent as TheiaNotificationToastsComponent } from '@theia/messages/lib/browser/notification-toasts-component';
export class NotificationToastsComponent extends TheiaNotificationToastsComponent { export class NotificationToastsComponent extends TheiaNotificationToastsComponent {
render(): React.ReactNode { override render(): React.ReactNode {
return ( return (
<div <div
className={`theia-notifications-container theia-notification-toasts ${ className={`theia-notifications-container theia-notification-toasts ${

View File

@ -8,7 +8,7 @@ import { NotificationManager as TheiaNotificationManager } from '@theia/messages
@injectable() @injectable()
export class NotificationManager extends TheiaNotificationManager { export class NotificationManager extends TheiaNotificationManager {
async reportProgress( override async reportProgress(
messageId: string, messageId: string,
update: ProgressUpdate, update: ProgressUpdate,
originalMessage: ProgressMessage, originalMessage: ProgressMessage,
@ -34,7 +34,7 @@ export class NotificationManager extends TheiaNotificationManager {
this.fireUpdatedEvent(); this.fireUpdatedEvent();
} }
protected toPlainProgress(update: ProgressUpdate): number | undefined { protected override toPlainProgress(update: ProgressUpdate): number | undefined {
if (!update.work) { if (!update.work) {
return undefined; return undefined;
} }

View File

@ -7,7 +7,7 @@ import { NotificationsRenderer as TheiaNotificationsRenderer } from '@theia/mess
@injectable() @injectable()
export class NotificationsRenderer extends TheiaNotificationsRenderer { export class NotificationsRenderer extends TheiaNotificationsRenderer {
protected render(): void { protected override render(): void {
ReactDOM.render( ReactDOM.render(
<div> <div>
<NotificationToastsComponent <NotificationToastsComponent

View File

@ -26,7 +26,7 @@ export class MonacoEditorProvider extends TheiaMonacoEditorProvider {
@inject(SketchesServiceClientImpl) @inject(SketchesServiceClientImpl)
protected readonly sketchesServiceClient: SketchesServiceClientImpl; protected readonly sketchesServiceClient: SketchesServiceClientImpl;
protected async doCreateEditor( protected override async doCreateEditor(
uri: URI, uri: URI,
factory: EditorFactory factory: EditorFactory
): Promise<MonacoEditor> { ): Promise<MonacoEditor> {

View File

@ -3,7 +3,7 @@ import { MonacoStatusBarContribution as TheiaMonacoStatusBarContribution } from
@injectable() @injectable()
export class MonacoStatusBarContribution extends TheiaMonacoStatusBarContribution { export class MonacoStatusBarContribution extends TheiaMonacoStatusBarContribution {
protected setConfigTabSizeWidget() {} protected override setConfigTabSizeWidget() {}
protected setLineEndingWidget() {} protected override setLineEndingWidget() {}
} }

View File

@ -13,7 +13,7 @@ export class MonacoTextModelService extends TheiaMonacoTextModelService {
@inject(SketchesServiceClientImpl) @inject(SketchesServiceClientImpl)
protected readonly sketchesServiceClient: SketchesServiceClientImpl; protected readonly sketchesServiceClient: SketchesServiceClientImpl;
protected async createModel(resource: Resource): Promise<MonacoEditorModel> { protected override async createModel(resource: Resource): Promise<MonacoEditorModel> {
const factory = this.factories const factory = this.factories
.getContributions() .getContributions()
.find(({ scheme }) => resource.uri.scheme === scheme); .find(({ scheme }) => resource.uri.scheme === scheme);
@ -33,7 +33,7 @@ export class MonacoTextModelService extends TheiaMonacoTextModelService {
// https://github.com/eclipse-theia/theia/pull/8491 // https://github.com/eclipse-theia/theia/pull/8491
class SilentMonacoEditorModel extends MonacoEditorModel { class SilentMonacoEditorModel extends MonacoEditorModel {
protected trace(loggable: Loggable): void { protected override trace(loggable: Loggable): void {
if (this.logger) { if (this.logger) {
this.logger.trace((log: Log) => this.logger.trace((log: Log) =>
loggable((message, ...params) => loggable((message, ...params) =>
@ -46,24 +46,24 @@ class SilentMonacoEditorModel extends MonacoEditorModel {
class MaybeReadonlyMonacoEditorModel extends SilentMonacoEditorModel { class MaybeReadonlyMonacoEditorModel extends SilentMonacoEditorModel {
constructor( constructor(
protected readonly resource: Resource, protected override readonly resource: Resource,
protected readonly m2p: MonacoToProtocolConverter, protected override readonly m2p: MonacoToProtocolConverter,
protected readonly p2m: ProtocolToMonacoConverter, protected override readonly p2m: ProtocolToMonacoConverter,
protected readonly logger?: ILogger, protected override readonly logger?: ILogger,
protected readonly editorPreferences?: EditorPreferences, protected override readonly editorPreferences?: EditorPreferences,
protected readonly _readOnly?: boolean protected readonly _readOnly?: boolean
) { ) {
super(resource, m2p, p2m, logger, editorPreferences); super(resource, m2p, p2m, logger, editorPreferences);
} }
get readOnly(): boolean { override get readOnly(): boolean {
if (typeof this._readOnly === 'boolean') { if (typeof this._readOnly === 'boolean') {
return this._readOnly; return this._readOnly;
} }
return this.resource.saveContents === undefined; return this.resource.saveContents === undefined;
} }
protected setDirty(dirty: boolean): void { protected override setDirty(dirty: boolean): void {
if (this._readOnly === true) { if (this._readOnly === true) {
// NOOP // NOOP
return; return;

View File

@ -13,14 +13,14 @@ import { WorkspacePreferences } from '@theia/workspace/lib/browser/workspace-pre
export class FileNavigatorContribution extends TheiaFileNavigatorContribution { export class FileNavigatorContribution extends TheiaFileNavigatorContribution {
constructor( constructor(
@inject(FileNavigatorPreferences) @inject(FileNavigatorPreferences)
protected readonly fileNavigatorPreferences: FileNavigatorPreferences, protected override readonly fileNavigatorPreferences: FileNavigatorPreferences,
@inject(OpenerService) protected readonly openerService: OpenerService, @inject(OpenerService) protected override readonly openerService: OpenerService,
@inject(FileNavigatorFilter) @inject(FileNavigatorFilter)
protected readonly fileNavigatorFilter: FileNavigatorFilter, protected override readonly fileNavigatorFilter: FileNavigatorFilter,
@inject(WorkspaceService) @inject(WorkspaceService)
protected readonly workspaceService: WorkspaceService, protected override readonly workspaceService: WorkspaceService,
@inject(WorkspacePreferences) @inject(WorkspacePreferences)
protected readonly workspacePreferences: WorkspacePreferences protected override readonly workspacePreferences: WorkspacePreferences
) { ) {
super( super(
fileNavigatorPreferences, fileNavigatorPreferences,
@ -32,11 +32,11 @@ export class FileNavigatorContribution extends TheiaFileNavigatorContribution {
this.options.defaultWidgetOptions.rank = 1; this.options.defaultWidgetOptions.rank = 1;
} }
async initializeLayout(app: FrontendApplication): Promise<void> { override async initializeLayout(app: FrontendApplication): Promise<void> {
// NOOP // NOOP
} }
registerKeybindings(registry: KeybindingRegistry): void { override registerKeybindings(registry: KeybindingRegistry): void {
super.registerKeybindings(registry); super.registerKeybindings(registry);
[WorkspaceCommands.FILE_RENAME, WorkspaceCommands.FILE_DELETE].forEach( [WorkspaceCommands.FILE_RENAME, WorkspaceCommands.FILE_DELETE].forEach(
registry.unregisterKeybinding.bind(registry) registry.unregisterKeybinding.bind(registry)

View File

@ -8,11 +8,11 @@ import { NavigatorTabBarDecorator as TheiaNavigatorTabBarDecorator } from '@thei
*/ */
@injectable() @injectable()
export class NavigatorTabBarDecorator extends TheiaNavigatorTabBarDecorator { export class NavigatorTabBarDecorator extends TheiaNavigatorTabBarDecorator {
onStart(): void { override onStart(): void {
// NOOP // NOOP
} }
decorate(): WidgetDecoration.Data[] { override decorate(): WidgetDecoration.Data[] {
// Does not decorate anything. // Does not decorate anything.
return []; return [];
} }

View File

@ -12,7 +12,7 @@ export class OutlineViewContribution extends TheiaOutlineViewContribution {
}; };
} }
async initializeLayout(app: FrontendApplication): Promise<void> { override async initializeLayout(app: FrontendApplication): Promise<void> {
// NOOP // NOOP
} }
} }

View File

@ -11,7 +11,7 @@ import {
@injectable() @injectable()
export class OutputChannelManager extends TheiaOutputChannelManager { export class OutputChannelManager extends TheiaOutputChannelManager {
getChannel(name: string): TheiaOutputChannel { override getChannel(name: string): TheiaOutputChannel {
const existing = this.channels.get(name); const existing = this.channels.get(name);
if (existing) { if (existing) {
return existing; return existing;
@ -43,7 +43,7 @@ export class OutputChannelManager extends TheiaOutputChannelManager {
} }
export class OutputChannel extends TheiaOutputChannel { export class OutputChannel extends TheiaOutputChannel {
dispose(): void { override dispose(): void {
super.dispose(); super.dispose();
if ((this as any).disposed) { if ((this as any).disposed) {
const textModifyQueue: PQueue = (this as any).textModifyQueue; const textModifyQueue: PQueue = (this as any).textModifyQueue;

View File

@ -8,7 +8,7 @@ import { OutputToolbarContribution as TheiaOutputToolbarContribution } from '@th
@injectable() @injectable()
export class OutputToolbarContribution extends TheiaOutputToolbarContribution { export class OutputToolbarContribution extends TheiaOutputToolbarContribution {
async registerToolbarItems(registry: TabBarToolbarRegistry): Promise<void> { override async registerToolbarItems(registry: TabBarToolbarRegistry): Promise<void> {
await super.registerToolbarItems(registry); // Why is it async? await super.registerToolbarItems(registry); // Why is it async?
// It's a hack. Currently, it's not possible to unregister a toolbar contribution via API. // It's a hack. Currently, it's not possible to unregister a toolbar contribution via API.
( (

View File

@ -6,7 +6,7 @@ import { OutputWidget as TheiaOutputWidget } from '@theia/output/lib/browser/out
// Remove this module after ATL-222 and the Theia update. // Remove this module after ATL-222 and the Theia update.
@injectable() @injectable()
export class OutputWidget extends TheiaOutputWidget { export class OutputWidget extends TheiaOutputWidget {
protected onAfterShow(msg: Message): void { protected override onAfterShow(msg: Message): void {
super.onAfterShow(msg); super.onAfterShow(msg);
this.onResize(Widget.ResizeMessage.UnknownSize); this.onResize(Widget.ResizeMessage.UnknownSize);
} }

View File

@ -7,9 +7,9 @@ import { OutputChannelRegistryMainImpl as TheiaOutputChannelRegistryMainImpl } f
@injectable() @injectable()
export class OutputChannelRegistryMainImpl extends TheiaOutputChannelRegistryMainImpl { export class OutputChannelRegistryMainImpl extends TheiaOutputChannelRegistryMainImpl {
@inject(CommandService) @inject(CommandService)
protected readonly commandService: CommandService; protected override readonly commandService: CommandService;
$append( override $append(
name: string, name: string,
text: string, text: string,
pluginInfo: PluginInfo pluginInfo: PluginInfo
@ -21,17 +21,17 @@ export class OutputChannelRegistryMainImpl extends TheiaOutputChannelRegistryMai
return Promise.resolve(); return Promise.resolve();
} }
$clear(name: string): PromiseLike<void> { override $clear(name: string): PromiseLike<void> {
this.commandService.executeCommand(OutputCommands.CLEAR.id, { name }); this.commandService.executeCommand(OutputCommands.CLEAR.id, { name });
return Promise.resolve(); return Promise.resolve();
} }
$dispose(name: string): PromiseLike<void> { override $dispose(name: string): PromiseLike<void> {
this.commandService.executeCommand(OutputCommands.DISPOSE.id, { name }); this.commandService.executeCommand(OutputCommands.DISPOSE.id, { name });
return Promise.resolve(); return Promise.resolve();
} }
async $reveal(name: string, preserveFocus: boolean): Promise<void> { override async $reveal(name: string, preserveFocus: boolean): Promise<void> {
const options = { preserveFocus }; const options = { preserveFocus };
this.commandService.executeCommand(OutputCommands.SHOW.id, { this.commandService.executeCommand(OutputCommands.SHOW.id, {
name, name,
@ -39,7 +39,7 @@ export class OutputChannelRegistryMainImpl extends TheiaOutputChannelRegistryMai
}); });
} }
$close(name: string): PromiseLike<void> { override $close(name: string): PromiseLike<void> {
this.commandService.executeCommand(OutputCommands.HIDE.id, { name }); this.commandService.executeCommand(OutputCommands.HIDE.id, { name });
return Promise.resolve(); return Promise.resolve();
} }

Some files were not shown because too many files have changed in this diff Show More