diff --git a/src/core/Buffer.cc b/src/core/Buffer.cc index de0b4dc..07606dd 100644 --- a/src/core/Buffer.cc +++ b/src/core/Buffer.cc @@ -39,6 +39,8 @@ void Buffer::common_initialization() m_eof_iterator->go_forward(); } m_change_buffer = std::make_shared(); + m_operation_level = 0; + m_current_operation_index = 0u; } void Buffer::load_empty_buffer() @@ -157,15 +159,18 @@ bool Buffer::write_to_file(const char * filename) void Buffer::enter_insert_mode() { m_insert_mode = true; + push_operation(); } void Buffer::exit_insert_mode() { m_insert_mode = false; + pop_operation(); } void Buffer::insert_code_point(const Buffer::Iterator & position, uint32_t code_point, bool adjust_iterators) { + push_operation(); Buffer::Iterator local_position = position; if ((code_point != '\n') && (size() == 0u)) { @@ -186,12 +191,14 @@ void Buffer::insert_code_point(const Buffer::Iterator & position, uint32_t code_ } } } + pop_operation(); } void Buffer::erase_code_point(const Buffer::Iterator & position) { if (position.valid()) { + push_operation(); Buffer::Iterator local_position = position; uint8_t bytes = 0u; uint32_t code_point = Encoding::decode(m_encoding, local_position.address(), &bytes); @@ -205,6 +212,19 @@ void Buffer::erase_code_point(const Buffer::Iterator & position) iterator->warp(-(ssize_t)bytes, lines); } } + pop_operation(); + } +} + +void Buffer::pop_operation() +{ + if (m_operation_level > 0) + { + m_operation_level--; + if (m_operation_level == 0) + { + save_current_operation(); + } } } @@ -276,3 +296,18 @@ void Buffer::record_change(uint8_t data[], size_t length, size_t buffer_position cu.insert = insert; m_current_change_operation->changes.push_back(cu); } + +void Buffer::save_current_operation() +{ + if (m_current_change_operation) + { + size_t new_change_operation_index = m_change_operations.size(); + if (m_current_operation_index < new_change_operation_index) + { + m_change_operations[m_current_operation_index]->children.push_back(new_change_operation_index); + } + m_change_operations.push_back(m_current_change_operation); + m_current_change_operation = nullptr; + m_current_operation_index = new_change_operation_index; + } +} diff --git a/src/core/Buffer.h b/src/core/Buffer.h index 180c54a..b650d31 100644 --- a/src/core/Buffer.h +++ b/src/core/Buffer.h @@ -8,6 +8,7 @@ #include "GapBuffer.h" #include #include "ChangeOperation.h" +#include class Buffer { @@ -117,6 +118,8 @@ public: std::string filename() const { return m_filename; } Iterator begin() const { return Iterator(this); } Iterator end() const { return *m_eof_iterator; } + void push_operation() { m_operation_level++; } + void pop_operation(); protected: bool m_eol_at_eof; @@ -130,6 +133,9 @@ protected: std::shared_ptr m_eof_iterator; std::string m_filename; std::shared_ptr m_current_change_operation; + int m_operation_level; + size_t m_current_operation_index; + std::vector> m_change_operations; void common_initialization(); bool load_from_file(const char * filename); @@ -137,6 +143,7 @@ protected: bool load_from_memory(const uint8_t * data, size_t data_length); void load_text_in_buffer(uint8_t * buffer, size_t buffer_size, size_t data_length); void record_change(uint8_t data[], size_t length, size_t buffer_position, bool insert); + void save_current_operation(); }; #endif