diff --git a/AUTHORS b/AUTHORS
index 8990f859..ad580ced 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -10,7 +10,7 @@ Inactive/former developers:
* Viktor Kojouharov (Виктор Кожухаров)
Patches (in no special order):
- * Daniel Bainton (:viewsource)
+ * Daniel Bainton (:viewsource, :command)
* Muthu Kannan (ctrl-v support)
* Lars Kindler (:buffer(s) functionality)
* Lee Hinman (:open ./.. support)
diff --git a/NEWS b/NEWS
index 7d6bb827..b41cfc3f 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,7 @@
removed the following hint options: 'hintchars' 'maxhints'
added the following hint options: 'hinttimeout'
* IMPORTANT: changed 'I' key to Ctrl-Q to also work in textboxes
+ * new :command to add user defined commands
* new setCustomMode for plugin writers
* :au[tocmd] executes commands on events (only 'PageLoad' actually) on websites
* @@ to repeat last macro
diff --git a/content/commands.js b/content/commands.js
index c6fb2843..ee57c333 100644
--- a/content/commands.js
+++ b/content/commands.js
@@ -86,6 +86,7 @@ vimperator.Command = function (specs, action, extraInfo) //{{{
this.shortHelp = extraInfo.shortHelp || null;
this.completer = extraInfo.completer || null;
this.args = extraInfo.args || [];
+ this.isUserCommand = extraInfo.isUserCommand || false;
}
};
@@ -443,6 +444,28 @@ vimperator.Commands = function () //{{{
throw StopIteration;
}
+ function getUserCommands(name)
+ {
+ var matches = [];
+ for (var i = 0; i < exCommands.length; i++)
+ {
+ if (exCommands[i].isUserCommand)
+ {
+ if (name)
+ {
+ if (exCommands[i].name.match("^"+name))
+ matches.push(exCommands[i]);
+ }
+ else
+ {
+ matches.push(exCommands[i]);
+ }
+ }
+ }
+ return matches;
+ }
+
+
/////////////////////////////////////////////////////////////////////////////}}}
////////////////////// PUBLIC SECTION //////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
@@ -454,13 +477,28 @@ vimperator.Commands = function () //{{{
return commandsIterator();
},
- add: function (command)
+ add: function (command, replace)
{
+ for (var i = 0; i < exCommands.length; i++)
+ {
+ if (exCommands[i].name == command.name)
+ {
+ if (!replace)
+ return false;
+ else
+ break;
+ }
+ }
+
+ // add an alias, so that commands can be accessed with
+ // vimperator.commands.zoom("130")
this[command.name] = function (args, special, count, modifiers)
{
command.execute(args, special, count, modifiers);
};
+
exCommands.push(command);
+ return true;
},
get: function (name)
@@ -776,21 +814,47 @@ vimperator.Commands = function () //{{{
}
));
commandManager.add(new vimperator.Command(["com[mand]"],
- function (args)
+ function (args, special)
{
- var res = parseArgs(args, this.args);
- if (!res)
- return;
+ if (args)
+ {
+ var res = args.match(/^(\w+)(?:\s+(.+))?$/);
+ if (!res)
+ {
+ vimperator.echoerr("E182: Invalid command name");
+ return false;
+ }
+ var [cmd, rep] = [res[1], res[2]]
+ }
- vimperator.echo(vimperator.util.colorize(res.args));
+ if (rep)
+ {
+ if (!vimperator.commands.add(new vimperator.Command([cmd], function (args, special, count, modifiers) { eval(rep) }, { isUserCommand: rep } ), special))
+ vimperator.echoerr("E174: Command already exists: add ! to replace it");
+ }
+ else
+ {
+ var cmdlist = getUserCommands(cmd);
+ if (cmdlist.length > 0)
+ {
+ var str = ":" + vimperator.util.escapeHTML(vimperator.commandline.getCommand()) + "
" +
+ "
| Name | Args | Definition |
|---|---|---|
| " + cmdlist[i].name + " | " + "*" + " | " + cmdlist[i].isUserCommand + " |