1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-23 22:52:38 +01:00

Better option completion.

This commit is contained in:
Kris Maglione
2008-10-02 22:08:58 +00:00
parent 8100d941f8
commit 298d0ab294

View File

@@ -394,6 +394,60 @@ liberator.Options = function () //{{{
}
);
// FIXME: Integrate with setter
function parseOpt(args, modifiers)
{
let ret = {};
ret.onlyNonDefault = false; // used for :set to print non-default options
if (!args)
{
args = "all";
ret.onlyNonDefault = true;
}
// 1 2 3 4 5 6
var matches = args.match(/^\s*(no|inv)?([a-z_]+)([?&!])?\s*(([-+^]?)=(.*))?\s*$/);
if (!matches)
return null;
ret.unsetBoolean = false;
if (matches[1] == "no")
ret.unsetBoolean = true;
ret.name = matches[2];
ret.all = false;
if (ret.name == "all")
ret.all = true;
ret.scope = modifiers && modifiers.scope || liberator.options.OPTION_SCOPE_BOTH;
ret.option = liberator.options.get(ret.name, ret.scope);
if (!ret.option && !ret.all)
return ret;
let valueGiven = !!matches[4];
ret.get = false;
if (ret.all || matches[3] == "?" || (ret.option.type != "boolean" && !valueGiven))
ret.get = true;
ret.reset = false;
if (matches[3] == "&")
ret.reset = true;
ret.invert = false;
if (matches[1] == "inv" || matches[3] == "!")
ret.invert = true;
ret.operator = matches[5];
ret.value = matches[6];
if (ret.value === undefined)
ret.value = "";
return ret;
}
// TODO: support setting multiple options at once
liberator.commands.add(["se[t]"],
"Set an option",
@@ -462,7 +516,7 @@ liberator.Options = function () //{{{
}
// 1 2 3 4 5 6
var matches = args.match(/^\s*(no|inv)?([a-z_]+)([?&!])?\s*(([-+^]?)=(.*))?\s*$/);
var matches = args.match(/^\s*(no|inv)?([a-z_]+)([?&!])?\s*(([-+^]?)=(.*))?$/);
if (!matches)
{
liberator.echoerr("E518: Unknown option: " + args);
@@ -662,20 +716,19 @@ liberator.Options = function () //{{{
if (filter.length > 0 && filter.lastIndexOf("=") == filter.length - 1)
{
for (let i = 0; i < prefArray.length; i++)
for (let [,name] in prefArray)
{
var name = prefArray[i];
if (name.match("^" + filter.substr(0, filter.length - 1) + "$" ))
{
var value = liberator.options.getPref(name) + "";
let value = liberator.options.getPref(name) + "";
return [filter.length + 1, [[value, ""]]];
}
}
return [0, []];
}
for (let i = 0; i < prefArray.length; i++)
optionCompletions.push([prefArray[i], liberator.options.getPref(prefArray[i])]);
optionCompletions = prefArray.map(function (pref)
[pref, liberator.options.getPref(pref)]);
return [0, liberator.completion.filter(optionCompletions, filter)];
}
@@ -684,61 +737,80 @@ liberator.Options = function () //{{{
if (modifiers && modifiers.scope)
scope = modifiers.scope;
let options = (opt for (opt in liberator.options)
if ((opt.scope & scope) && (!prefix || opt.type == "boolean")));
if (!filter)
{
var options = [];
for (let option in liberator.options)
{
if (!(option.scope & scope))
continue;
if (prefix && option.type != "boolean")
continue;
options.push([prefix + option.name, option.description]);
}
let options = [[prefix + option.name, option.description]
for (option in options)];
return [0, options];
}
// check if filter ends with =, then complete current value
else if (filter.length > 0 && filter.lastIndexOf("=") == filter.length - 1)
else if (filter.indexOf("=") == -1)
{
filter = filter.substr(0, filter.length - 1);
for (let option in liberator.options)
{
if (!(option.scope & scope))
continue;
if (option.hasName(filter))
{
// TODO: the starting value should be the current
// value, for compatibility with Vim (also the most
// useful approach in this case) while still
// offering much better completion
if (option.completer)
return [filter.length + 1, option.completer(filter)]; // FIXME: filter should be component after "option="
return [filter.length + 1, [[option.value + "", ""]]];
}
}
return [0, optionCompletions];
for (let option in options)
optionCompletions.push([[prefix + name, option.description]
for (name in option.names)
if (name.indexOf(filter) == 0)]);
// Flatten array.
optionCompletions = Array.concat.apply(Array, optionCompletions);
return [0, liberator.completion.filter(optionCompletions, prefix + filter, true)];
}
else if (prefix)
return;
var filterLength = filter.length;
for (let option in liberator.options)
let [name, value] = filter.split("=", 2);
let offset = name.length + 1;
let opt = parseOpt(filter, modifiers);
let option = opt.option;
if (opt.get || opt.reset || !option || prefix)
return [0, []];
let len = opt.value.length;
let completer = option.completer;
let have = null;
let have2;
switch (option.type)
{
if (!(option.scope & scope))
continue;
if (prefix && option.type != "boolean")
continue;
for (let j = 0; j < option.names.length; j++)
{
if (option.names[j].indexOf(filter) != 0)
continue;
optionCompletions.push([prefix + option.names[j], option.description]);
case "boolean":
completer = function () [["true", ""], ["false", ""]]
break;
case "stringlist":
have = option.value.split(",");
have2 = opt.value.split(",");
len = have2.pop().length;
break;
case "charlist":
have = option.value.split("");
have2 = opt.value;
len = 0;
break;
}
}
return [0, liberator.completion.filter(optionCompletions, prefix + filter, true)];
len = filter.length - len;
filter = filter.substr(len);
if (!completer)
return [len, [[option.value, ""]]];
let completions = completer(filter);
if (have)
{
completions = completions.filter(function (val) have2.indexOf(val[0]) == -1);
switch (opt.operator)
{
case "+":
completions = completions.filter(function (val) have.indexOf(val[0]) == -1);
break;
case "-":
completions = completions.filter(function (val) have.indexOf(val[0]) > -1);
break;
}
}
return [len, liberator.completion.filter(completions, filter, true)];
}
});