summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/content/buffer.js9
-rw-r--r--common/content/commandline.js3
-rw-r--r--common/content/dactyl.js4
-rw-r--r--common/content/events.js47
-rw-r--r--common/content/hints.js204
-rw-r--r--common/content/mappings.js22
-rw-r--r--common/modules/services.jsm1
-rw-r--r--common/modules/util.jsm2
8 files changed, 163 insertions, 129 deletions
diff --git a/common/content/buffer.js b/common/content/buffer.js
index 0e3f54f2..f5e0725b 100644
--- a/common/content/buffer.js
+++ b/common/content/buffer.js
@@ -1021,11 +1021,10 @@ var Buffer = Module("buffer", {
this.callback(file);
else {
this.file = io.createTempFile();
- var webBrowserPersist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
- .createInstance(Ci.nsIWebBrowserPersist);
- webBrowserPersist.persistFlags = webBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
- webBrowserPersist.progressListener = this;
- webBrowserPersist.saveURI(uri, null, null, null, null, this.file);
+ var persist = services.Persist();
+ persist.persistFlags = persist.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
+ persist.progressListener = this;
+ persist.saveURI(uri, null, null, null, null, this.file);
}
return null;
},
diff --git a/common/content/commandline.js b/common/content/commandline.js
index a8e58e23..ceaab95d 100644
--- a/common/content/commandline.js
+++ b/common/content/commandline.js
@@ -757,9 +757,6 @@ var CommandLine = Module("commandline", {
* the MOW.
*/
echo: function echo(str, highlightGroup, flags) {
- if (String(str) == "undefined")
- util.dumpStack();
-
// dactyl.echo uses different order of flags as it omits the highlight group, change commandline.echo argument order? --mst
if (this._silent)
return;
diff --git a/common/content/dactyl.js b/common/content/dactyl.js
index 04b4e38d..4a29001f 100644
--- a/common/content/dactyl.js
+++ b/common/content/dactyl.js
@@ -2131,12 +2131,12 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
dactyl.log("All modules loaded", 3);
- AddonManager.getAddonByID(services["dactyl:"].addonID, function (addon) {
+ AddonManager.getAddonByID(services["dactyl:"].addonID, this.wrapCallback(function (addon) {
// @DATE@ token replaced by the Makefile
// TODO: Find it automatically
prefs.set("extensions.dactyl.version", addon.version);
dactyl.version = addon.version + " (created: @DATE@)";
- });
+ }));
if (!services.commandLineHandler)
services.add("commandLineHandler", "@mozilla.org/commandlinehandler/general-startup;1?type=" + config.name);
diff --git a/common/content/events.js b/common/content/events.js
index bb6cb901..02944678 100644
--- a/common/content/events.js
+++ b/common/content/events.js
@@ -47,19 +47,29 @@ var Events = Module("events", {
this._keyTable = {
add: ["Plus", "Add"],
back_space: ["BS"],
+ count: ["count"],
delete: ["Del"],
escape: ["Esc", "Escape"],
insert: ["Insert", "Ins"],
+ leader: ["Leader"],
left_shift: ["LT", "<"],
+ nop: ["Nop"],
return: ["Return", "CR", "Enter"],
right_shift: [">"],
space: ["Space", " "],
subtract: ["Minus", "Subtract"]
};
+ this._pseudoKeys = set(["count", "leader", "nop"]);
+
+ this._key_key = {};
this._code_key = {};
this._key_code = {};
+ for (let list in values(this._keyTable))
+ for (let v in values(list))
+ this._key_key[v.toLowerCase()] = v;
+
for (let [k, v] in Iterator(KeyEvent)) {
k = k.substr(7).toLowerCase();
let names = [k.replace(/(^|_)(.)/g, function (m, n1, n2) n2.toUpperCase())
@@ -67,8 +77,10 @@ var Events = Module("events", {
if (k in this._keyTable)
names = this._keyTable[k];
this._code_key[v] = names[0];
- for (let [, name] in Iterator(names))
+ for (let [, name] in Iterator(names)) {
+ this._key_key[name.toLowerCase()] = name;
this._key_code[name.toLowerCase()] = v;
+ }
}
// HACK: as Gecko does not include an event for <, we must add this in manually.
@@ -436,7 +448,7 @@ var Events = Module("events", {
keyname = String.fromCharCode(parseInt(keyname.substr(1), 16));
if (keyname && (unknownOk || keyname.length == 1 || /mouse$/.test(keyname) ||
- this._key_code[keyname] || keyname == "nop")) {
+ this._key_code[keyname] || set.has(this._pseudoKeys, keyname))) {
evt_obj.ctrlKey = /C-/.test(modifier);
evt_obj.altKey = /A-/.test(modifier);
evt_obj.shiftKey = /S-/.test(modifier);
@@ -451,8 +463,8 @@ var Events = Module("events", {
evt_obj.charCode = keyname.charCodeAt(0);
}
- else if (keyname == "nop") {
- evt_obj.dactylString = "<Nop>";
+ else if (set.has(this._pseudoKeys)) {
+ evt_obj.dactylString = "<" + this._key_key[keyname] + ">";
}
else if (/mouse$/.test(keyname)) { // mouse events
evt_obj.type = (/2-/.test(modifier) ? "dblclick" : "click");
@@ -576,7 +588,7 @@ var Events = Module("events", {
}
}
if (key == null)
- key = event.dactylKeyname;
+ key = this._key_key[event.dactylKeyname] || event.dactylKeyname;
if (key == null)
return null;
}
@@ -1070,9 +1082,9 @@ var Events = Module("events", {
const self = this;
let key = events.toString(event);
- let [, countStr, candidateCommand] = /^((?:[1-9][0-9]*)?)(.*)/.exec(this.buffer + key);
+ let [, countStr, command] = /^((?:[1-9][0-9]*)?)(.*)/.exec(this.buffer + key);
- let map = mappings[event.noremap ? "getDefault" : "get"](this.main, candidateCommand);
+ let map = mappings[event.noremap ? "getDefault" : "get"](this.main, command);
function execute(map) {
if (self.preExecute)
@@ -1083,7 +1095,7 @@ var Events = Module("events", {
return res;
}
- let candidates = mappings.getCandidates(this.main, candidateCommand);
+ let candidates = mappings.getCandidates(this.main, command);
if (candidates.length == 0 && !map) {
map = this.pendingMap;
this.pendingMap = null;
@@ -1092,7 +1104,7 @@ var Events = Module("events", {
}
// counts must be at the start of a complete mapping (10j -> go 10 lines down)
- if (countStr && !candidateCommand) {
+ if (countStr && !command) {
// no count for insert mode mappings
if (!this.main.count)
return this.append(event);
@@ -1102,9 +1114,9 @@ var Events = Module("events", {
this.append(event);
}
else if (this.pendingArgMap) {
- let map = this.pendingArgMap;
+ let [map, command] = this.pendingArgMap;
if (!Events.isEscape(key))
- execute(map, null, this.count, key);
+ execute(map, null, this.count, key, command);
return true;
}
else if (map && !event.skipmap && candidates.length == 0) {
@@ -1118,27 +1130,28 @@ var Events = Module("events", {
if (map.arg) {
this.append(event);
- this.pendingArgMap = map;
+ this.pendingArgMap = [map, command];
}
else if (this.pendingMotionMap) {
+ let [map, command] = this.pendingMotionMap;
if (!Events.isEscape(key))
- execute(this.pendingMotionMap, candidateCommand, this.motionCount || this.count, null);
+ execute(map, command, this.motionCount || this.count, null, command);
return true;
}
else if (map.motion) {
this.buffer = "";
- this.pendingMotionMap = map;
+ this.pendingMotionMap = [map, command];
}
else {
if (modes.replaying && !this.waitForPageLoad())
return true;
- return !execute(map, null, this.count) || !map.route
+ return !execute(map, null, this.count, null, command) || !map.route
}
}
- else if (mappings.getCandidates(this.main, candidateCommand).length > 0 && !event.skipmap) {
+ else if (mappings.getCandidates(this.main, command).length > 0 && !event.skipmap) {
this.append(event);
- this.pendingMap = map;
+ this.pendingMap = [map, command];
}
else {
this.append(event);
diff --git a/common/content/hints.js b/common/content/hints.js
index f71d07b7..b2e97bd5 100644
--- a/common/content/hints.js
+++ b/common/content/hints.js
@@ -75,6 +75,15 @@ var Hints = Module("hints", {
},
/**
+ * Clear any timeout which might be active after pressing a number
+ */
+ clearTimeout: function () {
+ if (this._activeTimeout)
+ this._activeTimeout.cancel();
+ this._activeTimeout = null;
+ },
+
+ /**
* Reset hints, so that they can be cleanly used again.
*/
_reset: function _reset(slight) {
@@ -92,10 +101,7 @@ var Hints = Module("hints", {
this._pageHints = [];
this._validHints = [];
this._docs = [];
-
- if (this._activeTimeout)
- this._activeTimeout.cancel();
- this._activeTimeout = null;
+ this.clearTimeout();
},
__reset: function __reset() {
if (!this._usedTabKey)
@@ -582,11 +588,7 @@ var Hints = Module("hints", {
_onInput: function _onInput(event) {
this.prevInput = "text";
- // clear any timeout which might be active after pressing a number
- if (this._activeTimeout) {
- this._activeTimeout.cancel();
- this._activeTimeout = null;
- }
+ this.clearTimeout();
this._hintNumber = 0;
this._hintString = commandline.command;
@@ -896,104 +898,38 @@ var Hints = Module("hints", {
*/
onEvent: function onEvent(event) {
let key = events.toString(event);
- let followFirst = false;
-
- // clear any timeout which might be active after pressing a number
- if (this._activeTimeout) {
- this._activeTimeout.cancel();
- this._activeTimeout = null;
- }
-
- switch (key) {
- case "<Return>":
- followFirst = true;
- break;
-
- case "<Tab>":
- case "<S-Tab>":
- this._usedTabKey = true;
- if (this._hintNumber == 0)
- this._hintNumber = 1;
- let oldId = this._hintNumber;
- if (key == "<Tab>") {
- if (++this._hintNumber > this._validHints.length)
- this._hintNumber = 1;
- }
- else {
- if (--this._hintNumber < 1)
- this._hintNumber = this._validHints.length;
- }
- this._showActiveHint(this._hintNumber, oldId);
- this._updateStatusline();
- return false;
+ this.clearTimeout();
- case "<BS>":
- if (this.prevInput !== "number")
- return true;
+ if (!this.escNumbers && this.isHintKey(key)) {
+ this.prevInput = "number";
- if (this._hintNumber > 0 && !this._usedTabKey) {
- this._hintNumber = Math.floor(this._hintNumber / this.hintKeys.length);
- if (this._hintNumber == 0)
- this.prevInput = "text";
- }
- else {
- this._usedTabKey = false;
+ let oldHintNumber = this._hintNumber;
+ if (this._usedTabKey) {
this._hintNumber = 0;
- dactyl.beep();
- return;
+ this._usedTabKey = false;
}
- break;
-
- case options["mapleader"]:
- hints.escNumbers = !hints.escNumbers;
- if (hints.escNumbers && this._usedTabKey)
- this._hintNumber = 0;
-
- this._updateStatusline();
- return false;
-
- default:
- if (!this.escNumbers && this.isHintKey(key)) {
- this.prevInput = "number";
-
- let oldHintNumber = this._hintNumber;
- if (this._usedTabKey) {
- this._hintNumber = 0;
- this._usedTabKey = false;
- }
- this._hintNumber = this._hintNumber * this.hintKeys.length +
- this.hintKeys.indexOf(key);
-
- this._updateStatusline();
-
- if (!this._canUpdate)
- return;
+ this._hintNumber = this._hintNumber * this.hintKeys.length +
+ this.hintKeys.indexOf(key);
- if (this._docs.length == 0) {
- this._generate();
- this._showHints();
- }
- this._showActiveHint(this._hintNumber, oldHintNumber || 1);
+ this._updateStatusline();
- dactyl.assert(this._hintNumber != 0);
+ if (!this._canUpdate)
+ return;
- this._checkUnique();
- return false;
+ if (this._docs.length == 0) {
+ this._generate();
+ this._showHints();
}
- return true;
- }
+ this._showActiveHint(this._hintNumber, oldHintNumber || 1);
- this._updateStatusline();
-
- if (this._canUpdate) {
- if (this._docs.length == 0 && this._hintString.length > 0)
- this._generate();
+ dactyl.assert(this._hintNumber != 0);
- this._showHints();
- this._processHints(followFirst);
+ this._checkUnique();
+ return false;
}
- return false;
+
+ return !Events.isEscape(key);
}
//}}}
}, {
@@ -1118,6 +1054,84 @@ var Hints = Module("hints", {
"Start an extended hint mode and stay there until <Esc> is pressed",
function (count) { hints.open("g;", { continue: true, count: count }); },
{ count: true });
+
+ function update(followFirst) {
+ hints.clearTimeout();
+ hints._updateStatusline();
+
+ if (hints._canUpdate) {
+ if (hints._docs.length == 0 && hints._hintString.length > 0)
+ hints._generate();
+
+ hints._showHints();
+ hints._processHints(followFirst);
+ }
+ }
+
+ mappings.add(modes.HINTS, ["<Return>"],
+ "Follow the selected hint",
+ function () { update(true) });
+
+ function tab(previous) {
+ hints.clearTimeout();
+ this._usedTabKey = true;
+ if (this._hintNumber == 0)
+ this._hintNumber = 1;
+
+ let oldId = this._hintNumber;
+ if (!previous) {
+ if (++this._hintNumber > this._validHints.length)
+ this._hintNumber = 1;
+ }
+ else {
+ if (--this._hintNumber < 1)
+ this._hintNumber = this._validHints.length;
+ }
+
+ this._showActiveHint(this._hintNumber, oldId);
+ this._updateStatusline();
+ }
+
+ mappings.add(modes.HINTS, ["<Tab>"],
+ "Focus the next matching hint",
+ function () { tab.call(hints, false) });
+
+ mappings.add(modes.HINTS, ["<S-Tab>"],
+ "Focus the previous matching hint",
+ function () { tab.call(hints, true) });
+
+ mappings.add(modes.HINTS, ["<BS>", "<C-h>"],
+ "Delete the previous character",
+ function () {
+ hints.clearTimeout();
+ if (hints.prevInput !== "number")
+ return true;
+
+ if (hints._hintNumber > 0 && !hints._usedTabKey) {
+ hints._hintNumber = Math.floor(hints._hintNumber / hints.hintKeys.length);
+ if (hints._hintNumber == 0)
+ hints.prevInput = "text";
+ update(false);
+ }
+ else {
+ hints._usedTabKey = false;
+ hints._hintNumber = 0;
+ dactyl.beep();
+ }
+ return false;
+ },
+ { route: true });
+
+ mappings.add(modes.HINTS, ["<Leader>"],
+ "Toggle hint filtering",
+ function () {
+ hints.clearTimeout();
+ hints.escNumbers = !hints.escNumbers;
+ if (hints.escNumbers && hints._usedTabKey)
+ hints._hintNumber = 0;
+
+ hints._updateStatusline();
+ });
},
options: function () {
const DEFAULT_HINTTAGS =
diff --git a/common/content/mappings.js b/common/content/mappings.js
index d3a2a25d..a84bbf92 100644
--- a/common/content/mappings.js
+++ b/common/content/mappings.js
@@ -90,7 +90,9 @@ var Map = Class("Map", {
* @param {string} name The name to query.
* @returns {boolean}
*/
- hasName: function (name) this.names.indexOf(name) >= 0,
+ hasName: function (name) this.keys.indexOf(name) >= 0,
+
+ keys: Class.memoize(function () this.names.map(mappings._expandLeader)),
/**
* Execute the action for this mapping.
@@ -102,7 +104,7 @@ var Map = Class("Map", {
* @param {string} argument The normal argument if accepted by this
* mapping. E.g. "a" for "ma"
*/
- execute: function (motion, count, argument) {
+ execute: function (motion, count, argument, command) {
let args = [];
if (this.motion)
@@ -111,6 +113,7 @@ var Map = Class("Map", {
args.push(count);
if (this.arg)
args.push(argument);
+ args.push(command);
let self = this;
function repeat() self.action.apply(self, args);
@@ -153,10 +156,9 @@ var Mappings = Module("mappings", {
_getMap: function (mode, cmd, stack) {
let maps = stack[mode] || [];
- for (let [, map] in Iterator(maps)) {
+ for (let [, map] in Iterator(maps))
if (map.hasName(cmd))
return map;
- }
return null;
},
@@ -233,7 +235,6 @@ var Mappings = Module("mappings", {
* @optional
*/
addUserMap: function (modes, keys, description, action, extra) {
- keys = keys.map(this._expandLeader);
extra = extra || {};
extra.user = true;
let map = Map(modes, keys, description, action, extra);
@@ -631,7 +632,16 @@ var Mappings = Module("mappings", {
options: function () {
options.add(["mapleader", "ml"],
"Define the replacement keys for the <Leader> pseudo-key",
- "string", "\\");
+ "string", "\\", {
+ setter: function (value) {
+ if (this.hasChanged)
+ for (let hive in values([mappings._user, mappings._main]))
+ for (let mode in values(hive))
+ for (let map in values(mode))
+ delete map.keys;
+ return value;
+ }
+ });
}
});
diff --git a/common/modules/services.jsm b/common/modules/services.jsm
index 8c30b004..c29ecb95 100644
--- a/common/modules/services.jsm
+++ b/common/modules/services.jsm
@@ -66,6 +66,7 @@ var Services = Module("Services", {
this.addClass("Find", "@mozilla.org/embedcomp/rangefind;1", Ci.nsIFind);
this.addClass("HtmlConverter","@mozilla.org/widget/htmlformatconverter;1", Ci.nsIFormatConverter);
this.addClass("HtmlEncoder", "@mozilla.org/layout/htmlCopyEncoder;1", Ci.nsIDocumentEncoder);
+ this.addClass("Persist", "@mozilla.org/embedding/browser/nsWebBrowserPersist;1", Ci.nsIWebBrowserPersist);
this.addClass("Process", "@mozilla.org/process/util;1", Ci.nsIProcess, "init");
this.addClass("String", "@mozilla.org/supports-string;1", Ci.nsISupportsString);
this.addClass("Timer", "@mozilla.org/timer;1", Ci.nsITimer, "initWithCallback");
diff --git a/common/modules/util.jsm b/common/modules/util.jsm
index a5547713..cb8c65b6 100644
--- a/common/modules/util.jsm
+++ b/common/modules/util.jsm
@@ -486,7 +486,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
*/
dumpStack: function dumpStack(msg, frames) {
let stack = util.stackLines(Error().stack);
- stack = stack.slice(2, 2 + (frames || stack.length)).join("\n").replace(/^/gm, " ");
+ stack = stack.slice(1, 1 + (frames || stack.length)).join("\n").replace(/^/gm, " ");
util.dump((arguments.length == 0 ? "Stack" : msg) + "\n" + stack + "\n");
},