summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKris Maglione <maglione.k@gmail.com>2009-05-22 22:12:11 -0400
committerKris Maglione <maglione.k@gmail.com>2009-05-22 22:12:11 -0400
commit36f6ff463f9c6e125c964a68e160b433d5357135 (patch)
tree706a17955e935dfd8c401158c0020eab54fb6253
parentfa16e09a9a0e37fea08238ffd61dca4db1b93eb5 (diff)
downloadpentadactyl-36f6ff463f9c6e125c964a68e160b433d5357135.tar.gz
Store canonical names for all bound keys.
-rw-r--r--common/content/completion.js4
-rw-r--r--common/content/events.js262
-rw-r--r--common/content/liberator.js2
-rw-r--r--common/content/mappings.js2
4 files changed, 135 insertions, 135 deletions
diff --git a/common/content/completion.js b/common/content/completion.js
index 0eabbc15..071cfab2 100644
--- a/common/content/completion.js
+++ b/common/content/completion.js
@@ -815,7 +815,7 @@ function Completion() //{{{
let key = item[0];
if (!isNaN(key))
key = parseInt(key);
- else if (/^[A-Z_]+$/.test(key))
+ else if (/^[A-Z_][A-Z0-9_]*$/.test(key))
key = "";
item.key = key;
});
@@ -1120,7 +1120,7 @@ function Completion() //{{{
{
if (!isNaN(a.item.key) && !isNaN(b.item.key))
return a.item.key - b.item.key;
- return isNaN(b.item.key) - isNaN(a.item.key) || compare(a, b);
+ return isNaN(b.item.key) - isNaN(a.item.key) || compare(a.item.key, b.item.key);
}
if (!context.anchored) // We've already listed anchored matches, so don't list them again here.
context.filters.push(function (item) util.compareIgnoreCase(item.text.substr(0, this.filter.length), this.filter));
diff --git a/common/content/events.js b/common/content/events.js
index 56131a42..85af0be7 100644
--- a/common/content/events.js
+++ b/common/content/events.js
@@ -432,67 +432,34 @@ function Events() //{{{
// matters, so use that string as the first item, that you
// want to refer to within liberator's source code for
// comparisons like if (key == "<Esc>") { ... }
- var keyTable = [
- [ KeyEvent.DOM_VK_ESCAPE, ["Esc", "Escape"] ],
- [ KeyEvent.DOM_VK_LEFT_SHIFT, ["<"] ],
- [ KeyEvent.DOM_VK_RIGHT_SHIFT, [">"] ],
- [ KeyEvent.DOM_VK_RETURN, ["Return", "CR", "Enter"] ],
- [ KeyEvent.DOM_VK_TAB, ["Tab"] ],
- [ KeyEvent.DOM_VK_DELETE, ["Del"] ],
- [ KeyEvent.DOM_VK_BACK_SPACE, ["BS"] ],
- [ KeyEvent.DOM_VK_HOME, ["Home"] ],
- [ KeyEvent.DOM_VK_INSERT, ["Insert", "Ins"] ],
- [ KeyEvent.DOM_VK_END, ["End"] ],
- [ KeyEvent.DOM_VK_LEFT, ["Left"] ],
- [ KeyEvent.DOM_VK_RIGHT, ["Right"] ],
- [ KeyEvent.DOM_VK_UP, ["Up"] ],
- [ KeyEvent.DOM_VK_DOWN, ["Down"] ],
- [ KeyEvent.DOM_VK_PAGE_UP, ["PageUp"] ],
- [ KeyEvent.DOM_VK_PAGE_DOWN, ["PageDown"] ],
- [ KeyEvent.DOM_VK_F1, ["F1"] ],
- [ KeyEvent.DOM_VK_F2, ["F2"] ],
- [ KeyEvent.DOM_VK_F3, ["F3"] ],
- [ KeyEvent.DOM_VK_F4, ["F4"] ],
- [ KeyEvent.DOM_VK_F5, ["F5"] ],
- [ KeyEvent.DOM_VK_F6, ["F6"] ],
- [ KeyEvent.DOM_VK_F7, ["F7"] ],
- [ KeyEvent.DOM_VK_F8, ["F8"] ],
- [ KeyEvent.DOM_VK_F9, ["F9"] ],
- [ KeyEvent.DOM_VK_F10, ["F10"] ],
- [ KeyEvent.DOM_VK_F11, ["F11"] ],
- [ KeyEvent.DOM_VK_F12, ["F12"] ],
- [ KeyEvent.DOM_VK_F13, ["F13"] ],
- [ KeyEvent.DOM_VK_F14, ["F14"] ],
- [ KeyEvent.DOM_VK_F15, ["F15"] ],
- [ KeyEvent.DOM_VK_F16, ["F16"] ],
- [ KeyEvent.DOM_VK_F17, ["F17"] ],
- [ KeyEvent.DOM_VK_F18, ["F18"] ],
- [ KeyEvent.DOM_VK_F19, ["F19"] ],
- [ KeyEvent.DOM_VK_F20, ["F20"] ],
- [ KeyEvent.DOM_VK_F21, ["F21"] ],
- [ KeyEvent.DOM_VK_F22, ["F22"] ],
- [ KeyEvent.DOM_VK_F23, ["F23"] ],
- [ KeyEvent.DOM_VK_F24, ["F24"] ]
- ];
-
- function getKeyCode(str)
- {
- str = str.toLowerCase();
+ var keyTable = {
+ add: ["Plus", "Add"],
+ back_space: ["BS"],
+ delete: ["Del"],
+ escape: ["Esc", "Escape"],
+ insert: ["Insert", "Ins"],
+ left_shift: ["<"],
+ return: ["Return", "CR", "Enter"],
+ right_shift: [">"],
+ space: ["Space", " "],
+ subtract: ["Minus", "Subtract"],
+ };
- for (let [,key] in Iterator(keyTable))
- {
- for (let [,name] in Iterator(key[1]))
- {
- // we don't store lowercase keys in the keyTable, because we
- // also need to get good looking strings for the reverse action
- if (name.toLowerCase() == str)
- return key[0];
- }
+ const code_key = {};
+ const key_code = {};
+
+ for (let [k, v] in Iterator(KeyEvent))
+ if (/^DOM_VK_/.test(k)) {
+ k = k.substr(7).toLowerCase();
+ let names = [k.replace(/(^|_)(.)/g, function (m, n1, n2) n2.toUpperCase())
+ .replace(/^NUMPAD/, "k")];
+ if (k in keyTable)
+ names = keyTable[k];
+ code_key[v] = names[0]
+ for (let [,name] in Iterator(names))
+ key_code[name.toLowerCase()] = v
}
- return 0;
- }
-
function isFormElemFocused()
{
let elem = liberator.focus;
@@ -663,51 +630,53 @@ function Events() //{{{
////////////////////// MAPPINGS ////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
- mappings.add(modes.all,
- ["<Esc>", "<C-[>"], "Focus content",
- function () { events.onEscape(); });
-
- // add the ":" mapping in all but insert mode mappings
- mappings.add([modes.NORMAL, modes.PLAYER, modes.VISUAL, modes.HINTS, modes.MESSAGE, modes.COMPOSE, modes.CARET, modes.TEXTAREA],
- [":"], "Enter command line mode",
- function () { commandline.open(":", "", modes.EX); });
-
- // focus events
- mappings.add([modes.NORMAL, modes.PLAYER, modes.VISUAL, modes.CARET],
- ["<Tab>"], "Advance keyboard focus",
- function () { document.commandDispatcher.advanceFocus(); });
-
- mappings.add([modes.NORMAL, modes.PLAYER, modes.VISUAL, modes.CARET, modes.INSERT, modes.TEXTAREA],
- ["<S-Tab>"], "Rewind keyboard focus",
- function () { document.commandDispatcher.rewindFocus(); });
-
- mappings.add(modes.all,
- ["<C-z>"], "Temporarily ignore all " + config.name + " key bindings",
- function () { modes.passAllKeys = true; });
-
- mappings.add(modes.all,
- ["<C-v>"], "Pass through next key",
- function () { modes.passNextKey = true; });
-
- mappings.add(modes.all,
- ["<Nop>"], "Do nothing",
- function () { return; });
-
- // macros
- mappings.add([modes.NORMAL, modes.PLAYER, modes.MESSAGE],
- ["q"], "Record a key sequence into a macro",
- function (arg) { events.startRecording(arg); },
- { flags: Mappings.flags.ARGUMENT });
-
- mappings.add([modes.NORMAL, modes.PLAYER, modes.MESSAGE],
- ["@"], "Play a macro",
- function (count, arg)
- {
- if (count < 1) count = 1;
- while (count-- && events.playMacro(arg))
- ;
- },
- { flags: Mappings.flags.ARGUMENT | Mappings.flags.COUNT });
+ liberator.registerObserver("load_mappings", function() {
+ mappings.add(modes.all,
+ ["<Esc>", "<C-[>"], "Focus content",
+ function () { events.onEscape(); });
+
+ // add the ":" mapping in all but insert mode mappings
+ mappings.add([modes.NORMAL, modes.PLAYER, modes.VISUAL, modes.HINTS, modes.MESSAGE, modes.COMPOSE, modes.CARET, modes.TEXTAREA],
+ [":"], "Enter command line mode",
+ function () { commandline.open(":", "", modes.EX); });
+
+ // focus events
+ mappings.add([modes.NORMAL, modes.PLAYER, modes.VISUAL, modes.CARET],
+ ["<Tab>"], "Advance keyboard focus",
+ function () { document.commandDispatcher.advanceFocus(); });
+
+ mappings.add([modes.NORMAL, modes.PLAYER, modes.VISUAL, modes.CARET, modes.INSERT, modes.TEXTAREA],
+ ["<S-Tab>"], "Rewind keyboard focus",
+ function () { document.commandDispatcher.rewindFocus(); });
+
+ mappings.add(modes.all,
+ ["<C-z>"], "Temporarily ignore all " + config.name + " key bindings",
+ function () { modes.passAllKeys = true; });
+
+ mappings.add(modes.all,
+ ["<C-v>"], "Pass through next key",
+ function () { modes.passNextKey = true; });
+
+ mappings.add(modes.all,
+ ["<Nop>"], "Do nothing",
+ function () { return; });
+
+ // macros
+ mappings.add([modes.NORMAL, modes.PLAYER, modes.MESSAGE],
+ ["q"], "Record a key sequence into a macro",
+ function (arg) { events.startRecording(arg); },
+ { flags: Mappings.flags.ARGUMENT });
+
+ mappings.add([modes.NORMAL, modes.PLAYER, modes.MESSAGE],
+ ["@"], "Play a macro",
+ function (count, arg)
+ {
+ if (count < 1) count = 1;
+ while (count-- && events.playMacro(arg))
+ ;
+ },
+ { flags: Mappings.flags.ARGUMENT | Mappings.flags.COUNT });
+ });
/////////////////////////////////////////////////////////////////////////////}}}
////////////////////// COMMANDS ////////////////////////////////////////////////
@@ -899,6 +868,41 @@ function Events() //{{{
}
},
+ canonKeys: function(keys)
+ {
+ var res = []
+ for (var i = 0; i < keys.length; i++)
+ {
+ let key = [keys[i]];
+ let keyCode = 0;
+
+ if (keys[i] == "<")
+ {
+ let [match, modifier, keyname] = keys.substr(i).toLowerCase().match(/<((?:[csma]-)*)(.+?)>/) || [];
+ if (keyname)
+ {
+ modifier = modifier.toUpperCase();
+ key = [k + "-" for ([i, k] in Iterator("CASM")) if (modifier.indexOf(k + "-") >= 0)]
+ keyCode = key_code[keyname];
+
+ let c = String.fromCharCode(keyCode);
+ if (key.length == 0 && c == code_key[keyCode])
+ key = [c.toLowerCase()];
+ else
+ key = ["<"].concat(key, code_key[keyCode] || keyname, ">");
+ i += match.length - 1;
+ }
+ }
+ else // a simple key
+ {
+ if (keys[i] != keys[i].toLowerCase())
+ key = ["<S-", keys[i].toUpperCase(), ">"];
+ }
+ res.push(key);
+ }
+ return util.Array.flatten(res).join("");
+ },
+
/**
* Pushes keys onto the event queue from liberator. It is similar to
* Vim's feedkeys() method, but cannot cope with 2 partially-fed
@@ -942,6 +946,7 @@ function Events() //{{{
let [match, modifier, keyname] = keys.substr(i).match(/<((?:[CSMA]-)*)(.+?)>/i) || [];
if (keyname)
{
+ keyname = keyname.toLowerCase();
if (modifier) // check for modifiers
{
ctrl = /C-/i.test(modifier);
@@ -957,22 +962,24 @@ function Events() //{{{
keyname = keyname.toUpperCase();
charCode = keyname.charCodeAt(0);
}
- else if (keyname.toLowerCase() == "space")
- charCode = 32;
- else if (keyname.toLowerCase() == "nop")
+ else if (keyname == "nop")
string = "<Nop>";
- else if (keyCode = getKeyCode(keyname))
+ else if (keyname == "space")
+ ;
+ else if (keyCode = key_code[keyname])
charCode = 0;
else // an invalid key like <A-xxx> was found, stop propagation here (like Vim)
break;
+ if (keyCode == 32)
+ charCode = 32;
+
i += match.length - 1;
}
}
else // a simple key
{
- // FIXME: does not work for non A-Z keys like Ö,Ä,...
- shift = (keys[i] >= "A" && keys[i] <= "Z");
+ shift = keys[i] != keys[i].toLowerCase();
}
let elem = liberator.focus;
@@ -1026,7 +1033,7 @@ function Events() //{{{
* @param {Event} event
* @returns {string}
*/
- toString: function (event)
+ toString: function (event, all)
{
if (!event)
return "[object Mappings]";
@@ -1041,6 +1048,8 @@ function Events() //{{{
modifier += "C-";
if (event.altKey)
modifier += "A-";
+ if (event.shiftKey)
+ modifier += "S-";
if (event.metaKey)
modifier += "M-";
@@ -1048,17 +1057,8 @@ function Events() //{{{
{
if (event.charCode == 0)
{
- if (event.shiftKey)
- modifier += "S-";
-
- for (let i = 0; i < keyTable.length; i++)
- {
- if (keyTable[i][0] == event.keyCode)
- {
- key = keyTable[i][1][0];
- break;
- }
- }
+ if (event.keyCode in code_key)
+ key = code_key[event.keyCode];
}
// [Ctrl-Bug] special handling of mysterious <C-[>, <C-\\>, <C-]>, <C-^>, <C-_> bugs (OS/X)
// (i.e., cntrl codes 27--31)
@@ -1089,19 +1089,20 @@ function Events() //{{{
else // [Ctrl-Bug 2,3,4,5/5] the <C-\\>, <C-]>, <C-^>, <C-_> bugs
key = String.fromCharCode(event.charCode + 64);
}
- // special handling of the Space key
- else if (event.charCode == 32)
- {
- if (event.shiftKey)
- modifier += "S-";
- key = "Space";
- }
// a normal key like a, b, c, 0, etc.
else if (event.charCode > 0)
{
- key = String.fromCharCode(event.charCode);
+ key = String.fromCharCode(event.charCode).toLowerCase();
+ if (key in key_code)
+ key = code_key[key_code[key]];
+ }
+ if (key == null)
+ return;
+ let k = key.toLowerCase();
+ if (!(k in key_code) || String.fromCharCode(key_code[k]).toLowerCase() == k)
+ {
if (modifier.length == 0)
- return key;
+ return k;
}
}
else if (event.type == "click" || event.type == "dblclick")
@@ -1129,7 +1130,6 @@ function Events() //{{{
if (key == null)
return null;
- // a key like F1 is always enclosed in < and >
return "<" + modifier + key + ">";
},
diff --git a/common/content/liberator.js b/common/content/liberator.js
index 880ea30d..a5c62840 100644
--- a/common/content/liberator.js
+++ b/common/content/liberator.js
@@ -1268,9 +1268,9 @@ const liberator = (function () //{{{
// commands must always be the first module to be initialized
loadModule("commands", Commands);
loadModule("options", Options);
+ loadModule("events", Events);
loadModule("mappings", Mappings);
loadModule("buffer", Buffer);
- loadModule("events", Events);
loadModule("commandline", CommandLine);
loadModule("statusline", StatusLine);
loadModule("editor", Editor);
diff --git a/common/content/mappings.js b/common/content/mappings.js
index ada1aa94..233cbd12 100644
--- a/common/content/mappings.js
+++ b/common/content/mappings.js
@@ -58,7 +58,7 @@ function Map(modes, keys, description, action, extraInfo) //{{{
/** @property {number[]} All of the modes for which this mapping applies. */
this.modes = modes;
/** @property {string[]} All of this mapping's names (key sequences). */
- this.names = keys.map(function (cmd) cmd.replace(/[casm]-/g, String.toUpperCase)); // only store keysyms with uppercase modifier strings
+ this.names = keys.map(events.canonKeys);
/** @property {function (number)} The function called to execute this mapping. */
this.action = action;