Kaynağa Gözat

Merge pull request #190 from KsavinN/debug

Resolve-switching between notebooks removes the breakpoints from the UI
Jeremy Tuloup 5 yıl önce
ebeveyn
işleme
a9d04e5a08

+ 17 - 8
src/debugger.ts

@@ -128,6 +128,22 @@ export namespace Debugger {
     readonly variablesModel: Variables.Model;
     readonly connector: IDataConnector<ReadonlyJSONValue> | null;
 
+    dispose(): void {
+      this._isDisposed = true;
+      this._disposed.emit();
+    }
+
+    /**
+     * A signal emitted when the debugger widget is disposed.
+     */
+    get disposed(): ISignal<this, void> {
+      return this._disposed;
+    }
+
+    get isDisposed(): boolean {
+      return this._isDisposed;
+    }
+
     get mode(): IDebugger.Mode {
       return this._mode;
     }
@@ -144,10 +160,6 @@ export namespace Debugger {
       return this._modeChanged;
     }
 
-    get isDisposed(): boolean {
-      return this._isDisposed;
-    }
-
     get codeValue() {
       return this._codeValue;
     }
@@ -156,10 +168,6 @@ export namespace Debugger {
       this._codeValue = observableString;
     }
 
-    dispose(): void {
-      this._isDisposed = true;
-    }
-
     private async _populate(): Promise<void> {
       const { connector } = this;
 
@@ -172,6 +180,7 @@ export namespace Debugger {
     private _isDisposed = false;
     private _mode: IDebugger.Mode;
     private _modeChanged = new Signal<this, IDebugger.Mode>(this);
+    private _disposed = new Signal<this, void>(this);
   }
 
   export namespace Sidebar {

+ 54 - 32
src/handlers/cell.ts

@@ -29,11 +29,12 @@ const CELL_CHANGED_TIMEOUT = 1000;
 
 export class CellManager implements IDisposable {
   constructor(options: CellManager.IOptions) {
+    // TODO: should we use the client name or a debug session id?
+    this._id = options.debuggerService.session.client.name;
     this._debuggerService = options.debuggerService;
     this.onModelChanged();
     this._debuggerService.modelChanged.connect(() => this.onModelChanged());
     this.activeCell = options.activeCell;
-    this.onActiveCellChanged();
   }
 
   isDisposed: boolean;
@@ -47,7 +48,7 @@ export class CellManager implements IDisposable {
 
     this._debuggerModel.callstackModel.currentFrameChanged.connect(
       (_, frame) => {
-        CellManager.cleanupHighlight(this.activeCell);
+        CellManager.clearHighlight(this.activeCell);
         if (!frame) {
           return;
         }
@@ -72,7 +73,7 @@ export class CellManager implements IDisposable {
       this.addBreakpointsToEditor(this.activeCell);
     });
 
-    if (this.activeCell) {
+    if (this.activeCell && !this.activeCell.isDisposed) {
       this._debuggerModel.codeValue = this.activeCell.model.value;
     }
   }
@@ -81,15 +82,14 @@ export class CellManager implements IDisposable {
     if (this.isDisposed) {
       return;
     }
-    if (this.previousCell) {
-      this.removeListener(this.previousCell);
-    }
     if (this._cellMonitor) {
       this._cellMonitor.dispose();
     }
-    this.removeListener(this.activeCell);
-    CellManager.cleanupHighlight(this.activeCell);
+    this.removeGutterClick(this.activeCell);
+    CellManager.clearHighlight(this.activeCell);
+    CellManager.clearGutter(this.activeCell);
     Signal.clearData(this);
+    this.isDisposed = true;
   }
 
   set previousCell(cell: CodeCell) {
@@ -112,15 +112,6 @@ export class CellManager implements IDisposable {
     return this._activeCell;
   }
 
-  protected clearGutter(cell: CodeCell) {
-    const editor = cell.editor as CodeMirrorEditor;
-    editor.doc.eachLine(line => {
-      if ((line as ILineInfo).gutterMarkers) {
-        editor.editor.setGutterMarker(line, 'breakpoints', null);
-      }
-    });
-  }
-
   onActiveCellChanged() {
     if (
       this.activeCell &&
@@ -133,7 +124,7 @@ export class CellManager implements IDisposable {
         if (this._cellMonitor) {
           this._cellMonitor.dispose();
         }
-        this.removeListener(this.previousCell);
+        this.removeGutterClick(this.previousCell);
       }
 
       this._cellMonitor = new ActivityMonitor({
@@ -145,8 +136,11 @@ export class CellManager implements IDisposable {
         this.sendEditorBreakpoints();
       }, this);
 
+      requestAnimationFrame(() => {
+        this.setEditor(this.activeCell);
+      });
+
       this.previousCell = this.activeCell;
-      this.setEditor(this.activeCell);
     }
   }
 
@@ -187,7 +181,7 @@ export class CellManager implements IDisposable {
     editor.editor.on('gutterClick', this.onGutterClick);
   }
 
-  protected removeListener(cell: CodeCell) {
+  protected removeGutterClick(cell: CodeCell) {
     if (cell.isDisposed) {
       return;
     }
@@ -201,10 +195,14 @@ export class CellManager implements IDisposable {
 
   protected onGutterClick = (editor: Editor, lineNumber: number) => {
     const info = editor.lineInfo(lineNumber);
-    if (!info) {
+
+    if (!info || this._id !== this._debuggerService.session.client.name) {
       return;
     }
 
+    editor.focus();
+    CellManager.clearGutter(this.activeCell);
+
     const isRemoveGutter = !!info.gutterMarkers;
     let breakpoints: Breakpoints.IBreakpoint[] = this.getBreakpoints(
       this._activeCell
@@ -228,16 +226,22 @@ export class CellManager implements IDisposable {
   };
 
   private addBreakpointsToEditor(cell: CodeCell) {
-    this.clearGutter(cell);
     const editor = cell.editor as CodeMirrorEditor;
     const breakpoints = this.getBreakpoints(cell);
-    breakpoints.forEach(breakpoint => {
-      editor.editor.setGutterMarker(
-        breakpoint.line - 1,
-        'breakpoints',
-        Private.createMarkerNode()
-      );
-    });
+    if (
+      breakpoints.length === 0 &&
+      this._id === this._debuggerService.session.client.name
+    ) {
+      CellManager.clearGutter(cell);
+    } else {
+      breakpoints.forEach(breakpoint => {
+        editor.editor.setGutterMarker(
+          breakpoint.line - 1,
+          'breakpoints',
+          Private.createMarkerNode()
+        );
+      });
+    }
   }
 
   private getBreakpointsFromEditor(cell: CodeCell): ILineInfo[] {
@@ -263,6 +267,7 @@ export class CellManager implements IDisposable {
   private breakpointsModel: Breakpoints.Model;
   private _activeCell: CodeCell;
   private _debuggerService: IDebugger;
+  private _id: string;
   private _cellMonitor: ActivityMonitor<
     IObservableString,
     IObservableString.IChangedArgs
@@ -285,7 +290,7 @@ export namespace CellManager {
    */
   export function showCurrentLine(cell: Cell, frame: Callstack.IFrame) {
     const editor = cell.editor as CodeMirrorEditor;
-    cleanupHighlight(cell);
+    clearHighlight(cell);
     editor.editor.addLineClass(frame.line - 1, 'wrap', LINE_HIGHLIGHT_CLASS);
   }
 
@@ -293,8 +298,8 @@ export namespace CellManager {
    * Remove all line highlighting indicators for the given cell.
    * @param cell The cell to cleanup.
    */
-  export function cleanupHighlight(cell: Cell) {
-    if (!cell || cell.isDisposed) {
+  export function clearHighlight(cell: Cell) {
+    if (!cell || cell.isDisposed || !cell.inputArea) {
       return;
     }
     const editor = cell.editor as CodeMirrorEditor;
@@ -302,6 +307,23 @@ export namespace CellManager {
       editor.editor.removeLineClass(line, 'wrap', LINE_HIGHLIGHT_CLASS);
     });
   }
+
+  /**
+   * Remove line numbers and all gutters from cell.
+   * @param cell The cell to cleanup.
+   */
+
+  export function clearGutter(cell: Cell) {
+    if (!cell || !cell.inputArea) {
+      return;
+    }
+    const editor = cell.editor as CodeMirrorEditor;
+    editor.doc.eachLine(line => {
+      if ((line as ILineInfo).gutterMarkers) {
+        editor.editor.setGutterMarker(line, 'breakpoints', null);
+      }
+    });
+  }
 }
 
 export interface ILineInfo {

+ 0 - 8
src/handlers/console.ts

@@ -56,14 +56,6 @@ export class ConsoleHandler implements IDisposable {
     if (this.cellManager) {
       this.cellManager.previousCell = this.cellManager.activeCell;
       this.cellManager.activeCell = update;
-    } else if (!this.cellManager) {
-      this.cellManager = new CellManager({
-        activeCell: update,
-        breakpointsModel: this.breakpoints,
-        debuggerModel: this.debuggerModel,
-        debuggerService: this.debuggerService,
-        type: 'console'
-      });
     }
   }
 }

+ 19 - 6
src/handlers/notebook.ts

@@ -1,7 +1,11 @@
 // Copyright (c) Jupyter Development Team.
 // Distributed under the terms of the Modified BSD License.
 
-import { INotebookTracker, NotebookTracker } from '@jupyterlab/notebook';
+import {
+  INotebookTracker,
+  NotebookPanel,
+  NotebookTracker
+} from '@jupyterlab/notebook';
 
 import { CodeCell } from '@jupyterlab/cells';
 
@@ -24,6 +28,8 @@ export class NotebookHandler implements IDisposable {
     this.debuggerModel = options.debuggerService.model;
     this.debuggerService = options.debuggerService;
     this.notebookTracker = options.tracker;
+    this.notebookPanel = this.notebookTracker.currentWidget;
+
     this.id = options.id;
     this.breakpoints = this.debuggerModel.breakpointsModel;
 
@@ -53,10 +59,19 @@ export class NotebookHandler implements IDisposable {
       return;
     }
     this.isDisposed = true;
+    this.cleanAllCells();
     this.cellManager.dispose();
     Signal.clearData(this);
   }
 
+  protected cleanAllCells() {
+    const cells = this.notebookPanel.content.widgets;
+    cells.forEach(cell => {
+      CellManager.clearHighlight(cell);
+      CellManager.clearGutter(cell);
+    });
+  }
+
   protected onActiveCellChanged(
     notebookTracker: NotebookTracker,
     codeCell: CodeCell
@@ -64,10 +79,7 @@ export class NotebookHandler implements IDisposable {
     if (notebookTracker.currentWidget.id !== this.id) {
       return;
     }
-    // TODO: do we need this requestAnimationFrame?
-    requestAnimationFrame(() => {
-      this.cellManager.activeCell = codeCell;
-    });
+    this.cellManager.activeCell = codeCell;
   }
 
   private onCurrentFrameChanged(
@@ -80,7 +92,7 @@ export class NotebookHandler implements IDisposable {
     }
 
     const cells = notebook.content.widgets;
-    cells.forEach(cell => CellManager.cleanupHighlight(cell));
+    cells.forEach(cell => CellManager.clearHighlight(cell));
 
     if (!frame) {
       return;
@@ -103,6 +115,7 @@ export class NotebookHandler implements IDisposable {
   private debuggerService: IDebugger;
   private breakpoints: Breakpoints.Model;
   private cellManager: CellManager;
+  private notebookPanel: NotebookPanel;
   private id: string;
 }
 

+ 33 - 2
src/index.ts

@@ -68,6 +68,8 @@ export namespace CommandIDs {
   export const mount = 'debugger:mount';
 
   export const changeMode = 'debugger:change-mode';
+
+  export const closeDebugger = 'debugger:close';
 }
 
 async function setDebugSession(
@@ -104,6 +106,14 @@ class DebuggerHandler<H extends ConsoleHandler | NotebookHandler> {
         handler.dispose();
         delete this.handlers[widget.id];
       });
+
+      debug.model.disposed.connect(async () => {
+        await debug.stop();
+        Object.keys(this.handlers).forEach(id => {
+          this.handlers[id].dispose();
+        });
+        this.handlers = {};
+      });
     }
   }
 
@@ -201,7 +211,7 @@ const notebooks: JupyterFrontEndPlugin<void> = {
   ) => {
     const handler = new DebuggerHandler<NotebookHandler>(NotebookHandler);
 
-    labShell.currentChanged.connect(async (_, update) => {
+    labShell.activeChanged.connect(async (_, update) => {
       const widget = update.newValue;
       if (!(widget instanceof NotebookPanel)) {
         return;
@@ -218,13 +228,14 @@ const notebooks: JupyterFrontEndPlugin<void> = {
 const main: JupyterFrontEndPlugin<IDebugger> = {
   id: '@jupyterlab/debugger:main',
   optional: [ILayoutRestorer, ICommandPalette],
-  requires: [IStateDB, IEditorServices],
+  requires: [IStateDB, IEditorServices, ILabShell],
   provides: IDebugger,
   autoStart: true,
   activate: (
     app: JupyterFrontEnd,
     state: IStateDB,
     editorServices: IEditorServices,
+    labShell: ILabShell,
     restorer: ILayoutRestorer | null,
     palette: ICommandPalette | null
   ): IDebugger => {
@@ -241,6 +252,22 @@ const main: JupyterFrontEndPlugin<IDebugger> = {
 
     let widget: MainAreaWidget<Debugger>;
 
+    commands.addCommand(CommandIDs.closeDebugger, {
+      label: 'Close Debugger',
+      execute: args => {
+        if (!widget) {
+          return;
+        }
+        widget.content.sidebar.close();
+        widget.dispose();
+      }
+    });
+
+    app.contextMenu.addItem({
+      command: CommandIDs.closeDebugger,
+      selector: '.jp-DebuggerSidebar'
+    });
+
     commands.addCommand(CommandIDs.mount, {
       execute: async args => {
         if (!widget) {
@@ -275,7 +302,11 @@ const main: JupyterFrontEndPlugin<IDebugger> = {
 
         sidebar.id = 'jp-debugger-sidebar';
         sidebar.title.label = 'Environment';
+
         shell.add(sidebar, 'right', { activate: false });
+        if (labShell.currentWidget) {
+          labShell.currentWidget.activate();
+        }
 
         if (restorer) {
           restorer.add(sidebar, 'debugger-sidebar');

+ 4 - 2
src/service.ts

@@ -178,6 +178,7 @@ export class DebugService implements IDebugger {
    */
   async stop(): Promise<void> {
     await this.session.stop();
+    this._stoppedThreads.clear();
   }
 
   /**
@@ -188,7 +189,6 @@ export class DebugService implements IDebugger {
     const breakpoints = this.model.breakpointsModel.breakpoints;
     await this.stop();
     this.clearModel();
-    this._stoppedThreads.clear();
     await this.start();
 
     // No need to dump the cells again, we can simply
@@ -234,8 +234,10 @@ export class DebugService implements IDebugger {
         );
       });
     }
-    this._model.breakpointsModel.restoreBreakpoints(bpMap);
 
+    if (this._model) {
+      this._model.breakpointsModel.restoreBreakpoints(bpMap);
+    }
     if (!this.isStarted() && autoStart) {
       await this.start();
     }

+ 4 - 1
style/breakpoints.css

@@ -27,7 +27,10 @@
   top: -1px;
 }
 
-.jp-CodeCell.jp-mod-selected .CodeMirror-gutter-wrapper:hover::after,
+.jp-Notebook
+  .jp-mod-editMode
+  .jp-CodeCell.jp-mod-selected
+  .CodeMirror-gutter-wrapper:hover::after,
 .jp-Editor.jp-mod-focused
   .CodeMirror:not(.jp-mod-readOnly)
   .CodeMirror-gutter-wrapper:hover::after {

+ 20 - 0
style/icons.css

@@ -15,6 +15,10 @@
   background-image: url('icons/activate-breakpoints.svg');
 }
 
+[data-jp-theme-light='false'] .jp-DebuggerDeactivateIcon {
+  background-image: url('icons/md-dark/activate-breakpoints.svg');
+}
+
 .expand-toggle-collapsed {
   display: inline-block;
   vertical-align: middle;
@@ -35,14 +39,26 @@
   background-image: url('icons/step-over.svg');
 }
 
+[data-jp-theme-light='false'] .jp-StepOverIcon {
+  background-image: url('icons/md-dark/step-over.svg');
+}
+
 .jp-StepInIcon {
   background-image: url('icons/step-into.svg');
 }
 
+[data-jp-theme-light='false'] .jp-StepInIcon {
+  background-image: url('icons/md-dark/step-into.svg');
+}
+
 .jp-StepOutIcon {
   background-image: url('icons/step-out.svg');
 }
 
+[data-jp-theme-light='false'] .jp-StepOutIcon {
+  background-image: url('icons/md-dark/step-out.svg');
+}
+
 .jp-ClassIcon {
   background-image: url('icons/class.svg');
 }
@@ -58,3 +74,7 @@
 .jp-CloseAllIcon {
   background-image: url('icons/close-all.svg');
 }
+
+[data-jp-theme-light='false'] .jp-CloseAllIcon {
+  background-image: url('icons/md-dark/close-all.svg');
+}

+ 1 - 1
style/icons/activate-breakpoints.svg

@@ -1,3 +1,3 @@
 <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path d="M14.9991 5.50088C15.0304 6.61916 14.634 7.70725 13.8907 8.54339C13.1475 9.37953 12.1134 9.90077 10.9991 10.0009C10.9909 9.65848 10.9232 9.32011 10.7991 9.00088C11.6689 8.91143 12.4755 8.50545 13.0655 7.86014C13.6555 7.21482 13.9878 6.37518 13.9991 5.50088C13.9959 4.59898 13.6452 3.73302 13.0201 3.0829C12.395 2.43279 11.5434 2.0485 10.6423 2.00989C9.74125 1.97127 8.85994 2.28129 8.18148 2.87553C7.50302 3.46978 7.07959 4.30257 6.99915 5.20088C6.67717 5.08646 6.34037 5.0191 5.99915 5.00088C6.14761 3.90647 6.68305 2.9014 7.50851 2.16766C8.33397 1.43392 9.39488 1.02001 10.4991 1.00088C11.0908 0.998366 11.6771 1.11305 12.2242 1.3383C12.7713 1.56356 13.2684 1.89493 13.6867 2.31329C14.1051 2.73166 14.4365 3.22873 14.6617 3.77583C14.887 4.32293 15.0017 4.90923 14.9991 5.50088ZM5.49915 6.00088C4.60913 6.00088 3.7391 6.2648 2.99908 6.75927C2.25906 7.25373 1.68228 7.95654 1.34169 8.7788C1.0011 9.60107 0.91198 10.5059 1.08561 11.3788C1.25925 12.2517 1.68783 13.0535 2.31717 13.6829C2.9465 14.3122 3.74833 14.7408 4.62124 14.9144C5.49416 15.088 6.39896 14.9989 7.22122 14.6583C8.04349 14.3177 8.74629 13.741 9.24076 13.0009C9.73523 12.2609 9.99915 11.3909 9.99915 10.5009C9.99915 9.90993 9.88275 9.32477 9.65661 8.7788C9.43046 8.23284 9.09899 7.73676 8.68113 7.3189C8.26326 6.90104 7.76719 6.56957 7.22122 6.34342C6.67526 6.11728 6.0901 6.00088 5.49915 6.00088Z" fill="#424242"/>
+<path d="M14.9991 5.50088C15.0304 6.61916 14.634 7.70725 13.8907 8.54339C13.1475 9.37953 12.1134 9.90077 10.9991 10.0009C10.9909 9.65848 10.9232 9.32011 10.7991 9.00088C11.6689 8.91143 12.4755 8.50545 13.0655 7.86014C13.6555 7.21482 13.9878 6.37518 13.9991 5.50088C13.9959 4.59898 13.6452 3.73302 13.0201 3.0829C12.395 2.43279 11.5434 2.0485 10.6423 2.00989C9.74125 1.97127 8.85994 2.28129 8.18148 2.87553C7.50302 3.46978 7.07959 4.30257 6.99915 5.20088C6.67717 5.08646 6.34037 5.0191 5.99915 5.00088C6.14761 3.90647 6.68305 2.9014 7.50851 2.16766C8.33397 1.43392 9.39488 1.02001 10.4991 1.00088C11.0908 0.998366 11.6771 1.11305 12.2242 1.3383C12.7713 1.56356 13.2684 1.89493 13.6867 2.31329C14.1051 2.73166 14.4365 3.22873 14.6617 3.77583C14.887 4.32293 15.0017 4.90923 14.9991 5.50088ZM5.49915 6.00088C4.60913 6.00088 3.7391 6.2648 2.99908 6.75927C2.25906 7.25373 1.68228 7.95654 1.34169 8.7788C1.0011 9.60107 0.91198 10.5059 1.08561 11.3788C1.25925 12.2517 1.68783 13.0535 2.31717 13.6829C2.9465 14.3122 3.74833 14.7408 4.62124 14.9144C5.49416 15.088 6.39896 14.9989 7.22122 14.6583C8.04349 14.3177 8.74629 13.741 9.24076 13.0009C9.73523 12.2609 9.99915 11.3909 9.99915 10.5009C9.99915 9.90993 9.88275 9.32477 9.65661 8.7788C9.43046 8.23284 9.09899 7.73676 8.68113 7.3189C8.26326 6.90104 7.76719 6.56957 7.22122 6.34342C6.67526 6.11728 6.0901 6.00088 5.49915 6.00088Z" fill="#616161"/>
 </svg>

+ 3 - 0
style/icons/md-dark/activate-breakpoints.svg

@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M14.9991 5.50088C15.0304 6.61916 14.634 7.70725 13.8907 8.54339C13.1475 9.37953 12.1134 9.90077 10.9991 10.0009C10.9909 9.65848 10.9232 9.32011 10.7991 9.00088C11.6689 8.91143 12.4755 8.50545 13.0655 7.86014C13.6555 7.21482 13.9878 6.37518 13.9991 5.50088C13.9959 4.59898 13.6452 3.73302 13.0201 3.0829C12.395 2.43279 11.5434 2.0485 10.6423 2.00989C9.74125 1.97127 8.85994 2.28129 8.18148 2.87553C7.50302 3.46978 7.07959 4.30257 6.99915 5.20088C6.67717 5.08646 6.34037 5.0191 5.99915 5.00088C6.14761 3.90647 6.68305 2.9014 7.50851 2.16766C8.33397 1.43392 9.39488 1.02001 10.4991 1.00088C11.0908 0.998366 11.6771 1.11305 12.2242 1.3383C12.7713 1.56356 13.2684 1.89493 13.6867 2.31329C14.1051 2.73166 14.4365 3.22873 14.6617 3.77583C14.887 4.32293 15.0017 4.90923 14.9991 5.50088ZM5.49915 6.00088C4.60913 6.00088 3.7391 6.2648 2.99908 6.75927C2.25906 7.25373 1.68228 7.95654 1.34169 8.7788C1.0011 9.60107 0.91198 10.5059 1.08561 11.3788C1.25925 12.2517 1.68783 13.0535 2.31717 13.6829C2.9465 14.3122 3.74833 14.7408 4.62124 14.9144C5.49416 15.088 6.39896 14.9989 7.22122 14.6583C8.04349 14.3177 8.74629 13.741 9.24076 13.0009C9.73523 12.2609 9.99915 11.3909 9.99915 10.5009C9.99915 9.90993 9.88275 9.32477 9.65661 8.7788C9.43046 8.23284 9.09899 7.73676 8.68113 7.3189C8.26326 6.90104 7.76719 6.56957 7.22122 6.34342C6.67526 6.11728 6.0901 6.00088 5.49915 6.00088Z" fill="#bdbdbd"/>
+</svg>

+ 4 - 0
style/icons/md-dark/close-all.svg

@@ -0,0 +1,4 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M8.62132 8.0858L7.91421 7.37869L6.5 8.7929L5.08579 7.37869L4.37868 8.0858L5.79289 9.50001L4.37868 10.9142L5.08579 11.6213L6.5 10.2071L7.91421 11.6213L8.62132 10.9142L7.20711 9.50001L8.62132 8.0858Z" fill="#bdbdbd"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M5 3L6 2H13L14 3V10L13 11H11V13L10 14H3L2 13V6L3 5H5V3ZM6 5H10L11 6V10H13V3H6V5ZM10 6H3V13H10V6Z" fill="#bdbdbd"/>
+</svg>

+ 3 - 0
style/icons/md-dark/step-into.svg

@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M7.99998 9.53198H8.54198L12.447 5.62698L11.386 4.56698L8.74898 7.17698L8.74898 0.999985H7.99998H7.25098L7.25098 7.17698L4.61398 4.56698L3.55298 5.62698L7.45798 9.53198H7.99998ZM9.95598 13.013C9.95598 14.1175 9.06055 15.013 7.95598 15.013C6.85141 15.013 5.95598 14.1175 5.95598 13.013C5.95598 11.9084 6.85141 11.013 7.95598 11.013C9.06055 11.013 9.95598 11.9084 9.95598 13.013Z" fill="#bdbdbd"/>
+</svg>

+ 3 - 0
style/icons/md-dark/step-out.svg

@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M7.99998 1H7.45798L3.55298 4.905L4.61398 5.965L7.25098 3.355V9.532H7.99998H8.74898V3.355L11.386 5.965L12.447 4.905L8.54198 1H7.99998ZM9.95598 13.013C9.95598 14.1176 9.06055 15.013 7.95598 15.013C6.85141 15.013 5.95598 14.1176 5.95598 13.013C5.95598 11.9084 6.85141 11.013 7.95598 11.013C9.06055 11.013 9.95598 11.9084 9.95598 13.013Z" fill="#bdbdbd"/>
+</svg>

+ 3 - 0
style/icons/md-dark/step-over.svg

@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M14.25 5.75V1.75H12.75V4.2916C11.605 2.93303 9.83899 2.08334 7.90914 2.08334C4.73316 2.08334 1.98941 4.39036 1.75072 7.48075L1.72992 7.75H3.231L3.25287 7.5241C3.46541 5.32932 5.45509 3.58334 7.90914 3.58334C9.6452 3.58334 11.1528 4.45925 11.9587 5.75H9.12986V7.25H13.292L14.2535 6.27493V5.75H14.25ZM7.99997 14C9.10454 14 9.99997 13.1046 9.99997 12C9.99997 10.8954 9.10454 10 7.99997 10C6.8954 10 5.99997 10.8954 5.99997 12C5.99997 13.1046 6.8954 14 7.99997 14Z" fill="#bdbdbd"/>
+</svg>