summaryrefslogtreecommitdiff
path: root/src/buffer.cc
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2013-06-03 18:56:48 +0200
committerMaxime Coste <frrrwww@gmail.com>2013-06-03 18:56:48 +0200
commit02b33c7d8fd0167a4cbca78be26ed32e042c7370 (patch)
tree98c64de15bf03ae53aa9a9dba4815fba8cc8490c /src/buffer.cc
parentb198f6a5fb1a656e0dd4b31bf00c928b2c0b1fb2 (diff)
Buffer: add methods for char access instead of byte access
Diffstat (limited to 'src/buffer.cc')
-rw-r--r--src/buffer.cc55
1 files changed, 53 insertions, 2 deletions
diff --git a/src/buffer.cc b/src/buffer.cc
index a06d9783..4738cc47 100644
--- a/src/buffer.cc
+++ b/src/buffer.cc
@@ -88,7 +88,7 @@ bool Buffer::set_name(String name)
BufferIterator Buffer::iterator_at(const BufferCoord& coord) const
{
- return BufferIterator(*this, clamp(coord));
+ return is_end(coord) ? end() : BufferIterator(*this, clamp(coord));
}
ByteCount Buffer::line_length(LineCount line) const
@@ -634,6 +634,11 @@ BufferCoord Buffer::advance(BufferCoord coord, ByteCount count) const
return { LineCount{ (int)(it - m_lines.begin()) }, off - it->start };
}
+BufferCoord Buffer::char_advance(BufferCoord coord, CharCount count) const
+{
+ return utf8::advance(iterator_at(coord), end(), count);
+}
+
BufferCoord Buffer::next(BufferCoord coord) const
{
if (coord.column < m_lines[coord.line].length() - 1)
@@ -648,6 +653,23 @@ BufferCoord Buffer::next(BufferCoord coord) const
return coord;
}
+BufferCoord Buffer::char_next(BufferCoord coord) const
+{
+ if (coord.column < m_lines[coord.line].length() - 1)
+ {
+ auto& line = m_lines[coord.line].content;
+ coord.column += utf8::codepoint_size(line.begin() + (int)coord.column);
+ }
+ else if (coord.line == m_lines.size() - 1)
+ coord.column = m_lines.back().length();
+ else
+ {
+ ++coord.line;
+ coord.column = 0;
+ }
+ return coord;
+}
+
BufferCoord Buffer::prev(BufferCoord coord) const
{
if (coord.column == 0)
@@ -663,11 +685,34 @@ BufferCoord Buffer::prev(BufferCoord coord) const
return coord;
}
+BufferCoord Buffer::char_prev(BufferCoord coord) const
+{
+ kak_assert(is_valid(coord));
+ if (is_end(coord))
+ return coord = {(int)m_lines.size()-1, m_lines.back().length() - 1};
+ else if (coord.column == 0)
+ {
+ if (coord.line > 0)
+ coord = { coord.line-1, m_lines[coord.line-1].length() - 1 };
+ }
+ else
+ {
+ auto& line = m_lines[coord.line].content;
+ coord.column = (int)(utf8::character_start(line.begin() + (int)coord.column - 1) - line.begin());
+ }
+ return coord;
+}
+
ByteCount Buffer::distance(const BufferCoord& begin, const BufferCoord& end) const
{
return offset(end) - offset(begin);
}
+CharCount Buffer::char_distance(const BufferCoord& begin, const BufferCoord& end) const
+{
+ return utf8::distance(iterator_at(begin), iterator_at(end));
+}
+
ByteCount Buffer::offset(const BufferCoord& c) const
{
if (c.line == line_count())
@@ -688,10 +733,16 @@ bool Buffer::is_end(const BufferCoord& c) const
(c.line == line_count() - 1 and c.column == m_lines.back().length());
}
-char Buffer::at(const BufferCoord& c) const
+char Buffer::byte_at(const BufferCoord& c) const
{
kak_assert(c.line < line_count() and c.column < m_lines[c.line].length());
return m_lines[c.line].content[c.column];
}
+Codepoint Buffer::char_at(const BufferCoord& c) const
+{
+ kak_assert(c.line < line_count() and c.column < m_lines[c.line].length());
+ return utf8::codepoint(m_lines[c.line].content.begin() + (int)c.column);
+}
+
}