mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-11-17 14:19:29 +00:00
Make tab width 2 spaces (#445)
This commit is contained in:
@@ -10,138 +10,128 @@ import { SketchesService } from '../../../common/protocol';
|
||||
import { SketchesServiceClientImpl } from '../../../common/protocol/sketches-service-client-impl';
|
||||
import { DebugConfigurationModel } from './debug-configuration-model';
|
||||
import {
|
||||
FileOperationError,
|
||||
FileOperationResult,
|
||||
FileOperationError,
|
||||
FileOperationResult,
|
||||
} from '@theia/filesystem/lib/common/files';
|
||||
|
||||
@injectable()
|
||||
export class DebugConfigurationManager extends TheiaDebugConfigurationManager {
|
||||
@inject(SketchesService)
|
||||
protected readonly sketchesService: SketchesService;
|
||||
@inject(SketchesService)
|
||||
protected readonly sketchesService: SketchesService;
|
||||
|
||||
@inject(SketchesServiceClientImpl)
|
||||
protected readonly sketchesServiceClient: SketchesServiceClientImpl;
|
||||
@inject(SketchesServiceClientImpl)
|
||||
protected readonly sketchesServiceClient: SketchesServiceClientImpl;
|
||||
|
||||
@inject(FrontendApplicationStateService)
|
||||
protected readonly appStateService: FrontendApplicationStateService;
|
||||
@inject(FrontendApplicationStateService)
|
||||
protected readonly appStateService: FrontendApplicationStateService;
|
||||
|
||||
protected onTempContentDidChangeEmitter =
|
||||
new Emitter<TheiaDebugConfigurationModel.JsonContent>();
|
||||
get onTempContentDidChange(): Event<TheiaDebugConfigurationModel.JsonContent> {
|
||||
return this.onTempContentDidChangeEmitter.event;
|
||||
}
|
||||
protected onTempContentDidChangeEmitter =
|
||||
new Emitter<TheiaDebugConfigurationModel.JsonContent>();
|
||||
get onTempContentDidChange(): Event<TheiaDebugConfigurationModel.JsonContent> {
|
||||
return this.onTempContentDidChangeEmitter.event;
|
||||
}
|
||||
|
||||
@postConstruct()
|
||||
protected async init(): Promise<void> {
|
||||
super.init();
|
||||
this.appStateService.reachedState('ready').then(async () => {
|
||||
const tempContent = await this.getTempLaunchJsonContent();
|
||||
if (!tempContent) {
|
||||
// No active sketch.
|
||||
return;
|
||||
}
|
||||
// Watch the file of the container folder.
|
||||
this.fileService.watch(
|
||||
tempContent instanceof URI ? tempContent : tempContent.uri
|
||||
);
|
||||
// Use the normalized temp folder name. We cannot compare Theia URIs here.
|
||||
// /var/folders/k3/d2fkvv1j16v3_rz93k7f74180000gn/T/arduino-ide2-a0337d47f86b24a51df3dbcf2cc17925/launch.json
|
||||
// /private/var/folders/k3/d2fkvv1j16v3_rz93k7f74180000gn/T/arduino-ide2-A0337D47F86B24A51DF3DBCF2CC17925/launch.json
|
||||
const tempFolderName = (
|
||||
tempContent instanceof URI
|
||||
? tempContent
|
||||
: tempContent.uri.parent
|
||||
).path.base.toLowerCase();
|
||||
this.fileService.onDidFilesChange((event) => {
|
||||
for (const { resource } of event.changes) {
|
||||
if (
|
||||
resource.path.base === 'launch.json' &&
|
||||
resource.parent.path.base.toLowerCase() ===
|
||||
tempFolderName
|
||||
) {
|
||||
this.getTempLaunchJsonContent().then((config) => {
|
||||
if (config && !(config instanceof URI)) {
|
||||
this.onTempContentDidChangeEmitter.fire(config);
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
@postConstruct()
|
||||
protected async init(): Promise<void> {
|
||||
super.init();
|
||||
this.appStateService.reachedState('ready').then(async () => {
|
||||
const tempContent = await this.getTempLaunchJsonContent();
|
||||
if (!tempContent) {
|
||||
// No active sketch.
|
||||
return;
|
||||
}
|
||||
// Watch the file of the container folder.
|
||||
this.fileService.watch(
|
||||
tempContent instanceof URI ? tempContent : tempContent.uri
|
||||
);
|
||||
// Use the normalized temp folder name. We cannot compare Theia URIs here.
|
||||
// /var/folders/k3/d2fkvv1j16v3_rz93k7f74180000gn/T/arduino-ide2-a0337d47f86b24a51df3dbcf2cc17925/launch.json
|
||||
// /private/var/folders/k3/d2fkvv1j16v3_rz93k7f74180000gn/T/arduino-ide2-A0337D47F86B24A51DF3DBCF2CC17925/launch.json
|
||||
const tempFolderName = (
|
||||
tempContent instanceof URI ? tempContent : tempContent.uri.parent
|
||||
).path.base.toLowerCase();
|
||||
this.fileService.onDidFilesChange((event) => {
|
||||
for (const { resource } of event.changes) {
|
||||
if (
|
||||
resource.path.base === 'launch.json' &&
|
||||
resource.parent.path.base.toLowerCase() === tempFolderName
|
||||
) {
|
||||
this.getTempLaunchJsonContent().then((config) => {
|
||||
if (config && !(config instanceof URI)) {
|
||||
this.onTempContentDidChangeEmitter.fire(config);
|
||||
}
|
||||
});
|
||||
this.updateModels();
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
this.updateModels();
|
||||
});
|
||||
}
|
||||
|
||||
protected updateModels = debounce(async () => {
|
||||
await this.appStateService.reachedState('ready');
|
||||
const roots = await this.workspaceService.roots;
|
||||
const toDelete = new Set(this.models.keys());
|
||||
for (const rootStat of roots) {
|
||||
const key = rootStat.resource.toString();
|
||||
toDelete.delete(key);
|
||||
if (!this.models.has(key)) {
|
||||
const tempContent = await this.getTempLaunchJsonContent();
|
||||
if (!tempContent) {
|
||||
continue;
|
||||
}
|
||||
const configurations: DebugConfiguration[] =
|
||||
tempContent instanceof URI
|
||||
? []
|
||||
: tempContent.configurations;
|
||||
const uri =
|
||||
tempContent instanceof URI ? undefined : tempContent.uri;
|
||||
const model = new DebugConfigurationModel(
|
||||
key,
|
||||
this.preferences,
|
||||
configurations,
|
||||
uri,
|
||||
this.onTempContentDidChange
|
||||
);
|
||||
model.onDidChange(() => this.updateCurrent());
|
||||
model.onDispose(() => this.models.delete(key));
|
||||
this.models.set(key, model);
|
||||
}
|
||||
}
|
||||
for (const uri of toDelete) {
|
||||
const model = this.models.get(uri);
|
||||
if (model) {
|
||||
model.dispose();
|
||||
}
|
||||
}
|
||||
this.updateCurrent();
|
||||
}, 500);
|
||||
|
||||
protected async getTempLaunchJsonContent(): Promise<
|
||||
| (TheiaDebugConfigurationModel.JsonContent & { uri: URI })
|
||||
| URI
|
||||
| undefined
|
||||
> {
|
||||
const sketch = await this.sketchesServiceClient.currentSketch();
|
||||
if (!sketch) {
|
||||
return undefined;
|
||||
}
|
||||
const uri = await this.sketchesService.getIdeTempFolderUri(sketch);
|
||||
const tempFolderUri = new URI(uri);
|
||||
await this.fileService.createFolder(tempFolderUri);
|
||||
try {
|
||||
const uri = tempFolderUri.resolve('launch.json');
|
||||
const { value } = await this.fileService.read(uri);
|
||||
const configurations = DebugConfigurationModel.parse(
|
||||
JSON.parse(value)
|
||||
);
|
||||
return { uri, configurations };
|
||||
} catch (err) {
|
||||
if (
|
||||
err instanceof FileOperationError &&
|
||||
err.fileOperationResult === FileOperationResult.FILE_NOT_FOUND
|
||||
) {
|
||||
return tempFolderUri;
|
||||
}
|
||||
console.error(
|
||||
'Could not load debug configuration from IDE2 temp folder.',
|
||||
err
|
||||
);
|
||||
throw err;
|
||||
protected updateModels = debounce(async () => {
|
||||
await this.appStateService.reachedState('ready');
|
||||
const roots = await this.workspaceService.roots;
|
||||
const toDelete = new Set(this.models.keys());
|
||||
for (const rootStat of roots) {
|
||||
const key = rootStat.resource.toString();
|
||||
toDelete.delete(key);
|
||||
if (!this.models.has(key)) {
|
||||
const tempContent = await this.getTempLaunchJsonContent();
|
||||
if (!tempContent) {
|
||||
continue;
|
||||
}
|
||||
const configurations: DebugConfiguration[] =
|
||||
tempContent instanceof URI ? [] : tempContent.configurations;
|
||||
const uri = tempContent instanceof URI ? undefined : tempContent.uri;
|
||||
const model = new DebugConfigurationModel(
|
||||
key,
|
||||
this.preferences,
|
||||
configurations,
|
||||
uri,
|
||||
this.onTempContentDidChange
|
||||
);
|
||||
model.onDidChange(() => this.updateCurrent());
|
||||
model.onDispose(() => this.models.delete(key));
|
||||
this.models.set(key, model);
|
||||
}
|
||||
}
|
||||
for (const uri of toDelete) {
|
||||
const model = this.models.get(uri);
|
||||
if (model) {
|
||||
model.dispose();
|
||||
}
|
||||
}
|
||||
this.updateCurrent();
|
||||
}, 500);
|
||||
|
||||
protected async getTempLaunchJsonContent(): Promise<
|
||||
(TheiaDebugConfigurationModel.JsonContent & { uri: URI }) | URI | undefined
|
||||
> {
|
||||
const sketch = await this.sketchesServiceClient.currentSketch();
|
||||
if (!sketch) {
|
||||
return undefined;
|
||||
}
|
||||
const uri = await this.sketchesService.getIdeTempFolderUri(sketch);
|
||||
const tempFolderUri = new URI(uri);
|
||||
await this.fileService.createFolder(tempFolderUri);
|
||||
try {
|
||||
const uri = tempFolderUri.resolve('launch.json');
|
||||
const { value } = await this.fileService.read(uri);
|
||||
const configurations = DebugConfigurationModel.parse(JSON.parse(value));
|
||||
return { uri, configurations };
|
||||
} catch (err) {
|
||||
if (
|
||||
err instanceof FileOperationError &&
|
||||
err.fileOperationResult === FileOperationResult.FILE_NOT_FOUND
|
||||
) {
|
||||
return tempFolderUri;
|
||||
}
|
||||
console.error(
|
||||
'Could not load debug configuration from IDE2 temp folder.',
|
||||
err
|
||||
);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,50 +5,50 @@ import { DebugConfiguration } from '@theia/debug/lib/common/debug-common';
|
||||
import { DebugConfigurationModel as TheiaDebugConfigurationModel } from '@theia/debug/lib/browser/debug-configuration-model';
|
||||
|
||||
export class DebugConfigurationModel extends TheiaDebugConfigurationModel {
|
||||
constructor(
|
||||
readonly workspaceFolderUri: string,
|
||||
protected readonly preferences: PreferenceService,
|
||||
protected readonly config: DebugConfiguration[],
|
||||
protected configUri: URI | undefined,
|
||||
protected readonly onConfigDidChange: Event<TheiaDebugConfigurationModel.JsonContent>
|
||||
) {
|
||||
super(workspaceFolderUri, preferences);
|
||||
this.toDispose.push(
|
||||
onConfigDidChange((content) => {
|
||||
const { uri, configurations } = content;
|
||||
this.configUri = uri;
|
||||
this.config.length = 0;
|
||||
this.config.push(...configurations);
|
||||
this.reconcile();
|
||||
})
|
||||
);
|
||||
constructor(
|
||||
readonly workspaceFolderUri: string,
|
||||
protected readonly preferences: PreferenceService,
|
||||
protected readonly config: DebugConfiguration[],
|
||||
protected configUri: URI | undefined,
|
||||
protected readonly onConfigDidChange: Event<TheiaDebugConfigurationModel.JsonContent>
|
||||
) {
|
||||
super(workspaceFolderUri, preferences);
|
||||
this.toDispose.push(
|
||||
onConfigDidChange((content) => {
|
||||
const { uri, configurations } = content;
|
||||
this.configUri = uri;
|
||||
this.config.length = 0;
|
||||
this.config.push(...configurations);
|
||||
this.reconcile();
|
||||
}
|
||||
})
|
||||
);
|
||||
this.reconcile();
|
||||
}
|
||||
|
||||
protected parseConfigurations(): TheiaDebugConfigurationModel.JsonContent {
|
||||
return {
|
||||
uri: this.configUri,
|
||||
configurations: this.config,
|
||||
};
|
||||
}
|
||||
protected parseConfigurations(): TheiaDebugConfigurationModel.JsonContent {
|
||||
return {
|
||||
uri: this.configUri,
|
||||
configurations: this.config,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export namespace DebugConfigurationModel {
|
||||
export function parse(launchConfig: any): DebugConfiguration[] {
|
||||
const configurations: DebugConfiguration[] = [];
|
||||
if (
|
||||
launchConfig &&
|
||||
typeof launchConfig === 'object' &&
|
||||
'configurations' in launchConfig
|
||||
) {
|
||||
if (Array.isArray(launchConfig.configurations)) {
|
||||
for (const configuration of launchConfig.configurations) {
|
||||
if (DebugConfiguration.is(configuration)) {
|
||||
configurations.push(configuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
export function parse(launchConfig: any): DebugConfiguration[] {
|
||||
const configurations: DebugConfiguration[] = [];
|
||||
if (
|
||||
launchConfig &&
|
||||
typeof launchConfig === 'object' &&
|
||||
'configurations' in launchConfig
|
||||
) {
|
||||
if (Array.isArray(launchConfig.configurations)) {
|
||||
for (const configuration of launchConfig.configurations) {
|
||||
if (DebugConfiguration.is(configuration)) {
|
||||
configurations.push(configuration);
|
||||
}
|
||||
}
|
||||
return configurations;
|
||||
}
|
||||
}
|
||||
return configurations;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import debounce from 'p-debounce';
|
||||
import {
|
||||
inject,
|
||||
injectable,
|
||||
postConstruct,
|
||||
interfaces,
|
||||
Container,
|
||||
inject,
|
||||
injectable,
|
||||
postConstruct,
|
||||
interfaces,
|
||||
Container,
|
||||
} from 'inversify';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import {
|
||||
Disposable,
|
||||
DisposableCollection,
|
||||
Disposable,
|
||||
DisposableCollection,
|
||||
} from '@theia/core/lib/common/disposable';
|
||||
import { MonacoConfigurationService } from '@theia/monaco/lib/browser/monaco-frontend-module';
|
||||
import { INLINE_VALUE_DECORATION_KEY } from '@theia/debug/lib/browser/editor//debug-inline-value-decorator';
|
||||
@@ -22,95 +22,93 @@ import { createDebugHoverWidgetContainer } from './debug-hover-widget';
|
||||
// TODO: Remove after https://github.com/eclipse-theia/theia/pull/9256/
|
||||
@injectable()
|
||||
export class DebugEditorModel extends TheiaDebugEditorModel {
|
||||
static createContainer(
|
||||
parent: interfaces.Container,
|
||||
editor: DebugEditor
|
||||
): Container {
|
||||
const child = createDebugHoverWidgetContainer(parent, editor);
|
||||
child.bind(DebugEditorModel).toSelf();
|
||||
child.bind(DebugBreakpointWidget).toSelf();
|
||||
child.bind(DebugExceptionWidget).toSelf();
|
||||
return child;
|
||||
}
|
||||
static createContainer(
|
||||
parent: interfaces.Container,
|
||||
editor: DebugEditor
|
||||
): Container {
|
||||
const child = createDebugHoverWidgetContainer(parent, editor);
|
||||
child.bind(DebugEditorModel).toSelf();
|
||||
child.bind(DebugBreakpointWidget).toSelf();
|
||||
child.bind(DebugExceptionWidget).toSelf();
|
||||
return child;
|
||||
}
|
||||
|
||||
static createModel(
|
||||
parent: interfaces.Container,
|
||||
editor: DebugEditor
|
||||
): DebugEditorModel {
|
||||
return DebugEditorModel.createContainer(parent, editor).get(
|
||||
DebugEditorModel
|
||||
);
|
||||
}
|
||||
static createModel(
|
||||
parent: interfaces.Container,
|
||||
editor: DebugEditor
|
||||
): DebugEditorModel {
|
||||
return DebugEditorModel.createContainer(parent, editor).get(
|
||||
DebugEditorModel
|
||||
);
|
||||
}
|
||||
|
||||
@inject(MonacoConfigurationService)
|
||||
readonly configurationService: monaco.services.IConfigurationService;
|
||||
@inject(MonacoConfigurationService)
|
||||
readonly configurationService: monaco.services.IConfigurationService;
|
||||
|
||||
protected readonly toDisposeOnRenderFrames = new DisposableCollection();
|
||||
protected readonly toDisposeOnRenderFrames = new DisposableCollection();
|
||||
|
||||
@postConstruct()
|
||||
protected init(): void {
|
||||
this.toDispose.push(this.toDisposeOnRenderFrames);
|
||||
super.init();
|
||||
}
|
||||
@postConstruct()
|
||||
protected init(): void {
|
||||
this.toDispose.push(this.toDisposeOnRenderFrames);
|
||||
super.init();
|
||||
}
|
||||
|
||||
protected async updateEditorHover(): Promise<void> {
|
||||
if (this.isCurrentEditorFrame(this.uri)) {
|
||||
const codeEditor = this.editor.getControl();
|
||||
codeEditor.updateOptions({ hover: { enabled: false } });
|
||||
this.toDisposeOnRenderFrames.push(
|
||||
Disposable.create(() => {
|
||||
const model = codeEditor.getModel()!;
|
||||
const overrides = {
|
||||
resource: model.uri,
|
||||
overrideIdentifier: (
|
||||
model as any
|
||||
).getLanguageIdentifier().language,
|
||||
};
|
||||
const { enabled, delay, sticky } =
|
||||
this.configurationService._configuration.getValue(
|
||||
'editor.hover',
|
||||
overrides,
|
||||
undefined
|
||||
);
|
||||
codeEditor.updateOptions({
|
||||
hover: {
|
||||
enabled,
|
||||
delay,
|
||||
sticky,
|
||||
},
|
||||
});
|
||||
})
|
||||
protected async updateEditorHover(): Promise<void> {
|
||||
if (this.isCurrentEditorFrame(this.uri)) {
|
||||
const codeEditor = this.editor.getControl();
|
||||
codeEditor.updateOptions({ hover: { enabled: false } });
|
||||
this.toDisposeOnRenderFrames.push(
|
||||
Disposable.create(() => {
|
||||
const model = codeEditor.getModel()!;
|
||||
const overrides = {
|
||||
resource: model.uri,
|
||||
overrideIdentifier: (model as any).getLanguageIdentifier().language,
|
||||
};
|
||||
const { enabled, delay, sticky } =
|
||||
this.configurationService._configuration.getValue(
|
||||
'editor.hover',
|
||||
overrides,
|
||||
undefined
|
||||
);
|
||||
}
|
||||
codeEditor.updateOptions({
|
||||
hover: {
|
||||
enabled,
|
||||
delay,
|
||||
sticky,
|
||||
},
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private isCurrentEditorFrame(uri: URI): boolean {
|
||||
return (
|
||||
this.sessions.currentFrame?.source?.uri.toString() ===
|
||||
uri.toString()
|
||||
);
|
||||
private isCurrentEditorFrame(uri: URI): boolean {
|
||||
return (
|
||||
this.sessions.currentFrame?.source?.uri.toString() === uri.toString()
|
||||
);
|
||||
}
|
||||
|
||||
protected readonly renderFrames = debounce(async () => {
|
||||
if (this.toDispose.disposed) {
|
||||
return;
|
||||
}
|
||||
this.toDisposeOnRenderFrames.dispose();
|
||||
|
||||
protected readonly renderFrames = debounce(async () => {
|
||||
if (this.toDispose.disposed) {
|
||||
return;
|
||||
}
|
||||
this.toDisposeOnRenderFrames.dispose();
|
||||
|
||||
this.toggleExceptionWidget();
|
||||
const [newFrameDecorations, inlineValueDecorations] = await Promise.all(
|
||||
[this.createFrameDecorations(), this.createInlineValueDecorations()]
|
||||
);
|
||||
const codeEditor = this.editor.getControl();
|
||||
codeEditor.removeDecorations(INLINE_VALUE_DECORATION_KEY);
|
||||
codeEditor.setDecorations(
|
||||
INLINE_VALUE_DECORATION_KEY,
|
||||
inlineValueDecorations
|
||||
);
|
||||
this.frameDecorations = this.deltaDecorations(
|
||||
this.frameDecorations,
|
||||
newFrameDecorations
|
||||
);
|
||||
this.updateEditorHover();
|
||||
}, 100);
|
||||
this.toggleExceptionWidget();
|
||||
const [newFrameDecorations, inlineValueDecorations] = await Promise.all([
|
||||
this.createFrameDecorations(),
|
||||
this.createInlineValueDecorations(),
|
||||
]);
|
||||
const codeEditor = this.editor.getControl();
|
||||
codeEditor.removeDecorations(INLINE_VALUE_DECORATION_KEY);
|
||||
codeEditor.setDecorations(
|
||||
INLINE_VALUE_DECORATION_KEY,
|
||||
inlineValueDecorations
|
||||
);
|
||||
this.frameDecorations = this.deltaDecorations(
|
||||
this.frameDecorations,
|
||||
newFrameDecorations
|
||||
);
|
||||
this.updateEditorHover();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import { injectable } from 'inversify';
|
||||
import { MenuModelRegistry } from '@theia/core/lib/common/menu';
|
||||
import {
|
||||
DebugFrontendApplicationContribution as TheiaDebugFrontendApplicationContribution,
|
||||
DebugMenus,
|
||||
DebugFrontendApplicationContribution as TheiaDebugFrontendApplicationContribution,
|
||||
DebugMenus,
|
||||
} from '@theia/debug/lib/browser/debug-frontend-application-contribution';
|
||||
import { unregisterSubmenu } from '../../menu/arduino-menus';
|
||||
|
||||
@injectable()
|
||||
export class DebugFrontendApplicationContribution extends TheiaDebugFrontendApplicationContribution {
|
||||
constructor() {
|
||||
super();
|
||||
this.options.defaultWidgetOptions.rank = 4;
|
||||
}
|
||||
constructor() {
|
||||
super();
|
||||
this.options.defaultWidgetOptions.rank = 4;
|
||||
}
|
||||
|
||||
registerMenus(registry: MenuModelRegistry): void {
|
||||
super.registerMenus(registry);
|
||||
unregisterSubmenu(DebugMenus.DEBUG, registry);
|
||||
}
|
||||
registerMenus(registry: MenuModelRegistry): void {
|
||||
super.registerMenus(registry);
|
||||
unregisterSubmenu(DebugMenus.DEBUG, registry);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
import { injectable } from 'inversify';
|
||||
import {
|
||||
ExpressionItem,
|
||||
DebugVariable,
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,116 +7,113 @@ import { DebugVariable } from '@theia/debug/lib/browser/console/debug-console-it
|
||||
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,
|
||||
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
|
||||
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;
|
||||
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
|
||||
);
|
||||
});
|
||||
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
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,54 +6,48 @@ import { DebugSessionManager as TheiaDebugSessionManager } from '@theia/debug/li
|
||||
|
||||
@injectable()
|
||||
export class DebugSessionManager extends TheiaDebugSessionManager {
|
||||
async start(
|
||||
options: DebugSessionOptions
|
||||
): Promise<DebugSession | undefined> {
|
||||
return this.progressService.withProgress(
|
||||
'Start...',
|
||||
'debug',
|
||||
async () => {
|
||||
try {
|
||||
// Only save when dirty. To avoid saving temporary sketches.
|
||||
// This is a quick fix for not saving the editor when there are no dirty editors.
|
||||
// // https://github.com/bcmi-labs/arduino-editor/pull/172#issuecomment-741831888
|
||||
if (this.shell.canSaveAll()) {
|
||||
await this.shell.saveAll();
|
||||
}
|
||||
await this.fireWillStartDebugSession();
|
||||
const resolved = await this.resolveConfiguration(options);
|
||||
async start(options: DebugSessionOptions): Promise<DebugSession | undefined> {
|
||||
return this.progressService.withProgress('Start...', 'debug', async () => {
|
||||
try {
|
||||
// Only save when dirty. To avoid saving temporary sketches.
|
||||
// This is a quick fix for not saving the editor when there are no dirty editors.
|
||||
// // https://github.com/bcmi-labs/arduino-editor/pull/172#issuecomment-741831888
|
||||
if (this.shell.canSaveAll()) {
|
||||
await this.shell.saveAll();
|
||||
}
|
||||
await this.fireWillStartDebugSession();
|
||||
const resolved = await this.resolveConfiguration(options);
|
||||
|
||||
// preLaunchTask isn't run in case of auto restart as well as postDebugTask
|
||||
if (!options.configuration.__restart) {
|
||||
const taskRun = await this.runTask(
|
||||
options.workspaceFolderUri,
|
||||
resolved.configuration.preLaunchTask,
|
||||
true
|
||||
);
|
||||
if (!taskRun) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
// preLaunchTask isn't run in case of auto restart as well as postDebugTask
|
||||
if (!options.configuration.__restart) {
|
||||
const taskRun = await this.runTask(
|
||||
options.workspaceFolderUri,
|
||||
resolved.configuration.preLaunchTask,
|
||||
true
|
||||
);
|
||||
if (!taskRun) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
const sessionId = await this.debug.createDebugSession(
|
||||
resolved.configuration
|
||||
);
|
||||
return this.doStart(sessionId, resolved);
|
||||
} catch (e) {
|
||||
if (DebugError.NotFound.is(e)) {
|
||||
this.messageService.error(
|
||||
`The debug session type "${e.data.type}" is not supported.`
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
this.messageService.error(
|
||||
'There was an error starting the debug session, check the logs for more details.'
|
||||
);
|
||||
console.error('Error starting the debug session', e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
const sessionId = await this.debug.createDebugSession(
|
||||
resolved.configuration
|
||||
);
|
||||
}
|
||||
return this.doStart(sessionId, resolved);
|
||||
} catch (e) {
|
||||
if (DebugError.NotFound.is(e)) {
|
||||
this.messageService.error(
|
||||
`The debug session type "${e.data.type}" is not supported.`
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
this.messageService.error(
|
||||
'There was an error starting the debug session, check the logs for more details.'
|
||||
);
|
||||
console.error('Error starting the debug session', e);
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user