@theia/debug 1.67.0-next.59 → 1.67.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser/breakpoint/breakpoint-manager.js +1 -1
- package/lib/browser/breakpoint/breakpoint-manager.js.map +1 -1
- package/lib/browser/console/debug-console-items.d.ts +13 -3
- package/lib/browser/console/debug-console-items.d.ts.map +1 -1
- package/lib/browser/console/debug-console-items.js +81 -20
- package/lib/browser/console/debug-console-items.js.map +1 -1
- package/lib/browser/console/debug-console-session.d.ts.map +1 -1
- package/lib/browser/console/debug-console-session.js +1 -0
- package/lib/browser/console/debug-console-session.js.map +1 -1
- package/lib/browser/debug-commands.d.ts +153 -0
- package/lib/browser/debug-commands.d.ts.map +1 -0
- package/lib/browser/debug-commands.js +399 -0
- package/lib/browser/debug-commands.js.map +1 -0
- package/lib/browser/debug-frontend-application-contribution.d.ts +1 -150
- package/lib/browser/debug-frontend-application-contribution.d.ts.map +1 -1
- package/lib/browser/debug-frontend-application-contribution.js +155 -532
- package/lib/browser/debug-frontend-application-contribution.js.map +1 -1
- package/lib/browser/debug-prefix-configuration.js +3 -3
- package/lib/browser/debug-prefix-configuration.js.map +1 -1
- package/lib/browser/debug-session-contribution.d.ts +2 -1
- package/lib/browser/debug-session-contribution.d.ts.map +1 -1
- package/lib/browser/debug-session-contribution.js +5 -1
- package/lib/browser/debug-session-contribution.js.map +1 -1
- package/lib/browser/debug-session-manager.d.ts +11 -3
- package/lib/browser/debug-session-manager.d.ts.map +1 -1
- package/lib/browser/debug-session-manager.js +49 -8
- package/lib/browser/debug-session-manager.js.map +1 -1
- package/lib/browser/debug-session.d.ts +9 -3
- package/lib/browser/debug-session.d.ts.map +1 -1
- package/lib/browser/debug-session.js +13 -3
- package/lib/browser/debug-session.js.map +1 -1
- package/lib/browser/editor/debug-hover-source.d.ts +1 -0
- package/lib/browser/editor/debug-hover-source.d.ts.map +1 -1
- package/lib/browser/editor/debug-hover-source.js +9 -0
- package/lib/browser/editor/debug-hover-source.js.map +1 -1
- package/lib/browser/editor/debug-inline-value-decorator.js +1 -1
- package/lib/browser/editor/debug-inline-value-decorator.js.map +1 -1
- package/lib/browser/model/debug-breakpoint.d.ts +4 -2
- package/lib/browser/model/debug-breakpoint.d.ts.map +1 -1
- package/lib/browser/model/debug-breakpoint.js +10 -2
- package/lib/browser/model/debug-breakpoint.js.map +1 -1
- package/lib/browser/model/debug-data-breakpoint.d.ts +2 -0
- package/lib/browser/model/debug-data-breakpoint.d.ts.map +1 -1
- package/lib/browser/model/debug-data-breakpoint.js +16 -5
- package/lib/browser/model/debug-data-breakpoint.js.map +1 -1
- package/lib/browser/model/debug-function-breakpoint.d.ts +3 -0
- package/lib/browser/model/debug-function-breakpoint.d.ts.map +1 -1
- package/lib/browser/model/debug-function-breakpoint.js +17 -1
- package/lib/browser/model/debug-function-breakpoint.js.map +1 -1
- package/lib/browser/model/debug-instruction-breakpoint.d.ts +2 -0
- package/lib/browser/model/debug-instruction-breakpoint.d.ts.map +1 -1
- package/lib/browser/model/debug-instruction-breakpoint.js +13 -1
- package/lib/browser/model/debug-instruction-breakpoint.js.map +1 -1
- package/lib/browser/model/debug-source-breakpoint.d.ts +6 -1
- package/lib/browser/model/debug-source-breakpoint.d.ts.map +1 -1
- package/lib/browser/model/debug-source-breakpoint.js +17 -1
- package/lib/browser/model/debug-source-breakpoint.js.map +1 -1
- package/lib/browser/model/debug-stack-frame.d.ts +2 -2
- package/lib/browser/model/debug-stack-frame.d.ts.map +1 -1
- package/lib/browser/model/debug-stack-frame.js +13 -5
- package/lib/browser/model/debug-stack-frame.js.map +1 -1
- package/lib/browser/model/debug-thread.d.ts +2 -2
- package/lib/browser/model/debug-thread.d.ts.map +1 -1
- package/lib/browser/model/debug-thread.js +13 -9
- package/lib/browser/model/debug-thread.js.map +1 -1
- package/lib/browser/view/debug-action.d.ts +1 -0
- package/lib/browser/view/debug-action.d.ts.map +1 -1
- package/lib/browser/view/debug-action.js +2 -2
- package/lib/browser/view/debug-action.js.map +1 -1
- package/lib/browser/view/debug-breakpoints-source.d.ts +2 -0
- package/lib/browser/view/debug-breakpoints-source.d.ts.map +1 -1
- package/lib/browser/view/debug-breakpoints-source.js +6 -1
- package/lib/browser/view/debug-breakpoints-source.js.map +1 -1
- package/lib/browser/view/debug-configuration-widget.js +2 -2
- package/lib/browser/view/debug-configuration-widget.js.map +1 -1
- package/lib/browser/view/debug-exception-breakpoint.d.ts +9 -2
- package/lib/browser/view/debug-exception-breakpoint.d.ts.map +1 -1
- package/lib/browser/view/debug-exception-breakpoint.js +26 -5
- package/lib/browser/view/debug-exception-breakpoint.js.map +1 -1
- package/lib/browser/view/debug-session-widget.d.ts +0 -1
- package/lib/browser/view/debug-session-widget.d.ts.map +1 -1
- package/lib/browser/view/debug-session-widget.js +0 -4
- package/lib/browser/view/debug-session-widget.js.map +1 -1
- package/lib/browser/view/debug-threads-widget.d.ts +6 -1
- package/lib/browser/view/debug-threads-widget.d.ts.map +1 -1
- package/lib/browser/view/debug-threads-widget.js +69 -5
- package/lib/browser/view/debug-threads-widget.js.map +1 -1
- package/lib/browser/view/debug-toolbar-widget.d.ts +5 -18
- package/lib/browser/view/debug-toolbar-widget.d.ts.map +1 -1
- package/lib/browser/view/debug-toolbar-widget.js +14 -58
- package/lib/browser/view/debug-toolbar-widget.js.map +1 -1
- package/lib/browser/view/debug-variables-source.d.ts.map +1 -1
- package/lib/browser/view/debug-variables-source.js +1 -0
- package/lib/browser/view/debug-variables-source.js.map +1 -1
- package/lib/browser/view/debug-variables-widget.d.ts +15 -0
- package/lib/browser/view/debug-variables-widget.d.ts.map +1 -1
- package/lib/browser/view/debug-variables-widget.js +56 -1
- package/lib/browser/view/debug-variables-widget.js.map +1 -1
- package/lib/browser/view/debug-view-model.d.ts +4 -0
- package/lib/browser/view/debug-view-model.d.ts.map +1 -1
- package/lib/browser/view/debug-view-model.js +18 -9
- package/lib/browser/view/debug-view-model.js.map +1 -1
- package/lib/browser/view/debug-watch-expression.d.ts.map +1 -1
- package/lib/browser/view/debug-watch-expression.js +4 -5
- package/lib/browser/view/debug-watch-expression.js.map +1 -1
- package/lib/browser/view/debug-watch-source.d.ts.map +1 -1
- package/lib/browser/view/debug-watch-source.js +1 -0
- package/lib/browser/view/debug-watch-source.js.map +1 -1
- package/lib/common/debug-preferences.d.ts +1 -0
- package/lib/common/debug-preferences.d.ts.map +1 -1
- package/lib/common/debug-preferences.js +11 -1
- package/lib/common/debug-preferences.js.map +1 -1
- package/package.json +16 -16
- package/src/browser/breakpoint/breakpoint-manager.ts +1 -1
- package/src/browser/console/debug-console-items.tsx +90 -21
- package/src/browser/console/debug-console-session.ts +1 -0
- package/src/browser/debug-commands.ts +402 -0
- package/src/browser/debug-frontend-application-contribution.ts +35 -410
- package/src/browser/debug-prefix-configuration.ts +1 -1
- package/src/browser/debug-session-contribution.ts +7 -2
- package/src/browser/debug-session-manager.ts +62 -9
- package/src/browser/debug-session.tsx +17 -4
- package/src/browser/editor/debug-hover-source.tsx +6 -2
- package/src/browser/editor/debug-inline-value-decorator.ts +1 -1
- package/src/browser/model/debug-breakpoint.tsx +12 -3
- package/src/browser/model/debug-data-breakpoint.tsx +21 -6
- package/src/browser/model/debug-function-breakpoint.tsx +22 -1
- package/src/browser/model/debug-instruction-breakpoint.tsx +16 -1
- package/src/browser/model/debug-source-breakpoint.tsx +24 -3
- package/src/browser/model/debug-stack-frame.tsx +13 -6
- package/src/browser/model/debug-thread.tsx +14 -10
- package/src/browser/style/index.css +30 -5
- package/src/browser/view/debug-action.tsx +3 -2
- package/src/browser/view/debug-breakpoints-source.tsx +5 -1
- package/src/browser/view/debug-configuration-widget.tsx +1 -1
- package/src/browser/view/debug-exception-breakpoint.tsx +30 -5
- package/src/browser/view/debug-session-widget.ts +0 -5
- package/src/browser/view/debug-threads-widget.ts +84 -6
- package/src/browser/view/debug-toolbar-widget.tsx +13 -60
- package/src/browser/view/debug-variables-source.ts +1 -0
- package/src/browser/view/debug-variables-widget.ts +59 -0
- package/src/browser/view/debug-view-model.ts +20 -8
- package/src/browser/view/debug-watch-expression.tsx +5 -6
- package/src/browser/view/debug-watch-source.ts +1 -0
- package/src/common/debug-preferences.ts +12 -1
|
@@ -69,14 +69,13 @@
|
|
|
69
69
|
font-size: var(--theia-ui-font-size0);
|
|
70
70
|
line-height: calc(var(--theia-private-horizontal-tab-height) / 2);
|
|
71
71
|
border-radius: 2px;
|
|
72
|
+
margin-left: calc(var(--theia-ui-padding) / 2);
|
|
73
|
+
white-space: nowrap;
|
|
74
|
+
flex-shrink: 0;
|
|
72
75
|
}
|
|
73
76
|
|
|
74
77
|
.theia-data-breakpoint .theia-access-type {
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
.theia-source-breakpoint > .theia-input {
|
|
79
|
-
min-height: auto;
|
|
78
|
+
margin-left: var(--theia-ui-padding);
|
|
80
79
|
}
|
|
81
80
|
|
|
82
81
|
.theia-debug-session .status,
|
|
@@ -187,6 +186,7 @@
|
|
|
187
186
|
}
|
|
188
187
|
|
|
189
188
|
.theia-debug-console-variable {
|
|
189
|
+
display: flex;
|
|
190
190
|
white-space: nowrap;
|
|
191
191
|
overflow: hidden;
|
|
192
192
|
text-overflow: ellipsis;
|
|
@@ -212,6 +212,22 @@
|
|
|
212
212
|
color: var(--theia-variable-name-color);
|
|
213
213
|
}
|
|
214
214
|
|
|
215
|
+
.theia-debug-console-variable .lazy-button {
|
|
216
|
+
margin-left: 3px;
|
|
217
|
+
border-radius: 5px;
|
|
218
|
+
cursor: pointer;
|
|
219
|
+
align-self: center;
|
|
220
|
+
color: var(--theia-icon-foreground);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.theia-debug-console-variable .lazy-button:hover {
|
|
224
|
+
background-color: var(--theia-toolbar-hoverBackground);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.theia-debug-console-variable .value {
|
|
228
|
+
margin-left: 6px;
|
|
229
|
+
}
|
|
230
|
+
|
|
215
231
|
.theia-TreeNode:not(:hover) .theia-debug-console-variable .action-label {
|
|
216
232
|
visibility: hidden;
|
|
217
233
|
}
|
|
@@ -234,6 +250,15 @@
|
|
|
234
250
|
display: flex;
|
|
235
251
|
}
|
|
236
252
|
|
|
253
|
+
.theia-debug-breakpoint-actions {
|
|
254
|
+
display: none;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.theia-source-breakpoint:hover .theia-debug-breakpoint-actions {
|
|
258
|
+
display: flex;
|
|
259
|
+
align-items: center;
|
|
260
|
+
}
|
|
261
|
+
|
|
237
262
|
/** Editor **/
|
|
238
263
|
|
|
239
264
|
.theia-debug-breakpoint-icon {
|
|
@@ -21,7 +21,7 @@ import { MenuPath } from '@theia/core';
|
|
|
21
21
|
export class DebugAction extends React.Component<DebugAction.Props> {
|
|
22
22
|
|
|
23
23
|
override render(): React.ReactNode {
|
|
24
|
-
const { enabled, label, iconClass } = this.props;
|
|
24
|
+
const { enabled, label, tooltip, iconClass } = this.props;
|
|
25
25
|
const classNames = ['debug-action'];
|
|
26
26
|
if (iconClass) {
|
|
27
27
|
classNames.push(...codiconArray(iconClass, true));
|
|
@@ -31,7 +31,7 @@ export class DebugAction extends React.Component<DebugAction.Props> {
|
|
|
31
31
|
}
|
|
32
32
|
return <span tabIndex={0}
|
|
33
33
|
className={classNames.join(' ')}
|
|
34
|
-
title={label}
|
|
34
|
+
title={tooltip || label}
|
|
35
35
|
onClick={() => { this.props.run([]); }}
|
|
36
36
|
ref={this.setRef} >
|
|
37
37
|
{!iconClass && <div>{label}</div>}
|
|
@@ -51,6 +51,7 @@ export class DebugAction extends React.Component<DebugAction.Props> {
|
|
|
51
51
|
export namespace DebugAction {
|
|
52
52
|
export interface Props {
|
|
53
53
|
label: string
|
|
54
|
+
tooltip?: string
|
|
54
55
|
iconClass: string
|
|
55
56
|
run: (effectiveMenuPath: MenuPath) => void
|
|
56
57
|
enabled?: boolean
|
|
@@ -19,6 +19,7 @@ import { TreeSource, TreeElement } from '@theia/core/lib/browser/source-tree';
|
|
|
19
19
|
import { DebugViewModel } from './debug-view-model';
|
|
20
20
|
import { BreakpointManager } from '../breakpoint/breakpoint-manager';
|
|
21
21
|
import { DebugExceptionBreakpoint } from './debug-exception-breakpoint';
|
|
22
|
+
import { CommandService } from '@theia/core/lib/common';
|
|
22
23
|
|
|
23
24
|
@injectable()
|
|
24
25
|
export class DebugBreakpointsSource extends TreeSource {
|
|
@@ -29,6 +30,9 @@ export class DebugBreakpointsSource extends TreeSource {
|
|
|
29
30
|
@inject(BreakpointManager)
|
|
30
31
|
protected readonly breakpoints: BreakpointManager;
|
|
31
32
|
|
|
33
|
+
@inject(CommandService)
|
|
34
|
+
protected readonly commandService: CommandService;
|
|
35
|
+
|
|
32
36
|
@postConstruct()
|
|
33
37
|
protected init(): void {
|
|
34
38
|
this.fireDidChange();
|
|
@@ -37,7 +41,7 @@ export class DebugBreakpointsSource extends TreeSource {
|
|
|
37
41
|
|
|
38
42
|
*getElements(): IterableIterator<TreeElement> {
|
|
39
43
|
for (const exceptionBreakpoint of this.breakpoints.getExceptionBreakpoints()) {
|
|
40
|
-
yield new DebugExceptionBreakpoint(exceptionBreakpoint, this.breakpoints);
|
|
44
|
+
yield new DebugExceptionBreakpoint(exceptionBreakpoint, this.breakpoints, this.commandService);
|
|
41
45
|
}
|
|
42
46
|
yield* this.model.dataBreakpoints;
|
|
43
47
|
yield* this.model.functionBreakpoints;
|
|
@@ -21,7 +21,7 @@ import * as React from '@theia/core/shared/react';
|
|
|
21
21
|
import { WorkspaceService } from '@theia/workspace/lib/browser';
|
|
22
22
|
import { DebugConsoleContribution } from '../console/debug-console-contribution';
|
|
23
23
|
import { DebugConfigurationManager } from '../debug-configuration-manager';
|
|
24
|
-
import { DebugCommands } from '../debug-
|
|
24
|
+
import { DebugCommands } from '../debug-commands';
|
|
25
25
|
import { DebugSessionManager } from '../debug-session-manager';
|
|
26
26
|
import { DebugAction } from './debug-action';
|
|
27
27
|
import { DebugConfigurationSelect } from './debug-configuration-select';
|
|
@@ -18,22 +18,26 @@ import * as React from '@theia/core/shared/react';
|
|
|
18
18
|
import { TreeElement } from '@theia/core/lib/browser/source-tree';
|
|
19
19
|
import { BreakpointManager } from '../breakpoint/breakpoint-manager';
|
|
20
20
|
import { ExceptionBreakpoint } from '../breakpoint/breakpoint-marker';
|
|
21
|
-
import { SingleTextInputDialog } from '@theia/core/lib/browser
|
|
22
|
-
import {
|
|
23
|
-
import { nls } from '@theia/core';
|
|
21
|
+
import { SingleTextInputDialog, TREE_NODE_INFO_CLASS, codicon, TreeWidget } from '@theia/core/lib/browser';
|
|
22
|
+
import { SelectableTreeNode } from '@theia/core/lib/browser/tree/tree-selection';
|
|
23
|
+
import { nls, CommandService } from '@theia/core';
|
|
24
|
+
import { DebugCommands } from '../debug-commands';
|
|
24
25
|
|
|
25
26
|
export class DebugExceptionBreakpoint implements TreeElement {
|
|
26
27
|
|
|
27
28
|
readonly id: string;
|
|
29
|
+
protected treeWidget?: TreeWidget;
|
|
28
30
|
|
|
29
31
|
constructor(
|
|
30
32
|
readonly data: ExceptionBreakpoint,
|
|
31
|
-
readonly breakpoints: BreakpointManager
|
|
33
|
+
readonly breakpoints: BreakpointManager,
|
|
34
|
+
protected readonly commandService: CommandService
|
|
32
35
|
) {
|
|
33
36
|
this.id = data.raw.filter + ':' + data.raw.label;
|
|
34
37
|
}
|
|
35
38
|
|
|
36
|
-
render(): React.ReactNode {
|
|
39
|
+
render(host: TreeWidget): React.ReactNode {
|
|
40
|
+
this.treeWidget = host;
|
|
37
41
|
return <div title={this.data.raw.description || this.data.raw.label} className='theia-source-breakpoint'>
|
|
38
42
|
<span className='theia-debug-breakpoint-icon' />
|
|
39
43
|
<input type='checkbox' checked={this.data.enabled} onChange={this.toggle} />
|
|
@@ -43,9 +47,30 @@ export class DebugExceptionBreakpoint implements TreeElement {
|
|
|
43
47
|
<span title={nls.localizeByDefault('Expression condition: {0}', this.data.condition)}
|
|
44
48
|
className={'path ' + TREE_NODE_INFO_CLASS}>{this.data.condition} </span>}
|
|
45
49
|
</span>
|
|
50
|
+
{this.renderActions()}
|
|
46
51
|
</div>;
|
|
47
52
|
}
|
|
48
53
|
|
|
54
|
+
protected renderActions(): React.ReactNode {
|
|
55
|
+
if (this.data.raw.supportsCondition) {
|
|
56
|
+
return <div className='theia-debug-breakpoint-actions'>
|
|
57
|
+
<div className={codicon('edit', true)} title={nls.localizeByDefault('Edit Condition...')} onClick={this.onEdit} />
|
|
58
|
+
</div>;
|
|
59
|
+
}
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
protected onEdit = async () => {
|
|
64
|
+
await this.selectInTree();
|
|
65
|
+
this.commandService.executeCommand(DebugCommands.EDIT_BREAKPOINT_CONDITION.id);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
protected async selectInTree(): Promise<void> {
|
|
69
|
+
if (this.treeWidget?.model && SelectableTreeNode.is(this)) {
|
|
70
|
+
this.treeWidget.model.selectNode(this);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
49
74
|
protected toggle = () => this.breakpoints.toggleExceptionBreakpoint(this.data.raw.filter);
|
|
50
75
|
|
|
51
76
|
async editCondition(): Promise<void> {
|
|
@@ -100,11 +100,6 @@ export class DebugSessionWidget extends BaseWidget implements StatefulWidget, Ap
|
|
|
100
100
|
layout.addWidget(this.viewContainer);
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
protected override onActivateRequest(msg: Message): void {
|
|
104
|
-
super.onActivateRequest(msg);
|
|
105
|
-
this.toolbar.focus();
|
|
106
|
-
}
|
|
107
|
-
|
|
108
103
|
protected override onAfterShow(msg: Message): void {
|
|
109
104
|
super.onAfterShow(msg);
|
|
110
105
|
this.getTrackableWidgets().forEach(w => w.update());
|
|
@@ -16,8 +16,9 @@
|
|
|
16
16
|
|
|
17
17
|
import { injectable, inject, postConstruct, interfaces, Container } from '@theia/core/shared/inversify';
|
|
18
18
|
import { MenuPath } from '@theia/core';
|
|
19
|
-
import { TreeNode, NodeProps, SelectableTreeNode } from '@theia/core/lib/browser';
|
|
19
|
+
import { TreeNode, NodeProps, SelectableTreeNode, CompositeTreeNode } from '@theia/core/lib/browser';
|
|
20
20
|
import { SourceTreeWidget, TreeElementNode } from '@theia/core/lib/browser/source-tree';
|
|
21
|
+
import { ExpandableTreeNode } from '@theia/core/lib/browser/tree/tree-expansion';
|
|
21
22
|
import { DebugThreadsSource } from './debug-threads-source';
|
|
22
23
|
import { DebugSession } from '../debug-session';
|
|
23
24
|
import { DebugThread } from '../model/debug-thread';
|
|
@@ -65,28 +66,105 @@ export class DebugThreadsWidget extends SourceTreeWidget {
|
|
|
65
66
|
this.toDispose.push(this.threads);
|
|
66
67
|
this.source = this.threads;
|
|
67
68
|
|
|
68
|
-
this.toDispose.push(this.viewModel.onDidChange(() =>
|
|
69
|
+
this.toDispose.push(this.viewModel.onDidChange(() => {
|
|
70
|
+
this.updateWidgetSelection();
|
|
71
|
+
}));
|
|
69
72
|
this.toDispose.push(this.model.onSelectionChanged(() => this.updateModelSelection()));
|
|
70
73
|
}
|
|
71
74
|
|
|
72
75
|
protected updatingSelection = false;
|
|
73
|
-
protected updateWidgetSelection(): void {
|
|
76
|
+
protected async updateWidgetSelection(): Promise<void> {
|
|
74
77
|
if (this.updatingSelection) {
|
|
75
78
|
return;
|
|
76
79
|
}
|
|
77
80
|
this.updatingSelection = true;
|
|
78
81
|
try {
|
|
82
|
+
await this.model.refresh();
|
|
83
|
+
|
|
79
84
|
const { currentThread } = this.viewModel;
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
85
|
+
|
|
86
|
+
// Check if current selection still exists in the tree
|
|
87
|
+
const selectedNode = this.model.selectedNodes[0];
|
|
88
|
+
const selectionStillValid = selectedNode && this.model.getNode(selectedNode.id);
|
|
89
|
+
|
|
90
|
+
// Only update selection if:
|
|
91
|
+
// 1. Current selection is invalid (node no longer in tree), OR
|
|
92
|
+
// 2. There's a stopped thread to show
|
|
93
|
+
if (selectionStillValid && (!currentThread || !currentThread.stopped)) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Try to select the current stopped thread, or clear if none
|
|
98
|
+
if (currentThread && currentThread.stopped) {
|
|
99
|
+
const node = await this.waitForNode(currentThread);
|
|
100
|
+
|
|
101
|
+
// Re-check stopped state after async wait
|
|
102
|
+
if (!currentThread.stopped) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (node && SelectableTreeNode.is(node)) {
|
|
83
107
|
this.model.selectNode(node);
|
|
108
|
+
|
|
109
|
+
// Set context key
|
|
110
|
+
if (TreeElementNode.is(node)) {
|
|
111
|
+
if (node.element instanceof DebugThread) {
|
|
112
|
+
this.debugCallStackItemTypeKey.set('thread');
|
|
113
|
+
} else if (node.element instanceof DebugSession) {
|
|
114
|
+
this.debugCallStackItemTypeKey.set('session');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
84
117
|
}
|
|
118
|
+
} else if (!selectionStillValid) {
|
|
119
|
+
// Selection is stale and no stopped thread to select
|
|
120
|
+
this.model.clearSelection();
|
|
85
121
|
}
|
|
86
122
|
} finally {
|
|
87
123
|
this.updatingSelection = false;
|
|
88
124
|
}
|
|
89
125
|
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Wait for a node to appear in the tree, expanding root children to populate the tree
|
|
129
|
+
*/
|
|
130
|
+
protected async waitForNode(thread: DebugThread): Promise<TreeNode | undefined> {
|
|
131
|
+
const maxAttempts = 10;
|
|
132
|
+
const delayMs = 50;
|
|
133
|
+
const threadId = thread.id;
|
|
134
|
+
|
|
135
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
136
|
+
// If thread continued during wait, abort
|
|
137
|
+
if (!thread.stopped) {
|
|
138
|
+
return undefined;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
await this.model.refresh();
|
|
142
|
+
|
|
143
|
+
const root = this.model.root;
|
|
144
|
+
|
|
145
|
+
// Expand all root's direct children to populate the tree
|
|
146
|
+
if (root && CompositeTreeNode.is(root)) {
|
|
147
|
+
for (const child of root.children) {
|
|
148
|
+
if (ExpandableTreeNode.is(child) && !child.expanded) {
|
|
149
|
+
await this.model.expandNode(child);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Now look directly for the thread node
|
|
155
|
+
const threadNode = this.model.getNode(threadId);
|
|
156
|
+
if (threadNode) {
|
|
157
|
+
return threadNode;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (attempt < maxAttempts - 1) {
|
|
161
|
+
await new Promise(resolve => setTimeout(resolve, delayMs));
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return undefined;
|
|
166
|
+
}
|
|
167
|
+
|
|
90
168
|
protected updateModelSelection(): void {
|
|
91
169
|
if (this.updatingSelection) {
|
|
92
170
|
return;
|
|
@@ -16,69 +16,38 @@
|
|
|
16
16
|
|
|
17
17
|
import * as React from '@theia/core/shared/react';
|
|
18
18
|
import { inject, postConstruct, injectable } from '@theia/core/shared/inversify';
|
|
19
|
-
import { CommandMenu,
|
|
19
|
+
import { CommandMenu, CompoundMenuNode, MenuModelRegistry, MenuPath } from '@theia/core';
|
|
20
|
+
import { KeybindingRegistry } from '@theia/core/lib/browser';
|
|
20
21
|
import { ContextKeyService } from '@theia/core/lib/browser/context-key-service';
|
|
21
22
|
import { ReactWidget } from '@theia/core/lib/browser/widgets';
|
|
22
23
|
import { DebugViewModel } from './debug-view-model';
|
|
23
|
-
import { DebugState } from '../debug-session';
|
|
24
24
|
import { DebugAction } from './debug-action';
|
|
25
|
-
import { nls } from '@theia/core/lib/common/nls';
|
|
26
25
|
|
|
27
26
|
@injectable()
|
|
28
27
|
export class DebugToolBar extends ReactWidget {
|
|
29
28
|
|
|
30
29
|
static readonly MENU: MenuPath = ['debug-toolbar-menu'];
|
|
30
|
+
static readonly CONTROLS: MenuPath = [...DebugToolBar.MENU, 'z_controls'];
|
|
31
31
|
|
|
32
|
-
@inject(CommandRegistry) protected readonly commandRegistry: CommandRegistry;
|
|
33
32
|
@inject(MenuModelRegistry) protected readonly menuModelRegistry: MenuModelRegistry;
|
|
33
|
+
@inject(KeybindingRegistry) protected readonly keybindingRegistry: KeybindingRegistry;
|
|
34
34
|
@inject(ContextKeyService) protected readonly contextKeyService: ContextKeyService;
|
|
35
35
|
@inject(DebugViewModel) protected readonly model: DebugViewModel;
|
|
36
36
|
|
|
37
|
-
protected readonly onRender = new DisposableCollection();
|
|
38
|
-
|
|
39
37
|
@postConstruct()
|
|
40
38
|
protected init(): void {
|
|
41
39
|
this.id = 'debug:toolbar:' + this.model.id;
|
|
42
40
|
this.addClass('debug-toolbar');
|
|
43
41
|
this.toDispose.push(this.model);
|
|
44
42
|
this.toDispose.push(this.model.onDidChange(() => this.update()));
|
|
43
|
+
this.toDispose.push(this.keybindingRegistry.onKeybindingsChanged(() => this.update()));
|
|
45
44
|
this.scrollOptions = undefined;
|
|
46
45
|
this.update();
|
|
47
46
|
}
|
|
48
47
|
|
|
49
|
-
focus(): void {
|
|
50
|
-
if (!this.doFocus()) {
|
|
51
|
-
this.onRender.push(Disposable.create(() => this.doFocus()));
|
|
52
|
-
this.update();
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
protected doFocus(): boolean {
|
|
56
|
-
if (!this.stepRef) {
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
this.stepRef.focus();
|
|
60
|
-
return true;
|
|
61
|
-
}
|
|
62
|
-
protected stepRef: DebugAction | undefined;
|
|
63
|
-
protected setStepRef = (stepRef: DebugAction | null) => {
|
|
64
|
-
this.stepRef = stepRef || undefined;
|
|
65
|
-
this.onRender.dispose();
|
|
66
|
-
};
|
|
67
|
-
|
|
68
48
|
protected render(): React.ReactNode {
|
|
69
|
-
const { state } = this.model;
|
|
70
49
|
return <React.Fragment>
|
|
71
50
|
{this.renderContributedCommands()}
|
|
72
|
-
{this.renderContinue()}
|
|
73
|
-
<DebugAction enabled={state === DebugState.Stopped} run={this.stepOver} label={nls.localizeByDefault('Step Over')}
|
|
74
|
-
iconClass='debug-step-over' ref={this.setStepRef} />
|
|
75
|
-
<DebugAction enabled={state === DebugState.Stopped} run={this.stepIn} label={nls.localizeByDefault('Step Into')}
|
|
76
|
-
iconClass='debug-step-into' />
|
|
77
|
-
<DebugAction enabled={state === DebugState.Stopped} run={this.stepOut} label={nls.localizeByDefault('Step Out')}
|
|
78
|
-
iconClass='debug-step-out' />
|
|
79
|
-
<DebugAction enabled={state !== DebugState.Inactive} run={this.restart} label={nls.localizeByDefault('Restart')}
|
|
80
|
-
iconClass='debug-restart' />
|
|
81
|
-
{this.renderStart()}
|
|
82
51
|
</React.Fragment>;
|
|
83
52
|
}
|
|
84
53
|
|
|
@@ -99,36 +68,20 @@ export class DebugToolBar extends ReactWidget {
|
|
|
99
68
|
}
|
|
100
69
|
|
|
101
70
|
protected debugAction(commandMenuNode: CommandMenu): React.ReactNode {
|
|
71
|
+
const accelerator = this.acceleratorFor(commandMenuNode.id);
|
|
72
|
+
const run = (effectiveMenuPath: MenuPath) => commandMenuNode.run(effectiveMenuPath).catch(e => console.error(e));
|
|
102
73
|
return <DebugAction
|
|
103
74
|
key={commandMenuNode.id}
|
|
104
|
-
enabled={
|
|
75
|
+
enabled={commandMenuNode.isEnabled(DebugToolBar.MENU)}
|
|
105
76
|
label={commandMenuNode.label}
|
|
77
|
+
tooltip={commandMenuNode.label + (accelerator ? ` (${accelerator})` : '')}
|
|
106
78
|
iconClass={commandMenuNode.icon || ''}
|
|
107
|
-
run={
|
|
79
|
+
run={run} />;
|
|
108
80
|
}
|
|
109
81
|
|
|
110
|
-
protected
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
return <DebugAction run={this.start} label={nls.localizeByDefault('Start')} iconClass='debug-start' />;
|
|
114
|
-
}
|
|
115
|
-
return <DebugAction enabled={state !== DebugState.Inactive} run={this.stop} label={nls.localizeByDefault('Stop')} iconClass='debug-stop' />;
|
|
116
|
-
}
|
|
117
|
-
protected renderContinue(): React.ReactNode {
|
|
118
|
-
const { state } = this.model;
|
|
119
|
-
if (state === DebugState.Stopped) {
|
|
120
|
-
return <DebugAction run={this.continue} label={nls.localizeByDefault('Continue')} iconClass='debug-continue' />;
|
|
121
|
-
}
|
|
122
|
-
return <DebugAction enabled={state === DebugState.Running} run={this.pause} label={nls.localizeByDefault('Pause')} iconClass='debug-pause' />;
|
|
82
|
+
protected acceleratorFor(commandId: string): string | undefined {
|
|
83
|
+
const keybindings = this.keybindingRegistry.getKeybindingsForCommand(commandId);
|
|
84
|
+
return keybindings.length ? this.keybindingRegistry.acceleratorFor(keybindings[0], '+').join(' ') : undefined;
|
|
123
85
|
}
|
|
124
86
|
|
|
125
|
-
protected start = () => this.model.start({ startedByUser: true });
|
|
126
|
-
protected restart = () => this.model.restart();
|
|
127
|
-
protected stop = () => this.model.terminate();
|
|
128
|
-
protected continue = () => this.model.currentThread && this.model.currentThread.continue();
|
|
129
|
-
protected pause = () => this.model.currentThread && this.model.currentThread.pause();
|
|
130
|
-
protected stepOver = () => this.model.currentThread && this.model.currentThread.stepOver();
|
|
131
|
-
protected stepIn = () => this.model.currentThread && this.model.currentThread.stepIn();
|
|
132
|
-
protected stepOut = () => this.model.currentThread && this.model.currentThread.stepOut();
|
|
133
|
-
|
|
134
87
|
}
|
|
@@ -30,6 +30,7 @@ export class DebugVariablesSource extends TreeSource {
|
|
|
30
30
|
protected init(): void {
|
|
31
31
|
this.refresh();
|
|
32
32
|
this.toDispose.push(this.model.onDidChange(() => this.refresh()));
|
|
33
|
+
this.toDispose.push(this.model.onDidResolveLazyVariable(() => this.fireDidChange()));
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
protected readonly refresh = debounce(() => this.fireDidChange(), 400);
|
|
@@ -25,6 +25,9 @@ import { SelectableTreeNode, TreeNode, TreeSelection } from '@theia/core/lib/bro
|
|
|
25
25
|
import { DebugVariable } from '../console/debug-console-items';
|
|
26
26
|
import { BreakpointManager } from '../breakpoint/breakpoint-manager';
|
|
27
27
|
import { DataBreakpoint, DataBreakpointSource, DataBreakpointSourceType } from '../breakpoint/breakpoint-marker';
|
|
28
|
+
import { DebugSessionManager } from '../debug-session-manager';
|
|
29
|
+
import { DebugSession } from '../debug-session';
|
|
30
|
+
import { DebugStackFrame } from '../model/debug-stack-frame';
|
|
28
31
|
|
|
29
32
|
@injectable()
|
|
30
33
|
export class DebugVariablesWidget extends SourceTreeWidget {
|
|
@@ -64,6 +67,12 @@ export class DebugVariablesWidget extends SourceTreeWidget {
|
|
|
64
67
|
@inject(BreakpointManager)
|
|
65
68
|
protected readonly breakpointManager: BreakpointManager;
|
|
66
69
|
|
|
70
|
+
@inject(DebugSessionManager)
|
|
71
|
+
protected readonly sessionManager: DebugSessionManager;
|
|
72
|
+
|
|
73
|
+
protected stackFrame: DebugStackFrame | undefined;
|
|
74
|
+
protected readonly statePerSession = new Map<string, DebugVariablesWidgetSessionState>();
|
|
75
|
+
|
|
67
76
|
@postConstruct()
|
|
68
77
|
protected override init(): void {
|
|
69
78
|
super.init();
|
|
@@ -71,6 +80,44 @@ export class DebugVariablesWidget extends SourceTreeWidget {
|
|
|
71
80
|
this.title.label = nls.localizeByDefault('Variables');
|
|
72
81
|
this.toDispose.push(this.variables);
|
|
73
82
|
this.source = this.variables;
|
|
83
|
+
this.toDispose.push(this.sessionManager.onDidFocusStackFrame(stackFrame => this.handleDidFocusStackFrame(stackFrame)));
|
|
84
|
+
this.toDispose.push(this.sessionManager.onDidDestroyDebugSession(session => this.handleDidDestroyDebugSession(session)));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
protected handleDidFocusStackFrame(stackFrame: DebugStackFrame | undefined): void {
|
|
88
|
+
if (this.stackFrame !== stackFrame) {
|
|
89
|
+
if (this.stackFrame) {
|
|
90
|
+
const sessionState = this.getOrCreateSessionState(this.stackFrame.session);
|
|
91
|
+
sessionState.setStateForStackFrame(this.stackFrame, this.superStoreState());
|
|
92
|
+
}
|
|
93
|
+
if (stackFrame) {
|
|
94
|
+
const sessionState = this.statePerSession.get(stackFrame.session.id);
|
|
95
|
+
if (sessionState) {
|
|
96
|
+
const state = sessionState.getStateForStackFrame(stackFrame);
|
|
97
|
+
if (state) {
|
|
98
|
+
this.superRestoreState(state);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
this.stackFrame = stackFrame;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
protected getOrCreateSessionState(session: DebugSession): DebugVariablesWidgetSessionState {
|
|
107
|
+
let sessionState = this.statePerSession.get(session.id);
|
|
108
|
+
if (!sessionState) {
|
|
109
|
+
sessionState = this.newSessionState();
|
|
110
|
+
this.statePerSession.set(session.id, sessionState);
|
|
111
|
+
}
|
|
112
|
+
return sessionState;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
protected newSessionState(): DebugVariablesWidgetSessionState {
|
|
116
|
+
return new DebugVariablesWidgetSessionState();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
protected handleDidDestroyDebugSession(session: DebugSession): void {
|
|
120
|
+
this.statePerSession.delete(session.id);
|
|
74
121
|
}
|
|
75
122
|
|
|
76
123
|
protected override handleContextMenuEvent(node: TreeNode | undefined, event: MouseEvent<HTMLElement>): void {
|
|
@@ -156,3 +203,15 @@ export class DebugVariablesWidget extends SourceTreeWidget {
|
|
|
156
203
|
);
|
|
157
204
|
}
|
|
158
205
|
}
|
|
206
|
+
|
|
207
|
+
export class DebugVariablesWidgetSessionState {
|
|
208
|
+
protected readonly statePerStackFrame = new Map<string, object>();
|
|
209
|
+
|
|
210
|
+
setStateForStackFrame(stackFrame: DebugStackFrame, state: object): void {
|
|
211
|
+
this.statePerStackFrame.set(stackFrame.id, state);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
getStateForStackFrame(stackFrame: DebugStackFrame): object | undefined {
|
|
215
|
+
return this.statePerStackFrame.get(stackFrame.id);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
@@ -29,6 +29,7 @@ import { DebugFunctionBreakpoint } from '../model/debug-function-breakpoint';
|
|
|
29
29
|
import { DebugInstructionBreakpoint } from '../model/debug-instruction-breakpoint';
|
|
30
30
|
import { DebugSessionOptionsBase } from '../debug-session-options';
|
|
31
31
|
import { DebugDataBreakpoint } from '../model/debug-data-breakpoint';
|
|
32
|
+
import { DebugVariable } from '../console/debug-console-items';
|
|
32
33
|
|
|
33
34
|
@injectable()
|
|
34
35
|
export class DebugViewModel implements Disposable {
|
|
@@ -46,6 +47,12 @@ export class DebugViewModel implements Disposable {
|
|
|
46
47
|
this.onDidChangeBreakpointsEmitter.fire(uri);
|
|
47
48
|
}
|
|
48
49
|
|
|
50
|
+
protected readonly onDidResolveLazyVariableEmitter = new Emitter<DebugVariable>();
|
|
51
|
+
readonly onDidResolveLazyVariable: Event<DebugVariable> = this.onDidResolveLazyVariableEmitter.event;
|
|
52
|
+
protected fireDidResolveLazyVariable(variable: DebugVariable): void {
|
|
53
|
+
this.onDidResolveLazyVariableEmitter.fire(variable);
|
|
54
|
+
}
|
|
55
|
+
|
|
49
56
|
protected readonly _watchExpressions = new Map<number, DebugWatchExpression>();
|
|
50
57
|
|
|
51
58
|
protected readonly onDidChangeWatchExpressionsEmitter = new Emitter<void>();
|
|
@@ -57,6 +64,7 @@ export class DebugViewModel implements Disposable {
|
|
|
57
64
|
protected readonly toDispose = new DisposableCollection(
|
|
58
65
|
this.onDidChangeEmitter,
|
|
59
66
|
this.onDidChangeBreakpointsEmitter,
|
|
67
|
+
this.onDidResolveLazyVariableEmitter,
|
|
60
68
|
this.onDidChangeWatchExpressionsEmitter,
|
|
61
69
|
);
|
|
62
70
|
|
|
@@ -88,13 +96,17 @@ export class DebugViewModel implements Disposable {
|
|
|
88
96
|
this.fireDidChange();
|
|
89
97
|
}));
|
|
90
98
|
this.toDispose.push(this.manager.onDidChange(current => {
|
|
91
|
-
if
|
|
92
|
-
|
|
93
|
-
|
|
99
|
+
// Always fire change to update views, even if session is not current
|
|
100
|
+
// This ensures threads view updates for all sessions
|
|
101
|
+
this.fireDidChange();
|
|
94
102
|
}));
|
|
95
103
|
this.toDispose.push(this.manager.onDidChangeBreakpoints(({ session, uri }) => {
|
|
96
|
-
|
|
97
|
-
|
|
104
|
+
// Fire for all sessions since we now show breakpoints from all active sessions
|
|
105
|
+
this.fireDidChangeBreakpoints(uri);
|
|
106
|
+
}));
|
|
107
|
+
this.toDispose.push(this.manager.onDidResolveLazyVariable(({ session, variable }) => {
|
|
108
|
+
if (session === this.currentSession) {
|
|
109
|
+
this.fireDidResolveLazyVariable(variable);
|
|
98
110
|
}
|
|
99
111
|
}));
|
|
100
112
|
this.updateWatchExpressions();
|
|
@@ -127,15 +139,15 @@ export class DebugViewModel implements Disposable {
|
|
|
127
139
|
}
|
|
128
140
|
|
|
129
141
|
get breakpoints(): DebugSourceBreakpoint[] {
|
|
130
|
-
return this.manager.getBreakpoints(
|
|
142
|
+
return this.manager.getBreakpoints();
|
|
131
143
|
}
|
|
132
144
|
|
|
133
145
|
get functionBreakpoints(): DebugFunctionBreakpoint[] {
|
|
134
|
-
return this.manager.getFunctionBreakpoints(
|
|
146
|
+
return this.manager.getFunctionBreakpoints();
|
|
135
147
|
}
|
|
136
148
|
|
|
137
149
|
get instructionBreakpoints(): DebugInstructionBreakpoint[] {
|
|
138
|
-
return this.manager.getInstructionBreakpoints(
|
|
150
|
+
return this.manager.getInstructionBreakpoints();
|
|
139
151
|
}
|
|
140
152
|
|
|
141
153
|
get dataBreakpoints(): DebugDataBreakpoint[] {
|
|
@@ -23,7 +23,7 @@ import { nls } from '@theia/core';
|
|
|
23
23
|
|
|
24
24
|
export class DebugWatchExpression extends ExpressionItem {
|
|
25
25
|
|
|
26
|
-
readonly id: number;
|
|
26
|
+
override readonly id: number;
|
|
27
27
|
protected isError: boolean;
|
|
28
28
|
protected isNotAvailable: boolean;
|
|
29
29
|
|
|
@@ -34,12 +34,12 @@ export class DebugWatchExpression extends ExpressionItem {
|
|
|
34
34
|
remove: () => void,
|
|
35
35
|
onDidChange: () => void
|
|
36
36
|
}) {
|
|
37
|
-
super(options.expression, options.session);
|
|
38
|
-
this.id = options.id;
|
|
37
|
+
super(options.expression, options.session, options.id);
|
|
39
38
|
}
|
|
40
39
|
|
|
41
40
|
override async evaluate(): Promise<void> {
|
|
42
41
|
await super.evaluate('watch');
|
|
42
|
+
this.options.onDidChange();
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
protected override setResult(body?: DebugProtocol.EvaluateResponse['body'], error?: string): void {
|
|
@@ -56,14 +56,13 @@ export class DebugWatchExpression extends ExpressionItem {
|
|
|
56
56
|
super.setResult(body, error);
|
|
57
57
|
this.isError = !!error;
|
|
58
58
|
}
|
|
59
|
-
this.options.onDidChange();
|
|
60
59
|
}
|
|
61
60
|
|
|
62
61
|
override render(): React.ReactNode {
|
|
63
62
|
const valueClass = this.valueClass();
|
|
64
63
|
return <div className='theia-debug-console-variable theia-debug-watch-expression'>
|
|
65
64
|
<div className={TREE_NODE_SEGMENT_GROW_CLASS}>
|
|
66
|
-
<span title={this.type || this._expression} className='name'>{this._expression}
|
|
65
|
+
<span title={this.type || this._expression} className='name'>{this._expression}:</span>
|
|
67
66
|
<span title={this._value} ref={this.setValueRef} className={valueClass}>{this._value}</span>
|
|
68
67
|
</div>
|
|
69
68
|
<div className={codicon('close', true)} title={nls.localizeByDefault('Remove Expression')} onClick={this.options.remove} />
|
|
@@ -77,7 +76,7 @@ export class DebugWatchExpression extends ExpressionItem {
|
|
|
77
76
|
if (this.isNotAvailable) {
|
|
78
77
|
return 'watch-not-available';
|
|
79
78
|
}
|
|
80
|
-
return '';
|
|
79
|
+
return 'value';
|
|
81
80
|
}
|
|
82
81
|
|
|
83
82
|
async open(): Promise<void> {
|
|
@@ -30,6 +30,7 @@ export class DebugWatchSource extends TreeSource {
|
|
|
30
30
|
protected init(): void {
|
|
31
31
|
this.refresh();
|
|
32
32
|
this.toDispose.push(this.model.onDidChangeWatchExpressions(() => this.refresh()));
|
|
33
|
+
this.toDispose.push(this.model.onDidResolveLazyVariable(() => this.refresh()));
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
protected readonly refresh = debounce(() => this.fireDidChange(), 100);
|