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
# environment variables
.env
# content trace files for electron
electron-app/traces

View File

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

40
.vscode/launch.json vendored
View File

@ -1,6 +1,44 @@
{
"version": "0.2.0",
"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",
"request": "launch",
@ -10,7 +48,6 @@
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd",
},
"cwd": "${workspaceFolder}/electron-app",
"protocol": "inspector",
"args": [
".",
"--log-level=debug",
@ -78,7 +115,6 @@
{
"type": "node",
"request": "launch",
"protocol": "inspector",
"name": "Run Test [current]",
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
"args": [

View File

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

View File

@ -4,30 +4,93 @@
const version = '1.9.1';
(async () => {
const os = require('os');
const { promises: fs } = require('fs');
const path = require('path');
const shell = require('shelljs');
const { v4 } = require('uuid');
const os = require('os');
const path = require('path');
const shell = require('shelljs');
const { v4 } = require('uuid');
const repository = path.join(os.tmpdir(), `${v4()}-arduino-examples`);
if (shell.mkdir('-p', repository).code !== 0) {
shell.exit(1);
}
const repository = path.join(os.tmpdir(), `${v4()}-arduino-examples`);
if (shell.mkdir('-p', repository).code !== 0) {
shell.exit(1);
process.exit(1);
if (
shell.exec(
`git clone https://github.com/arduino/arduino-examples.git ${repository}`
).code !== 0
) {
shell.exit(1);
}
if (
shell.exec(`git -C ${repository} checkout tags/${version} -b ${version}`)
.code !== 0
) {
shell.exit(1);
}
const destination = path.join(__dirname, '..', 'Examples');
shell.mkdir('-p', 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;
}
if (shell.exec(`git clone https://github.com/arduino/arduino-examples.git ${repository}`).code !== 0) {
shell.exit(1);
process.exit(1);
};
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);
}
}
}
}
if (shell.exec(`git -C ${repository} checkout tags/${version} -b ${version}`).code !== 0) {
shell.exit(1);
process.exit(1);
}
const destination = path.join(__dirname, '..', 'Examples');
shell.mkdir('-p', destination);
shell.cp('-fR', path.join(repository, 'examples', '*'), destination);
};
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 remote from '@theia/core/electron-shared/@electron/remote';
import {
@ -7,6 +11,7 @@ import {
ExecutableService,
Sketch,
LibraryService,
ArduinoDaemon,
} from '../common/protocol';
import { Mutex } from 'async-mutex';
import {
@ -46,18 +51,12 @@ import {
EditorManager,
EditorOpenerOptions,
} 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 { FileNavigatorCommands, FileNavigatorContribution } 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 { FileNavigatorCommands } from '@theia/navigator/lib/browser/navigator-contribution';
import { TerminalMenus } from '@theia/terminal/lib/browser/terminal-frontend-contribution';
import { FileService } from '@theia/filesystem/lib/browser/file-service';
import { FileChangeType } from '@theia/filesystem/lib/browser';
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
import { ConfigService } from '../common/protocol/config-service';
import { ArduinoCommands } from './arduino-commands';
import { BoardsConfig } from './boards/boards-config';
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 { ArduinoToolbar } from './toolbar/arduino-toolbar';
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 { SketchbookWidgetContribution } from './widgets/sketchbook/sketchbook-widget-contribution';
import { IDEUpdaterDialog } from './dialogs/ide-updater/ide-updater-dialog';
import { IDEUpdater } from '../common/protocol/ide-updater';
import { FileSystemFrontendContribution } from '@theia/filesystem/lib/browser/filesystem-frontend-contribution';
@ -86,93 +87,73 @@ export class ArduinoFrontendContribution
TabBarToolbarContribution,
CommandContribution,
MenuContribution,
ColorContribution {
ColorContribution
{
@inject(ILogger)
protected logger: ILogger;
private readonly logger: ILogger;
@inject(MessageService)
protected readonly messageService: MessageService;
private readonly messageService: MessageService;
@inject(BoardsService)
protected readonly boardsService: BoardsService;
private readonly boardsService: BoardsService;
@inject(LibraryService)
protected readonly libraryService: LibraryService;
private readonly libraryService: LibraryService;
@inject(BoardsServiceProvider)
protected readonly boardsServiceClientImpl: BoardsServiceProvider;
private readonly boardsServiceClientImpl: BoardsServiceProvider;
@inject(EditorManager)
protected readonly editorManager: EditorManager;
private readonly editorManager: EditorManager;
@inject(FileService)
protected readonly fileService: FileService;
private readonly fileService: FileService;
@inject(SketchesService)
protected readonly sketchService: SketchesService;
private readonly sketchService: SketchesService;
@inject(BoardsConfigDialog)
protected readonly boardsConfigDialog: BoardsConfigDialog;
private readonly boardsConfigDialog: BoardsConfigDialog;
@inject(CommandRegistry)
protected readonly commandRegistry: CommandRegistry;
private readonly commandRegistry: CommandRegistry;
@inject(StatusBar)
protected 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;
private readonly statusBar: StatusBar;
@inject(EditorMode)
protected readonly editorMode: EditorMode;
@inject(ConfigService)
protected readonly configService: ConfigService;
private readonly editorMode: EditorMode;
@inject(HostedPluginEvents)
protected hostedPluginEvents: HostedPluginEvents;
private readonly hostedPluginEvents: HostedPluginEvents;
@inject(ExecutableService)
protected executableService: ExecutableService;
private readonly executableService: ExecutableService;
@inject(ArduinoPreferences)
protected readonly arduinoPreferences: ArduinoPreferences;
private readonly arduinoPreferences: ArduinoPreferences;
@inject(SketchesServiceClientImpl)
protected readonly sketchServiceClient: SketchesServiceClientImpl;
private readonly sketchServiceClient: SketchesServiceClientImpl;
@inject(FrontendApplicationStateService)
protected readonly appStateService: FrontendApplicationStateService;
private readonly appStateService: FrontendApplicationStateService;
@inject(LocalStorageService)
protected readonly localStorageService: LocalStorageService;
private readonly localStorageService: LocalStorageService;
@inject(FileSystemFrontendContribution)
protected readonly fileSystemFrontendContribution: FileSystemFrontendContribution;
private readonly fileSystemFrontendContribution: FileSystemFrontendContribution;
@inject(IDEUpdater)
protected readonly updater: IDEUpdater;
private readonly updater: IDEUpdater;
@inject(IDEUpdaterDialog)
protected readonly updaterDialog: IDEUpdaterDialog;
private readonly updaterDialog: IDEUpdaterDialog;
@inject(ArduinoDaemon)
private readonly daemon: ArduinoDaemon;
protected invalidConfigPopup:
| Promise<void | 'No' | 'Yes' | undefined>
@ -243,7 +224,10 @@ export class ArduinoFrontendContribution
updateStatusBar(this.boardsServiceClientImpl.boardsConfig);
this.appStateService.reachedState('ready').then(async () => {
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.onDidFilesChange(async (event) => {
@ -269,21 +253,6 @@ export class ArduinoFrontendContribution
}
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
.init(
this.arduinoPreferences.get('arduino.ide.updateChannel'),
@ -353,16 +322,18 @@ export class ArduinoFrontendContribution
app.shell.leftPanelHandler.removeBottomMenu('settings-menu');
this.fileSystemFrontendContribution.onDidChangeEditorFile(e => {
if (e.type === FileChangeType.DELETED) {
const editorWidget = e.editor;
if (SaveableWidget.is(editorWidget)) {
editorWidget.closeWithoutSaving();
} else {
editorWidget.close();
this.fileSystemFrontendContribution.onDidChangeEditorFile(
({ type, editor }) => {
if (type === FileChangeType.DELETED) {
const editorWidget = editor;
if (SaveableWidget.is(editorWidget)) {
editorWidget.closeWithoutSaving();
} else {
editorWidget.close();
}
}
}
});
);
}
onStop(): void {
@ -375,6 +346,10 @@ export class ArduinoFrontendContribution
fqbn: string,
name: string | undefined
): Promise<void> {
const port = await this.daemon.tryGetPort();
if (!port) {
return;
}
const release = await this.languageServerStartMutex.acquire();
try {
await this.hostedPluginEvents.didStart;
@ -412,7 +387,7 @@ export class ArduinoFrontendContribution
let currentSketchPath: string | undefined = undefined;
if (log) {
const currentSketch = await this.sketchServiceClient.currentSketch();
if (currentSketch) {
if (CurrentSketch.isValid(currentSketch)) {
currentSketchPath = await this.fileService.fsPath(
new URI(currentSketch.uri)
);
@ -424,8 +399,6 @@ export class ArduinoFrontendContribution
this.fileService.fsPath(new URI(lsUri)),
]);
const config = await this.configService.getConfiguration();
this.languageServerFqbn = await Promise.race([
new Promise<undefined>((_, reject) =>
setTimeout(
@ -437,7 +410,7 @@ export class ArduinoFrontendContribution
'arduino.languageserver.start',
{
lsPath,
cliDaemonAddr: `localhost:${config.daemon.port}`, // TODO: verify if this port is coming from the BE
cliDaemonAddr: `localhost:${port}`,
clangdPath,
log: currentSketchPath ? currentSketchPath : log,
cliDaemonInstance: '1',
@ -503,13 +476,13 @@ export class ArduinoFrontendContribution
EditorCommands.SPLIT_EDITOR_UP,
EditorCommands.SPLIT_EDITOR_VERTICAL,
EditorCommands.SPLIT_EDITOR_HORIZONTAL,
FileNavigatorCommands.REVEAL_IN_NAVIGATOR
FileNavigatorCommands.REVEAL_IN_NAVIGATOR,
]) {
registry.unregisterCommand(command);
}
}
registerMenus(registry: MenuModelRegistry) {
registerMenus(registry: MenuModelRegistry): void {
const menuId = (menuPath: string[]): string => {
const index = menuPath.length - 1;
const menuId = menuPath[index];
@ -578,16 +551,19 @@ export class ArduinoFrontendContribution
uri: string,
forceOpen = false,
options?: EditorOpenerOptions | undefined
): Promise<any> {
): Promise<unknown> {
const widget = this.editorManager.all.find(
(widget) => widget.editor.uri.toString() === uri
);
if (!widget || forceOpen) {
return this.editorManager.open(new URI(uri), options ?? {
mode: 'reveal',
preview: false,
counter: 0
});
return this.editorManager.open(
new URI(uri),
options ?? {
mode: 'reveal',
preview: false,
counter: 0,
}
);
}
}
@ -677,13 +653,13 @@ export class ArduinoFrontendContribution
reason: 'temp-sketch',
action: () => {
return this.showTempSketchDialog();
}
}
},
};
}
private async showTempSketchDialog(): Promise<boolean> {
const sketch = await this.sketchServiceClient.currentSketch();
if (!sketch) {
if (!CurrentSketch.isValid(sketch)) {
return true;
}
const isTemp = await this.sketchService.isTemp(sketch);
@ -693,8 +669,14 @@ export class ArduinoFrontendContribution
const messageBoxResult = await remote.dialog.showMessageBox(
remote.getCurrentWindow(),
{
message: nls.localize('arduino/sketch/saveTempSketch', 'Save your sketch to open it again later.'),
title: nls.localize('theia/core/quitTitle', 'Are you sure you want to quit?'),
message: nls.localize(
'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',
buttons: [
Dialog.CANCEL,
@ -702,7 +684,7 @@ export class ArduinoFrontendContribution
nls.localizeByDefault("Don't Save"),
],
}
)
);
const result = messageBoxResult.response;
if (result === 2) {
return true;
@ -712,10 +694,10 @@ export class ArduinoFrontendContribution
{
execOnlyIfTemp: false,
openAfterMove: false,
wipeOriginal: true
wipeOriginal: true,
}
));
}
return false
return false;
}
}

View File

@ -50,7 +50,6 @@ import {
ApplicationShell as TheiaApplicationShell,
ShellLayoutRestorer as TheiaShellLayoutRestorer,
CommonFrontendContribution as TheiaCommonFrontendContribution,
KeybindingRegistry as TheiaKeybindingRegistry,
TabBarRendererFactory,
ContextMenuRenderer,
createTreeContainer,
@ -138,7 +137,6 @@ import { PreferencesContribution } from './theia/preferences/preferences-contrib
import { QuitApp } from './contributions/quit-app';
import { SketchControl } from './contributions/sketch-control';
import { Settings } from './contributions/settings';
import { KeybindingRegistry } from './theia/core/keybindings';
import { WorkspaceCommandContribution } from './theia/workspace/workspace-commands';
import { WorkspaceDeleteHandler as TheiaWorkspaceDeleteHandler } from '@theia/workspace/lib/browser/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 { MonacoFormattingConflictsContribution } from './theia/monaco/monaco-formatting-conflicts';
import { MonacoFormattingConflictsContribution as TheiaMonacoFormattingConflictsContribution } from '@theia/monaco/lib/browser/monaco-formatting-conflicts';
const ElementQueries = require('css-element-queries/src/ElementQueries');
import { DefaultJsonSchemaContribution } from './theia/core/json-schema-store';
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({
id: 'arduino-theme',
@ -302,9 +306,6 @@ MonacoThemingService.register({
});
export default new ContainerModule((bind, unbind, isBound, rebind) => {
ElementQueries.listen();
ElementQueries.init();
// Commands and toolbar items
bind(ArduinoFrontendContribution).toSelf().inSingletonScope();
bind(CommandContribution).toService(ArduinoFrontendContribution);
@ -493,7 +494,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
rebind(TheiaPreferencesContribution)
.to(PreferencesContribution)
.inSingletonScope();
rebind(TheiaKeybindingRegistry).to(KeybindingRegistry).inSingletonScope();
rebind(TheiaWorkspaceCommandContribution)
.to(WorkspaceCommandContribution)
.inSingletonScope();
@ -560,9 +560,9 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
bind(ProblemManager).toSelf().inSingletonScope();
rebind(TheiaProblemManager).toService(ProblemManager);
// Customized layout restorer that can restore the state in async way: https://github.com/eclipse-theia/theia/issues/6579
bind(ShellLayoutRestorer).toSelf().inSingletonScope();
rebind(TheiaShellLayoutRestorer).toService(ShellLayoutRestorer);
// Customized layout restorer that can restore the state in async way: https://github.com/eclipse-theia/theia/issues/6579
bind(ShellLayoutRestorer).toSelf().inSingletonScope();
rebind(TheiaShellLayoutRestorer).toService(ShellLayoutRestorer);
// No dropdown for the _Output_ view.
bind(OutputToolbarContribution).toSelf().inSingletonScope();
@ -714,6 +714,26 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
bind(NavigatorTabBarDecorator).toSelf().inSingletonScope();
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.
bind(DebugSessionManager).toSelf().inSingletonScope();
rebind(TheiaDebugSessionManager).toService(DebugSessionManager);

View File

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

View File

@ -26,7 +26,7 @@ export class BoardsConfigDialog extends AbstractDialog<BoardsConfig.Config> {
constructor(
@inject(BoardsConfigDialogProps)
protected readonly props: BoardsConfigDialogProps
protected override readonly props: BoardsConfigDialogProps
) {
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.
*/
async open(
override async open(
query: string | undefined = undefined
): Promise<BoardsConfig.Config | undefined> {
if (typeof query === 'string') {
@ -95,7 +95,7 @@ export class BoardsConfigDialog extends AbstractDialog<BoardsConfig.Config> {
return head;
}
protected onAfterAttach(msg: Message): void {
protected override onAfterAttach(msg: Message): void {
if (this.widget.isAttached) {
Widget.detach(this.widget);
}
@ -110,23 +110,23 @@ export class BoardsConfigDialog extends AbstractDialog<BoardsConfig.Config> {
this.update();
}
protected onUpdateRequest(msg: Message) {
protected override onUpdateRequest(msg: Message): void {
super.onUpdateRequest(msg);
this.widget.update();
}
protected onActivateRequest(msg: Message): void {
protected override onActivateRequest(msg: Message): void {
super.onActivateRequest(msg);
this.widget.activate();
}
protected handleEnter(event: KeyboardEvent): boolean | void {
protected override handleEnter(event: KeyboardEvent): boolean | void {
if (event.target instanceof HTMLTextAreaElement) {
return false;
}
}
protected isValid(value: BoardsConfig.Config): DialogError {
protected override isValid(value: BoardsConfig.Config): DialogError {
if (!value.selectedBoard) {
if (value.selectedPort) {
return nls.localize(

View File

@ -16,6 +16,7 @@ import {
} from './boards-service-provider';
import { naturalCompare } from '../../common/utils';
import { nls } from '@theia/core/lib/common';
import { FrontendApplicationState } from '@theia/core/lib/common/frontend-application-state';
export namespace BoardsConfig {
export interface Config {
@ -29,6 +30,7 @@ export namespace BoardsConfig {
readonly onConfigChange: (config: Config) => void;
readonly onFocusNodeSet: (element: HTMLElement | undefined) => void;
readonly onFilteredTextDidChangeEvent: Event<string>;
readonly onAppStateDidChange: Event<FrontendApplicationState>;
}
export interface State extends Config {
@ -47,7 +49,7 @@ export abstract class Item<T> extends React.Component<{
missing?: boolean;
details?: string;
}> {
render(): React.ReactNode {
override render(): React.ReactNode {
const { selected, label, missing, details } = this.props;
const classNames = ['item'];
if (selected) {
@ -99,14 +101,18 @@ export class BoardsConfig extends React.Component<
};
}
componentDidMount() {
this.updateBoards();
this.updatePorts(
this.props.boardsServiceProvider.availableBoards
.map(({ port }) => port)
.filter(notEmpty)
);
override componentDidMount(): void {
this.toDispose.pushAll([
this.props.onAppStateDidChange((state) => {
if (state === 'ready') {
this.updateBoards();
this.updatePorts(
this.props.boardsServiceProvider.availableBoards
.map(({ port }) => port)
.filter(notEmpty)
);
}
}),
this.props.notificationCenter.onAttachedBoardsChanged((event) =>
this.updatePorts(
event.newState.ports,
@ -141,11 +147,11 @@ export class BoardsConfig extends React.Component<
]);
}
componentWillUnmount(): void {
override componentWillUnmount(): void {
this.toDispose.dispose();
}
protected fireConfigChanged() {
protected fireConfigChanged(): void {
const { selectedBoard, selectedPort } = this.state;
this.props.onConfigChange({ selectedBoard, selectedPort });
}
@ -250,7 +256,7 @@ export class BoardsConfig extends React.Component<
this.props.onFocusNodeSet(element || undefined);
};
render(): React.ReactNode {
override render(): React.ReactNode {
return (
<div className="body">
{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 { ArduinoMenus, unregisterSubmenu } from '../menu/arduino-menus';
import { nls } from '@theia/core/lib/common';
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
@injectable()
export class BoardsDataMenuUpdater implements FrontendApplicationContribution {
@ -31,11 +32,20 @@ export class BoardsDataMenuUpdater implements FrontendApplicationContribution {
@inject(BoardsServiceProvider)
protected readonly boardsServiceClient: BoardsServiceProvider;
@inject(FrontendApplicationStateService)
private readonly appStateService: FrontendApplicationStateService;
protected readonly queue = new PQueue({ autoStart: true, concurrency: 1 });
protected readonly toDisposeOnBoardChange = new DisposableCollection();
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.updateMenuActions(
this.boardsServiceClient.boardsConfig.selectedBoard

View File

@ -30,7 +30,7 @@ export class BoardsListWidget extends ListWidget<BoardsPackage> {
}
@postConstruct()
protected init(): void {
protected override init(): void {
super.init();
this.toDispose.pushAll([
this.notificationCenter.onPlatformInstalled(() =>
@ -42,7 +42,7 @@ export class BoardsListWidget extends ListWidget<BoardsPackage> {
]);
}
protected async install({
protected override async install({
item,
progressId,
version,
@ -63,7 +63,7 @@ export class BoardsListWidget extends ListWidget<BoardsPackage> {
);
}
protected async uninstall({
protected override async uninstall({
item,
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);
}
@ -130,13 +130,13 @@ export class BoardsToolBarItem extends React.Component<
});
}
componentDidMount() {
override componentDidMount(): void {
this.props.boardsServiceClient.onAvailableBoardsChanged((availableBoards) =>
this.setState({ availableBoards })
);
}
componentWillUnmount(): void {
override componentWillUnmount(): void {
this.toDispose.dispose();
}
@ -161,7 +161,7 @@ export class BoardsToolBarItem extends React.Component<
event.nativeEvent.stopImmediatePropagation();
};
render(): React.ReactNode {
override render(): React.ReactNode {
const { coords, availableBoards } = this.state;
const boardsConfig = this.props.boardsServiceClient.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();
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -47,7 +47,7 @@ export class BoardSelection extends SketchContribution {
protected readonly toDisposeBeforeMenuRebuild = new DisposableCollection();
registerCommands(registry: CommandRegistry): void {
override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(BoardSelection.Commands.GET_BOARD_INFO, {
execute: async () => {
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.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> {

View File

@ -28,15 +28,15 @@ export class BurnBootloader extends SketchContribution {
protected readonly boardsServiceClientImpl: BoardsServiceProvider;
@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, {
execute: () => this.burnBootloader(),
});
}
registerMenus(registry: MenuModelRegistry): void {
override registerMenus(registry: MenuModelRegistry): void {
registry.registerMenuAction(ArduinoMenus.TOOLS__BOARD_SETTINGS_GROUP, {
commandId: BurnBootloader.Commands.BURN_BOOTLOADER.id,
label: nls.localize(

View File

@ -21,21 +21,21 @@ import { nls } from '@theia/core/lib/common';
@injectable()
export class Close extends SketchContribution {
@inject(EditorManager)
protected readonly editorManager: EditorManager;
protected override readonly editorManager: EditorManager;
protected shell: ApplicationShell;
onStart(app: FrontendApplication): void {
override onStart(app: FrontendApplication): void {
this.shell = app.shell;
}
registerCommands(registry: CommandRegistry): void {
override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(Close.Commands.CLOSE, {
execute: () => remote.getCurrentWindow().close()
});
}
registerMenus(registry: MenuModelRegistry): void {
override registerMenus(registry: MenuModelRegistry): void {
registry.registerMenuAction(ArduinoMenus.FILE__SKETCH_GROUP, {
commandId: Close.Commands.CLOSE.id,
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({
command: Close.Commands.CLOSE.id,
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 { ILogger } from '@theia/core/lib/common/logger';
import { Saveable } from '@theia/core/lib/browser/saveable';
@ -34,7 +39,10 @@ import {
} from '@theia/core/lib/common/command';
import { EditorMode } from '../editor-mode';
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 {
SketchesService,
ConfigService,
@ -42,6 +50,7 @@ import {
Sketch,
} from '../../common/protocol';
import { ArduinoPreferences } from '../arduino-preferences';
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
export {
Command,
@ -84,15 +93,31 @@ export abstract class Contribution
@inject(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> {}
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function, unused-imports/no-unused-vars
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 {}
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function, unused-imports/no-unused-vars
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 {}
// eslint-disable-next-line @typescript-eslint/no-empty-function
onReady(): MaybePromise<void> {}
}
@injectable()
@ -127,7 +152,7 @@ export abstract class SketchContribution extends Contribution {
protected async sourceOverride(): Promise<Record<string, string>> {
const override: Record<string, string> = {};
const sketch = await this.sketchServiceClient.currentSketch();
if (sketch) {
if (CurrentSketch.isValid(sketch)) {
for (const editor of this.editorManager.all) {
const uri = editor.editor.uri;
if (Saveable.isDirty(editor) && Sketch.isInSketch(uri, sketch)) {
@ -140,7 +165,7 @@ export abstract class SketchContribution extends Contribution {
}
export namespace Contribution {
export function configure<T>(
export function configure(
bind: interfaces.Bind,
serviceIdentifier: typeof Contribution
): void {

View File

@ -12,7 +12,8 @@ import {
SketchContribution,
TabBarToolbarRegistry,
} 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()
export class Debug extends SketchContribution {
@ -66,7 +67,7 @@ export class Debug extends SketchContribution {
onDidChange: this.onDisabledMessageDidChange as Event<void>,
};
onStart(): void {
override onStart(): void {
this.onDisabledMessageDidChange(
() =>
(this.debugToolbarItem.tooltip = `${
@ -79,55 +80,18 @@ export class Debug extends SketchContribution {
: Debug.Commands.START_DEBUGGING.label
}`)
);
const refreshState = async (
board: Board | undefined = this.boardsServiceProvider.boardsConfig
.selectedBoard
) => {
if (!board) {
this.disabledMessage = nls.localize(
'arduino/common/noBoardSelected',
'No board selected'
);
return;
}
const fqbn = board.fqbn;
if (!fqbn) {
this.disabledMessage = nls.localize(
'arduino/debug/noPlatformInstalledFor',
"Platform is not installed for '{0}'",
board.name
);
return;
}
const details = await this.boardService.getBoardDetails({ fqbn });
if (!details) {
this.disabledMessage = nls.localize(
'arduino/debug/noPlatformInstalledFor',
"Platform is not installed for '{0}'",
board.name
);
return;
}
const { debuggingSupported } = details;
if (!debuggingSupported) {
this.disabledMessage = nls.localize(
'arduino/debug/debuggingNotSupported',
"Debugging is not supported by '{0}'",
board.name
);
} else {
this.disabledMessage = undefined;
}
};
this.boardsServiceProvider.onBoardsConfigChanged(({ selectedBoard }) =>
refreshState(selectedBoard)
this.refreshState(selectedBoard)
);
this.notificationCenter.onPlatformInstalled(() => refreshState());
this.notificationCenter.onPlatformUninstalled(() => refreshState());
refreshState();
this.notificationCenter.onPlatformInstalled(() => this.refreshState());
this.notificationCenter.onPlatformUninstalled(() => this.refreshState());
}
registerCommands(registry: CommandRegistry): void {
override onReady(): MaybePromise<void> {
this.refreshState();
}
override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(Debug.Commands.START_DEBUGGING, {
execute: () => this.startDebug(),
isVisible: (widget) =>
@ -136,10 +100,51 @@ export class Debug extends SketchContribution {
});
}
registerToolbarItems(registry: TabBarToolbarRegistry): void {
override registerToolbarItems(registry: TabBarToolbarRegistry): void {
registry.registerItem(this.debugToolbarItem);
}
private async refreshState(
board: Board | undefined = this.boardsServiceProvider.boardsConfig
.selectedBoard
): Promise<void> {
if (!board) {
this.disabledMessage = nls.localize(
'arduino/common/noBoardSelected',
'No board selected'
);
return;
}
const fqbn = board.fqbn;
if (!fqbn) {
this.disabledMessage = nls.localize(
'arduino/debug/noPlatformInstalledFor',
"Platform is not installed for '{0}'",
board.name
);
return;
}
const details = await this.boardService.getBoardDetails({ fqbn });
if (!details) {
this.disabledMessage = nls.localize(
'arduino/debug/noPlatformInstalledFor',
"Platform is not installed for '{0}'",
board.name
);
return;
}
const { debuggingSupported } = details;
if (!debuggingSupported) {
this.disabledMessage = nls.localize(
'arduino/debug/debuggingNotSupported',
"Debugging is not supported by '{0}'",
board.name
);
} else {
this.disabledMessage = undefined;
}
}
protected async startDebug(
board: Board | undefined = this.boardsServiceProvider.boardsConfig
.selectedBoard
@ -156,7 +161,7 @@ export class Debug extends SketchContribution {
this.sketchServiceClient.currentSketch(),
this.executableService.list(),
]);
if (!sketch) {
if (!CurrentSketch.isValid(sketch)) {
return;
}
const ideTempFolderUri = await this.sketchService.getIdeTempFolderUri(

View File

@ -28,7 +28,7 @@ export class EditContributions extends Contribution {
@inject(PreferenceService)
protected readonly preferences: PreferenceService;
registerCommands(registry: CommandRegistry): void {
override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(EditContributions.Commands.GO_TO_LINE, {
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, {
commandId: CommonCommands.CUT.id,
order: '0',
@ -201,7 +201,7 @@ ${value}
});
}
registerKeybindings(registry: KeybindingRegistry): void {
override registerKeybindings(registry: KeybindingRegistry): void {
registry.registerKeybinding({
command: EditContributions.Commands.COPY_FOR_FORUM.id,
keybinding: 'CtrlCmd+Shift+C',

View File

@ -1,5 +1,5 @@
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 {
MenuPath,
@ -21,7 +21,7 @@ import {
MenuModelRegistry,
} from './contribution';
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';
@injectable()
@ -43,8 +43,8 @@ export abstract class Examples extends SketchContribution {
protected readonly toDispose = new DisposableCollection();
@postConstruct()
init(): void {
protected override init(): void {
super.init();
this.boardsServiceClient.onBoardsConfigChanged(({ selectedBoard }) =>
this.handleBoardChanged(selectedBoard)
);
@ -54,7 +54,7 @@ export abstract class Examples extends SketchContribution {
// NOOP
}
registerMenus(registry: MenuModelRegistry): void {
override registerMenus(registry: MenuModelRegistry): void {
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.
const index = ArduinoMenus.FILE__EXAMPLES_SUBMENU.length - 1;
@ -82,7 +82,7 @@ export abstract class Examples extends SketchContribution {
registerRecursively(
sketchContainerOrPlaceholder:
| SketchContainer
| (Sketch | SketchContainer)[]
| (SketchRef | SketchContainer)[]
| string,
menuPath: MenuPath,
pushToDispose: DisposableCollection = new DisposableCollection(),
@ -100,7 +100,7 @@ export abstract class Examples extends SketchContribution {
)
);
} else {
const sketches: Sketch[] = [];
const sketches: SketchRef[] = [];
const children: SketchContainer[] = [];
let submenuPath = menuPath;
@ -161,7 +161,7 @@ export abstract class Examples extends SketchContribution {
@injectable()
export class BuiltInExamples extends Examples {
onStart(): void {
override async onReady(): Promise<void> {
this.register(); // no `await`
}
@ -201,13 +201,16 @@ export class LibraryExamples extends Examples {
protected readonly queue = new PQueue({ autoStart: true, concurrency: 1 });
onStart(): void {
this.register(); // no `await`
override onStart(): void {
this.notificationCenter.onLibraryInstalled(() => 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);
}

View File

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

View File

@ -17,6 +17,7 @@ import { SketchContribution, Command, CommandRegistry } from './contribution';
import { NotificationCenter } from '../notification-center';
import { nls } from '@theia/core/lib/common';
import * as monaco from '@theia/monaco-editor-core';
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
@injectable()
export class IncludeLibrary extends SketchContribution {
@ -30,7 +31,7 @@ export class IncludeLibrary extends SketchContribution {
protected readonly mainMenuManager: MainMenuManager;
@inject(EditorManager)
protected readonly editorManager: EditorManager;
protected override readonly editorManager: EditorManager;
@inject(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 toDispose = new DisposableCollection();
onStart(): void {
this.updateMenuActions();
override onStart(): void {
this.boardsServiceClient.onBoardsConfigChanged(() =>
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
const includeLibMenuPath = [
...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, {
execute: async (arg) => {
if (LibraryPackage.is(arg)) {
@ -169,7 +173,7 @@ export class IncludeLibrary extends SketchContribution {
protected async includeLibrary(library: LibraryPackage): Promise<void> {
const sketch = await this.sketchServiceClient.currentSketch();
if (!sketch) {
if (!CurrentSketch.isValid(sketch)) {
return;
}
// If the current editor is one of the additional files from the sketch, we use that.

View File

@ -14,7 +14,7 @@ import {
@injectable()
export class NewSketch extends SketchContribution {
registerCommands(registry: CommandRegistry): void {
override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(NewSketch.Commands.NEW_SKETCH, {
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, {
commandId: NewSketch.Commands.NEW_SKETCH.id,
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({
command: NewSketch.Commands.NEW_SKETCH.id,
keybinding: 'CtrlCmd+N',
});
}
registerToolbarItems(registry: TabBarToolbarRegistry): void {
override registerToolbarItems(registry: TabBarToolbarRegistry): void {
registry.registerItem({
id: 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>();
onStart(): void {
const refreshMenu = (sketches: Sketch[]) => {
this.register(sketches);
this.mainMenuManager.update();
};
override onStart(): void {
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(
ArduinoMenus.FILE__OPEN_RECENT_SUBMENU,
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 {
const order = 0;
for (const sketch of sketches) {

View File

@ -13,13 +13,13 @@ import { nls } from '@theia/core/lib/common';
@injectable()
export class OpenSketchExternal extends SketchContribution {
registerCommands(registry: CommandRegistry): void {
override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(OpenSketchExternal.Commands.OPEN_EXTERNAL, {
execute: () => this.openExternal(),
});
}
registerMenus(registry: MenuModelRegistry): void {
override registerMenus(registry: MenuModelRegistry): void {
registry.registerMenuAction(ArduinoMenus.SKETCH__UTILS_GROUP, {
commandId: OpenSketchExternal.Commands.OPEN_EXTERNAL.id,
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({
command: OpenSketchExternal.Commands.OPEN_EXTERNAL.id,
keybinding: 'CtrlCmd+Alt+K',

View File

@ -43,7 +43,7 @@ export class OpenSketch extends SketchContribution {
protected readonly toDispose = new DisposableCollection();
registerCommands(registry: CommandRegistry): void {
override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(OpenSketch.Commands.OPEN_SKETCH, {
execute: (arg) =>
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, {
commandId: OpenSketch.Commands.OPEN_SKETCH.id,
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({
command: OpenSketch.Commands.OPEN_SKETCH.id,
keybinding: 'CtrlCmd+O',
});
}
registerToolbarItems(registry: TabBarToolbarRegistry): void {
override registerToolbarItems(registry: TabBarToolbarRegistry): void {
registry.registerItem({
id: 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()
export class QuitApp extends Contribution {
registerCommands(registry: CommandRegistry): void {
override registerCommands(registry: CommandRegistry): void {
if (!isOSX) {
registry.registerCommand(QuitApp.Commands.QUIT_APP, {
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.
if (!isOSX) {
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) {
registry.registerKeybinding({
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 { EditorManager } from '@theia/editor/lib/browser';
import { WindowService } from '@theia/core/lib/browser/window/window-service';
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
@injectable()
export class SaveAsSketch extends SketchContribution {
@ -22,18 +23,18 @@ export class SaveAsSketch extends SketchContribution {
protected readonly applicationShell: ApplicationShell;
@inject(EditorManager)
protected readonly editorManager: EditorManager;
protected override readonly editorManager: EditorManager;
@inject(WindowService)
protected readonly windowService: WindowService;
registerCommands(registry: CommandRegistry): void {
override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(SaveAsSketch.Commands.SAVE_AS_SKETCH, {
execute: (args) => this.saveAs(args),
});
}
registerMenus(registry: MenuModelRegistry): void {
override registerMenus(registry: MenuModelRegistry): void {
registry.registerMenuAction(ArduinoMenus.FILE__SKETCH_GROUP, {
commandId: SaveAsSketch.Commands.SAVE_AS_SKETCH.id,
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({
command: SaveAsSketch.Commands.SAVE_AS_SKETCH.id,
keybinding: 'CtrlCmd+Shift+S',
@ -59,7 +60,7 @@ export class SaveAsSketch extends SketchContribution {
}: SaveAsSketch.Options = SaveAsSketch.Options.DEFAULT
): Promise<boolean> {
const sketch = await this.sketchServiceClient.currentSketch();
if (!sketch) {
if (!CurrentSketch.isValid(sketch)) {
return false;
}

View File

@ -12,10 +12,11 @@ import {
TabBarToolbarRegistry,
} from './contribution';
import { nls } from '@theia/core/lib/common';
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
@injectable()
export class SaveSketch extends SketchContribution {
registerCommands(registry: CommandRegistry): void {
override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(SaveSketch.Commands.SAVE_SKETCH, {
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, {
commandId: SaveSketch.Commands.SAVE_SKETCH.id,
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({
command: SaveSketch.Commands.SAVE_SKETCH.id,
keybinding: 'CtrlCmd+S',
});
}
registerToolbarItems(registry: TabBarToolbarRegistry): void {
override registerToolbarItems(registry: TabBarToolbarRegistry): void {
registry.registerItem({
id: 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> {
const sketch = await this.sketchServiceClient.currentSketch();
if (!sketch) {
if (!CurrentSketch.isValid(sketch)) {
return;
}
const isTemp = await this.sketchService.isTemp(sketch);

View File

@ -18,7 +18,7 @@ export class Settings extends SketchContribution {
protected settingsOpened = false;
registerCommands(registry: CommandRegistry): void {
override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(Settings.Commands.OPEN, {
execute: async () => {
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, {
commandId: Settings.Commands.OPEN.id,
label:
@ -52,7 +52,7 @@ export class Settings extends SketchContribution {
registry.registerSubmenu(ArduinoMenus.FILE__ADVANCED_SUBMENU, 'Advanced');
}
registerKeybindings(registry: KeybindingRegistry): void {
override registerKeybindings(registry: KeybindingRegistry): void {
registry.registerKeybinding({
command: Settings.Commands.OPEN.id,
keybinding: 'CtrlCmd+,',

View File

@ -19,7 +19,10 @@ import {
} from './contribution';
import { ArduinoMenus, PlaceholderMenuNode } from '../menu/arduino-menus';
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 { nls } from '@theia/core/lib/common';
@ -35,7 +38,7 @@ export class SketchControl extends SketchContribution {
protected readonly contextMenuRenderer: ContextMenuRenderer;
@inject(EditorManager)
protected readonly editorManager: EditorManager;
protected override readonly editorManager: EditorManager;
@inject(SketchesServiceClientImpl)
protected readonly sketchesServiceClient: SketchesServiceClientImpl;
@ -46,7 +49,7 @@ export class SketchControl extends SketchContribution {
protected readonly toDisposeBeforeCreateNewContextMenu =
new DisposableCollection();
registerCommands(registry: CommandRegistry): void {
override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(
SketchControl.Commands.OPEN_SKETCH_CONTROL__TOOLBAR,
{
@ -55,7 +58,7 @@ export class SketchControl extends SketchContribution {
execute: async () => {
this.toDisposeBeforeCreateNewContextMenu.dispose();
const sketch = await this.sketchServiceClient.currentSketch();
if (!sketch) {
if (!CurrentSketch.isValid(sketch)) {
return;
}
@ -70,25 +73,22 @@ export class SketchControl extends SketchContribution {
return;
}
const { mainFileUri, rootFolderFileUris } =
await this.sketchService.loadSketch(sketch.uri);
const { mainFileUri, rootFolderFileUris } = sketch;
const uris = [mainFileUri, ...rootFolderFileUris];
const currentSketch =
await this.sketchesServiceClient.currentSketch();
const parentsketchUri = this.editorManager.currentEditor
const parentSketchUri = this.editorManager.currentEditor
?.getResourceUri()
?.toString();
const parentsketch = await this.sketchService.getSketchFolder(
parentsketchUri || ''
const parentSketch = await this.sketchService.getSketchFolder(
parentSketchUri || ''
);
// if the current file is in the current opened sketch, show extra menus
if (
currentSketch &&
parentsketch &&
parentsketch.uri === currentSketch.uri &&
this.allowRename(parentsketch.uri)
sketch &&
parentSketch &&
parentSketch.uri === sketch.uri &&
this.allowRename(parentSketch.uri)
) {
this.menuRegistry.registerMenuAction(
ArduinoMenus.SKETCH_CONTROL__CONTEXT__MAIN_GROUP,
@ -122,10 +122,10 @@ export class SketchControl extends SketchContribution {
}
if (
currentSketch &&
parentsketch &&
parentsketch.uri === currentSketch.uri &&
this.allowDelete(parentsketch.uri)
sketch &&
parentSketch &&
parentSketch.uri === sketch.uri &&
this.allowDelete(parentSketch.uri)
) {
this.menuRegistry.registerMenuAction(
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(
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({
command: WorkspaceCommands.NEW_FILE.id,
keybinding: 'CtrlCmd+Shift+N',
@ -243,7 +243,7 @@ export class SketchControl extends SketchContribution {
});
}
registerToolbarItems(registry: TabBarToolbarRegistry): void {
override registerToolbarItems(registry: TabBarToolbarRegistry): void {
registry.registerItem({
id: 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()
export class Sketchbook extends Examples {
@inject(CommandRegistry)
protected readonly commandRegistry: CommandRegistry;
protected override readonly commandRegistry: CommandRegistry;
@inject(MenuModelRegistry)
protected readonly menuRegistry: MenuModelRegistry;
protected override readonly menuRegistry: MenuModelRegistry;
@inject(MainMenuManager)
protected readonly mainMenuManager: MainMenuManager;
@ -23,11 +23,7 @@ export class Sketchbook extends Examples {
@inject(NotificationCenter)
protected readonly notificationCenter: NotificationCenter;
onStart(): void {
this.sketchService.getSketches({}).then((container) => {
this.register(container);
this.mainMenuManager.update();
});
override onStart(): void {
this.sketchServiceClient.onSketchbookDidChange(() => {
this.sketchService.getSketches({}).then((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(
ArduinoMenus.FILE__SKETCHBOOK_SUBMENU,
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 {
execute: async () => {
const sketch = await this.sketchService.loadSketch(uri);

View File

@ -39,7 +39,7 @@ export class UploadCertificate extends Contribution {
protected dialogOpened = false;
registerCommands(registry: CommandRegistry): void {
override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(UploadCertificate.Commands.OPEN, {
execute: async () => {
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, {
commandId: UploadCertificate.Commands.OPEN.id,
label: UploadCertificate.Commands.OPEN.label,

View File

@ -16,7 +16,7 @@ export class UploadFirmware extends Contribution {
protected dialogOpened = false;
registerCommands(registry: CommandRegistry): void {
override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(UploadFirmware.Commands.OPEN, {
execute: async () => {
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, {
commandId: UploadFirmware.Commands.OPEN.id,
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 { BoardUserField, CoreService } from '../../common/protocol';
import { ArduinoMenus, PlaceholderMenuNode } from '../menu/arduino-menus';
@ -16,6 +16,7 @@ import {
} from './contribution';
import { UserFieldsDialog } from '../dialogs/user-fields/user-fields-dialog';
import { DisposableCollection, nls } from '@theia/core/lib/common';
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
@injectable()
export class UploadSketch extends SketchContribution {
@ -47,8 +48,8 @@ export class UploadSketch extends SketchContribution {
protected readonly menuActionsDisposables = new DisposableCollection();
@postConstruct()
protected init(): void {
protected override init(): void {
super.init();
this.boardsServiceClientImpl.onBoardsConfigChanged(async () => {
const userFields =
await this.boardsServiceClientImpl.selectedBoardUserFields();
@ -72,7 +73,7 @@ export class UploadSketch extends SketchContribution {
return fqbn + '|' + address;
}
registerCommands(registry: CommandRegistry): void {
override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(UploadSketch.Commands.UPLOAD_SKETCH, {
execute: async () => {
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.push(
@ -177,7 +178,7 @@ export class UploadSketch extends SketchContribution {
);
}
registerKeybindings(registry: KeybindingRegistry): void {
override registerKeybindings(registry: KeybindingRegistry): void {
registry.registerKeybinding({
command: UploadSketch.Commands.UPLOAD_SKETCH.id,
keybinding: 'CtrlCmd+U',
@ -188,7 +189,7 @@ export class UploadSketch extends SketchContribution {
});
}
registerToolbarItems(registry: TabBarToolbarRegistry): void {
override registerToolbarItems(registry: TabBarToolbarRegistry): void {
registry.registerItem({
id: 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.onDidChangeEmitter.fire();
const sketch = await this.sketchServiceClient.currentSketch();
if (!sketch) {
if (!CurrentSketch.isValid(sketch)) {
return;
}

View File

@ -14,6 +14,7 @@ import {
TabBarToolbarRegistry,
} from './contribution';
import { nls } from '@theia/core/lib/common';
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
@injectable()
export class VerifySketch extends SketchContribution {
@ -31,7 +32,7 @@ export class VerifySketch extends SketchContribution {
protected verifyInProgress = false;
registerCommands(registry: CommandRegistry): void {
override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(VerifySketch.Commands.VERIFY_SKETCH, {
execute: () => this.verifySketch(),
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, {
commandId: VerifySketch.Commands.VERIFY_SKETCH.id,
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({
command: VerifySketch.Commands.VERIFY_SKETCH.id,
keybinding: 'CtrlCmd+R',
@ -77,7 +78,7 @@ export class VerifySketch extends SketchContribution {
});
}
registerToolbarItems(registry: TabBarToolbarRegistry): void {
override registerToolbarItems(registry: TabBarToolbarRegistry): void {
registry.registerItem({
id: 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();
const sketch = await this.sketchServiceClient.currentSketch();
if (!sketch) {
if (!CurrentSketch.isValid(sketch)) {
return;
}
try {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -56,7 +56,7 @@ export class SettingsDialog extends AbstractDialog<Promise<Settings>> {
constructor(
@inject(SettingsDialogProps)
protected readonly props: SettingsDialogProps
protected override readonly props: SettingsDialogProps
) {
super(props);
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);
if (typeof result === 'string') {
return result;
@ -85,7 +85,7 @@ export class SettingsDialog extends AbstractDialog<Promise<Settings>> {
return this.settingsService.settings();
}
protected onAfterAttach(msg: Message): void {
protected override onAfterAttach(msg: Message): void {
if (this.widget.isAttached) {
Widget.detach(this.widget);
}
@ -97,12 +97,12 @@ export class SettingsDialog extends AbstractDialog<Promise<Settings>> {
this.update();
}
protected onUpdateRequest(msg: Message): void {
protected override onUpdateRequest(msg: Message): void {
super.onUpdateRequest(msg);
this.widget.update();
}
protected onActivateRequest(msg: Message): void {
protected override onActivateRequest(msg: Message): void {
super.onActivateRequest(msg);
// 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');
}
protected onAfterAttach(message: Message): void {
protected override onAfterAttach(message: Message): void {
super.onAfterAttach(message);
this.addUpdateListener(this.textArea, 'input');
}
protected onActivateRequest(message: Message): void {
protected override onActivateRequest(message: Message): void {
super.onActivateRequest(message);
this.textArea.focus();
}
protected handleEnter(event: KeyboardEvent): boolean | void {
protected override handleEnter(event: KeyboardEvent): boolean | void {
if (event.target instanceof HTMLInputElement) {
return super.handleEnter(event);
}

View File

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

View File

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

View File

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

View File

@ -62,7 +62,7 @@ export class MonitorViewContribution
});
}
registerMenus(menus: MenuModelRegistry): void {
override registerMenus(menus: MenuModelRegistry): void {
if (this.toggleCommand) {
menus.registerMenuAction(ArduinoMenus.TOOLS__MAIN_GROUP, {
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, {
isEnabled: (widget) => widget instanceof MonitorWidget,
isVisible: (widget) => widget instanceof MonitorWidget,

View File

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

View File

@ -32,7 +32,7 @@ export class SerialMonitorSendInput extends React.Component<
this.onKeyDown = this.onKeyDown.bind(this);
}
componentDidMount(): void {
override componentDidMount(): void {
this.props.serialConnection.isBESerialConnected().then((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?
this.toDisposeBeforeUnmount.dispose();
}
render(): React.ReactNode {
override render(): React.ReactNode {
return (
<input
ref={this.setRef}

View File

@ -29,7 +29,7 @@ export class SerialMonitorOutput extends React.Component<
};
}
render(): React.ReactNode {
override render(): React.ReactNode {
return (
<List
className="serial-monitor-messages"
@ -51,11 +51,11 @@ export class SerialMonitorOutput extends React.Component<
);
}
shouldComponentUpdate(): boolean {
override shouldComponentUpdate(): boolean {
return true;
}
componentDidMount(): void {
override componentDidMount(): void {
this.scrollToBottom();
this.toDisposeBeforeUnmount.pushAll([
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?
this.toDisposeBeforeUnmount.dispose();
}

View File

@ -45,7 +45,7 @@ export class PlotterFrontendContribution extends Contribution {
@inject(BoardsServiceProvider)
protected readonly boardsServiceProvider: BoardsServiceProvider;
onStart(app: FrontendApplication): MaybePromise<void> {
override onStart(app: FrontendApplication): MaybePromise<void> {
this.url = new Endpoint({ path: '/plotter' }).getRestUrl().toString();
ipcRenderer.on('CLOSE_CHILD_WINDOW', async () => {
@ -56,13 +56,13 @@ export class PlotterFrontendContribution extends Contribution {
return super.onStart(app);
}
registerCommands(registry: CommandRegistry): void {
override registerCommands(registry: CommandRegistry): void {
registry.registerCommand(SerialPlotterContribution.Commands.OPEN, {
execute: this.connect.bind(this),
});
}
registerMenus(menus: MenuModelRegistry): void {
override registerMenus(menus: MenuModelRegistry): void {
menus.registerMenuAction(ArduinoMenus.TOOLS__MAIN_GROUP, {
commandId: SerialPlotterContribution.Commands.OPEN.id,
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';
import { Sketch } from '../../../common/protocol';
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 URI from '@theia/core/lib/common/uri';
@ -33,7 +33,7 @@ export class ApplicationShell extends TheiaApplicationShell {
@inject(ConnectionStatusService)
protected readonly connectionStatusService: ConnectionStatusService;
protected track(widget: Widget): void {
protected override track(widget: Widget): void {
super.track(widget);
if (widget instanceof OutputWidget) {
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) {
// Make the editor un-closeable asynchronously.
this.sketchesServiceClient.currentSketch().then((sketch) => {
if (sketch) {
if (CurrentSketch.isValid(sketch)) {
if (!this.isSketchFile(widget.editor.uri, sketch.uri)) {
return;
}
@ -61,7 +61,7 @@ export class ApplicationShell extends TheiaApplicationShell {
return false;
}
async addWidget(
override async addWidget(
widget: Widget,
options: Readonly<TheiaApplicationShell.WidgetOptions> = {}
): Promise<void> {
@ -87,19 +87,19 @@ export class ApplicationShell extends TheiaApplicationShell {
return super.addWidget(widget, { ...options, ref });
}
handleEvent(): boolean {
override handleEvent(): boolean {
// NOOP, dragging has been disabled
return false
return false;
}
// Avoid hiding top panel as we use it for arduino toolbar
protected createTopPanel(): Panel {
protected override createTopPanel(): Panel {
const topPanel = super.createTopPanel();
topPanel.show();
return topPanel;
}
async saveAll(): Promise<void> {
override async saveAll(): Promise<void> {
if (
this.connectionStatusService.currentStatus === ConnectionStatus.OFFLINE
) {

View File

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

View File

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

View File

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

View File

@ -20,22 +20,22 @@ export class FrontendApplication extends TheiaFrontendApplication {
@inject(SketchesService)
protected readonly sketchesService: SketchesService;
protected async initializeLayout(): Promise<void> {
protected override async initializeLayout(): Promise<void> {
await super.initializeLayout();
const roots = await this.workspaceService.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
this.workspaceService.roots.then(async (roots) => {
for (const root of roots) {
await this.commandService.executeCommand(
ArduinoCommands.OPEN_SKETCH_FILES.id,
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
if (!startupElement) {
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...');
const serializedLayoutData = await this.storageService.getData<string>(
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) {
const editor = title.owner.editor;
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`).
* 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 = '';
const classNames = [];
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';
export class TabBarRenderer extends TheiaTabBarRenderer {
createTabClass(data: TabBar.IRenderData<any>): string {
override createTabClass(data: TabBar.IRenderData<any>): string {
let className = super.createTabClass(data);
if (!data.title.closable && Saveable.isDirty(data.title.owner)) {
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 { DebugConfigurationManager as TheiaDebugConfigurationManager } from '@theia/debug/lib/browser/debug-configuration-manager';
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 {
FileOperationError,
@ -36,7 +39,7 @@ export class DebugConfigurationManager extends TheiaDebugConfigurationManager {
}
@postConstruct()
protected async init(): Promise<void> {
protected override async init(): Promise<void> {
super.init();
this.appStateService.reachedState('ready').then(async () => {
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');
const roots = await this.workspaceService.roots;
const toDelete = new Set(this.models.keys());
@ -113,7 +116,7 @@ export class DebugConfigurationManager extends TheiaDebugConfigurationManager {
(TheiaDebugConfigurationModel.JsonContent & { uri: URI }) | URI | undefined
> {
const sketch = await this.sketchesServiceClient.currentSketch();
if (!sketch) {
if (!CurrentSketch.isValid(sketch)) {
return undefined;
}
const uri = await this.sketchesService.getIdeTempFolderUri(sketch);

View File

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

View File

@ -13,7 +13,7 @@ export class DebugFrontendApplicationContribution extends TheiaDebugFrontendAppl
this.options.defaultWidgetOptions.rank = 4;
}
registerMenus(registry: MenuModelRegistry): void {
override registerMenus(registry: MenuModelRegistry): void {
super.registerMenus(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()
export class DebugSessionManager extends TheiaDebugSessionManager {
async start(options: DebugSessionOptions): Promise<DebugSession | undefined> {
override async start(options: DebugSessionOptions): Promise<DebugSession | undefined> {
return this.progressService.withProgress(
nls.localize('theia/debug/start', 'Start...'),
'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) {
this.updateCurrentSession(this._currentSession);
session = this._currentSession;

View File

@ -8,7 +8,7 @@ import {
@injectable()
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);
this.closeCrossNode.classList.remove(...codiconArray('close'));

View File

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

View File

@ -1,9 +1,7 @@
import { EditorManager as TheiaEditorManager } from '@theia/editor/lib/browser/editor-manager';
export class EditorManager extends TheiaEditorManager {
protected getOrCreateCounterForUri(): number {
protected override getOrCreateCounterForUri(): number {
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 { LabelProvider } from '@theia/core/lib/browser';
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 { nls } from '@theia/core/lib/common';
@ -16,9 +19,9 @@ export class EditorWidgetFactory extends TheiaEditorWidgetFactory {
protected readonly sketchesServiceClient: SketchesServiceClientImpl;
@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);
return this.maybeUpdateCaption(widget);
}
@ -28,7 +31,7 @@ export class EditorWidgetFactory extends TheiaEditorWidgetFactory {
): Promise<EditorWidget> {
const sketch = await this.sketchesServiceClient.currentSketch();
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);
if (isTemp) {
widget.title.caption = nls.localize(

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -8,7 +8,7 @@ import { OutputToolbarContribution as TheiaOutputToolbarContribution } from '@th
@injectable()
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?
// 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.
@injectable()
export class OutputWidget extends TheiaOutputWidget {
protected onAfterShow(msg: Message): void {
protected override onAfterShow(msg: Message): void {
super.onAfterShow(msg);
this.onResize(Widget.ResizeMessage.UnknownSize);
}

View File

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

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