Buffer::do_{erase,insert} takes coord parameters rather than iterators

BufferChangeListeners do as well use coord rather than iterators
This commit is contained in:
Maxime Coste 2013-05-22 19:21:59 +02:00
parent f23f48172f
commit 6c290eff9a
6 changed files with 61 additions and 65 deletions

View File

@ -445,25 +445,25 @@ void Buffer::check_invariant() const
#endif #endif
} }
void Buffer::do_insert(const BufferIterator& pos, const String& content) void Buffer::do_insert(const BufferCoord& pos, const String& content)
{ {
kak_assert(pos.is_valid()); kak_assert(is_valid(pos));
if (content.empty()) if (content.empty())
return; return;
++m_timestamp; ++m_timestamp;
ByteCount offset = pos.offset(); ByteCount offset = this->offset(pos);
// all following lines advanced by length // all following lines advanced by length
for (LineCount i = pos.line()+1; i < line_count(); ++i) for (LineCount i = pos.line+1; i < line_count(); ++i)
m_lines[i].start += content.length(); m_lines[i].start += content.length();
BufferIterator begin_it; BufferCoord begin;
BufferIterator end_it; BufferCoord end;
// 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 (pos.is_end()) if (is_end(pos))
{ {
ByteCount start = 0; ByteCount start = 0;
for (ByteCount i = 0; i < content.length(); ++i) for (ByteCount i = 0; i < content.length(); ++i)
@ -477,13 +477,13 @@ void Buffer::do_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) });
begin_it = pos.column() == 0 ? pos : BufferIterator{*this, { pos.line() + 1, 0 }}; begin = pos.column == 0 ? pos : BufferCoord{ pos.line + 1, 0 };
end_it = end(); end = this->end().coord();
} }
else else
{ {
String prefix = m_lines[pos.line()].content.substr(0, pos.column()); String prefix = m_lines[pos.line].content.substr(0, pos.column);
String suffix = m_lines[pos.line()].content.substr(pos.column()); String suffix = m_lines[pos.line].content.substr(pos.column);
std::vector<Line> new_lines; std::vector<Line> new_lines;
@ -509,40 +509,40 @@ void Buffer::do_insert(const BufferIterator& pos, const String& content)
else if (start != content.length() or not suffix.empty()) else if (start != content.length() or not suffix.empty())
new_lines.push_back({ offset + start, content.substr(start) + suffix }); new_lines.push_back({ offset + start, content.substr(start) + suffix });
LineCount last_line = pos.line() + new_lines.size() - 1; LineCount last_line = pos.line + new_lines.size() - 1;
auto line_it = m_lines.begin() + (int)pos.line(); auto line_it = m_lines.begin() + (int)pos.line;
*line_it = std::move(*new_lines.begin()); *line_it = std::move(*new_lines.begin());
m_lines.insert(line_it+1, std::make_move_iterator(new_lines.begin() + 1), m_lines.insert(line_it+1, std::make_move_iterator(new_lines.begin() + 1),
std::make_move_iterator(new_lines.end())); std::make_move_iterator(new_lines.end()));
begin_it = pos; begin = pos;
end_it = BufferIterator{*this, { last_line, m_lines[last_line].length() - suffix.length() }}; end = BufferCoord{ last_line, m_lines[last_line].length() - suffix.length() };
} }
for (auto listener : m_change_listeners) for (auto listener : m_change_listeners)
listener->on_insert(begin_it, end_it); listener->on_insert(begin, end);
} }
void Buffer::do_erase(const BufferIterator& begin, const BufferIterator& end) void Buffer::do_erase(const BufferCoord& begin, const BufferCoord& end)
{ {
kak_assert(begin.is_valid()); kak_assert(is_valid(begin));
kak_assert(end.is_valid()); kak_assert(is_valid(end));
++m_timestamp; ++m_timestamp;
const ByteCount length = end - begin; const ByteCount length = distance(begin, end);
String prefix = m_lines[begin.line()].content.substr(0, begin.column()); String prefix = m_lines[begin.line].content.substr(0, begin.column);
String suffix = m_lines[end.line()].content.substr(end.column()); String suffix = m_lines[end.line].content.substr(end.column);
Line new_line = { m_lines[begin.line()].start, prefix + suffix }; Line new_line = { m_lines[begin.line].start, prefix + suffix };
if (new_line.length() != 0) if (new_line.length() != 0)
{ {
m_lines.erase(m_lines.begin() + (int)begin.line(), m_lines.begin() + (int)end.line()); m_lines.erase(m_lines.begin() + (int)begin.line, m_lines.begin() + (int)end.line);
m_lines[begin.line()] = std::move(new_line); m_lines[begin.line] = std::move(new_line);
} }
else else
m_lines.erase(m_lines.begin() + (int)begin.line(), m_lines.begin() + (int)end.line() + 1); m_lines.erase(m_lines.begin() + (int)begin.line, m_lines.begin() + (int)end.line + 1);
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;
for (auto listener : m_change_listeners) for (auto listener : m_change_listeners)
@ -559,20 +559,20 @@ void Buffer::apply_modification(const Modification& modification)
if (coord.line < line_count()-1 and coord.column == m_lines[coord.line].length()) if (coord.line < line_count()-1 and coord.column == m_lines[coord.line].length())
coord = { coord.line + 1, 0 }; coord = { coord.line + 1, 0 };
BufferIterator pos{*this, coord}; kak_assert(is_valid(coord));
switch (modification.type) switch (modification.type)
{ {
case Modification::Insert: case Modification::Insert:
{ {
do_insert(pos, content); do_insert(coord, content);
break; break;
} }
case Modification::Erase: case Modification::Erase:
{ {
ByteCount count = content.length(); ByteCount count = content.length();
BufferIterator end = pos + count; BufferCoord end = advance(coord, count);
kak_assert(string(pos, end) == content); kak_assert(string({*this, coord}, {*this, end}) == content);
do_erase(pos, end); do_erase(coord, end);
break; break;
} }
default: default:
@ -590,7 +590,7 @@ void Buffer::insert(BufferIterator pos, String content)
if (not (m_flags & Flags::NoUndo)) if (not (m_flags & Flags::NoUndo))
m_current_undo_group.emplace_back(Modification::Insert, pos.coord(), content); m_current_undo_group.emplace_back(Modification::Insert, pos.coord(), content);
do_insert(pos, content); do_insert(pos.coord(), content);
} }
void Buffer::erase(BufferIterator begin, BufferIterator end) void Buffer::erase(BufferIterator begin, BufferIterator end)
@ -604,7 +604,7 @@ void Buffer::erase(BufferIterator begin, BufferIterator end)
if (not (m_flags & Flags::NoUndo)) if (not (m_flags & Flags::NoUndo))
m_current_undo_group.emplace_back(Modification::Erase, begin.coord(), m_current_undo_group.emplace_back(Modification::Erase, begin.coord(),
string(begin, end)); string(begin, end));
do_erase(begin, end); do_erase(begin.coord(), end.coord());
} }
bool Buffer::is_modified() const bool Buffer::is_modified() const

View File

@ -80,8 +80,8 @@ private:
class BufferChangeListener class BufferChangeListener
{ {
public: public:
virtual void on_insert(const BufferIterator& begin, const BufferIterator& end) = 0; virtual void on_insert(const BufferCoord& begin, const BufferCoord& end) = 0;
virtual void on_erase(const BufferIterator& begin, const BufferIterator& end) = 0; virtual void on_erase(const BufferCoord& begin, const BufferCoord& end) = 0;
}; };
// A Buffer is a in-memory representation of a file // A Buffer is a in-memory representation of a file
@ -198,8 +198,8 @@ private:
}; };
LineList m_lines; LineList m_lines;
void do_insert(const BufferIterator& pos, const String& content); void do_insert(const BufferCoord& pos, const String& content);
void do_erase(const BufferIterator& begin, const BufferIterator& end); void do_erase(const BufferCoord& begin, const BufferCoord& end);
String m_name; String m_name;
Flags m_flags; Flags m_flags;

View File

@ -29,14 +29,14 @@ void DynamicSelectionList::check_invariant() const
#endif #endif
} }
void DynamicSelectionList::on_insert(const BufferIterator& begin, const BufferIterator& end) void DynamicSelectionList::on_insert(const BufferCoord& begin, const BufferCoord& end)
{ {
update_insert(begin.coord(), end.coord()); update_insert(begin, end);
} }
void DynamicSelectionList::on_erase(const BufferIterator& begin, const BufferIterator& end) void DynamicSelectionList::on_erase(const BufferCoord& begin, const BufferCoord& end)
{ {
update_erase(begin.coord(), end.coord()); update_erase(begin, end);
} }
} }

View File

@ -19,10 +19,8 @@ public:
void check_invariant() const; void check_invariant() const;
private: private:
void on_insert(const BufferIterator& begin, void on_insert(const BufferCoord& begin, const BufferCoord& end) override;
const BufferIterator& end) override; void on_erase(const BufferCoord& begin, const BufferCoord& end) override;
void on_erase(const BufferIterator& begin,
const BufferIterator& end) override;
}; };
} }

View File

@ -367,28 +367,26 @@ public:
ModifiedRangesListener(Buffer& buffer) ModifiedRangesListener(Buffer& buffer)
: BufferChangeListener_AutoRegister(buffer) {} : BufferChangeListener_AutoRegister(buffer) {}
void on_insert(const BufferIterator& begin, const BufferIterator& end) void on_insert(const BufferCoord& begin, const BufferCoord& end)
{ {
kak_assert(begin.is_valid()); m_ranges.update_insert(begin, end);
kak_assert(end.is_valid());
m_ranges.update_insert(begin.coord(), end.coord());
auto it = std::upper_bound(m_ranges.begin(), m_ranges.end(), begin, auto it = std::upper_bound(m_ranges.begin(), m_ranges.end(), begin,
[](const BufferIterator& it, const Selection& sel) [](const BufferCoord& c, const Selection& sel)
{ return it < sel.begin(); }); { return c < sel.begin().coord(); });
m_ranges.emplace(it, begin, utf8::previous(end)); m_ranges.emplace(it, registry().iterator_at(begin),
utf8::previous(registry().iterator_at(end)));
} }
void on_erase(const BufferIterator& begin, const BufferIterator& end) void on_erase(const BufferCoord& begin, const BufferCoord& end)
{ {
kak_assert(begin.is_valid()); m_ranges.update_erase(begin, end);
m_ranges.update_erase(begin.coord(), end.coord()); BufferIterator pos{registry(), begin};
auto pos = begin;
if (pos >= buffer().end()) if (pos >= buffer().end())
pos = utf8::previous(buffer().end()); pos = utf8::previous(buffer().end());
auto it = std::upper_bound(m_ranges.begin(), m_ranges.end(), begin, auto it = std::upper_bound(m_ranges.begin(), m_ranges.end(), begin,
[](const BufferIterator& it, const Selection& sel) [](const BufferCoord& c, const Selection& sel)
{ return it < sel.begin(); }); { return c < sel.begin().coord(); });
m_ranges.emplace(it, pos, pos); m_ranges.emplace(it, pos, pos);
} }
SelectionList& ranges() { return m_ranges; } SelectionList& ranges() { return m_ranges; }

View File

@ -383,31 +383,31 @@ private:
m_option->get<std::vector<LineAndFlag>>(); m_option->get<std::vector<LineAndFlag>>();
} }
void on_insert(const BufferIterator& begin, const BufferIterator& end) override void on_insert(const BufferCoord& begin, const BufferCoord& end) override
{ {
LineCount new_lines = end.line() - begin.line(); LineCount new_lines = end.line - begin.line;
if (new_lines == 0) if (new_lines == 0)
return; return;
auto lines = m_option->get<std::vector<LineAndFlag>>(); auto lines = m_option->get<std::vector<LineAndFlag>>();
for (auto& line : lines) for (auto& line : lines)
{ {
if (std::get<0>(line) > begin.line()) if (std::get<0>(line) > begin.line)
std::get<0>(line) += new_lines; std::get<0>(line) += new_lines;
} }
m_option->set(lines); m_option->set(lines);
} }
void on_erase(const BufferIterator& begin, const BufferIterator& end) override void on_erase(const BufferCoord& begin, const BufferCoord& end) override
{ {
LineCount removed_lines = end.line() - begin.line(); LineCount removed_lines = end.line - begin.line;
if (removed_lines == 0) if (removed_lines == 0)
return; return;
auto lines = m_option->get<std::vector<LineAndFlag>>(); auto lines = m_option->get<std::vector<LineAndFlag>>();
for (auto& line : lines) for (auto& line : lines)
{ {
if (std::get<0>(line) > begin.line()) if (std::get<0>(line) > begin.line)
std::get<0>(line) -= removed_lines; std::get<0>(line) -= removed_lines;
} }
m_option->set(lines); m_option->set(lines);