diff options
| author | Tim Allen <screwtape@froup.com> | 2018-08-28 17:34:18 +1000 |
|---|---|---|
| committer | Tim Allen <screwtape@froup.com> | 2018-08-28 17:43:16 +1000 |
| commit | 82c01c5dd382e2cd1bca0c027e598b66321705ce (patch) | |
| tree | 4ff941a1ff766829edb0ec8cc96aa09ead99deee /src | |
| parent | 373858f9bfb50fe2c5670beffbfe63654cc12314 (diff) | |
Speed up wrapping at word boundaries.
Previously, when wrapping lines at word boundaries, we would iterate forwards
for "wrap-width" characters, then iterate backwards until we found a word-break,
which was horribly slow.
Now we record the last word-boundary we saw as we iterate forwards, getting a
result in one pass.
Fixes #2339.
Diffstat (limited to 'src')
| -rw-r--r-- | src/highlighters.cc | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/src/highlighters.cc b/src/highlighters.cc index 173a7594..e75baed8 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -822,6 +822,8 @@ struct WrapHighlighter : Highlighter StringView content = buffer[line]; SplitPos pos = current; + SplitPos last_boundary = {0, 0}; + while (pos.byte < content.length() and pos.column < target_column) { if (content[pos.byte] == '\t') @@ -831,32 +833,30 @@ struct WrapHighlighter : Highlighter break; pos.column = next_column; ++pos.byte; + last_boundary = pos; } else { const char* it = &content[pos.byte]; - const ColumnCount width = codepoint_width(utf8::read_codepoint(it, content.end())); + const Codepoint cp = utf8::read_codepoint(it, content.end()); + const ColumnCount width = codepoint_width(cp); if (pos.column + width > target_column and pos.byte != current.byte) // the target column was in the char + { + if (!is_word<WORD>(cp)) + last_boundary = pos; break; + } pos.column += width; pos.byte = (int)(it - content.begin()); + if (!is_word<WORD>(cp)) + last_boundary = pos; } } if (m_word_wrap and pos.byte < content.length()) // find a word boundary before current position - { - utf8::iterator<const char*> it{&content[pos.byte], content}; - while (it != content.begin() and is_word<WORD>(*it)) - --it; + if (last_boundary.byte > 0) + pos = last_boundary; - if (it != content.begin() and it != &content[pos.byte] and - (it+1) > &content[current.byte]) - { - const ByteCount word_split = (it+1).base() - content.begin(); - pos.column -= content.substr(word_split, pos.byte - word_split).column_length(); - pos.byte = word_split; - } - } return pos; }; |
