Ver Fonte

Add undo/redo metacommand.

Ian Rose há 7 anos atrás
pai
commit
31cebf497a

+ 8 - 1
packages/fileeditor-extension/src/index.ts

@@ -30,7 +30,7 @@ import {
 } from '@jupyterlab/launcher';
 
 import {
-  IMainMenu, IKernelMenu, IViewMenu
+  IEditMenu, IMainMenu, IKernelMenu, IViewMenu
 } from '@jupyterlab/mainmenu';
 
 
@@ -397,6 +397,13 @@ function activate(app: JupyterLab, editorServices: IEditorServices, browserFacto
     // Add new text file creation to the file menu.
     menu.fileMenu.newMenu.addItem({ command: CommandIDs.createNew });
 
+    // Add undo/redo hooks to the edit menu.
+    menu.editMenu.undoers.set('Editor', {
+      tracker,
+      undo: widget => { widget.editor.undo(); },
+      redo: widget => { widget.editor.redo(); }
+    } as IEditMenu.IUndoer<FileEditor>);
+
     // Add editor view options.
     menu.viewMenu.editorViewers.set('Editor', {
       tracker,

+ 26 - 0
packages/mainmenu-extension/src/index.ts

@@ -20,6 +20,12 @@ import {
  */
 export
 namespace CommandIDs {
+  export
+  const undo = 'editmenu:undo';
+
+  export
+  const redo = 'editmenu:redo';
+
   export
   const clear = 'editmenu:clear';
 
@@ -101,6 +107,26 @@ const menuPlugin: JupyterLabPlugin<IMainMenu> = {
 function createEditMenu(app: JupyterLab, menu: EditMenu): void {
   const commands = menu.commands;
 
+  // Add the undo/redo commands the the Edit menu.
+  commands.addCommand(CommandIDs.undo, {
+    label: 'Undo',
+    isEnabled:
+      Private.delegateEnabled(app, menu.undoers, 'undo'),
+    execute:
+      Private.delegateExecute(app, menu.undoers, 'undo')
+  });
+  commands.addCommand(CommandIDs.redo, {
+    label: 'Redo',
+    isEnabled:
+      Private.delegateEnabled(app, menu.undoers, 'redo'),
+    execute:
+      Private.delegateExecute(app, menu.undoers, 'redo')
+  });
+  menu.addGroup([
+    { command: CommandIDs.undo },
+    { command: CommandIDs.redo }
+  ], 0);
+
   // Add the clear command to the Edit menu.
   commands.addCommand(CommandIDs.clear, {
     label: () => {

+ 35 - 0
packages/mainmenu/src/edit.ts

@@ -15,6 +15,14 @@ import {
  */
 export
 interface IEditMenu extends IJupyterLabMenu {
+  /**
+   * A map storing IUndoers for the Edit menu.
+   *
+   * ### Notes
+   * The key for the map may be used in menu labels.
+   */
+  readonly undoers: Map<string, IEditMenu.IUndoer<Widget>>;
+
   /**
    * A map storing IClearers for the Edit menu.
    *
@@ -44,6 +52,9 @@ class EditMenu extends JupyterLabMenu implements IEditMenu {
     super(options);
     this.title.label = 'Edit';
 
+    this.undoers =
+      new Map<string, IEditMenu.IUndoer<Widget>>();
+
     this.clearers =
       new Map<string, IEditMenu.IClearer<Widget>>();
 
@@ -51,6 +62,14 @@ class EditMenu extends JupyterLabMenu implements IEditMenu {
       new Map<string, IEditMenu.IFindReplacer<Widget>>();
   }
 
+  /**
+   * A map storing IUndoers for the Edit menu.
+   *
+   * ### Notes
+   * The key for the map may be used in menu labels.
+   */
+  readonly undoers: Map<string, IEditMenu.IUndoer<Widget>>;
+
   /**
    * A map storing IClearers for the Edit menu.
    *
@@ -73,6 +92,22 @@ class EditMenu extends JupyterLabMenu implements IEditMenu {
  */
 export
 namespace IEditMenu {
+  /**
+   * Interface for an activity that uses Undo/Redo.
+   */
+  export
+  interface IUndoer<T extends Widget> extends IMenuExtender<T> {
+    /**
+     * Execute an undo command for the activity.
+     */
+    undo?: (widget: T) => void;
+
+    /**
+     * Execute a redo command for the activity.
+     */
+    redo?: (widget: T) => void;
+  }
+
   /**
    * Interface for an activity that wants to register a 'Clear...' menu item
    */

+ 20 - 12
packages/notebook-extension/src/index.ts

@@ -171,10 +171,10 @@ namespace CommandIDs {
   const toggleAllLines = 'notebook:toggle-all-cell-line-numbers';
 
   export
-  const undo = 'notebook:undo-cell-action';
+  const undoCellAction = 'notebook:undo-cell-action';
 
   export
-  const redo = 'notebook:redo-cell-action';
+  const redoCellAction = 'notebook:redo-cell-action';
 
   export
   const markdown1 = 'notebook:change-cell-to-heading-1';
@@ -491,12 +491,12 @@ function activateNotebookHandler(app: JupyterLab, mainMenu: IMainMenu, palette:
     rank: 0
   });
   app.contextMenu.addItem({
-    command: CommandIDs.undo,
+    command: CommandIDs.undoCellAction,
     selector: '.jp-Notebook',
     rank: 1
   });
   app.contextMenu.addItem({
-    command: CommandIDs.redo,
+    command: CommandIDs.redoCellAction,
     selector: '.jp-Notebook',
     rank: 2
   });
@@ -967,7 +967,7 @@ function addCommands(app: JupyterLab, services: ServiceManager, tracker: Noteboo
     },
     isEnabled: hasWidget
   });
-  commands.addCommand(CommandIDs.undo, {
+  commands.addCommand(CommandIDs.undoCellAction, {
     label: 'Undo Cell Operation',
     execute: args => {
       const current = getCurrent(args);
@@ -978,7 +978,7 @@ function addCommands(app: JupyterLab, services: ServiceManager, tracker: Noteboo
     },
     isEnabled: hasWidget
   });
-  commands.addCommand(CommandIDs.redo, {
+  commands.addCommand(CommandIDs.redoCellAction, {
     label: 'Redo Cell Operation',
     execute: args => {
       const current = getCurrent(args);
@@ -1265,8 +1265,8 @@ function populatePalette(palette: ICommandPalette): void {
     CommandIDs.extendBelow,
     CommandIDs.moveDown,
     CommandIDs.moveUp,
-    CommandIDs.undo,
-    CommandIDs.redo,
+    CommandIDs.undoCellAction,
+    CommandIDs.redoCellAction,
     CommandIDs.markdown1,
     CommandIDs.markdown2,
     CommandIDs.markdown3,
@@ -1291,6 +1291,14 @@ function populatePalette(palette: ICommandPalette): void {
 function populateMenus(app: JupyterLab, mainMenu: IMainMenu, tracker: INotebookTracker): void {
   let { commands } = app;
 
+  // Add undo/redo hooks to the edit menu.
+  mainMenu.editMenu.undoers.set('Notebook', {
+    tracker,
+    undo: widget => { widget.notebook.activeCell.editor.undo(); },
+    redo: widget => { widget.notebook.activeCell.editor.redo(); }
+  } as IEditMenu.IUndoer<NotebookPanel>);
+
+    // Add editor view options.
   // Add a clearer to the edit menu
   mainMenu.editMenu.clearers.set('Notebook', {
     tracker,
@@ -1401,9 +1409,9 @@ function populateMenus(app: JupyterLab, mainMenu: IMainMenu, tracker: INotebookT
   } as IRunMenu.ICodeRunner<NotebookPanel>);
 
   // Add commands to the application edit menu.
-  const undoGroup = [
-    CommandIDs.undo,
-    CommandIDs.redo
+  const undoCellActionGroup = [
+    CommandIDs.undoCellAction,
+    CommandIDs.redoCellAction
   ].map(command => { return { command }; });
   const editGroup = [
     CommandIDs.cut,
@@ -1413,6 +1421,6 @@ function populateMenus(app: JupyterLab, mainMenu: IMainMenu, tracker: INotebookT
     CommandIDs.split,
     CommandIDs.merge
   ].map(command => { return { command }; });
-  mainMenu.editMenu.addGroup(undoGroup, 4);
+  mainMenu.editMenu.addGroup(undoCellActionGroup, 4);
   mainMenu.editMenu.addGroup(editGroup, 5);
 }