forked from lix-project/lix
Ensure the completion marker is not processed beyond completion
I was surprised to see an error mentioning ___COMPLETE___ when trying to complete a flag argument that had no completer implemented
This commit is contained in:
parent
5f06a91bf7
commit
a6d7cd4183
|
@ -127,9 +127,9 @@ bool Args::processFlag(Strings::iterator & pos, Strings::iterator end)
|
||||||
if (flag.handler.arity == ArityAny) break;
|
if (flag.handler.arity == ArityAny) break;
|
||||||
throw UsageError("flag '%s' requires %d argument(s)", name, flag.handler.arity);
|
throw UsageError("flag '%s' requires %d argument(s)", name, flag.handler.arity);
|
||||||
}
|
}
|
||||||
if (flag.completer)
|
|
||||||
if (auto prefix = needsCompletion(*pos)) {
|
if (auto prefix = needsCompletion(*pos)) {
|
||||||
anyCompleted = true;
|
anyCompleted = true;
|
||||||
|
if (flag.completer)
|
||||||
flag.completer(n, *prefix);
|
flag.completer(n, *prefix);
|
||||||
}
|
}
|
||||||
args.push_back(*pos++);
|
args.push_back(*pos++);
|
||||||
|
@ -146,6 +146,7 @@ bool Args::processFlag(Strings::iterator & pos, Strings::iterator end)
|
||||||
&& hasPrefix(name, std::string(*prefix, 2)))
|
&& hasPrefix(name, std::string(*prefix, 2)))
|
||||||
completions->add("--" + name, flag->description);
|
completions->add("--" + name, flag->description);
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
auto i = longFlags.find(std::string(*pos, 2));
|
auto i = longFlags.find(std::string(*pos, 2));
|
||||||
if (i == longFlags.end()) return false;
|
if (i == longFlags.end()) return false;
|
||||||
|
@ -187,10 +188,12 @@ bool Args::processArgs(const Strings & args, bool finish)
|
||||||
{
|
{
|
||||||
std::vector<std::string> ss;
|
std::vector<std::string> ss;
|
||||||
for (const auto &[n, s] : enumerate(args)) {
|
for (const auto &[n, s] : enumerate(args)) {
|
||||||
ss.push_back(s);
|
if (auto prefix = needsCompletion(s)) {
|
||||||
|
ss.push_back(*prefix);
|
||||||
if (exp.completer)
|
if (exp.completer)
|
||||||
if (auto prefix = needsCompletion(s))
|
|
||||||
exp.completer(n, *prefix);
|
exp.completer(n, *prefix);
|
||||||
|
} else
|
||||||
|
ss.push_back(s);
|
||||||
}
|
}
|
||||||
exp.handler.fun(ss);
|
exp.handler.fun(ss);
|
||||||
expectedArgs.pop_front();
|
expectedArgs.pop_front();
|
||||||
|
@ -322,16 +325,16 @@ MultiCommand::MultiCommand(const Commands & commands_)
|
||||||
.optional = true,
|
.optional = true,
|
||||||
.handler = {[=](std::string s) {
|
.handler = {[=](std::string s) {
|
||||||
assert(!command);
|
assert(!command);
|
||||||
if (auto prefix = needsCompletion(s)) {
|
|
||||||
for (auto & [name, command] : commands)
|
|
||||||
if (hasPrefix(name, *prefix))
|
|
||||||
completions->add(name);
|
|
||||||
}
|
|
||||||
auto i = commands.find(s);
|
auto i = commands.find(s);
|
||||||
if (i == commands.end())
|
if (i == commands.end())
|
||||||
throw UsageError("'%s' is not a recognised command", s);
|
throw UsageError("'%s' is not a recognised command", s);
|
||||||
command = {s, i->second()};
|
command = {s, i->second()};
|
||||||
command->second->parent = this;
|
command->second->parent = this;
|
||||||
|
}},
|
||||||
|
.completer = {[&](size_t, std::string_view prefix) {
|
||||||
|
for (auto & [name, command] : commands)
|
||||||
|
if (hasPrefix(name, prefix))
|
||||||
|
completions->add(name);
|
||||||
}}
|
}}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue