diff options
| author | Maxime Coste <frrrwww@gmail.com> | 2014-10-22 00:20:09 +0100 |
|---|---|---|
| committer | Maxime Coste <frrrwww@gmail.com> | 2014-10-22 13:54:03 +0100 |
| commit | b2e90fe21eb2bffd65d66fb40c02195cabbb3fa3 (patch) | |
| tree | 843ddd3c82fdf4e6830efc3ae7d32139b7313a84 /src/highlighter_group.cc | |
| parent | fc4142178f2619a9ba0cac62ce1081590a56ed79 (diff) | |
Refactor highlighters, use an interface with virtual methods
Diffstat (limited to 'src/highlighter_group.cc')
| -rw-r--r-- | src/highlighter_group.cc | 152 |
1 files changed, 21 insertions, 131 deletions
diff --git a/src/highlighter_group.cc b/src/highlighter_group.cc index d9c8131d..4379c4c5 100644 --- a/src/highlighter_group.cc +++ b/src/highlighter_group.cc @@ -3,164 +3,54 @@ namespace Kakoune { -static constexpr Codepoint path_separator = '/'; - - -void HighlighterGroup::operator()(const Context& context, HighlightFlags flags, DisplayBuffer& display_buffer) const +void HighlighterGroup::highlight(const Context& context, HighlightFlags flags, + DisplayBuffer& display_buffer) { for (auto& hl : m_highlighters) - hl.second(context, flags, display_buffer); + hl.second->highlight(context, flags, display_buffer); } -void HighlighterGroup::append(HighlighterAndId&& hl) +void HighlighterGroup::add_child(HighlighterAndId&& hl) { if (m_highlighters.contains(hl.first)) throw runtime_error("duplicate id: " + hl.first); m_highlighters.append(std::move(hl)); } -void HighlighterGroup::remove(StringView id) -{ - m_highlighters.remove(id); -} -HighlighterGroup& HighlighterGroup::get_group(StringView path) +void HighlighterGroup::remove_child(StringView id) { - auto sep_it = find(path, path_separator); - StringView id(path.begin(), sep_it); - auto it = m_highlighters.find(id); - if (it == m_highlighters.end()) - throw group_not_found("no such id: "_str + id); - if (auto* group = it->second.target<HighlighterGroup>()) - { - if (sep_it != path.end()) - return group->get_group({sep_it+1, path.end()}); - return *group; - } - else if (auto* hier_group = it->second.target<HierachicalHighlighter>()) - { - 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()}); - } - else - throw group_not_found("not a group: "_str + id); + m_highlighters.remove(id); } -HighlighterFunc HighlighterGroup::get_highlighter(StringView path) const +Highlighter& HighlighterGroup::get_child(StringView path) { - auto sep_it = find(path, path_separator); + auto sep_it = find(path, '/'); StringView id(path.begin(), sep_it); auto it = m_highlighters.find(id); if (it == m_highlighters.end()) - throw group_not_found("no such id: "_str + id); - if (sep_it == path.end()) - return HighlighterFunc{std::ref(it->second)}; - else if (auto* group = it->second.target<HighlighterGroup>()) - return group->get_highlighter({sep_it+1, path.end()}); - else if (auto* hier_group = it->second.target<HierachicalHighlighter>()) - return hier_group->get_highlighter({sep_it+1, path.end()}); - else - throw group_not_found("not a group: "_str + id); -} - -template<Completions (HighlighterGroup::*hg_complete)(StringView path, ByteCount cursor_pos) const, - Completions (HierachicalHighlighter::*hh_complete)(StringView path, ByteCount cursor_pos) const, - typename Condition> -Completions complete_impl(const id_map<HighlighterFunc>& highlighters, Condition condition, - StringView path, ByteCount cursor_pos) -{ - auto sep_it = find(path, path_separator); - StringView id(path.begin(), sep_it); + throw child_not_found("no such id: "_str + id); if (sep_it == path.end()) - return { 0_byte, path.length(), highlighters.complete_id_if(path, cursor_pos, condition) }; - - auto it = highlighters.find(id); - if (it != highlighters.end()) - { - const ByteCount offset = (int)(sep_it + 1 - path.begin()); - cursor_pos -= offset; - if (auto* group = it->second.target<HighlighterGroup>()) - return offset_pos((group->*hg_complete)({sep_it+1, path.end()}, cursor_pos), offset); - if (auto* hier_group = it->second.target<HierachicalHighlighter>()) - return offset_pos((hier_group->*hh_complete)({sep_it+1, path.end()}, cursor_pos), offset); - } - return {}; -} - -Completions HighlighterGroup::complete_id(StringView path, ByteCount cursor_pos) const -{ - return complete_impl< - &HighlighterGroup::complete_id, - &HierachicalHighlighter::complete_id - >(m_highlighters, [](const HighlighterAndId&) { return true; }, path, cursor_pos); -} - -Completions HighlighterGroup::complete_group_id(StringView path, ByteCount cursor_pos) const -{ - return complete_impl< - &HighlighterGroup::complete_group_id, - &HierachicalHighlighter::complete_group_id - >(m_highlighters, [](const HighlighterAndId& func) { - return func.second.target<HighlighterGroup>() or - func.second.target<HierachicalHighlighter>(); - }, path, cursor_pos); -} - -HighlighterGroup& HierachicalHighlighter::get_group(StringView path) -{ - auto sep_it = find(path, 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())); + return *it->second; else - return it->second; + return it->second->get_child({sep_it+1, path.end()}); } -HighlighterFunc HierachicalHighlighter::get_highlighter(StringView path) const +Completions HighlighterGroup::complete_child(StringView path, ByteCount cursor_pos, bool group) const { - auto sep_it = find(path, 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); + auto sep_it = find(path, '/'); if (sep_it != path.end()) - return it->second.get_highlighter(StringView(sep_it+1, path.end())); - else - return HighlighterFunc(std::ref(it->second)); -} - -template<Completions (HighlighterGroup::*complete)(StringView path, ByteCount cursor_pos) const> -Completions complete_impl(const HierachicalHighlighter::GroupMap& groups, - StringView path, ByteCount cursor_pos) -{ - auto sep_it = find(path, path_separator); - StringView id(path.begin(), sep_it); - auto it = groups.find(id); - if (sep_it == path.end()) - return { 0_byte, id.length(), groups.complete_id(id, cursor_pos) }; - - if (it != groups.end()) { - const ByteCount offset = (int)(sep_it + 1- path.begin()); - return offset_pos( - (it->second.*complete)({sep_it+1, path.end()}, - cursor_pos - offset), offset); + ByteCount offset = sep_it+1 - path.begin(); + Highlighter& hl = const_cast<HighlighterGroup*>(this)->get_child({path.begin(), sep_it}); + return offset_pos(hl.complete_child(path.substr(offset), cursor_pos - offset, group), offset); } - return {}; -} - -Completions HierachicalHighlighter::complete_id(StringView path, ByteCount cursor_pos) const -{ - return complete_impl<&HighlighterGroup::complete_id>(m_groups, path, cursor_pos); -} -Completions HierachicalHighlighter::complete_group_id(StringView path, ByteCount cursor_pos) const -{ - return complete_impl<&HighlighterGroup::complete_group_id>(m_groups, path, cursor_pos); + auto condition = [=](const HighlighterMap::value_type& hl) + { + return not group || hl.second->has_children(); + }; + return { 0, 0, m_highlighters.complete_id_if(path, cursor_pos, condition) }; } } |
