remove DynamicBufferIterator and make Selection a ModificationListener
DynamicBufferIterator is only used by Selections. And each selection had two iterators, resulting in two ModificationListeners registered in the buffer instead of one now.
This commit is contained in:
parent
382d5a334c
commit
a72d185f79
|
@ -1,73 +0,0 @@
|
|||
#include "dynamic_buffer_iterator.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
DynamicBufferIterator::DynamicBufferIterator(const Buffer& buffer,
|
||||
BufferPos position)
|
||||
: BufferIterator(buffer, position)
|
||||
{
|
||||
register_ifp();
|
||||
}
|
||||
|
||||
DynamicBufferIterator::DynamicBufferIterator(DynamicBufferIterator&& other)
|
||||
: BufferIterator(other)
|
||||
{
|
||||
register_ifp();
|
||||
}
|
||||
|
||||
DynamicBufferIterator::DynamicBufferIterator(const BufferIterator& other)
|
||||
: BufferIterator(other)
|
||||
{
|
||||
register_ifp();
|
||||
}
|
||||
|
||||
DynamicBufferIterator& DynamicBufferIterator::operator=(const BufferIterator& other)
|
||||
{
|
||||
unregister_ifn();
|
||||
BufferIterator::operator=(other);
|
||||
register_ifp();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
DynamicBufferIterator::~DynamicBufferIterator()
|
||||
{
|
||||
unregister_ifn();
|
||||
}
|
||||
|
||||
void DynamicBufferIterator::on_modification(const Modification& modification)
|
||||
{
|
||||
if (*this < modification.position)
|
||||
return;
|
||||
|
||||
size_t length = modification.content.length();
|
||||
if (modification.type == Modification::Erase)
|
||||
{
|
||||
// do not move length on the other side of the inequality,
|
||||
// as modification.position + length may be after buffer end
|
||||
if (*this - length <= modification.position)
|
||||
BufferIterator::operator=(modification.position);
|
||||
else
|
||||
*this -= length;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(modification.type == Modification::Insert);
|
||||
*this += length;
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicBufferIterator::register_ifp()
|
||||
{
|
||||
if (is_valid())
|
||||
const_cast<Buffer&>(buffer()).register_modification_listener(this);
|
||||
}
|
||||
|
||||
void DynamicBufferIterator::unregister_ifn()
|
||||
{
|
||||
if (is_valid())
|
||||
const_cast<Buffer&>(buffer()).unregister_modification_listener(this);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
#ifndef dynamic_buffer_iterator_hh_INCLUDED
|
||||
#define dynamic_buffer_iterator_hh_INCLUDED
|
||||
|
||||
#include "buffer.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
class DynamicBufferIterator : public BufferIterator,
|
||||
public ModificationListener
|
||||
{
|
||||
public:
|
||||
DynamicBufferIterator() : BufferIterator() {}
|
||||
DynamicBufferIterator(const Buffer& buffer, BufferPos position);
|
||||
DynamicBufferIterator(const BufferIterator& other);
|
||||
DynamicBufferIterator(const DynamicBufferIterator& other)
|
||||
: BufferIterator(other) { register_ifp(); }
|
||||
|
||||
DynamicBufferIterator(DynamicBufferIterator&& other);
|
||||
DynamicBufferIterator& operator=(const BufferIterator& other);
|
||||
DynamicBufferIterator& operator=(const DynamicBufferIterator& other)
|
||||
{ return this->operator= (static_cast<const BufferIterator&>(other)); }
|
||||
~DynamicBufferIterator();
|
||||
|
||||
void on_modification(const Modification& modification);
|
||||
|
||||
private:
|
||||
void register_ifp();
|
||||
void unregister_ifn();
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif // dynamic_buffer_iterator_hh_INCLUDED
|
|
@ -11,6 +11,55 @@
|
|||
namespace Kakoune
|
||||
{
|
||||
|
||||
Selection::Selection(const BufferIterator& first, const BufferIterator& last,
|
||||
const CaptureList& captures)
|
||||
: m_first(first), m_last(last), m_captures(captures)
|
||||
{
|
||||
register_with_buffer();
|
||||
}
|
||||
|
||||
Selection::Selection(const BufferIterator& first, const BufferIterator& last,
|
||||
CaptureList&& captures)
|
||||
: m_first(first), m_last(last), m_captures(captures)
|
||||
{
|
||||
register_with_buffer();
|
||||
}
|
||||
|
||||
Selection::Selection(const Selection& other)
|
||||
: m_first(other.m_first), m_last(other.m_last),
|
||||
m_captures(other.m_captures)
|
||||
{
|
||||
register_with_buffer();
|
||||
}
|
||||
|
||||
Selection::Selection(Selection&& other)
|
||||
: m_first(other.m_first), m_last(other.m_last),
|
||||
m_captures(other.m_captures)
|
||||
{
|
||||
register_with_buffer();
|
||||
}
|
||||
|
||||
Selection::~Selection()
|
||||
{
|
||||
unregister_with_buffer();
|
||||
}
|
||||
|
||||
Selection& Selection::operator=(const Selection& other)
|
||||
{
|
||||
const bool new_buffer = &m_first.buffer() != &other.m_first.buffer();
|
||||
if (new_buffer)
|
||||
unregister_with_buffer();
|
||||
|
||||
m_first = other.m_first;
|
||||
m_last = other.m_last;
|
||||
m_captures = other.m_captures;
|
||||
|
||||
if (new_buffer)
|
||||
register_with_buffer();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BufferIterator Selection::begin() const
|
||||
{
|
||||
return std::min(m_first, m_last);
|
||||
|
@ -37,6 +86,45 @@ BufferString Selection::capture(size_t index) const
|
|||
return "";
|
||||
}
|
||||
|
||||
static void update_iterator(const Modification& modification,
|
||||
BufferIterator& iterator)
|
||||
{
|
||||
if (iterator < modification.position)
|
||||
return;
|
||||
|
||||
size_t length = modification.content.length();
|
||||
if (modification.type == Modification::Erase)
|
||||
{
|
||||
// do not move length on the other side of the inequality,
|
||||
// as modification.position + length may be after buffer end
|
||||
if (iterator - length <= modification.position)
|
||||
iterator = modification.position;
|
||||
else
|
||||
iterator -= length;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(modification.type == Modification::Insert);
|
||||
iterator += length;
|
||||
}
|
||||
}
|
||||
|
||||
void Selection::on_modification(const Modification& modification)
|
||||
{
|
||||
update_iterator(modification, m_first);
|
||||
update_iterator(modification, m_last);
|
||||
}
|
||||
|
||||
void Selection::register_with_buffer()
|
||||
{
|
||||
const_cast<Buffer&>(m_first.buffer()).register_modification_listener(this);
|
||||
}
|
||||
|
||||
void Selection::unregister_with_buffer()
|
||||
{
|
||||
const_cast<Buffer&>(m_first.buffer()).unregister_modification_listener(this);
|
||||
}
|
||||
|
||||
struct scoped_undo_group
|
||||
{
|
||||
scoped_undo_group(Buffer& buffer)
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include <functional>
|
||||
|
||||
#include "buffer.hh"
|
||||
#include "dynamic_buffer_iterator.hh"
|
||||
#include "display_buffer.hh"
|
||||
#include "completion.hh"
|
||||
#include "highlighter.hh"
|
||||
|
@ -16,17 +15,22 @@
|
|||
namespace Kakoune
|
||||
{
|
||||
|
||||
struct Selection
|
||||
struct Selection : public ModificationListener
|
||||
{
|
||||
typedef std::vector<BufferString> CaptureList;
|
||||
|
||||
Selection(const BufferIterator& first, const BufferIterator& last,
|
||||
const CaptureList& captures = CaptureList())
|
||||
: m_first(first), m_last(last), m_captures(captures) {}
|
||||
const CaptureList& captures = CaptureList());
|
||||
|
||||
Selection(const BufferIterator& first, const BufferIterator& last,
|
||||
CaptureList&& captures)
|
||||
: m_first(first), m_last(last), m_captures(captures) {}
|
||||
CaptureList&& captures);
|
||||
|
||||
Selection(const Selection& other);
|
||||
Selection(Selection&& other);
|
||||
|
||||
~Selection();
|
||||
|
||||
Selection& operator=(const Selection& other);
|
||||
|
||||
BufferIterator begin() const;
|
||||
BufferIterator end() const;
|
||||
|
@ -40,10 +44,17 @@ struct Selection
|
|||
const CaptureList& captures() const { return m_captures; }
|
||||
|
||||
private:
|
||||
DynamicBufferIterator m_first;
|
||||
DynamicBufferIterator m_last;
|
||||
BufferIterator m_first;
|
||||
BufferIterator m_last;
|
||||
|
||||
CaptureList m_captures;
|
||||
|
||||
void on_modification(const Modification& modification);
|
||||
|
||||
void register_with_buffer();
|
||||
void unregister_with_buffer();
|
||||
|
||||
void check_invariant();
|
||||
};
|
||||
|
||||
typedef std::vector<Selection> SelectionList;
|
||||
|
|
Loading…
Reference in New Issue
Block a user