diff --git a/src/core/Buffer.cc b/src/core/Buffer.cc index 6e2f66c..fe47b15 100644 --- a/src/core/Buffer.cc +++ b/src/core/Buffer.cc @@ -24,6 +24,7 @@ void Buffer::load_empty_buffer() { m_gap_buffer = std::make_shared(Encoding::UTF_8); m_eol_at_eof = true; + m_line_endings = LineEndings::LF; } bool Buffer::load_from_file(const char * filename) @@ -59,6 +60,7 @@ bool Buffer::load_from_file(const char * filename) m_gap_buffer = std::make_shared(buffer, buffer_size, loaded_size, text_loader.get_encoding()); m_eol_at_eof = text_loader.get_eol_at_eof(); + m_line_endings = text_loader.get_line_endings(); return true; } @@ -71,7 +73,39 @@ bool Buffer::write_to_file(const char * filename) return false; } - /* TODO */ + m_gap_buffer->compact(); + + GapBuffer::Cursor start_of_line(&*m_gap_buffer); + size_t bytes_written = 0u; + + while (start_of_line.valid()) + { + GapBuffer::Cursor cursor = start_of_line; + cursor.go_end_of_line(true); + size_t len = cursor.address() - start_of_line.address(); + if (len > 0u) + { + if (!file.write(start_of_line.address(), len)) + { + return false; + } + bytes_written += len; + } + bool moved_down = cursor.go_down(0u); + if (moved_down || m_eol_at_eof) + { + if (!file.write(LineEndings::spans[m_line_endings])) + { + return false; + } + bytes_written += LineEndings::spans[m_line_endings].length; + } + if (!moved_down) + { + break; + } + start_of_line = cursor; + } return true; } diff --git a/src/core/Buffer.h b/src/core/Buffer.h index 1eab87e..edc51e9 100644 --- a/src/core/Buffer.h +++ b/src/core/Buffer.h @@ -15,6 +15,7 @@ public: protected: bool m_eol_at_eof; + LineEndings::Type m_line_endings; std::shared_ptr m_gap_buffer; bool load_from_file(const char * filename); diff --git a/src/core/GapBuffer.cc b/src/core/GapBuffer.cc index d38d58f..7199d20 100644 --- a/src/core/GapBuffer.cc +++ b/src/core/GapBuffer.cc @@ -153,14 +153,14 @@ bool GapBuffer::Cursor::go_start_of_line() return moved; } -bool GapBuffer::Cursor::go_end_of_line() +bool GapBuffer::Cursor::go_end_of_line(bool allow_eol) { bool moved = false; - if (go_right(false)) + if (go_right(allow_eol)) { moved = true; } - while (go_right(false)) + while (go_right(allow_eol)) { ; } @@ -230,7 +230,7 @@ bool GapBuffer::Cursor::go_up(size_t target_column) bool GapBuffer::Cursor::go_down(size_t target_column) { Cursor c2 = *this; - c2.go_end_of_line(); + c2.go_end_of_line(true); if (!c2.m_iterator.check_go_forward()) { return false; diff --git a/src/core/GapBuffer.h b/src/core/GapBuffer.h index e5f80a3..6df18a2 100644 --- a/src/core/GapBuffer.h +++ b/src/core/GapBuffer.h @@ -64,7 +64,7 @@ public: bool is_start_of_line(); bool is_end_of_line(bool allow_eol); bool go_start_of_line(); - bool go_end_of_line(); + bool go_end_of_line(bool allow_eol); bool go_left(); bool go_right(bool allow_eol); bool go_up(size_t target_column); @@ -75,6 +75,7 @@ public: } uint32_t operator*() const { return *m_iterator; } uint8_t * address() const { return m_iterator.address(); } + bool valid() const { return m_iterator.valid(); } protected: Iterator m_iterator;