mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-23 15:52:29 +01:00
Add "literal" option to addCommand, to treat all args after argCount as a literal string
This commit is contained in:
@@ -80,6 +80,7 @@ liberator.Command = function (specs, description, action, extraInfo) //{{{
|
|||||||
this.options = extraInfo.options || [];
|
this.options = extraInfo.options || [];
|
||||||
this.bang = extraInfo.bang || false;
|
this.bang = extraInfo.bang || false;
|
||||||
this.count = extraInfo.count || false;
|
this.count = extraInfo.count || false;
|
||||||
|
this.literal = extraInfo.literal || false;
|
||||||
|
|
||||||
this.isUserCommand = extraInfo.isUserCommand || false;
|
this.isUserCommand = extraInfo.isUserCommand || false;
|
||||||
this.replacementText = extraInfo.replacementText || null;
|
this.replacementText = extraInfo.replacementText || null;
|
||||||
@@ -99,7 +100,7 @@ liberator.Command.prototype = {
|
|||||||
// we use our args parser instead of passing a string to the callback
|
// we use our args parser instead of passing a string to the callback
|
||||||
if (this.options.length > 0 || this.argCount)
|
if (this.options.length > 0 || this.argCount)
|
||||||
{
|
{
|
||||||
args = liberator.commands.parseArgs(args, this.options, this.argCount);
|
args = liberator.commands.parseArgs(args, this.options, this.argCount, false, this.literal);
|
||||||
if (args == null)
|
if (args == null)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -158,21 +159,27 @@ liberator.Commands = function () //{{{
|
|||||||
|
|
||||||
var exCommands = [];
|
var exCommands = [];
|
||||||
|
|
||||||
function getMatchingUserCommands(name)
|
function getMatchingUserCommands(name, filter)
|
||||||
{
|
{
|
||||||
var matches = [];
|
var matches = [];
|
||||||
for (let i = 0; i < exCommands.length; i++)
|
outer:
|
||||||
|
for (let [,cmd] in Iterator(exCommands))
|
||||||
{
|
{
|
||||||
if (exCommands[i].isUserCommand)
|
if (cmd.isUserCommand)
|
||||||
{
|
{
|
||||||
|
for (let [k, v] in Iterator(filter))
|
||||||
|
{
|
||||||
|
if (v != null && cmd[k] != v)
|
||||||
|
continue outer;
|
||||||
|
}
|
||||||
if (name)
|
if (name)
|
||||||
{
|
{
|
||||||
if (exCommands[i].name.match("^" + name))
|
if (cmd.name.match("^" + name))
|
||||||
matches.push(exCommands[i]);
|
matches.push(cmd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
matches.push(exCommands[i]);
|
matches.push(cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -318,7 +325,7 @@ liberator.Commands = function () //{{{
|
|||||||
// @param allowUnknownOptions: -foo won't result in an error, if -foo isn't
|
// @param allowUnknownOptions: -foo won't result in an error, if -foo isn't
|
||||||
// specified in "options"
|
// specified in "options"
|
||||||
// TODO: should it handle comments?
|
// TODO: should it handle comments?
|
||||||
parseArgs: function (str, options, argCount, allowUnknownOptions, complete) //{{{
|
parseArgs: function (str, options, argCount, allowUnknownOptions, literal, complete) //{{{
|
||||||
{
|
{
|
||||||
function quoteArg(quote)
|
function quoteArg(quote)
|
||||||
{
|
{
|
||||||
@@ -428,12 +435,13 @@ liberator.Commands = function () //{{{
|
|||||||
|
|
||||||
if (!argCount)
|
if (!argCount)
|
||||||
argCount = "*";
|
argCount = "*";
|
||||||
|
if (literal)
|
||||||
|
argCount = parseInt(argCount);
|
||||||
|
|
||||||
var args = {}; // parsed options
|
var args = {}; // parsed options
|
||||||
args.arguments = []; // remaining arguments
|
args.arguments = []; // remaining arguments
|
||||||
args.string = str; // for access to the unparsed string
|
args.string = str; // for access to the unparsed string
|
||||||
// FIXME: quick hack! Best way to do this? -- djk
|
args.literalArg = "";
|
||||||
args.argumentsString = "";
|
|
||||||
|
|
||||||
var invalid = false;
|
var invalid = false;
|
||||||
var onlyArgumentsRemaining = allowUnknownOptions || false; // after a -- has been found
|
var onlyArgumentsRemaining = allowUnknownOptions || false; // after a -- has been found
|
||||||
@@ -593,9 +601,11 @@ liberator.Commands = function () //{{{
|
|||||||
}
|
}
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
// FIXME: quick hack! -- djk
|
if (literal && args.arguments.length == argCount)
|
||||||
if (!args.argumentsString)
|
{
|
||||||
args.argumentsString = str.substr(i);
|
args.literalArg = sub;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// if not an option, treat this token as an argument
|
// if not an option, treat this token as an argument
|
||||||
var [count, arg] = getNextArg(sub);
|
var [count, arg] = getNextArg(sub);
|
||||||
@@ -616,6 +626,9 @@ liberator.Commands = function () //{{{
|
|||||||
i += count; // hopefully count is always > 0, otherwise we get an endless loop
|
i += count; // hopefully count is always > 0, otherwise we get an endless loop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (literal)
|
||||||
|
return args;
|
||||||
|
|
||||||
// check for correct number of arguments
|
// check for correct number of arguments
|
||||||
if (args.arguments.length == 0 && (argCount == "1" || argCount == "+"))
|
if (args.arguments.length == 0 && (argCount == "1" || argCount == "+"))
|
||||||
{
|
{
|
||||||
@@ -691,26 +704,57 @@ liberator.Commands = function () //{{{
|
|||||||
////////////////////// COMMANDS ////////////////////////////////////////////////
|
////////////////////// COMMANDS ////////////////////////////////////////////////
|
||||||
/////////////////////////////////////////////////////////////////////////////{{{
|
/////////////////////////////////////////////////////////////////////////////{{{
|
||||||
|
|
||||||
|
function userCommand(args, special, count, modifiers)
|
||||||
|
{
|
||||||
|
function replaceTokens(token)
|
||||||
|
{
|
||||||
|
let ret;
|
||||||
|
let quote = false;
|
||||||
|
|
||||||
|
// ignore quoting of <lt> like Vim, not needed for <count>
|
||||||
|
if (/^<q-(?!(lt|count))[a-z]+>$/.test(token))
|
||||||
|
quote = true;
|
||||||
|
|
||||||
|
token = token.replace("q-", "");
|
||||||
|
|
||||||
|
switch (token)
|
||||||
|
{
|
||||||
|
case "<args>":
|
||||||
|
ret = args.argumentsString;
|
||||||
|
break;
|
||||||
|
case "<bang>":
|
||||||
|
ret = bangOpt ? (special ? "!" : "") : token;
|
||||||
|
break;
|
||||||
|
case "<count>":
|
||||||
|
ret = countOpt ? (count > -1 ? count : 0) : token;
|
||||||
|
break;
|
||||||
|
case "<lt>":
|
||||||
|
ret = "<";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
return quote ? '"' + ret.replace('"', '\\"', "g") + '"' : ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
liberator.execute(this.replacementText.replace(/<(?:q-)?[a-z]+>/g, replaceTokens));
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Vim allows commands to be defined without {rep} if there are {attr}s
|
// TODO: Vim allows commands to be defined without {rep} if there are {attr}s
|
||||||
// specified - useful?
|
// specified - useful?
|
||||||
commandManager.add(["com[mand]"],
|
commandManager.add(["com[mand]"],
|
||||||
"List and define commands",
|
"List and define commands",
|
||||||
function (args, special)
|
function (args, special)
|
||||||
{
|
{
|
||||||
if (args.argumentsString)
|
let cmd = args.arguments[0];
|
||||||
|
if (cmd != null && /\W/.test(cmd))
|
||||||
{
|
{
|
||||||
let matches = args.argumentsString.match(/^(\w+)(?:\s+(.+))?$/);
|
liberator.echoerr("E182: Invalid command name");
|
||||||
|
return;
|
||||||
if (!matches)
|
|
||||||
{
|
|
||||||
liberator.echoerr("E182: Invalid command name");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var [cmd, rep] = [matches[1], matches[2]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rep)
|
if (args.literalArg)
|
||||||
{
|
{
|
||||||
let nargsOpt = args["-nargs"] || "0";
|
let nargsOpt = args["-nargs"] || "0";
|
||||||
let bangOpt = "-bang" in args;
|
let bangOpt = "-bang" in args;
|
||||||
@@ -719,47 +763,12 @@ liberator.Commands = function () //{{{
|
|||||||
if (!liberator.commands.addUserCommand(
|
if (!liberator.commands.addUserCommand(
|
||||||
[cmd],
|
[cmd],
|
||||||
"User defined command",
|
"User defined command",
|
||||||
function (args, special, count, modifiers)
|
userCommand,
|
||||||
{
|
|
||||||
function replaceTokens(token)
|
|
||||||
{
|
|
||||||
let ret;
|
|
||||||
let quote = false;
|
|
||||||
|
|
||||||
// ignore quoting of <lt> like Vim, not needed for <count>
|
|
||||||
if (/^<q-(?!(lt|count))[a-z]+>$/.test(token))
|
|
||||||
quote = true;
|
|
||||||
|
|
||||||
token = token.replace("q-", "");
|
|
||||||
|
|
||||||
switch (token)
|
|
||||||
{
|
|
||||||
case "<args>":
|
|
||||||
ret = args.argumentsString;
|
|
||||||
break;
|
|
||||||
case "<bang>":
|
|
||||||
ret = bangOpt ? (special ? "!" : "") : token;
|
|
||||||
break;
|
|
||||||
case "<count>":
|
|
||||||
ret = countOpt ? (count > -1 ? count : 0) : token;
|
|
||||||
break;
|
|
||||||
case "<lt>":
|
|
||||||
ret = "<";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ret = token;
|
|
||||||
}
|
|
||||||
|
|
||||||
return quote ? '"' + ret.replace('"', '\\"', "g") + '"' : ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
liberator.execute(rep.replace(/<(?:q-)?[a-z]+>/g, replaceTokens));
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
argCount: nargsOpt,
|
argCount: nargsOpt,
|
||||||
bang: bangOpt,
|
bang: bangOpt,
|
||||||
count: countOpt,
|
count: countOpt,
|
||||||
replacementText: rep
|
replacementText: args.literalArg
|
||||||
},
|
},
|
||||||
special)
|
special)
|
||||||
)
|
)
|
||||||
@@ -769,7 +778,12 @@ liberator.Commands = function () //{{{
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
let cmds = getMatchingUserCommands(cmd);
|
let filter = {
|
||||||
|
argCount: args["-nargs"],
|
||||||
|
bang: "-bang" in args && true,
|
||||||
|
count: args["-count"],
|
||||||
|
};
|
||||||
|
let cmds = getMatchingUserCommands(cmd, filter);
|
||||||
|
|
||||||
if (cmds.length > 0)
|
if (cmds.length > 0)
|
||||||
{
|
{
|
||||||
@@ -789,6 +803,8 @@ liberator.Commands = function () //{{{
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
literal: true,
|
||||||
|
argCount: 1,
|
||||||
bang: true,
|
bang: true,
|
||||||
completer: function (filter) liberator.completion.userCommand(filter),
|
completer: function (filter) liberator.completion.userCommand(filter),
|
||||||
options: [
|
options: [
|
||||||
|
|||||||
Reference in New Issue
Block a user