Components.utils.import('resource://greasemonkey/prefmanager.js');

const EXPORTED_SYMBOLS = ['getEditor'];

function getEditor(change) {
  var editorPath = GM_prefRoot.getValue("editor");

  if (!change && editorPath) {
    var editor;
    try {
      editor = Components.classes["@mozilla.org/file/local;1"]
                   .createInstance(Components.interfaces.nsILocalFile);
      editor.followLinks = true;
      editor.initWithPath(editorPath);
    } catch (e) {
      editor = null;
    }

    // make sure the editor preference is still valid
    if (editor && editor.exists() && editor.isExecutable()) {
      return editor;
    } else {
      GM_prefRoot.remove("editor");
    }
  }

  // Ask the user to choose a new editor. Sometimes users get confused and
  // pick a non-executable file, so we set this up in a loop so that if they do
  // that we can give them an error and try again.
  while (true) {
    var nsIFilePicker = Components.interfaces.nsIFilePicker;
    var filePicker = Components.classes["@mozilla.org/filepicker;1"]
                               .createInstance(nsIFilePicker);

    filePicker.init(window, GM_stringBundle.GetStringFromName("editor.prompt"),
                    nsIFilePicker.modeOpen);
    filePicker.appendFilters(nsIFilePicker.filterApplication);
    filePicker.appendFilters(nsIFilePicker.filterAll);

    if (filePicker.show() != nsIFilePicker.returnOK) {
      // The user canceled, return null.
      return null;
    }

    if (filePicker.file.exists() && filePicker.file.isExecutable()) {
      GM_prefRoot.setValue("editor", filePicker.file.path);
      return filePicker.file;
    } else {
      alert(GM_stringBundle.GetStringFromName("editor.please_pick_executable"));
    }
  }
}

@@ -64,47 +64,474 @@
 ');%0A
-%0Aconst EXPORTED_SYMBOLS = %5B'getEditor'%5D
+Components.utils.import('resource://greasemonkey/util.js');%0A%0Aconst EXPORTED_SYMBOLS = %5B'getEditor'%5D;%0Avar stringBundle = Components%0A    .classes%5B%22@mozilla.org/intl/stringbundle;1%22%5D%0A    .getService(Components.interfaces.nsIStringBundleService)%0A    .createBundle(%22chrome://greasemonkey/locale/gm-browser.properties%22);%0Aconst EDITOR_PROMPT = stringBundle.GetStringFromName(%22editor.prompt%22);%0Aconst PICK_EXE = stringBundle.GetStringFromName(%22editor.please_pick_executable%22)
 ;%0A%0Af
@@ -736,33 +736,24 @@
 %5D%0A          
-         
 .createInsta
@@ -1461,39 +1461,16 @@
 ker;1%22%5D%0A
-                       
         
@@ -1526,87 +1526,59 @@
 nit(
-window, GM_stringBundle.GetStringFromName(%22editor.prompt%22),%0A                   
+%0A        GM_util.getBrowserWindow(), EDITOR_PROMPT,
  nsI
@@ -2029,74 +2029,16 @@
 ert(
-GM_stringBundle.GetStringFromName(%22editor.please_pick_executable%22)
+PICK_EXE
 );%0A 

Fix getEditor() module.