1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-21 23:17:59 +01:00

add initial (very rough) implementations of :map, :mapclear and :unmap

This commit is contained in:
Doug Kearns
2007-07-21 16:42:38 +00:00
parent 039544a697
commit 38fd04be35
2 changed files with 319 additions and 66 deletions

View File

@@ -187,6 +187,7 @@ function Commands() //{{{
if (ex_commands[i].hasName(name)) if (ex_commands[i].hasName(name))
return ex_commands[i]; return ex_commands[i];
} }
return null; return null;
} }
@@ -505,6 +506,73 @@ function Commands() //{{{
"The special version <code class=\"command\">:javascript!</code> will open the javascript console of Firefox." "The special version <code class=\"command\">:javascript!</code> will open the javascript console of Firefox."
} }
)); ));
addDefaultCommand(new Command(["map"],
// 0 args -> list all maps
// 1 arg -> list the maps starting with args
// 2 args -> map arg1 to arg*
function(args)
{
if (args.length == 0)
{
vimperator.mappings.list(vimperator.modes.NORMAL);
return;
}
var matches = args.match(/^([^ ]+)(?:\s+(.+))?$/);
var [lhs, rhs] = [matches[1], matches[2]];
if (rhs)
{
if (/^:/.test(rhs))
{
vimperator.mappings.add(
new Map(vimperator.modes.NORMAL, [lhs], function() { execute(rhs); }, { rhs: rhs })
);
}
else
{
var map = vimperator.mappings.get(vimperator.modes.NORMAL, rhs);
// create a new Map for {lhs} with the same action as
// {rhs}...until we have feedkeys().
// NOTE: Currently only really useful for static use ie. from
// the RC file
if (map)
vimperator.mappings.add(
new Map(vimperator.modes.NORMAL, [lhs], map.action, { rhs: rhs })
);
else
vimperator.echoerr("E475: Invalid argument: " + "{rhs} must be a existing singular mapping");
}
}
else
{
// FIXME: no filtering for now
vimperator.mappings.list(vimperator.modes.NORMAL, lhs);
}
},
{
usage: ["map {lhs} {rhs}", "map {lhs}", "map"],
short_help: "Map the key sequence {lhs} to {rhs}",
help: ""
}
));
addDefaultCommand(new Command(["mapc[lear]"],
function(args)
{
if (args.length > 0)
{
vimperator.echoerr("E474: Invalid argument");
return;
}
vimperator.mappings.removeAll(vimperator.modes.NORMAL);
},
{
short_help: "Remove all mappings",
help: ""
}
));
addDefaultCommand(new Command(["ma[rk]"], addDefaultCommand(new Command(["ma[rk]"],
function(args) function(args)
{ {
@@ -891,6 +959,28 @@ function Commands() //{{{
help: "TODO." help: "TODO."
} }
)); ));
addDefaultCommand(new Command(["unm[ap]"],
function(args)
{
if (args.length == 0)
{
vimperator.echoerr("E474: Invalid argument");
return;
}
var lhs = args;
if (vimperator.mappings.hasMap(vimperator.modes.NORMAL, lhs))
vimperator.mappings.remove(vimperator.modes.NORMAL, lhs);
else
vimperator.echoerr("E31: No such mapping");
},
{
usage: ["unm[ap] {lhs}"],
short_help: "Remove the mapping of {lhs}",
help: ""
}
));
addDefaultCommand(new Command(["ve[rsion]"], addDefaultCommand(new Command(["ve[rsion]"],
function(args, special) function(args, special)
{ {

View File

@@ -26,14 +26,14 @@ 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. the terms of any one of the MPL, the GPL or the LGPL.
}}} ***** END LICENSE BLOCK *****/ }}} ***** END LICENSE BLOCK *****/
function Map(mode, cmds, act, extra_info) //{{{ function Map(mode, cmds, action, extra_info) //{{{
{ {
if (!mode || (!cmds || !cmds.length) || !act) if (!mode || (!cmds || !cmds.length) || !action)
return null; return null;
this.mode = mode; this.mode = mode;
this.names = cmds; this.names = cmds;
this.action = act; this.action = action;
this.usage = [this.names[0]]; this.usage = [this.names[0]];
@@ -56,6 +56,8 @@ function Map(mode, cmds, act, extra_info) //{{{
this.help = extra_info.help || null; this.help = extra_info.help || null;
this.short_help = extra_info.short_help || null; this.short_help = extra_info.short_help || null;
this.rhs = extra_info.rhs || null;
// TODO: are these limited to HINTS mode? // TODO: are these limited to HINTS mode?
// Only set for hints maps // Only set for hints maps
this.cancel_mode = extra_info.cancel_mode || false; this.cancel_mode = extra_info.cancel_mode || false;
@@ -64,6 +66,17 @@ function Map(mode, cmds, act, extra_info) //{{{
} }
Map.prototype.hasName = function(name)
{
for (var i = 0; i < this.names.length; i++)
{
if (this.names[i] == name)
return true;
}
return false;
}
// Since we will add many Map-objects, we add some functions as prototypes // Since we will add many Map-objects, we add some functions as prototypes
// this will ensure we only have one copy of each function, not one for each object // this will ensure we only have one copy of each function, not one for each object
Map.prototype.execute = function(motion, count, argument) Map.prototype.execute = function(motion, count, argument)
@@ -96,6 +109,7 @@ function Mappings() //{{{
////////////////////// PRIVATE SECTION ///////////////////////////////////////// ////////////////////// PRIVATE SECTION /////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
// TODO: initialize empty map tables?
var main = []; // array of default Map() objects var main = []; // array of default Map() objects
var user = []; // array of objects created by :map var user = []; // array of objects created by :map
@@ -103,33 +117,56 @@ function Mappings() //{{{
{ {
if (!main[map.mode]) if (!main[map.mode])
main[map.mode] = []; main[map.mode] = [];
main[map.mode].push(map); main[map.mode].push(map);
} }
function getFrom(mode, cmd, stack) function getMap(mode, cmd, stack)
{ {
if (!stack || !stack[mode] || !stack[mode].length)
return;
var substack = stack[mode]; var substack = stack[mode];
var stack_length = substack.length;
for (var i = 0; i < stack_length; i++) for (var i = 0; i < substack.length; i++)
{ {
for (var j = 0; j < substack[i].names.length; j++) for (var j = 0; j < substack[i].names.length; j++)
if (substack[i].names[j] == cmd) if (substack[i].names[j] == cmd)
return substack[i]; return substack[i];
} }
return null;
}
function removeMap(mode, cmd)
{
var maps = user[mode];
var names;
for (var i = 0; i < maps.length; i++)
{
names = maps[i].names;
for (var j = 0; j < names.length; j++)
{
if (names[j] == cmd)
{
names.splice(j, 1)
if (names.length == 0)
maps.splice(i, 1);
return;
}
}
}
} }
function mappingsIterator(mode) function mappingsIterator(mode)
{ {
var mappings; var mappings = main[mode];
// FIXME: initialize empty map tables //// FIXME: do we want to document user commands by default?
if (user[mode]) //if (user[mode])
mappings = user[mode].concat(main[mode]); // mappings = user[mode].concat(main[mode]);
else //else
mappings = main[mode] // mappings = main[mode]
for (var i = 0; i < mappings.length; i++) for (var i = 0; i < mappings.length; i++)
yield mappings[i]; yield mappings[i];
@@ -158,39 +195,46 @@ function Mappings() //{{{
return mappingsIterator(mode); return mappingsIterator(mode);
} }
this.hasMap = function(mode, cmd)
{
var user_maps = user[mode];
for (var i = 0; i < user_maps.length; i++)
{
if (user_maps[i].names.indexOf(cmd) != -1)
return true;
}
return false;
}
this.add = function(map) this.add = function(map)
{ {
if (!map)
return false;
if (!user[map.mode]) if (!user[map.mode])
user[map.mode] = []; user[map.mode] = [];
user[map.mode].push(map); for (var i = 0; i < map.names.length; i++)
removeMap(map.mode, map.names[i]);
return true; user[map.mode].push(map);
} }
// FIXME: this doesn't work this.remove = function(mode, cmd)
this.remove = function(map)
{ {
var index; removeMap(mode, cmd);
}
if (!map || !(index = user[map.mode].indexOf(map))) this.removeAll = function(mode)
return false; {
user[mode] = [];
user[map.mode].splice(index, 1);
return true;
} }
this.get = function(mode, cmd) this.get = function(mode, cmd)
{ {
if (!mode || !cmd) var map = getMap(mode, cmd, user);
return null;
var map = getFrom(mode, cmd, user);
if (!map) if (!map)
map = getFrom(mode, cmd, main); map = getMap(mode, cmd, main);
return map; return map;
} }
@@ -201,9 +245,6 @@ function Mappings() //{{{
var mappings = []; var mappings = [];
var matches = []; var matches = [];
if (!mode || !cmd)
return matches;
if (user[mode]) if (user[mode])
mappings = user[mode].concat(main[mode]); mappings = user[mode].concat(main[mode]);
else else
@@ -222,6 +263,35 @@ function Mappings() //{{{
return matches; return matches;
} }
// TODO: implement filtering
this.list = function(mode, filter)
{
var maps = user[mode];
if (!maps || maps.length == 0)
{
vimperator.echo("No mappings found");
return;
}
var list = "<table>";
for (var i = 0; i < maps.length; i++)
{
for (var j = 0; j < maps[i].names.length; j++)
{
list += "<tr>";
list += "<td>&nbsp;" + maps[i].names[j].replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</td>"
if (maps[i].rhs)
list += "<td>&nbsp;" + maps[i].rhs.replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</td>"
list += "</tr>";
}
}
list += "</table>";
vimperator.commandline.echo(list, true); // TODO: force of multiline widget a better way
}
/////////////////////////////////////////////////////////////////////////////}}} /////////////////////////////////////////////////////////////////////////////}}}
////////////////////// DEFAULT MAPPINGS //////////////////////////////////////// ////////////////////// DEFAULT MAPPINGS ////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
@@ -800,135 +870,228 @@ function Mappings() //{{{
// action keys // action keys
addDefaultMap(new Map(vimperator.modes.HINTS, ["o"], addDefaultMap(new Map(vimperator.modes.HINTS, ["o"],
function() { vimperator.hints.openHints(false, false); }, function() { vimperator.hints.openHints(false, false); },
{ cancel_mode: true, always_active: false } {
cancel_mode: true,
always_active: false
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["t"], addDefaultMap(new Map(vimperator.modes.HINTS, ["t"],
function() { vimperator.hints.openHints(true, false); }, function() { vimperator.hints.openHints(true, false); },
{ cancel_mode: true, always_active: false } {
cancel_mode: true,
always_active: false
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-w>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-w>"],
function() { vimperator.hints.openHints(false, true ); }, function() { vimperator.hints.openHints(false, true ); },
{ cancel_mode: true, always_active: false } {
cancel_mode: true,
always_active: false
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["s"], addDefaultMap(new Map(vimperator.modes.HINTS, ["s"],
function() { vimperator.echoerr('Saving of links not yet implemented'); }, function() { vimperator.echoerr('Saving of links not yet implemented'); },
{ cancel_mode: true, always_active: false } {
cancel_mode: true,
always_active: false
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["y"], addDefaultMap(new Map(vimperator.modes.HINTS, ["y"],
function() { vimperator.hints.yankUrlHints(); }, function() { vimperator.hints.yankUrlHints(); },
{ cancel_mode: true, always_active: false } {
cancel_mode: true,
always_active: false
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["Y"], addDefaultMap(new Map(vimperator.modes.HINTS, ["Y"],
function() { vimperator.hints.yankTextHints(); }, function() { vimperator.hints.yankTextHints(); },
{ cancel_mode: true, always_active: false } {
cancel_mode: true,
always_active: false
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, [","], addDefaultMap(new Map(vimperator.modes.HINTS, [","],
function() { vimperator.input.buffer += ','; vimperator.hints.setCurrentState(0); }, function() { vimperator.input.buffer += ','; vimperator.hints.setCurrentState(0); },
{ cancel_mode: false, always_active: true } {
cancel_mode: false,
always_active: true
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, [":"], addDefaultMap(new Map(vimperator.modes.HINTS, [":"],
function() { vimperator.commandline.open(':', '', vimperator.modes.EX); }, function() { vimperator.commandline.open(':', '', vimperator.modes.EX); },
{ cancel_mode: false, always_active: true } {
cancel_mode: false,
always_active: true
}
)); ));
// movement keys // movement keys
addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-e>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-e>"],
function() { scrollBufferRelative(0, 1); }, function() { scrollBufferRelative(0, 1); },
{ cancel_mode: false, always_active: true } {
cancel_mode: false,
always_active: true
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-y>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-y>"],
function() { scrollBufferRelative(0, -1); }, function() { scrollBufferRelative(0, -1); },
{ cancel_mode: false, always_active: true } {
cancel_mode: false,
always_active: true
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<Home>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<Home>"],
function() { scrollBufferAbsolute(-1, 0); }, function() { scrollBufferAbsolute(-1, 0); },
{ cancel_mode: false, always_active: true } {
cancel_mode: false,
always_active: true
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<End>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<End>"],
function() { scrollBufferAbsolute(-1, 100); }, function() { scrollBufferAbsolute(-1, 100); },
{ cancel_mode: false, always_active: true } {
cancel_mode: false,
always_active: true
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-b>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-b>"],
function() { goDoCommand('cmd_scrollPageUp'); }, function() { goDoCommand('cmd_scrollPageUp'); },
{ cancel_mode: false, always_active: true } {
cancel_mode: false,
always_active: true
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<PageUp>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<PageUp>"],
function() { goDoCommand('cmd_scrollPageUp'); }, function() { goDoCommand('cmd_scrollPageUp'); },
{ cancel_mode: false, always_active: true } {
cancel_mode: false,
always_active: true
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-f>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-f>"],
function() { goDoCommand('cmd_scrollPageDown'); }, function() { goDoCommand('cmd_scrollPageDown'); },
{ cancel_mode: false, always_active: true } {
cancel_mode: false,
always_active: true
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<PageDown>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<PageDown>"],
function() { goDoCommand('cmd_scrollPageDown'); }, function() { goDoCommand('cmd_scrollPageDown'); },
{ cancel_mode: false, always_active: true } {
cancel_mode: false,
always_active: true
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<Left>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<Left>"],
function() { scrollBufferRelative(-1, 0); }, function() { scrollBufferRelative(-1, 0); },
{ cancel_mode: false, always_active: true } {
cancel_mode: false,
always_active: true
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<Down>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<Down>"],
function() { scrollBufferRelative(0, 1); }, function() { scrollBufferRelative(0, 1); },
{ cancel_mode: false, always_active: true } {
cancel_mode: false,
always_active: true
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<Up>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<Up>"],
function() { scrollBufferRelative(0, -1); }, function() { scrollBufferRelative(0, -1); },
{ cancel_mode: false, always_active: true } {
cancel_mode: false,
always_active: true
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<Right>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<Right>"],
function() { scrollBufferRelative(1, 0); }, function() { scrollBufferRelative(1, 0); },
{ cancel_mode: false, always_active: true } {
cancel_mode: false,
always_active: true
}
)); ));
// tab management // tab management
addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-n>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-n>"],
function() { vimperator.tabs.select('+1', true); }, function() { vimperator.tabs.select('+1', true); },
{ cancel_mode: true, always_active: true } {
cancel_mode: true,
always_active: true
}
)); // same as gt, but no count supported )); // same as gt, but no count supported
addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-p>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-p>"],
function() { vimperator.tabs.select('-1', true); }, function() { vimperator.tabs.select('-1', true); },
{ cancel_mode: true, always_active: true } {
cancel_mode: true,
always_active: true
}
)); ));
// navigation // navigation
addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-o>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-o>"],
function() { vimperator.history.stepTo(vimperator.input.count > 0 ? -1 * vimperator.input.count : -1); }, function() { vimperator.history.stepTo(vimperator.input.count > 0 ? -1 * vimperator.input.count : -1); },
{ cancel_mode: false, always_active: true } {
cancel_mode: false,
always_active: true
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-i>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-i>"],
function() { vimperator.history.stepTo(vimperator.input.count > 0 ? vimperator.input.count : 1); }, function() { vimperator.history.stepTo(vimperator.input.count > 0 ? vimperator.input.count : 1); },
{ cancel_mode: false, always_active: true } {
cancel_mode: false,
always_active: true
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-h>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-h>"],
function() { vimperator.history.stepTo(vimperator.input.count > 0 ? -1 * vimperator.input.count : -1); }, function() { vimperator.history.stepTo(vimperator.input.count > 0 ? -1 * vimperator.input.count : -1); },
{ cancel_mode: false, always_active: true } {
cancel_mode: false,
always_active: true
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-l>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-l>"],
function() { vimperator.history.stepTo(vimperator.input.count > 0 ? vimperator.input.count : 1); }, function() { vimperator.history.stepTo(vimperator.input.count > 0 ? vimperator.input.count : 1); },
{ cancel_mode: false, always_active: true } {
cancel_mode: false,
always_active: true
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-d>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-d>"],
function() { vimperator.tabs.remove(getBrowser().mCurrentTab, vimperator.input.count, false, 0); }, function() { vimperator.tabs.remove(getBrowser().mCurrentTab, vimperator.input.count, false, 0); },
{ cancel_mode: true, always_active: true } {
cancel_mode: true,
always_active: true
}
)); ));
// cancel_mode hint mode keys // cancel_mode hint mode keys
addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-c>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-c>"],
function() { ; }, function() { ; },
{ cancel_mode: true, always_active: true } {
cancel_mode: true,
always_active: true
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-g>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-g>"],
function() { ; }, function() { ; },
{ cancel_mode: true, always_active: true } {
cancel_mode: true,
always_active: true
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-[>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-[>"],
function() { ; }, function() { ; },
{ cancel_mode: true, always_active: true } {
cancel_mode: true,
always_active: true
}
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<Esc>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<Esc>"],
function() { ; }, function() { ; },
{ cancel_mode: true, always_active: true } {
cancel_mode: true,
always_active: true
}
)); ));
//}}} //}}}
//}}} //}}}