summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2022-12-15 13:16:07 +1100
committerMaxime Coste <mawww@kakoune.org>2022-12-15 13:17:00 +1100
commit8279a3776f38c875ef58da7823f56fb5ef3407bb (patch)
tree41987ead81d34debe9e1f3d7c7ba21a9b54f39e2
parent36d1713b0973e1aa2ab2de6343f1185a70f62a0d (diff)
Optimize TabulationHighlighter
-rw-r--r--src/highlighters.cc43
1 files changed, 31 insertions, 12 deletions
diff --git a/src/highlighters.cc b/src/highlighters.cc
index 8f7a97f3..32f27e84 100644
--- a/src/highlighters.cc
+++ b/src/highlighters.cc
@@ -976,27 +976,46 @@ struct TabulationHighlighter : Highlighter
const auto& buffer = context.context.buffer();
for (auto& line : display_buffer.lines())
{
+ ColumnCount column = 0;
+ const char* line_data = nullptr;
+ const char* pos = nullptr;
for (auto atom_it = line.begin(); atom_it != line.end(); ++atom_it)
{
if (atom_it->type() != DisplayAtom::Range)
continue;
- auto begin = get_iterator(buffer, atom_it->begin());
- auto end = get_iterator(buffer, atom_it->end());
- for (BufferIterator it = begin; it != end; ++it)
+ auto begin = atom_it->begin();
+ if (auto* atom_line_data = buffer[begin.line].data(); atom_line_data != line_data)
+ {
+ pos = line_data = atom_line_data;
+ column = 0;
+ }
+
+ kak_assert(pos != nullptr and pos <= line_data + (int)begin.column);
+ for (auto end = line_data + (int)atom_it->end().column; pos != end; ++pos)
{
- if (*it == '\t')
+ const char* next_tab = std::find(pos, end, '\t');
+ if (next_tab == end)
{
- if (it != begin)
- atom_it = ++line.split(atom_it, it.coord());
- if (it+1 != end)
- atom_it = line.split(atom_it, (it+1).coord());
-
- const ColumnCount column = get_column(buffer, tabstop, it.coord());
- const ColumnCount count = tabstop - (column % tabstop);
- atom_it->replace(String{' ', count});
+ pos = end;
break;
}
+
+ while (pos != next_tab)
+ column += codepoint_width(utf8::read_codepoint(pos, next_tab));
+ const ColumnCount tabwidth = tabstop - (column % tabstop);
+ column += tabwidth;
+
+ if (pos >= line_data + (int)atom_it->begin().column)
+ {
+ if (pos != line_data + (int)atom_it->begin().column)
+ atom_it = ++line.split(atom_it, {begin.line, ByteCount(pos - line_data)});
+ if (pos + 1 != end)
+ atom_it = line.split(atom_it, {begin.line, ByteCount(pos + 1 - line_data)});
+
+ atom_it->replace(String{' ', tabwidth});
+ ++atom_it;
+ }
}
}
}