summaryrefslogtreecommitdiff
path: root/src/string_utils.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/string_utils.cc')
-rw-r--r--src/string_utils.cc51
1 files changed, 27 insertions, 24 deletions
diff --git a/src/string_utils.cc b/src/string_utils.cc
index 43e7ef18..3ce98940 100644
--- a/src/string_utils.cc
+++ b/src/string_utils.cc
@@ -235,58 +235,61 @@ String expand_tabs(StringView line, ColumnCount tabstop, ColumnCount col)
return res;
}
-Vector<StringView> wrap_lines(StringView text, ColumnCount max_width)
+WrapView::Iterator::Iterator(StringView text, ColumnCount max_width)
+ : m_remaining{text}, m_max_width{max_width}
{
if (max_width <= 0)
throw runtime_error("Invalid max width");
+ ++*this;
+}
+WrapView::Iterator& WrapView::Iterator::operator++()
+{
using Utf8It = utf8::iterator<const char*>;
- Utf8It it{text.begin(), text};
- Utf8It end{text.end(), text};
- Utf8It line_begin = it;
+ Utf8It it{m_remaining.begin(), m_remaining};
Utf8It last_word_end = it;
- Vector<StringView> lines;
- while (it != end)
+ while (it != m_remaining.end())
{
const CharCategories cat = categorize(*it, {'_'});
if (cat == CharCategories::EndOfLine)
{
- lines.emplace_back(line_begin.base(), it.base());
- line_begin = it = it+1;
- continue;
+ m_current = StringView{m_remaining.begin(), it.base()};
+ m_remaining = StringView{(it+1).base(), m_remaining.end()};
+ return *this;
}
Utf8It word_end = it+1;
- while (word_end != end and categorize(*word_end, {'_'}) == cat)
+ while (word_end != m_remaining.end() and categorize(*word_end, {'_'}) == cat)
++word_end;
- while (word_end > line_begin and
- utf8::column_distance(line_begin.base(), word_end.base()) >= max_width)
+ if (word_end > m_remaining.begin() and
+ utf8::column_distance(m_remaining.begin(), word_end.base()) >= m_max_width)
{
- auto line_end = last_word_end <= line_begin ?
- Utf8It{utf8::advance(line_begin.base(), text.end(), max_width), text}
+ auto line_end = last_word_end <= m_remaining.begin() ?
+ Utf8It{utf8::advance(m_remaining.begin(), m_remaining.end(), m_max_width), m_remaining}
: last_word_end;
- lines.emplace_back(line_begin.base(), line_end.base());
+ m_current = StringView{m_remaining.begin(), line_end.base()};
- while (line_end != end and is_horizontal_blank(*line_end))
+ while (line_end != m_remaining.end() and is_horizontal_blank(*line_end))
++line_end;
- if (line_end != end and *line_end == '\n')
+ if (line_end != m_remaining.end() and *line_end == '\n')
++line_end;
- it = line_begin = line_end;
+ m_remaining = StringView{line_end.base(), m_remaining.end()};
+ return *this;
}
if (cat == CharCategories::Word or cat == CharCategories::Punctuation)
last_word_end = word_end;
- if (word_end > line_begin)
+ if (word_end > m_remaining.begin())
it = word_end;
}
- if (line_begin != end)
- lines.emplace_back(line_begin.base(), text.end());
- return lines;
+ m_current = m_remaining;
+ m_remaining = StringView{};
+ return *this;
}
template<typename AppendFunc>
@@ -378,7 +381,7 @@ UnitTest test_string{[]()
{
kak_assert(String("youpi ") + "matin" == "youpi matin");
- Vector<StringView> wrapped = wrap_lines("wrap this paragraph\n respecting whitespaces and much_too_long_words", 16);
+ auto wrapped = "wrap this paragraph\n respecting whitespaces and much_too_long_words" | wrap_at(16) | gather<Vector>();
kak_assert(wrapped.size() == 6);
kak_assert(wrapped[0] == "wrap this");
kak_assert(wrapped[1] == "paragraph");
@@ -387,7 +390,7 @@ UnitTest test_string{[]()
kak_assert(wrapped[4] == "much_too_long_wo");
kak_assert(wrapped[5] == "rds");
- Vector<StringView> wrapped2 = wrap_lines("error: unknown type", 7);
+ auto wrapped2 = "error: unknown type" | wrap_at(7) | gather<Vector>();
kak_assert(wrapped2.size() == 3);
kak_assert(wrapped2[0] == "error:");
kak_assert(wrapped2[1] == "unknown");