Buffer: add some method to work directly with coord instead of iterators
This commit is contained in:
parent
0be8566dd7
commit
f23f48172f
|
@ -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());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user