summaryrefslogtreecommitdiff
path: root/src/dynamic_buffer_iterator.cc
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2011-10-24 14:26:21 +0000
committerMaxime Coste <frrrwww@gmail.com>2011-10-24 14:26:21 +0000
commitd2c6ceb47b532d125c3cafffdca79fada54ee21f (patch)
treee13757428f023d134cf0ba51bfab880a60c8ae40 /src/dynamic_buffer_iterator.cc
parentbace526fa31f1ce9fbc89a1c468f2dc91bee8845 (diff)
DynamicBufferIterator: add and use in Selections
DynamicBufferIterator are a new type of BufferIterators that automatically update themselves when their buffer is modified. Selections now uses this type of iterators instead of plain ones
Diffstat (limited to 'src/dynamic_buffer_iterator.cc')
-rw-r--r--src/dynamic_buffer_iterator.cc71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/dynamic_buffer_iterator.cc b/src/dynamic_buffer_iterator.cc
new file mode 100644
index 00000000..42c9d39c
--- /dev/null
+++ b/src/dynamic_buffer_iterator.cc
@@ -0,0 +1,71 @@
+#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 BufferModification& modification)
+{
+ if (*this < modification.position)
+ return;
+
+ size_t length = modification.content.length();
+ if (modification.type == BufferModification::Erase)
+ {
+ if (*this <= modification.position + length)
+ BufferIterator::operator=(modification.position);
+ else
+ *this -= length;
+ }
+ else
+ {
+ assert(modification.type == BufferModification::Insert);
+ *this += length;
+ }
+}
+
+void DynamicBufferIterator::register_ifp()
+{
+ if (is_valid())
+ buffer().register_modification_listener(this);
+}
+
+void DynamicBufferIterator::unregister_ifn()
+{
+ if (is_valid())
+ buffer().unregister_modification_listener(this);
+}
+
+}