From 82c01c5dd382e2cd1bca0c027e598b66321705ce Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Tue, 28 Aug 2018 17:34:18 +1000 Subject: [PATCH] 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. --- src/highlighters.cc | 26 +++++++++++++------------- 1 file 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(cp)) + last_boundary = pos; break; + } pos.column += width; pos.byte = (int)(it - content.begin()); + if (!is_word(cp)) + last_boundary = pos; } } if (m_word_wrap and pos.byte < content.length()) // find a word boundary before current position - { - utf8::iterator it{&content[pos.byte], content}; - while (it != content.begin() and is_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; };