Sfoglia il codice sorgente

Add an option to toggle autosave for the document manager.

Ian Rose 7 anni fa
parent
commit
7c988fafea

+ 5 - 2
packages/docmanager-extension/package.json

@@ -11,7 +11,8 @@
   "files": [
     "lib/*.d.ts",
     "lib/*.js.map",
-    "lib/*.js"
+    "lib/*.js",
+    "schema/*.json"
   ],
   "main": "lib/index.js",
   "types": "lib/index.d.ts",
@@ -34,6 +35,7 @@
     "@jupyterlab/coreutils": "^1.0.4",
     "@jupyterlab/docmanager": "^0.15.2",
     "@jupyterlab/docregistry": "^0.15.2",
+    "@jupyterlab/mainmenu": "^0.4.2",
     "@jupyterlab/services": "^1.1.2",
     "@phosphor/disposable": "^1.1.2"
   },
@@ -42,6 +44,7 @@
     "typescript": "~2.6.2"
   },
   "jupyterlab": {
-    "extension": true
+    "extension": true,
+    "schemaDir": "schema"
   }
 }

+ 16 - 0
packages/docmanager-extension/schema/plugin.json

@@ -0,0 +1,16 @@
+{
+  "jupyter.lab.setting-icon-class": "jp-FileIcon",
+  "jupyter.lab.setting-icon-label": "Document Manager",
+  "title": "Document Manager",
+  "description": "Document Manager settings.",
+  "properties": {
+    "autosave": {
+      "type": "boolean",
+      "title": "Autosave Documents",
+      "description": "Whether to autosave documents",
+      "default": true
+    }
+  },
+  "additionalProperties": false,
+  "type": "object"
+}

+ 50 - 6
packages/docmanager-extension/src/index.ts

@@ -10,7 +10,7 @@ import {
 } from '@jupyterlab/apputils';
 
 import {
-  IChangedArgs
+  IChangedArgs, ISettingRegistry
 } from '@jupyterlab/coreutils';
 
 import {
@@ -21,6 +21,10 @@ import {
   DocumentRegistry
 } from '@jupyterlab/docregistry';
 
+import {
+  IMainMenu
+} from '@jupyterlab/mainmenu';
+
 import {
   Contents, Kernel
 } from '@jupyterlab/services';
@@ -69,17 +73,21 @@ namespace CommandIDs {
 
   export
   const saveAs = 'docmanager:save-as';
+
+  export
+  const toggleAutosave = 'docmanager:toggle-autosave';
 }
 
+const pluginId = '@jupyterlab/docmanager-extension:plugin';
 
 /**
  * The default document manager provider.
  */
 const plugin: JupyterLabPlugin<IDocumentManager> = {
-  id: '@jupyterlab/docmanager-extension:plugin',
+  id: pluginId,
   provides: IDocumentManager,
-  requires: [ICommandPalette],
-  activate: (app: JupyterLab, palette: ICommandPalette): IDocumentManager => {
+  requires: [ICommandPalette, IMainMenu, ISettingRegistry],
+  activate: (app: JupyterLab, palette: ICommandPalette, menu: IMainMenu, settingRegistry: ISettingRegistry): IDocumentManager => {
     const manager = app.serviceManager;
     const contexts = new WeakSet<DocumentRegistry.Context>();
     const opener: DocumentManager.IWidgetOpener = {
@@ -119,7 +127,24 @@ const plugin: JupyterLabPlugin<IDocumentManager> = {
     const docManager = new DocumentManager({ registry, manager, opener });
 
     // Register the file operations commands.
-    addCommands(app, docManager, palette, opener);
+    addCommands(app, docManager, palette, opener, settingRegistry);
+
+    const onSettingsUpdated = (settings: ISettingRegistry.ISettings) => {
+      const autosave = settings.get('autosave').composite as boolean | null;
+      docManager.autosave = (autosave === true || autosave === false)
+                            ? autosave
+                            : true;
+    };
+
+    // Fetch the initial state of the settings.
+    Promise.all([settingRegistry.load(pluginId), app.restored])
+    .then(([settings]) => {
+      settings.changed.connect(onSettingsUpdated);
+      onSettingsUpdated(settings);
+    }).catch((reason: Error) => {
+      console.error(reason.message);
+    });
+    menu.settingsMenu.addGroup([{ command: CommandIDs.toggleAutosave }], 5);
 
     return docManager;
   }
@@ -135,7 +160,7 @@ export default plugin;
 /**
  * Add the file operations commands to the application's command registry.
  */
-function addCommands(app: JupyterLab, docManager: IDocumentManager, palette: ICommandPalette, opener: DocumentManager.IWidgetOpener): void {
+function addCommands(app: JupyterLab, docManager: IDocumentManager, palette: ICommandPalette, opener: DocumentManager.IWidgetOpener, settingRegistry: ISettingRegistry): void {
   const { commands, docRegistry } = app;
   const category = 'File Operations';
   const isEnabled = () => {
@@ -336,6 +361,20 @@ function addCommands(app: JupyterLab, docManager: IDocumentManager, palette: ICo
     },
   });
 
+  commands.addCommand(CommandIDs.toggleAutosave, {
+    label: args =>
+      args['isPalette'] ? 'Toggle Document Autosave' : 'Autosave Documents',
+    isToggled: () => docManager.autosave,
+    execute: () => {
+      const value = !docManager.autosave;
+      const key = 'autosave';
+      return settingRegistry.set(pluginId, key, value)
+      .catch((reason: Error) => {
+        console.error(`Failed to set ${pluginId}:${key} - ${reason.message}`);
+      });
+    }
+  });
+
   app.contextMenu.addItem({
     command: CommandIDs.rename,
     selector: '[data-type="document-title"]',
@@ -355,6 +394,11 @@ function addCommands(app: JupyterLab, docManager: IDocumentManager, palette: ICo
     CommandIDs.close,
     CommandIDs.closeAllFiles
   ].forEach(command => { palette.addItem({ command, category }); });
+  palette.addItem({
+    command: CommandIDs.toggleAutosave,
+    category,
+    args: { isPalette: true }
+  });
 }
 
 

+ 22 - 1
packages/docmanager/src/manager.ts

@@ -110,6 +110,24 @@ class DocumentManager implements IDisposable {
     return this._activateRequested;
   }
 
+  /**
+   * Whether to autosave documents.
+   */
+  get autosave(): boolean {
+    return this._autosave;
+  }
+  set autosave(value: boolean) {
+    this._autosave = value;
+    each(toArray(this._contexts), context => {
+      const handler = Private.saveHandlerProperty.get(context);
+      if (value === true && !handler.isActive) {
+        handler.start();
+      } else if (value === false && handler.isActive) {
+        handler.stop();
+      }
+    });
+  }
+
   /**
    * Get whether the document manager has been disposed.
    */
@@ -394,7 +412,9 @@ class DocumentManager implements IDisposable {
     let handler = new SaveHandler({ context });
     Private.saveHandlerProperty.set(context, handler);
     context.ready.then(() => {
-      handler.start();
+      if (this.autosave) {
+        handler.start();
+      }
     });
     context.disposed.connect(this._onContextDisposed, this);
     this._contexts.push(context);
@@ -482,6 +502,7 @@ class DocumentManager implements IDisposable {
   private _opener: DocumentManager.IWidgetOpener;
   private _widgetManager: DocumentWidgetManager;
   private _isDisposed = false;
+  private _autosave = true;
 }