diff --git a/README.asciidoc b/README.asciidoc index ede9854c..eea1e6ba 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -726,15 +726,16 @@ Options are typed, their type can be * `int`: an integer number * `bool`: a boolean value, `yes/true` or `no/false` - * `yesnoask`: similar to a boolean, but the additional - value `ask` is supported. * `str`: a string, some freeform text * `coord`: a line,column pair (separated by comma) * `regex`: as a string but the `set` commands will complain if the entered text is not a valid regex. * `{int,str}-list`: a list, elements are separated by a colon (:) if an element needs to contain a colon, it can be escaped with a - backslash. + backslash. + * `enum(value1|value2|...)`: an enum, taking on of the given values + * `flags(value1|value2|...)`: a set of flags, taking a combination + of the given values joined by `|`. Options value can be changed using the `set` commands: @@ -781,7 +782,8 @@ Some options are built in Kakoune, and can be used to control it's behaviour: candidates exist, enable completion with common prefix. * `incsearch` _bool_: execute search as it is typed * `aligntab` _bool_: use tabs for alignement command - * `autoinfo` _bool_: display automatic information box for certain commands. + * `autoinfo` _flags(command|onkey|normal)_: display automatic information + box in the enabled contexts. * `autoshowcompl` _bool_: automatically display possible completions when editing a prompt. * `ignored_files` _regex_: filenames matching this regex wont be considered @@ -804,7 +806,7 @@ Some options are built in Kakoune, and can be used to control it's behaviour: element of the list should follow the format: _.[+]@_ to define where the completion apply in the buffer, and the other strings are the candidates. - * `autoreload` _yesnoask_: auto reload the buffers when an external + * `autoreload` _enum(yes|no|ask)_: auto reload the buffers when an external modification is detected. * `modelinefmt` _string_: A format string used to generate the mode line, that string is first expanded as a command line would be (expanding `%...{...}` diff --git a/src/commands.cc b/src/commands.cc index 9594223c..16114bff 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -1221,7 +1221,7 @@ void context_wrap(const ParametersParser& parser, Context& context, Func func) { // Disable these options to avoid costly code paths (and potential screen // redraws) That are useful only in interactive contexts. - DisableOption disable_autoinfo(context, "autoinfo"); + DisableOption disable_autoinfo(context, "autoinfo"); DisableOption disable_autoshowcompl(context, "autoshowcompl"); DisableOption disable_incsearch(context, "incsearch"); diff --git a/src/input_handler.cc b/src/input_handler.cc index 80178984..353ced8a 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -251,7 +251,8 @@ public: { return lhs.key < rhs; }); if (it != keymap.end() and it->key == key) { - if (context().options()["autoinfo"].get() >= 2 and context().has_ui()) + auto autoinfo = context().options()["autoinfo"].get(); + if (autoinfo & AutoInfo::Normal and context().has_ui()) context().ui().info_show(key_to_str(key), it->docstring, CharCoord{}, get_face("Information"), InfoStyle::Prompt); @@ -1413,13 +1414,15 @@ DisplayLine InputHandler::mode_line() const return current_mode().mode_line(); } - -bool show_auto_info_ifn(StringView title, StringView info, const Context& context) +bool show_auto_info_ifn(StringView title, StringView info, AutoInfo mask, const Context& context) { - if (context.options()["autoinfo"].get() < 1 or not context.has_ui()) + if ((context.options()["autoinfo"].get() & mask) or + not context.has_ui()) return false; + Face face = get_face("Information"); context.ui().info_show(title, info, CharCoord{}, face, InfoStyle::Prompt); return true; } + } diff --git a/src/input_handler.hh b/src/input_handler.hh index 025f8979..49767eb4 100644 --- a/src/input_handler.hh +++ b/src/input_handler.hh @@ -103,13 +103,13 @@ private: int m_handle_key_level = 0; }; -bool show_auto_info_ifn(StringView title, StringView info, const Context& context); +bool show_auto_info_ifn(StringView title, StringView info, AutoInfo mask, const Context& context); template void on_next_key_with_autoinfo(const Context& context, KeymapMode keymap_mode, Cmd cmd, StringView title, StringView info) { - const bool hide = show_auto_info_ifn(title, info, context); + const bool hide = show_auto_info_ifn(title, info, AutoInfo::OnKey, context); context.input_handler().on_next_key( keymap_mode, [hide,cmd](Key key, Context& context) mutable { if (hide) diff --git a/src/main.cc b/src/main.cc index 42424325..182f0c5f 100644 --- a/src/main.cc +++ b/src/main.cc @@ -201,7 +201,7 @@ void register_options() true); reg.declare_option("autoinfo", "automatically display contextual help", - 1); + AutoInfo::Command | AutoInfo::OnKey); reg.declare_option("autoshowcompl", "automatically display possible completions for prompts", true); diff --git a/src/normal.cc b/src/normal.cc index 9b9f5088..009a2224 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -349,7 +349,8 @@ void command(Context& context, NormalParams params) if (context.has_ui()) { context.ui().info_hide(); - if (event == PromptEvent::Change and context.options()["autoinfo"].get() > 0) + auto autoinfo = context.options()["autoinfo"].get(); + if (event == PromptEvent::Change and autoinfo & AutoInfo::Command) { Face face = get_face("Information"); if (cmdline.length() == 1 and is_horizontal_blank(cmdline[0_byte])) diff --git a/src/option_types.hh b/src/option_types.hh index d2161be2..a504efd7 100644 --- a/src/option_types.hh +++ b/src/option_types.hh @@ -7,6 +7,7 @@ #include "coord.hh" #include "array_view.hh" #include "id_map.hh" +#include "flags.hh" #include #include @@ -222,6 +223,45 @@ inline void option_from_string(StringView str, YesNoAsk& opt) throw runtime_error(format("invalid value '{}', expected yes, no or ask", str)); } +enum class AutoInfo +{ + None = 0, + Command = 1 << 0, + OnKey = 1 << 1, + Normal = 1 << 2 +}; + +template<> +struct WithBitOps : std::true_type {}; + +inline String option_to_string(AutoInfo opt) +{ + String res; + if (opt & AutoInfo::Command) + res = "command"; + if (opt & AutoInfo::OnKey) + res += res.empty() ? "onkey" : "|onkey"; + if (opt & AutoInfo::Normal) + res += res.empty() ? "normal" : "|normal"; + return res; +} + +inline void option_from_string(StringView str, AutoInfo& opt) +{ + opt = AutoInfo::None; + for (auto s : split(str, '|')) + { + if (s == "command") + opt |= AutoInfo::Command; + else if (s == "onkey") + opt |= AutoInfo::OnKey; + else if (s == "normal") + opt |= AutoInfo::Normal; + else + throw runtime_error(format("invalid value '{}'", s)); + } +} + } #endif // option_types_hh_INCLUDED