diff options
| author | Maxime Coste <frrrwww@gmail.com> | 2016-09-22 20:36:26 +0100 |
|---|---|---|
| committer | Maxime Coste <frrrwww@gmail.com> | 2016-10-01 13:45:00 +0100 |
| commit | 35559b65ddf107fea2a4dda92fcbd664986976d9 (patch) | |
| tree | 58840b2523abb01459afb09ad2480df07b9ddd2d /src/string.hh | |
| parent | 6e17ecfb6eadc157cc5229f3c36f2962cfe1fcdf (diff) | |
Support codepoints of variable width
Add a ColumnCount type and use it in place of CharCount whenever
more appropriate, take column size of codepoints into account for
vertical movements and docstring wrapping.
Fixes #811
Diffstat (limited to 'src/string.hh')
| -rw-r--r-- | src/string.hh | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/src/string.hh b/src/string.hh index 3fa08a83..2f3fc787 100644 --- a/src/string.hh +++ b/src/string.hh @@ -65,18 +65,26 @@ public: { return utf8::codepoint(utf8::advance(begin(), end(), pos), end()); } CharCount char_length() const { return utf8::distance(begin(), end()); } + ColumnCount column_length() const { return utf8::column_distance(begin(), end()); } [[gnu::always_inline]] bool empty() const { return type().length() == 0_byte; } ByteCount byte_count_to(CharCount count) const - { return utf8::advance(begin(), end(), (int)count) - begin(); } + { return utf8::advance(begin(), end(), count) - begin(); } + + ByteCount byte_count_to(ColumnCount count) const + { return utf8::advance(begin(), end(), count) - begin(); } CharCount char_count_to(ByteCount count) const { return utf8::distance(begin(), begin() + (int)count); } + ColumnCount column_count_to(ByteCount count) const + { return utf8::column_distance(begin(), begin() + (int)count); } + StringView substr(ByteCount from, ByteCount length = INT_MAX) const; StringView substr(CharCount from, CharCount length = INT_MAX) const; + StringView substr(ColumnCount from, ColumnCount length = INT_MAX) const; private: [[gnu::always_inline]] @@ -103,6 +111,14 @@ public: while (count-- > 0) utf8::dump(std::back_inserter(*this), cp); } + explicit String(Codepoint cp, ColumnCount count) + { + kak_assert(count % get_width(cp) == 0); + int cp_count = (int)count / get_width(cp); + reserve(utf8::codepoint_size(cp) * cp_count); + while (cp_count-- > 0) + utf8::dump(std::back_inserter(*this), cp); + } String(const char* begin, const char* end) : m_data(begin, end-begin) {} [[gnu::always_inline]] @@ -251,7 +267,16 @@ inline StringView StringOps<Type, CharType>::substr(CharCount from, CharCount le { if (length < 0) length = INT_MAX; - auto beg = utf8::advance(begin(), end(), (int)from); + auto beg = utf8::advance(begin(), end(), from); + return StringView{ beg, utf8::advance(beg, end(), length) }; +} + +template<typename Type, typename CharType> +inline StringView StringOps<Type, CharType>::substr(ColumnCount from, ColumnCount length) const +{ + if (length < 0) + length = INT_MAX; + auto beg = utf8::advance(begin(), end(), from); return StringView{ beg, utf8::advance(beg, end(), length) }; } @@ -358,9 +383,9 @@ inline bool prefix_match(StringView str, StringView prefix) bool subsequence_match(StringView str, StringView subseq); -String expand_tabs(StringView line, CharCount tabstop, CharCount col = 0); +String expand_tabs(StringView line, ColumnCount tabstop, ColumnCount col = 0); -Vector<StringView> wrap_lines(StringView text, CharCount max_width); +Vector<StringView> wrap_lines(StringView text, ColumnCount max_width); namespace detail { |
