2014-01-12 18:19:05 +01:00
|
|
|
#ifndef buffer_inl_h_INCLUDED
|
|
|
|
#define buffer_inl_h_INCLUDED
|
2011-10-18 00:05:06 +02:00
|
|
|
|
|
|
|
#include "assert.hh"
|
|
|
|
|
|
|
|
namespace Kakoune
|
|
|
|
{
|
|
|
|
|
2014-07-19 01:18:16 +02:00
|
|
|
[[gnu::always_inline]]
|
2016-09-22 21:36:26 +02:00
|
|
|
inline const char& Buffer::byte_at(BufferCoord c) const
|
2014-01-12 18:19:05 +01:00
|
|
|
{
|
|
|
|
kak_assert(c.line < line_count() and c.column < m_lines[c.line].length());
|
2014-05-24 18:08:01 +02:00
|
|
|
return m_lines[c.line][c.column];
|
2014-01-12 18:19:05 +01:00
|
|
|
}
|
|
|
|
|
2016-09-22 21:36:26 +02:00
|
|
|
inline BufferCoord Buffer::next(BufferCoord coord) const
|
2014-01-12 18:19:05 +01:00
|
|
|
{
|
|
|
|
if (coord.column < m_lines[coord.line].length() - 1)
|
|
|
|
++coord.column;
|
|
|
|
else if (coord.line == m_lines.size() - 1)
|
|
|
|
coord.column = m_lines.back().length();
|
|
|
|
else
|
|
|
|
{
|
|
|
|
++coord.line;
|
|
|
|
coord.column = 0;
|
|
|
|
}
|
|
|
|
return coord;
|
|
|
|
}
|
|
|
|
|
2016-09-22 21:36:26 +02:00
|
|
|
inline BufferCoord Buffer::prev(BufferCoord coord) const
|
2014-01-12 18:19:05 +01:00
|
|
|
{
|
|
|
|
if (coord.column == 0)
|
|
|
|
{
|
|
|
|
if (coord.line > 0)
|
|
|
|
coord.column = m_lines[--coord.line].length() - 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
--coord.column;
|
|
|
|
return coord;
|
|
|
|
}
|
|
|
|
|
2016-09-22 21:36:26 +02:00
|
|
|
inline ByteCount Buffer::distance(BufferCoord begin, BufferCoord end) const
|
2014-01-12 18:19:05 +01:00
|
|
|
{
|
2014-05-24 18:08:01 +02:00
|
|
|
if (begin > end)
|
|
|
|
return -distance(end, begin);
|
2015-11-04 01:37:39 +01:00
|
|
|
if (begin.line == end.line)
|
|
|
|
return end.column - begin.column;
|
|
|
|
|
|
|
|
ByteCount res = m_lines[begin.line].length() - begin.column;
|
|
|
|
for (LineCount l = begin.line+1; l < end.line; ++l)
|
|
|
|
res += m_lines[l].length();
|
|
|
|
res += end.column;
|
2014-05-24 18:08:01 +02:00
|
|
|
return res;
|
2014-01-12 18:19:05 +01:00
|
|
|
}
|
|
|
|
|
2016-09-22 21:36:26 +02:00
|
|
|
inline bool Buffer::is_valid(BufferCoord c) const
|
2014-01-12 18:19:05 +01:00
|
|
|
{
|
2014-05-13 19:59:22 +02:00
|
|
|
if (c.line < 0 or c.column < 0)
|
|
|
|
return false;
|
|
|
|
|
2014-01-12 18:19:05 +01:00
|
|
|
return (c.line < line_count() and c.column < m_lines[c.line].length()) or
|
|
|
|
(c.line == line_count() - 1 and c.column == m_lines.back().length()) or
|
|
|
|
(c.line == line_count() and c.column == 0);
|
|
|
|
}
|
|
|
|
|
2016-09-22 21:36:26 +02:00
|
|
|
inline bool Buffer::is_end(BufferCoord c) const
|
2014-01-12 18:19:05 +01:00
|
|
|
{
|
2014-10-28 22:55:08 +01:00
|
|
|
return c >= end_coord();
|
2014-01-12 18:19:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
inline BufferIterator Buffer::begin() const
|
|
|
|
{
|
2015-06-24 14:44:47 +02:00
|
|
|
return {*this, { 0_line, 0 }};
|
2014-01-12 18:19:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
inline BufferIterator Buffer::end() const
|
|
|
|
{
|
2015-06-24 14:44:47 +02:00
|
|
|
return {*this, end_coord()};
|
2014-01-12 18:19:05 +01:00
|
|
|
}
|
|
|
|
|
2014-07-19 01:18:16 +02:00
|
|
|
[[gnu::always_inline]]
|
2014-01-12 18:19:05 +01:00
|
|
|
inline LineCount Buffer::line_count() const
|
|
|
|
{
|
|
|
|
return LineCount(m_lines.size());
|
|
|
|
}
|
|
|
|
|
2014-04-01 19:54:46 +02:00
|
|
|
inline size_t Buffer::timestamp() const
|
|
|
|
{
|
2014-05-11 13:20:59 +02:00
|
|
|
return m_changes.size();
|
|
|
|
}
|
|
|
|
|
2017-02-20 20:19:26 +01:00
|
|
|
inline StringView Buffer::substr(BufferCoord begin, BufferCoord end) const
|
|
|
|
{
|
|
|
|
kak_assert(begin.line == end.line);
|
|
|
|
return m_lines[begin.line].substr(begin.column, end.column - begin.column);
|
|
|
|
}
|
|
|
|
|
2015-03-09 14:48:41 +01:00
|
|
|
inline ConstArrayView<Buffer::Change> Buffer::changes_since(size_t timestamp) const
|
2014-05-11 13:20:59 +02:00
|
|
|
{
|
2015-12-13 00:50:01 +01:00
|
|
|
if (timestamp < m_changes.size())
|
|
|
|
return { m_changes.data() + timestamp,
|
|
|
|
m_changes.data() + m_changes.size() };
|
|
|
|
return {};
|
2014-04-01 19:54:46 +02:00
|
|
|
}
|
|
|
|
|
2016-09-22 21:36:26 +02:00
|
|
|
inline BufferCoord Buffer::back_coord() const
|
2014-04-01 19:54:46 +02:00
|
|
|
{
|
|
|
|
return { line_count() - 1, m_lines.back().length() - 1 };
|
|
|
|
}
|
|
|
|
|
2016-09-22 21:36:26 +02:00
|
|
|
inline BufferCoord Buffer::end_coord() const
|
2014-04-01 19:54:46 +02:00
|
|
|
{
|
2016-03-10 00:16:14 +01:00
|
|
|
return m_lines.empty() ?
|
2016-09-22 21:36:26 +02:00
|
|
|
BufferCoord{0,0} : BufferCoord{ line_count() - 1, m_lines.back().length() };
|
2014-04-01 19:54:46 +02:00
|
|
|
}
|
|
|
|
|
2017-06-07 11:58:01 +02:00
|
|
|
inline BufferIterator::BufferIterator(const Buffer& buffer, BufferCoord coord) noexcept
|
2015-11-07 17:55:48 +01:00
|
|
|
: m_buffer(&buffer), m_coord(coord),
|
2016-07-15 20:48:13 +02:00
|
|
|
m_line((*m_buffer)[coord.line]),
|
2017-06-07 11:58:01 +02:00
|
|
|
m_last_line(buffer.line_count()-1) {}
|
2011-10-24 16:26:21 +02:00
|
|
|
|
2017-06-07 11:58:01 +02:00
|
|
|
inline bool BufferIterator::operator==(const BufferIterator& iterator) const noexcept
|
2011-10-18 00:05:06 +02:00
|
|
|
{
|
2016-04-21 21:26:25 +02:00
|
|
|
return m_buffer == iterator.m_buffer and m_coord == iterator.m_coord;
|
2011-10-18 00:05:06 +02:00
|
|
|
}
|
|
|
|
|
2017-06-07 11:58:01 +02:00
|
|
|
inline bool BufferIterator::operator!=(const BufferIterator& iterator) const noexcept
|
2011-10-18 00:05:06 +02:00
|
|
|
{
|
2016-04-21 21:26:25 +02:00
|
|
|
return m_buffer != iterator.m_buffer or m_coord != iterator.m_coord;
|
2011-10-18 00:05:06 +02:00
|
|
|
}
|
|
|
|
|
2017-06-07 11:58:01 +02:00
|
|
|
inline bool BufferIterator::operator<(const BufferIterator& iterator) const noexcept
|
2011-10-18 00:05:06 +02:00
|
|
|
{
|
2013-04-09 20:04:11 +02:00
|
|
|
kak_assert(m_buffer == iterator.m_buffer);
|
2012-03-30 13:37:18 +02:00
|
|
|
return (m_coord < iterator.m_coord);
|
2011-10-18 00:05:06 +02:00
|
|
|
}
|
|
|
|
|
2017-06-07 11:58:01 +02:00
|
|
|
inline bool BufferIterator::operator<=(const BufferIterator& iterator) const noexcept
|
2011-10-18 00:05:06 +02:00
|
|
|
{
|
2013-04-09 20:04:11 +02:00
|
|
|
kak_assert(m_buffer == iterator.m_buffer);
|
2012-03-30 13:37:18 +02:00
|
|
|
return (m_coord <= iterator.m_coord);
|
2011-10-18 00:05:06 +02:00
|
|
|
}
|
|
|
|
|
2017-06-07 11:58:01 +02:00
|
|
|
inline bool BufferIterator::operator>(const BufferIterator& iterator) const noexcept
|
2011-10-18 00:05:06 +02:00
|
|
|
{
|
2013-04-09 20:04:11 +02:00
|
|
|
kak_assert(m_buffer == iterator.m_buffer);
|
2012-03-30 13:37:18 +02:00
|
|
|
return (m_coord > iterator.m_coord);
|
2011-10-18 00:05:06 +02:00
|
|
|
}
|
|
|
|
|
2017-06-07 11:58:01 +02:00
|
|
|
inline bool BufferIterator::operator>=(const BufferIterator& iterator) const noexcept
|
2011-10-18 00:05:06 +02:00
|
|
|
{
|
2013-04-09 20:04:11 +02:00
|
|
|
kak_assert(m_buffer == iterator.m_buffer);
|
2012-03-30 13:37:18 +02:00
|
|
|
return (m_coord >= iterator.m_coord);
|
|
|
|
}
|
|
|
|
|
2014-07-19 01:18:16 +02:00
|
|
|
[[gnu::always_inline]]
|
2017-06-07 11:58:01 +02:00
|
|
|
inline const char& BufferIterator::operator*() const noexcept
|
2011-10-18 00:05:06 +02:00
|
|
|
{
|
2016-07-15 20:48:13 +02:00
|
|
|
return m_line[m_coord.column];
|
2012-03-30 13:37:18 +02:00
|
|
|
}
|
|
|
|
|
2017-06-07 11:58:01 +02:00
|
|
|
inline const char& BufferIterator::operator[](size_t n) const noexcept
|
2013-05-30 14:05:05 +02:00
|
|
|
{
|
2013-06-03 18:56:48 +02:00
|
|
|
return m_buffer->byte_at(m_buffer->advance(m_coord, n));
|
2013-05-30 14:05:05 +02:00
|
|
|
}
|
|
|
|
|
2012-08-23 23:56:35 +02:00
|
|
|
inline size_t BufferIterator::operator-(const BufferIterator& iterator) const
|
2011-10-18 00:05:06 +02:00
|
|
|
{
|
2013-04-09 20:04:11 +02:00
|
|
|
kak_assert(m_buffer == iterator.m_buffer);
|
2016-04-22 22:01:54 +02:00
|
|
|
return (size_t)m_buffer->distance(iterator.m_coord, m_coord);
|
2011-10-18 00:05:06 +02:00
|
|
|
}
|
|
|
|
|
2012-10-11 00:41:48 +02:00
|
|
|
inline BufferIterator BufferIterator::operator+(ByteCount size) const
|
2011-10-18 00:05:06 +02:00
|
|
|
{
|
2013-04-09 20:04:11 +02:00
|
|
|
kak_assert(m_buffer);
|
2013-05-22 18:59:55 +02:00
|
|
|
return { *m_buffer, m_buffer->advance(m_coord, size) };
|
2011-10-18 00:05:06 +02:00
|
|
|
}
|
|
|
|
|
2012-10-11 00:41:48 +02:00
|
|
|
inline BufferIterator BufferIterator::operator-(ByteCount size) const
|
2011-10-18 00:05:06 +02:00
|
|
|
{
|
2013-05-22 18:59:55 +02:00
|
|
|
return { *m_buffer, m_buffer->advance(m_coord, -size) };
|
2011-10-18 00:05:06 +02:00
|
|
|
}
|
|
|
|
|
2012-10-11 00:41:48 +02:00
|
|
|
inline BufferIterator& BufferIterator::operator+=(ByteCount size)
|
2011-10-18 00:05:06 +02:00
|
|
|
{
|
2015-02-26 22:58:56 +01:00
|
|
|
m_coord = m_buffer->advance(m_coord, size);
|
2016-07-15 20:48:13 +02:00
|
|
|
m_line = (*m_buffer)[m_coord.line];
|
2015-02-26 22:58:56 +01:00
|
|
|
return *this;
|
2011-10-18 00:05:06 +02:00
|
|
|
}
|
|
|
|
|
2012-10-11 00:41:48 +02:00
|
|
|
inline BufferIterator& BufferIterator::operator-=(ByteCount size)
|
2011-10-18 00:05:06 +02:00
|
|
|
{
|
2015-02-26 22:58:56 +01:00
|
|
|
m_coord = m_buffer->advance(m_coord, -size);
|
2016-07-15 20:48:13 +02:00
|
|
|
m_line = (*m_buffer)[m_coord.line];
|
2015-02-26 22:58:56 +01:00
|
|
|
return *this;
|
2011-10-18 00:05:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
inline BufferIterator& BufferIterator::operator++()
|
|
|
|
{
|
2016-07-15 20:48:13 +02:00
|
|
|
if (++m_coord.column == m_line.length() and m_coord.line != m_last_line)
|
2015-11-07 17:55:48 +01:00
|
|
|
{
|
2016-07-15 20:48:13 +02:00
|
|
|
m_line = (*m_buffer)[++m_coord.line];
|
2015-11-07 17:55:48 +01:00
|
|
|
m_coord.column = 0;
|
|
|
|
}
|
2012-03-31 17:21:14 +02:00
|
|
|
return *this;
|
2011-10-18 00:05:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
inline BufferIterator& BufferIterator::operator--()
|
|
|
|
{
|
2015-11-12 14:59:36 +01:00
|
|
|
if (m_coord.column == 0 and m_coord.line > 0)
|
2015-11-07 17:55:48 +01:00
|
|
|
{
|
2016-07-15 20:48:13 +02:00
|
|
|
m_line = (*m_buffer)[--m_coord.line];
|
|
|
|
m_coord.column = m_line.length() - 1;
|
2015-11-07 17:55:48 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
--m_coord.column;
|
2012-03-31 17:21:14 +02:00
|
|
|
return *this;
|
2011-10-18 00:05:06 +02:00
|
|
|
}
|
|
|
|
|
2012-10-02 14:09:06 +02:00
|
|
|
inline BufferIterator BufferIterator::operator++(int)
|
|
|
|
{
|
|
|
|
BufferIterator save = *this;
|
|
|
|
++*this;
|
|
|
|
return save;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline BufferIterator BufferIterator::operator--(int)
|
|
|
|
{
|
|
|
|
BufferIterator save = *this;
|
|
|
|
--*this;
|
|
|
|
return save;
|
|
|
|
}
|
|
|
|
|
2011-10-18 00:05:06 +02:00
|
|
|
}
|
2014-01-12 18:19:05 +01:00
|
|
|
#endif // buffer_inl_h_INCLUDED
|