diff --git a/src/commands.cc b/src/commands.cc index 722b25b3..1c1ce310 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -37,6 +37,18 @@ namespace Kakoune { +template<> +struct option_type_name> +{ + static StringView name() { return "line-flags"; } +}; + +template<> +struct option_type_name> +{ + static StringView name() { return "range-faces"; } +}; + namespace { diff --git a/src/coord.hh b/src/coord.hh index 252496d1..2a55695a 100644 --- a/src/coord.hh +++ b/src/coord.hh @@ -103,6 +103,8 @@ struct CharCoord : LineAndColumn [[gnu::always_inline]] constexpr CharCoord(LineCount line = 0, CharCount column = 0) : LineAndColumn(line, column) {} + + static constexpr const char* option_type_name = "coord"; }; struct ByteCoordAndTarget : ByteCoord diff --git a/src/insert_completer.hh b/src/insert_completer.hh index 572e3be1..8868337b 100644 --- a/src/insert_completer.hh +++ b/src/insert_completer.hh @@ -37,9 +37,19 @@ using InsertCompleterDescList = Vector struct option_type_name +{ + static constexpr StringView name() { return "completer"; } +}; + using CompletionCandidate = std::tuple; using CompletionList = PrefixedList; +template<> struct option_type_name +{ + static constexpr StringView name() { return "completions"; } +}; + struct InsertCompletion { struct Candidate diff --git a/src/main.cc b/src/main.cc index a9d369be..004630d4 100644 --- a/src/main.cc +++ b/src/main.cc @@ -213,8 +213,8 @@ void register_options() reg.declare_option( "scrolloff", "number of lines and columns to keep visible main cursor when scrolling", {0,0}); - reg.declare_option("eolformat", "end of line format: crlf or lf", EolFormat::Lf); - reg.declare_option("BOM", "insert a byte order mark when writing buffer (none or utf8)", + reg.declare_option("eolformat", "end of line format", EolFormat::Lf); + reg.declare_option("BOM", "byte order mark to use when writing buffer", ByteOrderMark::None); reg.declare_option("incsearch", "incrementaly apply search/select/split regex", diff --git a/src/option_manager.hh b/src/option_manager.hh index 9fb57c8d..94340d10 100644 --- a/src/option_manager.hh +++ b/src/option_manager.hh @@ -9,6 +9,7 @@ #include "vector.hh" #include +#include namespace Kakoune { @@ -223,7 +224,7 @@ public: return **it; throw runtime_error(format("option '{}' already declared with different type or flags", name)); } - m_descs.emplace_back(new OptionDesc{name.str(), docstring.str(), flags}); + m_descs.emplace_back(new OptionDesc{name.str(), format("({}): {}", option_type_name::name(), docstring), flags}); opts.emplace_back(new TypedCheckedOption{m_global_manager, *m_descs.back(), value}); return *opts.back(); } diff --git a/src/option_types.hh b/src/option_types.hh index ad35bd92..21f2acda 100644 --- a/src/option_types.hh +++ b/src/option_types.hh @@ -16,9 +16,25 @@ namespace Kakoune { -inline String option_to_string(StringView opt) { return opt.str(); } -inline void option_from_string(StringView str, String& opt) { opt = str.str(); } -inline bool option_add(String& opt, StringView val) { opt += val; return not val.empty(); } +template struct option_type_name; +template using void_t = void; + +template +struct option_type_name> +{ + static decltype(T::option_type_name) name() { return T::option_type_name; } +}; + +template +struct option_type_name::value>::type> +{ + static String name() + { + constexpr StringView type = WithBitOps::value ? "flags" : "enum"; + auto name = enum_desc(Enum{}); + return type + "(" + join(name | transform([](const EnumDesc& d) { return d.name; }), '|') + ")"; + } +}; inline String option_to_string(int opt) { return to_string(opt); } inline void option_from_string(StringView str, int& opt) { opt = str_to_int(str); } @@ -28,6 +44,7 @@ inline bool option_add(int& opt, StringView str) opt += val; return val != 0; } +template<> struct option_type_name { static StringView name() { return "int"; } }; inline String option_to_string(size_t opt) { return to_string(opt); } inline void option_from_string(StringView str, size_t& opt) { opt = str_to_int(str); } @@ -42,6 +59,7 @@ inline void option_from_string(StringView str, bool& opt) else throw runtime_error("boolean values are either true, yes, false or no"); } +template<> struct option_type_name { static StringView name() { return "bool"; } }; constexpr char list_separator = ':'; @@ -82,6 +100,12 @@ bool option_add(Vector& opt, StringView str) return not vec.empty(); } +template +struct option_type_name> +{ + static String name() { return option_type_name::name() + StringView{"-list"}; } +}; + template String option_to_string(const IdMap& opt) { @@ -114,6 +138,12 @@ void option_from_string(StringView str, IdMap& opt) } } +template +struct option_type_name> +{ + static String name() { return format("str-to-{}-map", option_type_name::name()); } +}; + constexpr char tuple_separator = '|'; template diff --git a/src/regex.hh b/src/regex.hh index f2457f4d..ab1c3f34 100644 --- a/src/regex.hh +++ b/src/regex.hh @@ -31,6 +31,8 @@ struct Regex : RegexBase const String& str() const { return m_str; } + static constexpr StringView option_type_name = "regex"; + private: String m_str; }; diff --git a/src/string.hh b/src/string.hh index d7e0e56c..74fbb51a 100644 --- a/src/string.hh +++ b/src/string.hh @@ -128,6 +128,7 @@ public: void resize(ByteCount size, char c); static const String ms_empty; + static constexpr const char* option_type_name = "str"; union Data { @@ -305,6 +306,10 @@ inline String operator"" _str(const char* str, size_t) int str_to_int(StringView str); // throws on error Optional str_to_int_ifp(StringView str); +inline String option_to_string(StringView opt) { return opt.str(); } +inline void option_from_string(StringView str, String& opt) { opt = str.str(); } +inline bool option_add(String& opt, StringView val) { opt += val; return not val.empty(); } + template struct InplaceString {