From af66a95ef882447ca7bdc2149a8dfde50035301e Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Mon, 12 Jun 2023 14:38:31 +1000 Subject: [PATCH] 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. --- src/display_buffer.cc | 12 ++++++++---- src/display_buffer.hh | 4 ++-- src/highlighters.cc | 38 ++++++++++++++++++++------------------ src/window.cc | 6 ++++-- 4 files changed, 34 insertions(+), 26 deletions(-) diff --git a/src/display_buffer.cc b/src/display_buffer.cc index 92837c6a..26c58754 100644 --- a/src/display_buffer.cc +++ b/src/display_buffer.cc @@ -264,18 +264,22 @@ bool DisplayLine::trim_from(ColumnCount first_col, ColumnCount front, ColumnCoun } auto front_it = it; - Face last_face{}; + Optional 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) diff --git a/src/display_buffer.hh b/src/display_buffer.hh index e3b4983e..23948263 100644 --- a/src/display_buffer.hh +++ b/src/display_buffer.hh @@ -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); } diff --git a/src/highlighters.cc b/src/highlighters.cc index 15654517..7933d1be 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -530,7 +530,7 @@ std::unique_ptr 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 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 insert_idx; + Vector> 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(); } } }; diff --git a/src/window.cc b/src/window.cc index 9aa3ea73..7926183f 100644 --- a/src/window.cc +++ b/src/window.cc @@ -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});