Buffer: add methods for char access instead of byte access

This commit is contained in:
Maxime Coste 2013-06-03 18:56:48 +02:00
parent b198f6a5fb
commit 02b33c7d8f
3 changed files with 64 additions and 5 deletions

View File

@ -88,7 +88,7 @@ bool Buffer::set_name(String name)
BufferIterator Buffer::iterator_at(const BufferCoord& coord) const 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 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 }; 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 BufferCoord Buffer::next(BufferCoord coord) const
{ {
if (coord.column < m_lines[coord.line].length() - 1) if (coord.column < m_lines[coord.line].length() - 1)
@ -648,6 +653,23 @@ BufferCoord Buffer::next(BufferCoord coord) const
return coord; 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 BufferCoord Buffer::prev(BufferCoord coord) const
{ {
if (coord.column == 0) if (coord.column == 0)
@ -663,11 +685,34 @@ BufferCoord Buffer::prev(BufferCoord coord) const
return coord; 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 ByteCount Buffer::distance(const BufferCoord& begin, const BufferCoord& end) const
{ {
return offset(end) - offset(begin); 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 ByteCount Buffer::offset(const BufferCoord& c) const
{ {
if (c.line == line_count()) 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()); (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()); kak_assert(c.line < line_count() and c.column < m_lines[c.line].length());
return m_lines[c.line].content[c.column]; 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);
}
} }

View File

@ -120,12 +120,20 @@ public:
bool redo(); bool redo();
String string(const BufferCoord& begin, const BufferCoord& end) const; String string(const BufferCoord& begin, const BufferCoord& end) const;
char at(const BufferCoord& c) const;
char byte_at(const BufferCoord& c) const;
ByteCount offset(const BufferCoord& c) const; ByteCount offset(const BufferCoord& c) const;
ByteCount distance(const BufferCoord& begin, const BufferCoord& end) const; ByteCount distance(const BufferCoord& begin, const BufferCoord& end) const;
BufferCoord advance(BufferCoord coord, ByteCount count) const; BufferCoord advance(BufferCoord coord, ByteCount count) const;
BufferCoord next(BufferCoord coord) const; BufferCoord next(BufferCoord coord) const;
BufferCoord prev(BufferCoord coord) const; BufferCoord prev(BufferCoord coord) const;
Codepoint char_at(const BufferCoord& c) const;
CharCount char_distance(const BufferCoord& begin, const BufferCoord& end) const;
BufferCoord char_advance(BufferCoord coord, CharCount count) const;
BufferCoord char_next(BufferCoord coord) const;
BufferCoord char_prev(BufferCoord coord) const;
bool is_valid(const BufferCoord& c) const; bool is_valid(const BufferCoord& c) const;
bool is_end(const BufferCoord& c) const; bool is_end(const BufferCoord& c) const;

View File

@ -59,12 +59,12 @@ inline bool BufferIterator::operator>=(const BufferIterator& iterator) const
inline char BufferIterator::operator*() const inline char BufferIterator::operator*() const
{ {
return m_buffer->at(m_coord); return m_buffer->byte_at(m_coord);
} }
inline char BufferIterator::operator[](size_t n) const inline char BufferIterator::operator[](size_t n) const
{ {
return m_buffer->at(m_buffer->advance(m_coord, n)); return m_buffer->byte_at(m_buffer->advance(m_coord, n));
} }
inline size_t BufferIterator::operator-(const BufferIterator& iterator) const inline size_t BufferIterator::operator-(const BufferIterator& iterator) const