Go back to a generic BufferChangeListener interface for selection update
This commit is contained in:
parent
fe988868e5
commit
31c0931dff
|
@ -45,7 +45,7 @@ Buffer::~Buffer()
|
||||||
{
|
{
|
||||||
m_windows.clear();
|
m_windows.clear();
|
||||||
BufferManager::instance().unregister_buffer(this);
|
BufferManager::instance().unregister_buffer(this);
|
||||||
assert(m_iterators_to_update.empty());
|
assert(m_change_listeners.empty());
|
||||||
|
|
||||||
m_hook_manager.run_hook("BufClose", m_name, Context(*this));
|
m_hook_manager.run_hook("BufClose", m_name, Context(*this));
|
||||||
}
|
}
|
||||||
|
@ -213,7 +213,8 @@ void Buffer::insert(const BufferIterator& pos, const String& content)
|
||||||
for (size_t i = pos.line()+1; i < line_count(); ++i)
|
for (size_t i = pos.line()+1; i < line_count(); ++i)
|
||||||
m_lines[i].start += content.length();
|
m_lines[i].start += content.length();
|
||||||
|
|
||||||
BufferCoord end_pos;
|
BufferIterator begin_it;
|
||||||
|
BufferIterator end_it;
|
||||||
// if we inserted at the end of the buffer, we may have created a new
|
// if we inserted at the end of the buffer, we may have created a new
|
||||||
// line without inserting a '\n'
|
// line without inserting a '\n'
|
||||||
if (pos == end() and (pos == begin() or *(pos-1) == '\n'))
|
if (pos == end() and (pos == begin() or *(pos-1) == '\n'))
|
||||||
|
@ -230,7 +231,8 @@ void Buffer::insert(const BufferIterator& pos, const String& content)
|
||||||
if (start != content.length())
|
if (start != content.length())
|
||||||
m_lines.push_back({ offset + start, content.substr(start) });
|
m_lines.push_back({ offset + start, content.substr(start) });
|
||||||
|
|
||||||
end_pos = end().m_coord;
|
begin_it = iterator_at({ pos.m_coord.line + 1, 0 });
|
||||||
|
end_it = end();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -265,13 +267,14 @@ void Buffer::insert(const BufferIterator& pos, const String& content)
|
||||||
else
|
else
|
||||||
line_it = m_lines.insert(line_it, { offset + start, content.substr(start) + suffix });
|
line_it = m_lines.insert(line_it, { offset + start, content.substr(start) + suffix });
|
||||||
|
|
||||||
end_pos = { int(line_it - m_lines.begin()), int(line_it->length() - suffix.length()) };
|
begin_it = pos;
|
||||||
|
end_it = iterator_at({ int(line_it - m_lines.begin()), int(line_it->length() - suffix.length()) });
|
||||||
}
|
}
|
||||||
|
|
||||||
check_invariant();
|
check_invariant();
|
||||||
|
|
||||||
for (auto iterator : m_iterators_to_update)
|
for (auto listener : m_change_listeners)
|
||||||
iterator->on_insert(pos.m_coord, end_pos);
|
listener->on_insert(begin_it, end_it);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Buffer::erase(const BufferIterator& pos, BufferSize length)
|
void Buffer::erase(const BufferIterator& pos, BufferSize length)
|
||||||
|
@ -291,8 +294,8 @@ void Buffer::erase(const BufferIterator& pos, BufferSize length)
|
||||||
|
|
||||||
check_invariant();
|
check_invariant();
|
||||||
|
|
||||||
for (auto iterator : m_iterators_to_update)
|
for (auto listener : m_change_listeners)
|
||||||
iterator->on_erase(pos.m_coord, end.m_coord);
|
listener->on_erase(pos, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Buffer::apply_modification(const Modification& modification)
|
void Buffer::apply_modification(const Modification& modification)
|
||||||
|
@ -360,19 +363,19 @@ void Buffer::notify_saved()
|
||||||
m_last_save_undo_index = history_cursor_index;
|
m_last_save_undo_index = history_cursor_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Buffer::add_iterator_to_update(BufferIterator& iterator)
|
void Buffer::add_change_listener(BufferChangeListener& listener)
|
||||||
{
|
{
|
||||||
assert(not contains(m_iterators_to_update, &iterator));
|
assert(not contains(m_change_listeners, &listener));
|
||||||
m_iterators_to_update.push_back(&iterator);
|
m_change_listeners.push_back(&listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Buffer::remove_iterator_from_update(BufferIterator& iterator)
|
void Buffer::remove_change_listener(BufferChangeListener& listener)
|
||||||
{
|
{
|
||||||
auto it = std::find(m_iterators_to_update.begin(),
|
auto it = std::find(m_change_listeners.begin(),
|
||||||
m_iterators_to_update.end(),
|
m_change_listeners.end(),
|
||||||
&iterator);
|
&listener);
|
||||||
assert(it != m_iterators_to_update.end());
|
assert(it != m_change_listeners.end());
|
||||||
m_iterators_to_update.erase(it);
|
m_change_listeners.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,7 @@ public:
|
||||||
void on_erase(const BufferCoord& begin, const BufferCoord& end);
|
void on_erase(const BufferCoord& begin, const BufferCoord& end);
|
||||||
|
|
||||||
const Buffer& buffer() const;
|
const Buffer& buffer() const;
|
||||||
|
const BufferCoord& coord() const { return m_coord; }
|
||||||
BufferSize line() const { return m_coord.line; }
|
BufferSize line() const { return m_coord.line; }
|
||||||
BufferSize column() const { return m_coord.column; }
|
BufferSize column() const { return m_coord.column; }
|
||||||
|
|
||||||
|
@ -100,6 +101,13 @@ struct Modification
|
||||||
static Modification make_insert(BufferIterator position, String content);
|
static Modification make_insert(BufferIterator position, String content);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class BufferChangeListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void on_insert(const BufferIterator& begin, const BufferIterator& end) = 0;
|
||||||
|
virtual void on_erase(const BufferIterator& begin, const BufferIterator& end) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
// A Buffer is a in-memory representation of a file
|
// A Buffer is a in-memory representation of a file
|
||||||
//
|
//
|
||||||
// The Buffer class permits to read and mutate this file
|
// The Buffer class permits to read and mutate this file
|
||||||
|
@ -157,8 +165,8 @@ public:
|
||||||
// notify the buffer that it was saved in the current state
|
// notify the buffer that it was saved in the current state
|
||||||
void notify_saved();
|
void notify_saved();
|
||||||
|
|
||||||
void add_iterator_to_update(BufferIterator& iterator);
|
void add_change_listener(BufferChangeListener& listener);
|
||||||
void remove_iterator_from_update(BufferIterator& iterator);
|
void remove_change_listener(BufferChangeListener& listener);
|
||||||
|
|
||||||
// returns an iterator pointing to the first character of the line
|
// returns an iterator pointing to the first character of the line
|
||||||
// iterator is on
|
// iterator is on
|
||||||
|
@ -210,7 +218,7 @@ private:
|
||||||
|
|
||||||
size_t m_last_save_undo_index;
|
size_t m_last_save_undo_index;
|
||||||
|
|
||||||
std::vector<BufferIterator*> m_iterators_to_update;
|
std::vector<BufferChangeListener*> m_change_listeners;
|
||||||
|
|
||||||
OptionManager m_option_manager;
|
OptionManager m_option_manager;
|
||||||
HookManager m_hook_manager;
|
HookManager m_hook_manager;
|
||||||
|
|
|
@ -54,18 +54,28 @@ void Selection::merge_with(const Selection& selection)
|
||||||
m_last = selection.m_last;
|
m_last = selection.m_last;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Selection::on_insert(const BufferIterator& begin, const BufferIterator& end)
|
||||||
|
{
|
||||||
|
m_first.on_insert(begin.coord(), end.coord());
|
||||||
|
m_last.on_insert(begin.coord(), end.coord());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Selection::on_erase(const BufferIterator& begin, const BufferIterator& end)
|
||||||
|
{
|
||||||
|
m_first.on_erase(begin.coord(), end.coord());
|
||||||
|
m_last.on_erase(begin.coord(), end.coord());
|
||||||
|
}
|
||||||
|
|
||||||
void Selection::register_with_buffer()
|
void Selection::register_with_buffer()
|
||||||
{
|
{
|
||||||
Buffer& buffer = const_cast<Buffer&>(m_first.buffer());
|
Buffer& buffer = const_cast<Buffer&>(m_first.buffer());
|
||||||
buffer.add_iterator_to_update(m_first);
|
buffer.add_change_listener(*this);
|
||||||
buffer.add_iterator_to_update(m_last);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Selection::unregister_with_buffer()
|
void Selection::unregister_with_buffer()
|
||||||
{
|
{
|
||||||
Buffer& buffer = const_cast<Buffer&>(m_first.buffer());
|
Buffer& buffer = const_cast<Buffer&>(m_first.buffer());
|
||||||
buffer.remove_iterator_from_update(m_first);
|
buffer.remove_change_listener(*this);
|
||||||
buffer.remove_iterator_from_update(m_last);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace Kakoune
|
||||||
// Selections are oriented, first may be > last, and inclusive.
|
// Selections are oriented, first may be > last, and inclusive.
|
||||||
// Selection updates it's iterators according to modifications made
|
// Selection updates it's iterators according to modifications made
|
||||||
// in the buffer.
|
// in the buffer.
|
||||||
struct Selection
|
struct Selection : public BufferChangeListener
|
||||||
{
|
{
|
||||||
Selection(const BufferIterator& first, const BufferIterator& last);
|
Selection(const BufferIterator& first, const BufferIterator& last);
|
||||||
Selection(const Selection& other);
|
Selection(const Selection& other);
|
||||||
|
@ -30,6 +30,9 @@ struct Selection
|
||||||
|
|
||||||
void merge_with(const Selection& selection);
|
void merge_with(const Selection& selection);
|
||||||
|
|
||||||
|
void on_insert(const BufferIterator& begin, const BufferIterator& end);
|
||||||
|
void on_erase(const BufferIterator& begin, const BufferIterator& end);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BufferIterator m_first;
|
BufferIterator m_first;
|
||||||
BufferIterator m_last;
|
BufferIterator m_last;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user