Move option name completion to the OptionRegistry

Option names are the same for every option manager.
This commit is contained in:
Maxime Coste 2015-08-10 13:38:06 +01:00
parent f5e4562bd9
commit bfb116b8b4
4 changed files with 31 additions and 39 deletions

View File

@ -552,7 +552,7 @@ Completions CommandManager::complete(const Context& context,
case Token::Type::OptionExpand:
{
Completions result(start , cursor_pos);
result.candidates = context.options().complete_option_name(
result.candidates = GlobalScope::instance().option_registry().complete_option_name(
tokens[tok_idx].content(), cursor_pos_in_token);
return result;
}

View File

@ -1009,11 +1009,8 @@ const CommandDesc set_option_cmd = {
return { 0_byte, params[0].length(),
complete(params[0], pos_in_token, scopes) };
else if (token_to_complete == 1)
{
OptionManager& options = get_scope(params[0], context).options();
return { 0_byte, params[1].length(),
options.complete_option_name(params[1], pos_in_token) };
}
GlobalScope::instance().option_registry().complete_option_name(params[1], pos_in_token) };
else if (token_to_complete == 2 and
GlobalScope::instance().option_registry().option_exists(params[1]))
{

View File

@ -76,35 +76,6 @@ const Option& OptionManager::operator[](StringView name) const
return const_cast<OptionManager&>(*this)[name];
}
template<typename MatchingFunc>
CandidateList OptionManager::get_matching_names(MatchingFunc func)
{
CandidateList result;
if (m_parent)
result = m_parent->get_matching_names(func);
for (auto& option : m_options)
{
if (option->flags() & OptionFlags::Hidden)
continue;
const auto& name = option->name();
if (func(name) and not contains(result, name))
result.push_back(name);
}
return result;
}
CandidateList OptionManager::complete_option_name(StringView prefix,
ByteCount cursor_pos)
{
using namespace std::placeholders;
auto real_prefix = prefix.substr(0, cursor_pos);
auto result = get_matching_names(std::bind(prefix_match, _1, real_prefix));
if (result.empty())
result = get_matching_names(std::bind(subsequence_match, _1, real_prefix));
return result;
}
OptionManager::OptionList OptionManager::flatten_options() const
{
OptionList res = m_parent ? m_parent->flatten_options() : OptionList{};
@ -130,4 +101,31 @@ void OptionManager::on_option_changed(const Option& option)
watcher->on_option_changed(option);
}
template<typename Container, typename MatchingFunc>
static CandidateList get_matching_names(const Container& options, MatchingFunc func)
{
CandidateList result;
for (auto& option : options)
{
if (option->flags() & OptionFlags::Hidden)
continue;
const auto& name = option->name();
if (func(name))
result.push_back(name);
}
return result;
}
CandidateList OptionsRegistry::complete_option_name(StringView prefix,
ByteCount cursor_pos) const
{
using namespace std::placeholders;
auto real_prefix = prefix.substr(0, cursor_pos);
auto result = get_matching_names(m_descs, std::bind(prefix_match, _1, real_prefix));
if (result.empty())
result = get_matching_names(m_descs, std::bind(subsequence_match, _1, real_prefix));
return result;
}
}

View File

@ -83,8 +83,6 @@ public:
const Option& operator[] (StringView name) const;
Option& get_local_option(StringView name);
CandidateList complete_option_name(StringView prefix,
ByteCount cursor_pos);
using OptionList = Vector<const Option*>;
OptionList flatten_options() const;
@ -100,9 +98,6 @@ private:
friend class Scope;
friend class OptionsRegistry;
template<typename MatchingFunc>
CandidateList get_matching_names(MatchingFunc func);
Vector<std::unique_ptr<Option>, MemoryDomain::Options> m_options;
OptionManager* m_parent;
@ -222,6 +217,8 @@ public:
return opt->name() == name;
}) != m_descs.end();
}
CandidateList complete_option_name(StringView prefix, ByteCount cursor_pos) const;
private:
OptionManager& m_global_manager;
Vector<std::unique_ptr<OptionDesc>, MemoryDomain::Options> m_descs;