diff --git a/src/commands.cc b/src/commands.cc index 9366466a..e4116bf0 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -987,7 +987,19 @@ const CommandDesc add_highlighter_cmd = { HighlighterRegistry& registry = HighlighterRegistry::instance(); auto it = registry.find(params[1]); if (it != registry.end()) - return format("{}:\n{}", params[1], indent(it->value.docstring)); + { + auto docstring = it->value.description->docstring; + auto desc_params = generate_switches_doc(it->value.description->params.switches); + + if (desc_params.empty()) + return format("{}:\n{}", params[1], indent(docstring)); + else + { + auto desc_indent = Vector{docstring, "Switches:", indent(desc_params)} + | transform([](auto& s) { return indent(s); }); + return format("{}:\n{}", params[1], join(desc_indent, "\n")); + } + } } return ""; }, diff --git a/src/highlighter.hh b/src/highlighter.hh index a9029433..0f91ac1c 100644 --- a/src/highlighter.hh +++ b/src/highlighter.hh @@ -10,6 +10,7 @@ #include "array_view.hh" #include "string.hh" #include "utils.hh" +#include "parameters_parser.hh" #include @@ -86,13 +87,19 @@ private: using HighlighterParameters = ConstArrayView; using HighlighterFactory = std::unique_ptr (*)(HighlighterParameters params, Highlighter* parent); -struct HighlighterFactoryAndDocstring +struct HighlighterDesc { - HighlighterFactory factory; - String docstring; + const char* docstring; + ParameterDesc params; }; -struct HighlighterRegistry : HashMap, +struct HighlighterFactoryAndDescription +{ + HighlighterFactory factory; + const HighlighterDesc* description; +}; + +struct HighlighterRegistry : HashMap, Singleton {}; diff --git a/src/highlighters.cc b/src/highlighters.cc index 448427ec..80797afa 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -221,6 +221,10 @@ auto apply_face = [](const Face& face) }; }; +const HighlighterDesc fill_desc = { + "Fill the whole highlighted range with the given face", + {} +}; static std::unique_ptr create_fill_highlighter(HighlighterParameters params, Highlighter*) { if (params.size() != 1) @@ -253,6 +257,11 @@ private: using FacesSpec = Vector, MemoryDomain::Highlight>; +const HighlighterDesc regex_desc = { + "Parameters: : :...\n" + "Highlights the matches for captures from the regex with the given faces", + {} +}; class RegexHighlighter : public Highlighter { public: @@ -479,6 +488,11 @@ private: RegexHighlighter m_highlighter; }; +const HighlighterDesc dynamic_regex_desc = { + "Parameters: : :...\n" + "Evaluate expression at every redraw to gather a regex", + {} +}; std::unique_ptr create_dynamic_regex_highlighter(HighlighterParameters params, Highlighter*) { if (params.size() < 2) @@ -544,6 +558,11 @@ std::unique_ptr create_dynamic_regex_highlighter(HighlighterParamet return make_hl(get_regex, get_face); } +const HighlighterDesc line_desc = { + "Parameters: \n" + "Highlight the line given by evaluating with ", + {} +}; std::unique_ptr create_line_highlighter(HighlighterParameters params, Highlighter*) { if (params.size() != 2) @@ -591,6 +610,11 @@ std::unique_ptr create_line_highlighter(HighlighterParameters param return make_highlighter(std::move(func)); } +const HighlighterDesc column_desc = { + "Parameters: \n" + "Highlight the column given by evaluating with ", + {} +}; std::unique_ptr create_column_highlighter(HighlighterParameters params, Highlighter*) { if (params.size() != 2) @@ -651,6 +675,17 @@ std::unique_ptr create_column_highlighter(HighlighterParameters par return make_highlighter(std::move(func)); } +const HighlighterDesc wrap_desc = { + "Parameters: [-word] [-indent] [-width ] [-marker ]\n" + "Wrap lines to window width", + { { + { "word", { false, "wrap at word boundaries instead of codepoint boundaries" } }, + { "indent", { false, "preserve line indentation of the wrapped line" } }, + { "width", { true, "wrap at the given column instead of the window's width" } }, + { "marker", { true, "insert the given text at the beginning of the wrapped line" } }, }, + ParameterDesc::Flags::None, 0, 0 + } +}; struct WrapHighlighter : Highlighter { WrapHighlighter(ColumnCount max_width, bool word_wrap, bool preserve_indent, String marker) @@ -915,14 +950,7 @@ struct WrapHighlighter : Highlighter static std::unique_ptr create(HighlighterParameters params, Highlighter*) { - static const ParameterDesc param_desc{ - { { "word", { false, "" } }, - { "indent", { false, "" } }, - { "width", { true, "" } }, - { "marker", { true, "" } } }, - ParameterDesc::Flags::None, 0, 0 - }; - ParametersParser parser(params, param_desc); + ParametersParser parser(params, wrap_desc.params); ColumnCount max_width = parser.get_switch("width").map(str_to_int) .value_or(std::numeric_limits::max()); @@ -998,6 +1026,18 @@ struct TabulationHighlighter : Highlighter } }; +const HighlighterDesc show_whitespace_desc = { + "Parameters: [-tab ] [-tabpad ] [-lf ] [-spc ] [-nbsp ]\n" + "Display whitespaces using symbols", + { { + { "tab", { true, "replace tabulations with the given character" } }, + { "tabpad", { true, "append as many of the given character as is necessary to honor `tabstop`" } }, + { "spc", { true, "replace spaces with the given character" } }, + { "lf", { true, "replace line feeds with the given character" } }, + { "nbsp", { true, "replace non-breakable spaces with the given character" } } }, + ParameterDesc::Flags::None, 0, 0 + } +}; struct ShowWhitespacesHighlighter : Highlighter { ShowWhitespacesHighlighter(String tab, String tabpad, String spc, String lf, String nbsp) @@ -1007,15 +1047,7 @@ struct ShowWhitespacesHighlighter : Highlighter static std::unique_ptr create(HighlighterParameters params, Highlighter*) { - static const ParameterDesc param_desc{ - { { "tab", { true, "" } }, - { "tabpad", { true, "" } }, - { "spc", { true, "" } }, - { "lf", { true, "" } }, - { "nbsp", { true, "" } } }, - ParameterDesc::Flags::None, 0, 0 - }; - ParametersParser parser(params, param_desc); + ParametersParser parser(params, show_whitespace_desc.params); auto get_param = [&](StringView param, StringView fallback) { StringView value = parser.get_switch(param).value_or(fallback); @@ -1080,6 +1112,18 @@ private: const String m_tab, m_tabpad, m_spc, m_lf, m_nbsp; }; +const HighlighterDesc line_numbers_desc = { + "Parameters: [-relative] [-hlcursor] [-separators ] [-min-digits ]\n" + "Display line numbers", + { { + { "relative", { false, "show line numbers relative to the main cursor line" } }, + { "separator", { true, "string to separate the line numbers column from the rest of the buffer (default '|')" } }, + { "cursor-separator", { true, "identical to -separator but applies only to the line of the cursor (default is the same value passed to -separator)" } }, + { "min-digits", { true, "use at least the given number of columns to display line numbers (default 2)" } }, + { "hlcursor", { false, "highlight the cursor line with a separate face" } } }, + ParameterDesc::Flags::None, 0, 0 + } +}; struct LineNumbersHighlighter : Highlighter { LineNumbersHighlighter(bool relative, bool hl_cursor_line, String separator, String cursor_separator, int min_digits) @@ -1092,15 +1136,7 @@ struct LineNumbersHighlighter : Highlighter static std::unique_ptr create(HighlighterParameters params, Highlighter*) { - static const ParameterDesc param_desc{ - { { "relative", { false, "" } }, - { "separator", { true, "" } }, - { "cursor-separator", { true, "" } }, - { "min-digits", { true, "" } }, - { "hlcursor", { false, "" } } }, - ParameterDesc::Flags::None, 0, 0 - }; - ParametersParser parser(params, param_desc); + ParametersParser parser(params, line_numbers_desc.params); StringView separator = parser.get_switch("separator").value_or("│"); StringView cursor_separator = parser.get_switch("cursor-separator").value_or(separator); @@ -1192,6 +1228,10 @@ private: constexpr StringView LineNumbersHighlighter::ms_id; +const HighlighterDesc show_matching_desc = { + "Apply the MatchingChar face to the char matching the one under the cursor", + {} +}; void show_matching_char(HighlightContext context, DisplayBuffer& display_buffer, BufferRange) { const Face face = context.context.faces()["MatchingChar"]; @@ -1364,6 +1404,11 @@ void option_list_postprocess(Vector& opt) { return std::get<0>(lhs) < std::get<0>(rhs); }); } +const HighlighterDesc flag_lines_desc = { + "Parameters: