diff --git a/content/buffers.js b/content/buffers.js
index b0b387c6..48793d5f 100644
--- a/content/buffers.js
+++ b/content/buffers.js
@@ -687,7 +687,7 @@ vimperator.Buffer = function () //{{{
// TODO: print more useful information, just like the DOM inspector
showElementInfo: function (elem)
{
- vimperator.echo("Element:
" + vimperator.objectToString(elem), vimperator.commandline.FORCE_MULTILINE);
+ vimperator.echo("Element:
" + vimperator.util.objectToString(elem), vimperator.commandline.FORCE_MULTILINE);
},
showPageInfo: function (verbose)
diff --git a/content/commands.js b/content/commands.js
index 303d533f..c0ac34eb 100644
--- a/content/commands.js
+++ b/content/commands.js
@@ -926,7 +926,7 @@ vimperator.Commands = function () //{{{
}
if (typeof arg === "object")
- arg = vimperator.objectToString(arg, color);
+ arg = vimperator.util.objectToString(arg, color);
else if (typeof arg === "function")
arg = vimperator.util.escapeHTML(arg.toString());
else if (typeof arg === "number" || typeof arg === "boolean")
@@ -2081,7 +2081,7 @@ vimperator.Commands = function () //{{{
// return;
//}
- vimperator.source(args, special);
+ vimperator.io.source(args, special);
},
{
shortHelp: "Read Ex commands from {file}",
@@ -2471,7 +2471,7 @@ vimperator.Commands = function () //{{{
var prog = args.shift();
args.push(url)
- vimperator.callFunctionInThread(newThread, vimperator.run, [prog, args, true]);
+ vimperator.callFunctionInThread(newThread, vimperator.io.run, [prog, args, true]);
}
else
{
@@ -2572,7 +2572,7 @@ vimperator.Commands = function () //{{{
args = args.replace(/(^|[^\\])!/g, "$1" + lastRunCommand);
lastRunCommand = args;
- var output = vimperator.system(args);
+ var output = vimperator.io.system(args);
if (output)
vimperator.echo(vimperator.util.escapeHTML(output));
},
diff --git a/content/editor.js b/content/editor.js
index 5f462d30..c96fb89b 100644
--- a/content/editor.js
+++ b/content/editor.js
@@ -364,7 +364,7 @@ vimperator.Editor = function () //{{{
textBox.style.backgroundColor = "#bbbbbb";
var newThread = Components.classes["@mozilla.org/thread-manager;1"].getService().newThread(0);
// TODO: save return value in v:shell_error
- vimperator.callFunctionInThread(newThread, vimperator.run, [prog, args, true]);
+ vimperator.callFunctionInThread(newThread, vimperator.io.run, [prog, args, true]);
textBox.removeAttribute("readonly");
diff --git a/content/events.js b/content/events.js
index 82b03923..1e5d1167 100644
--- a/content/events.js
+++ b/content/events.js
@@ -185,33 +185,36 @@ vimperator.Events = function () //{{{
// any tab related events
var tabcontainer = getBrowser().mTabContainer;
- tabcontainer.addEventListener("TabMove", function (event)
+ if (tabcontainer) // not every VIM-like extension has a tab container
{
- vimperator.statusline.updateTabCount();
- vimperator.buffer.updateBufferList();
- }, false);
- tabcontainer.addEventListener("TabOpen", function (event)
- {
- vimperator.statusline.updateTabCount();
- vimperator.buffer.updateBufferList();
- }, false);
- tabcontainer.addEventListener("TabClose", function (event)
- {
- vimperator.statusline.updateTabCount();
- vimperator.buffer.updateBufferList();
- }, false);
- tabcontainer.addEventListener("TabSelect", function (event)
- {
- // TODO: is all of that necessary?
- vimperator.modes.reset();
- vimperator.commandline.clear();
- vimperator.modes.show();
- vimperator.statusline.updateTabCount();
- vimperator.buffer.updateBufferList();
- vimperator.tabs.updateSelectionHistory();
+ tabcontainer.addEventListener("TabMove", function (event)
+ {
+ vimperator.statusline.updateTabCount();
+ vimperator.buffer.updateBufferList();
+ }, false);
+ tabcontainer.addEventListener("TabOpen", function (event)
+ {
+ vimperator.statusline.updateTabCount();
+ vimperator.buffer.updateBufferList();
+ }, false);
+ tabcontainer.addEventListener("TabClose", function (event)
+ {
+ vimperator.statusline.updateTabCount();
+ vimperator.buffer.updateBufferList();
+ }, false);
+ tabcontainer.addEventListener("TabSelect", function (event)
+ {
+ // TODO: is all of that necessary?
+ vimperator.modes.reset();
+ vimperator.commandline.clear();
+ vimperator.modes.show();
+ vimperator.statusline.updateTabCount();
+ vimperator.buffer.updateBufferList();
+ vimperator.tabs.updateSelectionHistory();
- setTimeout(function () { vimperator.focusContent(true); }, 10); // just make sure, that no widget has focus
- }, false);
+ setTimeout(function () { vimperator.focusContent(true); }, 10); // just make sure, that no widget has focus
+ }, false);
+ }
// this adds an event which is is called on each page load, even if the
// page is loaded in a background tab
diff --git a/content/io.js b/content/io.js
index 5bfbccb7..5318fc8e 100644
--- a/content/io.js
+++ b/content/io.js
@@ -308,6 +308,167 @@ vimperator.IO = function () //{{{
ocstream.close();
ofstream.close();
+ },
+
+ run: function (program, args, blocking)
+ {
+ var file = Components.classes["@mozilla.org/file/local;1"].
+ createInstance(Components.interfaces.nsILocalFile);
+
+ if (!args)
+ args = [];
+
+ if (typeof blocking != "boolean")
+ blocking = false;
+
+ try
+ {
+ file.initWithPath(program);
+ }
+ catch (e)
+ {
+ var dirs = environmentService.get("PATH").split(WINDOWS ? ";" : ":");
+ for (var i = 0; i < dirs.length; i++)
+ {
+ var path = dirs[i] + (WINDOWS ? "\\" : "/") + program;
+ try
+ {
+ file.initWithPath(path);
+ if (file.exists())
+ break;
+ }
+ catch (e) { }
+ }
+ }
+
+ if (!file.exists())
+ {
+ vimperator.echoerr("command not found: " + program);
+ return -1;
+ }
+
+ var process = Components.classes["@mozilla.org/process/util;1"].
+ createInstance(Components.interfaces.nsIProcess);
+ process.init(file);
+
+ var ec = process.run(blocking, args, args.length);
+ return ec;
+ },
+
+ // when https://bugzilla.mozilla.org/show_bug.cgi?id=68702 is fixed
+ // is fixed, should use that instead of a tmpfile
+ // TODO: add shell/shellcmdflag options to replace "sh" and "-c"
+ system: function (str, input)
+ {
+ var fileout = this.createTempFile();
+ if (!fileout)
+ return "";
+
+ if (WINDOWS)
+ var command = str + " > " + fileout.path;
+ else
+ var command = str + " > \"" + fileout.path.replace('"', '\\"') + "\"";
+
+ var filein = null;
+ if (input)
+ {
+ filein = this.createTempFile();
+ this.writeFile(filein, input);
+ command += " < \"" + filein.path.replace('"', '\\"') + "\"";
+ }
+
+ var res;
+ if (WINDOWS)
+ res = this.run("cmd.exe", ["/C", command], true);
+ else
+ res = this.run("sh", ["-c", command], true);
+
+ var output = this.readFile(fileout);
+ fileout.remove(false);
+ if (filein)
+ filein.remove(false);
+
+ // if there is only one \n at the end, chop it off
+ if (output && output.indexOf("\n") == output.length - 1)
+ output = output.substr(0, output.length - 1);
+
+ return output;
+ },
+
+ // files which end in .js are sourced as pure javascript files,
+ // no need (actually forbidden) to add: js <
-
+
+
+
diff --git a/content/options.js b/content/options.js
index b10aa867..32af4e66 100644
--- a/content/options.js
+++ b/content/options.js
@@ -420,6 +420,9 @@ vimperator.Options = function () //{{{
// this hack is only needed, because we need to do asynchronous loading of the .vimperatorrc
setInitialGUI: function ()
{
+ if (vimperator.config.name != "Vimperator")
+ return;
+
if (!guioptionsDone)
this.get("guioptions").reset();
if (!laststatusDone)
@@ -734,6 +737,12 @@ vimperator.Options = function () //{{{
// we start with an "empty" GUI so that no toolbars or tabbar is shown if the user
// sets them to empty in the .vimperatorrc, which is sourced asynchronously
+ if (vimperator.config.name != "Vimperator")
+ alert("mooh");
+ else alert("maeh");
+ if (vimperator.config.name != "Vimperator")
+ return optionManager;
+
setShowTabline(0);
setGuiOptions("");
setLastStatus(0);
diff --git a/content/util.js b/content/util.js
index 418d5af9..b5da1ba3 100644
--- a/content/util.js
+++ b/content/util.js
@@ -28,17 +28,6 @@ the terms of any one of the MPL, the GPL or the LGPL.
vimperator.util = { //{{{
- escapeHTML: function (str)
- {
- // XXX: the following code is _much_ slower than a simple .replace()
- // :history display went down from 2 to 1 second after changing
- //
- // var e = window.content.document.createElement("div");
- // e.appendChild(window.content.document.createTextNode(str));
- // return e.innerHTML;
- return str.replace(/&/g, "&").replace(//g, ">");
- },
-
// TODO: use :highlight color groups
// if "processStrings" is true, any passed strings will be surrounded by " and
// any line breaks are displayed as \n
@@ -90,65 +79,15 @@ vimperator.util = { //{{{
return "<unknown type>";
},
- // takes a string like 'google bla, www.osnews.com'
- // and returns an array ['www.google.com/search?q=bla', 'www.osnews.com']
- stringToURLArray: function (str)
+ escapeHTML: function (str)
{
- var urls = str.split(/\s*\,\s+/);
-
- begin: for (var url = 0; url < urls.length; url++)
- {
- // strip each 'URL' - makes things simpler later on
- urls[url] = urls[url].replace(/^\s+/, "").replace(/\s+$/, "");
-
- // first check if it is an existing local file
- var file = vimperator.io.getFile(urls[url]);
- if (file.exists() && file.isReadable())
- {
- urls[url] = file.path;
- continue;
- }
-
- // if the string doesn't look like a valid URL (i.e. contains a space
- // or does not contain any of: .:/) try opening it with a search engine
- // or keyword bookmark
- var matches;
- if (/\s/.test(urls[url]) || !/[.:\/]/.test(urls[url]))
- {
- matches = urls[url].match(/^(\S+)(?:\s+(.+))?$/);
-
- var alias = matches[1];
- var text = matches[2] || null;
-
- // TODO: it would be clearer if the appropriate call to
- // getSearchURL was made based on whether or not the first word was
- // indeed an SE alias rather than seeing if getSearchURL can
- // process the call usefully and trying again if it fails - much
- // like the comments below ;-)
-
- // check if the first word is a search engine
- var searchURL = vimperator.bookmarks.getSearchURL(text, alias);
- if (searchURL/* && searchURL.length >= 1*/)
- {
- urls[url] = searchURL;
- continue;
- }
- else // the first word was not a search engine, search for the whole string in the default engine
- {
- searchURL = vimperator.bookmarks.getSearchURL(urls[url], null);
- if (searchURL/* && searchURL.length >= 1*/)
- {
- urls[url] = searchURL;
- continue;
- }
- }
- }
-
- // if we are here let Firefox handle the url and hope it does
- // something useful with it :)
- }
-
- return urls;
+ // XXX: the following code is _much_ slower than a simple .replace()
+ // :history display went down from 2 to 1 second after changing
+ //
+ // var e = window.content.document.createElement("div");
+ // e.appendChild(window.content.document.createTextNode(str));
+ // return e.innerHTML;
+ return str.replace(/&/g, "&").replace(//g, ">");
},
formatBytes: function (num, decimalPlaces, humanReadable)
@@ -242,8 +181,121 @@ vimperator.util = { //{{{
return "" + vimperator.util.escapeHTML(str) + "";
else
return str;
- }
+ },
+ // if color = true it uses HTML markup to color certain items
+ objectToString: function (object, color)
+ {
+ if (object === null)
+ return "null";
+
+ if (typeof object != "object")
+ return false;
+
+ var string = "";
+ var obj = "";
+ try
+ { // for window.JSON
+ obj = object.toString();
+ }
+ catch (e)
+ {
+ obj = "<Object>";
+ }
+
+ if (color)
+ string += "" + obj + "::\n";
+ else
+ string += obj + "::\n";
+
+ try // window.content often does not want to be queried with "var i in object"
+ {
+ for (var i in object)
+ {
+ var value;
+ try
+ {
+ value = object[i];
+ }
+ catch (e)
+ {
+ value = "<no value>";
+ }
+
+ if (color)
+ {
+ value = this.colorize(value, true);
+ string += "" + i + ": " + value + "\n";
+ }
+ else
+ string += i + ": " + value + "\n";
+ }
+ }
+ catch (e) { }
+
+ return string;
+ },
+
+ // takes a string like 'google bla, www.osnews.com'
+ // and returns an array ['www.google.com/search?q=bla', 'www.osnews.com']
+ stringToURLArray: function (str)
+ {
+ var urls = str.split(/\s*\,\s+/);
+
+ begin: for (var url = 0; url < urls.length; url++)
+ {
+ // strip each 'URL' - makes things simpler later on
+ urls[url] = urls[url].replace(/^\s+/, "").replace(/\s+$/, "");
+
+ // first check if it is an existing local file
+ var file = vimperator.io.getFile(urls[url]);
+ if (file.exists() && file.isReadable())
+ {
+ urls[url] = file.path;
+ continue;
+ }
+
+ // if the string doesn't look like a valid URL (i.e. contains a space
+ // or does not contain any of: .:/) try opening it with a search engine
+ // or keyword bookmark
+ var matches;
+ if (/\s/.test(urls[url]) || !/[.:\/]/.test(urls[url]))
+ {
+ matches = urls[url].match(/^(\S+)(?:\s+(.+))?$/);
+
+ var alias = matches[1];
+ var text = matches[2] || null;
+
+ // TODO: it would be clearer if the appropriate call to
+ // getSearchURL was made based on whether or not the first word was
+ // indeed an SE alias rather than seeing if getSearchURL can
+ // process the call usefully and trying again if it fails - much
+ // like the comments below ;-)
+
+ // check if the first word is a search engine
+ var searchURL = vimperator.bookmarks.getSearchURL(text, alias);
+ if (searchURL/* && searchURL.length >= 1*/)
+ {
+ urls[url] = searchURL;
+ continue;
+ }
+ else // the first word was not a search engine, search for the whole string in the default engine
+ {
+ searchURL = vimperator.bookmarks.getSearchURL(urls[url], null);
+ if (searchURL/* && searchURL.length >= 1*/)
+ {
+ urls[url] = searchURL;
+ continue;
+ }
+ }
+ }
+
+ // if we are here let Firefox handle the url and hope it does
+ // something useful with it :)
+ }
+
+ return urls;
+ }
}; //}}}
// vim: set fdm=marker sw=4 ts=4 et:
diff --git a/content/vimperator.js b/content/vimperator.js
index 3fdd4445..0f0959cc 100644
--- a/content/vimperator.js
+++ b/content/vimperator.js
@@ -26,759 +26,8 @@ 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 *****/
-const vimperator = (function () //{{{
-{
- ////////////////////////////////////////////////////////////////////////////////
- ////////////////////// PRIVATE SECTION /////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////{{{
-
- var callbacks = [];
-
- /////////////////////////////////////////////////////////////////////////////}}}
- ////////////////////// PUBLIC SECTION //////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////{{{
-
- return {
-
- get mode() { return vimperator.modes.main; },
- set mode(value) { vimperator.modes.main = value; },
-
- // Global constants
- CURRENT_TAB: 1,
- NEW_TAB: 2,
- NEW_BACKGROUND_TAB: 3,
- NEW_WINDOW: 4,
-
- // ###VERSION### and ###DATE### are replaced by the Makefile
- version: "###VERSION### (created: ###DATE###)",
-
- input: {
- buffer: "", // partial command storage
- pendingMotionMap: null, // e.g. "d{motion}" if we wait for a motion of the "d" command
- pendingArgMap: null, // pending map storage for commands like m{a-z}
- count: -1 // parsed count from the input buffer
- },
-
- // @param type can be:
- // "submit": when the user pressed enter in the command line
- // "change"
- // "cancel"
- // "complete"
- // TODO: "zoom": if the zoom value of the current buffer changed
- registerCallback: function (type, mode, func)
- {
- // TODO: check if callback is already registered
- callbacks.push([type, mode, func]);
- },
-
- triggerCallback: function (type, mode, data)
- {
- // dump("type: " + type + " mode: " + mode + "data: " + data + "\n");
- for (var i in callbacks)
- {
- var [thistype, thismode, thisfunc] = callbacks[i];
- if (mode == thismode && type == thistype)
- return thisfunc.call(this, data);
- }
- return false;
- },
-
- beep: function ()
- {
- if (vimperator.options["visualbell"])
- {
- // flash the visual bell
- var popup = document.getElementById("vimperator-visualbell");
- var win = getBrowser().mPanelContainer;
- var box = document.getBoxObjectFor(win);
-
- popup.height = box.height;
- popup.width = box.width;
- popup.openPopup(win, "overlap", 0, 0, false, false);
- setTimeout(function () { popup.hidePopup(); }, 50);
- }
- else
- {
- var soundService = Components.classes["@mozilla.org/sound;1"].
- getService(Components.interfaces.nsISound);
- soundService.beep();
- }
- },
-
- copyToClipboard: function (str, verbose)
- {
- var clipboardHelper = Components.classes["@mozilla.org/widget/clipboardhelper;1"]
- .getService(Components.interfaces.nsIClipboardHelper);
- clipboardHelper.copyString(str);
-
- if (verbose)
- vimperator.echo("Yanked " + str, vimperator.commandline.FORCE_SINGLELINE);
- },
-
- execute: function (str, modifiers)
- {
- // skip comments and blank lines
- if (/^\s*("|$)/.test(str))
- return;
-
- if (!modifiers)
- modifiers = {};
-
- var [count, cmd, special, args] = vimperator.commands.parseCommand(str.replace(/^'(.*)'$/, "$1"));
- var command = vimperator.commands.get(cmd);
-
- if (command === null)
- {
- vimperator.echoerr("E492: Not an editor command: " + str);
- vimperator.focusContent();
- return;
- }
-
- // TODO: need to perform this test? -- djk
- if (command.action === null)
- {
- vimperator.echoerr("E666: Internal error: command.action === null");
- return;
- }
-
- // valid command, call it:
- command.execute(args, special, count, modifiers);
- },
-
- // after pressing Escape, put focus on a non-input field of the browser document
- // if clearFocusedElement, also blur a focused link
- focusContent: function (clearFocusedElement)
- {
- var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"].
- getService(Components.interfaces.nsIWindowWatcher);
-
- if (window == ww.activeWindow && document.commandDispatcher.focusedElement && clearFocusedElement)
- document.commandDispatcher.focusedElement.blur();
-
- content.focus();
- },
-
- // partial sixth level expression evaluation
- eval: function (string)
- {
- string = string.toString().replace(/^\s*/, "").replace(/\s*$/, "");
- var matches = string.match(/^&(\w+)/);
- if (matches)
- {
- var opt = this.options.get(matches[1]);
- if (!opt)
- {
- this.echoerr("E113: Unknown option: " + matches[1]);
- return;
- }
- var type = opt.type;
- var value = opt.getter();
- if (type != "boolean" && type != "number")
- value = value.toString();
- return value;
- }
-
- // String
- else if (matches = string.match(/^(['"])([^\1]*?[^\\]?)\1/))
- {
- if (matches)
- return matches[2].toString();
- else
- {
- this.echoerr("E115: Missing quote: " + string);
- return;
- }
- }
-
- // Number
- else if (matches = string.match(/^(\d+)$/))
- {
- return parseInt(match[1], 10);
- }
-
- var reference = this.variableReference(string);
- if (!reference[0])
- this.echoerr("E121: Undefined variable: " + string);
- else
- return reference[0][reference[1]];
-
- return;
- },
-
- variableReference: function (string)
- {
- if (!string)
- return [null, null, null];
-
- var matches = string.match(/^([bwtglsv]):(\w+)/);
- if (matches) // Variable
- {
- // Other variables should be implemented
- if (matches[1] == "g")
- {
- if (matches[2] in this.globalVariables)
- return [this.globalVariables, matches[2], matches[1]];
- else
- return [null, matches[2], matches[1]];
- }
- }
- else // Global variable
- {
- if (string in this.globalVariables)
- return [this.globalVariables, string, "g"];
- else
- return [null, string, "g"];
- }
- },
-
- // TODO: move to vimp.util.? --mst
- // if color = true it uses HTML markup to color certain items
- objectToString: function (object, color)
- {
- if (object === null)
- return "null";
-
- if (typeof object != "object")
- return false;
-
- var string = "";
- var obj = "";
- try
- { // for window.JSON
- obj = object.toString();
- }
- catch (e)
- {
- obj = "<Object>";
- }
-
- if (color)
- string += "" + obj + "::\n";
- else
- string += obj + "::\n";
-
- try // window.content often does not want to be queried with "var i in object"
- {
- for (var i in object)
- {
- var value;
- try
- {
- value = object[i];
- }
- catch (e)
- {
- value = "<no value>";
- }
-
- if (color)
- {
- value = vimperator.util.colorize(value, true);
- string += "" + i + ": " + value + "\n";
- }
- else
- string += i + ": " + value + "\n";
- }
- }
- catch (e) { }
-
- return string;
- },
-
- // logs a message to the javascript error console
- // if msg is an object, it is beautified
- log: function (msg, level)
- {
- //if (vimperator.options.getPref("verbose") >= level) // FIXME: hangs vimperator, probably timing issue --mst
- if (typeof msg == "object")
- msg = this.objectToString(msg, false);
-
- var consoleService = Components.classes["@mozilla.org/consoleservice;1"].
- getService(Components.interfaces.nsIConsoleService);
- consoleService.logStringMessage("vimperator: " + msg);
- },
-
- // open one or more URLs
- //
- // @param urls: either a string or an array of urls
- // The array can look like this:
- // ["url1", "url2", "url3", ...] or:
- // [["url1", postdata1], ["url2", postdata2], ...]
- // @param where: if ommited, CURRENT_TAB is assumed
- // @param callback: not implemented, will be allowed to specify a callback function
- // which is called, when the page finished loading
- // @returns true when load was initiated, or false on error
- open: function (urls, where, callback)
- {
- // convert the string to an array of converted URLs
- // -> see vimperator.util.stringToURLArray for more details
- if (typeof urls == "string")
- urls = vimperator.util.stringToURLArray(urls);
-
- if (urls.length == 0)
- return false;
-
- if (!where)
- where = vimperator.CURRENT_TAB;
-
- var url = typeof urls[0] == "string" ? urls[0] : urls[0][0];
- var postdata = typeof urls[0] == "string" ? null : urls[0][1];
- var whichwindow = window;
-
- // decide where to load the first url
- switch (where)
- {
- case vimperator.CURRENT_TAB:
- window.loadURI(url, null, postdata); // getBrowser.loadURI() did not work with postdata in my quick experiments --mst
- break;
-
- case vimperator.NEW_TAB:
- var firsttab = getBrowser().addTab(url, null, null, postdata);
- getBrowser().selectedTab = firsttab;
- break;
-
- case vimperator.NEW_BACKGROUND_TAB:
- getBrowser().addTab(url, null, null, postdata);
- break;
-
- case vimperator.NEW_WINDOW:
- window.open();
- var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
- whichwindow = wm.getMostRecentWindow("navigator:browser");
- whichwindow.loadURI(url, null, postdata);
- break;
-
- default:
- vimperator.echoerr("Exxx: Invalid 'where' directive in vimperator.open(...)");
- return false;
- }
-
- // all other URLs are always loaded in background
- for (var i = 1; i < urls.length; i++)
- {
- url = typeof urls[i] == "string" ? urls[i] : urls[i][0];
- postdata = typeof urls[i] == "string" ? null : urls[i][1];
- whichwindow.getBrowser().addTab(url, null, null, postdata);
- }
-
- // TODO: register callbacks
-
- return true;
- },
-
- // quit vimperator, no matter how many tabs/windows are open
- quit: function (saveSession)
- {
- vimperator.autocommands.trigger("BrowserExit", "");
-
- if (saveSession)
- vimperator.options.setFirefoxPref("browser.startup.page", 3); // start with saved session
- else
- vimperator.options.setFirefoxPref("browser.startup.page", 1); // start with default homepage session
-
- goQuitApplication();
- },
-
- restart: function ()
- {
- vimperator.autocommands.trigger("BrowserRestart", "");
-
- const nsIAppStartup = Components.interfaces.nsIAppStartup;
-
- // notify all windows that an application quit has been requested.
- var os = Components.classes["@mozilla.org/observer-service;1"]
- .getService(Components.interfaces.nsIObserverService);
- var cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"]
- .createInstance(Components.interfaces.nsISupportsPRBool);
- os.notifyObservers(cancelQuit, "quit-application-requested", null);
-
- // something aborted the quit process.
- if (cancelQuit.data)
- return;
-
- // notify all windows that an application quit has been granted.
- os.notifyObservers(null, "quit-application-granted", null);
-
- // enumerate all windows and call shutdown handlers
- var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
- var windows = wm.getEnumerator(null);
- while (windows.hasMoreElements())
- {
- var win = windows.getNext();
- if (("tryToClose" in win) && !win.tryToClose())
- return;
- }
- Components.classes["@mozilla.org/toolkit/app-startup;1"].getService(nsIAppStartup)
- .quit(nsIAppStartup.eRestart | nsIAppStartup.eAttemptQuit);
- },
-
- run: function (program, args, blocking)
- {
- var file = Components.classes["@mozilla.org/file/local;1"].
- createInstance(Components.interfaces.nsILocalFile);
- const WINDOWS = navigator.platform == "Win32";
-
- if (!args)
- args = [];
-
- if (typeof blocking != "boolean")
- blocking = false;
-
- try
- {
- file.initWithPath(program);
- }
- catch (e)
- {
- var environmentService = Components.classes["@mozilla.org/process/environment;1"]
- .getService(Components.interfaces.nsIEnvironment);
-
- var dirs = environmentService.get("PATH").split(WINDOWS ? ";" : ":");
- for (var i = 0; i < dirs.length; i++)
- {
- var path = dirs[i] + (WINDOWS ? "\\" : "/") + program;
- try
- {
- file.initWithPath(path);
- if (file.exists())
- break;
- }
- catch (e) { }
- }
- }
-
- if (!file.exists())
- {
- vimperator.echoerr("command not found: " + program);
- return -1;
- }
-
- var process = Components.classes["@mozilla.org/process/util;1"].
- createInstance(Components.interfaces.nsIProcess);
- process.init(file);
-
- var ec = process.run(blocking, args, args.length);
- return ec;
- },
-
- // when https://bugzilla.mozilla.org/show_bug.cgi?id=68702 is fixed
- // is fixed, should use that instead of a tmpfile
- // TODO: add shell/shellcmdflag options to replace "sh" and "-c"
- system: function (str, input)
- {
- const WINDOWS = navigator.platform == "Win32"; // FIXME: duplicated everywhere
-
- var fileout = vimperator.io.createTempFile();
- if (!fileout)
- return "";
-
- if (WINDOWS)
- var command = str + " > " + fileout.path;
- else
- var command = str + " > \"" + fileout.path.replace('"', '\\"') + "\"";
-
- var filein = null;
- if (input)
- {
- filein = vimperator.io.createTempFile();
- vimperator.io.writeFile(filein, input);
- command += " < \"" + filein.path.replace('"', '\\"') + "\"";
- }
-
- var res;
- if (WINDOWS)
- res = this.run("cmd.exe", ["/C", command], true);
- else
- res = this.run("sh", ["-c", command], true);
-
- var output = vimperator.io.readFile(fileout);
- fileout.remove(false);
- if (filein)
- filein.remove(false);
-
- // if there is only one \n at the end, chop it off
- if (output && output.indexOf("\n") == output.length - 1)
- output = output.substr(0, output.length - 1);
-
- return output;
- },
-
- // files which end in .js are sourced as pure javascript files,
- // no need (actually forbidden) to add: js < string to show on v.modes.CUSTOM
- // v.plugins.stop = hooked on a v.modes.reset()
- // v.plugins.onEvent = function triggered, on keypresses (unless ) (see events.js)
- vimperator.plugins = {};
-
- // TODO: move elsewhere
- vimperator.registerCallback("submit", vimperator.modes.EX, function (command) { vimperator.execute(command); });
- vimperator.registerCallback("complete", vimperator.modes.EX, function (str) { return vimperator.completion.exTabCompletion(str); });
-
- // first time intro message
- if (vimperator.options.getPref("firsttime", true))
- {
- setTimeout(function () {
- vimperator.commands.help();
- vimperator.options.setPref("firsttime", false);
- }, 1000);
- }
-
- // disable caret browsing initially
- //vimperator.options.setFirefoxPref("accessibility.browsewithcaret", false);
- //vimperator.focusContent();
-
- // always start in normal mode
- vimperator.modes.reset();
-
- // finally, read a ~/.vimperatorrc
- // make sourcing asynchronous, otherwise commands that open new tabs won't work
- setTimeout(function () {
-
- var rcFile = vimperator.io.getRCFile();
-
- if (rcFile)
- vimperator.source(rcFile.path, true);
- else
- vimperator.log("No user RC file found", 3);
-
- // also source plugins in ~/.vimperator/plugin/
- try
- {
- var pluginDir = vimperator.io.getSpecialDirectory("plugin");
- if (pluginDir)
- {
- var files = vimperator.io.readDirectory(pluginDir.path);
- vimperator.log("Sourcing plugin directory...", 3);
- files.forEach(function (file) {
- if (!file.isDirectory() && /\.(js|vimp)$/i.test(file.path))
- vimperator.source(file.path, false);
- });
- }
- else
- {
- vimperator.log("No user plugin directory found", 3);
- }
- }
- catch (e)
- {
- // thrown if directory does not exist
- //vimperator.log("Error sourcing plugin directory: " + e);
- }
-
- // after sourcing the initialization files, this function will set
- // all gui options to their default values, if they have not been
- // set before by any rc file
- vimperator.options.setInitialGUI();
- }, 0);
-
- vimperator.statusline.update();
- vimperator.log("Vimperator fully initialized", 1);
- },
-
- shutdown: function ()
- {
- window.dump("Vimperator shutdown\n");
-
- // save our preferences
- vimperator.commandline.destroy();
- vimperator.quickmarks.destroy();
- vimperator.options.destroy();
- vimperator.events.destroy();
-
- window.dump("All vimperator modules destroyed\n");
- },
-
- sleep: function (ms)
- {
- var threadManager = Components.classes["@mozilla.org/thread-manager;1"].
- getService(Components.interfaces.nsIThreadManager);
- var mainThread = threadManager.mainThread;
-
- var then = new Date().getTime(), now = then;
- for (; now - then < ms; now = new Date().getTime())
- mainThread.processNextEvent(true);
- },
-
- get windows()
- {
- var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
- var wa = [];
- var enumerator = wm.getEnumerator("navigator:browser");
- while (enumerator.hasMoreElements())
- wa.push(enumerator.getNext());
- return wa;
- },
-
- // be sure to call GUI related methods like alert() or dump() ONLY in the main thread
- callFunctionInThread: function (thread, func, args)
- {
- function CallbackEvent(func, args)
- {
- if (!(args instanceof Array))
- args = [];
-
- return {
- QueryInterface: function (iid)
- {
- if (iid.equals(Components.interfaces.nsIRunnable) ||
- iid.equals(Components.interfaces.nsISupports))
- return this;
- throw Components.results.NS_ERROR_NO_INTERFACE;
- },
-
- run: function ()
- {
- func.apply(window, args);
- }
- };
- }
-
- if (!thread)
- thread = Components.classes["@mozilla.org/thread-manager;1"].getService().newThread(0);
-
- // DISPATCH_SYNC is necessary, otherwise strange things will happen
- thread.dispatch(new CallbackEvent(func, args), thread.DISPATCH_SYNC);
- }
-
- }; //}}}
-})(); //}}}
-
-// called when the chrome is fully loaded and before the main window is shown
-window.addEventListener("load", vimperator.startup, false);
-window.addEventListener("unload", vimperator.shutdown, false);
-
-// vim: set fdm=marker sw=4 ts=4 et:
+vimperator.config = {
+ name: "Vimperator",
+ hostApplication: "Firefox",
+ dialogs: []
+}
diff --git a/content/vimperator.xul b/content/vimperator.xul
index ba3f59fc..5858172d 100644
--- a/content/vimperator.xul
+++ b/content/vimperator.xul
@@ -37,7 +37,9 @@ the terms of any one of the MPL, the GPL or the LGPL.
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+