Refactor range highlighting into a struct

This commit is contained in:
Maxime Coste 2017-05-08 12:05:45 +01:00
parent 6a97455b3b
commit f9a609e479

View File

@ -1278,63 +1278,72 @@ private:
BufferCoord& get_first(RangeAndFace& r) { return std::get<0>(r).begin; } BufferCoord& get_first(RangeAndFace& r) { return std::get<0>(r).begin; }
BufferCoord& get_last(RangeAndFace& r) { return std::get<0>(r).end; } BufferCoord& get_last(RangeAndFace& r) { return std::get<0>(r).end; }
HighlighterAndId create_ranges_highlighter(HighlighterParameters params) struct RangesHighlighter : Highlighter
{ {
RangesHighlighter(String option_name)
: Highlighter{HighlightPass::Colorize}
, m_option_name{std::move(option_name)} {}
static HighlighterAndId create(HighlighterParameters params)
{
if (params.size() != 1) if (params.size() != 1)
throw runtime_error("wrong parameter count"); throw runtime_error("wrong parameter count");
const String& option_name = params[0]; const String& option_name = params[0];
// throw if wrong option type // throw if wrong option type
GlobalScope::instance().options()[option_name].get<TimestampedList<RangeAndFace>>(); GlobalScope::instance().options()[option_name].get<TimestampedList<RangeAndFace>>();
auto func = [=](const Context& context, HighlightPass, DisplayBuffer& display_buffer, BufferRange) return {"hlranges_" + params[0], make_unique<RangesHighlighter>(option_name)};
{ }
auto& range_and_faces = context.options()[option_name].get_mutable<TimestampedList<RangeAndFace>>();
auto& ranges = range_and_faces.list;
private:
void do_highlight(const Context& context, HighlightPass, DisplayBuffer& display_buffer, BufferRange) override
{
auto& buffer = context.buffer(); auto& buffer = context.buffer();
if (range_and_faces.prefix != buffer.timestamp()) auto& range_and_faces = context.options()[m_option_name].get_mutable<TimestampedList<RangeAndFace>>();
{ update_ranges_ifn(buffer, range_and_faces);
auto changes = buffer.changes_since(range_and_faces.prefix);
auto change_it = changes.begin();
while (change_it != changes.end())
{
auto forward_end = forward_sorted_until(change_it, changes.end());
auto backward_end = backward_sorted_until(change_it, changes.end());
if (forward_end >= backward_end) for (auto& range : range_and_faces.list)
{
update_forward({ change_it, forward_end }, ranges);
change_it = forward_end;
}
else
{
update_backward({ change_it, backward_end }, ranges);
change_it = backward_end;
}
}
range_and_faces.prefix = buffer.timestamp();
}
for (auto& range : ranges)
{ {
try try
{ {
auto& r = std::get<0>(range); auto& r = std::get<0>(range);
if (not buffer.is_valid(r.begin) or not buffer.is_valid(r.end)) if (buffer.is_valid(r.begin) and buffer.is_valid(r.end))
continue;
highlight_range(display_buffer, r.begin, r.end, true, highlight_range(display_buffer, r.begin, r.end, true,
apply_face(get_face(std::get<1>(range)))); apply_face(get_face(std::get<1>(range))));
} }
catch (runtime_error&) catch (runtime_error&)
{} {}
} }
}; }
return {"hlranges_" + params[0], make_highlighter(func) }; void update_ranges_ifn(const Buffer& buffer, TimestampedList<RangeAndFace>& range_and_faces)
} {
if (range_and_faces.prefix == buffer.timestamp())
return;
auto changes = buffer.changes_since(range_and_faces.prefix);
for (auto change_it = changes.begin(); change_it != changes.end(); )
{
auto forward_end = forward_sorted_until(change_it, changes.end());
auto backward_end = backward_sorted_until(change_it, changes.end());
if (forward_end >= backward_end)
{
update_forward({ change_it, forward_end }, range_and_faces.list);
change_it = forward_end;
}
else
{
update_backward({ change_it, backward_end }, range_and_faces.list);
change_it = backward_end;
}
}
range_and_faces.prefix = buffer.timestamp();
}
const String m_option_name;
};
HighlighterAndId create_highlighter_group(HighlighterParameters params) HighlighterAndId create_highlighter_group(HighlighterParameters params)
{ {
@ -1842,7 +1851,7 @@ void register_highlighters()
"A line-flag is written: <line>|<fg color>|<text>, the list is : separated" } }); "A line-flag is written: <line>|<fg color>|<text>, the list is : separated" } });
registry.insert({ registry.insert({
"ranges", "ranges",
{ create_ranges_highlighter, { RangesHighlighter::create,
"Parameters: <option name>\n" "Parameters: <option name>\n"
"Use the range-faces option given as parameter to highlight buffer\n" } }); "Use the range-faces option given as parameter to highlight buffer\n" } });
registry.insert({ registry.insert({