2014-06-10 20:58:02 +02:00
|
|
|
#include "highlighter_group.hh"
|
|
|
|
|
2017-08-29 10:23:03 +02:00
|
|
|
#include "ranges.hh"
|
2017-10-09 16:12:42 +02:00
|
|
|
#include "string_utils.hh"
|
2014-12-23 14:34:21 +01:00
|
|
|
|
2014-06-10 20:58:02 +02:00
|
|
|
namespace Kakoune
|
|
|
|
{
|
|
|
|
|
2017-11-25 05:53:33 +01:00
|
|
|
void HighlighterGroup::do_highlight(HighlightContext context, DisplayBuffer& display_buffer, BufferRange range)
|
2014-06-10 20:58:02 +02:00
|
|
|
{
|
|
|
|
for (auto& hl : m_highlighters)
|
2017-11-25 05:53:33 +01:00
|
|
|
hl.value->highlight(context, display_buffer, range);
|
2017-04-27 20:27:28 +02:00
|
|
|
}
|
|
|
|
|
2017-11-25 05:53:33 +01:00
|
|
|
void HighlighterGroup::do_compute_display_setup(HighlightContext context, DisplaySetup& setup)
|
2017-04-27 20:27:28 +02:00
|
|
|
{
|
|
|
|
for (auto& hl : m_highlighters)
|
2017-11-25 05:53:33 +01:00
|
|
|
hl.value->compute_display_setup(context, setup);
|
|
|
|
}
|
|
|
|
|
|
|
|
void HighlighterGroup::fill_unique_ids(Vector<StringView>& unique_ids) const
|
|
|
|
{
|
|
|
|
for (auto& hl : m_highlighters)
|
|
|
|
hl.value->fill_unique_ids(unique_ids);
|
2014-06-10 20:58:02 +02:00
|
|
|
}
|
|
|
|
|
2014-10-22 01:20:09 +02:00
|
|
|
void HighlighterGroup::add_child(HighlighterAndId&& hl)
|
2014-06-10 20:58:02 +02:00
|
|
|
{
|
2017-05-03 20:41:37 +02:00
|
|
|
if ((hl.second->passes() & passes()) != hl.second->passes())
|
2018-02-22 21:28:01 +01:00
|
|
|
throw runtime_error{"Cannot add that highlighter to this group, passes don't match"};
|
2017-05-03 20:41:37 +02:00
|
|
|
|
2016-02-13 13:59:27 +01:00
|
|
|
hl.first = replace(hl.first, "/", "<slash>");
|
|
|
|
|
2014-06-10 20:58:02 +02:00
|
|
|
if (m_highlighters.contains(hl.first))
|
2015-06-01 22:15:59 +02:00
|
|
|
throw runtime_error(format("duplicate id: '{}'", hl.first));
|
2014-06-10 20:58:02 +02:00
|
|
|
|
2017-03-07 02:12:37 +01:00
|
|
|
m_highlighters.insert({std::move(hl.first), std::move(hl.second)});
|
2014-06-10 20:58:02 +02:00
|
|
|
}
|
|
|
|
|
2014-10-22 01:20:09 +02:00
|
|
|
void HighlighterGroup::remove_child(StringView id)
|
2014-06-10 20:58:02 +02:00
|
|
|
{
|
2014-10-22 01:20:09 +02:00
|
|
|
m_highlighters.remove(id);
|
2014-06-10 20:58:02 +02:00
|
|
|
}
|
|
|
|
|
2014-10-22 01:20:09 +02:00
|
|
|
Highlighter& HighlighterGroup::get_child(StringView path)
|
2014-06-12 22:52:23 +02:00
|
|
|
{
|
2014-10-22 01:20:09 +02:00
|
|
|
auto sep_it = find(path, '/');
|
2014-06-12 22:52:23 +02:00
|
|
|
StringView id(path.begin(), sep_it);
|
|
|
|
auto it = m_highlighters.find(id);
|
|
|
|
if (it == m_highlighters.end())
|
2015-06-01 22:15:59 +02:00
|
|
|
throw child_not_found(format("no such id: '{}'", id));
|
2014-06-15 17:04:38 +02:00
|
|
|
if (sep_it == path.end())
|
2015-09-16 20:57:57 +02:00
|
|
|
return *it->value;
|
2014-06-10 22:35:03 +02:00
|
|
|
else
|
2015-09-16 20:57:57 +02:00
|
|
|
return it->value->get_child({sep_it+1, path.end()});
|
2014-06-10 22:35:03 +02:00
|
|
|
}
|
|
|
|
|
2014-10-22 01:20:09 +02:00
|
|
|
Completions HighlighterGroup::complete_child(StringView path, ByteCount cursor_pos, bool group) const
|
2014-06-12 22:52:23 +02:00
|
|
|
{
|
2014-10-22 01:20:09 +02:00
|
|
|
auto sep_it = find(path, '/');
|
2014-06-12 22:52:23 +02:00
|
|
|
if (sep_it != path.end())
|
2014-06-15 17:04:38 +02:00
|
|
|
{
|
2014-10-22 01:20:09 +02:00
|
|
|
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);
|
2014-06-15 17:04:38 +02:00
|
|
|
}
|
|
|
|
|
2015-11-11 20:14:35 +01:00
|
|
|
auto candidates = complete(
|
|
|
|
path, cursor_pos,
|
2017-11-02 11:05:18 +01:00
|
|
|
m_highlighters | filter([=](auto& hl) { return not group or hl.value->has_children(); })
|
|
|
|
| transform([](auto& hl) { return hl.value->has_children() ? hl.key + "/" : hl.key; })
|
|
|
|
| gather<Vector<String>>());
|
2015-11-11 20:14:35 +01:00
|
|
|
|
|
|
|
return { 0, 0, std::move(candidates) };
|
2014-06-15 17:04:38 +02:00
|
|
|
}
|
|
|
|
|
2017-11-25 05:53:33 +01:00
|
|
|
void Highlighters::highlight(HighlightContext context, DisplayBuffer& display_buffer, BufferRange range)
|
2017-10-28 05:00:51 +02:00
|
|
|
{
|
2017-11-25 05:53:33 +01:00
|
|
|
Vector<StringView> disabled_ids(context.disabled_ids.begin(), context.disabled_ids.end());
|
|
|
|
m_group.fill_unique_ids(disabled_ids);
|
|
|
|
|
2017-10-28 05:00:51 +02:00
|
|
|
if (m_parent)
|
2017-11-25 05:53:33 +01:00
|
|
|
m_parent->highlight({context.context, context.pass, disabled_ids}, display_buffer, range);
|
|
|
|
m_group.highlight(context, display_buffer, range);
|
2017-10-28 05:00:51 +02:00
|
|
|
}
|
|
|
|
|
2017-11-25 05:53:33 +01:00
|
|
|
void Highlighters::compute_display_setup(HighlightContext context, DisplaySetup& setup)
|
2017-10-28 05:00:51 +02:00
|
|
|
{
|
2017-11-25 05:53:33 +01:00
|
|
|
Vector<StringView> disabled_ids(context.disabled_ids.begin(), context.disabled_ids.end());
|
|
|
|
m_group.fill_unique_ids(disabled_ids);
|
|
|
|
|
2017-10-28 05:00:51 +02:00
|
|
|
if (m_parent)
|
2017-11-25 05:53:33 +01:00
|
|
|
m_parent->compute_display_setup({context.context, context.pass, disabled_ids}, setup);
|
|
|
|
m_group.compute_display_setup(context, setup);
|
2017-10-28 05:00:51 +02:00
|
|
|
}
|
|
|
|
|
2014-06-10 20:58:02 +02:00
|
|
|
}
|