summaryrefslogtreecommitdiff
path: root/src/selection.cc
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2012-01-31 19:12:06 +0000
committerMaxime Coste <frrrwww@gmail.com>2012-01-31 19:12:06 +0000
commit69d96c90da543fee83cd6f9fbac6d3348d28d446 (patch)
tree49a3a90f68a2dd504630db0171468fda082c5266 /src/selection.cc
parentd23a175533ebc04fa5c8a9712118cc5bf509adf0 (diff)
extract an Editor class from Window and refactor
Diffstat (limited to 'src/selection.cc')
-rw-r--r--src/selection.cc120
1 files changed, 120 insertions, 0 deletions
diff --git a/src/selection.cc b/src/selection.cc
new file mode 100644
index 00000000..e772179c
--- /dev/null
+++ b/src/selection.cc
@@ -0,0 +1,120 @@
+#include "selection.hh"
+
+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);
+}
+
+BufferIterator Selection::end() const
+{
+ return std::max(m_first, m_last) + 1;
+}
+
+void Selection::merge_with(const Selection& selection)
+{
+ if (m_first <= m_last)
+ m_first = std::min(m_first, selection.m_first);
+ else
+ m_first = std::max(m_first, selection.m_first);
+ m_last = selection.m_last;
+}
+
+BufferString Selection::capture(size_t index) const
+{
+ if (index < m_captures.size())
+ return m_captures[index];
+ 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);
+}
+
+}