Explorar el Código

Merge pull request #1728 from afshin/capture-keymap

Listen to capture phase for keymap + completer shortcut
S. Chris Colbert hace 8 años
padre
commit
07ec775b04

+ 12 - 0
src/application/index.ts

@@ -132,6 +132,18 @@ class JupyterLab extends Application<ApplicationShell> {
     mods.forEach(mod => { this.registerPluginModule(mod); });
   }
 
+  /**
+   * Add the application-wide listeners.
+   *
+   * #### Notes
+   * TODO: This method can be removed when phosphor 1.0 is deployed.
+   */
+  protected addEventListeners(): void {
+    // Listen for keydown events in the capture phase.
+    document.addEventListener('keydown', this, true);
+    window.addEventListener('resize', this);
+  }
+
   /**
    * Create the application shell for the JupyterLab application.
    */

+ 2 - 2
src/application/plugin.ts

@@ -28,14 +28,14 @@ const plugin: JupyterLabPlugin<void> = {
     command = CommandIDs.activateNextTab;
     app.commands.addCommand(command, {
       label: 'Activate Next Tab',
-      execute: () => { app.shell.activateNextTab() }
+      execute: () => { app.shell.activateNextTab(); }
     });
     palette.addItem({ command, category: 'Main Area' });
 
     command = CommandIDs.activatePreviousTab;
     app.commands.addCommand(command, {
       label: 'Activate Previous Tab',
-      execute: () => { app.shell.activatePreviousTab() }
+      execute: () => { app.shell.activatePreviousTab(); }
     });
     palette.addItem({ command, category: 'Main Area' });
 

+ 0 - 23
src/completer/handler.ts

@@ -42,7 +42,6 @@ class CompletionHandler implements IDisposable {
     this._completer.selected.connect(this.onCompletionSelected, this);
     this._completer.visibilityChanged.connect(this.onVisibilityChanged, this);
     this._kernel = options.kernel || null;
-    this._interrupt = options.interrupt || null;
   }
 
   /**
@@ -80,13 +79,6 @@ class CompletionHandler implements IDisposable {
     return this._completer === null;
   }
 
-  /**
-   * The interrupt keydown handler used to short circuit the invocation keydown.
-   */
-  get interrupter(): IDisposable {
-    return this._interrupter;
-  }
-
   /**
    * The kernel used by the completion handler.
    */
@@ -248,14 +240,6 @@ class CompletionHandler implements IDisposable {
 
     host.classList.add(COMPLETABLE_CLASS);
 
-    if (this._interrupter) {
-      this._interrupter.dispose();
-    }
-
-    if (this._interrupt) {
-      this._interrupter = editor.addKeydownHandler(this._interrupt);
-    }
-
     this._completer.model.handleTextChange(request);
   }
 
@@ -294,10 +278,8 @@ class CompletionHandler implements IDisposable {
 
   private _editor: CodeEditor.IEditor | null = null;
   private _completer: CompleterWidget | null = null;
-  private _interrupter: IDisposable | null = null;
   private _kernel: Kernel.IKernel | null = null;
   private _pending = 0;
-  private _interrupt: CodeEditor.KeydownHandler | null = null;
 }
 
 
@@ -320,11 +302,6 @@ namespace CompletionHandler {
      * The kernel for the completion handler.
      */
     kernel?: Kernel.IKernel;
-
-    /**
-     * A keydown handler that can short circuit a key event to the editor.
-     */
-    interrupt?: CodeEditor.KeydownHandler;
   }
 
   /**

+ 5 - 48
src/completer/plugin.ts

@@ -1,10 +1,6 @@
 // Copyright (c) Jupyter Development Team.
 // Distributed under the terms of the Modified BSD License.
 
-import {
-  Keymap
-} from 'phosphor/lib/ui/keymap';
-
 import {
   Widget
 } from 'phosphor/lib/ui/widget';
@@ -22,27 +18,11 @@ import {
 } from '../notebook';
 
 import {
-  CommandIDs, COMPLETABLE_CLASS,
-  CompleterModel, CompleterWidget, CompletionHandler, ICompletionManager
+  CommandIDs, CompleterModel, CompleterWidget, CompletionHandler,
+  ICompletionManager
 } from './';
 
 
-/**
- * The keyboard shortcut used to invoke a completer.
- *
- * #### Notes
- * The limitation of only supporting a single character completer invocation
- * shortcut stems from the fact that the current application-level APIs only
- * support adding shortcuts that are processed in the bubble phase of keydown
- * events.
- * Therefore, TODO: after upgrading to phosphor 1.0
- * - remove the `interrupt` function in the invoke commands
- * - switch the invoke commands to be processed in the capture phase
- * - remove the `shortcut` const and allow arbitrary shortcuts
- */
-const shortcut = 'Tab';
-
-
 /**
  * A service providing code completion for editors.
  */
@@ -51,11 +31,7 @@ const service: JupyterLabPlugin<ICompletionManager> = {
   autoStart: true,
   provides: ICompletionManager,
   activate: (app: JupyterLab): ICompletionManager => {
-    const { layout } = app.keymap;
     const handlers: { [id: string]: CompletionHandler } = {};
-    const interrupt = (instance: any, event: KeyboardEvent): boolean => {
-      return Keymap.keystrokeForKeydownEvent(event, layout) === shortcut;
-    };
 
     app.commands.addCommand(CommandIDs.invoke, {
       execute: args => {
@@ -65,14 +41,9 @@ const service: JupyterLabPlugin<ICompletionManager> = {
         }
 
         const handler = handlers[id];
-        if (!handler) {
-          return;
-        }
-
-        if (handler.interrupter) {
-          handler.interrupter.dispose();
+        if (handler) {
+          handler.invoke();
         }
-        handler.invoke();
       }
     });
 
@@ -81,7 +52,7 @@ const service: JupyterLabPlugin<ICompletionManager> = {
         const { anchor, editor, kernel, parent } = completable;
         const model = new CompleterModel();
         const completer = new CompleterWidget({ anchor, model });
-        const handler = new CompletionHandler({ completer, interrupt, kernel });
+        const handler = new CompletionHandler({ completer, kernel });
         const id = parent.id;
 
         // Associate the handler with the parent widget.
@@ -146,13 +117,6 @@ const consolePlugin: JupyterLabPlugin<void> = {
         return app.commands.execute(CommandIDs.invoke, { id });
       }
     });
-
-    // Add console completer invocation key binding.
-    app.keymap.addBinding({
-      command: CommandIDs.invokeConsole,
-      keys: [shortcut],
-      selector: `.jp-ConsolePanel .${COMPLETABLE_CLASS}`
-    });
   }
 };
 
@@ -191,13 +155,6 @@ const notebookPlugin: JupyterLabPlugin<void> = {
         return app.commands.execute(CommandIDs.invoke, { id });
       }
     });
-
-    // Add notebook completer invocation key binding.
-    app.keymap.addBinding({
-      command: CommandIDs.invokeNotebook,
-      keys: [shortcut],
-      selector: `.jp-Notebook .${COMPLETABLE_CLASS}`
-    });
   }
 };
 

+ 19 - 5
src/shortcuts/plugin.ts

@@ -9,6 +9,10 @@ import {
   CommandIDs as CommandPaletteCommandIDs
 } from '../commandpalette';
 
+import {
+  CommandIDs as CompleterCommandIDs, COMPLETABLE_CLASS
+} from '../completer';
+
 import {
   CommandIDs as ConsoleCommandIDs
 } from '../console';
@@ -66,11 +70,6 @@ import {
  * required, using the `'body'` selector is more appropriate.
  */
 const SHORTCUTS = [
-  {
-    command: CommandPaletteCommandIDs.activate,
-    selector: 'body',
-    keys: ['Accel Shift P']
-  },
   {
     command: ApplicationCommandIDs.activateNextTab,
     selector: 'body',
@@ -81,6 +80,21 @@ const SHORTCUTS = [
     selector: 'body',
     keys: ['Accel ArrowLeft']
   },
+  {
+    command: CommandPaletteCommandIDs.activate,
+    selector: 'body',
+    keys: ['Accel Shift P']
+  },
+  {
+    command: CompleterCommandIDs.invokeConsole,
+    selector: `.jp-ConsolePanel .${COMPLETABLE_CLASS}`,
+    keys: ['Tab']
+  },
+  {
+    command: CompleterCommandIDs.invokeNotebook,
+    selector: `.jp-Notebook .${COMPLETABLE_CLASS}`,
+    keys: ['Tab']
+  },
   {
     command: ConsoleCommandIDs.run,
     selector: '.jp-CodeConsole-prompt',