Explorar o código

Split components into the packages, and plugins into the extensions.

Ian Rose %!s(int64=6) %!d(string=hai) anos
pai
achega
9dfc6e4510
Modificáronse 38 ficheiros con 595 adicións e 693 borrados
  1. 39 2
      packages/codemirror-extension/src/index.ts
  2. 5 1
      packages/codemirror/package.json
  3. 1 0
      packages/codemirror/src/index.ts
  4. 8 75
      packages/codemirror/src/syntaxstatus.tsx
  5. 3 0
      packages/codemirror/tsconfig.json
  6. 1 0
      packages/docmanager-extension/package.json
  7. 73 4
      packages/docmanager-extension/src/index.ts
  8. 3 0
      packages/docmanager-extension/tsconfig.json
  9. 3 1
      packages/docmanager/package.json
  10. 2 0
      packages/docmanager/src/index.ts
  11. 20 49
      packages/docmanager/src/pathstatus.tsx
  12. 4 36
      packages/docmanager/src/savingstatus.tsx
  13. 3 0
      packages/docmanager/tsconfig.json
  14. 1 0
      packages/fileeditor-extension/package.json
  15. 73 2
      packages/fileeditor-extension/src/index.ts
  16. 3 0
      packages/fileeditor-extension/tsconfig.json
  17. 3 1
      packages/fileeditor/package.json
  18. 2 0
      packages/fileeditor/src/index.ts
  19. 4 80
      packages/fileeditor/src/tabspacestatus.tsx
  20. 3 0
      packages/fileeditor/tsconfig.json
  21. 67 5
      packages/notebook-extension/src/index.ts
  22. 1 0
      packages/notebook/package.json
  23. 2 0
      packages/notebook/src/index.ts
  24. 9 89
      packages/notebook/src/modestatus.tsx
  25. 12 87
      packages/notebook/src/truststatus.tsx
  26. 3 0
      packages/notebook/tsconfig.json
  27. 222 14
      packages/statusbar-extension/src/index.ts
  28. 0 0
      packages/statusbar/context.ts
  29. 3 0
      packages/statusbar/package.json
  30. 0 0
      packages/statusbar/settings.ts
  31. 0 3
      packages/statusbar/src/defaults/index.ts
  32. 3 79
      packages/statusbar/src/defaults/kernelStatus.tsx
  33. 3 105
      packages/statusbar/src/defaults/lineCol.tsx
  34. 3 28
      packages/statusbar/src/defaults/memoryUsage.tsx
  35. 3 32
      packages/statusbar/src/defaults/runningSessions.tsx
  36. 1 0
      packages/statusbar/src/index.ts
  37. 0 0
      packages/statusbar/src/style/lineForm.ts
  38. 9 0
      packages/statusbar/tsconfig.json

+ 39 - 2
packages/codemirror-extension/src/index.ts

@@ -11,7 +11,12 @@ import { IMainMenu, IEditMenu } from '@jupyterlab/mainmenu';
 
 import { IEditorServices } from '@jupyterlab/codeeditor';
 
-import { editorServices, CodeMirrorEditor, Mode } from '@jupyterlab/codemirror';
+import {
+  editorServices,
+  EditorSyntaxStatus,
+  CodeMirrorEditor,
+  Mode
+} from '@jupyterlab/codemirror';
 
 import { ISettingRegistry, IStateDB } from '@jupyterlab/coreutils';
 
@@ -19,7 +24,7 @@ import { IDocumentWidget } from '@jupyterlab/docregistry';
 
 import { IEditorTracker, FileEditor } from '@jupyterlab/fileeditor';
 
-import { editorSyntaxStatus } from './syntaxstatus';
+import { IStatusBar } from '@jupyterlab/statusbar';
 
 /**
  * The command IDs used by the codemirror plugin.
@@ -57,6 +62,38 @@ const commands: JupyterLabPlugin<void> = {
   autoStart: true
 };
 
+/**
+ * The JupyterLab plugin for the EditorSyntax status item.
+ */
+export const editorSyntaxStatus: JupyterLabPlugin<void> = {
+  id: '@jupyterlab/codemirror-extension:editor-syntax-status',
+  autoStart: true,
+  requires: [IStatusBar, IEditorTracker],
+  activate: (
+    app: JupyterLab,
+    statusBar: IStatusBar,
+    tracker: IEditorTracker
+  ) => {
+    let item = new EditorSyntaxStatus({ commands: app.commands });
+    app.shell.currentChanged.connect(() => {
+      const current = app.shell.currentWidget;
+      if (current && tracker.has(current)) {
+        item.model.editor = (current as IDocumentWidget<
+          FileEditor
+        >).content.editor;
+      }
+    });
+    statusBar.registerStatusItem('editor-syntax-item', item, {
+      align: 'left',
+      rank: 0,
+      isActive: () =>
+        app.shell.currentWidget &&
+        tracker.currentWidget &&
+        app.shell.currentWidget === tracker.currentWidget
+    });
+  }
+};
+
 /**
  * Export the plugins as default.
  */

+ 5 - 1
packages/codemirror/package.json

@@ -35,11 +35,15 @@
     "@jupyterlab/codeeditor": "^0.19.1",
     "@jupyterlab/coreutils": "^2.2.1",
     "@jupyterlab/observables": "^2.1.1",
+    "@jupyterlab/statusbar": "^0.7.1",
     "@phosphor/algorithm": "^1.1.2",
+    "@phosphor/commands": "^1.6.1",
     "@phosphor/coreutils": "^1.3.0",
     "@phosphor/disposable": "^1.1.2",
     "@phosphor/signaling": "^1.2.2",
-    "codemirror": "~5.39.0"
+    "@phosphor/widgets": "^1.6.0",
+    "codemirror": "~5.39.0",
+    "react": "~16.4.2"
   },
   "devDependencies": {
     "@types/codemirror": "~0.0.46",

+ 1 - 0
packages/codemirror/src/index.ts

@@ -13,6 +13,7 @@ export * from './mode';
 export * from './editor';
 export * from './factory';
 export * from './mimetype';
+export * from './syntaxstatus';
 
 /**
  * The default editor services.

+ 8 - 75
packages/codemirror-extension/src/syntaxstatus.tsx → packages/codemirror/src/syntaxstatus.tsx

@@ -1,26 +1,19 @@
 import React from 'react';
 
-import { JupyterLabPlugin, JupyterLab } from '@jupyterlab/application';
-
 import { VDomRenderer, VDomModel } from '@jupyterlab/apputils';
 
 import { CodeEditor } from '@jupyterlab/codeeditor';
 
 import { IChangedArgs } from '@jupyterlab/coreutils';
 
-import { IDocumentWidget, DocumentRegistry } from '@jupyterlab/docregistry';
-
-import { IEditorTracker, FileEditor } from '@jupyterlab/fileeditor';
-
 import {
-  IStatusBar,
   interactiveItem,
   Popup,
   showPopup,
   TextItem
 } from '@jupyterlab/statusbar';
 
-import { Mode } from '@jupyterlab/codemirror';
+import { Mode } from '.';
 
 import { CommandRegistry } from '@phosphor/commands';
 
@@ -66,21 +59,14 @@ function EditorSyntaxComponent(
 /**
  * StatusBar item to change the language syntax highlighting of the file editor.
  */
-class EditorSyntax extends VDomRenderer<EditorSyntax.Model> {
+export class EditorSyntaxStatus extends VDomRenderer<EditorSyntaxStatus.Model> {
   /**
    * Construct a new VDomRenderer for the status item.
    */
-  constructor(opts: EditorSyntax.IOptions) {
+  constructor(opts: EditorSyntaxStatus.IOptions) {
     super();
-
-    this._tracker = opts.tracker;
+    this.model = new EditorSyntaxStatus.Model();
     this._commands = opts.commands;
-
-    this._tracker.currentChanged.connect(this._onEditorChange);
-    this.model = new EditorSyntax.Model(
-      this._tracker.currentWidget && this._tracker.currentWidget.content.editor
-    );
-
     this.addClass(interactiveItem);
     this.title.caption = 'Change text editor syntax highlighting';
   }
@@ -89,6 +75,9 @@ class EditorSyntax extends VDomRenderer<EditorSyntax.Model> {
    * Render the status item.
    */
   render() {
+    if (!this.model) {
+      return null;
+    }
     return (
       <EditorSyntaxComponent
         mode={this.model.mode}
@@ -97,14 +86,6 @@ class EditorSyntax extends VDomRenderer<EditorSyntax.Model> {
     );
   }
 
-  /**
-   * Dispose of the widget.
-   */
-  dispose() {
-    super.dispose();
-    this._tracker.currentChanged.disconnect(this._onEditorChange);
-  }
-
   /**
    * Create a menu for selecting the mode of the editor.
    */
@@ -142,17 +123,6 @@ class EditorSyntax extends VDomRenderer<EditorSyntax.Model> {
     });
   };
 
-  /**
-   * When the editor changes, update the model.
-   */
-  private _onEditorChange = (
-    tracker: IEditorTracker,
-    editor: IDocumentWidget<FileEditor, DocumentRegistry.IModel> | null
-  ) => {
-    this.model.editor = editor && editor.content.editor;
-  };
-
-  private _tracker: IEditorTracker;
   private _commands: CommandRegistry;
   private _popup: Popup | null = null;
 }
@@ -160,19 +130,11 @@ class EditorSyntax extends VDomRenderer<EditorSyntax.Model> {
 /**
  * A namespace for EditorSyntax statics.
  */
-namespace EditorSyntax {
+export namespace EditorSyntaxStatus {
   /**
    * A VDomModel for the current editor/mode combination.
    */
   export class Model extends VDomModel {
-    /**
-     * Construct a new EditorSyntax model.
-     */
-    constructor(editor: CodeEditor.IEditor | null) {
-      super();
-      this.editor = editor;
-    }
-
     /**
      * The current mode for the editor. If no editor is present,
      * returns the empty string.
@@ -237,38 +199,9 @@ namespace EditorSyntax {
    * Options for the EditorSyntax status item.
    */
   export interface IOptions {
-    /**
-     * The application editor tracker.
-     */
-    tracker: IEditorTracker;
-
     /**
      * The application command registry.
      */
     commands: CommandRegistry;
   }
 }
-
-/**
- * The JupyterLab plugin for the EditorSyntax status item.
- */
-export const editorSyntaxStatus: JupyterLabPlugin<void> = {
-  id: '@jupyterlab/codemirror-extension:editor-syntax-status',
-  autoStart: true,
-  requires: [IStatusBar, IEditorTracker],
-  activate: (
-    app: JupyterLab,
-    statusBar: IStatusBar,
-    tracker: IEditorTracker
-  ) => {
-    let item = new EditorSyntax({ tracker, commands: app.commands });
-    statusBar.registerStatusItem('editor-syntax-item', item, {
-      align: 'left',
-      rank: 0,
-      isActive: () =>
-        app.shell.currentWidget &&
-        tracker.currentWidget &&
-        app.shell.currentWidget === tracker.currentWidget
-    });
-  }
-};

+ 3 - 0
packages/codemirror/tsconfig.json

@@ -17,6 +17,9 @@
     },
     {
       "path": "../observables"
+    },
+    {
+      "path": "../statusbar"
     }
   ]
 }

+ 1 - 0
packages/docmanager-extension/package.json

@@ -38,6 +38,7 @@
     "@jupyterlab/docregistry": "^0.19.1",
     "@jupyterlab/mainmenu": "^0.8.1",
     "@jupyterlab/services": "^3.2.1",
+    "@jupyterlab/statusbar": "^0.7.1",
     "@phosphor/algorithm": "^1.1.2",
     "@phosphor/disposable": "^1.1.2",
     "@phosphor/widgets": "^1.6.0"

+ 73 - 4
packages/docmanager-extension/src/index.ts

@@ -20,7 +20,9 @@ import {
   renameDialog,
   getOpenPath,
   DocumentManager,
-  IDocumentManager
+  IDocumentManager,
+  PathStatus,
+  SavingStatus
 } from '@jupyterlab/docmanager';
 
 import { DocumentRegistry } from '@jupyterlab/docregistry';
@@ -29,6 +31,8 @@ import { IMainMenu } from '@jupyterlab/mainmenu';
 
 import { Contents, Kernel } from '@jupyterlab/services';
 
+import { IStatusBar } from '@jupyterlab/statusbar';
+
 import { IDisposable } from '@phosphor/disposable';
 
 /**
@@ -84,7 +88,7 @@ const pluginId = '@jupyterlab/docmanager-extension:plugin';
 /**
  * The default document manager provider.
  */
-const plugin: JupyterLabPlugin<IDocumentManager> = {
+const docManagerPlugin: JupyterLabPlugin<IDocumentManager> = {
   id: pluginId,
   provides: IDocumentManager,
   requires: [ICommandPalette, IMainMenu, ISettingRegistry],
@@ -156,9 +160,74 @@ const plugin: JupyterLabPlugin<IDocumentManager> = {
 };
 
 /**
- * Export the plugin as default.
+ * A plugin for adding a saving status item to the status bar.
+ */
+export const savingStatusPlugin: JupyterLabPlugin<void> = {
+  id: '@jupyterlab/docmanager-extension:saving-status',
+  autoStart: true,
+  requires: [IStatusBar, IDocumentManager],
+  activate: (
+    app: JupyterLab,
+    statusBar: IStatusBar,
+    docManager: IDocumentManager
+  ) => {
+    let item = new SavingStatus({ docManager });
+
+    // Keep the currently active widget synchronized.
+    item.model!.widget = app.shell.currentWidget;
+    app.shell.currentChanged.connect(
+      () => (item.model!.widget = app.shell.currentWidget)
+    );
+
+    statusBar.registerStatusItem('saving-status', item, {
+      align: 'middle',
+      isActive: () => {
+        return true;
+      },
+      stateChanged: item.model!.stateChanged
+    });
+  }
+};
+
+/**
+ * A plugin providing a file path widget to the status bar.
+ */
+export const pathStatusPlugin: JupyterLabPlugin<void> = {
+  id: '@jupyterlab/docmanager-extension:path-status',
+  autoStart: true,
+  requires: [IStatusBar, IDocumentManager],
+  activate: (
+    app: JupyterLab,
+    statusBar: IStatusBar,
+    docManager: IDocumentManager
+  ) => {
+    let item = new PathStatus({ docManager });
+
+    // Keep the file path widget up-to-date with the application active widget.
+    item.model!.widget = app.shell.currentWidget;
+    app.shell.currentChanged.connect(() => {
+      item.model!.widget = app.shell.currentWidget;
+    });
+
+    statusBar.registerStatusItem('path-status', item, {
+      align: 'right',
+      rank: 0,
+      isActive: () => {
+        return true;
+      }
+    });
+  }
+};
+
+/**
+ * Export the plugins as default.
  */
-export default plugin;
+const plugins: JupyterLabPlugin<any>[] = [
+  docManagerPlugin,
+  pathStatusPlugin,
+  savingStatusPlugin
+];
+export default plugins;
 
 /* Widget to display the revert to checkpoint confirmation. */
 class RevertConfirmWidget extends Widget {

+ 3 - 0
packages/docmanager-extension/tsconfig.json

@@ -26,6 +26,9 @@
     },
     {
       "path": "../services"
+    },
+    {
+      "path": "../statusbar"
     }
   ]
 }

+ 3 - 1
packages/docmanager/package.json

@@ -34,13 +34,15 @@
     "@jupyterlab/coreutils": "^2.2.1",
     "@jupyterlab/docregistry": "^0.19.1",
     "@jupyterlab/services": "^3.2.1",
+    "@jupyterlab/statusbar": "^0.7.1",
     "@phosphor/algorithm": "^1.1.2",
     "@phosphor/coreutils": "^1.3.0",
     "@phosphor/disposable": "^1.1.2",
     "@phosphor/messaging": "^1.2.2",
     "@phosphor/properties": "^1.1.2",
     "@phosphor/signaling": "^1.2.2",
-    "@phosphor/widgets": "^1.6.0"
+    "@phosphor/widgets": "^1.6.0",
+    "react": "~16.4.2"
   },
   "devDependencies": {
     "rimraf": "~2.6.2",

+ 2 - 0
packages/docmanager/src/index.ts

@@ -4,4 +4,6 @@
 export * from './dialogs';
 export * from './manager';
 export * from './savehandler';
+export * from './savingstatus';
+export * from './pathstatus';
 export * from './widgetmanager';

+ 20 - 49
packages/statusbar-extension/src/defaults/filePath.tsx → packages/docmanager/src/pathstatus.tsx

@@ -3,26 +3,24 @@
 
 import React from 'react';
 
-import { JupyterLabPlugin, JupyterLab } from '@jupyterlab/application';
-
 import { VDomModel, VDomRenderer } from '@jupyterlab/apputils';
 
 import { PathExt } from '@jupyterlab/coreutils';
 
-import { IDocumentManager } from '@jupyterlab/docmanager';
+import { IDocumentManager } from './manager';
 
 import { DocumentRegistry } from '@jupyterlab/docregistry';
 
-import { IStatusBar, TextItem } from '@jupyterlab/statusbar';
+import { TextItem } from '@jupyterlab/statusbar';
 
 import { Widget, Title } from '@phosphor/widgets';
 
 /**
- * A namespace for FilePathComponent statics.
+ * A namespace for PathStatusComponent statics.
  */
-namespace FilePathComponent {
+namespace PathStatusComponent {
   /**
-   * The props for rendering a FilePathComponent.
+   * The props for rendering a PathStatusComponent.
    */
   export interface IProps {
     /**
@@ -44,23 +42,23 @@ namespace FilePathComponent {
  *
  * @returns a tsx component for a file path.
  */
-function FilePathComponent(
-  props: FilePathComponent.IProps
-): React.ReactElement<FilePathComponent.IProps> {
+function PathStatusComponent(
+  props: PathStatusComponent.IProps
+): React.ReactElement<PathStatusComponent.IProps> {
   return <TextItem source={props.name} title={props.fullPath} />;
 }
 
 /**
  * A status bar item for the current file path (or activity name).
  */
-class FilePath extends VDomRenderer<FilePath.Model> {
+export class PathStatus extends VDomRenderer<PathStatus.Model> {
   /**
-   * Construct a new FilePath status item.
+   * Construct a new PathStatus status item.
    */
-  constructor(opts: FilePath.IOptions) {
+  constructor(opts: PathStatus.IOptions) {
     super();
     this._docManager = opts.docManager;
-    this.model = new FilePath.Model(this._docManager);
+    this.model = new PathStatus.Model(this._docManager);
     this.node.title = this.model.path;
   }
 
@@ -69,7 +67,10 @@ class FilePath extends VDomRenderer<FilePath.Model> {
    */
   render() {
     return (
-      <FilePathComponent fullPath={this.model!.path} name={this.model!.name!} />
+      <PathStatusComponent
+        fullPath={this.model!.path}
+        name={this.model!.name!}
+      />
     );
   }
 
@@ -77,11 +78,11 @@ class FilePath extends VDomRenderer<FilePath.Model> {
 }
 
 /**
- * A namespace for FilePath statics.
+ * A namespace for PathStatus statics.
  */
-namespace FilePath {
+export namespace PathStatus {
   /**
-   * A VDomModel for rendering the FilePath status item.
+   * A VDomModel for rendering the PathStatus status item.
    */
   export class Model extends VDomModel {
     /**
@@ -198,7 +199,7 @@ namespace FilePath {
   }
 
   /**
-   * Options for creating the FilePath widget.
+   * Options for creating the PathStatus widget.
    */
   export interface IOptions {
     /**
@@ -207,33 +208,3 @@ namespace FilePath {
     docManager: IDocumentManager;
   }
 }
-
-/**
- * A plugin providing a file path widget to the status bar.
- */
-export const filePathStatus: JupyterLabPlugin<void> = {
-  id: '@jupyterlab/statusbar:file-path-status',
-  autoStart: true,
-  requires: [IStatusBar, IDocumentManager],
-  activate: (
-    app: JupyterLab,
-    statusBar: IStatusBar,
-    docManager: IDocumentManager
-  ) => {
-    let item = new FilePath({ docManager });
-
-    // Keep the file path widget up-to-date with the application active widget.
-    item.model!.widget = app.shell.currentWidget;
-    app.shell.currentChanged.connect(() => {
-      item.model!.widget = app.shell.currentWidget;
-    });
-
-    statusBar.registerStatusItem('file-path-item', item, {
-      align: 'right',
-      rank: 0,
-      isActive: () => {
-        return true;
-      }
-    });
-  }
-};

+ 4 - 36
packages/statusbar-extension/src/defaults/savingStatus.tsx → packages/docmanager/src/savingstatus.tsx

@@ -3,15 +3,13 @@
 
 import React from 'react';
 
-import { JupyterLabPlugin, JupyterLab } from '@jupyterlab/application';
-
 import { VDomModel, VDomRenderer } from '@jupyterlab/apputils';
 
-import { IDocumentManager } from '@jupyterlab/docmanager';
+import { IDocumentManager } from './manager';
 
 import { DocumentRegistry } from '@jupyterlab/docregistry';
 
-import { IStatusBar, TextItem } from '@jupyterlab/statusbar';
+import { TextItem } from '@jupyterlab/statusbar';
 
 import { Widget } from '@phosphor/widgets';
 
@@ -52,7 +50,7 @@ const SAVING_COMPLETE_MESSAGE_MILLIS = 2000;
 /**
  * A VDomRenderer for a saving status item.
  */
-class SavingStatus extends VDomRenderer<SavingStatus.Model> {
+export class SavingStatus extends VDomRenderer<SavingStatus.Model> {
   /**
    * Create a new SavingStatus item.
    */
@@ -79,7 +77,7 @@ class SavingStatus extends VDomRenderer<SavingStatus.Model> {
 /**
  * A namespace for SavingStatus statics.
  */
-namespace SavingStatus {
+export namespace SavingStatus {
   /**
    * A VDomModel for the SavingStatus item.
    */
@@ -165,33 +163,3 @@ namespace SavingStatus {
     docManager: IDocumentManager;
   }
 }
-
-/**
- * A plugin for adding a saving status item to the status bar.
- */
-export const savingStatusItem: JupyterLabPlugin<void> = {
-  id: '@jupyterlab/statusbar:saving-status-item',
-  autoStart: true,
-  requires: [IStatusBar, IDocumentManager],
-  activate: (
-    app: JupyterLab,
-    statusBar: IStatusBar,
-    docManager: IDocumentManager
-  ) => {
-    let item = new SavingStatus({ docManager });
-
-    // Keep the currently active widget synchronized.
-    item.model!.widget = app.shell.currentWidget;
-    app.shell.currentChanged.connect(
-      () => (item.model!.widget = app.shell.currentWidget)
-    );
-
-    statusBar.registerStatusItem('saving-status-item', item, {
-      align: 'middle',
-      isActive: () => {
-        return true;
-      },
-      stateChanged: item.model!.stateChanged
-    });
-  }
-};

+ 3 - 0
packages/docmanager/tsconfig.json

@@ -17,6 +17,9 @@
     },
     {
       "path": "../services"
+    },
+    {
+      "path": "../statusbar"
     }
   ]
 }

+ 1 - 0
packages/fileeditor-extension/package.json

@@ -41,6 +41,7 @@
     "@jupyterlab/fileeditor": "^0.19.1",
     "@jupyterlab/launcher": "^0.19.1",
     "@jupyterlab/mainmenu": "^0.8.1",
+    "@jupyterlab/statusbar": "^0.7.1",
     "@phosphor/coreutils": "^1.3.0",
     "@phosphor/widgets": "^1.6.0"
   },

+ 73 - 2
packages/fileeditor-extension/src/index.ts

@@ -26,7 +26,8 @@ import { IFileBrowserFactory } from '@jupyterlab/filebrowser';
 import {
   FileEditor,
   FileEditorFactory,
-  IEditorTracker
+  IEditorTracker,
+  TabSpaceStatus
 } from '@jupyterlab/fileeditor';
 
 import { ILauncher } from '@jupyterlab/launcher';
@@ -39,6 +40,8 @@ import {
   IViewMenu
 } from '@jupyterlab/mainmenu';
 
+import { IStatusBar } from '@jupyterlab/statusbar';
+
 import { JSONObject } from '@phosphor/coreutils';
 
 import { Menu } from '@phosphor/widgets';
@@ -103,10 +106,78 @@ const plugin: JupyterLabPlugin<IEditorTracker> = {
   autoStart: true
 };
 
+/**
+ * A plugin that provides a status item allowing the user to
+ * switch tabs vs spaces and tab widths for text editors.
+ */
+export const tabSpaceStatus: JupyterLabPlugin<void> = {
+  id: '@jupyterlab/fileeditor-extension:tab-space-item',
+  autoStart: true,
+  requires: [IStatusBar, IEditorTracker, ISettingRegistry],
+  activate: (
+    app: JupyterLab,
+    statusBar: IStatusBar,
+    editorTracker: IEditorTracker,
+    settingRegistry: ISettingRegistry
+  ) => {
+    // Create a menu for switching tabs vs spaces.
+    const menu = new Menu({ commands: app.commands });
+    const command = 'fileeditor:change-tabs';
+    const args: JSONObject = {
+      insertSpaces: false,
+      size: 4,
+      name: 'Indent with Tab'
+    };
+    menu.addItem({ command, args });
+    for (let size of [1, 2, 4, 8]) {
+      let args: JSONObject = {
+        insertSpaces: true,
+        size,
+        name: `Spaces: ${size} `
+      };
+      menu.addItem({ command, args });
+    }
+
+    // Create the status item.
+    const item = new TabSpaceStatus({ menu });
+
+    // Keep a reference to the code editor config from the settings system.
+    const updateSettings = (settings: ISettingRegistry.ISettings): void => {
+      const cached = settings.get('editorConfig').composite as Partial<
+        CodeEditor.IConfig
+      >;
+      const config: CodeEditor.IConfig = {
+        ...CodeEditor.defaultConfig,
+        ...cached
+      };
+      item.model!.config = config;
+    };
+    Promise.all([
+      settingRegistry.load('@jupyterlab/fileeditor-extension:plugin'),
+      app.restored
+    ]).then(([settings]) => {
+      updateSettings(settings);
+      settings.changed.connect(updateSettings);
+    });
+
+    // Add the status item.
+    statusBar.registerStatusItem('tab-space-item', item, {
+      align: 'right',
+      rank: 1,
+      isActive: () => {
+        return (
+          app.shell.currentWidget && editorTracker.has(app.shell.currentWidget)
+        );
+      }
+    });
+  }
+};
+
 /**
  * Export the plugins as default.
  */
-export default plugin;
+const plugins: JupyterLabPlugin<any>[] = [plugin, tabSpaceStatus];
+export default plugins;
 
 /**
  * Activate the editor tracker plugin.

+ 3 - 0
packages/fileeditor-extension/tsconfig.json

@@ -35,6 +35,9 @@
     },
     {
       "path": "../mainmenu"
+    },
+    {
+      "path": "../statusbar"
     }
   ]
 }

+ 3 - 1
packages/fileeditor/package.json

@@ -34,9 +34,11 @@
     "@jupyterlab/apputils": "^0.19.1",
     "@jupyterlab/codeeditor": "^0.19.1",
     "@jupyterlab/docregistry": "^0.19.1",
+    "@jupyterlab/statusbar": "^0.7.1",
     "@phosphor/coreutils": "^1.3.0",
     "@phosphor/messaging": "^1.2.2",
-    "@phosphor/widgets": "^1.6.0"
+    "@phosphor/widgets": "^1.6.0",
+    "react": "~16.4.2"
   },
   "devDependencies": {
     "rimraf": "~2.6.2",

+ 2 - 0
packages/fileeditor/src/index.ts

@@ -13,6 +13,8 @@ import '../style/index.css';
 
 export * from './widget';
 
+export * from './tabspacestatus';
+
 /**
  * A class that tracks editor widgets.
  */

+ 4 - 80
packages/statusbar-extension/src/defaults/tabSpace.tsx → packages/fileeditor/src/tabspacestatus.tsx

@@ -3,18 +3,11 @@
 
 import React from 'react';
 
-import { JupyterLabPlugin, JupyterLab } from '@jupyterlab/application';
-
 import { VDomRenderer, VDomModel } from '@jupyterlab/apputils';
 
 import { CodeEditor } from '@jupyterlab/codeeditor';
 
-import { ISettingRegistry } from '@jupyterlab/coreutils';
-
-import { IEditorTracker } from '@jupyterlab/fileeditor';
-
 import {
-  IStatusBar,
   interactiveItem,
   clickedItem,
   Popup,
@@ -22,12 +15,8 @@ import {
   TextItem
 } from '@jupyterlab/statusbar';
 
-import { JSONObject } from '@phosphor/coreutils';
-
 import { Menu } from '@phosphor/widgets';
 
-import { IStatusContext } from '../context';
-
 /**
  * A namespace for TabSpaceComponent statics.
  */
@@ -73,14 +62,14 @@ function TabSpaceComponent(
 /**
  * A VDomRenderer for a tabs vs. spaces status item.
  */
-class TabSpace extends VDomRenderer<TabSpace.Model> {
+export class TabSpaceStatus extends VDomRenderer<TabSpaceStatus.Model> {
   /**
    * Create a new tab/space status item.
    */
-  constructor(options: TabSpace.IOptions) {
+  constructor(options: TabSpaceStatus.IOptions) {
     super();
     this._menu = options.menu;
-    this.model = new TabSpace.Model();
+    this.model = new TabSpaceStatus.Model();
     this.addClass(interactiveItem);
   }
 
@@ -133,7 +122,7 @@ class TabSpace extends VDomRenderer<TabSpace.Model> {
 /**
  * A namespace for TabSpace statics.
  */
-namespace TabSpace {
+export namespace TabSpaceStatus {
   /**
    * A VDomModel for the TabSpace status item.
    */
@@ -177,68 +166,3 @@ namespace TabSpace {
     menu: Menu;
   }
 }
-
-/**
- * A plugin that provides a status item allowing the user to
- * switch tabs vs spaces and tab widths for text editors.
- */
-export const tabSpaceItem: JupyterLabPlugin<void> = {
-  id: '@jupyterlab/statusbar:tab-space-item',
-  autoStart: true,
-  requires: [IStatusBar, IEditorTracker, ISettingRegistry],
-  activate: (
-    app: JupyterLab,
-    statusBar: IStatusBar,
-    editorTracker: IEditorTracker,
-    settingRegistry: ISettingRegistry
-  ) => {
-    // Create a menu for switching tabs vs spaces.
-    const menu = new Menu({ commands: app.commands });
-    const command = 'fileeditor:change-tabs';
-    const args: JSONObject = {
-      insertSpaces: false,
-      size: 4,
-      name: 'Indent with Tab'
-    };
-    menu.addItem({ command, args });
-    for (let size of [1, 2, 4, 8]) {
-      let args: JSONObject = {
-        insertSpaces: true,
-        size,
-        name: `Spaces: ${size} `
-      };
-      menu.addItem({ command, args });
-    }
-
-    // Create the status item.
-    const item = new TabSpace({ menu });
-
-    // Keep a reference to the code editor config from the settings system.
-    const updateSettings = (settings: ISettingRegistry.ISettings): void => {
-      const cached = settings.get('editorConfig').composite as Partial<
-        CodeEditor.IConfig
-      >;
-      const config: CodeEditor.IConfig = {
-        ...CodeEditor.defaultConfig,
-        ...cached
-      };
-      item.model!.config = config;
-    };
-    Promise.all([
-      settingRegistry.load('@jupyterlab/fileeditor-extension:plugin'),
-      app.restored
-    ]).then(([settings]) => {
-      updateSettings(settings);
-      settings.changed.connect(updateSettings);
-    });
-
-    // Add the status item.
-    statusBar.registerStatusItem('tab-space-item', item, {
-      align: 'right',
-      rank: 1,
-      isActive: IStatusContext.delegateActive(app.shell, [
-        { tracker: editorTracker }
-      ])
-    });
-  }
-};

+ 3 - 0
packages/fileeditor/tsconfig.json

@@ -14,6 +14,9 @@
     },
     {
       "path": "../docregistry"
+    },
+    {
+      "path": "../statusbar"
     }
   ]
 }

+ 67 - 5
packages/notebook-extension/src/index.ts

@@ -50,23 +50,23 @@ import {
   NotebookPanel,
   NotebookTracker,
   NotebookWidgetFactory,
-  StaticNotebook
+  StaticNotebook,
+  CommandEditStatus,
+  NotebookTrustStatus
 } from '@jupyterlab/notebook';
 
 import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
 
 import { ServiceManager } from '@jupyterlab/services';
 
+import { IStatusBar } from '@jupyterlab/statusbar';
+
 import { ReadonlyJSONObject, JSONValue } from '@phosphor/coreutils';
 
 import { Message, MessageLoop } from '@phosphor/messaging';
 
 import { Menu } from '@phosphor/widgets';
 
-import { commandEditItem } from './modestatus';
-
-import { notebookTrustItem } from './truststatus';
-
 /**
  * The command IDs used by the notebook plugin.
  */
@@ -285,6 +285,68 @@ const tools: JupyterLabPlugin<ICellTools> = {
   requires: [INotebookTracker, IEditorServices, IStateDB]
 };
 
+/**
+ * A plugin providing a CommandEdit status item.
+ */
+export const commandEditItem: JupyterLabPlugin<void> = {
+  id: '@jupyterlab/notebook-extension:mode-status',
+  autoStart: true,
+  requires: [IStatusBar, INotebookTracker],
+  activate: (
+    app: JupyterLab,
+    statusBar: IStatusBar,
+    tracker: INotebookTracker
+  ) => {
+    const item = new CommandEditStatus();
+
+    // Keep the status item up-to-date with the current notebook.
+    tracker.currentChanged.connect(() => {
+      const current = tracker.currentWidget;
+      item.model.notebook = current.content;
+    });
+
+    statusBar.registerStatusItem('command-edit-item', item, {
+      align: 'right',
+      rank: 4,
+      isActive: () =>
+        app.shell.currentWidget &&
+        tracker.currentWidget &&
+        app.shell.currentWidget === tracker.currentWidget
+    });
+  }
+};
+
+/**
+ * A plugin that adds a notebook trust status item to the status bar.
+ */
+export const notebookTrustItem: JupyterLabPlugin<void> = {
+  id: '@jupyterlab/notebook-extension:trust-status',
+  autoStart: true,
+  requires: [IStatusBar, INotebookTracker],
+  activate: (
+    app: JupyterLab,
+    statusBar: IStatusBar,
+    tracker: INotebookTracker
+  ) => {
+    const item = new NotebookTrustStatus();
+
+    // Keep the status item up-to-date with the current notebook.
+    tracker.currentChanged.connect(() => {
+      const current = tracker.currentWidget;
+      item.model.notebook = current.content;
+    });
+
+    statusBar.registerStatusItem('notebook-trust-item', item, {
+      align: 'right',
+      rank: 3,
+      isActive: () =>
+        app.shell.currentWidget &&
+        tracker.currentWidget &&
+        app.shell.currentWidget === tracker.currentWidget
+    });
+  }
+};
+
 /**
  * Export the plugins as default.
  */

+ 1 - 0
packages/notebook/package.json

@@ -39,6 +39,7 @@
     "@jupyterlab/observables": "^2.1.1",
     "@jupyterlab/rendermime": "^0.19.1",
     "@jupyterlab/services": "^3.2.1",
+    "@jupyterlab/statusbar": "^0.7.1",
     "@phosphor/algorithm": "^1.1.2",
     "@phosphor/coreutils": "^1.3.0",
     "@phosphor/domutils": "^1.1.2",

+ 2 - 0
packages/notebook/src/index.ts

@@ -12,3 +12,5 @@ export * from './panel';
 export * from './tracker';
 export * from './widget';
 export * from './widgetfactory';
+export * from './modestatus';
+export * from './truststatus';

+ 9 - 89
packages/notebook-extension/src/modestatus.tsx → packages/notebook/src/modestatus.tsx

@@ -1,19 +1,12 @@
 import * as React from 'react';
 
-import { JupyterLabPlugin, JupyterLab } from '@jupyterlab/application';
-
 import { VDomRenderer, VDomModel } from '@jupyterlab/apputils';
 
 import { Text } from '@jupyterlab/coreutils';
 
-import {
-  INotebookTracker,
-  Notebook,
-  NotebookPanel,
-  NotebookMode
-} from '@jupyterlab/notebook';
+import { Notebook, NotebookMode } from '.';
 
-import { IStatusBar, TextItem } from '@jupyterlab/statusbar';
+import { TextItem } from '@jupyterlab/statusbar';
 
 /**
  * A pure function for rendering a Command/Edit mode component.
@@ -46,74 +39,35 @@ namespace CommandEditComponent {
 /**
  * StatusBar item to display which notebook mode user is in.
  */
-class CommandEdit extends VDomRenderer<CommandEdit.Model> {
+export class CommandEditStatus extends VDomRenderer<CommandEditStatus.Model> {
   /**
    * Construct a new CommandEdit status item.
    */
-  constructor(opts: CommandEdit.IOptions) {
+  constructor() {
     super();
-    this._tracker = opts.tracker;
-
-    this._tracker.currentChanged.connect(
-      this._onNotebookChange,
-      this
-    );
-
-    this.model = new CommandEdit.Model(
-      this._tracker.currentWidget && this._tracker.currentWidget.content
-    );
-    this.title.caption = `Notebook is in ${this.model.notebookMode} mode`;
+    this.model = new CommandEditStatus.Model();
   }
 
   /**
    * Render the CommandEdit status item.
    */
   render() {
+    if (!this.model) {
+      return null;
+    }
     this.node.title = `Notebook is in ${this.model.notebookMode} mode`;
     return <CommandEditComponent notebookMode={this.model.notebookMode} />;
   }
-
-  /**
-   * Dispose of the status item.
-   */
-  dispose() {
-    super.dispose();
-    this._tracker.currentChanged.disconnect(this._onNotebookChange, this);
-  }
-
-  /**
-   * Update the model when the tracker current widget changes.
-   */
-  private _onNotebookChange(
-    tracker: INotebookTracker,
-    notebook: NotebookPanel | null
-  ): void {
-    if (notebook === null) {
-      this.model.notebook = null;
-    } else {
-      this.model.notebook = notebook.content;
-    }
-  }
-
-  private _tracker: INotebookTracker;
 }
 
 /**
  * A namespace for CommandEdit statics.
  */
-namespace CommandEdit {
+export namespace CommandEditStatus {
   /**
    * A VDomModle for the CommandEdit renderer.
    */
   export class Model extends VDomModel {
-    /**
-     * Construct a new CommandEdit model.
-     */
-    constructor(notebook: Notebook | null) {
-      super();
-      this.notebook = notebook;
-    }
-
     /**
      * The current mode of the current notebook.
      */
@@ -180,38 +134,4 @@ namespace CommandEdit {
     private _notebookMode: NotebookMode = 'command';
     private _notebook: Notebook | null = null;
   }
-
-  /**
-   * Options for creating a CommandEdit status item.
-   */
-  export interface IOptions {
-    tracker: INotebookTracker;
-  }
 }
-
-/**
- * A plugin providing a CommandEdit status item.
- */
-export const commandEditItem: JupyterLabPlugin<void> = {
-  id: '@jupyterlab/notebook-extension:mode-status',
-  autoStart: true,
-  requires: [IStatusBar, INotebookTracker],
-  activate: (
-    app: JupyterLab,
-    statusBar: IStatusBar,
-    tracker: INotebookTracker
-  ) => {
-    const item = new CommandEdit({
-      tracker
-    });
-
-    statusBar.registerStatusItem('command-edit-item', item, {
-      align: 'right',
-      rank: 4,
-      isActive: () =>
-        app.shell.currentWidget &&
-        tracker.currentWidget &&
-        app.shell.currentWidget === tracker.currentWidget
-    });
-  }
-};

+ 12 - 87
packages/notebook-extension/src/truststatus.tsx → packages/notebook/src/truststatus.tsx

@@ -1,19 +1,12 @@
 import React from 'react';
 
-import { JupyterLabPlugin, JupyterLab } from '@jupyterlab/application';
-
 import { VDomRenderer, VDomModel } from '@jupyterlab/apputils';
 
-import {
-  INotebookTracker,
-  NotebookPanel,
-  INotebookModel,
-  Notebook
-} from '@jupyterlab/notebook';
+import { INotebookModel, Notebook } from '.';
 
 import { Cell } from '@jupyterlab/cells';
 
-import { IconItem, IStatusBar } from '@jupyterlab/statusbar';
+import { IconItem } from '@jupyterlab/statusbar';
 
 import { toArray } from '@phosphor/algorithm';
 
@@ -21,7 +14,7 @@ import { toArray } from '@phosphor/algorithm';
  * Determine the notebook trust status message.
  */
 function cellTrust(
-  props: NotebookTrustComponent.IProps | NotebookTrust.Model
+  props: NotebookTrustComponent.IProps | NotebookTrustStatus.Model
 ): string[] {
   if (props.trustedCells === props.totalCells) {
     return [
@@ -94,28 +87,24 @@ namespace NotebookTrustComponent {
 /**
  * The NotebookTrust status item.
  */
-class NotebookTrust extends VDomRenderer<NotebookTrust.Model> {
+export class NotebookTrustStatus extends VDomRenderer<
+  NotebookTrustStatus.Model
+> {
   /**
    * Construct a new status item.
    */
-  constructor(opts: NotebookTrust.IOptions) {
+  constructor() {
     super();
-    this._tracker = opts.tracker;
-    this._tracker.currentChanged.connect(
-      this._onNotebookChange,
-      this
-    );
-    this.model = new NotebookTrust.Model(
-      this._tracker.currentWidget && this._tracker.currentWidget.content
-    );
-
-    this.title.caption = cellTrust(this.model)[0];
+    this.model = new NotebookTrustStatus.Model();
   }
 
   /**
    * Render the NotebookTrust status item.
    */
   render() {
+    if (!this.model) {
+      return null;
+    }
     this.node.title = cellTrust(this.model)[0];
     return (
       <div>
@@ -128,48 +117,16 @@ class NotebookTrust extends VDomRenderer<NotebookTrust.Model> {
       </div>
     );
   }
-
-  /**
-   * Dispose of the notebook trust item.
-   */
-  dispose() {
-    super.dispose();
-    this._tracker.currentChanged.disconnect(this._onNotebookChange, this);
-  }
-
-  /**
-   * When update the trust model when the notebook changes.
-   */
-  private _onNotebookChange(
-    tracker: INotebookTracker,
-    notebook: NotebookPanel | null
-  ): void {
-    if (notebook === null) {
-      this.model.notebook = null;
-    } else {
-      this.model.notebook = notebook.content;
-    }
-  }
-
-  private _tracker: INotebookTracker;
 }
 
 /**
  * A namespace for NotebookTrust statics.
  */
-namespace NotebookTrust {
+export namespace NotebookTrustStatus {
   /**
    * A VDomModel for the NotebookTrust status item.
    */
   export class Model extends VDomModel {
-    /**
-     * Construct a new NotebookTrust model.
-     */
-    constructor(notebook: Notebook | null) {
-      super();
-      this.notebook = notebook;
-    }
-
     /**
      * The number of trusted cells in the current notebook.
      */
@@ -320,36 +277,4 @@ namespace NotebookTrust {
     private _activeCellTrusted: boolean = false;
     private _notebook: Notebook | null = null;
   }
-
-  /**
-   * Options for creating a NotebookTrust status item.
-   */
-  export interface IOptions {
-    tracker: INotebookTracker;
-  }
 }
-
-/**
- * A plugin that adds a notebook trust status item to the status bar.
- */
-export const notebookTrustItem: JupyterLabPlugin<void> = {
-  id: '@jupyterlab/notebook-extension:trust-status',
-  autoStart: true,
-  requires: [IStatusBar, INotebookTracker],
-  activate: (
-    app: JupyterLab,
-    statusBar: IStatusBar,
-    tracker: INotebookTracker
-  ) => {
-    const item = new NotebookTrust({ tracker });
-
-    statusBar.registerStatusItem('notebook-trust-item', item, {
-      align: 'right',
-      rank: 3,
-      isActive: () =>
-        app.shell.currentWidget &&
-        tracker.currentWidget &&
-        app.shell.currentWidget === tracker.currentWidget
-    });
-  }
-};

+ 3 - 0
packages/notebook/tsconfig.json

@@ -29,6 +29,9 @@
     },
     {
       "path": "../services"
+    },
+    {
+      "path": "../statusbar"
     }
   ]
 }

+ 222 - 14
packages/statusbar-extension/src/index.ts

@@ -6,19 +6,36 @@ import '../style/index.css';
 
 import { JupyterLab, JupyterLabPlugin } from '@jupyterlab/application';
 
-import { IStatusBar, StatusBar } from '@jupyterlab/statusbar';
+import { IClientSession } from '@jupyterlab/apputils';
 
-// Export default status bar items
+import { Cell, CodeCell } from '@jupyterlab/cells';
 
 import {
-  lineColItem,
-  kernelStatus,
-  runningSessionsItem,
-  filePathStatus,
-  tabSpaceItem,
-  memoryUsageItem,
-  savingStatusItem
-} from './defaults';
+  CodeConsole,
+  ConsolePanel,
+  IConsoleTracker
+} from '@jupyterlab/console';
+
+import { IDocumentWidget } from '@jupyterlab/docregistry';
+
+import { FileEditor, IEditorTracker } from '@jupyterlab/fileeditor';
+
+import {
+  INotebookTracker,
+  Notebook,
+  NotebookPanel
+} from '@jupyterlab/notebook';
+
+import {
+  IStatusBar,
+  KernelStatus,
+  LineCol,
+  MemoryUsage,
+  RunningSessions,
+  StatusBar
+} from '@jupyterlab/statusbar';
+
+import { Title, Widget } from '@phosphor/widgets';
 
 export const STATUSBAR_PLUGIN_ID = '@jupyterlab/statusbar-extension:plugin';
 
@@ -42,15 +59,206 @@ const statusBar: JupyterLabPlugin<IStatusBar> = {
   }
 };
 
+/**
+ * A plugin that provides a kernel status item to the status bar.
+ */
+export const kernelStatus: JupyterLabPlugin<void> = {
+  id: '@jupyterlab/statusbar:kernel-status',
+  autoStart: true,
+  requires: [IStatusBar, INotebookTracker, IConsoleTracker],
+  activate: (
+    app: JupyterLab,
+    statusBar: IStatusBar,
+    notebookTracker: INotebookTracker,
+    consoleTracker: IConsoleTracker
+  ) => {
+    // When the status item is clicked, launch the kernel
+    // selection dialog for the current session.
+    let currentSession: IClientSession | null = null;
+    const changeKernel = () => {
+      if (!currentSession) {
+        return;
+      }
+      currentSession.selectKernel();
+    };
+
+    // Create the status item.
+    const item = new KernelStatus({
+      onClick: changeKernel
+    });
+
+    // When the title of the active widget changes, update the label
+    // of the hover text.
+    const onTitleChanged = (title: Title<Widget>) => {
+      item.model!.activityName = title.label;
+    };
+
+    // Keep the session object on the status item up-to-date.
+    app.shell.currentChanged.connect((shell, change) => {
+      const { oldValue, newValue } = change;
+
+      // Clean up after the old value if it exists,
+      // listen for changes to the title of the activity
+      if (oldValue) {
+        oldValue.title.changed.disconnect(onTitleChanged);
+      }
+      if (newValue) {
+        newValue.title.changed.connect(onTitleChanged);
+      }
+
+      // Grab the session off of the current widget, if it exists.
+      if (newValue && consoleTracker.has(newValue)) {
+        currentSession = (newValue as ConsolePanel).session;
+      } else if (newValue && notebookTracker.has(newValue)) {
+        currentSession = (newValue as NotebookPanel).session;
+      } else {
+        currentSession = null;
+      }
+      item.model!.session = currentSession;
+    });
+
+    statusBar.registerStatusItem('kernel-status-item', item, {
+      align: 'left',
+      rank: 1,
+      isActive: () => {
+        const current = app.shell.currentWidget;
+        return (
+          current &&
+          (notebookTracker.has(current) || consoleTracker.has(current))
+        );
+      }
+    });
+  }
+};
+
+/**
+ * A plugin providing a line/column status item to the application.
+ */
+export const lineColItem: JupyterLabPlugin<void> = {
+  id: '@jupyterlab/statusbar:line-col-item',
+  autoStart: true,
+  requires: [IStatusBar, INotebookTracker, IEditorTracker, IConsoleTracker],
+  activate: (
+    app: JupyterLab,
+    statusBar: IStatusBar,
+    notebookTracker: INotebookTracker,
+    editorTracker: IEditorTracker,
+    consoleTracker: IConsoleTracker
+  ) => {
+    const item = new LineCol();
+
+    const onActiveCellChanged = (notebook: Notebook, cell: Cell) => {
+      item.model!.editor = cell && cell.editor;
+    };
+
+    const onPromptCreated = (console: CodeConsole, prompt: CodeCell) => {
+      item.model!.editor = prompt && prompt.editor;
+    };
+
+    app.shell.currentChanged.connect((shell, change) => {
+      const { oldValue, newValue } = change;
+
+      // Check if we need to disconnect the console listener
+      // or the notebook active cell listener
+      if (oldValue && consoleTracker.has(oldValue)) {
+        (oldValue as ConsolePanel).console.promptCellCreated.disconnect(
+          onPromptCreated
+        );
+      } else if (oldValue && notebookTracker.has(oldValue)) {
+        (oldValue as NotebookPanel).content.activeCellChanged.disconnect(
+          onActiveCellChanged
+        );
+      }
+
+      // Wire up the new editor to the model if it exists
+      if (newValue && consoleTracker.has(newValue)) {
+        (newValue as ConsolePanel).console.promptCellCreated.connect(
+          onPromptCreated
+        );
+        const prompt = (newValue as ConsolePanel).console.promptCell;
+        item.model!.editor = prompt && prompt.editor;
+      } else if (newValue && notebookTracker.has(newValue)) {
+        (newValue as NotebookPanel).content.activeCellChanged.connect(
+          onActiveCellChanged
+        );
+        const cell = (newValue as NotebookPanel).content.activeCell;
+        item.model!.editor = cell && cell.editor;
+      } else if (newValue && editorTracker.has(newValue)) {
+        item.model!.editor = (newValue as IDocumentWidget<
+          FileEditor
+        >).content.editor;
+      } else {
+        item.model!.editor = null;
+      }
+    });
+
+    // Add the status item to the status bar.
+    statusBar.registerStatusItem('line-col-item', item, {
+      align: 'right',
+      rank: 2,
+      isActive: () => {
+        const current = app.shell.currentWidget;
+        return (
+          current &&
+          (notebookTracker.has(current) ||
+            editorTracker.has(current) ||
+            consoleTracker.has(current))
+        );
+      }
+    });
+  }
+};
+
+/**
+ * A plugin providing memory usage statistics to the application.
+ *
+ * #### Notes
+ * This plugin will not work unless the memory usage server extension
+ * is installed.
+ */
+export const memoryUsageItem: JupyterLabPlugin<void> = {
+  id: '@jupyterlab/statusbar:memory-usage-item',
+  autoStart: true,
+  requires: [IStatusBar],
+  activate: (app: JupyterLab, statusBar: IStatusBar) => {
+    let item = new MemoryUsage();
+
+    statusBar.registerStatusItem('memory-usage-item', item, {
+      align: 'left',
+      rank: 2,
+      isActive: () => item.model!.metricsAvailable,
+      stateChanged: item.model!.stateChanged
+    });
+  }
+};
+
+/*
+ * A plugin providing running terminals and sessions information
+ * to the status bar.
+ */
+export const runningSessionsItem: JupyterLabPlugin<void> = {
+  id: '@jupyterlab/statusbar:running-sessions-item',
+  autoStart: true,
+  requires: [IStatusBar],
+  activate: (app: JupyterLab, statusBar: IStatusBar) => {
+    const item = new RunningSessions({
+      onClick: () => app.shell.activateById('jp-running-sessions'),
+      serviceManager: app.serviceManager
+    });
+
+    statusBar.registerStatusItem('running-sessions-item', item, {
+      align: 'left',
+      rank: 0
+    });
+  }
+};
+
 const plugins: JupyterLabPlugin<any>[] = [
   statusBar,
   lineColItem,
   kernelStatus,
   runningSessionsItem,
-  filePathStatus,
-  tabSpaceItem,
-  memoryUsageItem,
-  savingStatusItem
+  memoryUsageItem
 ];
 
 export default plugins;

+ 0 - 0
packages/statusbar-extension/src/context.ts → packages/statusbar/context.ts


+ 3 - 0
packages/statusbar/package.json

@@ -30,6 +30,9 @@
   },
   "dependencies": {
     "@jupyterlab/apputils": "^0.19.1",
+    "@jupyterlab/codeeditor": "^0.19.1",
+    "@jupyterlab/coreutils": "^2.2.1",
+    "@jupyterlab/services": "^3.2.1",
     "@phosphor/algorithm": "^1.1.2",
     "@phosphor/coreutils": "^1.3.0",
     "@phosphor/disposable": "^1.1.2",

+ 0 - 0
packages/statusbar-extension/src/settings.ts → packages/statusbar/settings.ts


+ 0 - 3
packages/statusbar-extension/src/defaults/index.ts → packages/statusbar/src/defaults/index.ts

@@ -4,7 +4,4 @@
 export * from './lineCol';
 export * from './kernelStatus';
 export * from './runningSessions';
-export * from './filePath';
-export * from './tabSpace';
 export * from './memoryUsage';
-export * from './savingStatus';

+ 3 - 79
packages/statusbar-extension/src/defaults/kernelStatus.tsx → packages/statusbar/src/defaults/kernelStatus.tsx

@@ -3,26 +3,16 @@
 
 import React from 'react';
 
-import { JupyterLabPlugin, JupyterLab } from '@jupyterlab/application';
-
 import { IClientSession, VDomRenderer, VDomModel } from '@jupyterlab/apputils';
 
-import { IConsoleTracker, ConsolePanel } from '@jupyterlab/console';
-
 import { Text } from '@jupyterlab/coreutils';
 
-import { INotebookTracker, NotebookPanel } from '@jupyterlab/notebook';
-
 import { Kernel, Session } from '@jupyterlab/services';
 
-import { interactiveItem, IStatusBar, TextItem } from '@jupyterlab/statusbar';
+import { interactiveItem, TextItem } from '..';
 
 import { JSONExt } from '@phosphor/coreutils';
 
-import { Title, Widget } from '@phosphor/widgets';
-
-import { IStatusContext } from '../context';
-
 /**
  * A pure functional component for rendering kernel status.
  */
@@ -74,7 +64,7 @@ namespace KernelStatusComponent {
 /**
  * A VDomRenderer widget for displaying the status of a kernel.
  */
-class KernelStatus extends VDomRenderer<KernelStatus.Model> {
+export class KernelStatus extends VDomRenderer<KernelStatus.Model> {
   /**
    * Construct the kernel status widget.
    */
@@ -109,7 +99,7 @@ class KernelStatus extends VDomRenderer<KernelStatus.Model> {
 /**
  * A namespace for KernelStatus statics.
  */
-namespace KernelStatus {
+export namespace KernelStatus {
   /**
    * A VDomModel for the kernel status indicator.
    */
@@ -233,69 +223,3 @@ namespace KernelStatus {
     onClick: () => void;
   }
 }
-
-export const kernelStatus: JupyterLabPlugin<void> = {
-  id: '@jupyterlab/statusbar:kernel-status',
-  autoStart: true,
-  requires: [IStatusBar, INotebookTracker, IConsoleTracker],
-  activate: (
-    app: JupyterLab,
-    statusBar: IStatusBar,
-    notebookTracker: INotebookTracker,
-    consoleTracker: IConsoleTracker
-  ) => {
-    // When the status item is clicked, launch the kernel
-    // selection dialog for the current session.
-    let currentSession: IClientSession | null = null;
-    const changeKernel = () => {
-      if (!currentSession) {
-        return;
-      }
-      currentSession.selectKernel();
-    };
-
-    // Create the status item.
-    const item = new KernelStatus({
-      onClick: changeKernel
-    });
-
-    // When the title of the active widget changes, update the label
-    // of the hover text.
-    const onTitleChanged = (title: Title<Widget>) => {
-      item.model!.activityName = title.label;
-    };
-
-    // Keep the session object on the status item up-to-date.
-    app.shell.currentChanged.connect((shell, change) => {
-      const { oldValue, newValue } = change;
-
-      // Clean up after the old value if it exists,
-      // listen for changes to the title of the activity
-      if (oldValue) {
-        oldValue.title.changed.disconnect(onTitleChanged);
-      }
-      if (newValue) {
-        newValue.title.changed.connect(onTitleChanged);
-      }
-
-      // Grab the session off of the current widget, if it exists.
-      if (newValue && consoleTracker.has(newValue)) {
-        currentSession = (newValue as ConsolePanel).session;
-      } else if (newValue && notebookTracker.has(newValue)) {
-        currentSession = (newValue as NotebookPanel).session;
-      } else {
-        currentSession = null;
-      }
-      item.model!.session = currentSession;
-    });
-
-    statusBar.registerStatusItem('kernel-status-item', item, {
-      align: 'left',
-      rank: 1,
-      isActive: IStatusContext.delegateActive(app.shell, [
-        { tracker: notebookTracker },
-        { tracker: consoleTracker }
-      ])
-    });
-  }
-};

+ 3 - 105
packages/statusbar-extension/src/defaults/lineCol.tsx → packages/statusbar/src/defaults/lineCol.tsx

@@ -3,43 +3,15 @@
 
 import React from 'react';
 
-import { JupyterLabPlugin, JupyterLab } from '@jupyterlab/application';
-
 import {
   VDomRenderer,
   VDomModel,
   ReactElementWidget
 } from '@jupyterlab/apputils';
 
-import { Cell, CodeCell } from '@jupyterlab/cells';
-
-import {
-  IConsoleTracker,
-  ConsolePanel,
-  CodeConsole
-} from '@jupyterlab/console';
-
 import { CodeEditor } from '@jupyterlab/codeeditor';
 
-import { IDocumentWidget } from '@jupyterlab/docregistry';
-
-import { IEditorTracker, FileEditor } from '@jupyterlab/fileeditor';
-
-import {
-  INotebookTracker,
-  Notebook,
-  NotebookPanel
-} from '@jupyterlab/notebook';
-
-import {
-  IStatusBar,
-  interactiveItem,
-  showPopup,
-  Popup,
-  TextItem
-} from '@jupyterlab/statusbar';
-
-import { IStatusContext } from '../context';
+import { interactiveItem, showPopup, Popup, TextItem } from '..';
 
 import {
   lineFormWrapper,
@@ -246,7 +218,7 @@ function LineColComponent(
 /**
  * A widget implementing a line/column status item.
  */
-class LineCol extends VDomRenderer<LineCol.Model> {
+export class LineCol extends VDomRenderer<LineCol.Model> {
   /**
    * Construct a new LineCol status item.
    */
@@ -312,7 +284,7 @@ class LineCol extends VDomRenderer<LineCol.Model> {
 /**
  * A namespace for LineCol statics.
  */
-namespace LineCol {
+export namespace LineCol {
   /**
    * A VDom model for a status item tracking the line/column of an editor.
    */
@@ -389,77 +361,3 @@ namespace LineCol {
     private _editor: CodeEditor.IEditor | null = null;
   }
 }
-
-/**
- * A plugin providing a line/column status item to the application.
- */
-export const lineColItem: JupyterLabPlugin<void> = {
-  id: '@jupyterlab/statusbar:line-col-item',
-  autoStart: true,
-  requires: [IStatusBar, INotebookTracker, IEditorTracker, IConsoleTracker],
-  activate: (
-    app: JupyterLab,
-    statusBar: IStatusBar,
-    notebookTracker: INotebookTracker,
-    editorTracker: IEditorTracker,
-    consoleTracker: IConsoleTracker
-  ) => {
-    const item = new LineCol();
-
-    const onActiveCellChanged = (notebook: Notebook, cell: Cell) => {
-      item.model!.editor = cell && cell.editor;
-    };
-
-    const onPromptCreated = (console: CodeConsole, prompt: CodeCell) => {
-      item.model!.editor = prompt && prompt.editor;
-    };
-
-    app.shell.currentChanged.connect((shell, change) => {
-      const { oldValue, newValue } = change;
-
-      // Check if we need to disconnect the console listener
-      // or the notebook active cell listener
-      if (oldValue && consoleTracker.has(oldValue)) {
-        (oldValue as ConsolePanel).console.promptCellCreated.disconnect(
-          onPromptCreated
-        );
-      } else if (oldValue && notebookTracker.has(oldValue)) {
-        (oldValue as NotebookPanel).content.activeCellChanged.disconnect(
-          onActiveCellChanged
-        );
-      }
-
-      // Wire up the new editor to the model if it exists
-      if (newValue && consoleTracker.has(newValue)) {
-        (newValue as ConsolePanel).console.promptCellCreated.connect(
-          onPromptCreated
-        );
-        const prompt = (newValue as ConsolePanel).console.promptCell;
-        item.model!.editor = prompt && prompt.editor;
-      } else if (newValue && notebookTracker.has(newValue)) {
-        (newValue as NotebookPanel).content.activeCellChanged.connect(
-          onActiveCellChanged
-        );
-        const cell = (newValue as NotebookPanel).content.activeCell;
-        item.model!.editor = cell && cell.editor;
-      } else if (newValue && editorTracker.has(newValue)) {
-        item.model!.editor = (newValue as IDocumentWidget<
-          FileEditor
-        >).content.editor;
-      } else {
-        item.model!.editor = null;
-      }
-    });
-
-    // Add the status item to the status bar.
-    statusBar.registerStatusItem('line-col-item', item, {
-      align: 'right',
-      rank: 2,
-      isActive: IStatusContext.delegateActive(app.shell, [
-        { tracker: notebookTracker },
-        { tracker: editorTracker },
-        { tracker: consoleTracker }
-      ])
-    });
-  }
-};

+ 3 - 28
packages/statusbar-extension/src/defaults/memoryUsage.tsx → packages/statusbar/src/defaults/memoryUsage.tsx

@@ -3,20 +3,18 @@
 
 import React from 'react';
 
-import { JupyterLabPlugin, JupyterLab } from '@jupyterlab/application';
-
 import { VDomModel, VDomRenderer } from '@jupyterlab/apputils';
 
 import { URLExt } from '@jupyterlab/coreutils';
 
-import { IStatusBar, TextItem } from '@jupyterlab/statusbar';
+import { TextItem } from '..';
 
 import { ServerConnection } from '@jupyterlab/services';
 
 /**
  * A VDomRenderer for showing memory usage by a kernel.
  */
-class MemoryUsage extends VDomRenderer<MemoryUsage.Model> {
+export class MemoryUsage extends VDomRenderer<MemoryUsage.Model> {
   /**
    * Construct a new memory usage status item.
    */
@@ -53,7 +51,7 @@ class MemoryUsage extends VDomRenderer<MemoryUsage.Model> {
 /**
  * A namespace for MemoryUsage statics.
  */
-namespace MemoryUsage {
+export namespace MemoryUsage {
   /**
    * A VDomModel for the memory usage status item.
    */
@@ -314,26 +312,3 @@ namespace Private {
     return request;
   }
 }
-
-/**
- * A plugin providing memory usage statistics to the application.
- *
- * #### Notes
- * This plugin will not work unless the memory usage server extension
- * is installed.
- */
-export const memoryUsageItem: JupyterLabPlugin<void> = {
-  id: '@jupyterlab/statusbar:memory-usage-item',
-  autoStart: true,
-  requires: [IStatusBar],
-  activate: (app: JupyterLab, statusBar: IStatusBar) => {
-    let item = new MemoryUsage();
-
-    statusBar.registerStatusItem('memory-usage-item', item, {
-      align: 'left',
-      rank: 2,
-      isActive: () => item.model!.metricsAvailable,
-      stateChanged: item.model!.stateChanged
-    });
-  }
-};

+ 3 - 32
packages/statusbar-extension/src/defaults/runningSessions.tsx → packages/statusbar/src/defaults/runningSessions.tsx

@@ -3,8 +3,6 @@
 
 import React from 'react';
 
-import { JupyterLabPlugin, JupyterLab } from '@jupyterlab/application';
-
 import { VDomRenderer, VDomModel } from '@jupyterlab/apputils';
 
 import {
@@ -15,13 +13,7 @@ import {
   SessionManager
 } from '@jupyterlab/services';
 
-import {
-  GroupItem,
-  IconItem,
-  IStatusBar,
-  interactiveItem,
-  TextItem
-} from '@jupyterlab/statusbar';
+import { GroupItem, IconItem, interactiveItem, TextItem } from '..';
 
 /**
  * Half spacing between subitems in a status item.
@@ -81,7 +73,7 @@ namespace RunningSessionsComponent {
 /**
  * A VDomRenderer for a RunningSessions status item.
  */
-class RunningSessions extends VDomRenderer<RunningSessions.Model> {
+export class RunningSessions extends VDomRenderer<RunningSessions.Model> {
   /**
    * Create a new RunningSessions widget.
    */
@@ -165,7 +157,7 @@ class RunningSessions extends VDomRenderer<RunningSessions.Model> {
 /**
  * A namespace for RunninSessions statics.
  */
-namespace RunningSessions {
+export namespace RunningSessions {
   /**
    * A VDomModel for the RunninSessions status item.
    */
@@ -220,24 +212,3 @@ namespace RunningSessions {
     onClick: () => void;
   }
 }
-
-/*
- * A plugin providing running terminals and sessions information
- * to the status bar.
- */
-export const runningSessionsItem: JupyterLabPlugin<void> = {
-  id: '@jupyterlab/statusbar:running-sessions-item',
-  autoStart: true,
-  requires: [IStatusBar],
-  activate: (app: JupyterLab, statusBar: IStatusBar) => {
-    const item = new RunningSessions({
-      onClick: () => app.shell.activateById('jp-running-sessions'),
-      serviceManager: app.serviceManager
-    });
-
-    statusBar.registerStatusItem('running-sessions-item', item, {
-      align: 'left',
-      rank: 0
-    });
-  }
-};

+ 1 - 0
packages/statusbar/src/index.ts

@@ -6,3 +6,4 @@
 export * from './statusbar';
 export * from './style/statusbar';
 export * from './components';
+export * from './defaults';

+ 0 - 0
packages/statusbar-extension/src/style/lineForm.ts → packages/statusbar/src/style/lineForm.ts


+ 9 - 0
packages/statusbar/tsconfig.json

@@ -8,6 +8,15 @@
   "references": [
     {
       "path": "../apputils"
+    },
+    {
+      "path": "../codeeditor"
+    },
+    {
+      "path": "../coreutils"
+    },
+    {
+      "path": "../services"
     }
   ]
 }