mirror of
https://github.com/mawww/kakoune.git
synced 2024-12-25 04:24:48 +03:00
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();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -78,7 +78,7 @@ void Buffer::reload(std::vector<String> lines, time_t fs_timestamp)
|
||||
for (auto listener : m_change_listeners)
|
||||
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_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_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)
|
||||
listener->on_insert(*this, {0,0}, back_coord());
|
||||
@ -459,6 +459,7 @@ ByteCoord Buffer::do_insert(ByteCoord pos, const String& content)
|
||||
|
||||
ByteCoord begin;
|
||||
ByteCoord end;
|
||||
bool at_end = false;
|
||||
// if we inserted at the end of the buffer, we have created a new
|
||||
// line without inserting a '\n'
|
||||
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 };
|
||||
end = ByteCoord{ line_count()-1, m_lines.back().length() };
|
||||
at_end = true;
|
||||
}
|
||||
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() };
|
||||
}
|
||||
|
||||
m_changes.push_back({ Change::Insert, begin, end });
|
||||
m_changes.push_back({ Change::Insert, begin, end, at_end });
|
||||
for (auto listener : m_change_listeners)
|
||||
listener->on_insert(*this, begin, end);
|
||||
return begin;
|
||||
@ -550,7 +552,7 @@ ByteCoord Buffer::do_erase(ByteCoord begin, ByteCoord end)
|
||||
for (LineCount i = begin.line+1; i < line_count(); ++i)
|
||||
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)
|
||||
listener->on_erase(*this, begin, end);
|
||||
return next;
|
||||
|
@ -182,6 +182,7 @@ public:
|
||||
Type type;
|
||||
ByteCoord begin;
|
||||
ByteCoord end;
|
||||
bool at_end;
|
||||
};
|
||||
memoryview<Change> changes_since(size_t timestamp) const;
|
||||
private:
|
||||
|
@ -1,12 +1,57 @@
|
||||
#include "line_change_watcher.hh"
|
||||
|
||||
#include "buffer.hh"
|
||||
|
||||
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> 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,
|
||||
[](const LineCount& l, const LineModification& c)
|
||||
@ -58,28 +103,8 @@ std::vector<LineModification> LineChangeWatcher::compute_modifications()
|
||||
it->new_line -= num_removed;
|
||||
}
|
||||
}
|
||||
m_changes.clear();
|
||||
m_timestamp = m_buffer->timestamp();
|
||||
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
|
||||
#define line_change_watcher_hh_INCLUDED
|
||||
|
||||
#include "buffer.hh"
|
||||
#include "units.hh"
|
||||
#include "utils.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
class Buffer;
|
||||
|
||||
struct LineModification
|
||||
{
|
||||
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; }
|
||||
};
|
||||
|
||||
class LineChangeWatcher : public BufferChangeListener_AutoRegister
|
||||
class LineChangeWatcher
|
||||
{
|
||||
public:
|
||||
LineChangeWatcher (const Buffer& buffer)
|
||||
: BufferChangeListener_AutoRegister(const_cast<Buffer&>(buffer)) {}
|
||||
LineChangeWatcher (const Buffer& buffer);
|
||||
|
||||
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
|
||||
{
|
||||
LineCount pos;
|
||||
LineCount num;
|
||||
};
|
||||
std::vector<Change> m_changes;
|
||||
const Buffer& buffer() const { return *m_buffer; }
|
||||
private:
|
||||
safe_ptr<const Buffer> m_buffer;
|
||||
size_t m_timestamp;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ void WordDB::update_db()
|
||||
if (modifs.empty())
|
||||
return;
|
||||
|
||||
auto& buffer = m_change_watcher.registry();
|
||||
auto& buffer = m_change_watcher.buffer();
|
||||
|
||||
LineToWords new_lines;
|
||||
new_lines.reserve((int)buffer.line_count());
|
||||
|
Loading…
Reference in New Issue
Block a user