Parcourir la source

Merge pull request #1160 from blink1073/console-name

Add Console support to kernel selection and the running tab
Afshin Darian il y a 8 ans
Parent
commit
128639b262

+ 2 - 22
src/console/panel.ts

@@ -89,28 +89,8 @@ class ConsolePanel extends Panel {
    * Handle `'close-request'` messages.
    */
   protected onCloseRequest(msg: Message): void {
-    let session = this._content.session;
-
-    if (!session || !session.kernel) {
-      super.onCloseRequest(msg);
-      this.dispose();
-      return;
-    }
-
-    session.kernel.getSpec().then(spec => {
-      let name = spec.display_name;
-      return showDialog({
-        title: 'Shut down kernel?',
-        body: `Shut down ${name}?`
-      });
-    }).then(value => {
-      if (value && value.text === 'OK') {
-        return session.shutdown();
-      }
-    }).then(() => {
-      super.onCloseRequest(msg);
-      this.dispose();
-    });
+    super.onCloseRequest(msg);
+    this.dispose();
   }
 
   private _content: ConsoleContent = null;

+ 36 - 5
src/console/plugin.ts

@@ -5,6 +5,10 @@ import {
   ContentsManager, Kernel, Session, utils
 } from '@jupyterlab/services';
 
+import {
+  find
+} from 'phosphor/lib/algorithm/searching';
+
 import {
   JSONObject
 } from 'phosphor/lib/algorithm/json';
@@ -89,6 +93,11 @@ const LANDSCAPE_ICON_CLASS = 'jp-MainAreaLandscapeIcon';
  */
 const CONSOLE_ICON_CLASS = 'jp-ImageCodeConsole';
 
+/**
+ * A regex for console names.
+ */
+const CONSOLE_REGEX = /^console-(\d)+-[0-9a-f]+$/;
+
 /**
  * The console panel instance tracker.
  */
@@ -99,7 +108,7 @@ const tracker = new InstanceTracker<ConsolePanel>();
  * The interface for a start console.
  */
 interface ICreateConsoleArgs extends JSONObject {
-  sessionId?: string;
+  id?: string;
   path?: string;
   kernel?: Kernel.IModel;
   preferredLanguage?: string;
@@ -221,9 +230,12 @@ function activateConsole(app: JupyterLab, services: IServiceManager, rendermime:
       let name = `Console ${++count}`;
 
       // If we get a session, use it.
-      if (args.sessionId) {
-        return manager.connectTo(args.sessionId).then(session => {
+      if (args.id) {
+        return manager.connectTo(args.id).then(session => {
+          name = session.path.split('/').pop();
+          name = `Console ${name.match(CONSOLE_REGEX)[1]}`;
           createConsole(session, name);
+          manager.listRunning();  // Trigger a refresh.
           return session.id;
         });
       }
@@ -234,7 +246,7 @@ function activateConsole(app: JupyterLab, services: IServiceManager, rendermime:
       if (ContentsManager.extname(path)) {
         path = ContentsManager.dirname(path);
       }
-      path = `${path}/console-${utils.uuid()}`;
+      path = `${path}/console-${count}-${utils.uuid()}`;
 
       // Get the kernel model.
       return getKernel(args, name).then(kernel => {
@@ -249,6 +261,7 @@ function activateConsole(app: JupyterLab, services: IServiceManager, rendermime:
         };
         return manager.startNew(options).then(session => {
           createConsole(session, name);
+          manager.listRunning();  // Trigger a refresh.
           return session.id;
         });
       });
@@ -259,11 +272,29 @@ function activateConsole(app: JupyterLab, services: IServiceManager, rendermime:
   commands.addCommand(command, {
     execute: (args: JSONObject) => {
       let id = args['id'];
-      tracker.forEach(widget => {
+      tracker.find(widget => {
         if (widget.content.session.id === id) {
           widget.content.inject(args['code'] as string);
+          return true;
+        }
+      });
+    }
+  });
+
+  command = 'console:open';
+  commands.addCommand(command, {
+    execute: (args: JSONObject) => {
+      let id = args['id'];
+      let widget = tracker.find(value => {
+        if (value.content.session.id === id) {
+          return true;
         }
       });
+      if (widget) {
+        app.shell.activateMain(widget.id);
+      } else {
+        app.commands.execute('console:create', { id });
+      }
     }
   });
 

+ 5 - 0
src/docregistry/kernelselector.ts

@@ -261,6 +261,7 @@ function populateKernels(node: HTMLSelectElement, options: IPopulateOptions): vo
   if (otherNames.length) {
     node.appendChild(createSeparatorOption(maxLength));
   }
+
   // Add the sessions using the preferred language first.
   let matchingSessions: Session.IModel[] = [];
   if (preferredLanguage) {
@@ -329,6 +330,10 @@ function optionForName(name: string, displayName: string): HTMLOptionElement {
 function optionForSession(session: Session.IModel, displayName: string, maxLength: number): HTMLOptionElement {
   let option = document.createElement('option');
   let sessionName = session.notebook.path.split('/').pop();
+  const CONSOLE_REGEX = /^console-(\d)+-[0-9a-f]+$/;
+  if (CONSOLE_REGEX.test(sessionName)) {
+    sessionName = `Console ${sessionName.match(CONSOLE_REGEX)[1]}`;
+  }
   if (sessionName.length > maxLength) {
     sessionName = sessionName.slice(0, maxLength - 3) + '...';
   }

+ 5 - 0
src/running/index.css

@@ -121,6 +121,11 @@
 }
 
 
+.jp-RunningSessions-itemIcon.jp-mod-console:before {
+  content: '\f109';
+}
+
+
 .jp-RunningSessions-itemIcon.jp-mod-file:before {
   content: '\f016';
 }

+ 19 - 3
src/running/index.ts

@@ -96,6 +96,11 @@ const SHUTDOWN_BUTTON_CLASS = 'jp-RunningSessions-itemShutdown';
  */
 const NOTEBOOK_ICON_CLASS = 'jp-mod-notebook';
 
+/**
+ * The class name added to a console icon.
+ */
+const CONSOLE_ICON_CLASS = 'jp-mod-console';
+
 /**
  * The class name added to a file icon.
  */
@@ -111,6 +116,12 @@ const TERMINAL_ICON_CLASS = 'jp-mod-terminal';
  */
 const REFRESH_DURATION = 10000;
 
+/**
+ * A regex for console names.
+ */
+export
+const CONSOLE_REGEX = /^console-(\d)+-[0-9a-f]+$/;
+
 
 /**
  * A class that exposes the running terminal and kernel sessions.
@@ -355,7 +366,7 @@ class RunningSessions extends Widget {
     this._runningSessions = [];
     for (let session of models) {
       let name = session.notebook.path.split('/').pop();
-      if (name.indexOf('.') !== -1) {
+      if (name.indexOf('.') !== -1 || CONSOLE_REGEX.test(name)) {
         this._runningSessions.push(session);
       }
     }
@@ -672,13 +683,18 @@ namespace RunningSessions {
      */
     updateSessionNode(node: HTMLLIElement, model: Session.IModel, kernelName: string): void {
       let icon = findElement(node, ITEM_ICON_CLASS);
-      if (model.notebook.path.indexOf('.ipynb') !== -1) {
+      let path = model.notebook.path;
+      let name = path.split('/').pop();
+      if (name.indexOf('.ipynb') !== -1) {
         icon.className = `${ITEM_ICON_CLASS} ${NOTEBOOK_ICON_CLASS}`;
+      } else if (CONSOLE_REGEX.test(name)) {
+        icon.className = `${ITEM_ICON_CLASS} ${CONSOLE_ICON_CLASS}`;
+        path = `Console ${name.match(CONSOLE_REGEX)[1]}`;
       } else {
         icon.className = `${ITEM_ICON_CLASS} ${FILE_ICON_CLASS}`;
       }
       let label = findElement(node, ITEM_LABEL_CLASS);
-      label.textContent = model.notebook.path;
+      label.textContent = path;
       let title = (
         `Path: ${model.notebook.path}\n` +
         `Kernel: ${kernelName}`

+ 9 - 2
src/running/plugin.ts

@@ -10,7 +10,7 @@ import {
 } from '../services';
 
 import {
-  RunningSessions
+  RunningSessions, CONSOLE_REGEX
 } from './index';
 
 
@@ -33,7 +33,14 @@ function activateRunningSessions(app: JupyterLab, services: IServiceManager): vo
   running.title.label = 'Running';
 
   running.sessionOpenRequested.connect((sender, model) => {
-    app.commands.execute('file-operations:open', { path: model.notebook.path });
+    let path = model.notebook.path;
+    let name = path.split('/').pop();
+    if (CONSOLE_REGEX.test(name)) {
+      app.commands.execute('console:open', { id: model.id });
+    } else {
+      app.commands.execute('file-operations:open', { path });
+    }
+
   });
   running.terminalOpenRequested.connect((sender, model) => {
     app.commands.execute('terminal:open', { name: model.name });