1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-23 16:02:26 +01:00

add rough -nargs, -bang and -count support to :command

This commit is contained in:
Doug Kearns
2008-10-10 13:52:08 +00:00
parent 41c1006eaa
commit 16164154ba
4 changed files with 153 additions and 49 deletions

8
NEWS
View File

@@ -7,6 +7,7 @@
special versions for the old behavior special versions for the old behavior
* IMPORTANT: renamed Startup and Quit autocmd events to VimperatorEnter and * IMPORTANT: renamed Startup and Quit autocmd events to VimperatorEnter and
VimperatorLeave respectively VimperatorLeave respectively
* add -nargs, -bang, and -count attribute support to :command
* much improved completion support, including javascript, option, and search keyword * much improved completion support, including javascript, option, and search keyword
* add <PageUp>/<S-Up> and <PageDown>/<S-Down> command-line mappings for * add <PageUp>/<S-Up> and <PageDown>/<S-Down> command-line mappings for
selecting the previous and next history items selecting the previous and next history items
@@ -53,7 +54,7 @@
* IMPORTANT: removed old :buffers! buffer window, as it was ugly and slightly broken * IMPORTANT: removed old :buffers! buffer window, as it was ugly and slightly broken
use "B" or :buffers instead use "B" or :buffers instead
* IMPORTANT: input fields are not blured anymore by default after a page has loaded * IMPORTANT: input fields are not blured anymore by default after a page has loaded
use :set [no]focuscontent to control the behavior (thanks Paul Sobey for the use :set [no]focuscontent to control the behavior (thanks Paul Sobey for the
generous donation which made this behavior possible) generous donation which made this behavior possible)
* IMPORTANT: ctrl-x/a never take possible negative URLs into account, it was just * IMPORTANT: ctrl-x/a never take possible negative URLs into account, it was just
too unpredictable too unpredictable
@@ -67,7 +68,7 @@
* add :bn[ext], :bp[revious], :bN[ext] to switch to next/previous tab * add :bn[ext], :bp[revious], :bN[ext] to switch to next/previous tab
* add :pagestyle command to allow for switching between alternate style sheets * add :pagestyle command to allow for switching between alternate style sheets
* add :b# to select the alternate buffer * add :b# to select the alternate buffer
* add :tabduplicate command * add :tabduplicate command
* new 'urlseparator' option for specifying the regexp used to split the arg to * new 'urlseparator' option for specifying the regexp used to split the arg to
:open, :tabopen and :winopen :open, :tabopen and :winopen
* :set editor now accepts quoting/escaping to use an editor with spaces in the path * :set editor now accepts quoting/escaping to use an editor with spaces in the path
@@ -205,7 +206,7 @@
* new :time command for profiling * new :time command for profiling
* added new :sidebar and :sbclose commands * added new :sidebar and :sbclose commands
* added 'more' and standard more-prompt key mappings to control * added 'more' and standard more-prompt key mappings to control
behaviour of the message list pager behaviour of the message list pager
* added 'hlsearchstyle' option to allow for user CSS styling of the * added 'hlsearchstyle' option to allow for user CSS styling of the
highlighted text strings when 'hlsearch' is set highlighted text strings when 'hlsearch' is set
* added 'linksearch' option to restrict page searches to link text - \L * added 'linksearch' option to restrict page searches to link text - \L
@@ -323,7 +324,6 @@
* showmode setting which shows the current mode in the command line (patch from Виктор Кожухаров) * showmode setting which shows the current mode in the command line (patch from Виктор Кожухаров)
* gh goes home :) gH in a new tab * gh goes home :) gH in a new tab
* :open! bypasses cache * :open! bypasses cache
* :buffer and :buffers support (patch from Lars Kindler) * :buffer and :buffers support (patch from Lars Kindler)
* added :edit, :e and :tabedit aliases for :open, :tabopen * added :edit, :e and :tabedit aliases for :open, :tabopen
* settings can now be changed with += and -= like in vim (patch from Виктор Кожухаров) * settings can now be changed with += and -= like in vim (patch from Виктор Кожухаров)

View File

@@ -235,6 +235,8 @@ liberator.Commands = function () //{{{
description = description || "User defined command"; description = description || "User defined command";
var command = new liberator.Command(names, description, action, extra); var command = new liberator.Command(names, description, action, extra);
// FIXME: shouldn't this be testing for an existing command by name?
// Requiring uppercase user command names like Vim would be easier
if (!command) if (!command)
return false; return false;
@@ -255,6 +257,7 @@ liberator.Commands = function () //{{{
} }
exCommands.push(command); exCommands.push(command);
return true; return true;
}, },
@@ -318,7 +321,7 @@ liberator.Commands = function () //{{{
parseArgs: function (str, options, argCount, allowUnknownOptions) //{{{ parseArgs: function (str, options, argCount, allowUnknownOptions) //{{{
{ {
// returns [count, parsed_argument] // returns [count, parsed_argument]
function getNextArg(str) function getNextArg(str) // {{{
{ {
var inSingleString = false; var inSingleString = false;
var inDoubleString = false; var inDoubleString = false;
@@ -415,7 +418,7 @@ liberator.Commands = function () //{{{
return [-1, "trailing \\"]; return [-1, "trailing \\"];
else else
return [str.length, arg]; return [str.length, arg];
} } // }}}
if (!options) if (!options)
options = []; options = [];
@@ -426,6 +429,8 @@ liberator.Commands = function () //{{{
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.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
@@ -452,7 +457,7 @@ liberator.Commands = function () //{{{
} }
var optname = ""; var optname = "";
if (!onlyArgumentsRemaining) if (!onlyArgumentsRemaining) //{{{
{ {
for (let opt = 0; opt < options.length; opt++) for (let opt = 0; opt < options.length; opt++)
{ {
@@ -578,7 +583,11 @@ liberator.Commands = function () //{{{
} }
} }
} }
} } //}}}
// FIXME: quick hack! -- djk
if (!args.argumentsString)
args.argumentsString = str.substr(i);
// 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);
@@ -596,7 +605,7 @@ liberator.Commands = function () //{{{
if (arg != null) if (arg != null)
args.arguments.push(arg); args.arguments.push(arg);
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
} }
// check for correct number of arguments // check for correct number of arguments
@@ -674,53 +683,95 @@ liberator.Commands = function () //{{{
////////////////////// COMMANDS //////////////////////////////////////////////// ////////////////////// COMMANDS ////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
// TODO: Vim allows commands to be defined without {rep} if there are {attr}s
// 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) if (args.argumentsString)
{ {
var res = args.match(/^(\w+)(?:\s+(.+))?$/); let matches = args.argumentsString.match(/^(\w+)(?:\s+(.+))?$/);
if (!res)
if (!matches)
{ {
liberator.echoerr("E182: Invalid command name"); liberator.echoerr("E182: Invalid command name");
return false; return;
} }
var [cmd, rep] = [res[1], res[2]];
var [cmd, rep] = [matches[1], matches[2]];
} }
if (rep) if (rep)
{ {
if (!liberator.commands.addUserCommand([cmd], let nargsOpt = args["-nargs"] || "0";
let bangOpt = "-bang" in args;
let countOpt = "-count" in args;
if (!liberator.commands.addUserCommand(
[cmd],
"User defined command", "User defined command",
function (args, special, count, modifiers) function (args, special, count, modifiers)
{ {
var replaced = rep.replace("<args>", args); function replaceTokens(token)
replaced = replaced.replace("<q-args>", '"' + args.replace('"', '\\"', "g") + '"'); {
replaced = replaced.replace("<lt>", "<"); let ret;
let quote = false;
liberator.execute(replaced); // 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));
}, },
{ {
bang: true, // FIXME: until we implement -bang argCount: nargsOpt,
bang: bangOpt,
count: countOpt,
replacementText: rep replacementText: rep
}, },
special) special)
) )
{ {
liberator.echoerr("E174: Command already exists: add ! to replace it"); liberator.echoerr("E174: Command already exists: add ! to replace it");
} }
} }
else else
{ {
var cmdlist = getMatchingUserCommands(cmd); let cmds = getMatchingUserCommands(cmd);
if (cmdlist.length > 0)
if (cmds.length > 0)
{ {
var str = liberator.template.tabular(["Name", "Args", "Definition"], [], let str = liberator.template.tabular(["", "Name", "Args", "Range", "Definition"], ["padding-right: 2em;"],
([cmd.name, ([cmd.bang ? "!" : " ",
"*", cmd.name,
cmd.replacementText || "function () { ... }"] cmd.argCount,
for each (cmd in cmdlist))); cmd.count ? "0c" : "",
cmd.replacementText || "function () { ... }"] for each (cmd in cmds)));
liberator.commandline.echo(str, liberator.commandline.HL_NORMAL, liberator.commandline.FORCE_MULTILINE); liberator.commandline.echo(str, liberator.commandline.HL_NORMAL, liberator.commandline.FORCE_MULTILINE);
} }
else else
@@ -731,10 +782,12 @@ liberator.Commands = function () //{{{
}, },
{ {
bang: true, bang: true,
completer: function (filter) liberator.completion.userCommand(filter) completer: function (filter) liberator.completion.userCommand(filter),
/*options: [[["-nargs"], OPTION_STRING, function (arg) { return /^(0|1|\*|\?|\+)$/.test(arg); }], options: [
[["-bang"], OPTION_NOARG], [["-nargs"], commandManager.OPTION_STRING, function (arg) /^[01*?+]$/.test(arg), ["0", "1", "*", "?", "+"]],
[["-bar"], OPTION_NOARG]] */ [["-bang"], commandManager.OPTION_NOARG],
[["-count"], commandManager.OPTION_NOARG],
]
}); });
commandManager.add(["comc[lear]"], commandManager.add(["comc[lear]"],

View File

@@ -58,15 +58,15 @@ section:Examples[autocmd-examples]
Enable _passthrough_ mode on all Google sites: Enable _passthrough_ mode on all Google sites:
:au LocationChange .* js modes.passAllKeys = /google\.com/.test(buffer.URL) :autocmd LocationChange .* js modes.passAllKeys = /google\.com/.test(buffer.URL)
Enable _passthrough_ mode on *some* Google sites: Enable _passthrough_ mode on *some* Google sites:
:au LocationChange .* js modes.passAllKeys = /(www|mail)\.google\.com/.test(buffer.URL) :autocmd LocationChange .* js modes.passAllKeys = /(www|mail)\.google\.com/.test(buffer.URL)
Set the filetype to mail when editing email at Gmail: Set the filetype to mail when editing email at Gmail:
:au LocationChange .* :set editor=gvim -f :autocmd LocationChange .* :set editor=gvim -f
:au LocationChange mail\.google\.com :set editor=gvim -f -c 'set ft=mail' :autocmd LocationChange mail\.google\.com :set editor=gvim -f -c 'set ft=mail'
// vim: set syntax=asciidoc: // vim: set syntax=asciidoc:

View File

@@ -55,8 +55,10 @@ ________________________________________________________________________________
||:map|| ||:map||
________________________________________________________________________________ ________________________________________________________________________________
Map the key sequence {lhs} to {rhs}. The {rhs} is remapped, allowing for Map the key sequence {lhs} to {rhs}. The {rhs} is remapped, allowing for
nested and recursive mappings. Mappings are NOT saved during sessions, make nested and recursive mappings.
sure you put them in your vimperatorrc file!
Warning: Mappings are NOT saved during sessions, make sure you put them in your
vimperatorrc file!
________________________________________________________________________________ ________________________________________________________________________________
@@ -66,8 +68,10 @@ ________________________________________________________________________________
||:cmap|| ||:cmap||
________________________________________________________________________________ ________________________________________________________________________________
Map the key sequence {lhs} to {rhs} (in Command-line mode). The {rhs} is Map the key sequence {lhs} to {rhs} (in Command-line mode). The {rhs} is
remapped, allowing for nested and recursive mappings. Mappings are NOT saved remapped, allowing for nested and recursive mappings.
during sessions, make sure you put them in your vimperatorrc file!
Warning: Mappings are NOT saved during sessions, make sure you put them in your
vimperatorrc file!
________________________________________________________________________________ ________________________________________________________________________________
@@ -77,8 +81,10 @@ ________________________________________________________________________________
||:imap|| ||:imap||
________________________________________________________________________________ ________________________________________________________________________________
Map the key sequence {lhs} to {rhs} (in insert mode). The {rhs} is remapped, Map the key sequence {lhs} to {rhs} (in insert mode). The {rhs} is remapped,
allowing for nested and recursive mappings. Mappings are NOT saved during allowing for nested and recursive mappings.
sessions, make sure you put them in your vimperatorrc file!
Warning: Mappings are NOT saved during sessions, make sure you put them in your
vimperatorrc file!
________________________________________________________________________________ ________________________________________________________________________________
@@ -247,24 +253,61 @@ ________________________________________________________________________________
||:com[mand][!] [{attr}...] {cmd} {rep}|| + ||:com[mand][!] [{attr}...] {cmd} {rep}|| +
________________________________________________________________________________ ________________________________________________________________________________
Define a new user command. The name of the command is {cmd} and its relacement Define a new user command. The name of the command is {cmd} and its relacement
text is {rep}. The command's attributes are {attr}. If a command with this text is {rep}. The command's attributes are {attr}. If a command with this name
name already exists an error is reported unless [!] is specified, in which case already exists an error is reported unless [!] is specified, in which case the
the command is redefined. Unlike Vim, the command may start with a lowercase command is redefined. Unlike Vim, the command may start with a lowercase
letter. letter.
The command's behavior can be specified by providing attributes when the
command is defined.
|E175| |E176| |:command-nargs| +
Argument handling
By default user commands accept no arguments. This can be changed by specifying
the -nargs attribute.
The valid values are:
`----------`--------------------------------------------------------------------
*-nargs=0* No arguments are allowed (default)
*-nargs=1* One argument is allowed
*-nargs=** Zero or more arguments are allowed
*-nargs=?* Zero or one argument is allowed
*-nargs=+* One or more argument is allowd
--------------------------------------------------------------------------------
|E177| |E178| |:command-count| +
Count handling
By default user commands do not accept a count. Use the -count attribute if
you'd like to have a count passed to your user command. This will then be
available for expansion as <count> in the argument.
|:command-bang| +
Special cases
By default a user command does not have a special version. i.e. a version
executed with the ! modifier. Providing the -bang attribute will enable this
and <bang> will be available in the argument.
|:command-replacement-text| +
Replacement text
The replacement text {rep} is scanned for escape sequences and these are The replacement text {rep} is scanned for escape sequences and these are
replaced with values from the user entered command-line. The resulting string replaced with values from the user entered command-line. The resulting string
is then executed as an Ex command. is then executed as an Ex command.
The valid escape sequences are: The valid escape sequences are:
`----------`-------------------------------------------------------------------- `----------`--------------------------------------------------------------------
*<args>* The command arguments exactly as supplied *<args>* The command arguments exactly as supplied
*<q-args>* The command arguments quoted as a single value in a manner suitable for expression evaluation *<count>* Any supplied count E.g. 5
*<bang>* ! if the command was executed with the ! modifier
*<lt>* A literal '<' character to allow for a literal copy of one of the escape sequences. E.g. <lt>args> will expand to a literal <args> *<lt>* A literal '<' character to allow for a literal copy of one of the escape sequences. E.g. <lt>args> will expand to a literal <args>
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
Note: {attr} not implemented yet. "q-" can be prefixed to the escape sequence so that the value is quoted, making
it suitable for expression evaluation. Example: <q-args>
________________________________________________________________________________ ________________________________________________________________________________
@@ -281,4 +324,12 @@ ________________________________________________________________________________
Delete the user-defined command {cmd}. Delete the user-defined command {cmd}.
________________________________________________________________________________ ________________________________________________________________________________
section:Examples[command-examples]
Add a :Google command to search via google:
:command -nargs=* Google open google <args>
// TODO: add decent examples
// vim: set syntax=asciidoc: // vim: set syntax=asciidoc: