diff options
| author | Maxime Coste <frrrwww@gmail.com> | 2012-01-31 19:12:06 +0000 |
|---|---|---|
| committer | Maxime Coste <frrrwww@gmail.com> | 2012-01-31 19:12:06 +0000 |
| commit | 69d96c90da543fee83cd6f9fbac6d3348d28d446 (patch) | |
| tree | 49a3a90f68a2dd504630db0171468fda082c5266 /src/selection.cc | |
| parent | d23a175533ebc04fa5c8a9712118cc5bf509adf0 (diff) | |
extract an Editor class from Window and refactor
Diffstat (limited to 'src/selection.cc')
| -rw-r--r-- | src/selection.cc | 120 |
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); +} + +} |
