Buffer: stronger invariant, a buffer is never empty and all lines finish by '\n'

This commit is contained in:
Maxime Coste 2012-08-14 14:13:10 +02:00
parent 25899f33cd
commit 4e34f777b0
3 changed files with 21 additions and 6 deletions

View File

@ -30,8 +30,10 @@ Buffer::Buffer(String name, Type type,
m_option_manager(GlobalOptionManager::instance()) m_option_manager(GlobalOptionManager::instance())
{ {
BufferManager::instance().register_buffer(*this); BufferManager::instance().register_buffer(*this);
if (not initial_content.empty()) if (initial_content.back() != '\n')
do_insert(begin(), std::move(initial_content)); initial_content += '\n';
do_insert(begin(), std::move(initial_content));
Editor editor_for_hooks(*this); Editor editor_for_hooks(*this);
Context context(editor_for_hooks); Context context(editor_for_hooks);
@ -219,10 +221,12 @@ void Buffer::reset_undo_data()
void Buffer::check_invariant() const void Buffer::check_invariant() const
{ {
BufferSize start = 0; BufferSize start = 0;
assert(not m_lines.empty());
for (auto& line : m_lines) for (auto& line : m_lines)
{ {
assert(line.start == start); assert(line.start == start);
assert(line.length() > 0); assert(line.length() > 0);
assert(line.content.back() == '\n');
start += line.length(); start += line.length();
} }
} }
@ -349,16 +353,23 @@ void Buffer::apply_modification(const Modification& modification)
} }
} }
void Buffer::insert(const BufferIterator& pos, const String& content) void Buffer::insert(BufferIterator pos, const String& content)
{ {
if (content.empty()) if (content.empty())
return; return;
if (pos.is_end())
--pos;
m_current_undo_group.emplace_back(Modification::Insert, pos, content); m_current_undo_group.emplace_back(Modification::Insert, pos, content);
do_insert(pos, content); do_insert(pos, content);
} }
void Buffer::erase(const BufferIterator& begin, const BufferIterator& end) void Buffer::erase(BufferIterator begin, BufferIterator end)
{ {
if (end.is_end() and (begin.column() != 0 or begin.is_begin()))
--end;
if (begin == end) if (begin == end)
return; return;

View File

@ -111,8 +111,8 @@ public:
Type type() const { return m_type; } Type type() const { return m_type; }
void insert(const BufferIterator& pos, const String& content); void insert(BufferIterator pos, const String& content);
void erase(const BufferIterator& begin, const BufferIterator& end); void erase(BufferIterator begin, BufferIterator end);
void begin_undo_group(); void begin_undo_group();
void end_undo_group(); void end_undo_group();

View File

@ -130,6 +130,10 @@ Buffer* create_buffer_from_file(const String& filename)
option_manager.set_option("eolformat", Option(crlf ? "crlf" : "lf")); option_manager.set_option("eolformat", Option(crlf ? "crlf" : "lf"));
option_manager.set_option("BOM", Option(bom ? "utf-8" : "no")); option_manager.set_option("BOM", Option(bom ? "utf-8" : "no"));
// if the file ended with a \n, remove the \n added by the buffer
if (*(buffer->end() - 2) == '\n')
buffer->erase(buffer->end() - 1, buffer->end());
// it never happened, buffer always was like that // it never happened, buffer always was like that
buffer->reset_undo_data(); buffer->reset_undo_data();