summaryrefslogtreecommitdiff
path: root/src/string.hh
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2016-09-22 20:36:26 +0100
committerMaxime Coste <frrrwww@gmail.com>2016-10-01 13:45:00 +0100
commit35559b65ddf107fea2a4dda92fcbd664986976d9 (patch)
tree58840b2523abb01459afb09ad2480df07b9ddd2d /src/string.hh
parent6e17ecfb6eadc157cc5229f3c36f2962cfe1fcdf (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.hh33
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
{