Move enum option handling in enum.hh and refactor enum options
This commit is contained in:
parent
c0f1b7b99f
commit
5e4f5cd2a0
|
@ -236,15 +236,15 @@ void Client::check_if_buffer_needs_reloading()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Buffer& buffer = context().buffer();
|
Buffer& buffer = context().buffer();
|
||||||
auto reload = context().options()["autoreload"].get<YesNoAsk>();
|
auto reload = context().options()["autoreload"].get<Autoreload>();
|
||||||
if (not (buffer.flags() & Buffer::Flags::File) or reload == No)
|
if (not (buffer.flags() & Buffer::Flags::File) or reload == Autoreload::No)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const String& filename = buffer.name();
|
const String& filename = buffer.name();
|
||||||
timespec ts = get_fs_timestamp(filename);
|
timespec ts = get_fs_timestamp(filename);
|
||||||
if (ts == InvalidTime or ts == buffer.fs_timestamp())
|
if (ts == InvalidTime or ts == buffer.fs_timestamp())
|
||||||
return;
|
return;
|
||||||
if (reload == Ask)
|
if (reload == Autoreload::Ask)
|
||||||
{
|
{
|
||||||
m_ui->info_show(
|
m_ui->info_show(
|
||||||
format("reload '{}' ?", buffer.display_name()),
|
format("reload '{}' ?", buffer.display_name()),
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "safe_ptr.hh"
|
#include "safe_ptr.hh"
|
||||||
#include "utils.hh"
|
#include "utils.hh"
|
||||||
#include "option_manager.hh"
|
#include "option_manager.hh"
|
||||||
|
#include "enum.hh"
|
||||||
|
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
@ -84,6 +85,24 @@ private:
|
||||||
SafePtr<Buffer> m_last_buffer;
|
SafePtr<Buffer> m_last_buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class Autoreload
|
||||||
|
{
|
||||||
|
Yes,
|
||||||
|
No,
|
||||||
|
Ask
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr Array<EnumDesc<Autoreload>, 5> enum_desc(Autoreload)
|
||||||
|
{
|
||||||
|
return { {
|
||||||
|
{ Autoreload::Yes, "yes" },
|
||||||
|
{ Autoreload::No, "no" },
|
||||||
|
{ Autoreload::Ask, "ask" },
|
||||||
|
{ Autoreload::Yes, "true" },
|
||||||
|
{ Autoreload::No, "false" }
|
||||||
|
} };
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // client_hh_INCLUDED
|
#endif // client_hh_INCLUDED
|
||||||
|
|
76
src/enum.hh
Normal file
76
src/enum.hh
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
#ifndef enum_hh_INCLUDED
|
||||||
|
#define enum_hh_INCLUDED
|
||||||
|
|
||||||
|
#include "flags.hh"
|
||||||
|
#include "string.hh"
|
||||||
|
#include "exception.hh"
|
||||||
|
#include "containers.hh"
|
||||||
|
|
||||||
|
namespace Kakoune
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename T, size_t N>
|
||||||
|
struct Array
|
||||||
|
{
|
||||||
|
constexpr size_t size() const { return N; }
|
||||||
|
constexpr const T& operator[](int i) const { return m_data[i]; }
|
||||||
|
constexpr const T* begin() const { return m_data; }
|
||||||
|
constexpr const T* end() const { return m_data+N; }
|
||||||
|
|
||||||
|
T m_data[N];
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T> struct EnumDesc { T value; StringView name; };
|
||||||
|
|
||||||
|
template<typename Flags, typename = decltype(enum_desc(Flags{}))>
|
||||||
|
EnableIfWithBitOps<Flags, String> option_to_string(Flags flags)
|
||||||
|
{
|
||||||
|
constexpr auto desc = enum_desc(Flags{});
|
||||||
|
String res;
|
||||||
|
for (int i = 0; i < desc.size(); ++i)
|
||||||
|
{
|
||||||
|
if (not (flags & desc[i].value))
|
||||||
|
continue;
|
||||||
|
if (not res.empty())
|
||||||
|
res += "|";
|
||||||
|
res += desc[i].name;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Enum, typename = decltype(enum_desc(Enum{}))>
|
||||||
|
EnableIfWithoutBitOps<Enum, String> option_to_string(Enum e)
|
||||||
|
{
|
||||||
|
constexpr auto desc = enum_desc(Enum{});
|
||||||
|
auto it = find_if(desc, [e](const EnumDesc<Enum>& d) { return d.value == e; });
|
||||||
|
kak_assert(it != desc.end());
|
||||||
|
return it->name.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Flags, typename = decltype(enum_desc(Flags{}))>
|
||||||
|
EnableIfWithBitOps<Flags> option_from_string(StringView str, Flags& flags)
|
||||||
|
{
|
||||||
|
constexpr auto desc = enum_desc(Flags{});
|
||||||
|
flags = Flags{};
|
||||||
|
for (auto s : split(str, '|'))
|
||||||
|
{
|
||||||
|
auto it = find_if(desc, [s](const EnumDesc<Flags>& d) { return d.name == s; });
|
||||||
|
if (it == desc.end())
|
||||||
|
throw runtime_error(format("invalid flag value '{}'", s));
|
||||||
|
flags |= it->value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Enum, typename = decltype(enum_desc(Enum{}))>
|
||||||
|
EnableIfWithoutBitOps<Enum> option_from_string(StringView str, Enum& e)
|
||||||
|
{
|
||||||
|
constexpr auto desc = enum_desc(Enum{});
|
||||||
|
auto it = find_if(desc, [str](const EnumDesc<Enum>& d) { return d.name == str; });
|
||||||
|
if (it == desc.end())
|
||||||
|
throw runtime_error(format("invalid enum value '{}'", str));
|
||||||
|
e = it->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // enum_hh_INCLUDED
|
|
@ -12,8 +12,11 @@ struct WithBitOps : std::false_type {};
|
||||||
template<typename Flags>
|
template<typename Flags>
|
||||||
using UnderlyingType = typename std::underlying_type<Flags>::type;
|
using UnderlyingType = typename std::underlying_type<Flags>::type;
|
||||||
|
|
||||||
template<typename Flags>
|
template<typename Flags, typename T = void>
|
||||||
using EnableIfWithBitOps = typename std::enable_if<WithBitOps<Flags>::value>::type;
|
using EnableIfWithBitOps = typename std::enable_if<WithBitOps<Flags>::value, T>::type;
|
||||||
|
|
||||||
|
template<typename Flags, typename T = void>
|
||||||
|
using EnableIfWithoutBitOps = typename std::enable_if<not WithBitOps<Flags>::value, T>::type;
|
||||||
|
|
||||||
template<typename Flags, typename = EnableIfWithBitOps<Flags>>
|
template<typename Flags, typename = EnableIfWithBitOps<Flags>>
|
||||||
constexpr Flags operator|(Flags lhs, Flags rhs)
|
constexpr Flags operator|(Flags lhs, Flags rhs)
|
||||||
|
|
|
@ -103,6 +103,26 @@ private:
|
||||||
int m_handle_key_level = 0;
|
int m_handle_key_level = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class AutoInfo
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Command = 1 << 0,
|
||||||
|
OnKey = 1 << 1,
|
||||||
|
Normal = 1 << 2
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct WithBitOps<AutoInfo> : std::true_type {};
|
||||||
|
|
||||||
|
constexpr Array<EnumDesc<AutoInfo>, 3> enum_desc(AutoInfo)
|
||||||
|
{
|
||||||
|
return { {
|
||||||
|
{ AutoInfo::Command, "command"},
|
||||||
|
{ AutoInfo::OnKey, "onkey"},
|
||||||
|
{ AutoInfo::Normal, "normal" }
|
||||||
|
} };
|
||||||
|
}
|
||||||
|
|
||||||
bool show_auto_info_ifn(StringView title, StringView info, AutoInfo mask, const Context& context);
|
bool show_auto_info_ifn(StringView title, StringView info, AutoInfo mask, const Context& context);
|
||||||
|
|
||||||
template<typename Cmd>
|
template<typename Cmd>
|
||||||
|
|
|
@ -224,7 +224,7 @@ void register_options()
|
||||||
}), OptionFlags::None);
|
}), OptionFlags::None);
|
||||||
reg.declare_option("autoreload",
|
reg.declare_option("autoreload",
|
||||||
"autoreload buffer when a filesystem modification is detected",
|
"autoreload buffer when a filesystem modification is detected",
|
||||||
Ask);
|
Autoreload::Ask);
|
||||||
reg.declare_option("ui_options",
|
reg.declare_option("ui_options",
|
||||||
"colon separated list of <key>=<value> options that are "
|
"colon separated list of <key>=<value> options that are "
|
||||||
"passed to and interpreted by the user interface\n"
|
"passed to and interpreted by the user interface\n"
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "array_view.hh"
|
#include "array_view.hh"
|
||||||
#include "id_map.hh"
|
#include "id_map.hh"
|
||||||
#include "flags.hh"
|
#include "flags.hh"
|
||||||
|
#include "enum.hh"
|
||||||
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -192,101 +193,6 @@ inline String option_to_string(const LineAndColumn<EffectiveType, LineType, Colu
|
||||||
return format("{},{}", opt.line, opt.column);
|
return format("{},{}", opt.line, opt.column);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum YesNoAsk
|
|
||||||
{
|
|
||||||
Yes,
|
|
||||||
No,
|
|
||||||
Ask
|
|
||||||
};
|
|
||||||
|
|
||||||
inline String option_to_string(YesNoAsk opt)
|
|
||||||
{
|
|
||||||
switch (opt)
|
|
||||||
{
|
|
||||||
case Yes: return "yes";
|
|
||||||
case No: return "no";
|
|
||||||
case Ask: return "ask";
|
|
||||||
}
|
|
||||||
kak_assert(false);
|
|
||||||
return "ask";
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void option_from_string(StringView str, YesNoAsk& opt)
|
|
||||||
{
|
|
||||||
if (str == "yes" or str == "true")
|
|
||||||
opt = Yes;
|
|
||||||
else if (str == "no" or str == "false")
|
|
||||||
opt = No;
|
|
||||||
else if (str == "ask")
|
|
||||||
opt = Ask;
|
|
||||||
else
|
|
||||||
throw runtime_error(format("invalid value '{}', expected yes, no or ask", str));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T> struct EnumInfo;
|
|
||||||
|
|
||||||
template<typename Flags,
|
|
||||||
typename = EnableIfWithBitOps<Flags>,
|
|
||||||
typename = decltype(EnumInfo<Flags>::values(), EnumInfo<Flags>::names())>
|
|
||||||
String option_to_string(Flags flags)
|
|
||||||
{
|
|
||||||
auto names = EnumInfo<Flags>::names();
|
|
||||||
auto values = EnumInfo<Flags>::values();
|
|
||||||
String res;
|
|
||||||
for (int i = 0; i < values.size(); ++i)
|
|
||||||
{
|
|
||||||
if (not (flags & values[i]))
|
|
||||||
continue;
|
|
||||||
if (not res.empty())
|
|
||||||
res += "|";
|
|
||||||
res += names[i];
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Flags,
|
|
||||||
typename = EnableIfWithBitOps<Flags>,
|
|
||||||
typename = decltype(EnumInfo<Flags>::values(), EnumInfo<Flags>::names())>
|
|
||||||
void option_from_string(StringView str, Flags& flags)
|
|
||||||
{
|
|
||||||
auto names = EnumInfo<Flags>::names();
|
|
||||||
auto values = EnumInfo<Flags>::values();
|
|
||||||
flags = Flags{};
|
|
||||||
for (auto s : split(str, '|'))
|
|
||||||
{
|
|
||||||
auto it = std::find(names.begin(), names.end(), s);
|
|
||||||
if (it == names.end())
|
|
||||||
throw runtime_error(format("invalid flag value '{}'", s));
|
|
||||||
flags |= values[it - names.begin()];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class AutoInfo
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
Command = 1 << 0,
|
|
||||||
OnKey = 1 << 1,
|
|
||||||
Normal = 1 << 2
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct WithBitOps<AutoInfo> : std::true_type {};
|
|
||||||
|
|
||||||
template<> struct EnumInfo<AutoInfo>
|
|
||||||
{
|
|
||||||
static ArrayView<const AutoInfo> values()
|
|
||||||
{
|
|
||||||
static constexpr AutoInfo values[] = { AutoInfo::Command, AutoInfo::OnKey, AutoInfo::Normal };
|
|
||||||
return { values };
|
|
||||||
}
|
|
||||||
|
|
||||||
static ArrayView<const StringView> names()
|
|
||||||
{
|
|
||||||
static constexpr StringView names[] = { "command", "onkey", "normal" };
|
|
||||||
return { names };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class DebugFlags
|
enum class DebugFlags
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
|
@ -297,21 +203,14 @@ enum class DebugFlags
|
||||||
template<>
|
template<>
|
||||||
struct WithBitOps<DebugFlags> : std::true_type {};
|
struct WithBitOps<DebugFlags> : std::true_type {};
|
||||||
|
|
||||||
template<> struct EnumInfo<DebugFlags>
|
constexpr Array<EnumDesc<DebugFlags>, 2> enum_desc(DebugFlags)
|
||||||
{
|
{
|
||||||
static ArrayView<const DebugFlags> values()
|
return { {
|
||||||
{
|
{ DebugFlags::Hooks, "hooks" },
|
||||||
static constexpr DebugFlags values[] = { DebugFlags::Hooks, DebugFlags::Shell };
|
{ DebugFlags::Shell, "shell" }
|
||||||
return { values };
|
} };
|
||||||
}
|
}
|
||||||
|
|
||||||
static ArrayView<const StringView> names()
|
|
||||||
{
|
|
||||||
static constexpr StringView names[] = { "hooks", "shell" };
|
|
||||||
return { names };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // option_types_hh_INCLUDED
|
#endif // option_types_hh_INCLUDED
|
||||||
|
|
Loading…
Reference in New Issue
Block a user