@jupyterlab/debugger 4.5.0-alpha.3 → 4.5.0-beta.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.
@@ -4,6 +4,15 @@
4
4
  import { ReactWidget } from '@jupyterlab/ui-components';
5
5
  import React, { useEffect, useState } from 'react';
6
6
  import { IDebugger } from '../../tokens';
7
+ import {
8
+ ITranslator,
9
+ nullTranslator,
10
+ TranslationBundle
11
+ } from '@jupyterlab/translation';
12
+ import {
13
+ breakpointIcon,
14
+ selectedBreakpointIcon
15
+ } from '@jupyterlab/ui-components';
7
16
 
8
17
  /**
9
18
  * The body for a Breakpoints Panel.
@@ -14,9 +23,14 @@ export class BreakpointsBody extends ReactWidget {
14
23
  *
15
24
  * @param model The model for the breakpoints.
16
25
  */
17
- constructor(model: IDebugger.Model.IBreakpoints) {
26
+ constructor(
27
+ model: IDebugger.Model.IBreakpoints,
28
+ translator: ITranslator = nullTranslator
29
+ ) {
18
30
  super();
19
31
  this._model = model;
32
+ this._translator = translator;
33
+
20
34
  this.addClass('jp-DebuggerBreakpoints-body');
21
35
  }
22
36
 
@@ -24,10 +38,13 @@ export class BreakpointsBody extends ReactWidget {
24
38
  * Render the BreakpointsComponent.
25
39
  */
26
40
  render(): JSX.Element {
27
- return <BreakpointsComponent model={this._model} />;
41
+ return (
42
+ <BreakpointsComponent model={this._model} translator={this._translator} />
43
+ );
28
44
  }
29
45
 
30
46
  private _model: IDebugger.Model.IBreakpoints;
47
+ private _translator: ITranslator;
31
48
  }
32
49
 
33
50
  /**
@@ -37,13 +54,18 @@ export class BreakpointsBody extends ReactWidget {
37
54
  * @param props.model The model for the breakpoints.
38
55
  */
39
56
  const BreakpointsComponent = ({
40
- model
57
+ model,
58
+ translator
41
59
  }: {
42
60
  model: IDebugger.Model.IBreakpoints;
61
+ translator: ITranslator;
43
62
  }): JSX.Element => {
63
+ const trans = translator.load('jupyterlab');
44
64
  const [breakpoints, setBreakpoints] = useState(
45
65
  Array.from(model.breakpoints.entries())
46
66
  );
67
+ const [selectedBreakpoint, setSelectedBreakpoint] =
68
+ useState<IDebugger.IBreakpoint | null>(null);
47
69
 
48
70
  useEffect(() => {
49
71
  const updateBreakpoints = (
@@ -57,12 +79,27 @@ const BreakpointsComponent = ({
57
79
  setBreakpoints(Array.from(model.breakpoints.entries()));
58
80
  };
59
81
 
82
+ const handleClick = (
83
+ _: IDebugger.Model.IBreakpoints,
84
+ breakpoint: IDebugger.IBreakpoint
85
+ ): void => {
86
+ model.selectedBreakpoint = breakpoint;
87
+ };
88
+
89
+ const handleSelectedChanged = (_: IDebugger.Model.IBreakpoints): void => {
90
+ setSelectedBreakpoint(model.selectedBreakpoint);
91
+ };
92
+
60
93
  model.changed.connect(updateBreakpoints);
61
94
  model.restored.connect(restoreBreakpoints);
95
+ model.clicked.connect(handleClick);
96
+ model.selectedChanged.connect(handleSelectedChanged);
62
97
 
63
98
  return (): void => {
64
99
  model.changed.disconnect(updateBreakpoints);
65
100
  model.restored.disconnect(restoreBreakpoints);
101
+ model.clicked.disconnect(handleClick);
102
+ model.selectedChanged.disconnect(() => handleSelectedChanged);
66
103
  };
67
104
  });
68
105
 
@@ -73,6 +110,8 @@ const BreakpointsComponent = ({
73
110
  key={entry[0]}
74
111
  breakpoints={entry[1]}
75
112
  model={model}
113
+ selectedBreakpoint={selectedBreakpoint}
114
+ trans={trans}
76
115
  />
77
116
  ))}
78
117
  </>
@@ -88,10 +127,14 @@ const BreakpointsComponent = ({
88
127
  */
89
128
  const BreakpointCellComponent = ({
90
129
  breakpoints,
91
- model
130
+ model,
131
+ selectedBreakpoint,
132
+ trans
92
133
  }: {
93
134
  breakpoints: IDebugger.IBreakpoint[];
94
135
  model: IDebugger.Model.IBreakpoints;
136
+ selectedBreakpoint: IDebugger.IBreakpoint | null;
137
+ trans: TranslationBundle;
95
138
  }): JSX.Element => {
96
139
  return (
97
140
  <>
@@ -104,6 +147,11 @@ const BreakpointCellComponent = ({
104
147
  key={(breakpoint.source?.path ?? '') + index}
105
148
  breakpoint={breakpoint}
106
149
  model={model}
150
+ isSelected={
151
+ selectedBreakpoint?.line === breakpoint.line &&
152
+ selectedBreakpoint?.source?.path === breakpoint.source?.path
153
+ }
154
+ trans={trans}
107
155
  />
108
156
  ))}
109
157
  </>
@@ -119,10 +167,14 @@ const BreakpointCellComponent = ({
119
167
  */
120
168
  const BreakpointComponent = ({
121
169
  breakpoint,
122
- model
170
+ model,
171
+ isSelected,
172
+ trans
123
173
  }: {
124
174
  breakpoint: IDebugger.IBreakpoint;
125
175
  model: IDebugger.Model.IBreakpoints;
176
+ isSelected: boolean;
177
+ trans: TranslationBundle;
126
178
  }): JSX.Element => {
127
179
  const moveToEndFirstCharIfSlash = (breakpointSourcePath: string): string => {
128
180
  return breakpointSourcePath[0] === '/'
@@ -135,7 +187,17 @@ const BreakpointComponent = ({
135
187
  onClick={(): void => model.clicked.emit(breakpoint)}
136
188
  title={breakpoint.source?.path}
137
189
  >
138
- <span className={'jp-DebuggerBreakpoint-marker'}>●</span>
190
+ <span className="jp-DebuggerBreakpoint-container">
191
+ {!isSelected ? (
192
+ <breakpointIcon.react
193
+ aria-label={trans.__('Breakpoint')}
194
+ ></breakpointIcon.react>
195
+ ) : (
196
+ <selectedBreakpointIcon.react
197
+ aria-label={trans.__('Selected breakpoint')}
198
+ ></selectedBreakpointIcon.react>
199
+ )}
200
+ </span>
139
201
  <span className={'jp-DebuggerBreakpoint-source jp-left-truncated'}>
140
202
  {moveToEndFirstCharIfSlash(breakpoint.source?.path ?? '')}
141
203
  </span>
@@ -30,6 +30,28 @@ export class BreakpointsModel implements IDebugger.Model.IBreakpoints {
30
30
  return this._clicked;
31
31
  }
32
32
 
33
+ /**
34
+ * Signal emitted when the selected breakpoint changes.
35
+ */
36
+ get selectedChanged(): Signal<this, IDebugger.IBreakpoint> {
37
+ return this._selectedChanged;
38
+ }
39
+
40
+ /**
41
+ * Get selected breakpoint
42
+ */
43
+ get selectedBreakpoint(): IDebugger.IBreakpoint {
44
+ return this._selectedBreakpoint;
45
+ }
46
+
47
+ /**
48
+ * Set selected breakpoint
49
+ */
50
+ set selectedBreakpoint(selected: IDebugger.IBreakpoint) {
51
+ this._selectedBreakpoint = selected;
52
+ this._selectedChanged.emit(selected);
53
+ }
54
+
33
55
  /**
34
56
  * Get all the breakpoints.
35
57
  */
@@ -71,4 +93,6 @@ export class BreakpointsModel implements IDebugger.Model.IBreakpoints {
71
93
  private _changed = new Signal<this, IDebugger.IBreakpoint[]>(this);
72
94
  private _restored = new Signal<this, void>(this);
73
95
  private _clicked = new Signal<this, IDebugger.IBreakpoint>(this);
96
+ private _selectedBreakpoint: IDebugger.IBreakpoint;
97
+ private _selectedChanged = new Signal<this, IDebugger.IBreakpoint>(this);
74
98
  }
@@ -122,7 +122,7 @@ export class SourcesBody extends Widget {
122
122
  };
123
123
 
124
124
  requestAnimationFrame(() => {
125
- EditorHandler.showCurrentLine(this._editor.editor, frame.line);
125
+ EditorHandler.showCurrentLine(this._editor.editor, frame.line, 'start');
126
126
  });
127
127
 
128
128
  this._editor.show();
package/src/service.ts CHANGED
@@ -256,11 +256,15 @@ export class DebuggerService implements IDebugger, IDisposable {
256
256
  expression,
257
257
  frameId
258
258
  });
259
+
259
260
  if (!reply.success) {
260
261
  return null;
261
262
  }
263
+
264
+ // TODO - Should this be here?
265
+ this._model.variables.scopes = [];
266
+
262
267
  // get the frames to retrieve the latest state of the variables
263
- this._clearModel();
264
268
  await this._getAllFrames();
265
269
 
266
270
  return reply.body;
@@ -460,7 +464,7 @@ export class DebuggerService implements IDebugger, IDisposable {
460
464
  if (stoppedThreads.size !== 0) {
461
465
  await this._getAllFrames();
462
466
  } else if (this.isStarted) {
463
- this._clearModel();
467
+ this._model.callstack.frames = [];
464
468
  this._clearSignals();
465
469
  }
466
470
 
@@ -593,7 +597,6 @@ export class DebuggerService implements IDebugger, IDisposable {
593
597
 
594
598
  // Update the local model and finish kernel configuration.
595
599
  this._model.breakpoints.setBreakpoints(path, updatedBreakpoints);
596
- await this.session.sendRequest('configurationDone', {});
597
600
  }
598
601
 
599
602
  /**
package/src/tokens.ts CHANGED
@@ -855,6 +855,16 @@ export namespace IDebugger {
855
855
  */
856
856
  readonly restored: ISignal<this, void>;
857
857
 
858
+ /**
859
+ * Signal emitted when the breakpoints are restored.
860
+ */
861
+ readonly selectedChanged: Signal<this, IDebugger.IBreakpoint>;
862
+
863
+ /**
864
+ * Selected breakpoint
865
+ */
866
+ selectedBreakpoint: IDebugger.IBreakpoint | null;
867
+
858
868
  /**
859
869
  * Get the breakpoints for a given id (path).
860
870
  *
@@ -18,6 +18,7 @@
18
18
  .jp-DebuggerBreakpoint {
19
19
  display: flex;
20
20
  align-items: center;
21
+ height: 24px;
21
22
  }
22
23
 
23
24
  .jp-DebuggerBreakpoint:hover {
@@ -25,11 +26,12 @@
25
26
  cursor: pointer;
26
27
  }
27
28
 
28
- .jp-DebuggerBreakpoint-marker {
29
- font-size: 20px;
30
- padding-right: 5px;
31
- content: '●';
32
- color: var(--jp-error-color1);
29
+ .jp-DebuggerBreakpoint-container {
30
+ height: 24px;
31
+ display: flex;
32
+ align-items: center;
33
+ justify-content: center;
34
+ margin-right: 10px;
33
35
  }
34
36
 
35
37
  .jp-DebuggerBreakpoint-source {
@@ -56,7 +58,6 @@
56
58
  }
57
59
 
58
60
  [data-jp-debugger='true'] .cm-breakpoint-gutter .cm-gutterElement:empty::after {
59
- content: '●';
60
61
  color: var(--jp-error-color1);
61
62
  opacity: 0;
62
63
  }
@@ -66,11 +67,8 @@
66
67
  }
67
68
 
68
69
  .cm-breakpoint-gutter .cm-gutterElement {
69
- color: var(--jp-error-color1);
70
- padding-left: 5px;
71
- font-size: 20px;
72
- position: relative;
73
- top: -5px;
70
+ padding-top: 1.1px;
71
+ height: 18.2px;
74
72
  }
75
73
 
76
74
  [data-jp-debugger='true'].jp-Editor
package/style/sources.css CHANGED
@@ -6,6 +6,7 @@
6
6
  .jp-DebuggerSources {
7
7
  min-height: 50px;
8
8
  margin-top: 3px;
9
+ overflow-y: scroll;
9
10
  }
10
11
 
11
12
  [data-jp-debugger='true'].jp-Editor .jp-mod-readOnly {