LineChangeWatcher uses Buffer::changes_since rather than listening
This commit is contained in:
parent
a510276025
commit
ddd8f8d392
|
@ -39,7 +39,7 @@ Buffer::Buffer(String name, Flags flags, std::vector<String> lines,
|
||||||
pos += m_lines.back().length();
|
pos += m_lines.back().length();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_changes.push_back({ Change::Insert, {0,0}, line_count() });
|
m_changes.push_back({ Change::Insert, {0,0}, line_count(), true });
|
||||||
|
|
||||||
if (flags & Flags::File)
|
if (flags & Flags::File)
|
||||||
{
|
{
|
||||||
|
@ -78,7 +78,7 @@ void Buffer::reload(std::vector<String> lines, time_t fs_timestamp)
|
||||||
for (auto listener : m_change_listeners)
|
for (auto listener : m_change_listeners)
|
||||||
listener->on_erase(*this, {0,0}, back_coord());
|
listener->on_erase(*this, {0,0}, back_coord());
|
||||||
|
|
||||||
m_changes.push_back({ Change::Erase, {0,0}, back_coord() });
|
m_changes.push_back({ Change::Erase, {0,0}, back_coord(), true });
|
||||||
|
|
||||||
m_history.clear();
|
m_history.clear();
|
||||||
m_current_undo_group.clear();
|
m_current_undo_group.clear();
|
||||||
|
@ -99,7 +99,7 @@ void Buffer::reload(std::vector<String> lines, time_t fs_timestamp)
|
||||||
}
|
}
|
||||||
m_fs_timestamp = fs_timestamp;
|
m_fs_timestamp = fs_timestamp;
|
||||||
|
|
||||||
m_changes.push_back({ Change::Insert, {0,0}, back_coord() });
|
m_changes.push_back({ Change::Insert, {0,0}, back_coord(), true });
|
||||||
|
|
||||||
for (auto listener : m_change_listeners)
|
for (auto listener : m_change_listeners)
|
||||||
listener->on_insert(*this, {0,0}, back_coord());
|
listener->on_insert(*this, {0,0}, back_coord());
|
||||||
|
@ -459,6 +459,7 @@ ByteCoord Buffer::do_insert(ByteCoord pos, const String& content)
|
||||||
|
|
||||||
ByteCoord begin;
|
ByteCoord begin;
|
||||||
ByteCoord end;
|
ByteCoord end;
|
||||||
|
bool at_end = false;
|
||||||
// if we inserted at the end of the buffer, we have created a new
|
// if we inserted at the end of the buffer, we have created a new
|
||||||
// line without inserting a '\n'
|
// line without inserting a '\n'
|
||||||
if (is_end(pos))
|
if (is_end(pos))
|
||||||
|
@ -477,6 +478,7 @@ ByteCoord Buffer::do_insert(ByteCoord pos, const String& content)
|
||||||
|
|
||||||
begin = pos.column == 0 ? pos : ByteCoord{ pos.line + 1, 0 };
|
begin = pos.column == 0 ? pos : ByteCoord{ pos.line + 1, 0 };
|
||||||
end = ByteCoord{ line_count()-1, m_lines.back().length() };
|
end = ByteCoord{ line_count()-1, m_lines.back().length() };
|
||||||
|
at_end = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -519,7 +521,7 @@ ByteCoord Buffer::do_insert(ByteCoord pos, const String& content)
|
||||||
end = ByteCoord{ last_line, m_lines[last_line].length() - suffix.length() };
|
end = ByteCoord{ last_line, m_lines[last_line].length() - suffix.length() };
|
||||||
}
|
}
|
||||||
|
|
||||||
m_changes.push_back({ Change::Insert, begin, end });
|
m_changes.push_back({ Change::Insert, begin, end, at_end });
|
||||||
for (auto listener : m_change_listeners)
|
for (auto listener : m_change_listeners)
|
||||||
listener->on_insert(*this, begin, end);
|
listener->on_insert(*this, begin, end);
|
||||||
return begin;
|
return begin;
|
||||||
|
@ -550,7 +552,7 @@ ByteCoord Buffer::do_erase(ByteCoord begin, ByteCoord end)
|
||||||
for (LineCount i = begin.line+1; i < line_count(); ++i)
|
for (LineCount i = begin.line+1; i < line_count(); ++i)
|
||||||
m_lines[i].start -= length;
|
m_lines[i].start -= length;
|
||||||
|
|
||||||
m_changes.push_back({ Change::Erase, begin, end });
|
m_changes.push_back({ Change::Erase, begin, end, is_end(begin) });
|
||||||
for (auto listener : m_change_listeners)
|
for (auto listener : m_change_listeners)
|
||||||
listener->on_erase(*this, begin, end);
|
listener->on_erase(*this, begin, end);
|
||||||
return next;
|
return next;
|
||||||
|
|
|
@ -182,6 +182,7 @@ public:
|
||||||
Type type;
|
Type type;
|
||||||
ByteCoord begin;
|
ByteCoord begin;
|
||||||
ByteCoord end;
|
ByteCoord end;
|
||||||
|
bool at_end;
|
||||||
};
|
};
|
||||||
memoryview<Change> changes_since(size_t timestamp) const;
|
memoryview<Change> changes_since(size_t timestamp) const;
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1,12 +1,57 @@
|
||||||
#include "line_change_watcher.hh"
|
#include "line_change_watcher.hh"
|
||||||
|
|
||||||
|
#include "buffer.hh"
|
||||||
|
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
struct Change
|
||||||
|
{
|
||||||
|
LineCount pos;
|
||||||
|
LineCount num;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<Change> compute_changes(const Buffer& buffer, size_t timestamp)
|
||||||
|
{
|
||||||
|
std::vector<Change> res;
|
||||||
|
for (auto& change : buffer.changes_since(timestamp))
|
||||||
|
{
|
||||||
|
ByteCoord begin = change.begin;
|
||||||
|
ByteCoord end = change.end;
|
||||||
|
if (change.type == Buffer::Change::Insert)
|
||||||
|
{
|
||||||
|
if (change.at_end and begin != ByteCoord{0,0})
|
||||||
|
{
|
||||||
|
kak_assert(begin.column == 0);
|
||||||
|
--begin.line;
|
||||||
|
}
|
||||||
|
res.push_back({begin.line, end.line - begin.line});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (change.at_end and begin != ByteCoord{0,0})
|
||||||
|
{
|
||||||
|
kak_assert(begin.column == 0);
|
||||||
|
--begin.line;
|
||||||
|
}
|
||||||
|
res.push_back({begin.line, begin.line - end.line});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
LineChangeWatcher::LineChangeWatcher(const Buffer& buffer)
|
||||||
|
: m_buffer(&buffer), m_timestamp(buffer.timestamp()) {}
|
||||||
|
|
||||||
std::vector<LineModification> LineChangeWatcher::compute_modifications()
|
std::vector<LineModification> LineChangeWatcher::compute_modifications()
|
||||||
{
|
{
|
||||||
std::vector<LineModification> res;
|
std::vector<LineModification> res;
|
||||||
for (auto& change : m_changes)
|
for (auto& change : compute_changes(*m_buffer, m_timestamp))
|
||||||
{
|
{
|
||||||
auto pos = std::upper_bound(res.begin(), res.end(), change.pos,
|
auto pos = std::upper_bound(res.begin(), res.end(), change.pos,
|
||||||
[](const LineCount& l, const LineModification& c)
|
[](const LineCount& l, const LineModification& c)
|
||||||
|
@ -58,28 +103,8 @@ std::vector<LineModification> LineChangeWatcher::compute_modifications()
|
||||||
it->new_line -= num_removed;
|
it->new_line -= num_removed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_changes.clear();
|
m_timestamp = m_buffer->timestamp();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LineChangeWatcher::on_insert(const Buffer& buffer, ByteCoord begin, ByteCoord end)
|
|
||||||
{
|
|
||||||
if (buffer.is_end(end))
|
|
||||||
{
|
|
||||||
kak_assert(begin.column == 0);
|
|
||||||
--begin.line;
|
|
||||||
}
|
|
||||||
m_changes.push_back({begin.line, end.line - begin.line});
|
|
||||||
}
|
|
||||||
|
|
||||||
void LineChangeWatcher::on_erase(const Buffer& buffer, ByteCoord begin, ByteCoord end)
|
|
||||||
{
|
|
||||||
if (begin.line == buffer.line_count())
|
|
||||||
{
|
|
||||||
kak_assert(begin.column == 0);
|
|
||||||
--begin.line;
|
|
||||||
}
|
|
||||||
m_changes.push_back({begin.line, begin.line - end.line});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
#ifndef line_change_watcher_hh_INCLUDED
|
#ifndef line_change_watcher_hh_INCLUDED
|
||||||
#define line_change_watcher_hh_INCLUDED
|
#define line_change_watcher_hh_INCLUDED
|
||||||
|
|
||||||
#include "buffer.hh"
|
#include "units.hh"
|
||||||
|
#include "utils.hh"
|
||||||
|
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class Buffer;
|
||||||
|
|
||||||
struct LineModification
|
struct LineModification
|
||||||
{
|
{
|
||||||
LineCount old_line; // line position in the old buffer
|
LineCount old_line; // line position in the old buffer
|
||||||
|
@ -16,23 +19,17 @@ struct LineModification
|
||||||
LineCount diff() const { return new_line - old_line + num_added - num_removed; }
|
LineCount diff() const { return new_line - old_line + num_added - num_removed; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class LineChangeWatcher : public BufferChangeListener_AutoRegister
|
class LineChangeWatcher
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LineChangeWatcher (const Buffer& buffer)
|
LineChangeWatcher (const Buffer& buffer);
|
||||||
: BufferChangeListener_AutoRegister(const_cast<Buffer&>(buffer)) {}
|
|
||||||
|
|
||||||
std::vector<LineModification> compute_modifications();
|
std::vector<LineModification> compute_modifications();
|
||||||
private:
|
|
||||||
void on_insert(const Buffer& buffer, ByteCoord begin, ByteCoord end) override;
|
|
||||||
void on_erase(const Buffer& buffer, ByteCoord begin, ByteCoord end) override;
|
|
||||||
|
|
||||||
struct Change
|
const Buffer& buffer() const { return *m_buffer; }
|
||||||
{
|
private:
|
||||||
LineCount pos;
|
safe_ptr<const Buffer> m_buffer;
|
||||||
LineCount num;
|
size_t m_timestamp;
|
||||||
};
|
|
||||||
std::vector<Change> m_changes;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ void WordDB::update_db()
|
||||||
if (modifs.empty())
|
if (modifs.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto& buffer = m_change_watcher.registry();
|
auto& buffer = m_change_watcher.buffer();
|
||||||
|
|
||||||
LineToWords new_lines;
|
LineToWords new_lines;
|
||||||
new_lines.reserve((int)buffer.line_count());
|
new_lines.reserve((int)buffer.line_count());
|
||||||
|
|
Loading…
Reference in New Issue
Block a user