Buffer: add some method to work directly with coord instead of iterators

This commit is contained in:
Maxime Coste 2013-05-22 18:59:55 +02:00
parent 0be8566dd7
commit f23f48172f
3 changed files with 36 additions and 36 deletions

View File

@ -95,9 +95,7 @@ BufferIterator Buffer::iterator_at(const BufferCoord& line_and_column,
ByteCount Buffer::line_length(LineCount line) const ByteCount Buffer::line_length(LineCount line) const
{ {
kak_assert(line < line_count()); kak_assert(line < line_count());
ByteCount end = (line < line_count() - 1) ? return m_lines[line].length();
m_lines[line + 1].start : byte_count();
return end - m_lines[line].start;
} }
BufferCoord Buffer::clamp(const BufferCoord& line_and_column, BufferCoord Buffer::clamp(const BufferCoord& line_and_column,
@ -630,6 +628,26 @@ void Buffer::notify_saved()
} }
} }
BufferCoord Buffer::advance(BufferCoord coord, ByteCount count) const
{
ByteCount off = Kakoune::clamp(offset(coord) + count, 0_byte, byte_count());
auto it = std::upper_bound(m_lines.begin(), m_lines.end(), off,
[](ByteCount s, const Line& l) { return s < l.start; }) - 1;
return { LineCount{ (int)(it - m_lines.begin()) }, off - it->start };
}
ByteCount Buffer::distance(const BufferCoord& begin, const BufferCoord& end) const
{
return offset(end) - offset(begin);
}
ByteCount Buffer::offset(const BufferCoord& c) const
{
if (c.line == line_count())
return m_lines.back().start + m_lines.back().length();
return m_lines[c.line].start + c.column;
}
bool Buffer::is_valid(const BufferCoord& c) const bool Buffer::is_valid(const BufferCoord& c) const
{ {
return (c.line < line_count() and c.column < m_lines[c.line].length()) or return (c.line < line_count() and c.column < m_lines[c.line].length()) or
@ -637,4 +655,10 @@ bool Buffer::is_valid(const BufferCoord& c) const
(c.line == line_count() and c.column == 0); (c.line == line_count() and c.column == 0);
} }
bool Buffer::is_end(const BufferCoord& c) const
{
return (c.line == line_count() and c.column == 0) or
(c.line == line_count() - 1 and c.column == m_lines.back().length());
}
} }

View File

@ -123,7 +123,11 @@ public:
String string(const BufferIterator& begin, String string(const BufferIterator& begin,
const BufferIterator& end) const; const BufferIterator& end) const;
ByteCount offset(const BufferCoord& c) const;
ByteCount distance(const BufferCoord& begin, const BufferCoord& end) const;
BufferCoord advance(BufferCoord coord, ByteCount count) const;
bool is_valid(const BufferCoord& c) const; bool is_valid(const BufferCoord& c) const;
bool is_end(const BufferCoord& c) const;
BufferIterator begin() const; BufferIterator begin() const;
BufferIterator end() const; BufferIterator end() const;

View File

@ -71,47 +71,24 @@ inline char BufferIterator::operator*() const
inline ByteCount BufferIterator::offset() const inline ByteCount BufferIterator::offset() const
{ {
kak_assert(m_buffer); kak_assert(m_buffer);
return line() >= m_buffer->line_count() ? return m_buffer->offset(m_coord);
m_buffer->byte_count() : m_buffer->m_lines[line()].start + column();
} }
inline size_t BufferIterator::operator-(const BufferIterator& iterator) const inline size_t BufferIterator::operator-(const BufferIterator& iterator) const
{ {
kak_assert(m_buffer == iterator.m_buffer); kak_assert(m_buffer == iterator.m_buffer);
return (size_t)(int)(offset() - iterator.offset()); return (size_t)(int)m_buffer->distance(iterator.m_coord, m_coord);
} }
inline BufferIterator BufferIterator::operator+(ByteCount size) const inline BufferIterator BufferIterator::operator+(ByteCount size) const
{ {
kak_assert(m_buffer); kak_assert(m_buffer);
if (size >= 0) return { *m_buffer, m_buffer->advance(m_coord, size) };
{
ByteCount o = std::min(m_buffer->byte_count(), offset() + size);
for (LineCount i = line() + 1; i < m_buffer->line_count(); ++i)
{
if (m_buffer->m_lines[i].start > o)
return BufferIterator(*m_buffer, { i-1, o - m_buffer->m_lines[i-1].start });
}
LineCount last_line = std::max(0_line, m_buffer->line_count() - 1);
return BufferIterator(*m_buffer, { last_line, o - m_buffer->m_lines[last_line].start });
}
return operator-(-size);
} }
inline BufferIterator BufferIterator::operator-(ByteCount size) const inline BufferIterator BufferIterator::operator-(ByteCount size) const
{ {
kak_assert(m_buffer); return { *m_buffer, m_buffer->advance(m_coord, -size) };
if (size >= 0)
{
ByteCount o = std::max(0_byte, offset() - size);
for (LineCount i = line(); i >= 0; --i)
{
if (m_buffer->m_lines[i].start <= o)
return BufferIterator(*m_buffer, { i, o - m_buffer->m_lines[i].start });
}
kak_assert(false);
}
return operator+(-size);
} }
inline BufferIterator& BufferIterator::operator+=(ByteCount size) inline BufferIterator& BufferIterator::operator+=(ByteCount size)
@ -183,12 +160,7 @@ inline bool BufferIterator::is_begin() const
inline bool BufferIterator::is_end() const inline bool BufferIterator::is_end() const
{ {
kak_assert(m_buffer); kak_assert(m_buffer);
if (m_coord.line == m_buffer->line_count()) return m_buffer->is_end(m_coord);
{
kak_assert(m_coord.column == 0);
return true;
}
return offset() == m_buffer->byte_count();
} }
} }