From f23f48172f2c95b053977e6fbddab35c22a4a953 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Wed, 22 May 2013 18:59:55 +0200 Subject: [PATCH] Buffer: add some method to work directly with coord instead of iterators --- src/buffer.cc | 30 +++++++++++++++++++++++++++--- src/buffer.hh | 4 ++++ src/buffer_iterator.inl.hh | 38 +++++--------------------------------- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/buffer.cc b/src/buffer.cc index 14507528..30da1305 100644 --- a/src/buffer.cc +++ b/src/buffer.cc @@ -95,9 +95,7 @@ BufferIterator Buffer::iterator_at(const BufferCoord& line_and_column, ByteCount Buffer::line_length(LineCount line) const { kak_assert(line < line_count()); - ByteCount end = (line < line_count() - 1) ? - m_lines[line + 1].start : byte_count(); - return end - m_lines[line].start; + return m_lines[line].length(); } 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 { 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); } +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()); +} + } diff --git a/src/buffer.hh b/src/buffer.hh index 78271b20..fe116b3a 100644 --- a/src/buffer.hh +++ b/src/buffer.hh @@ -123,7 +123,11 @@ public: String string(const BufferIterator& begin, 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_end(const BufferCoord& c) const; BufferIterator begin() const; BufferIterator end() const; diff --git a/src/buffer_iterator.inl.hh b/src/buffer_iterator.inl.hh index 194a293f..575ed03f 100644 --- a/src/buffer_iterator.inl.hh +++ b/src/buffer_iterator.inl.hh @@ -71,47 +71,24 @@ inline char BufferIterator::operator*() const inline ByteCount BufferIterator::offset() const { kak_assert(m_buffer); - return line() >= m_buffer->line_count() ? - m_buffer->byte_count() : m_buffer->m_lines[line()].start + column(); + return m_buffer->offset(m_coord); } inline size_t BufferIterator::operator-(const BufferIterator& iterator) const { 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 { kak_assert(m_buffer); - if (size >= 0) - { - 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); + return { *m_buffer, m_buffer->advance(m_coord, size) }; } inline BufferIterator BufferIterator::operator-(ByteCount size) const { - kak_assert(m_buffer); - 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); + return { *m_buffer, m_buffer->advance(m_coord, -size) }; } inline BufferIterator& BufferIterator::operator+=(ByteCount size) @@ -183,12 +160,7 @@ inline bool BufferIterator::is_begin() const inline bool BufferIterator::is_end() const { kak_assert(m_buffer); - if (m_coord.line == m_buffer->line_count()) - { - kak_assert(m_coord.column == 0); - return true; - } - return offset() == m_buffer->byte_count(); + return m_buffer->is_end(m_coord); } }