mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-11-10 02:48:33 +00:00
renamed customization folder to theia.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
This commit is contained in:
25
arduino-ide-extension/src/browser/theia/core/about-dialog.ts
Normal file
25
arduino-ide-extension/src/browser/theia/core/about-dialog.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { injectable, inject, postConstruct } from 'inversify';
|
||||
import { AboutDialog as TheiaAboutDialog, ABOUT_CONTENT_CLASS } from '@theia/core/lib/browser/about-dialog';
|
||||
import { ConfigService } from '../../../common/protocol/config-service';
|
||||
|
||||
@injectable()
|
||||
export class AboutDialog extends TheiaAboutDialog {
|
||||
|
||||
@inject(ConfigService)
|
||||
protected readonly configService: ConfigService;
|
||||
|
||||
@postConstruct()
|
||||
protected async init(): Promise<void> {
|
||||
const [, version] = await Promise.all([super.init(), this.configService.getVersion()]);
|
||||
if (version) {
|
||||
const { firstChild } = this.contentNode;
|
||||
if (firstChild instanceof HTMLElement && firstChild.classList.contains(ABOUT_CONTENT_CLASS)) {
|
||||
const cliVersion = document.createElement('div');
|
||||
cliVersion.textContent = version;
|
||||
firstChild.appendChild(cliVersion);
|
||||
// TODO: anchor to the commit in the `arduino-cli` repository.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
import { injectable, inject } from 'inversify';
|
||||
import { EditorWidget } from '@theia/editor/lib/browser';
|
||||
import { CommandService } from '@theia/core/lib/common/command';
|
||||
import { PreferencesWidget } from '@theia/preferences/lib/browser/views/preference-widget';
|
||||
import { ApplicationShell as TheiaApplicationShell, Widget } from '@theia/core/lib/browser';
|
||||
import { EditorMode } from '../../editor-mode';
|
||||
import { SaveAsSketch } from '../../contributions/save-as-sketch';
|
||||
|
||||
@injectable()
|
||||
export class ApplicationShell extends TheiaApplicationShell {
|
||||
|
||||
@inject(EditorMode)
|
||||
protected readonly editorMode: EditorMode;
|
||||
|
||||
@inject(CommandService)
|
||||
protected readonly commandService: CommandService;
|
||||
|
||||
protected track(widget: Widget): void {
|
||||
super.track(widget);
|
||||
if (!this.editorMode.proMode) {
|
||||
if (widget instanceof EditorWidget) {
|
||||
// Always allow closing the whitelisted files.
|
||||
// TODO: It would be better to blacklist the sketch files only.
|
||||
if (['tasks.json',
|
||||
'launch.json',
|
||||
'settings.json',
|
||||
'arduino-cli.yaml'].some(fileName => widget.editor.uri.toString().endsWith(fileName))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (widget instanceof PreferencesWidget) {
|
||||
return;
|
||||
}
|
||||
widget.title.closable = false;
|
||||
}
|
||||
}
|
||||
|
||||
async save(): Promise<void> {
|
||||
await super.save();
|
||||
await this.commandService.executeCommand(SaveAsSketch.Commands.SAVE_AS_SKETCH.id, { execOnlyIfTemp: true, openAfterMove: true });
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { injectable } from 'inversify';
|
||||
import { BrowserMainMenuFactory as TheiaBrowserMainMenuFactory, MenuBarWidget } from '@theia/core/lib/browser/menu/browser-menu-plugin';
|
||||
import { MainMenuManager } from '../../../common/main-menu-manager';
|
||||
|
||||
@injectable()
|
||||
export class BrowserMainMenuFactory extends TheiaBrowserMainMenuFactory implements MainMenuManager {
|
||||
|
||||
protected menuBar: MenuBarWidget | undefined;
|
||||
|
||||
createMenuBar(): MenuBarWidget {
|
||||
this.menuBar = super.createMenuBar();
|
||||
return this.menuBar;
|
||||
}
|
||||
|
||||
update() {
|
||||
if (this.menuBar) {
|
||||
this.menuBar.clearMenus();
|
||||
this.fillMenuBar(this.menuBar);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import '../../../../src/browser/style/browser-menu.css';
|
||||
import { ContainerModule } from 'inversify';
|
||||
import { BrowserMenuBarContribution, BrowserMainMenuFactory as TheiaBrowserMainMenuFactory } from '@theia/core/lib/browser/menu/browser-menu-plugin';
|
||||
import { MainMenuManager } from '../../../common/main-menu-manager';
|
||||
import { ArduinoMenuContribution } from './browser-menu-plugin';
|
||||
import { BrowserMainMenuFactory } from './browser-main-menu-factory';
|
||||
|
||||
export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
bind(BrowserMainMenuFactory).toSelf().inSingletonScope();
|
||||
bind(MainMenuManager).toService(BrowserMainMenuFactory);
|
||||
rebind(TheiaBrowserMainMenuFactory).toService(BrowserMainMenuFactory);
|
||||
rebind(BrowserMenuBarContribution).to(ArduinoMenuContribution).inSingletonScope();
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
import { injectable } from 'inversify';
|
||||
import { FrontendApplication } from '@theia/core/lib/browser';
|
||||
import { BrowserMenuBarContribution } from '@theia/core/lib/browser/menu/browser-menu-plugin';
|
||||
|
||||
@injectable()
|
||||
export class ArduinoMenuContribution extends BrowserMenuBarContribution {
|
||||
|
||||
onStart(app: FrontendApplication): void {
|
||||
const menu = this.factory.createMenuBar();
|
||||
app.shell.addWidget(menu, { area: 'top' });
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { injectable } from 'inversify';
|
||||
import { MenuModelRegistry } from '@theia/core/lib/common/menu';
|
||||
import { CommonFrontendContribution as TheiaCommonFrontendContribution, CommonCommands } from '@theia/core/lib/browser/common-frontend-contribution';
|
||||
|
||||
@injectable()
|
||||
export class CommonFrontendContribution extends TheiaCommonFrontendContribution {
|
||||
|
||||
registerMenus(registry: MenuModelRegistry): void {
|
||||
super.registerMenus(registry);
|
||||
for (const command of [
|
||||
CommonCommands.SAVE,
|
||||
CommonCommands.SAVE_ALL,
|
||||
CommonCommands.CUT,
|
||||
CommonCommands.COPY,
|
||||
CommonCommands.PASTE,
|
||||
CommonCommands.COPY_PATH,
|
||||
CommonCommands.FIND,
|
||||
CommonCommands.REPLACE
|
||||
]) {
|
||||
registry.unregisterMenuAction(command);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import { inject, injectable, postConstruct } from 'inversify';
|
||||
import { Disposable } from '@theia/core/lib/common/disposable';
|
||||
import { StatusBarAlignment } from '@theia/core/lib/browser/status-bar/status-bar';
|
||||
import {
|
||||
FrontendConnectionStatusService as TheiaFrontendConnectionStatusService,
|
||||
ApplicationConnectionStatusContribution as TheiaApplicationConnectionStatusContribution,
|
||||
ConnectionStatus
|
||||
} from '@theia/core/lib/browser/connection-status-service';
|
||||
import { ArduinoDaemonClientImpl } from '../../arduino-daemon-client-impl';
|
||||
|
||||
@injectable()
|
||||
export class FrontendConnectionStatusService extends TheiaFrontendConnectionStatusService {
|
||||
|
||||
@inject(ArduinoDaemonClientImpl)
|
||||
protected readonly daemonClient: ArduinoDaemonClientImpl;
|
||||
|
||||
@postConstruct()
|
||||
protected init(): void {
|
||||
this.schedulePing();
|
||||
this.wsConnectionProvider.onIncomingMessageActivity(() => {
|
||||
// natural activity
|
||||
this.updateStatus(this.daemonClient.isRunning);
|
||||
this.schedulePing();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@injectable()
|
||||
export class ApplicationConnectionStatusContribution extends TheiaApplicationConnectionStatusContribution {
|
||||
|
||||
@inject(ArduinoDaemonClientImpl)
|
||||
protected readonly daemonClient: ArduinoDaemonClientImpl;
|
||||
|
||||
protected onStateChange(state: ConnectionStatus): void {
|
||||
if (!this.daemonClient.isRunning && state === ConnectionStatus.ONLINE) {
|
||||
return;
|
||||
}
|
||||
super.onStateChange(state);
|
||||
}
|
||||
|
||||
protected handleOffline(): void {
|
||||
const { isRunning } = this.daemonClient;
|
||||
this.statusBar.setElement('connection-status', {
|
||||
alignment: StatusBarAlignment.LEFT,
|
||||
text: isRunning ? 'Offline' : '$(bolt) CLI Daemon Offline',
|
||||
tooltip: isRunning ? 'Cannot connect to the backend.' : 'Cannot connect to the CLI daemon.',
|
||||
priority: 5000
|
||||
});
|
||||
this.toDisposeOnOnline.push(Disposable.create(() => this.statusBar.removeElement('connection-status')));
|
||||
document.body.classList.add('theia-mod-offline');
|
||||
this.toDisposeOnOnline.push(Disposable.create(() => document.body.classList.remove('theia-mod-offline')));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { injectable, inject } from 'inversify';
|
||||
import { FileSystem } from '@theia/filesystem/lib/common/filesystem';
|
||||
import { CommandService } from '@theia/core/lib/common/command';
|
||||
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
|
||||
import { FrontendApplication as TheiaFrontendApplication } from '@theia/core/lib/browser/frontend-application';
|
||||
import { ArduinoCommands } from '../../arduino-commands';
|
||||
|
||||
@injectable()
|
||||
export class FrontendApplication extends TheiaFrontendApplication {
|
||||
|
||||
@inject(FileSystem)
|
||||
protected readonly fileSystem: FileSystem;
|
||||
|
||||
@inject(WorkspaceService)
|
||||
protected readonly workspaceService: WorkspaceService;
|
||||
|
||||
@inject(CommandService)
|
||||
protected readonly commandService: CommandService;
|
||||
|
||||
protected async initializeLayout(): Promise<void> {
|
||||
await super.initializeLayout();
|
||||
const roots = await this.workspaceService.roots;
|
||||
for (const root of roots) {
|
||||
const exists = await this.fileSystem.exists(root.uri);
|
||||
if (exists) {
|
||||
await this.commandService.executeCommand(ArduinoCommands.OPEN_SKETCH_FILES.id, root.uri);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { injectable } from 'inversify';
|
||||
import { FrontendApplication } from '@theia/core/lib/browser/frontend-application';
|
||||
import { ShellLayoutRestorer as TheiaShellLayoutRestorer } from '@theia/core/lib/browser/shell/shell-layout-restorer';
|
||||
|
||||
@injectable()
|
||||
export class ShellLayoutRestorer extends TheiaShellLayoutRestorer {
|
||||
|
||||
// Workaround for https://github.com/eclipse-theia/theia/issues/6579.
|
||||
async storeLayoutAsync(app: FrontendApplication): Promise<void> {
|
||||
if (this.shouldStoreLayout) {
|
||||
try {
|
||||
this.logger.info('>>> Storing the layout...');
|
||||
const layoutData = app.shell.getLayoutData();
|
||||
const serializedLayoutData = this.deflate(layoutData);
|
||||
await this.storageService.setData(this.storageKey, serializedLayoutData);
|
||||
this.logger.info('<<< The layout has been successfully stored.');
|
||||
} catch (error) {
|
||||
await this.storageService.setData(this.storageKey, undefined);
|
||||
this.logger.error('Error during serialization of layout data', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import { inject, injectable, postConstruct } from 'inversify';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { Title, Widget } from '@phosphor/widgets';
|
||||
import { ILogger } from '@theia/core';
|
||||
import { WidgetDecoration } from '@theia/core/lib/browser/widget-decoration';
|
||||
import { TabBarDecoratorService as TheiaTabBarDecoratorService } from '@theia/core/lib/browser/shell/tab-bar-decorator';
|
||||
import { ConfigService } from '../../../common/protocol/config-service';
|
||||
import { EditorWidget } from '@theia/editor/lib/browser';
|
||||
|
||||
@injectable()
|
||||
export class TabBarDecoratorService extends TheiaTabBarDecoratorService {
|
||||
|
||||
@inject(ConfigService)
|
||||
protected readonly configService: ConfigService;
|
||||
|
||||
@inject(ILogger)
|
||||
protected readonly logger: ILogger;
|
||||
|
||||
|
||||
protected dataDirUri: URI | undefined;
|
||||
|
||||
@postConstruct()
|
||||
protected init(): void {
|
||||
super.init();
|
||||
this.configService.getConfiguration()
|
||||
.then(({ dataDirUri }) => this.dataDirUri = new URI(dataDirUri))
|
||||
.catch(err => this.logger.error(`Failed to determine the data directory: ${err}`));
|
||||
}
|
||||
|
||||
getDecorations(title: Title<Widget>): WidgetDecoration.Data[] {
|
||||
if (title.owner instanceof EditorWidget) {
|
||||
const editor = title.owner.editor;
|
||||
if (this.dataDirUri && this.dataDirUri.isEqualOrParent(editor.uri)) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
return super.getDecorations(title);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { injectable } from 'inversify';
|
||||
import { EditorContribution as TheiaEditorContribution } from '@theia/editor/lib/browser/editor-contribution';
|
||||
import { TextEditor } from '@theia/editor/lib/browser';
|
||||
import { StatusBarAlignment } from '@theia/core/lib/browser';
|
||||
|
||||
@injectable()
|
||||
export class EditorContribution extends TheiaEditorContribution {
|
||||
|
||||
protected updateLanguageStatus(editor: TextEditor | undefined): void {
|
||||
}
|
||||
|
||||
protected setCursorPositionStatus(editor: TextEditor | undefined): void {
|
||||
if (!editor) {
|
||||
this.statusBar.removeElement('editor-status-cursor-position');
|
||||
return;
|
||||
}
|
||||
const { cursor } = editor;
|
||||
this.statusBar.setElement('editor-status-cursor-position', {
|
||||
text: `${cursor.line + 1}`,
|
||||
alignment: StatusBarAlignment.LEFT,
|
||||
priority: 100
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { EditorManager as TheiaEditorManager, EditorOpenerOptions } from '@theia/editor/lib/browser/editor-manager';
|
||||
import { ConfigService } from '../../../common/protocol/config-service';
|
||||
import { EditorWidget } from '@theia/editor/lib/browser';
|
||||
import { MonacoEditor } from '@theia/monaco/lib/browser/monaco-editor';
|
||||
|
||||
@injectable()
|
||||
export class EditorManager extends TheiaEditorManager {
|
||||
|
||||
@inject(ConfigService)
|
||||
protected readonly configService: ConfigService;
|
||||
|
||||
async open(uri: URI, options?: EditorOpenerOptions): Promise<EditorWidget> {
|
||||
const [widget, readOnly] = await Promise.all([super.open(uri, options), this.isReadOnly(uri)]);
|
||||
if (readOnly) {
|
||||
const { editor } = widget;
|
||||
if (editor instanceof MonacoEditor) {
|
||||
const codeEditor = editor.getControl();
|
||||
codeEditor.updateOptions({ readOnly });
|
||||
}
|
||||
}
|
||||
return widget;
|
||||
}
|
||||
|
||||
protected async isReadOnly(uri: URI): Promise<boolean> {
|
||||
const [config, configFileUri] = await Promise.all([
|
||||
this.configService.getConfiguration(),
|
||||
this.configService.getCliConfigFileUri()
|
||||
]);
|
||||
if (new URI(configFileUri).toString(true) === uri.toString(true)) {
|
||||
return false;
|
||||
}
|
||||
return new URI(config.dataDirUri).isEqualOrParent(uri)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { KeybindingRegistry } from '@theia/core/lib/browser';
|
||||
import { ProblemStat } from '@theia/markers/lib/browser/problem/problem-manager';
|
||||
import { FrontendApplication } from '@theia/core/lib/browser/frontend-application';
|
||||
import { ProblemContribution as TheiaProblemContribution } from '@theia/markers/lib/browser/problem/problem-contribution';
|
||||
import { EditorMode } from '../../editor-mode';
|
||||
|
||||
@injectable()
|
||||
export class ProblemContribution extends TheiaProblemContribution {
|
||||
|
||||
@inject(EditorMode)
|
||||
protected readonly editorMode: EditorMode;
|
||||
|
||||
async initializeLayout(app: FrontendApplication): Promise<void> {
|
||||
if (this.editorMode.proMode) {
|
||||
return super.initializeLayout(app);
|
||||
}
|
||||
}
|
||||
|
||||
protected setStatusBarElement(problemStat: ProblemStat): void {
|
||||
if (this.editorMode.proMode) {
|
||||
super.setStatusBarElement(problemStat);
|
||||
}
|
||||
}
|
||||
|
||||
registerKeybindings(keybindings: KeybindingRegistry): void {
|
||||
if (this.toggleCommand) {
|
||||
keybindings.registerKeybinding({
|
||||
command: this.toggleCommand.id,
|
||||
keybinding: 'ctrlcmd+alt+shift+m'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { inject, injectable, postConstruct } from 'inversify';
|
||||
import { Diagnostic } from 'vscode-languageserver-types';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { ILogger } from '@theia/core';
|
||||
import { Marker } from '@theia/markers/lib/common/marker';
|
||||
import { ProblemManager as TheiaProblemManager } from '@theia/markers/lib/browser/problem/problem-manager';
|
||||
import { ConfigService } from '../../../common/protocol/config-service';
|
||||
|
||||
@injectable()
|
||||
export class ProblemManager extends TheiaProblemManager {
|
||||
|
||||
@inject(ConfigService)
|
||||
protected readonly configService: ConfigService;
|
||||
|
||||
@inject(ILogger)
|
||||
protected readonly logger: ILogger;
|
||||
|
||||
protected dataDirUri: URI | undefined;
|
||||
|
||||
@postConstruct()
|
||||
protected init(): void {
|
||||
super.init();
|
||||
this.configService.getConfiguration()
|
||||
.then(({ dataDirUri }) => this.dataDirUri = new URI(dataDirUri))
|
||||
.catch(err => this.logger.error(`Failed to determine the data directory: ${err}`));
|
||||
}
|
||||
|
||||
setMarkers(uri: URI, owner: string, data: Diagnostic[]): Marker<Diagnostic>[] {
|
||||
if (this.dataDirUri && this.dataDirUri.isEqualOrParent(uri)) {
|
||||
return [];
|
||||
}
|
||||
return super.setMarkers(uri, owner, data);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { injectable } from 'inversify';
|
||||
import { MonacoStatusBarContribution as TheiaMonacoStatusBarContribution } from '@theia/monaco/lib/browser/monaco-status-bar-contribution';
|
||||
|
||||
@injectable()
|
||||
export class MonacoStatusBarContribution extends TheiaMonacoStatusBarContribution {
|
||||
|
||||
protected setConfigTabSizeWidget() {
|
||||
}
|
||||
|
||||
protected setLineEndingWidget() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { injectable, inject } from 'inversify';
|
||||
import { FrontendApplication } from '@theia/core/lib/browser/frontend-application';
|
||||
import { FileNavigatorContribution as TheiaFileNavigatorContribution } from '@theia/navigator/lib/browser/navigator-contribution';
|
||||
import { EditorMode } from '../../editor-mode';
|
||||
|
||||
@injectable()
|
||||
export class FileNavigatorContribution extends TheiaFileNavigatorContribution {
|
||||
|
||||
@inject(EditorMode)
|
||||
protected readonly editorMode: EditorMode;
|
||||
|
||||
async initializeLayout(app: FrontendApplication): Promise<void> {
|
||||
if (this.editorMode.proMode) {
|
||||
return super.initializeLayout(app);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { injectable, inject } from 'inversify';
|
||||
import { FrontendApplication } from '@theia/core/lib/browser/frontend-application';
|
||||
import { OutlineViewContribution as TheiaOutlineViewContribution } from '@theia/outline-view/lib/browser/outline-view-contribution';
|
||||
import { EditorMode } from '../../editor-mode';
|
||||
|
||||
@injectable()
|
||||
export class OutlineViewContribution extends TheiaOutlineViewContribution {
|
||||
|
||||
@inject(EditorMode)
|
||||
protected readonly editorMode: EditorMode;
|
||||
|
||||
async initializeLayout(app: FrontendApplication): Promise<void> {
|
||||
if (this.editorMode.proMode) {
|
||||
return super.initializeLayout(app);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { ScmContribution as TheiaScmContribution } from '@theia/scm/lib/browser/scm-contribution';
|
||||
import { StatusBarEntry } from '@theia/core/lib/browser/status-bar/status-bar';
|
||||
import { EditorMode } from '../../editor-mode';
|
||||
|
||||
@injectable()
|
||||
export class ScmContribution extends TheiaScmContribution {
|
||||
|
||||
@inject(EditorMode)
|
||||
protected readonly editorMode: EditorMode;
|
||||
|
||||
async initializeLayout(): Promise<void> {
|
||||
if (this.editorMode.proMode) {
|
||||
return super.initializeLayout();
|
||||
}
|
||||
}
|
||||
|
||||
protected setStatusBarEntry(id: string, entry: StatusBarEntry): void {
|
||||
if (this.editorMode.proMode) {
|
||||
super.setStatusBarEntry(id, entry);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { FrontendApplication } from '@theia/core/lib/browser/frontend-application';
|
||||
import { SearchInWorkspaceFrontendContribution as TheiaSearchInWorkspaceFrontendContribution, SearchInWorkspaceCommands } from '@theia/search-in-workspace/lib/browser/search-in-workspace-frontend-contribution';
|
||||
import { EditorMode } from '../../editor-mode';
|
||||
import { MenuModelRegistry } from '@theia/core';
|
||||
|
||||
@injectable()
|
||||
export class SearchInWorkspaceFrontendContribution extends TheiaSearchInWorkspaceFrontendContribution {
|
||||
|
||||
@inject(EditorMode)
|
||||
protected readonly editorMode: EditorMode;
|
||||
|
||||
async initializeLayout(app: FrontendApplication): Promise<void> {
|
||||
if (this.editorMode.proMode) {
|
||||
return super.initializeLayout(app);
|
||||
}
|
||||
}
|
||||
|
||||
registerMenus(registry: MenuModelRegistry): void {
|
||||
super.registerMenus(registry);
|
||||
registry.unregisterMenuAction(SearchInWorkspaceCommands.OPEN_SIW_WIDGET);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import { injectable } from 'inversify';
|
||||
import { CommandRegistry } from '@theia/core/lib/common/command';
|
||||
import { MenuModelRegistry } from '@theia/core/lib/common/menu';
|
||||
import { WorkspaceCommands, FileMenuContribution } from '@theia/workspace/lib/browser/workspace-commands';
|
||||
import { WorkspaceFrontendContribution as TheiaWorkspaceFrontendContribution } from '@theia/workspace/lib/browser/workspace-frontend-contribution';
|
||||
|
||||
@injectable()
|
||||
export class WorkspaceFrontendContribution extends TheiaWorkspaceFrontendContribution {
|
||||
|
||||
registerCommands(registry: CommandRegistry): void {
|
||||
super.registerCommands(registry);
|
||||
// TODO: instead of blacklisting commands to remove, it would be more robust to whitelist the ones we want to keep
|
||||
const commands = new Set(registry.commands);
|
||||
[
|
||||
WorkspaceCommands.OPEN,
|
||||
WorkspaceCommands.OPEN_FILE,
|
||||
WorkspaceCommands.OPEN_FOLDER,
|
||||
WorkspaceCommands.OPEN_WORKSPACE,
|
||||
WorkspaceCommands.OPEN_RECENT_WORKSPACE,
|
||||
WorkspaceCommands.SAVE_WORKSPACE_AS,
|
||||
WorkspaceCommands.SAVE_AS,
|
||||
WorkspaceCommands.CLOSE
|
||||
].filter(commands.has.bind(commands)).forEach(registry.unregisterCommand.bind(registry));
|
||||
}
|
||||
|
||||
registerMenus(_: MenuModelRegistry): void {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@injectable()
|
||||
export class ArduinoFileMenuContribution extends FileMenuContribution {
|
||||
|
||||
registerMenus(_: MenuModelRegistry): void {
|
||||
// NOOP
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
import { injectable, inject } from 'inversify';
|
||||
import { MessageService } from '@theia/core';
|
||||
import { LabelProvider } from '@theia/core/lib/browser';
|
||||
import { WorkspaceService as TheiaWorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
|
||||
import { ConfigService } from '../../../common/protocol/config-service';
|
||||
import { SketchesService } from '../../../common/protocol/sketches-service';
|
||||
import { ArduinoWorkspaceRootResolver } from '../../arduino-workspace-resolver';
|
||||
import { EditorMode } from '../../editor-mode';
|
||||
|
||||
@injectable()
|
||||
export class WorkspaceService extends TheiaWorkspaceService {
|
||||
|
||||
@inject(SketchesService)
|
||||
protected readonly sketchService: SketchesService;
|
||||
|
||||
@inject(ConfigService)
|
||||
protected readonly configService: ConfigService;
|
||||
|
||||
@inject(LabelProvider)
|
||||
protected readonly labelProvider: LabelProvider;
|
||||
|
||||
@inject(EditorMode)
|
||||
protected readonly editorMode: EditorMode;
|
||||
|
||||
@inject(MessageService)
|
||||
protected readonly messageService: MessageService;
|
||||
|
||||
private workspaceUri?: Promise<string | undefined>;
|
||||
|
||||
protected getDefaultWorkspaceUri(): Promise<string | undefined> {
|
||||
if (this.workspaceUri) {
|
||||
// Avoid creating a new sketch twice
|
||||
return this.workspaceUri;
|
||||
}
|
||||
this.workspaceUri = (async () => {
|
||||
try {
|
||||
const hash = window.location.hash;
|
||||
const [recentWorkspaces, recentSketches] = await Promise.all([
|
||||
this.server.getRecentWorkspaces(),
|
||||
this.sketchService.getSketches().then(sketches => sketches.map(s => s.uri))
|
||||
]);
|
||||
const toOpen = await new ArduinoWorkspaceRootResolver({
|
||||
isValid: this.isValid.bind(this)
|
||||
}).resolve({ hash, recentWorkspaces, recentSketches });
|
||||
if (toOpen) {
|
||||
const { uri } = toOpen;
|
||||
await this.server.setMostRecentlyUsedWorkspace(uri);
|
||||
return toOpen.uri;
|
||||
}
|
||||
return (await this.sketchService.createNewSketch()).uri;
|
||||
} catch (err) {
|
||||
this.logger.fatal(`Failed to determine the sketch directory: ${err}`)
|
||||
this.messageService.error(
|
||||
'There was an error creating the sketch directory. ' +
|
||||
'See the log for more details. ' +
|
||||
'The application will probably not work as expected.')
|
||||
return super.getDefaultWorkspaceUri();
|
||||
}
|
||||
})();
|
||||
return this.workspaceUri;
|
||||
}
|
||||
|
||||
private async isValid(uri: string): Promise<boolean> {
|
||||
const exists = await this.fileSystem.exists(uri);
|
||||
if (!exists) {
|
||||
return false;
|
||||
}
|
||||
// The workspace root location must exist. However, when opening a workspace root in pro-mode,
|
||||
// the workspace root must not be a sketch folder. It can be the default sketch directory, or any other directories, for instance.
|
||||
if (this.editorMode.proMode) {
|
||||
return true;
|
||||
}
|
||||
const sketchFolder = await this.sketchService.isSketchFolder(uri);
|
||||
return sketchFolder;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user