Skip to content

Commit 6c10cab

Browse files
author
Akos Kitta
committed
feat: programmatically update the debug config <select>
before starting the debug session Signed-off-by: Akos Kitta <[email protected]>
1 parent 3ec3ba9 commit 6c10cab

File tree

4 files changed

+128
-1
lines changed

4 files changed

+128
-1
lines changed

Diff for: arduino-ide-extension/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
"deepmerge": "^4.2.2",
7070
"drivelist": "^9.2.4",
7171
"electron-updater": "^4.6.5",
72+
"fast-deep-equal": "^3.1.3",
7273
"fast-json-stable-stringify": "^2.1.0",
7374
"fast-safe-stringify": "^2.1.1",
7475
"filename-reserved-regex": "^2.0.0",

Diff for: arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts

+31-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import '../../src/browser/style/index.css';
2-
import { ContainerModule } from '@theia/core/shared/inversify';
2+
import { Container, ContainerModule } from '@theia/core/shared/inversify';
33
import { WidgetFactory } from '@theia/core/lib/browser/widget-manager';
44
import { CommandContribution } from '@theia/core/lib/common/command';
55
import { bindViewContribution } from '@theia/core/lib/browser/shell/view-contribution';
@@ -363,6 +363,14 @@ import { CommandService } from '@theia/core/lib/common/command';
363363
import { CorePreferences } from '@theia/core/lib/browser/core-preferences';
364364
import { AutoSelectProgrammer } from './contributions/auto-select-programmer';
365365
import { HostedPluginSupport } from './hosted/hosted-plugin-support';
366+
import { DebugSessionManager as TheiaDebugSessionManager } from '@theia/debug/lib/browser/debug-session-manager';
367+
import { DebugSessionManager } from './theia/debug/debug-session-manager';
368+
import { DebugWidget } from '@theia/debug/lib/browser/view/debug-widget';
369+
import { DebugViewModel } from '@theia/debug/lib/browser/view/debug-view-model';
370+
import { DebugSessionWidget } from '@theia/debug/lib/browser/view/debug-session-widget';
371+
import { DebugConfigurationWidget } from './theia/debug/debug-configuration-widget';
372+
import { DebugConfigurationWidget as TheiaDebugConfigurationWidget } from '@theia/debug/lib/browser/view/debug-configuration-widget';
373+
import { DebugToolBar } from '@theia/debug/lib/browser/view/debug-toolbar-widget';
366374

367375
// Hack to fix copy/cut/paste issue after electron version update in Theia.
368376
// https://github.com/eclipse-theia/theia/issues/12487
@@ -860,6 +868,28 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
860868
// To be able to use a `launch.json` from outside of the workspace.
861869
bind(DebugConfigurationManager).toSelf().inSingletonScope();
862870
rebind(TheiaDebugConfigurationManager).toService(DebugConfigurationManager);
871+
// To update the currently selected debug config <select> option when starting a debug session.
872+
bind(DebugSessionManager).toSelf().inSingletonScope();
873+
rebind(TheiaDebugSessionManager).toService(DebugSessionManager);
874+
// Customized debug widget with its customized config <select> to update it programmatically.
875+
bind(WidgetFactory)
876+
.toDynamicValue(({ container }) => ({
877+
id: DebugWidget.ID,
878+
createWidget: () => {
879+
const child = new Container({ defaultScope: 'Singleton' });
880+
child.parent = container;
881+
child.bind(DebugViewModel).toSelf();
882+
child.bind(DebugToolBar).toSelf();
883+
child.bind(DebugSessionWidget).toSelf();
884+
child.bind(DebugConfigurationWidget).toSelf(); // with the patched select
885+
child // use the customized one in the Theia DI
886+
.bind(TheiaDebugConfigurationWidget)
887+
.toService(DebugConfigurationWidget);
888+
child.bind(DebugWidget).toSelf();
889+
return child.get(DebugWidget);
890+
},
891+
}))
892+
.inSingletonScope();
863893

864894
// To avoid duplicate tabs use deepEqual instead of string equal: https://github.com/eclipse-theia/theia/issues/11309
865895
bind(WidgetManager).toSelf().inSingletonScope();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { DisposableCollection } from '@theia/core/lib/common/disposable';
2+
import { nls } from '@theia/core/lib/common/nls';
3+
import { injectable } from '@theia/core/shared/inversify';
4+
import React from '@theia/core/shared/react';
5+
import { DebugAction } from '@theia/debug/lib/browser/view/debug-action';
6+
import { DebugConfigurationSelect as TheiaDebugConfigurationSelect } from '@theia/debug/lib/browser/view/debug-configuration-select';
7+
import { DebugConfigurationWidget as TheiaDebugConfigurationWidget } from '@theia/debug/lib/browser/view/debug-configuration-widget';
8+
9+
/**
10+
* Patched to programmatically update the debug config <select> in the widget.
11+
*/
12+
@injectable()
13+
export class DebugConfigurationWidget extends TheiaDebugConfigurationWidget {
14+
override render(): React.ReactNode {
15+
return (
16+
<React.Fragment>
17+
<DebugAction
18+
run={this.start}
19+
label={nls.localizeByDefault('Start Debugging')}
20+
iconClass="debug-start"
21+
ref={this.setStepRef}
22+
/>
23+
{/* The customized select component that will refresh when the config manager did change */}
24+
<DebugConfigurationSelect
25+
manager={this.manager}
26+
quickInputService={this.quickInputService}
27+
isMultiRoot={this.workspaceService.isMultiRootWorkspaceOpened}
28+
/>
29+
<DebugAction
30+
run={this.openConfiguration}
31+
label={nls.localizeByDefault('Open {0}', '"launch.json"')}
32+
iconClass="settings-gear"
33+
/>
34+
<DebugAction
35+
run={this.openConsole}
36+
label={nls.localizeByDefault('Debug Console')}
37+
iconClass="terminal"
38+
/>
39+
</React.Fragment>
40+
);
41+
}
42+
}
43+
44+
class DebugConfigurationSelect extends TheiaDebugConfigurationSelect {
45+
private readonly toDisposeOnUnmount = new DisposableCollection();
46+
47+
override componentDidMount(): void {
48+
super.componentDidMount();
49+
this.toDisposeOnUnmount.push(
50+
this['manager'].onDidChange(() => this.refreshDebugConfigurations())
51+
);
52+
}
53+
54+
override componentWillUnmount(): void {
55+
this.toDisposeOnUnmount.dispose();
56+
}
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { inject, injectable } from '@theia/core/shared/inversify';
2+
import { DebugSession } from '@theia/debug/lib/browser/debug-session';
3+
import { DebugSessionManager as TheiaDebugSessionManager } from '@theia/debug/lib/browser/debug-session-manager';
4+
import { DebugConfigurationSessionOptions } from '@theia/debug/lib/browser/debug-session-options';
5+
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
6+
import deepEqual from 'fast-deep-equal';
7+
8+
@injectable()
9+
export class DebugSessionManager extends TheiaDebugSessionManager {
10+
@inject(WorkspaceService)
11+
private readonly workspaceService: WorkspaceService;
12+
13+
protected override doStart(
14+
sessionId: string,
15+
options: DebugConfigurationSessionOptions
16+
): Promise<DebugSession> {
17+
this.syncCurrentOptions(options);
18+
return super.doStart(sessionId, options);
19+
}
20+
21+
/**
22+
* If the debug config manager knows about the currently started options, and it's not the currently selected one, select it.
23+
*/
24+
private syncCurrentOptions(options: DebugConfigurationSessionOptions): void {
25+
const knownConfigOptions = this.debugConfigurationManager.find(
26+
options.configuration,
27+
options.workspaceFolderUri ??
28+
this.workspaceService
29+
.tryGetRoots()
30+
.map((stat) => stat.resource.toString())[0]
31+
);
32+
if (
33+
knownConfigOptions &&
34+
!deepEqual(knownConfigOptions, this.debugConfigurationManager.current)
35+
) {
36+
this.debugConfigurationManager.current = knownConfigOptions;
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)