Bug 572259 - Introduce save hooks to allow plugins to perform tasks on save
authorPatrick Walton <pwalton@mozilla.com>
Mon, 20 Sep 2010 18:07:55 -0700
changeset 2041 46b17280cf9ef3c47d355bcd80669bf902bc8ecc
parent 2040 7a747cc4d5899ea97c782bf2a6599ee66e73b842
child 2042 19b3a4bad8230bd734ff4c1b3371e35e8e59b3ed
push id919
push userpwalton@mozilla.com
push dateTue, 21 Sep 2010 01:19:18 +0000
bugs572259
Bug 572259 - Introduce save hooks to allow plugins to perform tasks on save
plugins/supported/file_commands/index.js
plugins/supported/file_commands/package.json
--- a/plugins/supported/file_commands/index.js
+++ b/plugins/supported/file_commands/index.js
@@ -33,19 +33,21 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 var catalog = require('bespin:plugins').catalog;
 var pathUtil = require('filesystem:path');
 var env = require('environment').env;
+var promise = require('bespin:promise');
+var _ = require('underscore')._;
 
 var Buffer = require('text_editor:models/buffer').Buffer;
-var Promise = require('bespin:promise').Promise;
+var Promise = promise.Promise;
 
 /*
  * Creates a path based on the current working directory and the passed 'path'.
  * This is also deals with '..' within the path and '/' at the beginning.
  */
 exports.getCompletePath = function(path) {
     var ret;
     path = path || '';
@@ -118,47 +120,71 @@ exports.mkdirCommand = function(args, re
     files.makeDirectory(path).then(function() {
         request.done('Directory ' + path + ' created.');
     }, function(error) {
         request.doneWithError('Unable to make directory ' + path + ': '
                               + error.message);
     });
 };
 
+function runSaveHooks(file) {
+    var pr = new Promise();
+    var saveHooks = catalog.getExtensions('savehook');
+    promise.group(_(saveHooks).invoke('load')).then(function(hooks) {
+            var hookOutput = _(hooks).map(function(hook) {
+                return hook(file);
+            });
+            pr.resolve(hookOutput.join("\n"));
+        },
+        function(error) { pr.reject(error); });
+
+    return pr;
+}
+
 /**
  * 'save' command
  */
 exports.saveCommand = function(args, request) {
     var buffer = env.buffer;
     if (buffer.untitled()) {
         env.commandLine.setInput('saveas ');
         request.done('The current buffer is untitled. Please enter a name.');
         return;
     }
 
-    buffer.save().then(function() { request.done('Saved'); },
-        function(error) {
-            request.doneWithError('Unable to save: ' + error.message);
-        }
-    );
+    runSaveHooks(buffer.file).then(function(hookOutput) {
+        buffer.save().then(function() { request.done(hookOutput + "Saved."); },
+            function(error) {
+                var message = "Unable to save: " + error.message;
+                request.doneWithError(hookOutput + message);
+            });
+    }, function(err) {
+        request.doneWithError("Save hooks failed: " + err);
+    });
+
     request.async();
 };
 
 /**
  * 'save as' command
  */
 exports.saveAsCommand = function(args, request) {
     var files = env.files;
     var path = exports.getCompletePath(args.path);
+    var newFile = files.getFile(path);
 
-    var newFile = files.getFile(path);
-    env.buffer.saveAs(newFile).then(function() {
-        request.done('Saved to \'' + path + '\'');
+    runSaveHooks(newFile).then(function(hookOutput) {
+        env.buffer.saveAs(newFile).then(function() {
+            request.done(hookOutput + 'Saved to \'' + path + '\'.');
+        }, function(err) {
+            var message = "Save failed: " + err.message;
+            request.doneWithError(hookOutput + message);
+        });
     }, function(err) {
-        request.doneWithError('Save failed (' + err.message + ')');
+        request.doneWithError("Save hooks failed: " + err);
     });
 
     request.async();
 };
 
 /**
  * 'open' command
  */
--- a/plugins/supported/file_commands/package.json
+++ b/plugins/supported/file_commands/package.json
@@ -4,16 +4,21 @@
         "filesystem": "0.0",
         "matcher": "0.0",
         "command_line": "0.0",
         "text_editor": "0.0.0"
     },
     "provides":
     [
         {
+            "ep": "extensionpoint",
+            "name": "savehook",
+            "description": "Hooks to be executed on save"
+        },
+        {
             "ep": "command",
             "name": "ls",
             "params":
             [
                 {
                     "name": "path",
                     "type": "text",
                     "description": "list files relative to current file, or start with /projectname"