diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/content/buffer.js | 9 | ||||
-rw-r--r-- | common/content/commandline.js | 3 | ||||
-rw-r--r-- | common/content/dactyl.js | 4 | ||||
-rw-r--r-- | common/content/events.js | 47 | ||||
-rw-r--r-- | common/content/hints.js | 204 | ||||
-rw-r--r-- | common/content/mappings.js | 22 | ||||
-rw-r--r-- | common/modules/services.jsm | 1 | ||||
-rw-r--r-- | common/modules/util.jsm | 2 |
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"); }, |