1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-23 13:32:27 +01:00

More completion stuff

This commit is contained in:
Kris Maglione
2008-11-22 23:42:59 +00:00
parent d3449c2f50
commit 77dca6413f
5 changed files with 82 additions and 70 deletions

View File

@@ -280,8 +280,15 @@ function Bookmarks() //{{{
}, },
{ argCount: "0" }); { argCount: "0" });
function tags() util.Array.uniq(util.Array.flatten([b.tags for ([k, b] in Iterator(cache.bookmarks))])) function tags(context, args)
.map(function (tag) [tag, tag]); {
let filter = args.completeFilter;
let have = filter.split(",");
args.completeFilter = have.pop();
let prefix = filter.substr(0, filter.length - args.completeFilter.length);
let tags = util.Array.uniq(util.Array.flatten([b.tags for ([k, b] in Iterator(cache.bookmarks))]));
return [[prefix + tag, tag] for ([i, tag] in Iterator(tags)) if (have.indexOf(tag) < 0)];
}
commands.add(["bma[rk]"], commands.add(["bma[rk]"],
"Add a bookmark", "Add a bookmark",
@@ -318,13 +325,7 @@ function Bookmarks() //{{{
}, },
{ {
bang: true, bang: true,
completer: function (context, args) completer: function (context, args) completion.url(context, "b"),
{
if (args.completeOpt)
return;
context.advance(args.completeStart); // TODO: Move this to completion.ex?
completion.url(context, "b");
},
options: [[["-tags", "-T"], commands.OPTION_LIST, null, tags]] options: [[["-tags", "-T"], commands.OPTION_LIST, null, tags]]
}); });

View File

@@ -438,23 +438,22 @@ function Commands() //{{{
var arg = null; var arg = null;
var count = 0; // the length of the argument var count = 0; // the length of the argument
var i = 0; var i = 0;
var completeOpts;
// XXX // XXX
function matchOpts(arg) function matchOpts(arg)
{ {
// Push possible option matches into completions // Push possible option matches into completions
if (!onlyArgumentsRemaining && !quote) if (complete && !onlyArgumentsRemaining)
args.completions = [[opt[0][0], opt[0][0]] for ([i, opt] in Iterator(options)) if (opt[0][0].indexOf(arg) == 0)]; completeOpts = [[opt[0][0], opt[0][0]] for ([i, opt] in Iterator(options)) if (opt[0][0].indexOf(arg) == 0)];
//args.completions = util.Array.flatten(
// options.map(function ([names]) names.filter(
// function (name) name.indexOf(arg) == 0)));
} }
function resetCompletions() function resetCompletions()
{ {
completeOpts = null;
args.completeArg = null; args.completeArg = null;
args.completeOpt = null; args.completeOpt = null;
args.completeFilter = null;
args.completeStart = i; args.completeStart = i;
args.completions = [];
args.quote = quoteArg[""]; args.quote = quoteArg[""];
} }
if (complete) if (complete)
@@ -471,11 +470,10 @@ function Commands() //{{{
resetCompletions(); resetCompletions();
// skip whitespace // skip whitespace
if (/\s/.test(str[i])) while (/\s/.test(str[i]) && i < str.length)
{
i++; i++;
continue; if (i == str.length && !complete)
} break;
var sub = str.substr(i); var sub = str.substr(i);
//liberator.dump(i + ": " + sub + " - " + onlyArgumentsRemaining + "\n"); //liberator.dump(i + ": " + sub + " - " + onlyArgumentsRemaining + "\n");
@@ -486,6 +484,8 @@ function Commands() //{{{
continue; continue;
} }
matchOpts(sub);
var optname = ""; var optname = "";
if (!onlyArgumentsRemaining) if (!onlyArgumentsRemaining)
{ {
@@ -532,29 +532,22 @@ function Commands() //{{{
invalid = true; invalid = true;
} }
if (complete) let context = null;
{ if (!complete && quote)
if (quote || !invalid && count && i + optname.length + 1 + arg.length == str.length)
{
args.completeStart += optname.length + 1;
args.completeOpt = opt[0][0];
args.quote = quoteArg[quote] || quoteArg[""];
if (typeof opt[3] == "function")
var compl = opt[3]();
else
compl = opt[3] || [];
args.completions = completion.filter(compl.map(function ([k, v]) [args.quote(k), v]), arg);;
return args;
}
}
else if (quote)
{ {
liberator.echoerr("Invalid argument for option " + optname); liberator.echoerr("Invalid argument for option " + optname);
return null; return null;
} }
if (!invalid && (!complete || count)) if (!invalid)
{ {
if (complete && count > 0)
{
args.completeStart += optname.length + 1;
args.completeOpt = opt;
args.completeFilter = arg;
args.quote = quoteArg[quote] || quoteArg[""];
}
let type = argTypes[opt[1]]; let type = argTypes[opt[1]];
if (type) if (type)
{ {
@@ -562,12 +555,14 @@ function Commands() //{{{
if (arg == null || arg == NaN) if (arg == null || arg == NaN)
{ {
if (complete) if (complete)
commandline.highlight(completions.completeStart, arg.length, "SPELLCHECK"); complete.highlight(args.completeStart, count - 1, "SPELLCHECK");
else else
{
liberator.echoerr("Invalid argument for " + type.description + "option: " + optname); liberator.echoerr("Invalid argument for " + type.description + "option: " + optname);
return null; return null;
} }
} }
}
// we have a validator function // we have a validator function
if (typeof opt[2] == "function") if (typeof opt[2] == "function")
@@ -575,12 +570,14 @@ function Commands() //{{{
if (opt[2].call(this, arg) == false) if (opt[2].call(this, arg) == false)
{ {
if (complete) if (complete)
commandline.highlight(completions.completeStart, arg.length, "SPELLCHECK"); complete.highlight(args.completeStart, count - 1, "SPELLCHECK");
else else
{
liberator.echoerr("Invalid argument for option: " + optname); liberator.echoerr("Invalid argument for option: " + optname);
return null; return null;
} }
} }
}
args[opt[0][0]] = arg; // always use the first name of the option args[opt[0][0]] = arg; // always use the first name of the option
i += optname.length + count; i += optname.length + count;
@@ -597,18 +594,14 @@ function Commands() //{{{
args.literalArg = sub; args.literalArg = sub;
args.arguments.push(sub); args.arguments.push(sub);
if (complete) if (complete)
args.completeArg = args.arguments.length; args.completeArg = args.arguments.length - 1;
break; break;
} }
// if not an option, treat this token as an argument // if not an option, treat this token as an argument
var [count, arg, quote] = getNextArg(sub); var [count, arg, quote] = getNextArg(sub);
if (complete) if (complete)
{
args.quote = quoteArg[quote] || quoteArg[""]; args.quote = quoteArg[quote] || quoteArg[""];
args.completeArg = args.arguments.length;
matchOpts(arg);
}
else if (count == -1) else if (count == -1)
{ {
liberator.echoerr("Error parsing arguments: " + arg); liberator.echoerr("Error parsing arguments: " + arg);
@@ -623,13 +616,32 @@ function Commands() //{{{
if (arg != null) if (arg != null)
args.arguments.push(arg); args.arguments.push(arg);
if (complete) if (complete)
args.completeArg = args.arguments.length; args.completeArg = args.arguments.length - 1;
if (count <= 0) if (count <= 0)
throw Error("count <= 0"); // Shouldn't happen. break;
i += count; i += count;
} }
if (complete)
{
if (args.completeOpt)
{
let opt = args.completeOpt;
let context = complete.fork(opt[0][0], args.completeStart);
if (typeof opt[3] == "function")
var compl = opt[3](context, args);
else
compl = opt[3] || [];
context.title = [opt[0][0]];
context.items = completion.filter(compl.map(function ([k, v]) [args.quote(k), v]), args.completeFilter);;
}
complete.advance(args.completeStart);
complete.title = ["Options"];
if (completeOpts)
complete.items = completeOpts;
}
// check for correct number of arguments // check for correct number of arguments
if (args.arguments.length == 0 && (argCount == "1" || argCount == "+") && !complete) if (args.arguments.length == 0 && (argCount == "1" || argCount == "+") && !complete)
{ {

View File

@@ -1078,19 +1078,17 @@ function Completion() //{{{
{ {
[prefix] = context.filter.match(/^(?:\w*[\s!]|!)\s*/); [prefix] = context.filter.match(/^(?:\w*[\s!]|!)\s*/);
context = context.fork(cmd, prefix.length); context = context.fork(cmd, prefix.length);
args = command.parseArgs(context.filter, true); let argContext = context.fork("args", args.completeStart);
args = command.parseArgs(context.filter, argContext);
if (args) if (args)
{ {
// XXX, XXX, XXX // XXX, XXX, XXX
let argContext = context.fork("args", args.completeStart); if (!args.completeOpt)
{
context.advance(args.completeStart);
compObject = command.completer.call(command, context, args, special, count); compObject = command.completer.call(command, context, args, special, count);
if (compObject instanceof Array) // for now at least, let completion functions return arrays instead of objects if (compObject instanceof Array) // for now at least, let completion functions return arrays instead of objects
compObject = { start: compObject[0], items: compObject[1] }; compObject = { start: compObject[0], items: compObject[1] };
if (args.completions)
{
argContext.title = [args.completeOpt || "Options"];
argContext.items = args.completions;
}
if (compObject != null) if (compObject != null)
{ {
context.advance(compObject.start); context.advance(compObject.start);
@@ -1098,6 +1096,7 @@ function Completion() //{{{
context.items = compObject.items; context.items = compObject.items;
} }
} }
}
//liberator.dump([[v.name, v.offset, v.items.length, v.hasItems] for each (v in context.contexts)]); //liberator.dump([[v.name, v.offset, v.items.length, v.hasItems] for each (v in context.contexts)]);
} }
}, },

View File

@@ -441,9 +441,8 @@ liberator.registerObserver("load_commands", function ()
} }
catch (e) {} catch (e) {}
compl = compl.concat([[s, ""] for each (s in styles.sites)]) compl = compl.concat([[s, ""] for each (s in styles.sites)])
return [0, completion.filter(compl, args.arguments[0])]; context.items = completion.filter(compl, args.arguments[0]);
} }
return [0, []];
}, },
hereDoc: true, hereDoc: true,
literal: true, literal: true,

View File

@@ -1362,22 +1362,23 @@ function ItemList(id) //{{{
} }
let xml = <div class="ex-command-output hl-Normal" style="white-space: nowrap"> let xml = <div class="ex-command-output hl-Normal" style="white-space: nowrap">
{
items.allItems.items.length == 0 &&
<div class="hl-Completions"> <div class="hl-Completions">
{
items.allItems.items.length == 0 ?
<span class="hl-Title">No Completions</span> <span class="hl-Title">No Completions</span>
</div> || <></> : <></>
} }
{ {
template.map(items.contextList, function (context) context.hasItems && template.map(items.contextList, function (context) context.hasItems ?
<div class="hl-Completions"> <>
{ context.createRow(context, context.title || {}, "hl-CompTitle") } { context.createRow(context, context.title || {}, "hl-CompTitle") }
{ {
template.map(range(context), function (i) context.createRow(context, context.items[i])) template.map(range(context), function (i) context.createRow(context, context.items[i]))
} }
</div> </>
|| undefined) : undefined)
} }
</div>
<div class="hl-Completions"> <div class="hl-Completions">
{ {
// Hmm. The problem with not making this a CompItem is that // Hmm. The problem with not making this a CompItem is that