From 4e34f777b0001afb995f1840e6f8c049fcb3d4b4 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Tue, 14 Aug 2012 14:13:10 +0200 Subject: [PATCH] Buffer: stronger invariant, a buffer is never empty and all lines finish by '\n' --- src/buffer.cc | 19 +++++++++++++++---- src/buffer.hh | 4 ++-- src/file.cc | 4 ++++ 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/buffer.cc b/src/buffer.cc index 7b6e8caa..7c643dd5 100644 --- a/src/buffer.cc +++ b/src/buffer.cc @@ -30,8 +30,10 @@ Buffer::Buffer(String name, Type type, m_option_manager(GlobalOptionManager::instance()) { BufferManager::instance().register_buffer(*this); - if (not initial_content.empty()) - do_insert(begin(), std::move(initial_content)); + if (initial_content.back() != '\n') + initial_content += '\n'; + do_insert(begin(), std::move(initial_content)); + Editor editor_for_hooks(*this); Context context(editor_for_hooks); @@ -219,10 +221,12 @@ void Buffer::reset_undo_data() void Buffer::check_invariant() const { BufferSize start = 0; + assert(not m_lines.empty()); for (auto& line : m_lines) { assert(line.start == start); assert(line.length() > 0); + assert(line.content.back() == '\n'); 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()) return; + + if (pos.is_end()) + --pos; + m_current_undo_group.emplace_back(Modification::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) return; diff --git a/src/buffer.hh b/src/buffer.hh index 53523fae..cc20a607 100644 --- a/src/buffer.hh +++ b/src/buffer.hh @@ -111,8 +111,8 @@ public: Type type() const { return m_type; } - void insert(const BufferIterator& pos, const String& content); - void erase(const BufferIterator& begin, const BufferIterator& end); + void insert(BufferIterator pos, const String& content); + void erase(BufferIterator begin, BufferIterator end); void begin_undo_group(); void end_undo_group(); diff --git a/src/file.cc b/src/file.cc index 3fd7e586..fcba92c2 100644 --- a/src/file.cc +++ b/src/file.cc @@ -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("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 buffer->reset_undo_data();