浏览代码

Merge branch 'notebook_lines' into debugger-ui

Borys Palka 5 年之前
父节点
当前提交
ec77927368
共有 4 个文件被更改,包括 90 次插入70 次删除
  1. 0 1
      src/breakpoints/body.tsx
  2. 87 64
      src/breakpoints/index.ts
  3. 2 4
      src/index.ts
  4. 1 1
      style/breakpoints.css

+ 0 - 1
src/breakpoints/body.tsx

@@ -29,7 +29,6 @@ const BreakpointsComponent = ({ model }: { model: Breakpoints.IModel }) => {
       if (ArrayExt.shallowEqual(breakpoints, updates)) {
         return;
       }
-      console.log(updates);
       setBreakpoints(updates);
     }
   );

+ 87 - 64
src/breakpoints/index.ts

@@ -9,8 +9,8 @@ import { Body } from './body';
 import { Signal, ISignal } from '@phosphor/signaling';
 import { INotebookTracker } from '@jupyterlab/notebook';
 import { CodeMirrorEditor } from '@jupyterlab/codemirror';
-import { Editor } from 'codemirror';
-import { CodeCell, Cell } from '@jupyterlab/cells';
+import { Editor, Doc } from 'codemirror';
+import { CodeCell } from '@jupyterlab/cells';
 
 export class Breakpoints extends Panel {
   constructor(options: Breakpoints.IOptions) {
@@ -47,6 +47,8 @@ export class Breakpoints extends Panel {
         iconClassName: 'jp-CloseAllIcon',
         onClick: () => {
           this.model.breakpoints = [];
+          this.cellsBreakpoints[this.getCell().id] = {};
+          this.removeAllGutterBreakpoints(this.getCell());
         },
         tooltip: 'Remove All Breakpoints'
       })
@@ -63,25 +65,43 @@ export class Breakpoints extends Panel {
   readonly model: Breakpoints.IModel;
   notebook: INotebookTracker;
   previousCell: CodeCell;
+  previousLineCount: number;
+  cellsBreakpoints: any = {};
 
   protected onActiveCellChanged() {
     const activeCell = this.getCell();
-    if (this.previousCell && !this.previousCell.isDisposed) {
-      this.removeListner(this.previousCell);
+    if (this.model && activeCell) {
+      if (this.previousCell && !this.previousCell.isDisposed) {
+        this.removeListner(this.previousCell);
+      }
+      this.previousCell = activeCell;
+      const id: string = activeCell.model.id;
+      if (id && !this.cellsBreakpoints[id]) {
+        this.cellsBreakpoints[id] = [];
+      }
+      this.model.breakpoints = this.cellsBreakpoints[id];
+      this.setEditor(activeCell);
     }
-    this.previousCell = activeCell;
-    this.setEditor(activeCell);
   }
 
   protected getCell(): CodeCell {
     return this.notebook.activeCell as CodeCell;
   }
 
+  protected removeAllGutterBreakpoints(cell: CodeCell) {
+    const editor = cell.editor as CodeMirrorEditor;
+    editor.editor.getDoc().eachLine(line => {
+      editor.editor.setGutterMarker(line, 'breakpoints', null);
+    });
+  }
+
   removeListner(cell: CodeCell) {
     const editor = cell.editor as CodeMirrorEditor;
+    this.cellsBreakpoints[cell.model.id] = this.model.breakpoints;
+    this.model.breakpoints = [];
     editor.setOption('lineNumbers', false);
     editor.editor.off('gutterClick', this.addBreakpoint);
-    this.model.breakpoints = [];
+    editor.editor.off('renderLine', this.onNewRenderLine);
   }
 
   setEditor(cell: CodeCell) {
@@ -97,44 +117,74 @@ export class Breakpoints extends Panel {
     ]);
 
     editor.editor.on('gutterClick', this.addBreakpoint);
+    editor.editor.on('renderLine', this.onNewRenderLine);
   }
 
+  protected onNewRenderLine = (editor: Editor, line: any) => {
+    const lineInfo = editor.lineInfo(line);
+    if (
+      !this.model.breakpoints &&
+      this.model.breakpoints.length < 1 &&
+      lineInfo.handle &&
+      lineInfo.handle.order === false
+    ) {
+      return;
+    }
+
+    const doc: Doc = editor.getDoc();
+    const linesNumber = doc.lineCount();
+
+    if (this.previousLineCount !== linesNumber) {
+      if (this.previousLineCount > linesNumber) {
+        this.model.changeLines(lineInfo.line, -1);
+      }
+      if (this.previousLineCount < linesNumber) {
+        this.model.changeLines(lineInfo.line, +1);
+      }
+      this.previousLineCount = linesNumber;
+    }
+    // eage case for backspace line 2
+    if (lineInfo.line === 0) {
+      const breakpoint: Breakpoints.IBreakpoint = this.model.getBreakpointByLineNumber(
+        -1
+      );
+      if (breakpoint) {
+        this.model.removeBreakpoint(breakpoint);
+      }
+    }
+  };
+
   protected addBreakpoint = (editor: Editor, lineNumber: number) => {
     const info = editor.lineInfo(lineNumber);
     if (!info) {
       return;
     }
+    const removeGutter = !!info.gutterMarkers;
 
-    const breakpointMarker = {
-      line: lineNumber,
-      text: info.text,
-      remove: !!info.gutterMarkers
-    };
-
-    var breakpoint: Breakpoints.IBreakpoint = this.model.getBreakpointByLineNumber(
+    const breakpoint: Breakpoints.IBreakpoint = this.model.getBreakpointByLineNumber(
       lineNumber
     );
 
-    if (!breakpoint) {
-      breakpoint = {
+    if (!breakpoint && !removeGutter) {
+      this.model.breakpoint = {
         id: this.model.breakpoints.length + 1,
         active: true,
         verified: true,
         source: {
+          // TODO: need get filename
           name: 'untitled.py'
         },
         line: lineNumber
       };
+    } else if (removeGutter) {
+      this.model.removeBreakpoint(breakpoint);
     }
 
     editor.setGutterMarker(
       lineNumber,
       'breakpoints',
-      breakpointMarker.remove ? null : this.createMarkerNode()
+      removeGutter ? null : this.createMarkerNode()
     );
-
-    this.model.breakpoint = breakpoint;
-    this.getExistingBreakpoints(this.getCell());
   };
 
   createMarkerNode() {
@@ -143,30 +193,7 @@ export class Breakpoints extends Panel {
     marker.innerHTML = '●';
     return marker;
   }
-
-  protected getExistingBreakpoints(cell: Cell) {
-    const editor = cell.editor as CodeMirrorEditor;
-
-    // let lines = [];
-    editor.doc.eachLine(line => {
-      console.log(line);
-    });
-    //   for (let i = 0; i < editor.doc.lineCount(); i++) {
-    //     const info = editor.editor.lineInfo(i);
-    //     if (info.gutterMarkers) {
-    //       const breakpoint = {
-    //         line: info.line + 1, // lines start at 1
-    //         text: info.text,
-    //         remove: false
-    //       };
-    //       lines.push(breakpoint);
-    //     }
-    //   }
-    //   return lines;
-    // }
-  }
 }
-
 class BreakpointsHeader extends Widget {
   constructor(title: string) {
     super({ node: document.createElement('header') });
@@ -228,6 +255,23 @@ export namespace Breakpoints {
       }
     }
 
+    removeBreakpoint(breakpoint: IBreakpoint) {
+      const breakpoints = this.breakpoints.filter(
+        ele => ele.line !== breakpoint.line
+      );
+      this.breakpoints = [];
+      this.breakpoints = breakpoints;
+    }
+
+    changeLines(lineEnter: number, howMany: number) {
+      const breakpoints = this.breakpoints.map(ele => {
+        ele.line = lineEnter <= ele.line ? ele.line + howMany : ele.line;
+        return ele;
+      });
+      this.breakpoints = [];
+      this.breakpoints = breakpoints;
+    }
+
     getBreakpointByLineNumber(lineNumber: number) {
       return this.breakpoints.find(ele => ele.line === lineNumber);
     }
@@ -244,24 +288,3 @@ export namespace Breakpoints {
     notebook?: INotebookTracker;
   }
 }
-
-// const MOCK_BREAKPOINTS = [
-//   {
-//     id: 0,
-//     active: true,
-//     verified: true,
-//     source: {
-//       name: 'untitled.py'
-//     },
-//     line: 6
-//   },
-//   {
-//     id: 1,
-//     verified: true,
-//     active: false,
-//     source: {
-//       name: 'untitled.py'
-//     },
-//     line: 7
-//   }
-// ];

+ 2 - 4
src/index.ts

@@ -103,15 +103,13 @@ const sidebar: JupyterFrontEndPlugin<Debugger> = {
   activate: (
     app: JupyterFrontEnd,
     restorer: ILayoutRestorer | null,
-    notebookTracker: INotebookTracker,
-    editorTracker: IEditorTracker
+    notebookTracker: INotebookTracker
   ): Debugger => {
     const { shell } = app;
     const label = 'Environment';
     const namespace = 'jp-debugger-sidebar';
     const sidebar = new Debugger({
-      notebook: notebookTracker,
-      editor: editorTracker
+      notebook: notebookTracker
     });
 
     sidebar.id = namespace;

+ 1 - 1
style/breakpoints.css

@@ -9,7 +9,7 @@
 
 .jp-breakpoint-marker {
   position: absolute;
-  left: -30px;
+  left: -35px;
   top: -1px;
   color: #f22;
 }