Trim display lines before the colorize pass

Colorizing long lines can be costly, remove all the invisible atoms
earlier. Also optimize ForwardHighlighterApplier further by trimming
empty lines.
This commit is contained in:
Maxime Coste 2023-06-12 14:38:31 +10:00
parent 5a867ebdd1
commit af66a95ef8
4 changed files with 34 additions and 26 deletions

View File

@ -264,18 +264,22 @@ bool DisplayLine::trim_from(ColumnCount first_col, ColumnCount front, ColumnCoun
}
auto front_it = it;
Face last_face{};
Optional<DisplayAtom> padding;
while (front > 0 and it != end())
{
front -= it->trim_begin(front);
kak_assert(it->empty() or front <= 0);
last_face = it->face;
if (front < 0)
padding.emplace(it->has_buffer_range()
? DisplayAtom{it->buffer(), {it->begin(), it->begin()}, String{' ', -front}, it->face}
: DisplayAtom{String{' ', -front}, it->face});
if (it->empty())
++it;
}
it = m_atoms.erase(front_it, it);
if (front < 0)
it = m_atoms.insert(it, DisplayAtom{String{' ', -front}, last_face});
if (padding)
it = m_atoms.insert(it, std::move(*padding));
it = begin();
for (; it != end() and col_count > 0; ++it)

View File

@ -54,8 +54,8 @@ public:
void replace(String text)
{
kak_assert(m_type == Range);
m_type = ReplacedRange;
if (m_type == Range)
m_type = ReplacedRange;
m_text = std::move(text);
}

View File

@ -530,7 +530,7 @@ std::unique_ptr<Highlighter> create_column_highlighter(HighlighterParameters par
if (params.size() != 2)
throw runtime_error("wrong parameter count");
auto func = [col_expr=params[0], facespec=params[1]]
auto func = [col_expr=params[0], facespec=parse_face(params[1])]
(HighlightContext context, DisplayBuffer& display_buffer, BufferRange)
{
ColumnCount column = -1;
@ -551,7 +551,7 @@ std::unique_ptr<Highlighter> create_column_highlighter(HighlighterParameters par
if (column < context.setup.first_column or column >= context.setup.first_column + context.context.window().dimensions().column)
return;
column += context.setup.widget_columns;
column += context.setup.widget_columns - context.setup.first_column;
for (auto& line : display_buffer.lines())
{
auto remaining_col = column;
@ -1801,26 +1801,29 @@ struct ForwardHighlighterApplier
if (first_line != cur_line and first_line != end_line)
cur_atom = first_line->begin();
cur_line = first_line;
if (cur_line == end_line)
if (cur_line == end_line or cur_line->range().begin >= end)
return;
auto& region_lines = region_display.lines();
region_lines.clear();
Vector<size_t> insert_idx;
Vector<std::pair<DisplayLineList::iterator, size_t>> insert_pos;
while (cur_line != end_line and cur_line->range().begin < end)
{
auto& line = *cur_line;
auto first = std::find_if(cur_atom, line.end(), [&](auto&& atom) { return atom.has_buffer_range() and atom.end() > begin; });
if (first->type() != DisplayAtom::ReplacedRange and first->begin() < begin)
if (first->type() == DisplayAtom::Range and first->begin() < begin)
first = ++line.split(first, begin);
auto idx = first - line.begin();
auto last = std::find_if(first, line.end(), [&](auto&& atom) { return atom.has_buffer_range() and atom.end() > end; });
if (last != line.end() and last->type() != DisplayAtom::ReplacedRange and last->begin() < end and last->end() > end)
if (last != line.end() and last->type() == DisplayAtom::Range and last->begin() < end)
last = ++line.split(last, end);
insert_idx.push_back(idx);
region_lines.push_back(line.extract(line.begin() + idx, last));
if (line.begin() + idx != last)
{
insert_pos.emplace_back(cur_line, idx);
region_lines.push_back(line.extract(line.begin() + idx, last));
}
if (idx != line.atoms().size())
break;
@ -1828,21 +1831,20 @@ struct ForwardHighlighterApplier
cur_atom = cur_line->begin();
}
if (region_lines.empty())
return;
region_display.compute_range();
highlighter.highlight(context, region_display, {begin, end});
for (size_t i = 0; i < region_lines.size(); ++i, ++first_line)
for (size_t i = 0; i < insert_pos.size(); ++i)
{
auto it = first_line->insert(
first_line->begin() + insert_idx[i],
std::move_iterator(region_lines[i].begin()),
std::move_iterator(region_lines[i].end()));
auto& [line_it, idx] = insert_pos[i];
auto& atoms = region_lines[i].atoms();
auto it = line_it->insert(
line_it->begin() + idx,
std::move_iterator(atoms.begin()),
std::move_iterator(atoms.end()));
if (first_line == cur_line)
cur_atom = it + region_lines[i].atoms().size();
if (line_it == cur_line)
cur_atom = it + atoms.size();
}
}
};

View File

@ -155,12 +155,14 @@ const DisplayBuffer& Window::update_display_buffer(const Context& context)
m_display_buffer.compute_range();
const BufferRange range{{0,0}, buffer().end_coord()};
for (auto pass : { HighlightPass::Wrap, HighlightPass::Move, HighlightPass::Colorize })
m_builtin_highlighters.highlight({context, setup, pass, {}}, m_display_buffer, range);
m_builtin_highlighters.highlight({context, setup, HighlightPass::Wrap, {}}, m_display_buffer, range);
m_builtin_highlighters.highlight({context, setup, HighlightPass::Move, {}}, m_display_buffer, range);
for (auto& line : m_display_buffer.lines())
line.trim_from(setup.widget_columns, setup.first_column, m_dimensions.column);
m_builtin_highlighters.highlight({context, setup, HighlightPass::Colorize, {}}, m_display_buffer, range);
m_display_buffer.optimize();
set_position({setup.first_line, setup.first_column});