mirror of
https://github.com/mawww/kakoune.git
synced 2024-12-26 04:52:53 +03:00
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
This commit is contained in:
parent
bace526fa3
commit
d2c6ceb47b
@ -254,14 +254,14 @@ void Buffer::notify_saved()
|
|||||||
m_last_save_undo_group = m_history_cursor;
|
m_last_save_undo_group = m_history_cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Buffer::register_modification_listener(BufferModificationListener* listener)
|
void Buffer::register_modification_listener(BufferModificationListener* listener) const
|
||||||
{
|
{
|
||||||
assert(listener);
|
assert(listener);
|
||||||
assert(not contains(m_modification_listeners, listener));
|
assert(not contains(m_modification_listeners, listener));
|
||||||
m_modification_listeners.push_back(listener);
|
m_modification_listeners.push_back(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Buffer::unregister_modification_listener(BufferModificationListener* listener)
|
void Buffer::unregister_modification_listener(BufferModificationListener* listener) const
|
||||||
{
|
{
|
||||||
assert(listener);
|
assert(listener);
|
||||||
auto it = std::find(m_modification_listeners.begin(),
|
auto it = std::find(m_modification_listeners.begin(),
|
||||||
|
@ -63,6 +63,7 @@ public:
|
|||||||
|
|
||||||
bool is_begin() const;
|
bool is_begin() const;
|
||||||
bool is_end() const;
|
bool is_end() const;
|
||||||
|
bool is_valid() const;
|
||||||
|
|
||||||
const Buffer& buffer() const;
|
const Buffer& buffer() const;
|
||||||
|
|
||||||
@ -145,8 +146,8 @@ public:
|
|||||||
Type type() const { return m_type; }
|
Type type() const { return m_type; }
|
||||||
void notify_saved();
|
void notify_saved();
|
||||||
|
|
||||||
void register_modification_listener(BufferModificationListener* listener);
|
void register_modification_listener(BufferModificationListener* listener) const;
|
||||||
void unregister_modification_listener(BufferModificationListener* listener);
|
void unregister_modification_listener(BufferModificationListener* listener) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BufferChar at(BufferPos position) const;
|
BufferChar at(BufferPos position) const;
|
||||||
@ -185,7 +186,7 @@ private:
|
|||||||
|
|
||||||
std::vector<UndoGroup>::iterator m_last_save_undo_group;
|
std::vector<UndoGroup>::iterator m_last_save_undo_group;
|
||||||
|
|
||||||
std::vector<BufferModificationListener*> m_modification_listeners;
|
mutable std::vector<BufferModificationListener*> m_modification_listeners;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,11 @@ inline const Buffer& BufferIterator::buffer() const
|
|||||||
return *m_buffer;
|
return *m_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool BufferIterator::is_valid() const
|
||||||
|
{
|
||||||
|
return m_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
inline BufferIterator& BufferIterator::operator=(const BufferIterator& iterator)
|
inline BufferIterator& BufferIterator::operator=(const BufferIterator& iterator)
|
||||||
{
|
{
|
||||||
m_buffer = iterator.m_buffer;
|
m_buffer = iterator.m_buffer;
|
||||||
|
71
src/dynamic_buffer_iterator.cc
Normal file
71
src/dynamic_buffer_iterator.cc
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
35
src/dynamic_buffer_iterator.hh
Normal file
35
src/dynamic_buffer_iterator.hh
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef dynamic_buffer_iterator_hh_INCLUDED
|
||||||
|
#define dynamic_buffer_iterator_hh_INCLUDED
|
||||||
|
|
||||||
|
#include "buffer.hh"
|
||||||
|
|
||||||
|
namespace Kakoune
|
||||||
|
{
|
||||||
|
|
||||||
|
class DynamicBufferIterator : public BufferIterator,
|
||||||
|
public BufferModificationListener
|
||||||
|
{
|
||||||
|
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 BufferModification& modification);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void register_ifp();
|
||||||
|
void unregister_ifn();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // dynamic_buffer_iterator_hh_INCLUDED
|
@ -144,10 +144,7 @@ void Window::erase_noundo()
|
|||||||
{
|
{
|
||||||
check_invariant();
|
check_invariant();
|
||||||
for (auto& sel : m_selections)
|
for (auto& sel : m_selections)
|
||||||
{
|
|
||||||
m_buffer.erase(sel.begin(), sel.end());
|
m_buffer.erase(sel.begin(), sel.end());
|
||||||
sel = Selection(sel.begin(), sel.begin());
|
|
||||||
}
|
|
||||||
scroll_to_keep_cursor_visible_ifn();
|
scroll_to_keep_cursor_visible_ifn();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,10 +180,7 @@ void Window::insert(const String& string)
|
|||||||
void Window::insert_noundo(const String& string)
|
void Window::insert_noundo(const String& string)
|
||||||
{
|
{
|
||||||
for (auto& sel : m_selections)
|
for (auto& sel : m_selections)
|
||||||
{
|
|
||||||
m_buffer.insert(sel.begin(), string);
|
m_buffer.insert(sel.begin(), string);
|
||||||
sel.offset(string.length());
|
|
||||||
}
|
|
||||||
scroll_to_keep_cursor_visible_ifn();
|
scroll_to_keep_cursor_visible_ifn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#include "buffer.hh"
|
#include "buffer.hh"
|
||||||
|
#include "dynamic_buffer_iterator.hh"
|
||||||
#include "display_buffer.hh"
|
#include "display_buffer.hh"
|
||||||
|
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
@ -23,8 +24,8 @@ struct Selection
|
|||||||
void offset(int offset);
|
void offset(int offset);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BufferIterator m_first;
|
DynamicBufferIterator m_first;
|
||||||
BufferIterator m_last;
|
DynamicBufferIterator m_last;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<Selection> SelectionList;
|
typedef std::vector<Selection> SelectionList;
|
||||||
|
Loading…
Reference in New Issue
Block a user