From 4bb62d63e69dcb96f8e92a70be9c619a5b25594b Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Tue, 10 Jun 2014 21:35:03 +0100 Subject: [PATCH] Add HierachicalHighlighter class HierachicalHighlighter contains a map of names to HighlighterGroup and can wrap any highlighter that wants to access user settable sub groups. --- src/highlighter_group.cc | 32 ++++++++++++++++++++++++++------ src/highlighter_group.hh | 30 +++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/src/highlighter_group.cc b/src/highlighter_group.cc index c86e51cc..5f65cbdd 100644 --- a/src/highlighter_group.cc +++ b/src/highlighter_group.cc @@ -28,13 +28,20 @@ HighlighterGroup& HighlighterGroup::get_group(StringView path, Codepoint path_se auto it = m_highlighters.find(id); if (it == m_highlighters.end()) throw group_not_found("no such id: "_str + id); - HighlighterGroup* group = it->second.template target(); - if (not group) - throw group_not_found("not a group: "_str + id); - if (sep_it != path.end()) - return group->get_group(StringView(sep_it+1, path.end()), path_separator); - else + if (auto* group = it->second.target()) + { + if (sep_it != path.end()) + return group->get_group({sep_it+1, path.end()}, path_separator); return *group; + } + else if (auto* hier_group = it->second.target()) + { + if (sep_it == path.end()) + throw group_not_found("not a leaf group: "_str + id); + return hier_group->get_group({sep_it+1, path.end()}, path_separator); + } + else + throw group_not_found("not a group: "_str + id); } CandidateList HighlighterGroup::complete_id(StringView prefix, ByteCount cursor_pos) const @@ -50,4 +57,17 @@ CandidateList HighlighterGroup::complete_group_id(StringView prefix, ByteCount c }); } +HighlighterGroup& HierachicalHighlighter::get_group(StringView path, Codepoint path_separator) +{ + auto sep_it = std::find(path.begin(), path.end(), path_separator); + StringView id(path.begin(), sep_it); + auto it = m_groups.find(id); + if (it == m_groups.end()) + throw group_not_found("no such id: "_str + id); + if (sep_it != path.end()) + return it->second.get_group(StringView(sep_it+1, path.end()), path_separator); + else + return it->second; +} + } diff --git a/src/highlighter_group.hh b/src/highlighter_group.hh index 8445e445..14419b49 100644 --- a/src/highlighter_group.hh +++ b/src/highlighter_group.hh @@ -17,7 +17,9 @@ struct group_not_found : public runtime_error class HighlighterGroup { public: - void operator()(const Context& context, HighlightFlags flags, DisplayBuffer& display_buffer); + void operator()(const Context& context, + HighlightFlags flags, + DisplayBuffer& display_buffer); void append(HighlighterAndId&& hl); void remove(StringView id); @@ -31,6 +33,32 @@ private: id_map m_highlighters; }; +class HierachicalHighlighter +{ +public: + using GroupMap = id_map; + using Callback = std::function; + + HierachicalHighlighter(Callback callback, GroupMap groups) + : m_callback(std::move(callback)), m_groups(std::move(groups)) {} + + void operator()(const Context& context, + HighlightFlags flags, + DisplayBuffer& display_buffer) + { + m_callback(m_groups, context, flags, display_buffer); + } + + HighlighterGroup& get_group(StringView path, Codepoint path_separator = 0); + +protected: + Callback m_callback; + GroupMap m_groups; +}; + struct DefinedHighlighters : public HighlighterGroup, public Singleton {