Browse Source

Merge pull request #1380 from blink1073/remove-codemirror-plugins

Remove the extra codemirror plugins
Afshin Darian 8 years ago
parent
commit
4404845965
38 changed files with 372 additions and 549 deletions
  1. 5 5
      examples/console/src/index.ts
  2. 6 6
      examples/lab/index.js
  3. 6 4
      examples/notebook/src/index.ts
  4. 6 6
      jupyterlab/src/extensions.ts
  5. 1 1
      package.json
  6. 9 5
      src/codeeditor/editor.ts
  7. 45 19
      src/codemirror/editor.ts
  8. 45 2
      src/codemirror/index.css
  9. 22 0
      src/codemirror/index.ts
  10. 4 8
      src/codemirror/plugin.ts
  11. 0 51
      src/console/codemirror/index.ts
  12. 0 36
      src/console/codemirror/plugin.ts
  13. 35 29
      src/console/content.ts
  14. 20 1
      src/console/plugin.ts
  15. 1 1
      src/docregistry/default.ts
  16. 7 2
      src/notebook/cells/editor.ts
  17. 0 113
      src/notebook/codemirror/highlight.css
  18. 0 49
      src/notebook/codemirror/index.css
  19. 0 95
      src/notebook/codemirror/index.ts
  20. 0 38
      src/notebook/codemirror/plugin.ts
  21. 0 1
      src/notebook/index.css
  22. 14 23
      src/notebook/notebook/widget.ts
  23. 23 2
      src/notebook/plugin.ts
  24. 0 1
      src/renderers/widget.ts
  25. 4 4
      test/src/completer/handler.spec.ts
  26. 5 5
      test/src/console/content.spec.ts
  27. 4 4
      test/src/console/foreign.spec.ts
  28. 4 4
      test/src/console/panel.spec.ts
  29. 19 0
      test/src/console/utils.ts
  30. 1 1
      test/src/notebook/cells/editor.spec.ts
  31. 4 4
      test/src/notebook/cells/widget.spec.ts
  32. 1 5
      test/src/notebook/notebook/actions.spec.ts
  33. 1 5
      test/src/notebook/notebook/default-toolbar.spec.ts
  34. 1 5
      test/src/notebook/notebook/panel.spec.ts
  35. 1 5
      test/src/notebook/notebook/widget.spec.ts
  36. 4 4
      test/src/notebook/notebook/widgetfactory.spec.ts
  37. 1 5
      test/src/notebook/tracker.spec.ts
  38. 73 0
      test/src/notebook/utils.ts

+ 5 - 5
examples/console/src/index.ts

@@ -26,12 +26,12 @@ import {
 } from '@jupyterlab/services';
 
 import {
-  ConsolePanel
-} from 'jupyterlab/lib/console';
+  editorServices
+} from 'jupyterlab/lib/codemirror';
 
 import {
-  createRenderer
-} from 'jupyterlab/lib/console/codemirror';
+  ConsolePanel, ConsoleContent
+} from 'jupyterlab/lib/console';
 
 import {
   RenderMime
@@ -94,7 +94,7 @@ function startApp(session: Session.ISession) {
   }
   let sanitizer = defaultSanitizer;
   let rendermime = new RenderMime({ renderers, order, sanitizer });
-  let renderer = createRenderer();
+  let renderer = new ConsoleContent.Renderer({ editorServices });
 
   let consolePanel = new ConsolePanel({ session, renderer, rendermime });
   consolePanel.title.label = TITLE;

+ 6 - 6
examples/lab/index.js

@@ -16,12 +16,12 @@ lab.registerPlugins([
   require('jupyterlab/lib/about/plugin').plugin,
   require('jupyterlab/lib/application/plugin').plugin,
   require('jupyterlab/lib/clipboard/plugin').plugin,
-  require('jupyterlab/lib/codemirror/plugin').editorServices,
-  require('jupyterlab/lib/codemirror/plugin').editorCommands,
+  require('jupyterlab/lib/codemirror/plugin').servicesPlugin,
+  require('jupyterlab/lib/codemirror/plugin').commandsPlugin,
   require('jupyterlab/lib/commandlinker/plugin').plugin,
   require('jupyterlab/lib/commandpalette/plugin').plugin,
-  require('jupyterlab/lib/console/plugin').plugin,
-  require('jupyterlab/lib/console/codemirror/plugin').plugin,
+  require('jupyterlab/lib/console/plugin').trackerPlugin,
+  require('jupyterlab/lib/console/plugin').rendererPlugin,
   require('jupyterlab/lib/docregistry/plugin').plugin,
   require('jupyterlab/lib/docmanager/plugin').plugin,
   require('jupyterlab/lib/editorwidget/plugin').plugin,
@@ -35,8 +35,8 @@ lab.registerPlugins([
   require('jupyterlab/lib/layoutrestorer/plugin').plugin,
   require('jupyterlab/lib/mainmenu/plugin').plugin,
   require('jupyterlab/lib/markdownwidget/plugin').plugin,
-  require('jupyterlab/lib/notebook/plugin').plugin,
-  require('jupyterlab/lib/notebook/codemirror/plugin').plugin,
+  require('jupyterlab/lib/notebook/plugin').trackerPlugin,
+  require('jupyterlab/lib/notebook/plugin').rendererPlugin,
   require('jupyterlab/lib/rendermime/plugin').plugin,
   require('jupyterlab/lib/running/plugin').plugin,
   require('jupyterlab/lib/services/plugin').plugin,

+ 6 - 4
examples/notebook/src/index.ts

@@ -30,13 +30,13 @@ import {
 } from '@jupyterlab/services';
 
 import {
-  NotebookPanel, NotebookWidgetFactory,
+  NotebookPanel, NotebookWidgetFactory, Notebook,
   NotebookModelFactory, NotebookActions
 } from 'jupyterlab/lib/notebook';
 
 import {
-  createNotebookPanelRenderer
-} from 'jupyterlab/lib/notebook/codemirror';
+  editorServices
+} from 'jupyterlab/lib/codemirror';
 
 import {
   DocumentManager
@@ -129,7 +129,9 @@ function createApp(manager: ServiceManager.IManager): void {
   });
   let mFactory = new NotebookModelFactory();
   let clipboard = new MimeData();
-  let renderer = createNotebookPanelRenderer();
+  let notebookRenderer = new Notebook.Renderer({ editorServices });
+  let renderer = new NotebookPanel.Renderer({ notebookRenderer });
+
   let wFactory = new NotebookWidgetFactory({
     name: 'Notebook',
     modelName: 'notebook',

+ 6 - 6
jupyterlab/src/extensions.ts

@@ -5,12 +5,12 @@ module.exports = [
   require('../../lib/about/plugin').plugin,
   require('../../lib/application/plugin').plugin,
   require('../../lib/clipboard/plugin').plugin,
-  require('../../lib/codemirror/plugin').editorServices,
-  require('../../lib/codemirror/plugin').editorCommands,
+  require('../../lib/codemirror/plugin').servicesPlugin,
+  require('../../lib/codemirror/plugin').commandsPlugin,
   require('../../lib/commandlinker/plugin').plugin,
   require('../../lib/commandpalette/plugin').plugin,
-  require('../../lib/console/plugin').plugin,
-  require('../../lib/console/codemirror/plugin').plugin,
+  require('../../lib/console/plugin').trackerPlugin,
+  require('../../lib/console/plugin').rendererPlugin,
   require('../../lib/csvwidget/plugin').plugin,
   require('../../lib/docmanager/plugin').plugin,
   require('../../lib/docregistry/plugin').plugin,
@@ -25,8 +25,8 @@ module.exports = [
   require('../../lib/layoutrestorer/plugin').plugin,
   require('../../lib/mainmenu/plugin').plugin,
   require('../../lib/markdownwidget/plugin').plugin,
-  require('../../lib/notebook/plugin').plugin,
-  require('../../lib/notebook/codemirror/plugin').plugin,
+  require('../../lib/notebook/plugin').trackerPlugin,
+  require('../../lib/notebook/plugin').rendererPlugin,
   require('../../lib/rendermime/plugin').plugin,
   require('../../lib/running/plugin').plugin,
   require('../../lib/services/plugin').plugin,

+ 1 - 1
package.json

@@ -57,7 +57,7 @@
     "rimraf": "^2.5.0",
     "style-loader": "^0.13.0",
     "typedoc": "^0.5.0",
-    "typescript": "^2.0.3",
+    "typescript": "~2.0.3",
     "url-loader": "^0.5.7",
     "watch": "^0.17.1",
     "webpack": "^1.12.11"

+ 9 - 5
src/codeeditor/editor.ts

@@ -488,11 +488,6 @@ namespace CodeEditor {
      */
     readonly charWidth: number;
 
-    /**
-     * Handle keydown events for the editor.
-     */
-    onKeyDown: KeydownHandler | null;
-
     /**
      * Brings browser focus to this editor text.
      */
@@ -508,6 +503,15 @@ namespace CodeEditor {
      */
     refresh(): void;
 
+    /**
+     * Add a keydown handler to the editor.
+     *
+     * @param handler - A keydown handler.
+     *
+     * @returns A disposable that can be used to remove the handler.
+     */
+    addKeydownHandler(handler: KeydownHandler): IDisposable;
+
     /**
      * Set the size of the editor.
      *

+ 45 - 19
src/codemirror/editor.ts

@@ -4,6 +4,18 @@
 import * as CodeMirror
   from 'codemirror';
 
+import {
+  findIndex
+} from 'phosphor/lib/algorithm/searching';
+
+import {
+  IDisposable, DisposableDelegate
+} from 'phosphor/lib/core/disposable';
+
+import {
+  Vector
+} from 'phosphor/lib/collections/vector';
+
 import {
   IChangedArgs
 } from '../common/interfaces';
@@ -48,11 +60,6 @@ class CodeMirrorEditor implements CodeEditor.IEditor {
    */
   readonly selectionStyle?: CodeEditor.ISelectionStyle;
 
-  /**
-   * Handle keydown events for the editor.
-   */
-  onKeyDown: CodeEditor.KeydownHandler | null = null;
-
   /**
    * Construct a CodeMirror editor.
    */
@@ -67,10 +74,19 @@ class CodeMirrorEditor implements CodeEditor.IEditor {
     options.value = this._model.doc;
     this._editor = CodeMirror(host, options);
 
-    this._model.mimeTypeChanged.connect((model, args) => this._onMimeTypeChanged(model, args));
+    this._onMimeTypeChanged();
+    // TODO: handle initial selections.
+    this._model.mimeTypeChanged.connect(() => this._onMimeTypeChanged());
     this._model.selections.changed.connect((selections, args) => this._onSelectionsChanged(selections, args));
 
-    CodeMirror.on(this.editor, 'keydown', (editor, event) => this._onKeyDown(editor, event));
+    CodeMirror.on(this.editor, 'keydown', (editor, event) => {
+      findIndex(this._keydownHandlers, handler => {
+        if (handler(this, event) === true) {
+          event.preventDefault();
+          return true;
+        }
+      });
+    });
     CodeMirror.on(this.editor, 'cursorActivity', () => this._onCursorActivity());
   }
 
@@ -92,6 +108,7 @@ class CodeMirrorEditor implements CodeEditor.IEditor {
     this._model.dispose();
     this._model = null;
     this._editor = null;
+    this._keydownHandlers.clear();
   }
 
   /**
@@ -177,6 +194,20 @@ class CodeMirrorEditor implements CodeEditor.IEditor {
     this._editor.refresh();
   }
 
+  /**
+   * Add a keydown handler to the editor.
+   *
+   * @param handler - A keydown handler.
+   *
+   * @returns A disposable that can be used to remove the handler.
+   */
+  addKeydownHandler(handler: CodeEditor.KeydownHandler): IDisposable {
+    this._keydownHandlers.pushBack(handler);
+    return new DisposableDelegate(() => {
+      this._keydownHandlers.remove(handler);
+    });
+  }
+
   /**
    * Set the size of the editor in pixels.
    */
@@ -278,9 +309,12 @@ class CodeMirrorEditor implements CodeEditor.IEditor {
   /**
    * Handles a mime type change.
    */
-  protected _onMimeTypeChanged(model: CodeMirrorModel, args: IChangedArgs<string>): void {
-      const mime = args.newValue;
-      loadModeByMIME(this._editor, mime);
+  protected _onMimeTypeChanged(): void {
+    const mime = this._model.mimeType;
+    loadModeByMIME(this._editor, mime);
+    let isCode = (mime !== 'text/plain') && (mime !== 'text/x-ipythongfm');
+    this.editor.setOption('matchBrackets', isCode);
+    this.editor.setOption('autoCloseBrackets', isCode);
   }
 
   /**
@@ -318,15 +352,6 @@ class CodeMirrorEditor implements CodeEditor.IEditor {
     this.selectionMarkers[uuid] = markers;
   }
 
-  /**
-   * Handles a key down event.
-   */
-  protected _onKeyDown(editor: CodeMirror.Editor, event: KeyboardEvent): void {
-    if (this.onKeyDown && this.onKeyDown(this, event)) {
-      event.preventDefault();
-    }
-  }
-
   /**
    * Handles a cursor activity event.
    */
@@ -404,6 +429,7 @@ class CodeMirrorEditor implements CodeEditor.IEditor {
   private _editor: CodeMirror.Editor;
   private _isDisposed = false;
   protected selectionMarkers: { [key: string]: CodeMirror.TextMarker[] | undefined } = {};
+  private _keydownHandlers = new Vector<CodeEditor.KeydownHandler>();
 
 }
 

+ 45 - 2
src/codemirror/index.css

@@ -19,6 +19,49 @@
 @import url('~codemirror/theme/xq-light.css');
 
 
+.CodeMirror {
+  line-height: var(--jp-code-line-height);
+  font-size: var(--jp-code-font-size);
+  height: auto;
+  /* Changed to auto to autogrow */
+  background: none;
+}
+
+
+.CodeMirror pre {
+  padding: 0;
+  border: 0;
+  border-radius: 0;
+}
+
+
+/* This causes https://github.com/jupyter/jupyterlab/issues/522 */
+/* May not cause it not because we changed it! */
+.CodeMirror-lines {
+  padding: var(--jp-code-padding);
+}
+
+
+.CodeMirror-linenumbers {
+  padding: 0 4px 0 4px;
+}
+
+
+.jp-CodeMirrorWidget-static {
+  margin: var(--jp-code-padding);
+}
+
+
+.jp-CodeMirrorWidget, .jp-CodeMirrorWidget-static {
+  cursor: text;
+}
+
+
+.jp-CodeMirrorWidget.jp-mod-readOnly .CodeMirror-cursor {
+  display: none;
+}
+
+
 /*
   Here is our jupyter theme for CodeMirror syntax highlighting
   This is used in our marked.js syntax highlighting and CodeMirror itself
@@ -34,8 +77,8 @@
 .cm-s-jupyter span.cm-variable     { color: --md-grey-900 }
 .cm-s-jupyter span.cm-variable-2   { color: --md-grey-800 }
 .cm-s-jupyter span.cm-variable-3   { color: --md-grey-700 }
-.cm-s-jupyter span.cm-punctuation  {  }
-.cm-s-jupyter span.cm-property     {  }
+.cm-s-jupyter span.cm-punctuation  { color: #05a; }
+.cm-s-jupyter span.cm-property     { color: #05a; }
 .cm-s-jupyter span.cm-operator     { color: #AA22FF; font-weight: bold; }
 .cm-s-jupyter span.cm-comment      { color: #408080; font-style: italic; }
 .cm-s-jupyter span.cm-string       { color: #BA2121; }

+ 22 - 0
src/codemirror/index.ts

@@ -1,8 +1,30 @@
 // Copyright (c) Jupyter Development Team.
 // Distributed under the terms of the Modified BSD License.
 
+import {
+  IEditorServices
+} from '../codeeditor';
+
+import {
+  CodeMirrorEditorFactory
+} from './factory';
+
+import {
+  CodeMirrorMimeTypeService
+} from './mimetype';
+
 export * from './mode';
 export * from './model';
 export * from './editor';
 export * from './factory';
 export * from './mimetype';
+
+
+/**
+ * The default editor services.
+ */
+export
+const editorServices: IEditorServices = {
+  factory: new CodeMirrorEditorFactory(),
+  mimeTypeService: new CodeMirrorMimeTypeService()
+};

+ 4 - 8
src/codemirror/plugin.ts

@@ -31,7 +31,7 @@ import {
 } from '../mainmenu';
 
 import {
-  CodeMirrorEditorFactory, CodeMirrorMimeTypeService, CodeMirrorEditor, DEFAULT_CODEMIRROR_THEME
+  editorServices, CodeMirrorEditor, DEFAULT_CODEMIRROR_THEME
 } from '.';
 
 
@@ -39,14 +39,10 @@ import {
  * The editor services.
  */
 export
-const editorServices: JupyterLabPlugin<IEditorServices> = {
+const servicesPlugin: JupyterLabPlugin<IEditorServices> = {
   id: IEditorServices.name,
   provides: IEditorServices,
-  activate: (): IEditorServices => {
-    const factory = new CodeMirrorEditorFactory();
-    const mimeTypeService = new CodeMirrorMimeTypeService();
-    return { factory, mimeTypeService };
-  }
+  activate: (): IEditorServices => editorServices
 };
 
 
@@ -54,7 +50,7 @@ const editorServices: JupyterLabPlugin<IEditorServices> = {
  * The editor commands.
  */
 export
-const editorCommands: JupyterLabPlugin<void> = {
+const commandsPlugin: JupyterLabPlugin<void> = {
   id: 'jupyter.services.editor-commands',
   requires: [IEditorTracker, IMainMenu, ICommandPalette],
   activate: activateEditorCommands,

+ 0 - 51
src/console/codemirror/index.ts

@@ -1,51 +0,0 @@
-// Copyright (c) Jupyter Development Team.
-// Distributed under the terms of the Modified BSD License.
-
-import {
-  ConsoleContent
-} from '../content';
-
-import {
-  IEditorServices
-} from '../../codeeditor';
-
-import {
-  CodeMirrorEditorFactory, CodeMirrorMimeTypeService
-} from '../../codemirror';
-
-import {
-  CodeCellWidget
-} from '../../notebook/cells';
-
-
-/**
- * Create a console renderer given editor services.
- */
-export
-function createRenderer(editorServices?: IEditorServices): ConsoleContent.IRenderer {
-  editorServices = editorServices || {
-    factory: new CodeMirrorEditorFactory(),
-    mimeTypeService: new CodeMirrorMimeTypeService()
-  };
-  const bannerRenderer = new CodeCellWidget.Renderer({
-    editorFactory: host => editorServices.factory.newInlineEditor(host.node, {
-      wordWrap: true
-    })
-  });
-  const promptRenderer = new CodeCellWidget.Renderer({
-    editorFactory: host => editorServices.factory.newInlineEditor(host.node, {
-      extra: {
-        matchBrackets: false,
-        autoCloseBrackets: false,
-        extraKeys: {
-          Enter: function () { /* no-op */ }
-        }
-      }
-    })
-  });
-  const foreignCellRenderer = promptRenderer;
-  const editorMimeTypeService = editorServices.mimeTypeService;
-  return new ConsoleContent.Renderer({
-    bannerRenderer, promptRenderer, foreignCellRenderer, editorMimeTypeService
-  });
-}

+ 0 - 36
src/console/codemirror/plugin.ts

@@ -1,36 +0,0 @@
-// Copyright (c) Jupyter Development Team.
-// Distributed under the terms of the Modified BSD License.
-
-import {
-  JupyterLab, JupyterLabPlugin
-} from '../../application';
-
-import {
-  ConsoleContent
-} from '../content';
-
-import {
-  IEditorServices
-} from '../../codeeditor';
-
-import {
-  createRenderer
-} from '.';
-
-/**
- * The provider for a console's code mirror renderer.
- */
-export
-const plugin: JupyterLabPlugin<ConsoleContent.IRenderer> = {
-  id: 'jupyter.services.console.codemirror.renderer',
-  requires: [IEditorServices],
-  provides: ConsoleContent.IRenderer,
-  activate: activateRendererProvider
-};
-
-/**
- * Activates the renderer provider extension.
- */
-function activateRendererProvider(app: JupyterLab, editorServices: IEditorServices): ConsoleContent.IRenderer {
-  return createRenderer(editorServices);
-}

+ 35 - 29
src/console/content.ts

@@ -38,7 +38,7 @@ import {
 } from '../inspector';
 
 import {
-  IEditorMimeTypeService
+  IEditorMimeTypeService, IEditorServices, CodeEditor
 } from '../codeeditor';
 
 import {
@@ -713,19 +713,16 @@ namespace ConsoleContent {
    */
   export
   class Renderer implements IRenderer {
-
     /**
      * The banner renderer.
      */
-    readonly bannerRenderer: CodeCellWidget.IRenderer;
+    readonly bannerRenderer: BaseCellWidget.IRenderer;
+
     /**
      * The prompt renderer.
      */
     readonly promptRenderer: CodeCellWidget.IRenderer;
-    /**
-     * The foreign cell renderer.
-     */
-    readonly foreignCellRenderer: CodeCellWidget.IRenderer;
+
     /**
      * The mime type service of a code editor.
      */
@@ -735,10 +732,16 @@ namespace ConsoleContent {
      * Create a new renderer.
      */
     constructor(options: Renderer.IOptions) {
-      this.bannerRenderer = options.bannerRenderer;
-      this.promptRenderer = options.promptRenderer;
-      this.foreignCellRenderer = options.foreignCellRenderer;
-      this.editorMimeTypeService = options.editorMimeTypeService;
+      let factory = options.editorServices.factory;
+      this.bannerRenderer = new BaseCellWidget.Renderer({
+        editorFactory: host => factory.newInlineEditor(host.node, {
+          wordWrap: true
+        })
+      });
+      this.promptRenderer = new Private.PromptRenderer({
+        editorFactory: host => factory.newInlineEditor(host.node, {})
+      });
+      this.editorMimeTypeService = options.editorServices.mimeTypeService;
     }
 
     /**
@@ -770,7 +773,7 @@ namespace ConsoleContent {
     createForeignCell(rendermime: IRenderMime, context: ConsoleContent): CodeCellWidget {
       let widget = new CodeCellWidget({
         rendermime,
-        renderer: this.foreignCellRenderer
+        renderer: this.promptRenderer
       });
       widget.model = new CodeCellModel();
       return widget;
@@ -782,7 +785,6 @@ namespace ConsoleContent {
     getCodeMimetype(info: nbformat.ILanguageInfoMetadata): string {
       return this.editorMimeTypeService.getMimeTypeByLanguage(info);
     }
-
   }
 
   /**
@@ -795,22 +797,7 @@ namespace ConsoleContent {
      */
     export
     interface IOptions {
-      /**
-       * The banner renderer.
-       */
-      readonly bannerRenderer: CodeCellWidget.IRenderer;
-      /**
-       * The prompt renderer.
-       */
-      readonly promptRenderer: CodeCellWidget.IRenderer;
-      /**
-       * The foreign cell renderer.
-       */
-      readonly foreignCellRenderer: CodeCellWidget.IRenderer;
-      /**
-       * The mime type service of a code editor.
-       */
-      readonly editorMimeTypeService: IEditorMimeTypeService;
+      readonly editorServices: IEditorServices;
     }
   }
 
@@ -837,4 +824,23 @@ namespace Private {
   function scrollToBottom(node: HTMLElement): void {
     node.scrollTop = node.scrollHeight - node.clientHeight;
   }
+
+  /**
+   * A custom renderer for a prompt that suppresses "enter" handling.
+   */
+  export
+  class PromptRenderer extends CodeCellWidget.Renderer {
+    /**
+     * Create a new cell editor for the widget.
+     */
+    createCellEditor(): ICellEditorWidget {
+      let widget = super.createCellEditor();
+      // Suppress the default "Enter" key handling.
+      let cb = (editor: CodeEditor.IEditor, event: KeyboardEvent) => {
+        return event.keyCode === 13;  // Enter;
+      };
+      widget.editor.addKeydownHandler(cb);
+      return widget;
+    }
+  }
 }

+ 20 - 1
src/console/plugin.ts

@@ -17,6 +17,10 @@ import {
   JupyterLab, JupyterLabPlugin
 } from '../application';
 
+import {
+  IEditorServices
+} from '../codeeditor';
+
 import {
   ICommandPalette
 } from '../commandpalette';
@@ -70,7 +74,7 @@ import {
  * The console widget tracker provider.
  */
 export
-const plugin: JupyterLabPlugin<IConsoleTracker> = {
+const trackerPlugin: JupyterLabPlugin<IConsoleTracker> = {
   id: 'jupyter.services.console-tracker',
   provides: IConsoleTracker,
   requires: [
@@ -89,6 +93,21 @@ const plugin: JupyterLabPlugin<IConsoleTracker> = {
 };
 
 
+/**
+ * The console widget renderer.
+ */
+export
+const rendererPlugin: JupyterLabPlugin<ConsoleContent.IRenderer> = {
+  id: 'jupyter.services.console-renderer',
+  provides: ConsoleContent.IRenderer,
+  requires: [IEditorServices],
+  autoStart: true,
+  activate: (app: JupyterLab, editorServices: IEditorServices) => {
+    return new ConsoleContent.Renderer({ editorServices });
+  }
+};
+
+
 /**
  * The class name for all main area landscape tab icons.
  */

+ 1 - 1
src/docregistry/default.ts

@@ -7,7 +7,7 @@ import * as CodeMirror
 import 'codemirror/mode/meta';
 
 import {
-  Contents, Kernel
+  Contents
 } from '@jupyterlab/services';
 
 import {

+ 7 - 2
src/notebook/cells/editor.ts

@@ -133,6 +133,11 @@ interface ICompletionRequest extends IEditorState {
  */
 export
 interface ICellEditorWidget extends Widget {
+  /**
+   * The editor used by the widget.
+   */
+  readonly editor: CodeEditor.IEditor;
+
   /**
    * The cell model used by the editor.
    */
@@ -241,9 +246,9 @@ class CodeCellEditorWidget extends CodeEditorWidget implements ICellEditorWidget
     this.editor.model.value.changed.connect(() => {
       this.onEditorModelChange();
     });
-    this.editor.onKeyDown = (editor, event) => {
+    this.editor.addKeydownHandler((editor, event) => {
       return this.onEditorKeydown(editor, event);
-    };
+    });
   }
 
   /**

+ 0 - 113
src/notebook/codemirror/highlight.css

@@ -1,113 +0,0 @@
-/*-----------------------------------------------------------------------------
-| Copyright (c) Jupyter Development Team.
-| Distributed under the terms of the Modified BSD License.
-|----------------------------------------------------------------------------*/
-
-
-/*
-
-Original style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org>
-Adapted from GitHub theme
-
-*/
-
-.cm-s-ipython span.cm-variable {
-  color: black;
-}
-
-
-.cm-s-ipython span.cm-variable-2 {
-  color: #1a1a1a;
-}
-.cm-s-ipython span.cm-variable-3 {
-  color: #333;
-}
-
-
-.cm-s-ipython span.cm-punctuation {
-  color: #05a;
-}
-
-
-.cm-s-ipython span.cm-property {
-  color: #05a;
-}
-
-
-.cm-s-ipython span.cm-operator {
-  color: #AA22FF;
-  font-weight: bold;
-}
-
-
-.cm-s-ipython span.cm-comment {
-  color: #408080;
-  font-style: italic;
-}
-
-
-.cm-s-ipython span.cm-string {
-  color: #BA2121;
-}
-
-
-.cm-s-ipython span.cm-string-2 {
-  color: #05a;
-}
-
-
-.cm-s-ipython span.cm-meta {
-  color: #AA22FF;
-}
-
-
-.cm-s-ipython span.cm-qualifier {
-  color: #555;
-}
-
-
-.cm-s-ipython span.cm-builtin {
-  color: #008000;
-}
-
-
-.cm-s-ipython span.cm-bracket {
-  color: #997;
-}
-
-
-.cm-s-ipython span.cm-tag {
-  color: #170;
-}
-
-
-.cm-s-ipython span.cm-attribute {
-  color: #00c;
-}
-
-
-.cm-s-ipython span.cm-header {
-  color: blue;
-}
-
-
-.cm-s-ipython span.cm-quote {
-  color: #090;
-}
-
-
-.cm-s-ipython span.cm-link {
-  text-decoration: underline;
-}
-
-
-.cm-s-ipython span.cm-error {
-  color: #f00;
-}
-
-
-.cm-s-ipython span.cm-tab {
-  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);
-  background-position: right;
-  background-repeat: no-repeat;
-}

+ 0 - 49
src/notebook/codemirror/index.css

@@ -1,49 +0,0 @@
-/*-----------------------------------------------------------------------------
-| Copyright (c) Jupyter Development Team.
-| Distributed under the terms of the Modified BSD License.
-|----------------------------------------------------------------------------*/
-
-@import './highlight.css';
-
-
-.CodeMirror {
-  line-height: var(--jp-code-line-height);
-  font-size: var(--jp-code-font-size);
-  height: auto;
-  /* Changed to auto to autogrow */
-  background: none;
-}
-
-
-.CodeMirror pre {
-  padding: 0;
-  border: 0;
-  border-radius: 0;
-}
-
-
-/* This causes https://github.com/jupyter/jupyterlab/issues/522 */
-/* May not cause it not because we changed it! */
-.CodeMirror-lines {
-  padding: var(--jp-code-padding);
-}
-
-
-.CodeMirror-linenumbers {
-  padding: 0 4px 0 4px;
-}
-
-
-.jp-CodeMirrorWidget-static {
-  margin: var(--jp-code-padding);
-}
-
-
-.jp-CodeMirrorWidget, .jp-CodeMirrorWidget-static {
-  cursor: text;
-}
-
-
-.jp-CodeMirrorWidget.jp-mod-readOnly .CodeMirror-cursor {
-  display: none;
-}

+ 0 - 95
src/notebook/codemirror/index.ts

@@ -1,95 +0,0 @@
-// Copyright (c) Jupyter Development Team.
-// Distributed under the terms of the Modified BSD License.
-
-import {
-  NotebookPanel, Notebook
-} from '../notebook';
-
-import {
-  BaseCellWidget, CodeCellWidget, CodeCellEditorWidget
-} from '../cells';
-
-import {
-  IEditorServices, IEditorFactory
-} from '../../codeeditor';
-
-import {
-  CodeMirrorEditorFactory, CodeMirrorMimeTypeService
-} from '../../codemirror';
-
-
-/**
- * Create a base cell renderer.
- */
-export
-function createBaseCellRenderer(factory?: IEditorFactory): BaseCellWidget.Renderer {
-  factory = factory || new CodeMirrorEditorFactory();
-  return new BaseCellWidget.Renderer({
-    editorFactory: host => factory.newInlineEditor(host.node, {
-      wordWrap: true
-    })
-  });
-};
-
-
-/**
- * Create a new code cell renderer.
- */
-export
-function createCodeCellRenderer(factory?: IEditorFactory): CodeCellWidget.Renderer {
-  factory = factory || new CodeMirrorEditorFactory();
-  return new CodeCellWidget.Renderer({
-    editorFactory: host => factory.newInlineEditor(host.node, {
-      extra: {
-        matchBrackets: true,
-        autoCloseBrackets: true
-      }
-    })
-  });
-}
-
-
-/**
- * Create a cell editor widget given a factory.
- */
-export
-function createCellEditor(factory?: IEditorFactory): CodeCellEditorWidget {
-  factory = factory || new CodeMirrorEditorFactory();
-  return new CodeCellEditorWidget(
-    host => factory.newInlineEditor(host.node, {
-      wordWrap: true
-    })
-  );
-}
-
-
-/**
- * Create a notebook renderer.
- */
-export
-function createNotebookRenderer(editorServices?: IEditorServices): Notebook.Renderer {
-  editorServices = editorServices || {
-    factory: new CodeMirrorEditorFactory(),
-    mimeTypeService: new CodeMirrorMimeTypeService()
-  };
-  let factory = editorServices.factory;
-  const editorMimeTypeService = editorServices.mimeTypeService;
-  const codeCellRenderer = createCodeCellRenderer(factory);
-  const rawCellRenderer = createBaseCellRenderer(factory);
-  const markdownCellRenderer = rawCellRenderer;
-  return new Notebook.Renderer({
-    codeCellRenderer, markdownCellRenderer, rawCellRenderer, editorMimeTypeService
-  });
-}
-
-
-/**
- * Create a notebook panel renderer.
- */
-export
-function createNotebookPanelRenderer(editorServices?: IEditorServices): NotebookPanel.IRenderer {
-  const notebookRenderer = createNotebookRenderer(editorServices);
-  return new NotebookPanel.Renderer({
-    notebookRenderer
-  });
-}

+ 0 - 38
src/notebook/codemirror/plugin.ts

@@ -1,38 +0,0 @@
-// Copyright (c) Jupyter Development Team.
-// Distributed under the terms of the Modified BSD License.
-
-import {
-  NotebookPanel
-} from '../notebook';
-
-import {
-  JupyterLab, JupyterLabPlugin
-} from '../../application';
-
-import {
-  IEditorServices
-} from '../../codeeditor';
-
-import {
-  createNotebookPanelRenderer
-} from '.';
-
-
-/**
- * The provider for a notebook's code mirror renderer.
- */
-export
-const plugin: JupyterLabPlugin<NotebookPanel.IRenderer> = {
-  id: 'jupyter.services.notebook.codemirror.renderer',
-  requires: [IEditorServices],
-  provides: NotebookPanel.IRenderer,
-  activate: activateRendererProvider
-};
-
-/**
- * Activates the renderer provider extension.
- */
-function activateRendererProvider(app: JupyterLab, editorServices: IEditorServices): NotebookPanel.IRenderer {
-  return createNotebookPanelRenderer(editorServices);
-}
-

+ 0 - 1
src/notebook/index.css

@@ -24,7 +24,6 @@
 
 
 @import './cells/index.css';
-@import './codemirror/index.css';
 @import './notebook/index.css';
 @import './output-area/index.css';
 @import './toolbar.css';

+ 14 - 23
src/notebook/notebook/widget.ts

@@ -70,7 +70,7 @@ import {
 } from '../../rendermime';
 
 import {
-  IEditorMimeTypeService
+  IEditorMimeTypeService, IEditorServices
 } from '../../codeeditor';
 
 import {
@@ -540,7 +540,6 @@ namespace StaticNotebook {
    */
   export
   class Renderer implements IRenderer {
-
     /**
      * A code cell renderer.
      */
@@ -565,10 +564,17 @@ namespace StaticNotebook {
      * Creates a new renderer.
      */
     constructor(options: Renderer.IOptions) {
-      this.codeCellRenderer = options.codeCellRenderer;
-      this.markdownCellRenderer = options.markdownCellRenderer;
-      this.rawCellRenderer = options.rawCellRenderer;
-      this.editorMimeTypeService = options.editorMimeTypeService;
+      let factory = options.editorServices.factory;
+      this.codeCellRenderer = new CodeCellWidget.Renderer({
+        editorFactory: host => factory.newInlineEditor(host.node, {})
+      });
+      this.markdownCellRenderer = new BaseCellWidget.Renderer({
+        editorFactory: host => factory.newInlineEditor(host.node, {
+          wordWrap: true
+        })
+      });
+      this.rawCellRenderer = this.markdownCellRenderer;
+      this.editorMimeTypeService = options.editorServices.mimeTypeService;
     }
 
     /**
@@ -635,24 +641,9 @@ namespace StaticNotebook {
     export
     interface IOptions {
       /**
-       * A code cell renderer.
-       */
-      readonly codeCellRenderer: CodeCellWidget.IRenderer;
-
-      /**
-       * A markdown cell renderer.
-       */
-      readonly markdownCellRenderer: BaseCellWidget.IRenderer;
-
-      /**
-       * A raw cell renderer.
-       */
-      readonly rawCellRenderer: BaseCellWidget.IRenderer;
-
-      /**
-       * A mime type service of a code editor.
+       * The editor services.
        */
-      readonly editorMimeTypeService: IEditorMimeTypeService;
+      readonly editorServices: IEditorServices;
     }
   }
 }

+ 23 - 2
src/notebook/plugin.ts

@@ -13,6 +13,10 @@ import {
   IClipboard
 } from '../clipboard';
 
+import {
+  IEditorServices
+} from '../codeeditor';
+
 import {
   ICommandPalette
 } from '../commandpalette';
@@ -48,7 +52,7 @@ import {
 
 import {
   INotebookTracker, NotebookModelFactory, NotebookPanel, NotebookTracker,
-  NotebookWidgetFactory, NotebookActions
+  NotebookWidgetFactory, NotebookActions, Notebook
 } from './index';
 
 
@@ -119,7 +123,7 @@ const FACTORY = 'Notebook';
  * The notebook widget tracker provider.
  */
 export
-const plugin: JupyterLabPlugin<INotebookTracker> = {
+const trackerPlugin: JupyterLabPlugin<INotebookTracker> = {
   id: 'jupyter.services.notebook-tracker',
   provides: INotebookTracker,
   requires: [
@@ -139,10 +143,27 @@ const plugin: JupyterLabPlugin<INotebookTracker> = {
 };
 
 
+/**
+ * The notebook renderer provider.
+ */
+export
+const rendererPlugin: JupyterLabPlugin<NotebookPanel.IRenderer> = {
+  id: 'jupyter.services.notebook-renderer',
+  provides: NotebookPanel.IRenderer,
+  requires: [IEditorServices],
+  autoStart: true,
+  activate: (app: JupyterLab, editorServices: IEditorServices) => {
+    const notebookRenderer = new Notebook.Renderer({ editorServices });
+    return new NotebookPanel.Renderer({ notebookRenderer });
+  }
+};
+
+
 /**
  * Activate the notebook handler extension.
  */
 function activateNotebookHandler(app: JupyterLab, registry: IDocumentRegistry, services: IServiceManager, rendermime: IRenderMime, clipboard: IClipboard, mainMenu: IMainMenu, palette: ICommandPalette, inspector: IInspector, renderer: NotebookPanel.IRenderer, state: IStateDB, layout: ILayoutRestorer): INotebookTracker {
+
   const factory = new NotebookWidgetFactory({
     name: FACTORY,
     fileExtensions: ['.ipynb'],

+ 0 - 1
src/renderers/widget.ts

@@ -1,7 +1,6 @@
 // Copyright (c) Jupyter Development Team.
 // Distributed under the terms of the Modified BSD License.
 
-
 import {
   ansi_to_html, escape_for_html
 } from 'ansi_up';

+ 4 - 4
test/src/completer/handler.spec.ts

@@ -19,14 +19,14 @@ import {
   ICompletionRequest, ICellEditorWidget, ITextChange
 } from '../../../lib/notebook/cells/editor';
 
-import {
-  createBaseCellRenderer
-} from '../../../lib/notebook/codemirror';
-
 import {
   CompleterWidget, CellCompleterHandler, CompleterModel
 } from '../../../lib/completer';
 
+import {
+  createBaseCellRenderer
+} from '../notebook/utils';
+
 
 const renderer = createBaseCellRenderer();
 

+ 5 - 5
test/src/console/content.spec.ts

@@ -19,10 +19,6 @@ import {
   Widget
 } from 'phosphor/lib/ui/widget';
 
-import {
-  createRenderer
-} from '../../../lib/console/codemirror';
-
 import {
   ConsoleContent
 } from '../../../lib/console/content';
@@ -45,12 +41,16 @@ import {
 
 import {
   createCodeCellRenderer
-} from '../../../lib/notebook/codemirror';
+} from '../notebook/utils';
 
 import {
   defaultRenderMime
 } from '../utils';
 
+import {
+  createRenderer
+} from './utils';
+
 
 class TestContent extends ConsoleContent {
 

+ 4 - 4
test/src/console/foreign.spec.ts

@@ -15,10 +15,6 @@ import {
   Panel
 } from 'phosphor/lib/ui/panel';
 
-import {
-  createCodeCellRenderer
-} from '../../../lib/notebook/codemirror';
-
 import {
   ForeignHandler
 } from '../../../lib/console/foreign';
@@ -27,6 +23,10 @@ import {
   CodeCellModel, CodeCellWidget
 } from '../../../lib/notebook/cells';
 
+import {
+  createCodeCellRenderer
+} from '../notebook/utils';
+
 import {
   defaultRenderMime
 } from '../utils';

+ 4 - 4
test/src/console/panel.spec.ts

@@ -15,10 +15,6 @@ import {
   Widget
 } from 'phosphor/lib/ui/widget';
 
-import {
-  createRenderer
-} from '../../../lib/console/codemirror';
-
 import {
   ConsoleContent
 } from '../../../lib/console/content';
@@ -31,6 +27,10 @@ import {
   defaultRenderMime
 } from '../utils';
 
+import {
+  createRenderer
+} from './utils';
+
 
 class TestPanel extends ConsolePanel {
 

+ 19 - 0
test/src/console/utils.ts

@@ -0,0 +1,19 @@
+// Copyright (c) Jupyter Development Team.
+// Distributed under the terms of the Modified BSD License.
+
+import {
+  editorServices
+} from '../../../lib/codemirror';
+
+import {
+  ConsoleContent
+} from '../../../lib/console';
+
+
+/**
+ * Create a console renderer.
+ */
+export
+function createRenderer(): ConsoleContent.Renderer {
+  return new ConsoleContent.Renderer({ editorServices });
+}

+ 1 - 1
test/src/notebook/cells/editor.spec.ts

@@ -32,7 +32,7 @@ import {
 
 import {
   createCellEditor
-} from '../../../../lib/notebook/codemirror';
+} from '../utils';
 
 
 const UP_ARROW = 38;

+ 4 - 4
test/src/notebook/cells/widget.spec.ts

@@ -21,10 +21,6 @@ import {
   RawCellWidget, CodeCellEditorWidget
 } from '../../../../lib/notebook/cells';
 
-import {
-  createBaseCellRenderer, createCodeCellRenderer, createCellEditor
-} from '../../../../lib/notebook/codemirror';
-
 import {
   OutputAreaWidget
 } from '../../../../lib/notebook/output-area';
@@ -33,6 +29,10 @@ import {
   defaultRenderMime
 } from '../../utils';
 
+import {
+  createBaseCellRenderer, createCodeCellRenderer, createCellEditor
+} from '../utils';
+
 
 const RENDERED_CLASS = 'jp-mod-rendered';
 

+ 1 - 5
test/src/notebook/notebook/actions.spec.ts

@@ -19,10 +19,6 @@ import {
   CodeCellWidget, MarkdownCellWidget, RawCellWidget
 } from '../../../../lib/notebook/cells/widget';
 
-import {
-  createNotebookRenderer
-} from '../../../../lib/notebook/codemirror';
-
 import {
  NotebookModel
 } from '../../../../lib/notebook/notebook/model';
@@ -40,7 +36,7 @@ import {
 } from '../../utils';
 
 import {
-  DEFAULT_CONTENT
+  DEFAULT_CONTENT, createNotebookRenderer
 } from '../utils';
 
 

+ 1 - 5
test/src/notebook/notebook/default-toolbar.spec.ts

@@ -31,10 +31,6 @@ import {
   NotebookActions
 } from '../../../../lib/notebook/notebook/actions';
 
-import {
-  createNotebookPanelRenderer
-} from '../../../../lib/notebook/codemirror';
-
 import {
  ToolbarItems
 } from '../../../../lib/notebook/notebook/default-toolbar';
@@ -63,7 +59,7 @@ import {
 } from '../../utils';
 
 import {
-  DEFAULT_CONTENT
+  DEFAULT_CONTENT, createNotebookPanelRenderer
 } from '../utils';
 
 

+ 1 - 5
test/src/notebook/notebook/panel.spec.ts

@@ -23,10 +23,6 @@ import {
   CompleterWidget
 } from '../../../../lib/completer';
 
-import {
-  createNotebookPanelRenderer
-} from '../../../../lib/notebook/codemirror';
-
 import {
   INotebookModel
 } from '../../../../lib/notebook/notebook/model';
@@ -48,7 +44,7 @@ import {
 } from '../../utils';
 
 import {
-  DEFAULT_CONTENT
+  DEFAULT_CONTENT, createNotebookPanelRenderer
 } from '../utils';
 
 

+ 1 - 5
test/src/notebook/notebook/widget.spec.ts

@@ -28,10 +28,6 @@ import {
   RawCellModel, RawCellWidget, BaseCellWidget
 } from '../../../../lib/notebook/cells';
 
-import {
-  createNotebookRenderer
-} from '../../../../lib/notebook/codemirror';
-
 import {
   INotebookModel, NotebookModel
 } from '../../../../lib/notebook/notebook/model';
@@ -45,7 +41,7 @@ import {
 } from '../../utils';
 
 import {
-  DEFAULT_CONTENT
+  DEFAULT_CONTENT, createNotebookRenderer
 } from '../utils';
 
 

+ 4 - 4
test/src/notebook/notebook/widgetfactory.spec.ts

@@ -11,10 +11,6 @@ import {
   MimeData
 } from 'phosphor/lib/core/mimedata';
 
-import {
-  createNotebookPanelRenderer
-} from '../../../../lib/notebook/codemirror';
-
 import {
   INotebookModel
 } from '../../../../lib/notebook/notebook/model';
@@ -35,6 +31,10 @@ import {
   createNotebookContext, defaultRenderMime
 } from '../../utils';
 
+import {
+  createNotebookPanelRenderer
+} from '../utils';
+
 
 const rendermime = defaultRenderMime();
 const clipboard = new MimeData();

+ 1 - 5
test/src/notebook/tracker.spec.ts

@@ -7,10 +7,6 @@ import {
   MimeData
 } from 'phosphor/lib/core/mimedata';
 
-import {
-  createNotebookPanelRenderer
-} from '../../../lib/notebook/codemirror';
-
 import {
   BaseCellWidget
 } from '../../../lib/notebook/cells';
@@ -28,7 +24,7 @@ import {
 } from '../utils';
 
 import {
-  DEFAULT_CONTENT
+  DEFAULT_CONTENT, createNotebookPanelRenderer
 } from './utils';
 
 

+ 73 - 0
test/src/notebook/utils.ts

@@ -5,9 +5,82 @@ import {
   nbformat
 } from '@jupyterlab/services';
 
+import {
+  editorServices
+} from '../../../lib/codemirror';
+
+import {
+  NotebookPanel, Notebook
+} from '../../../lib/notebook';
+
+import {
+  BaseCellWidget, CodeCellWidget, CodeCellEditorWidget
+} from '../../../lib/notebook/cells';
+
 
 /**
  * The default notebook content.
  */
 export
 const DEFAULT_CONTENT: nbformat.INotebookContent = require('../../../examples/notebook/test.ipynb') as nbformat.INotebookContent;
+
+
+/**
+ * Create a base cell renderer.
+ */
+export
+function createBaseCellRenderer(): BaseCellWidget.Renderer {
+  return new BaseCellWidget.Renderer({
+    editorFactory: host => editorServices.factory.newInlineEditor(host.node, {
+      wordWrap: true
+    })
+  });
+};
+
+
+/**
+ * Create a new code cell renderer.
+ */
+export
+function createCodeCellRenderer(): CodeCellWidget.Renderer {
+  return new CodeCellWidget.Renderer({
+    editorFactory: host => editorServices.factory.newInlineEditor(host.node, {
+      extra: {
+        matchBrackets: true,
+        autoCloseBrackets: true
+      }
+    })
+  });
+}
+
+
+/**
+ * Create a cell editor widget given a factory.
+ */
+export
+function createCellEditor(): CodeCellEditorWidget {
+  return new CodeCellEditorWidget(
+    host => editorServices.factory.newInlineEditor(host.node, {
+      wordWrap: true
+    })
+  );
+}
+
+
+/**
+ * Create a default notebook renderer.
+ */
+export
+function createNotebookRenderer(): Notebook.Renderer {
+  return new Notebook.Renderer({ editorServices });
+}
+
+
+/**
+ * Create a default notebook panel renderer.
+ */
+export
+function createNotebookPanelRenderer(): NotebookPanel.Renderer {
+  const notebookRenderer = createNotebookRenderer();
+  return new NotebookPanel.Renderer({ notebookRenderer });
+}