Highlighters: Introduce unique highlighter support

Some highlighters, such as wrap or line numbers, are not intended
to be used multiple times on the same display. Add support for unique
ids that are used by highlighters to disable themselves if another
unique highlighter with the same id is supposed to override them.

The usual highlighter "precedence" takes, place, that it, that most
nested highlighter will the the one to run (window in priority to
buffer in priority to global).
This commit is contained in:
Maxime Coste 2017-11-25 12:53:33 +08:00
parent 66250a06eb
commit 318e77b25e
5 changed files with 154 additions and 107 deletions

View File

@ -51,21 +51,30 @@ struct DisplaySetup
bool full_lines; bool full_lines;
}; };
using HighlighterIdList = ConstArrayView<StringView>;
struct HighlightContext
{
const Context& context;
HighlightPass pass;
HighlighterIdList disabled_ids;
};
struct Highlighter struct Highlighter
{ {
Highlighter(HighlightPass passes) : m_passes{passes} {} Highlighter(HighlightPass passes) : m_passes{passes} {}
virtual ~Highlighter() = default; virtual ~Highlighter() = default;
void highlight(const Context& context, HighlightPass pass, DisplayBuffer& display_buffer, BufferRange range) void highlight(HighlightContext context, DisplayBuffer& display_buffer, BufferRange range)
{ {
if (pass & m_passes) if (context.pass & m_passes)
do_highlight(context, pass, display_buffer, range); do_highlight(context, display_buffer, range);
} }
void compute_display_setup(const Context& context, HighlightPass pass, DisplaySetup& setup) void compute_display_setup(HighlightContext context, DisplaySetup& setup)
{ {
if (pass & m_passes) if (context.pass & m_passes)
do_compute_display_setup(context, pass, setup); do_compute_display_setup(context, setup);
} }
virtual bool has_children() const { return false; } virtual bool has_children() const { return false; }
@ -74,11 +83,13 @@ struct Highlighter
virtual void remove_child(StringView id) { throw runtime_error("this highlighter do not hold children"); } virtual void remove_child(StringView id) { throw runtime_error("this highlighter do not hold children"); }
virtual Completions complete_child(StringView path, ByteCount cursor_pos, bool group) const { throw runtime_error("this highlighter do not hold children"); } virtual Completions complete_child(StringView path, ByteCount cursor_pos, bool group) const { throw runtime_error("this highlighter do not hold children"); }
virtual void fill_unique_ids(Vector<StringView>& unique_ids) const {}
HighlightPass passes() const { return m_passes; } HighlightPass passes() const { return m_passes; }
private: private:
virtual void do_highlight(const Context& context, HighlightPass pass, DisplayBuffer& display_buffer, BufferRange range) = 0; virtual void do_highlight(HighlightContext context, DisplayBuffer& display_buffer, BufferRange range) = 0;
virtual void do_compute_display_setup(const Context& context, HighlightPass pass, DisplaySetup& setup) {} virtual void do_compute_display_setup(HighlightContext context, DisplaySetup& setup) {}
const HighlightPass m_passes; const HighlightPass m_passes;
}; };

View File

@ -6,17 +6,22 @@
namespace Kakoune namespace Kakoune
{ {
void HighlighterGroup::do_highlight(const Context& context, HighlightPass pass, void HighlighterGroup::do_highlight(HighlightContext context, DisplayBuffer& display_buffer, BufferRange range)
DisplayBuffer& display_buffer, BufferRange range)
{ {
for (auto& hl : m_highlighters) for (auto& hl : m_highlighters)
hl.value->highlight(context, pass, display_buffer, range); hl.value->highlight(context, display_buffer, range);
} }
void HighlighterGroup::do_compute_display_setup(const Context& context, HighlightPass pass, DisplaySetup& setup) void HighlighterGroup::do_compute_display_setup(HighlightContext context, DisplaySetup& setup)
{ {
for (auto& hl : m_highlighters) for (auto& hl : m_highlighters)
hl.value->compute_display_setup(context, pass, setup); 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);
} }
void HighlighterGroup::add_child(HighlighterAndId&& hl) void HighlighterGroup::add_child(HighlighterAndId&& hl)
@ -69,19 +74,24 @@ Completions HighlighterGroup::complete_child(StringView path, ByteCount cursor_p
return { 0, 0, std::move(candidates) }; return { 0, 0, std::move(candidates) };
} }
void Highlighters::highlight(const Context& context, HighlightPass pass, void Highlighters::highlight(HighlightContext context, DisplayBuffer& display_buffer, BufferRange range)
DisplayBuffer& display_buffer, BufferRange range)
{ {
Vector<StringView> disabled_ids(context.disabled_ids.begin(), context.disabled_ids.end());
m_group.fill_unique_ids(disabled_ids);
if (m_parent) if (m_parent)
m_parent->highlight(context, pass, display_buffer, range); m_parent->highlight({context.context, context.pass, disabled_ids}, display_buffer, range);
m_group.highlight(context, pass, display_buffer, range); m_group.highlight(context, display_buffer, range);
} }
void Highlighters::compute_display_setup(const Context& context, HighlightPass pass, DisplaySetup& setup) void Highlighters::compute_display_setup(HighlightContext context, DisplaySetup& setup)
{ {
Vector<StringView> disabled_ids(context.disabled_ids.begin(), context.disabled_ids.end());
m_group.fill_unique_ids(disabled_ids);
if (m_parent) if (m_parent)
m_parent->compute_display_setup(context, pass, setup); m_parent->compute_display_setup({context.context, context.pass, disabled_ids}, setup);
m_group.compute_display_setup(context, pass, setup); m_group.compute_display_setup(context, setup);
} }
} }

View File

@ -28,9 +28,11 @@ public:
Completions complete_child(StringView path, ByteCount cursor_pos, bool group) const override; Completions complete_child(StringView path, ByteCount cursor_pos, bool group) const override;
void fill_unique_ids(Vector<StringView>& unique_ids) const override;
protected: protected:
void do_highlight(const Context& context, HighlightPass pass, DisplayBuffer& display_buffer, BufferRange range) override; void do_highlight(HighlightContext context, DisplayBuffer& display_buffer, BufferRange range) override;
void do_compute_display_setup(const Context& context, HighlightPass pass, DisplaySetup& setup) override; void do_compute_display_setup(HighlightContext context, DisplaySetup& setup) override;
using HighlighterMap = HashMap<String, std::unique_ptr<Highlighter>, MemoryDomain::Highlight>; using HighlighterMap = HashMap<String, std::unique_ptr<Highlighter>, MemoryDomain::Highlight>;
HighlighterMap m_highlighters; HighlighterMap m_highlighters;
@ -44,8 +46,8 @@ public:
HighlighterGroup& group() { return m_group; } HighlighterGroup& group() { return m_group; }
const HighlighterGroup& group() const { return m_group; } const HighlighterGroup& group() const { return m_group; }
void highlight(const Context& context, HighlightPass pass, DisplayBuffer& display_buffer, BufferRange range); void highlight(HighlightContext context, DisplayBuffer& display_buffer, BufferRange range);
void compute_display_setup(const Context& context, HighlightPass pass, DisplaySetup& setup); void compute_display_setup(HighlightContext context, DisplaySetup& setup);
private: private:
friend class Scope; friend class Scope;

View File

@ -34,9 +34,9 @@ std::unique_ptr<Highlighter> make_highlighter(Func func, HighlightPass pass = Hi
: Highlighter{pass}, m_func{std::move(func)} {} : Highlighter{pass}, m_func{std::move(func)} {}
private: private:
void do_highlight(const Context& context, HighlightPass pass, DisplayBuffer& display_buffer, BufferRange range) override void do_highlight(HighlightContext context, DisplayBuffer& display_buffer, BufferRange range) override
{ {
m_func(context, pass, display_buffer, range); m_func(context, display_buffer, range);
} }
Func m_func; Func m_func;
}; };
@ -124,9 +124,8 @@ void replace_range(DisplayBuffer& display_buffer,
} }
} }
void apply_highlighter(const Context& context, void apply_highlighter(HighlightContext context,
DisplayBuffer& display_buffer, DisplayBuffer& display_buffer,
HighlightPass pass,
BufferCoord begin, BufferCoord end, BufferCoord begin, BufferCoord end,
Highlighter& highlighter) Highlighter& highlighter)
{ {
@ -201,7 +200,7 @@ void apply_highlighter(const Context& context,
return; return;
region_display.compute_range(); region_display.compute_range();
highlighter.highlight(context, pass, region_display, {begin, end}); highlighter.highlight(context, region_display, {begin, end});
for (size_t i = 0; i < region_lines.size(); ++i) for (size_t i = 0; i < region_lines.size(); ++i)
{ {
@ -228,8 +227,7 @@ static HighlighterAndId create_fill_highlighter(HighlighterParameters params)
const String& facespec = params[0]; const String& facespec = params[0];
get_face(facespec); // validate param get_face(facespec); // validate param
auto func = [=](const Context& context, HighlightPass pass, auto func = [=](HighlightContext, DisplayBuffer& display_buffer, BufferRange range)
DisplayBuffer& display_buffer, BufferRange range)
{ {
highlight_range(display_buffer, range.begin, range.end, true, highlight_range(display_buffer, range.begin, range.end, true,
apply_face(get_face(facespec))); apply_face(get_face(facespec)));
@ -266,7 +264,7 @@ public:
ensure_first_face_is_capture_0(); ensure_first_face_is_capture_0();
} }
void do_highlight(const Context& context, HighlightPass, DisplayBuffer& display_buffer, BufferRange range) override void do_highlight(HighlightContext context, DisplayBuffer& display_buffer, BufferRange range) override
{ {
auto overlaps = [](const BufferRange& lhs, const BufferRange& rhs) { auto overlaps = [](const BufferRange& lhs, const BufferRange& rhs) {
return lhs.begin < rhs.begin ? lhs.end > rhs.begin return lhs.begin < rhs.begin ? lhs.end > rhs.begin
@ -283,7 +281,7 @@ public:
faces[f] = get_face(m_faces[f].second); faces[f] = get_face(m_faces[f].second);
} }
auto& matches = get_matches(context.buffer(), display_buffer.range(), range); auto& matches = get_matches(context.context.buffer(), display_buffer.range(), range);
kak_assert(matches.size() % m_faces.size() == 0); kak_assert(matches.size() % m_faces.size() == 0);
for (size_t m = 0; m < matches.size(); ++m) for (size_t m = 0; m < matches.size(); ++m)
{ {
@ -459,10 +457,10 @@ public:
m_face_getter(std::move(face_getter)), m_face_getter(std::move(face_getter)),
m_highlighter(Regex{}, FacesSpec{}) {} m_highlighter(Regex{}, FacesSpec{}) {}
void do_highlight(const Context& context, HighlightPass pass, DisplayBuffer& display_buffer, BufferRange range) override void do_highlight(HighlightContext context, DisplayBuffer& display_buffer, BufferRange range) override
{ {
Regex regex = m_regex_getter(context); Regex regex = m_regex_getter(context.context);
FacesSpec face = m_face_getter(context); FacesSpec face = m_face_getter(context.context);
if (regex != m_last_regex or face != m_last_face) if (regex != m_last_regex or face != m_last_face)
{ {
m_last_regex = std::move(regex); m_last_regex = std::move(regex);
@ -471,7 +469,7 @@ public:
m_highlighter.reset(m_last_regex, m_last_face); m_highlighter.reset(m_last_regex, m_last_face);
} }
if (not m_last_regex.empty() and not m_last_face.empty()) if (not m_last_regex.empty() and not m_last_face.empty())
m_highlighter.highlight(context, pass, display_buffer, range); m_highlighter.highlight(context, display_buffer, range);
} }
private: private:
@ -546,12 +544,12 @@ HighlighterAndId create_line_highlighter(HighlighterParameters params)
get_face(facespec); // validate facespec get_face(facespec); // validate facespec
auto func = [=](const Context& context, HighlightPass, DisplayBuffer& display_buffer, BufferRange) auto func = [=](HighlightContext context, DisplayBuffer& display_buffer, BufferRange)
{ {
LineCount line = -1; LineCount line = -1;
try try
{ {
line = str_to_int_ifp(expand(line_expr, context)).value_or(0) - 1; line = str_to_int_ifp(expand(line_expr, context.context)).value_or(0) - 1;
} }
catch (runtime_error& err) catch (runtime_error& err)
{ {
@ -579,7 +577,7 @@ HighlighterAndId create_line_highlighter(HighlighterParameters params)
kak_assert(atom.begin().line == line); kak_assert(atom.begin().line == line);
apply_face(face)(atom); apply_face(face)(atom);
} }
const ColumnCount remaining = context.window().dimensions().column - column; const ColumnCount remaining = context.context.window().dimensions().column - column;
if (remaining > 0) if (remaining > 0)
it->push_back({ String{' ', remaining}, face }); it->push_back({ String{' ', remaining}, face });
}; };
@ -597,12 +595,12 @@ HighlighterAndId create_column_highlighter(HighlighterParameters params)
get_face(facespec); // validate facespec get_face(facespec); // validate facespec
auto func = [=](const Context& context, HighlightPass, DisplayBuffer& display_buffer, BufferRange) auto func = [=](HighlightContext context, DisplayBuffer& display_buffer, BufferRange)
{ {
ColumnCount column = -1; ColumnCount column = -1;
try try
{ {
column = str_to_int_ifp(expand(col_expr, context)).value_or(0) - 1; column = str_to_int_ifp(expand(col_expr, context.context)).value_or(0) - 1;
} }
catch (runtime_error& err) catch (runtime_error& err)
{ {
@ -614,7 +612,7 @@ HighlighterAndId create_column_highlighter(HighlighterParameters params)
return; return;
auto face = get_face(facespec); auto face = get_face(facespec);
auto win_column = context.window().position().column; auto win_column = context.context.window().position().column;
for (auto& line : display_buffer.lines()) for (auto& line : display_buffer.lines())
{ {
auto target_col = column - win_column; auto target_col = column - win_column;
@ -656,17 +654,21 @@ struct WrapHighlighter : Highlighter
: Highlighter{HighlightPass::Wrap}, m_max_width{max_width}, : Highlighter{HighlightPass::Wrap}, m_max_width{max_width},
m_word_wrap{word_wrap}, m_preserve_indent{preserve_indent} {} m_word_wrap{word_wrap}, m_preserve_indent{preserve_indent} {}
void do_highlight(const Context& context, HighlightPass pass, static constexpr StringView ms_id = "wrap";
DisplayBuffer& display_buffer, BufferRange) override
void do_highlight(HighlightContext context, DisplayBuffer& display_buffer, BufferRange) override
{ {
const ColumnCount wrap_column = std::min(m_max_width, context.window().range().column); if (contains(context.disabled_ids, ms_id))
return;
const ColumnCount wrap_column = std::min(m_max_width, context.context.window().range().column);
if (wrap_column <= 0) if (wrap_column <= 0)
return; return;
const Buffer& buffer = context.buffer(); const Buffer& buffer = context.context.buffer();
const auto& cursor = context.selections().main().cursor(); const auto& cursor = context.context.selections().main().cursor();
const int tabstop = context.options()["tabstop"].get<int>(); const int tabstop = context.context.options()["tabstop"].get<int>();
const LineCount win_height = context.window().dimensions().line; const LineCount win_height = context.context.window().dimensions().line;
for (auto it = display_buffer.lines().begin(); for (auto it = display_buffer.lines().begin();
it != display_buffer.lines().end(); ++it) it != display_buffer.lines().end(); ++it)
{ {
@ -725,15 +727,18 @@ struct WrapHighlighter : Highlighter
} }
} }
void do_compute_display_setup(const Context& context, HighlightPass, DisplaySetup& setup) override void do_compute_display_setup(HighlightContext context, DisplaySetup& setup) override
{ {
if (contains(context.disabled_ids, ms_id))
return;
const ColumnCount wrap_column = std::min(setup.window_range.column, m_max_width); const ColumnCount wrap_column = std::min(setup.window_range.column, m_max_width);
if (wrap_column <= 0) if (wrap_column <= 0)
return; return;
const Buffer& buffer = context.buffer(); const Buffer& buffer = context.context.buffer();
const auto& cursor = context.selections().main().cursor(); const auto& cursor = context.context.selections().main().cursor();
const int tabstop = context.options()["tabstop"].get<int>(); const int tabstop = context.context.options()["tabstop"].get<int>();
auto line_wrap_count = [&](LineCount line, ColumnCount indent) { auto line_wrap_count = [&](LineCount line, ColumnCount indent) {
LineCount count = 0; LineCount count = 0;
@ -750,7 +755,7 @@ struct WrapHighlighter : Highlighter
return count; return count;
}; };
const auto win_height = context.window().dimensions().line; const auto win_height = context.context.window().dimensions().line;
// Disable horizontal scrolling when using a WrapHighlighter // Disable horizontal scrolling when using a WrapHighlighter
setup.window_pos.column = 0; setup.window_pos.column = 0;
@ -811,6 +816,11 @@ struct WrapHighlighter : Highlighter
} }
} }
void fill_unique_ids(Vector<StringView>& unique_ids) const override
{
unique_ids.push_back(ms_id);
}
BufferCoord next_split_coord(const Buffer& buffer, ColumnCount wrap_column, int tabstop, BufferCoord coord) BufferCoord next_split_coord(const Buffer& buffer, ColumnCount wrap_column, int tabstop, BufferCoord coord)
{ {
auto column = get_column(buffer, tabstop, coord); auto column = get_column(buffer, tabstop, coord);
@ -867,16 +877,17 @@ struct WrapHighlighter : Highlighter
const ColumnCount m_max_width; const ColumnCount m_max_width;
}; };
constexpr StringView WrapHighlighter::ms_id;
struct TabulationHighlighter : Highlighter struct TabulationHighlighter : Highlighter
{ {
TabulationHighlighter() : Highlighter{HighlightPass::Move} {} TabulationHighlighter() : Highlighter{HighlightPass::Move} {}
void do_highlight(const Context& context, HighlightPass, void do_highlight(HighlightContext context, DisplayBuffer& display_buffer, BufferRange) override
DisplayBuffer& display_buffer, BufferRange) override
{ {
const ColumnCount tabstop = context.options()["tabstop"].get<int>(); const ColumnCount tabstop = context.context.options()["tabstop"].get<int>();
auto& buffer = context.buffer(); auto& buffer = context.context.buffer();
auto win_column = context.window().position().column; auto win_column = context.context.window().position().column;
for (auto& line : display_buffer.lines()) for (auto& line : display_buffer.lines())
{ {
for (auto atom_it = line.begin(); atom_it != line.end(); ++atom_it) for (auto atom_it = line.begin(); atom_it != line.end(); ++atom_it)
@ -906,15 +917,15 @@ struct TabulationHighlighter : Highlighter
} }
} }
void do_compute_display_setup(const Context& context, HighlightPass, DisplaySetup& setup) override void do_compute_display_setup(HighlightContext context, DisplaySetup& setup) override
{ {
auto& buffer = context.buffer(); auto& buffer = context.context.buffer();
// Ensure that a cursor on a tab character makes the full tab character visible // Ensure that a cursor on a tab character makes the full tab character visible
auto cursor = context.selections().main().cursor(); auto cursor = context.context.selections().main().cursor();
if (buffer.byte_at(cursor) != '\t') if (buffer.byte_at(cursor) != '\t')
return; return;
const ColumnCount tabstop = context.options()["tabstop"].get<int>(); const ColumnCount tabstop = context.context.options()["tabstop"].get<int>();
const ColumnCount column = get_column(buffer, tabstop, cursor); const ColumnCount column = get_column(buffer, tabstop, cursor);
const ColumnCount width = tabstop - (column % tabstop); const ColumnCount width = tabstop - (column % tabstop);
const ColumnCount win_end = setup.window_pos.column + setup.window_range.column; const ColumnCount win_end = setup.window_pos.column + setup.window_range.column;
@ -925,14 +936,14 @@ struct TabulationHighlighter : Highlighter
} }
}; };
void show_whitespaces(const Context& context, HighlightPass, DisplayBuffer& display_buffer, BufferRange, void show_whitespaces(HighlightContext context, DisplayBuffer& display_buffer, BufferRange,
StringView tab, StringView tabpad, StringView tab, StringView tabpad,
StringView spc, StringView lf, StringView nbsp) StringView spc, StringView lf, StringView nbsp)
{ {
const int tabstop = context.options()["tabstop"].get<int>(); const int tabstop = context.context.options()["tabstop"].get<int>();
auto whitespaceface = get_face("Whitespace"); auto whitespaceface = get_face("Whitespace");
auto& buffer = context.buffer(); auto& buffer = context.context.buffer();
auto win_column = context.window().position().column; auto win_column = context.context.window().position().column;
for (auto& line : display_buffer.lines()) for (auto& line : display_buffer.lines())
{ {
for (auto atom_it = line.begin(); atom_it != line.end(); ++atom_it) for (auto atom_it = line.begin(); atom_it != line.end(); ++atom_it)
@ -994,7 +1005,7 @@ HighlighterAndId show_whitespaces_factory(HighlighterParameters params)
}; };
using namespace std::placeholders; using namespace std::placeholders;
auto func = std::bind(show_whitespaces, _1, _2, _3, _4, auto func = std::bind(show_whitespaces, _1, _2, _3,
get_param("tab", ""), get_param("tabpad", " "), get_param("tab", ""), get_param("tabpad", " "),
get_param("spc", "·"), get_param("spc", "·"),
get_param("lf", "¬"), get_param("lf", "¬"),
@ -1029,16 +1040,21 @@ struct LineNumbersHighlighter : Highlighter
} }
private: private:
void do_highlight(const Context& context, HighlightPass, DisplayBuffer& display_buffer, BufferRange) override static constexpr StringView ms_id = "line_numbers";
void do_highlight(HighlightContext context, DisplayBuffer& display_buffer, BufferRange) override
{ {
if (contains(context.disabled_ids, ms_id))
return;
const Face face = get_face("LineNumbers"); const Face face = get_face("LineNumbers");
const Face face_wrapped = get_face("LineNumbersWrapped"); const Face face_wrapped = get_face("LineNumbersWrapped");
const Face face_absolute = get_face("LineNumberCursor"); const Face face_absolute = get_face("LineNumberCursor");
int digit_count = compute_digit_count(context); int digit_count = compute_digit_count(context.context);
char format[16]; char format[16];
format_to(format, "%{}d", digit_count); format_to(format, "%{}d", digit_count);
const int main_line = (int)context.selections().main().cursor().line + 1; const int main_line = (int)context.context.selections().main().cursor().line + 1;
int last_line = -1; int last_line = -1;
for (auto& line : display_buffer.lines()) for (auto& line : display_buffer.lines())
{ {
@ -1057,12 +1073,20 @@ private:
} }
} }
void do_compute_display_setup(const Context& context, HighlightPass, DisplaySetup& setup) override void do_compute_display_setup(HighlightContext context, DisplaySetup& setup) override
{ {
ColumnCount width = compute_digit_count(context) + m_separator.column_length(); if (contains(context.disabled_ids, ms_id))
return;
ColumnCount width = compute_digit_count(context.context) + m_separator.column_length();
setup.window_range.column -= width; setup.window_range.column -= width;
} }
void fill_unique_ids(Vector<StringView>& unique_ids) const override
{
unique_ids.push_back(ms_id);
}
int compute_digit_count(const Context& context) int compute_digit_count(const Context& context)
{ {
int digit_count = 0; int digit_count = 0;
@ -1077,15 +1101,17 @@ private:
const String m_separator; const String m_separator;
}; };
constexpr StringView LineNumbersHighlighter::ms_id;
void show_matching_char(const Context& context, HighlightPass, DisplayBuffer& display_buffer, BufferRange)
void show_matching_char(HighlightContext context, DisplayBuffer& display_buffer, BufferRange)
{ {
const Face face = get_face("MatchingChar"); const Face face = get_face("MatchingChar");
using CodepointPair = std::pair<Codepoint, Codepoint>; using CodepointPair = std::pair<Codepoint, Codepoint>;
static const CodepointPair matching_chars[] = { { '(', ')' }, { '{', '}' }, { '[', ']' }, { '<', '>' } }; static const CodepointPair matching_chars[] = { { '(', ')' }, { '{', '}' }, { '[', ']' }, { '<', '>' } };
const auto range = display_buffer.range(); const auto range = display_buffer.range();
const auto& buffer = context.buffer(); const auto& buffer = context.context.buffer();
for (auto& sel : context.selections()) for (auto& sel : context.context.selections())
{ {
auto pos = sel.cursor(); auto pos = sel.cursor();
if (pos < range.begin or pos >= range.end) if (pos < range.begin or pos >= range.end)
@ -1137,15 +1163,15 @@ HighlighterAndId create_matching_char_highlighter(HighlighterParameters params)
return {"show_matching", make_highlighter(show_matching_char)}; return {"show_matching", make_highlighter(show_matching_char)};
} }
void highlight_selections(const Context& context, HighlightPass, DisplayBuffer& display_buffer, BufferRange) void highlight_selections(HighlightContext context, DisplayBuffer& display_buffer, BufferRange)
{ {
const auto& buffer = context.buffer(); const auto& buffer = context.context.buffer();
const Face primary_face = get_face("PrimarySelection"); const Face primary_face = get_face("PrimarySelection");
const Face secondary_face = get_face("SecondarySelection"); const Face secondary_face = get_face("SecondarySelection");
const Face primary_cursor_face = get_face("PrimaryCursor"); const Face primary_cursor_face = get_face("PrimaryCursor");
const Face secondary_cursor_face = get_face("SecondaryCursor"); const Face secondary_cursor_face = get_face("SecondaryCursor");
const auto& selections = context.selections(); const auto& selections = context.context.selections();
for (size_t i = 0; i < selections.size(); ++i) for (size_t i = 0; i < selections.size(); ++i)
{ {
auto& sel = selections[i]; auto& sel = selections[i];
@ -1166,9 +1192,9 @@ void highlight_selections(const Context& context, HighlightPass, DisplayBuffer&
} }
} }
void expand_unprintable(const Context& context, HighlightPass, DisplayBuffer& display_buffer, BufferRange) void expand_unprintable(HighlightContext context, DisplayBuffer& display_buffer, BufferRange)
{ {
auto& buffer = context.buffer(); auto& buffer = context.context.buffer();
auto error = get_face("Error"); auto error = get_face("Error");
for (auto& line : display_buffer.lines()) for (auto& line : display_buffer.lines())
{ {
@ -1265,11 +1291,10 @@ struct FlagLinesHighlighter : Highlighter
} }
private: private:
void do_highlight(const Context& context, HighlightPass, void do_highlight(HighlightContext context, DisplayBuffer& display_buffer, BufferRange) override
DisplayBuffer& display_buffer, BufferRange) override
{ {
auto& line_flags = context.options()[m_option_name].get_mutable<LineAndSpecList>(); auto& line_flags = context.context.options()[m_option_name].get_mutable<LineAndSpecList>();
auto& buffer = context.buffer(); auto& buffer = context.context.buffer();
update_line_specs_ifn(buffer, line_flags); update_line_specs_ifn(buffer, line_flags);
auto def_face = get_face(m_default_face); auto def_face = get_face(m_default_face);
@ -1316,10 +1341,10 @@ private:
} }
} }
void do_compute_display_setup(const Context& context, HighlightPass, DisplaySetup& setup) override void do_compute_display_setup(HighlightContext context, DisplaySetup& setup) override
{ {
auto& line_flags = context.options()[m_option_name].get_mutable<LineAndSpecList>(); auto& line_flags = context.context.options()[m_option_name].get_mutable<LineAndSpecList>();
auto& buffer = context.buffer(); auto& buffer = context.context.buffer();
update_line_specs_ifn(buffer, line_flags); update_line_specs_ifn(buffer, line_flags);
ColumnCount width = 0; ColumnCount width = 0;
@ -1434,10 +1459,10 @@ struct RangesHighlighter : Highlighter
} }
private: private:
void do_highlight(const Context& context, HighlightPass, DisplayBuffer& display_buffer, BufferRange) override void do_highlight(HighlightContext context, DisplayBuffer& display_buffer, BufferRange) override
{ {
auto& buffer = context.buffer(); auto& buffer = context.context.buffer();
auto& range_and_faces = context.options()[m_option_name].get_mutable<RangeAndStringList>(); auto& range_and_faces = context.context.options()[m_option_name].get_mutable<RangeAndStringList>();
update_ranges_ifn(buffer, range_and_faces); update_ranges_ifn(buffer, range_and_faces);
for (auto& range : range_and_faces.list) for (auto& range : range_and_faces.list)
@ -1476,10 +1501,10 @@ struct ReplaceRangesHighlighter : Highlighter
} }
private: private:
void do_highlight(const Context& context, HighlightPass, DisplayBuffer& display_buffer, BufferRange) override void do_highlight(HighlightContext context, DisplayBuffer& display_buffer, BufferRange) override
{ {
auto& buffer = context.buffer(); auto& buffer = context.context.buffer();
auto& range_and_faces = context.options()[m_option_name].get_mutable<RangeAndStringList>(); auto& range_and_faces = context.context.options()[m_option_name].get_mutable<RangeAndStringList>();
update_ranges_ifn(buffer, range_and_faces); update_ranges_ifn(buffer, range_and_faces);
for (auto& range : range_and_faces.list) for (auto& range : range_and_faces.list)
@ -1555,22 +1580,21 @@ struct ReferenceHighlighter : Highlighter
} }
private: private:
void do_highlight(const Context& context, HighlightPass pass, void do_highlight(HighlightContext context, DisplayBuffer& display_buffer, BufferRange range) override
DisplayBuffer& display_buffer, BufferRange range) override
{ {
try try
{ {
DefinedHighlighters::instance().get_child(m_name).highlight(context, pass, display_buffer, range); DefinedHighlighters::instance().get_child(m_name).highlight(context, display_buffer, range);
} }
catch (child_not_found&) catch (child_not_found&)
{} {}
} }
void do_compute_display_setup(const Context& context, HighlightPass pass, DisplaySetup& setup) override void do_compute_display_setup(HighlightContext context, DisplaySetup& setup) override
{ {
try try
{ {
DefinedHighlighters::instance().get_child(m_name).compute_display_setup(context, pass, setup); DefinedHighlighters::instance().get_child(m_name).compute_display_setup(context, setup);
} }
catch (child_not_found&) catch (child_not_found&)
{} {}
@ -1770,10 +1794,10 @@ public:
m_groups.insert({m_default_group, HighlighterGroup{HighlightPass::Colorize}}); m_groups.insert({m_default_group, HighlighterGroup{HighlightPass::Colorize}});
} }
void do_highlight(const Context& context, HighlightPass pass, DisplayBuffer& display_buffer, BufferRange range) override void do_highlight(HighlightContext context, DisplayBuffer& display_buffer, BufferRange range) override
{ {
auto display_range = display_buffer.range(); auto display_range = display_buffer.range();
const auto& buffer = context.buffer(); const auto& buffer = context.context.buffer();
auto& regions = get_regions_for_range(buffer, range); auto& regions = get_regions_for_range(buffer, range);
auto begin = std::lower_bound(regions.begin(), regions.end(), display_range.begin, auto begin = std::lower_bound(regions.begin(), regions.end(), display_range.begin,
@ -1795,20 +1819,20 @@ public:
for (; begin != end; ++begin) for (; begin != end; ++begin)
{ {
if (apply_default and last_begin < begin->begin) if (apply_default and last_begin < begin->begin)
apply_highlighter(context, display_buffer, pass, apply_highlighter(context, display_buffer,
correct(last_begin), correct(begin->begin), correct(last_begin), correct(begin->begin),
default_group_it->value); default_group_it->value);
auto it = m_groups.find(begin->group); auto it = m_groups.find(begin->group);
if (it == m_groups.end()) if (it == m_groups.end())
continue; continue;
apply_highlighter(context, display_buffer, pass, apply_highlighter(context, display_buffer,
correct(begin->begin), correct(begin->end), correct(begin->begin), correct(begin->end),
it->value); it->value);
last_begin = begin->end; last_begin = begin->end;
} }
if (apply_default and last_begin < display_range.end) if (apply_default and last_begin < display_range.end)
apply_highlighter(context, display_buffer, pass, apply_highlighter(context, display_buffer,
correct(last_begin), range.end, correct(last_begin), range.end,
default_group_it->value); default_group_it->value);
} }

View File

@ -143,7 +143,7 @@ const DisplayBuffer& Window::update_display_buffer(const Context& context)
m_display_buffer.compute_range(); m_display_buffer.compute_range();
BufferRange range{{0,0}, buffer().end_coord()}; BufferRange range{{0,0}, buffer().end_coord()};
for (auto pass : { HighlightPass::Wrap, HighlightPass::Move, HighlightPass::Colorize }) for (auto pass : { HighlightPass::Wrap, HighlightPass::Move, HighlightPass::Colorize })
m_builtin_highlighters.highlight(context, pass, m_display_buffer, range); m_builtin_highlighters.highlight({context, pass, {}}, m_display_buffer, range);
m_display_buffer.optimize(); m_display_buffer.optimize();
@ -200,7 +200,7 @@ DisplaySetup Window::compute_display_setup(const Context& context)
false false
}; };
for (auto pass : { HighlightPass::Move, HighlightPass::Wrap }) for (auto pass : { HighlightPass::Move, HighlightPass::Wrap })
m_builtin_highlighters.compute_display_setup(context, pass, setup); m_builtin_highlighters.compute_display_setup({context, pass, {}}, setup);
// now ensure the cursor column is visible // now ensure the cursor column is visible
{ {