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
}
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())
return;
++m_timestamp;
ByteCount offset = pos.offset();
ByteCount offset = this->offset(pos);
// 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();
BufferIterator begin_it;
BufferIterator end_it;
BufferCoord begin;
BufferCoord end;
// if we inserted at the end of the buffer, we have created a new
// line without inserting a '\n'
if (pos.is_end())
if (is_end(pos))
{
ByteCount start = 0;
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())
m_lines.push_back({ offset + start, content.substr(start) });
begin_it = pos.column() == 0 ? pos : BufferIterator{*this, { pos.line() + 1, 0 }};
end_it = end();
begin = pos.column == 0 ? pos : BufferCoord{ pos.line + 1, 0 };
end = this->end().coord();
}
else
{
String prefix = m_lines[pos.line()].content.substr(0, pos.column());
String suffix = m_lines[pos.line()].content.substr(pos.column());
String prefix = m_lines[pos.line].content.substr(0, pos.column);
String suffix = m_lines[pos.line].content.substr(pos.column);
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())
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());
m_lines.insert(line_it+1, std::make_move_iterator(new_lines.begin() + 1),
std::make_move_iterator(new_lines.end()));
begin_it = pos;
end_it = BufferIterator{*this, { last_line, m_lines[last_line].length() - suffix.length() }};
begin = pos;
end = BufferCoord{ last_line, m_lines[last_line].length() - suffix.length() };
}
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(end.is_valid());
kak_assert(is_valid(begin));
kak_assert(is_valid(end));
++m_timestamp;
const ByteCount length = end - begin;
String prefix = m_lines[begin.line()].content.substr(0, begin.column());
String suffix = m_lines[end.line()].content.substr(end.column());
Line new_line = { m_lines[begin.line()].start, prefix + suffix };
const ByteCount length = distance(begin, end);
String prefix = m_lines[begin.line].content.substr(0, begin.column);
String suffix = m_lines[end.line].content.substr(end.column);
Line new_line = { m_lines[begin.line].start, prefix + suffix };
if (new_line.length() != 0)
{
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.erase(m_lines.begin() + (int)begin.line, m_lines.begin() + (int)end.line);
m_lines[begin.line] = std::move(new_line);
}
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;
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())
coord = { coord.line + 1, 0 };
BufferIterator pos{*this, coord};
kak_assert(is_valid(coord));
switch (modification.type)
{
case Modification::Insert:
{
do_insert(pos, content);
do_insert(coord, content);
break;
}
case Modification::Erase:
{
ByteCount count = content.length();
BufferIterator end = pos + count;
kak_assert(string(pos, end) == content);
do_erase(pos, end);
BufferCoord end = advance(coord, count);
kak_assert(string({*this, coord}, {*this, end}) == content);
do_erase(coord, end);
break;
}
default:
@ -590,7 +590,7 @@ void Buffer::insert(BufferIterator pos, String content)
if (not (m_flags & Flags::NoUndo))
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)
@ -604,7 +604,7 @@ void Buffer::erase(BufferIterator begin, BufferIterator end)
if (not (m_flags & Flags::NoUndo))
m_current_undo_group.emplace_back(Modification::Erase, begin.coord(),
string(begin, end));
do_erase(begin, end);
do_erase(begin.coord(), end.coord());
}
bool Buffer::is_modified() const

View File

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

View File

@ -29,14 +29,14 @@ void DynamicSelectionList::check_invariant() const
#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;
private:
void on_insert(const BufferIterator& begin,
const BufferIterator& end) override;
void on_erase(const BufferIterator& begin,
const BufferIterator& end) override;
void on_insert(const BufferCoord& begin, const BufferCoord& end) override;
void on_erase(const BufferCoord& begin, const BufferCoord& end) override;
};
}

View File

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

View File

@ -383,31 +383,31 @@ private:
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)
return;
auto lines = m_option->get<std::vector<LineAndFlag>>();
for (auto& line : lines)
{
if (std::get<0>(line) > begin.line())
if (std::get<0>(line) > begin.line)
std::get<0>(line) += new_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)
return;
auto lines = m_option->get<std::vector<LineAndFlag>>();
for (auto& line : lines)
{
if (std::get<0>(line) > begin.line())
if (std::get<0>(line) > begin.line)
std::get<0>(line) -= removed_lines;
}
m_option->set(lines);