@opensumi/ide-debug 2.23.4 → 2.23.5-rc-1681807382.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.
Files changed (63) hide show
  1. package/lib/browser/breakpoint/breakpoint-marker.d.ts +2 -0
  2. package/lib/browser/breakpoint/breakpoint-marker.d.ts.map +1 -1
  3. package/lib/browser/breakpoint/breakpoint-marker.js +4 -1
  4. package/lib/browser/breakpoint/breakpoint-marker.js.map +1 -1
  5. package/lib/browser/debug-contribution.js +2 -2
  6. package/lib/browser/debug-contribution.js.map +1 -1
  7. package/lib/browser/model/debug-stack-frame.d.ts +12 -0
  8. package/lib/browser/model/debug-stack-frame.d.ts.map +1 -1
  9. package/lib/browser/model/debug-stack-frame.js +27 -1
  10. package/lib/browser/model/debug-stack-frame.js.map +1 -1
  11. package/lib/browser/model/debug-thread.d.ts.map +1 -1
  12. package/lib/browser/model/debug-thread.js +6 -4
  13. package/lib/browser/model/debug-thread.js.map +1 -1
  14. package/lib/browser/view/breakpoints/debug-breakpoints-tree.model.d.ts +14 -0
  15. package/lib/browser/view/breakpoints/debug-breakpoints-tree.model.d.ts.map +1 -0
  16. package/lib/browser/view/breakpoints/debug-breakpoints-tree.model.js +28 -0
  17. package/lib/browser/view/breakpoints/debug-breakpoints-tree.model.js.map +1 -0
  18. package/lib/browser/view/breakpoints/debug-breakpoints.module.less +6 -5
  19. package/lib/browser/view/breakpoints/debug-breakpoints.service.d.ts +8 -3
  20. package/lib/browser/view/breakpoints/debug-breakpoints.service.d.ts.map +1 -1
  21. package/lib/browser/view/breakpoints/debug-breakpoints.service.js +79 -33
  22. package/lib/browser/view/breakpoints/debug-breakpoints.service.js.map +1 -1
  23. package/lib/browser/view/breakpoints/debug-breakpoints.view.d.ts +2 -1
  24. package/lib/browser/view/breakpoints/debug-breakpoints.view.d.ts.map +1 -1
  25. package/lib/browser/view/breakpoints/debug-breakpoints.view.js +69 -12
  26. package/lib/browser/view/breakpoints/debug-breakpoints.view.js.map +1 -1
  27. package/lib/browser/view/configuration/debug-configuration.module.less +10 -4
  28. package/lib/browser/view/configuration/debug-configuration.view.d.ts +9 -1
  29. package/lib/browser/view/configuration/debug-configuration.view.d.ts.map +1 -1
  30. package/lib/browser/view/configuration/debug-configuration.view.js +16 -8
  31. package/lib/browser/view/configuration/debug-configuration.view.js.map +1 -1
  32. package/lib/browser/view/configuration/debug-toolbar.view.d.ts +5 -0
  33. package/lib/browser/view/configuration/debug-toolbar.view.d.ts.map +1 -1
  34. package/lib/browser/view/configuration/debug-toolbar.view.js +5 -1
  35. package/lib/browser/view/configuration/debug-toolbar.view.js.map +1 -1
  36. package/lib/browser/view/frames/debug-call-stack-frame.view.d.ts +1 -0
  37. package/lib/browser/view/frames/debug-call-stack-frame.view.d.ts.map +1 -1
  38. package/lib/browser/view/frames/debug-call-stack-frame.view.js +136 -26
  39. package/lib/browser/view/frames/debug-call-stack-frame.view.js.map +1 -1
  40. package/lib/browser/view/frames/debug-call-stack-session.view.d.ts.map +1 -1
  41. package/lib/browser/view/frames/debug-call-stack-session.view.js +17 -10
  42. package/lib/browser/view/frames/debug-call-stack-session.view.js.map +1 -1
  43. package/lib/browser/view/frames/debug-call-stack-thread.view.d.ts +1 -0
  44. package/lib/browser/view/frames/debug-call-stack-thread.view.d.ts.map +1 -1
  45. package/lib/browser/view/frames/debug-call-stack-thread.view.js +10 -7
  46. package/lib/browser/view/frames/debug-call-stack-thread.view.js.map +1 -1
  47. package/lib/browser/view/frames/debug-call-stack.module.less +1 -2
  48. package/package.json +23 -23
  49. package/src/browser/breakpoint/breakpoint-marker.ts +3 -1
  50. package/src/browser/debug-contribution.ts +3 -3
  51. package/src/browser/model/debug-stack-frame.ts +28 -2
  52. package/src/browser/model/debug-thread.ts +6 -4
  53. package/src/browser/view/breakpoints/debug-breakpoints-tree.model.ts +35 -0
  54. package/src/browser/view/breakpoints/debug-breakpoints.module.less +6 -5
  55. package/src/browser/view/breakpoints/debug-breakpoints.service.ts +80 -31
  56. package/src/browser/view/breakpoints/debug-breakpoints.view.tsx +120 -23
  57. package/src/browser/view/configuration/debug-configuration.module.less +10 -4
  58. package/src/browser/view/configuration/debug-configuration.view.tsx +36 -20
  59. package/src/browser/view/configuration/debug-toolbar.view.tsx +10 -5
  60. package/src/browser/view/frames/debug-call-stack-frame.view.tsx +184 -51
  61. package/src/browser/view/frames/debug-call-stack-session.view.tsx +29 -15
  62. package/src/browser/view/frames/debug-call-stack-thread.view.tsx +14 -8
  63. package/src/browser/view/frames/debug-call-stack.module.less +1 -2
@@ -1,4 +1,4 @@
1
- import { IRange } from '@opensumi/ide-core-browser';
1
+ import { formatLocalize, IRange } from '@opensumi/ide-core-browser';
2
2
  import { IResourceOpenOptions } from '@opensumi/ide-editor';
3
3
  import { Range } from '@opensumi/monaco-editor-core/esm/vs/editor/common/core/range';
4
4
  import { DebugProtocol } from '@opensumi/vscode-debugprotocol/lib/debugProtocol';
@@ -9,12 +9,15 @@ import { DebugScope, ExpressionContainer } from '../tree/debug-tree-node.define'
9
9
  import { DebugSource } from './debug-source';
10
10
  import { DebugThread } from './debug-thread';
11
11
 
12
-
13
12
  export class DebugStackFrameData {
14
13
  readonly raw: DebugProtocol.StackFrame;
15
14
  }
16
15
 
17
16
  export class DebugStackFrame extends DebugStackFrameData {
17
+ public static is(frame: any): frame is DebugStackFrame {
18
+ return !!frame && 'raw' in frame;
19
+ }
20
+
18
21
  constructor(readonly thread: DebugThread, readonly session: DebugSession) {
19
22
  super();
20
23
  }
@@ -109,3 +112,26 @@ export class DebugStackFrame extends DebugStackFrameData {
109
112
  return scopesContainingRange.length ? scopesContainingRange : nonExpensiveScopes;
110
113
  }
111
114
  }
115
+
116
+ export class ShowMoreDebugStackFrame {
117
+ constructor(
118
+ // `undefined` 说明已经在末尾
119
+ public readonly nextFrame: DebugStackFrame | undefined,
120
+ public readonly frames: DebugStackFrame[],
121
+ readonly session: DebugSession,
122
+ readonly origin: string,
123
+ readonly _open: (showMoreFrame: ShowMoreDebugStackFrame) => void,
124
+ ) {}
125
+
126
+ get name() {
127
+ return formatLocalize('debug.stack.showMoreAndOrigin', this.frames.length, this.origin);
128
+ }
129
+
130
+ get id(): string {
131
+ return `${this.session.id}:showMore:${this.nextFrame?.id}`;
132
+ }
133
+
134
+ open = () => {
135
+ this._open(this);
136
+ };
137
+ }
@@ -158,10 +158,12 @@ export class DebugThread extends DebugThreadData {
158
158
  const result = new Map<number, DebugStackFrame>(this._frames);
159
159
  for (const raw of frames) {
160
160
  const id = raw.id;
161
- const frame = this._frames.get(id) || new DebugStackFrame(this, this.session);
162
- this._frames.set(id, frame);
163
- frame.update({ raw });
164
- result.set(id, frame);
161
+ if (!this._frames.has(id)) {
162
+ const frame = new DebugStackFrame(this, this.session);
163
+ this._frames.set(id, frame);
164
+ frame.update({ raw });
165
+ result.set(id, frame);
166
+ }
165
167
  }
166
168
  const values = [...result.values()];
167
169
  frontEndTime('doUpdateFrames');
@@ -0,0 +1,35 @@
1
+ import { IBasicTreeData } from '@opensumi/ide-components';
2
+ import { Emitter, URI } from '@opensumi/ide-core-common';
3
+
4
+ import { isDebugBreakpoint } from '../../breakpoint';
5
+
6
+ import { BreakpointItem } from './debug-breakpoints.view';
7
+
8
+ export class BreakpointsTreeNode implements IBasicTreeData {
9
+ public label = '';
10
+ public rawData: BreakpointItem;
11
+ private _uri: URI;
12
+ private _onDescriptionChange = new Emitter<string>();
13
+
14
+ constructor(uri: URI, rawData: BreakpointItem) {
15
+ const { breakpoint } = rawData;
16
+
17
+ this._uri = uri;
18
+ this.label = isDebugBreakpoint(breakpoint) ? uri.displayName : '';
19
+ this.rawData = rawData;
20
+ this.rawData.onDescriptionChange = this._onDescriptionChange.event;
21
+ }
22
+
23
+ get breakpoint() {
24
+ return this.rawData.breakpoint;
25
+ }
26
+
27
+ get uri() {
28
+ return this._uri;
29
+ }
30
+
31
+ fireDescriptionChange(value: string): void {
32
+ this.rawData.description = value;
33
+ this._onDescriptionChange.fire(value);
34
+ }
35
+ }
@@ -21,8 +21,6 @@
21
21
  pointer-events: none;
22
22
  }
23
23
  &:hover {
24
- background: var(--list-hoverBackground);
25
- color: var(--list-hoverForeground);
26
24
  .debug_remove_breakpoints_icon {
27
25
  display: inline-block;
28
26
  pointer-events: all;
@@ -42,6 +40,7 @@
42
40
  width: 19px;
43
41
  height: 19px;
44
42
  min-width: 19px;
43
+ margin-right: 3px;
45
44
  }
46
45
 
47
46
  .debug_breakpoints_badge {
@@ -51,9 +50,7 @@
51
50
 
52
51
  .debug_breakpoints_description {
53
52
  display: block;
54
- transform: scale(0.95);
55
- opacity: 0.7;
56
- margin-left: 5px;
53
+ opacity: 0.85;
57
54
  display: inline;
58
55
  }
59
56
 
@@ -69,3 +66,7 @@
69
66
  margin-right: 5px;
70
67
  flex: 1;
71
68
  }
69
+
70
+ .debug_breakpoints_item_tree_node {
71
+ padding-left: 27px !important;
72
+ }
@@ -1,7 +1,16 @@
1
1
  import { observable, action, runInAction } from 'mobx';
2
2
 
3
3
  import { Injectable, Autowired } from '@opensumi/di';
4
- import { URI, WithEventBus, OnEvent, IContextKeyService, IReporterService, Schemes } from '@opensumi/ide-core-browser';
4
+ import {
5
+ URI,
6
+ WithEventBus,
7
+ OnEvent,
8
+ IContextKeyService,
9
+ IReporterService,
10
+ Schemes,
11
+ Emitter,
12
+ Event,
13
+ } from '@opensumi/ide-core-browser';
5
14
  import { LabelService } from '@opensumi/ide-core-browser/lib/services';
6
15
  import { ICodeEditor, EditorCollectionService, getSimpleEditorOptions } from '@opensumi/ide-editor';
7
16
  import { IEditorDocumentModelService } from '@opensumi/ide-editor/lib/browser';
@@ -16,10 +25,12 @@ import {
16
25
  isDebugExceptionBreakpoint,
17
26
  BreakpointManager,
18
27
  DebugDecorator,
28
+ EXCEPTION_BREAKPOINT_URI,
19
29
  } from '../../breakpoint';
20
30
  import { DebugSessionManager } from '../../debug-session-manager';
21
31
  import { DebugViewModel } from '../debug-view-model';
22
32
 
33
+ import { BreakpointsTreeNode } from './debug-breakpoints-tree.model';
23
34
  import { BreakpointItem } from './debug-breakpoints.view';
24
35
 
25
36
  @Injectable()
@@ -51,14 +62,17 @@ export class DebugBreakpointsService extends WithEventBus {
51
62
  @Autowired(IEditorDocumentModelService)
52
63
  protected readonly documentService: IEditorDocumentModelService;
53
64
 
65
+ private readonly _onDidChangeBreakpointsTreeNode = new Emitter<Map<string, BreakpointsTreeNode[]>>();
66
+ readonly onDidChangeBreakpointsTreeNode: Event<Map<string, BreakpointsTreeNode[]>> =
67
+ this._onDidChangeBreakpointsTreeNode.event;
68
+
54
69
  private _inputEditor: ICodeEditor;
55
70
 
56
71
  public get inputEditor(): ICodeEditor {
57
72
  return this._inputEditor;
58
73
  }
59
74
 
60
- @observable
61
- public nodes: BreakpointItem[] = [];
75
+ public treeNodeMap: Map<string, BreakpointsTreeNode[]> = new Map();
62
76
 
63
77
  @observable
64
78
  public enable: boolean;
@@ -75,7 +89,6 @@ export class DebugBreakpointsService extends WithEventBus {
75
89
 
76
90
  async init() {
77
91
  await this.updateRoots();
78
- await this.updateBreakpoints();
79
92
  this.workspaceService.onWorkspaceChanged(async () => {
80
93
  this.updateRoots();
81
94
  this.updateBreakpoints();
@@ -86,6 +99,9 @@ export class DebugBreakpointsService extends WithEventBus {
86
99
  this.breakpoints.onDidChangeExceptionsBreakpoints(() => {
87
100
  this.updateBreakpoints();
88
101
  });
102
+ this.breakpoints.whenReady.then(() => {
103
+ this.updateBreakpoints();
104
+ });
89
105
  this.contextKeyService.onDidChangeContext((e) => {
90
106
  if (e.payload.affectsSome(new Set([CONTEXT_IN_DEBUG_MODE_KEY]))) {
91
107
  runInAction(() => {
@@ -139,38 +155,71 @@ export class DebugBreakpointsService extends WithEventBus {
139
155
  }
140
156
  }
141
157
 
142
- extractNodes(items: (DebugExceptionBreakpoint | IDebugBreakpoint)[]) {
143
- const nodes: BreakpointItem[] = [];
144
- items.forEach((item) => {
145
- if (isDebugBreakpoint(item)) {
146
- const uri = URI.parse(item.uri);
147
- const parent = this.roots.filter((root) => root.isEqualOrParent(uri))[0];
148
- nodes.push({
149
- id: item.id,
150
- name: uri.displayName,
151
- description: parent && parent.relative(uri)!.toString(),
152
- breakpoint: item,
153
- });
154
- }
155
- if (isDebugExceptionBreakpoint(item)) {
156
- nodes.push({
157
- id: item.filter,
158
- name: item.label,
159
- description: '',
160
- breakpoint: item,
161
- });
162
- }
163
- });
164
- return nodes;
158
+ extractNodes(item: DebugExceptionBreakpoint | IDebugBreakpoint): BreakpointItem | undefined {
159
+ if (isDebugBreakpoint(item)) {
160
+ return {
161
+ id: item.id,
162
+ name: '',
163
+ description: '',
164
+ onDescriptionChange: Event.None,
165
+ breakpoint: item,
166
+ };
167
+ }
168
+ if (isDebugExceptionBreakpoint(item)) {
169
+ return {
170
+ id: item.filter,
171
+ name: item.label,
172
+ onDescriptionChange: Event.None,
173
+ description: '',
174
+ breakpoint: item,
175
+ };
176
+ }
165
177
  }
166
178
 
167
179
  @action
168
180
  private async updateBreakpoints() {
169
181
  await this.breakpoints.whenReady;
170
- this.nodes = this.extractNodes([
171
- ...this.breakpoints.getExceptionBreakpoints(),
172
- ...this.breakpoints.getBreakpoints(),
173
- ]);
182
+ this.treeNodeMap.clear();
183
+
184
+ const allBreakpoints = [...this.breakpoints.getExceptionBreakpoints(), ...this.breakpoints.getBreakpoints()];
185
+
186
+ allBreakpoints.forEach((item) => {
187
+ const extractNode = this.extractNodes(item);
188
+ if (extractNode) {
189
+ const uri = isDebugBreakpoint(item) ? URI.parse(item.uri) : EXCEPTION_BREAKPOINT_URI;
190
+ const getTreeNodes = this.treeNodeMap.get(uri.toString()) || [];
191
+ getTreeNodes.push(new BreakpointsTreeNode(uri, extractNode));
192
+ this.treeNodeMap.set(uri.toString(), getTreeNodes);
193
+ }
194
+ });
195
+ this._onDidChangeBreakpointsTreeNode.fire(this.treeNodeMap);
196
+ }
197
+
198
+ private async getDocumentModelRef(uri: URI) {
199
+ const document = this.documentService.getModelReference(uri);
200
+ if (!document) {
201
+ return this.documentService.createModelReference(uri);
202
+ }
203
+ return document;
204
+ }
205
+
206
+ public async refreshBreakpointsInfo() {
207
+ const treeNodeValues = this.treeNodeMap.values();
208
+ const allTreeNodes: BreakpointsTreeNode[] = Array.from(treeNodeValues).reduce((acc, cur) => acc.concat(cur), []);
209
+
210
+ for await (const node of allTreeNodes) {
211
+ const { rawData, uri } = node;
212
+ if (isDebugBreakpoint(rawData.breakpoint)) {
213
+ const line = rawData.breakpoint.raw.line;
214
+ const monacoModel = await this.getDocumentModelRef(uri);
215
+ if (!monacoModel) {
216
+ return;
217
+ }
218
+
219
+ const getContent = monacoModel.instance.getMonacoModel().getLineContent(line);
220
+ node.fireDescriptionChange(getContent.trim());
221
+ }
222
+ }
174
223
  }
175
224
 
176
225
  removeAllBreakpoints() {
@@ -1,16 +1,34 @@
1
1
  import cls from 'classnames';
2
2
  import { observer } from 'mobx-react-lite';
3
- import React from 'react';
3
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
4
 
5
- import { CheckBox } from '@opensumi/ide-components';
6
- import { Badge, RecycleList } from '@opensumi/ide-components';
7
- import { useInjectable, ViewState, CommandService, EDITOR_COMMANDS, URI, getIcon } from '@opensumi/ide-core-browser';
5
+ import { BasicRecycleTree, CheckBox, IBasicTreeData, ICompositeTreeNode } from '@opensumi/ide-components';
6
+ import { Badge } from '@opensumi/ide-components';
7
+ import {
8
+ useInjectable,
9
+ CommandService,
10
+ EDITOR_COMMANDS,
11
+ URI,
12
+ getIcon,
13
+ Disposable,
14
+ ViewState,
15
+ Event,
16
+ isUndefined,
17
+ } from '@opensumi/ide-core-browser';
8
18
  import { DebugProtocol } from '@opensumi/vscode-debugprotocol/lib/debugProtocol';
9
19
 
10
20
  import { IDebugBreakpoint, IDebugSessionManager, ISourceBreakpoint } from '../../../common';
11
- import { DebugExceptionBreakpoint, isDebugBreakpoint, isRuntimeBreakpoint, getStatus } from '../../breakpoint';
21
+ import {
22
+ DebugExceptionBreakpoint,
23
+ isDebugBreakpoint,
24
+ isRuntimeBreakpoint,
25
+ getStatus,
26
+ isDebugExceptionBreakpoint,
27
+ EXCEPTION_BREAKPOINT_URI,
28
+ } from '../../breakpoint';
12
29
  import { DebugSessionManager } from '../../debug-session-manager';
13
30
 
31
+ import { BreakpointsTreeNode } from './debug-breakpoints-tree.model';
14
32
  import styles from './debug-breakpoints.module.less';
15
33
  import { DebugBreakpointsService } from './debug-breakpoints.service';
16
34
 
@@ -18,29 +36,101 @@ export interface BreakpointItem {
18
36
  name: string;
19
37
  id: string;
20
38
  description: string;
39
+ onDescriptionChange: Event<string>;
21
40
  breakpoint: IDebugBreakpoint | DebugExceptionBreakpoint;
22
41
  }
23
42
 
24
43
  export const DebugBreakpointView = observer(({ viewState }: React.PropsWithChildren<{ viewState: ViewState }>) => {
25
- const { nodes, enable, inDebugMode, toggleBreakpointEnable }: DebugBreakpointsService =
26
- useInjectable(DebugBreakpointsService);
27
- const template = ({ data }: { data: BreakpointItem }) => (
28
- <BreakpointItem
29
- toggle={() => toggleBreakpointEnable(data.breakpoint)}
30
- breakpointEnabled={enable}
31
- data={data}
32
- isDebugMode={inDebugMode}
33
- ></BreakpointItem>
44
+ const debugBreakpointsService: DebugBreakpointsService = useInjectable(DebugBreakpointsService);
45
+ const { enable, toggleBreakpointEnable } = debugBreakpointsService;
46
+ const isDisposed = useRef<boolean>(false);
47
+ const [treeData, setTreeData] = useState<IBasicTreeData[]>([]);
48
+
49
+ const updateTreeData = useCallback(
50
+ (nodes: [string, BreakpointsTreeNode[]][]) => {
51
+ const { roots } = debugBreakpointsService;
52
+ const breakpointTreeData: IBasicTreeData[] = [];
53
+ nodes.forEach(([uri, items]) => {
54
+ const isException = EXCEPTION_BREAKPOINT_URI.toString() === uri;
55
+ if (isException) {
56
+ items.forEach((item) => {
57
+ breakpointTreeData.push({
58
+ label: '',
59
+ expandable: false,
60
+ children: [],
61
+ description: (
62
+ <BreakpointItem
63
+ toggle={() => toggleBreakpointEnable(item.breakpoint)}
64
+ breakpointEnabled={enable}
65
+ data={item.rawData}
66
+ isDebugMode={debugBreakpointsService.inDebugMode}
67
+ ></BreakpointItem>
68
+ ),
69
+ });
70
+ });
71
+ } else {
72
+ const toURI = URI.parse(uri);
73
+ const parent = roots.filter((root) => root.isEqualOrParent(toURI))[0];
74
+
75
+ breakpointTreeData.push({
76
+ label: parent ? parent.relative(toURI)?.toString() || '' : URI.parse(uri).displayName,
77
+ expandable: true,
78
+ iconClassName: getIcon('file-text'),
79
+ expanded: true,
80
+ children: items.map((item) => ({
81
+ ...item,
82
+ label: '',
83
+ expandable: false,
84
+ description: (
85
+ <BreakpointItem
86
+ toggle={() => toggleBreakpointEnable(item.breakpoint)}
87
+ breakpointEnabled={enable}
88
+ data={item.rawData}
89
+ isDebugMode={debugBreakpointsService.inDebugMode}
90
+ ></BreakpointItem>
91
+ ),
92
+ })),
93
+ });
94
+ }
95
+ });
96
+ if (!isDisposed.current) {
97
+ setTreeData(breakpointTreeData);
98
+ }
99
+ },
100
+ [treeData],
34
101
  );
35
102
 
36
- const containerStyle = {
37
- height: viewState.height,
38
- width: viewState.width,
39
- } as React.CSSProperties;
103
+ useEffect(() => {
104
+ const dispose = new Disposable();
105
+ updateTreeData(Array.from(debugBreakpointsService.treeNodeMap.entries()));
106
+ dispose.addDispose(
107
+ debugBreakpointsService.onDidChangeBreakpointsTreeNode((nodes: Map<string, BreakpointsTreeNode[]>) => {
108
+ updateTreeData(Array.from(nodes.entries()));
109
+ }),
110
+ );
111
+
112
+ return () => {
113
+ isDisposed.current = true;
114
+ dispose.dispose();
115
+ };
116
+ }, []);
40
117
 
118
+ useEffect(() => {
119
+ if (treeData.length > 0) {
120
+ requestAnimationFrame(() => {
121
+ debugBreakpointsService.refreshBreakpointsInfo();
122
+ });
123
+ }
124
+ }, [treeData]);
125
+
126
+ const getItemClassName = useCallback((item: ICompositeTreeNode) => {
127
+ if (!item.children && isUndefined((item as any).expandable)) {
128
+ return styles.debug_breakpoints_item_tree_node;
129
+ }
130
+ }, []);
41
131
  return (
42
132
  <div className={cls(styles.debug_breakpoints, !enable && styles.debug_breakpoints_disabled)}>
43
- <RecycleList data={nodes} itemHeight={22} template={template} style={containerStyle} />
133
+ <BasicRecycleTree treeData={treeData} height={viewState.height} getItemClassName={getItemClassName} />
44
134
  </div>
45
135
  );
46
136
  });
@@ -62,6 +152,7 @@ export const BreakpointItem = ({
62
152
  const debugBreakpointsService = useInjectable<DebugBreakpointsService>(DebugBreakpointsService);
63
153
  const [enabled, setEnabled] = React.useState<boolean>(defaultValue);
64
154
  const [status, setStatus] = React.useState<DebugProtocol.Breakpoint | false | undefined>(undefined);
155
+ const [description, setDescription] = React.useState<string>(data.description);
65
156
 
66
157
  const handleBreakpointChange = () => {
67
158
  toggle();
@@ -98,6 +189,8 @@ export const BreakpointItem = ({
98
189
  };
99
190
 
100
191
  React.useEffect(() => {
192
+ const disposable = new Disposable();
193
+
101
194
  const exec = () => {
102
195
  if (isDebugBreakpoint(data.breakpoint) && isRuntimeBreakpoint(data.breakpoint)) {
103
196
  const status = getStatus(data.breakpoint);
@@ -105,9 +198,11 @@ export const BreakpointItem = ({
105
198
  }
106
199
  };
107
200
 
108
- const disposable = manager.onDidChangeActiveDebugSession(() => exec());
201
+ disposable.addDispose(manager.onDidChangeActiveDebugSession(() => exec()));
109
202
  exec();
110
203
 
204
+ disposable.addDispose(data.onDescriptionChange(setDescription));
205
+
111
206
  return () => {
112
207
  setStatus(undefined);
113
208
  disposable.dispose();
@@ -142,13 +237,15 @@ export const BreakpointItem = ({
142
237
  debugBreakpointsService.delBreakpoint(data.breakpoint as IDebugBreakpoint);
143
238
  };
144
239
 
240
+ const isExceptionBreakpoint = useMemo(() => isDebugExceptionBreakpoint(data.breakpoint), [data]);
241
+
145
242
  return (
146
243
  <div className={cls(styles.debug_breakpoints_item)}>
147
- <div className={cls(converBreakpointClsState(), styles.debug_breakpoints_icon)}></div>
244
+ {!isExceptionBreakpoint && <div className={cls(converBreakpointClsState(), styles.debug_breakpoints_icon)}></div>}
148
245
  <CheckBox id={data.id} onChange={handleBreakpointChange} checked={enabled}></CheckBox>
149
246
  <div className={styles.debug_breakpoints_wrapper} onClick={handleBreakpointClick}>
150
- <span className={styles.debug_breakpoints_name}>{data.name}</span>
151
- <span className={styles.debug_breakpoints_description}>{data.description}</span>
247
+ {data.name && <span className={styles.debug_breakpoints_name}>{data.name}</span>}
248
+ <span className={styles.debug_breakpoints_description}>{description}</span>
152
249
  </div>
153
250
  {isDebugBreakpoint(data.breakpoint) ? (
154
251
  <>
@@ -1,11 +1,14 @@
1
1
  @import '~@opensumi/ide-components/lib/style/mixins.less';
2
2
 
3
+ .debug_action_bar_internal {
4
+ padding: 0px 8px;
5
+ margin-bottom: 8px;
6
+ }
7
+
3
8
  .debug_action_bar {
4
9
  height: 28px;
5
10
  display: flex;
6
11
  align-items: center;
7
- padding: 0px 8px;
8
- margin-bottom: 8px;
9
12
  justify-content: flex-start;
10
13
  pointer-events: all;
11
14
  overflow: hidden;
@@ -36,11 +39,14 @@
36
39
  }
37
40
  }
38
41
 
42
+ .debug_configuration_container {
43
+ padding-right: 8px;
44
+ margin-bottom: 8px;
45
+ }
46
+
39
47
  .debug_configuration_toolbar {
40
48
  display: flex;
41
49
  height: 28px;
42
- padding-right: 8px;
43
- margin-bottom: 8px;
44
50
  align-items: center;
45
51
 
46
52
  .debug_actions {
@@ -2,15 +2,15 @@ import cls from 'classnames';
2
2
  import { observer } from 'mobx-react-lite';
3
3
  import React from 'react';
4
4
 
5
- import { Select, Option } from '@opensumi/ide-components';
6
- import { useInjectable, localize, URI, AppConfig } from '@opensumi/ide-core-browser';
5
+ import { Option, Select } from '@opensumi/ide-components';
6
+ import { AppConfig, URI, localize, useInjectable } from '@opensumi/ide-core-browser';
7
7
  import { Select as NativeSelect } from '@opensumi/ide-core-browser/lib/components/select';
8
8
 
9
9
  import {
10
10
  DEFAULT_ADD_CONFIGURATION_KEY,
11
- DEFAULT_NO_CONFIGURATION_KEY,
12
11
  DEFAULT_CONFIGURATION_INDEX_SEPARATOR,
13
12
  DEFAULT_CONFIGURATION_NAME_SEPARATOR,
13
+ DEFAULT_NO_CONFIGURATION_KEY,
14
14
  DebugSessionOptions,
15
15
  } from '../../../common';
16
16
  import { DebugAction } from '../../components';
@@ -198,7 +198,26 @@ export const DebugActionBar = React.memo(({ runDebug, openConfiguration, openDeb
198
198
  </div>
199
199
  ));
200
200
 
201
- export const DebugConfigurationView = observer((props) => {
201
+ export const DebugConfigurationContainerView = observer(() => {
202
+ const { float } = useInjectable<DebugConfigurationService>(DebugConfigurationService);
203
+
204
+ return (
205
+ <>
206
+ <DebugControllerView className={styles.debug_configuration_container} />
207
+ {!float && <DebugToolbarView float={false} className={styles.debug_action_bar_internal} />}
208
+ </>
209
+ );
210
+ });
211
+
212
+ export interface DebugControllerViewProps {
213
+ className?: string;
214
+ }
215
+
216
+ /**
217
+ * 该组件支持用户导入
218
+ * 后续如果有一些改动需要考虑是否有 breakchange
219
+ */
220
+ export const DebugControllerView = observer((props: DebugControllerViewProps) => {
202
221
  const {
203
222
  configurationOptions,
204
223
  toValue,
@@ -208,12 +227,12 @@ export const DebugConfigurationView = observer((props) => {
208
227
  openDebugConsole,
209
228
  updateConfiguration,
210
229
  start,
211
- float,
212
230
  isMultiRootWorkspace,
213
231
  workspaceRoots,
214
232
  } = useInjectable<DebugConfigurationService>(DebugConfigurationService);
215
233
  const appConfig = useInjectable<AppConfig>(AppConfig);
216
234
  const addConfigurationLabel = localize('debug.action.add.configuration');
235
+
217
236
  const setCurrentConfiguration = React.useCallback((event: React.ChangeEvent<HTMLSelectElement> | string) => {
218
237
  let value: React.ChangeEvent<HTMLSelectElement> | string;
219
238
  if (typeof event === 'object') {
@@ -236,21 +255,18 @@ export const DebugConfigurationView = observer((props) => {
236
255
  }, []);
237
256
 
238
257
  return (
239
- <div>
240
- <div className={styles.debug_configuration_toolbar}>
241
- <ConfigurationSelector
242
- currentValue={currentValue}
243
- options={configurationOptions}
244
- onChangeConfiguration={setCurrentConfiguration}
245
- isMultiRootWorkspace={isMultiRootWorkspace}
246
- addConfigurationLabel={addConfigurationLabel}
247
- toValue={toValue}
248
- isElectronRenderer={appConfig.isElectronRenderer}
249
- workspaceRoots={workspaceRoots}
250
- />
251
- <DebugActionBar runDebug={start} openConfiguration={openConfiguration} openDebugConsole={openDebugConsole} />
252
- </div>
253
- {!float && <DebugToolbarView float={false} />}
258
+ <div className={cls(styles.debug_configuration_toolbar, props.className || '')}>
259
+ <ConfigurationSelector
260
+ currentValue={currentValue}
261
+ options={configurationOptions}
262
+ onChangeConfiguration={setCurrentConfiguration}
263
+ isMultiRootWorkspace={isMultiRootWorkspace}
264
+ addConfigurationLabel={addConfigurationLabel}
265
+ toValue={toValue}
266
+ isElectronRenderer={appConfig.isElectronRenderer}
267
+ workspaceRoots={workspaceRoots}
268
+ />
269
+ <DebugActionBar runDebug={start} openConfiguration={openConfiguration} openDebugConsole={openDebugConsole} />
254
270
  </div>
255
271
  );
256
272
  });
@@ -7,13 +7,13 @@ import { Injectable } from '@opensumi/di';
7
7
  import { Option, Select } from '@opensumi/ide-components';
8
8
  import {
9
9
  AppConfig,
10
- getIcon,
11
- localize,
12
- PreferenceService,
13
- useInjectable,
14
10
  DisposableCollection,
11
+ PreferenceService,
15
12
  electronEnv,
13
+ getIcon,
16
14
  isMacintosh,
15
+ localize,
16
+ useInjectable,
17
17
  } from '@opensumi/ide-core-browser';
18
18
  import { InlineMenuBar } from '@opensumi/ide-core-browser/lib/components/actions';
19
19
  import { Select as NativeSelect } from '@opensumi/ide-core-browser/lib/components/select';
@@ -79,8 +79,13 @@ class FloatController {
79
79
 
80
80
  export interface DebugToolbarViewProps {
81
81
  float: boolean;
82
+ className?: string;
82
83
  }
83
84
 
85
+ /**
86
+ * 该组件支持用户导入
87
+ * 后续如果有一些改动需要考虑是否有 breakchange
88
+ */
84
89
  export const DebugToolbarView = observer((props: DebugToolbarViewProps) => {
85
90
  const {
86
91
  state,
@@ -221,7 +226,7 @@ export const DebugToolbarView = observer((props: DebugToolbarViewProps) => {
221
226
  );
222
227
 
223
228
  return (
224
- <div className={styles.debug_action_bar}>
229
+ <div className={cls(styles.debug_action_bar, props.className || '')}>
225
230
  {renderSelections(sessions.filter((s: DebugSession) => !s.parentSession))}
226
231
  <div className={styles.debug_actions}>
227
232
  {renderContinue(state)}