2012-01-31 20:12:06 +01:00
|
|
|
#include "selection.hh"
|
|
|
|
|
2012-10-08 14:26:57 +02:00
|
|
|
#include "utf8.hh"
|
|
|
|
|
2012-01-31 20:12:06 +01:00
|
|
|
namespace Kakoune
|
|
|
|
{
|
|
|
|
|
2012-11-30 18:32:49 +01:00
|
|
|
void Range::merge_with(const Range& range)
|
|
|
|
{
|
|
|
|
if (m_first < m_last)
|
|
|
|
m_first = std::min(m_first, range.m_first);
|
|
|
|
if (m_first > m_last)
|
|
|
|
m_first = std::max(m_first, range.m_first);
|
|
|
|
m_last = range.m_last;
|
|
|
|
}
|
|
|
|
|
|
|
|
BufferIterator Range::begin() const
|
|
|
|
{
|
|
|
|
return std::min(m_first, m_last);
|
|
|
|
}
|
|
|
|
|
|
|
|
BufferIterator Range::end() const
|
|
|
|
{
|
|
|
|
return utf8::next(std::max(m_first, m_last));
|
|
|
|
}
|
|
|
|
|
|
|
|
Selection::Selection(const BufferIterator& first, const BufferIterator& last,
|
|
|
|
CaptureList captures)
|
|
|
|
: Range{first, last}, m_captures{std::move(captures)}
|
2012-01-31 20:12:06 +01:00
|
|
|
{
|
2012-10-08 14:26:57 +02:00
|
|
|
check_invariant();
|
|
|
|
register_with_buffer();
|
2012-01-31 20:12:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Selection::Selection(const Selection& other)
|
2012-11-30 18:32:49 +01:00
|
|
|
: Range(other), m_captures(other.m_captures)
|
|
|
|
{
|
|
|
|
register_with_buffer();
|
|
|
|
}
|
|
|
|
|
|
|
|
Selection::Selection(Selection&& other)
|
|
|
|
: Range{other},
|
|
|
|
m_captures{std::move(other.m_captures)}
|
2012-01-31 20:12:06 +01:00
|
|
|
{
|
|
|
|
register_with_buffer();
|
|
|
|
}
|
|
|
|
|
|
|
|
Selection::~Selection()
|
|
|
|
{
|
|
|
|
unregister_with_buffer();
|
|
|
|
}
|
|
|
|
|
|
|
|
Selection& Selection::operator=(const Selection& other)
|
|
|
|
{
|
2012-11-30 18:32:49 +01:00
|
|
|
const bool new_buffer = &first().buffer() != &other.first().buffer();
|
2012-01-31 20:12:06 +01:00
|
|
|
if (new_buffer)
|
|
|
|
unregister_with_buffer();
|
|
|
|
|
2012-11-30 18:32:49 +01:00
|
|
|
first() = other.first();
|
|
|
|
last() = other.last();
|
|
|
|
m_captures = other.m_captures;
|
2012-01-31 20:12:06 +01:00
|
|
|
|
|
|
|
if (new_buffer)
|
|
|
|
register_with_buffer();
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2012-11-30 18:32:49 +01:00
|
|
|
Selection& Selection::operator=(Selection&& other)
|
2012-01-31 20:12:06 +01:00
|
|
|
{
|
2012-11-30 18:32:49 +01:00
|
|
|
const bool new_buffer = &first().buffer() != &other.first().buffer();
|
|
|
|
if (new_buffer)
|
|
|
|
unregister_with_buffer();
|
2012-01-31 20:12:06 +01:00
|
|
|
|
2012-11-30 18:32:49 +01:00
|
|
|
first() = other.first();
|
|
|
|
last() = other.last();
|
|
|
|
m_captures = std::move(other.m_captures);
|
2012-01-31 20:12:06 +01:00
|
|
|
|
2012-11-30 18:32:49 +01:00
|
|
|
if (new_buffer)
|
|
|
|
register_with_buffer();
|
|
|
|
|
|
|
|
return *this;
|
2012-01-31 20:12:06 +01:00
|
|
|
}
|
|
|
|
|
2012-10-08 14:26:57 +02:00
|
|
|
static void avoid_eol(BufferIterator& it)
|
|
|
|
{
|
|
|
|
const auto column = it.column();
|
|
|
|
if (column != 0 and column == it.buffer().line_length(it.line()) - 1)
|
|
|
|
it = utf8::previous(it);
|
|
|
|
}
|
|
|
|
|
2012-08-15 18:20:02 +02:00
|
|
|
void Selection::avoid_eol()
|
|
|
|
{
|
2012-11-30 18:32:49 +01:00
|
|
|
Kakoune::avoid_eol(first());
|
|
|
|
Kakoune::avoid_eol(last());
|
2012-08-15 18:20:02 +02:00
|
|
|
}
|
|
|
|
|
2012-07-16 21:51:37 +02:00
|
|
|
void Selection::on_insert(const BufferIterator& begin, const BufferIterator& end)
|
|
|
|
{
|
2012-11-30 18:32:49 +01:00
|
|
|
first().on_insert(begin.coord(), end.coord());
|
|
|
|
last().on_insert(begin.coord(), end.coord());
|
2012-10-08 14:26:57 +02:00
|
|
|
check_invariant();
|
2012-07-16 21:51:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Selection::on_erase(const BufferIterator& begin, const BufferIterator& end)
|
|
|
|
{
|
2012-11-30 18:32:49 +01:00
|
|
|
first().on_erase(begin.coord(), end.coord());
|
|
|
|
last().on_erase(begin.coord(), end.coord());
|
2012-10-08 14:26:57 +02:00
|
|
|
check_invariant();
|
2012-07-16 21:51:37 +02:00
|
|
|
}
|
|
|
|
|
2012-01-31 20:12:06 +01:00
|
|
|
void Selection::register_with_buffer()
|
|
|
|
{
|
2012-11-30 18:32:49 +01:00
|
|
|
first().buffer().add_change_listener(*this);
|
2012-01-31 20:12:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void Selection::unregister_with_buffer()
|
|
|
|
{
|
2012-11-30 18:32:49 +01:00
|
|
|
first().buffer().remove_change_listener(*this);
|
2012-01-31 20:12:06 +01:00
|
|
|
}
|
|
|
|
|
2012-10-08 14:26:57 +02:00
|
|
|
void Selection::check_invariant() const
|
|
|
|
{
|
2012-11-30 18:32:49 +01:00
|
|
|
assert(utf8::is_character_start(first()));
|
|
|
|
assert(utf8::is_character_start(last()));
|
2012-10-08 14:26:57 +02:00
|
|
|
}
|
|
|
|
|
2012-01-31 20:12:06 +01:00
|
|
|
}
|