mirror of
https://github.com/mawww/kakoune.git
synced 2024-11-28 09:07:19 +03:00
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
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user