summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client.cc6
-rw-r--r--src/client.hh19
-rw-r--r--src/enum.hh76
-rw-r--r--src/flags.hh7
-rw-r--r--src/input_handler.hh20
-rw-r--r--src/main.cc2
-rw-r--r--src/option_types.hh115
7 files changed, 131 insertions, 114 deletions
diff --git a/src/client.cc b/src/client.cc
index 79d1df7a..ec7f3ce8 100644
--- a/src/client.cc
+++ b/src/client.cc
@@ -236,15 +236,15 @@ void Client::check_if_buffer_needs_reloading()
return;
Buffer& buffer = context().buffer();
- auto reload = context().options()["autoreload"].get<YesNoAsk>();
- if (not (buffer.flags() & Buffer::Flags::File) or reload == No)
+ auto reload = context().options()["autoreload"].get<Autoreload>();
+ if (not (buffer.flags() & Buffer::Flags::File) or reload == Autoreload::No)
return;
const String& filename = buffer.name();
timespec ts = get_fs_timestamp(filename);
if (ts == InvalidTime or ts == buffer.fs_timestamp())
return;
- if (reload == Ask)
+ if (reload == Autoreload::Ask)
{
m_ui->info_show(
format("reload '{}' ?", buffer.display_name()),
diff --git a/src/client.hh b/src/client.hh
index f16bd09b..7a0c8571 100644
--- a/src/client.hh
+++ b/src/client.hh
@@ -7,6 +7,7 @@
#include "safe_ptr.hh"
#include "utils.hh"
#include "option_manager.hh"
+#include "enum.hh"
namespace Kakoune
{
@@ -84,6 +85,24 @@ private:
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
diff --git a/src/enum.hh b/src/enum.hh
new file mode 100644
index 00000000..af532391
--- /dev/null
+++ b/src/enum.hh
@@ -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
diff --git a/src/flags.hh b/src/flags.hh
index 2b68751b..6b72ba05 100644
--- a/src/flags.hh
+++ b/src/flags.hh
@@ -12,8 +12,11 @@ struct WithBitOps : std::false_type {};
template<typename Flags>
using UnderlyingType = typename std::underlying_type<Flags>::type;
-template<typename Flags>
-using EnableIfWithBitOps = typename std::enable_if<WithBitOps<Flags>::value>::type;
+template<typename Flags, typename T = void>
+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>>
constexpr Flags operator|(Flags lhs, Flags rhs)
diff --git a/src/input_handler.hh b/src/input_handler.hh
index 49767eb4..036633dc 100644
--- a/src/input_handler.hh
+++ b/src/input_handler.hh
@@ -103,6 +103,26 @@ private:
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);
template<typename Cmd>
diff --git a/src/main.cc b/src/main.cc
index 5dc3d854..83d9519b 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -224,7 +224,7 @@ void register_options()
}), OptionFlags::None);
reg.declare_option("autoreload",
"autoreload buffer when a filesystem modification is detected",
- Ask);
+ Autoreload::Ask);
reg.declare_option("ui_options",
"colon separated list of <key>=<value> options that are "
"passed to and interpreted by the user interface\n"
diff --git a/src/option_types.hh b/src/option_types.hh
index 2dda3d7e..f95c61f0 100644
--- a/src/option_types.hh
+++ b/src/option_types.hh
@@ -8,6 +8,7 @@
#include "array_view.hh"
#include "id_map.hh"
#include "flags.hh"
+#include "enum.hh"
#include <tuple>
#include <vector>
@@ -192,101 +193,6 @@ inline String option_to_string(const LineAndColumn<EffectiveType, LineType, Colu
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
{
None = 0,
@@ -297,20 +203,13 @@ enum class DebugFlags
template<>
struct WithBitOps<DebugFlags> : std::true_type {};
-template<> struct EnumInfo<DebugFlags>
+constexpr Array<EnumDesc<DebugFlags>, 2> enum_desc(DebugFlags)
{
- static ArrayView<const DebugFlags> values()
- {
- static constexpr DebugFlags values[] = { DebugFlags::Hooks, DebugFlags::Shell };
- return { values };
- }
-
- static ArrayView<const StringView> names()
- {
- static constexpr StringView names[] = { "hooks", "shell" };
- return { names };
- }
-};
+ return { {
+ { DebugFlags::Hooks, "hooks" },
+ { DebugFlags::Shell, "shell" }
+ } };
+}
}