Extract option descriptions in an shared OptionDesc class

This commit is contained in:
Maxime Coste 2014-04-12 20:03:26 +01:00
parent e9276a0a85
commit 9ff356cb2b
3 changed files with 55 additions and 40 deletions

View File

@ -842,9 +842,9 @@ const CommandDesc declare_option_cmd = {
{ {
Option* opt = nullptr; Option* opt = nullptr;
Option::Flags flags = Option::Flags::None; OptionFlags flags = OptionFlags::None;
if (parser.has_option("hidden")) if (parser.has_option("hidden"))
flags = Option::Flags::Hidden; flags = OptionFlags::Hidden;
String docstring; String docstring;
if (parser.has_option("docstring")) if (parser.has_option("docstring"))

View File

@ -7,10 +7,12 @@
namespace Kakoune namespace Kakoune
{ {
Option::Option(OptionManager& manager, String name, String docstring, OptionDesc::OptionDesc(String name, String docstring, OptionFlags flags)
Flags flags) : m_name(std::move(name)), m_docstring(std::move(docstring)),
: m_manager(manager), m_name(std::move(name)), m_flags(flags) {}
m_docstring(std::move(docstring)), m_flags(flags) {}
Option::Option(const OptionDesc& desc, OptionManager& manager)
: m_manager(manager), m_desc(desc) {}
OptionManager::OptionManager(OptionManager& parent) OptionManager::OptionManager(OptionManager& parent)
: m_parent(&parent) : m_parent(&parent)
@ -73,7 +75,7 @@ CandidateList OptionManager::get_matching_names(MatchingFunc func)
result = m_parent->get_matching_names(func); result = m_parent->get_matching_names(func);
for (auto& option : m_options) for (auto& option : m_options)
{ {
if (option->flags() & Option::Flags::Hidden) if (option->flags() & OptionFlags::Hidden)
continue; continue;
const auto& name = option->name(); const auto& name = option->name();
@ -153,7 +155,7 @@ GlobalOptions::GlobalOptions()
std::vector<String>({ "./", "/usr/include" })); std::vector<String>({ "./", "/usr/include" }));
declare_option("completers", "insert mode completers to execute.", declare_option("completers", "insert mode completers to execute.",
std::vector<String>({"filename", "word=buffer"}), std::vector<String>({"filename", "word=buffer"}),
Option::Flags::None, OptionFlags::None,
OptionChecker<std::vector<String>>([](const std::vector<String>& s) { OptionChecker<std::vector<String>>([](const std::vector<String>& s) {
static const auto values = {"word=buffer", "word=all", "filename"}; static const auto values = {"word=buffer", "word=all", "filename"};
for (auto& v : s) for (auto& v : s)

View File

@ -19,18 +19,37 @@ struct option_not_found : public runtime_error
class OptionManager; class OptionManager;
class Option : public SafeCountable enum class OptionFlags
{ {
public:
enum class Flags
{
None = 0, None = 0,
Hidden = 1, Hidden = 1,
}; };
constexpr OptionFlags operator|(OptionFlags lhs, OptionFlags rhs)
{ return (OptionFlags)((int)lhs | (int)rhs); }
Option(OptionManager& manager, String name, String docstring, Flags flags); constexpr bool operator&(OptionFlags lhs, OptionFlags rhs)
virtual ~Option() {} { return (bool)((int)lhs & (int)rhs); }
class OptionDesc
{
public:
OptionDesc(String name, String docstring, OptionFlags flags);
const String& name() const { return m_name; }
const String& docstring() const { return m_docstring; }
OptionFlags flags() const { return m_flags; }
private:
String m_name;
String m_docstring;
OptionFlags m_flags;
};
class Option
{
public:
template<typename T> const T& get() const; template<typename T> const T& get() const;
template<typename T> void set(const T& val); template<typename T> void set(const T& val);
template<typename T> bool is_of_type() const; template<typename T> bool is_of_type() const;
@ -39,25 +58,18 @@ public:
virtual void set_from_string(const String& str) = 0; virtual void set_from_string(const String& str) = 0;
virtual void add_from_string(const String& str) = 0; virtual void add_from_string(const String& str) = 0;
const String& name() const { return m_name; } virtual Option* clone(OptionManager& manager) const = 0;
const String& docstring() const { return m_docstring; }
OptionManager& manager() const { return m_manager; } OptionManager& manager() const { return m_manager; }
virtual Option* clone(OptionManager& manager) const = 0; const String& name() const { return m_desc.name(); }
const String& docstring() const { return m_desc.docstring(); }
Flags flags() const { return m_flags; } OptionFlags flags() const { return m_desc.flags(); }
friend constexpr Flags operator|(Flags lhs, Flags rhs)
{ return (Flags)((int)lhs | (int)rhs); }
friend constexpr bool operator&(Flags lhs, Flags rhs)
{ return (bool)((int)lhs & (int)rhs); }
protected: protected:
Option(const OptionDesc& desc, OptionManager& manager);
OptionManager& m_manager; OptionManager& m_manager;
String m_name; const OptionDesc& m_desc;
String m_docstring;
Flags m_flags;
}; };
class OptionManagerWatcher class OptionManagerWatcher
@ -108,9 +120,9 @@ template<typename T>
class TypedOption : public Option class TypedOption : public Option
{ {
public: public:
TypedOption(OptionManager& manager, String name, String docstring, TypedOption(OptionManager& manager, const OptionDesc& desc,
Option::Flags flags, const T& value, OptionChecker<T> checker) const T& value, OptionChecker<T> checker)
: Option(manager, std::move(name), std::move(docstring), flags), : Option(desc, manager),
m_value(value), m_checker(std::move(checker)) {} m_value(value), m_checker(std::move(checker)) {}
void set(T value) void set(T value)
@ -120,7 +132,7 @@ public:
if (m_checker) if (m_checker)
m_checker(value); m_checker(value);
m_value = std::move(value); m_value = std::move(value);
m_manager.on_option_changed(*this); manager().on_option_changed(*this);
} }
} }
const T& get() const { return m_value; } const T& get() const { return m_value; }
@ -147,8 +159,7 @@ public:
Option* clone(OptionManager& manager) const override Option* clone(OptionManager& manager) const override
{ {
return new TypedOption{manager, name(), docstring(), flags(), return new TypedOption{manager, m_desc, m_value, m_checker};
m_value, m_checker};
} }
private: private:
T m_value; T m_value;
@ -192,7 +203,7 @@ public:
template<typename T> template<typename T>
Option& declare_option(const String& name, const String& docstring, Option& declare_option(const String& name, const String& docstring,
const T& value, const T& value,
Option::Flags flags = Option::Flags::None, OptionFlags flags = OptionFlags::None,
OptionChecker<T> checker = OptionChecker<T>{}) OptionChecker<T> checker = OptionChecker<T>{})
{ {
auto it = find_option(m_options, name); auto it = find_option(m_options, name);
@ -202,11 +213,13 @@ public:
return **it; return **it;
throw runtime_error("option " + name + " already declared with different type or flags"); throw runtime_error("option " + name + " already declared with different type or flags");
} }
m_options.emplace_back(new TypedOption<T>{*this, name, docstring, m_descs.emplace_back(new OptionDesc{name, docstring, flags});
flags, value, m_options.emplace_back(new TypedOption<T>{*this, *m_descs.back(),
std::move(checker)}); value, std::move(checker)});
return *m_options.back(); return *m_options.back();
} }
private:
std::vector<std::unique_ptr<OptionDesc>> m_descs;
}; };
struct OptionManagerRegisterFuncs struct OptionManagerRegisterFuncs