Skip to content

Commit 98c9bf6

Browse files
author
Akos Kitta
committed
open sketch files in dedicated contribution.
Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
1 parent cf12688 commit 98c9bf6

File tree

5 files changed

+157
-134
lines changed

5 files changed

+157
-134
lines changed

arduino-ide-extension/src/browser/arduino-commands.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,6 @@ export namespace ArduinoCommands {
88
id: 'arduino-toggle-compile-for-debug',
99
};
1010

11-
/**
12-
* Unlike `OPEN_SKETCH`, it opens all files from a sketch folder. (ino, cpp, etc...)
13-
*/
14-
export const OPEN_SKETCH_FILES: Command = {
15-
id: 'arduino-open-sketch-files',
16-
};
17-
1811
export const OPEN_BOARDS_DIALOG: Command = {
1912
id: 'arduino-open-boards-dialog',
2013
};

arduino-ide-extension/src/browser/arduino-frontend-contribution.tsx

Lines changed: 15 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import {
1212
Sketch,
1313
LibraryService,
1414
ArduinoDaemon,
15-
SketchesError,
1615
} from '../common/protocol';
1716
import { Mutex } from 'async-mutex';
1817
import {
@@ -21,7 +20,6 @@ import {
2120
MenuModelRegistry,
2221
ILogger,
2322
DisposableCollection,
24-
ApplicationError,
2523
} from '@theia/core';
2624
import {
2725
Dialog,
@@ -47,12 +45,7 @@ import {
4745
} from '@theia/core/lib/common/command';
4846
import { MessageService } from '@theia/core/lib/common/message-service';
4947
import URI from '@theia/core/lib/common/uri';
50-
import {
51-
EditorCommands,
52-
EditorMainMenu,
53-
EditorManager,
54-
EditorOpenerOptions,
55-
} from '@theia/editor/lib/browser';
48+
import { EditorCommands, EditorMainMenu } from '@theia/editor/lib/browser';
5649
import { MonacoMenus } from '@theia/monaco/lib/browser/monaco-menu';
5750
import { FileNavigatorCommands } from '@theia/navigator/lib/browser/navigator-contribution';
5851
import { TerminalMenus } from '@theia/terminal/lib/browser/terminal-frontend-contribution';
@@ -78,8 +71,7 @@ import { IDEUpdaterDialog } from './dialogs/ide-updater/ide-updater-dialog';
7871
import { IDEUpdater } from '../common/protocol/ide-updater';
7972
import { FileSystemFrontendContribution } from '@theia/filesystem/lib/browser/filesystem-frontend-contribution';
8073
import { HostedPluginEvents } from './hosted-plugin-events';
81-
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
82-
import { Notifications } from './contributions/notifications';
74+
import { OpenSketchFiles } from './contributions/open-sketch-files';
8375

8476
const INIT_LIBS_AND_PACKAGES = 'initializedLibsAndPackages';
8577
export const SKIP_IDE_VERSION = 'skipIDEVersion';
@@ -108,9 +100,6 @@ export class ArduinoFrontendContribution
108100
@inject(BoardsServiceProvider)
109101
private readonly boardsServiceClientImpl: BoardsServiceProvider;
110102

111-
@inject(EditorManager)
112-
private readonly editorManager: EditorManager;
113-
114103
@inject(FileService)
115104
private readonly fileService: FileService;
116105

@@ -159,12 +148,6 @@ export class ArduinoFrontendContribution
159148
@inject(ArduinoDaemon)
160149
private readonly daemon: ArduinoDaemon;
161150

162-
@inject(WorkspaceService)
163-
private readonly workspaceService: WorkspaceService;
164-
165-
protected invalidConfigPopup:
166-
| Promise<void | 'No' | 'Yes' | undefined>
167-
| undefined;
168151
protected toDisposeOnStop = new DisposableCollection();
169152

170153
@postConstruct()
@@ -247,9 +230,14 @@ export class ArduinoFrontendContribution
247230
sketch.uri
248231
);
249232
if (Sketch.isInSketch(resource, reloadedSketch)) {
250-
this.ensureOpened(resource.toString(), true, {
251-
mode: 'open',
252-
});
233+
this.commandRegistry.executeCommand(
234+
OpenSketchFiles.Commands.ENSURE_OPENED.id,
235+
resource.toString(),
236+
true,
237+
{
238+
mode: 'open',
239+
}
240+
);
253241
}
254242
}
255243
}
@@ -321,6 +309,11 @@ export class ArduinoFrontendContribution
321309
}
322310
}
323311
});
312+
313+
// TODO: Verify this! If true IDE2 can start ~100ms faster.
314+
// If the preferences is resolved, then the `ready` call will happen in the same tick
315+
// and will do a `send_sync` request to the electron main to get the current window.
316+
// Consider moving after app `ready`.
324317
this.arduinoPreferences.ready.then(() => {
325318
const webContents = remote.getCurrentWebContents();
326319
const zoomLevel = this.arduinoPreferences.get('arduino.window.zoomLevel');
@@ -462,11 +455,6 @@ export class ArduinoFrontendContribution
462455
execute: () => this.editorMode.toggleCompileForDebug(),
463456
isToggled: () => this.editorMode.compileForDebug,
464457
});
465-
registry.registerCommand(ArduinoCommands.OPEN_SKETCH_FILES, {
466-
execute: async (uri: URI) => {
467-
this.openSketchFiles(uri);
468-
},
469-
});
470458
registry.registerCommand(ArduinoCommands.OPEN_BOARDS_DIALOG, {
471459
execute: async (query?: string | undefined) => {
472460
const boardsConfig = await this.boardsConfigDialog.open(query);
@@ -518,104 +506,6 @@ export class ArduinoFrontendContribution
518506
});
519507
}
520508

521-
protected async openSketchFiles(uri: URI): Promise<void> {
522-
try {
523-
const sketch = await this.sketchService.loadSketch(uri.toString());
524-
const { mainFileUri, rootFolderFileUris } = sketch;
525-
for (const uri of [mainFileUri, ...rootFolderFileUris]) {
526-
await this.ensureOpened(uri);
527-
}
528-
if (mainFileUri.endsWith('.pde')) {
529-
const message = nls.localize(
530-
'arduino/common/oldFormat',
531-
"The '{0}' still uses the old `.pde` format. Do you want to switch to the new `.ino` extension?",
532-
sketch.name
533-
);
534-
const yes = nls.localize('vscode/extensionsUtils/yes', 'Yes');
535-
this.messageService
536-
.info(message, nls.localize('arduino/common/later', 'Later'), yes)
537-
.then(async (answer) => {
538-
if (answer === yes) {
539-
this.commandRegistry.executeCommand(
540-
SaveAsSketch.Commands.SAVE_AS_SKETCH.id,
541-
{
542-
execOnlyIfTemp: false,
543-
openAfterMove: true,
544-
wipeOriginal: false,
545-
}
546-
);
547-
}
548-
});
549-
}
550-
} catch (err) {
551-
if (SketchesError.NotFound.is(err)) {
552-
this.openFallbackSketch(err);
553-
} else {
554-
console.error(err);
555-
const message =
556-
err instanceof Error
557-
? err.message
558-
: typeof err === 'string'
559-
? err
560-
: String(err);
561-
this.messageService.error(message);
562-
}
563-
}
564-
}
565-
566-
private openFallbackSketch(
567-
err: ApplicationError<
568-
number,
569-
{
570-
uri: string;
571-
}
572-
>
573-
) {
574-
this.sketchService.createNewSketch().then((sketch) => {
575-
this.workspaceService.open(
576-
new URI(sketch.uri),
577-
Object.assign(
578-
{
579-
preserveWindow: true,
580-
},
581-
{
582-
tasks: [
583-
{
584-
command: Notifications.Commands.NOTIFY.id,
585-
args: [
586-
{
587-
type: 'error',
588-
message: err.message,
589-
},
590-
],
591-
},
592-
],
593-
}
594-
)
595-
);
596-
});
597-
}
598-
599-
protected async ensureOpened(
600-
uri: string,
601-
forceOpen = false,
602-
options?: EditorOpenerOptions | undefined
603-
): Promise<unknown> {
604-
const widget = this.editorManager.all.find(
605-
(widget) => widget.editor.uri.toString() === uri
606-
);
607-
if (!widget || forceOpen) {
608-
return this.editorManager.open(
609-
new URI(uri),
610-
options ?? {
611-
mode: 'reveal',
612-
preview: false,
613-
counter: 0,
614-
}
615-
);
616-
}
617-
}
618-
619509
registerColors(colors: ColorRegistry): void {
620510
colors.register(
621511
{

arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ import { StartupTasks } from './widgets/sketchbook/startup-task';
305305
import { IndexesUpdateProgress } from './contributions/indexes-update-progress';
306306
import { Daemon } from './contributions/daemon';
307307
import { Notifications } from './contributions/notifications';
308+
import { OpenSketchFiles } from './contributions/open-sketch-files';
308309

309310
MonacoThemingService.register({
310311
id: 'arduino-theme',
@@ -702,6 +703,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
702703
Contribution.configure(bind, Daemon);
703704
Contribution.configure(bind, StartupTasks);
704705
Contribution.configure(bind, Notifications);
706+
Contribution.configure(bind, OpenSketchFiles);
705707

706708
// Disabled the quick-pick customization from Theia when multiple formatters are available.
707709
// Use the default VS Code behavior, and pick the first one. In the IDE2, clang-format has `exclusive` selectors.
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import { ApplicationError } from '@theia/core/lib/common/application-error';
2+
import { nls } from '@theia/core/lib/common/nls';
3+
import { injectable } from '@theia/core/shared/inversify';
4+
import type { EditorOpenerOptions } from '@theia/editor/lib/browser/editor-manager';
5+
import { SketchesError } from '../../common/protocol';
6+
import {
7+
Command,
8+
CommandRegistry,
9+
SketchContribution,
10+
URI,
11+
} from './contribution';
12+
import { Notifications } from './notifications';
13+
import { SaveAsSketch } from './save-as-sketch';
14+
15+
@injectable()
16+
export class OpenSketchFiles extends SketchContribution {
17+
override registerCommands(registry: CommandRegistry): void {
18+
registry.registerCommand(OpenSketchFiles.Commands.OPEN_SKETCH_FILES, {
19+
execute: (uri: URI) => this.openSketchFiles(uri),
20+
});
21+
registry.registerCommand(OpenSketchFiles.Commands.ENSURE_OPENED, {
22+
execute: (
23+
uri: string,
24+
forceOpen?: boolean,
25+
options?: EditorOpenerOptions
26+
) => {
27+
this.ensureOpened(uri, forceOpen, options);
28+
},
29+
});
30+
}
31+
32+
private async openSketchFiles(uri: URI): Promise<void> {
33+
try {
34+
const sketch = await this.sketchService.loadSketch(uri.toString());
35+
const { mainFileUri, rootFolderFileUris } = sketch;
36+
for (const uri of [mainFileUri, ...rootFolderFileUris]) {
37+
await this.ensureOpened(uri);
38+
}
39+
if (mainFileUri.endsWith('.pde')) {
40+
const message = nls.localize(
41+
'arduino/common/oldFormat',
42+
"The '{0}' still uses the old `.pde` format. Do you want to switch to the new `.ino` extension?",
43+
sketch.name
44+
);
45+
const yes = nls.localize('vscode/extensionsUtils/yes', 'Yes');
46+
this.messageService
47+
.info(message, nls.localize('arduino/common/later', 'Later'), yes)
48+
.then(async (answer) => {
49+
if (answer === yes) {
50+
this.commandService.executeCommand(
51+
SaveAsSketch.Commands.SAVE_AS_SKETCH.id,
52+
{
53+
execOnlyIfTemp: false,
54+
openAfterMove: true,
55+
wipeOriginal: false,
56+
}
57+
);
58+
}
59+
});
60+
}
61+
} catch (err) {
62+
if (SketchesError.NotFound.is(err)) {
63+
this.openFallbackSketch(err);
64+
} else {
65+
console.error(err);
66+
const message =
67+
err instanceof Error
68+
? err.message
69+
: typeof err === 'string'
70+
? err
71+
: String(err);
72+
this.messageService.error(message);
73+
}
74+
}
75+
}
76+
77+
private async openFallbackSketch(
78+
err: ApplicationError<
79+
number,
80+
{
81+
uri: string;
82+
}
83+
>
84+
): Promise<void> {
85+
const sketch = await this.sketchService.createNewSketch();
86+
this.workspaceService.open(
87+
new URI(sketch.uri),
88+
Object.assign(
89+
{
90+
preserveWindow: true,
91+
},
92+
{
93+
tasks: [
94+
{
95+
command: Notifications.Commands.NOTIFY.id,
96+
args: [
97+
{
98+
type: 'error',
99+
message: err.message,
100+
},
101+
],
102+
},
103+
],
104+
}
105+
)
106+
);
107+
}
108+
109+
private async ensureOpened(
110+
uri: string,
111+
forceOpen = false,
112+
options?: EditorOpenerOptions
113+
): Promise<unknown> {
114+
const widget = this.editorManager.all.find(
115+
(widget) => widget.editor.uri.toString() === uri
116+
);
117+
if (!widget || forceOpen) {
118+
return this.editorManager.open(
119+
new URI(uri),
120+
options ?? {
121+
mode: 'reveal',
122+
preview: false,
123+
counter: 0,
124+
}
125+
);
126+
}
127+
}
128+
}
129+
export namespace OpenSketchFiles {
130+
export namespace Commands {
131+
export const OPEN_SKETCH_FILES: Command = {
132+
id: 'arduino-open-sketch-files',
133+
};
134+
export const ENSURE_OPENED: Command = {
135+
id: 'arduino-ensure-opened',
136+
};
137+
}
138+
}

arduino-ide-extension/src/browser/theia/core/frontend-application.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { CommandService } from '@theia/core/lib/common/command';
44
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
55
import { FrontendApplication as TheiaFrontendApplication } from '@theia/core/lib/browser/frontend-application';
66
import { SketchesService } from '../../../common/protocol';
7-
import { ArduinoCommands } from '../../arduino-commands';
7+
import { OpenSketchFiles } from '../../contributions/open-sketch-files';
88

99
@injectable()
1010
export class FrontendApplication extends TheiaFrontendApplication {
@@ -25,7 +25,7 @@ export class FrontendApplication extends TheiaFrontendApplication {
2525
this.workspaceService.roots.then(async (roots) => {
2626
for (const root of roots) {
2727
await this.commandService.executeCommand(
28-
ArduinoCommands.OPEN_SKETCH_FILES.id,
28+
OpenSketchFiles.Commands.OPEN_SKETCH_FILES.id,
2929
root.resource
3030
);
3131
this.sketchesService.markAsRecentlyOpened(root.resource.toString()); // no await, will get the notification later and rebuild the menu

0 commit comments

Comments
 (0)