mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-23 11:48:00 +01:00
More completion stuff
This commit is contained in:
@@ -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]]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -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,10 +555,12 @@ 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -575,10 +570,12 @@ 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1078,24 +1078,23 @@ 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)
|
||||||
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
|
|
||||||
compObject = { start: compObject[0], items: compObject[1] };
|
|
||||||
if (args.completions)
|
|
||||||
{
|
{
|
||||||
argContext.title = [args.completeOpt || "Options"];
|
context.advance(args.completeStart);
|
||||||
argContext.items = args.completions;
|
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 != null)
|
compObject = { start: compObject[0], items: compObject[1] };
|
||||||
{
|
if (compObject != null)
|
||||||
context.advance(compObject.start);
|
{
|
||||||
context.title = ["Completions"];
|
context.advance(compObject.start);
|
||||||
context.items = compObject.items;
|
context.title = ["Completions"];
|
||||||
|
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)]);
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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">
|
||||||
|
<div class="hl-Completions">
|
||||||
{
|
{
|
||||||
items.allItems.items.length == 0 &&
|
items.allItems.items.length == 0 ?
|
||||||
<div class="hl-Completions">
|
|
||||||
<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
|
||||||
|
|||||||
Reference in New Issue
Block a user