فهرست منبع

fix first start and dispose after close debugger

Borys Palka 5 سال پیش
والد
کامیت
6ea464b15b
5فایلهای تغییر یافته به همراه71 افزوده شده و 11 حذف شده
  1. 6 0
      src/debugger.ts
  2. 11 6
      src/handlers/cell.ts
  3. 16 1
      src/handlers/notebook.ts
  4. 34 3
      src/index.ts
  5. 4 1
      src/service.ts

+ 6 - 0
src/debugger.ts

@@ -156,8 +156,13 @@ export namespace Debugger {
       this._codeValue = observableString;
     }
 
+    get disposed(): ISignal<this, void> {
+      return this._disposed;
+    }
+
     dispose(): void {
       this._isDisposed = true;
+      this._disposed.emit();
     }
 
     private async _populate(): Promise<void> {
@@ -172,6 +177,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 {

+ 11 - 6
src/handlers/cell.ts

@@ -79,15 +79,13 @@ 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);
+    this.setOffOptions(this.activeCell);
     CellManager.cleanupHighlight(this.activeCell);
     Signal.clearData(this);
+    this.isDisposed = true;
   }
 
   set previousCell(cell: CodeCell) {
@@ -131,7 +129,7 @@ export class CellManager implements IDisposable {
         if (this._cellMonitor) {
           this._cellMonitor.dispose();
         }
-        this.removeListener(this.previousCell);
+        this.removeGutterClick(this.previousCell);
       }
 
       this._cellMonitor = new ActivityMonitor({
@@ -188,7 +186,7 @@ export class CellManager implements IDisposable {
     editor.editor.on('gutterClick', this.onGutterClick);
   }
 
-  protected removeListener(cell: CodeCell) {
+  protected removeGutterClick(cell: CodeCell) {
     if (cell.isDisposed) {
       return;
     }
@@ -196,6 +194,13 @@ export class CellManager implements IDisposable {
     editor.editor.off('gutterClick', this.onGutterClick);
   }
 
+  setOffOptions(cell: Cell) {
+    const editor = cell.editor as CodeMirrorEditor;
+    CellManager.cleanupHighlight(cell);
+    editor.editor.off('gutterClick', this.onGutterClick);
+    editor.setOption('lineNumbers', false);
+  }
+
   protected getEditorId(): string {
     return this.activeCell.editor.uuid;
   }

+ 16 - 1
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,18 @@ 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 => {
+      this.cellManager.setOffOptions(cell);
+    });
+  }
+
   protected onActiveCellChanged(
     notebookTracker: NotebookTracker,
     codeCell: CodeCell
@@ -100,6 +114,7 @@ export class NotebookHandler implements IDisposable {
   private debuggerService: IDebugger;
   private breakpoints: Breakpoints.Model;
   private cellManager: CellManager;
+  private notebookPanel: NotebookPanel;
   private id: string;
 }
 

+ 34 - 3
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;
@@ -217,7 +227,7 @@ const notebooks: JupyterFrontEndPlugin<void> = {
  */
 const main: JupyterFrontEndPlugin<IDebugger> = {
   id: '@jupyterlab/debugger:main',
-  optional: [ILayoutRestorer, ICommandPalette],
+  optional: [ILayoutRestorer, ICommandPalette, ILabShell],
   requires: [IStateDB, IEditorServices],
   provides: IDebugger,
   autoStart: true,
@@ -226,7 +236,8 @@ const main: JupyterFrontEndPlugin<IDebugger> = {
     state: IStateDB,
     editorServices: IEditorServices,
     restorer: ILayoutRestorer | null,
-    palette: ICommandPalette | null
+    palette: ICommandPalette | null,
+    labShell: ILabShell
   ): IDebugger => {
     const { commands, shell } = app;
     const editorFactory = editorServices.factoryService.newInlineEditor;
@@ -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 - 1
src/service.ts

@@ -178,6 +178,7 @@ export class DebugService implements IDebugger {
    */
   async stop(): Promise<void> {
     await this.session.stop();
+    this._stoppedThreads.clear();
   }
 
   /**
@@ -234,8 +235,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();
     }