From 99bbe81f6b0eeca1e130fc34f280330c6ddc37c5 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 5 Oct 2016 22:47:08 -0400 Subject: [PATCH] add PieceTable::begin_insert() --- src/core/PieceTable.cc | 69 +++++++++++++++++++++++++++++++++++++++--- src/core/PieceTable.h | 38 ++++++++++++++--------- src/gui/Window.cc | 3 ++ 3 files changed, 90 insertions(+), 20 deletions(-) diff --git a/src/core/PieceTable.cc b/src/core/PieceTable.cc index 2b113c2..eaee9ae 100644 --- a/src/core/PieceTable.cc +++ b/src/core/PieceTable.cc @@ -11,7 +11,7 @@ PieceTable::PieceTable(const uint8_t * file_buffer, unsigned long file_buffer_si m_piece_index = 2u; tabstop = 4u; m_append_buffer_index = 0u; - m_changes_buffer_index = 0u; + m_changes_index = 0u; } void PieceTable::append_initial_line_piece(uint8_t * start, uint32_t length, bool eol) @@ -334,6 +334,65 @@ void PieceTable::Cursor::forward_to_column(uint32_t c) } } +void PieceTable::begin_insert(const Cursor & cursor, bool before) +{ + Piece * piece = cursor.iterator.piece; + uint32_t offset = cursor.iterator.offset; + if (!before && cursor.iterator.has_char()) + { + offset += cursor.iterator.num_bytes_in_code_point(); + } + if (offset == 0u) + { + /* Insert happens at piece boundary between piece->prev and piece. */ + m_insert_before_piece = piece->prev; + } + else if (offset >= piece->length) + { + /* Insert happens at piece boundary between piece and piece->next. */ + m_insert_before_piece = piece; + } + else + { + /* Insert happens in the middle of a current piece. The piece must + * be split up. */ + Piece * new_piece_1 = add_piece(); + new_piece_1->start = piece->start; + new_piece_1->length = offset; + new_piece_1->flags = 0u; + + Piece * new_piece_2 = add_piece(); + new_piece_2->start = piece->start + offset; + new_piece_2->length = piece->length - offset; + new_piece_2->flags = piece->flags; + + new_piece_1->prev = piece->prev; + new_piece_1->next = new_piece_2; + new_piece_2->prev = new_piece_1; + new_piece_2->next = piece->next; + + Change * change = add_change(); + change->links[0][0][0] = piece->prev; + change->links[0][0][1] = piece; + change->links[0][1][0] = piece; + change->links[0][1][1] = piece->next; + change->links[1][0][0] = piece->prev; + change->links[1][0][1] = new_piece_1; + change->links[1][1][0] = new_piece_2; + change->links[1][1][1] = piece->next; + + apply_change(change, 1u); + } +} + +void PieceTable::insert_code_point(uint32_t code_point) +{ +} + +void PieceTable::end_insert() +{ +} + void PieceTable::insertion_test(Cursor & c) { Piece * piece = add_piece(); @@ -344,7 +403,7 @@ void PieceTable::insertion_test(Cursor & c) m_append_buffer[m_append_buffer_index++] = 'y'; m_append_buffer[m_append_buffer_index++] = 'z'; - Change * change = &m_changes_buffer[m_changes_buffer_index++]; + Change * change = &m_changes[m_changes_index++]; if (c.iterator.valid()) { @@ -412,10 +471,10 @@ void PieceTable::insertion_test(Cursor & c) void PieceTable::undo() { - if (m_changes_buffer_index > 0u) + if (m_changes_index > 0u) { - m_changes_buffer_index--; - apply_change(&m_changes_buffer[m_changes_buffer_index], 0u); + m_changes_index--; + apply_change(&m_changes[m_changes_index], 0u); } } diff --git a/src/core/PieceTable.h b/src/core/PieceTable.h index 9c9494c..af385da 100644 --- a/src/core/PieceTable.h +++ b/src/core/PieceTable.h @@ -145,6 +145,20 @@ public: PieceTable(const uint8_t * file_buffer, unsigned long file_buffer_size); + uint32_t get_num_lines() { return m_num_lines; } + + void append_initial_line_piece(uint8_t * start, uint32_t length, bool eol); + + std::shared_ptr add_cursor(); + + void begin_insert(const Cursor & cursor, bool before); + void insert_code_point(uint32_t code_point); + void end_insert(); + void insertion_test(Cursor & c); + + void undo(); + +protected: Piece * add_piece() { return &m_pieces[m_piece_index++]; @@ -155,31 +169,25 @@ public: return m_pieces[index]; } - uint32_t get_num_lines() { return m_num_lines; } - - void append_initial_line_piece(uint8_t * start, uint32_t length, bool eol); - - std::shared_ptr add_cursor(); - - void insertion_test(Cursor & c); - - void undo(); + Change * add_change() + { + return &m_changes[m_changes_index++]; + } void apply_change(Change * change, uint8_t forward); -protected: const uint8_t * m_file_buffer; unsigned long m_file_buffer_size; uint32_t m_num_lines; - /** Next available piece index. */ - uint32_t m_piece_index; - PagedBuffer m_append_buffer; uint32_t m_append_buffer_index; PagedBuffer m_pieces; - PagedBuffer m_changes_buffer; - uint32_t m_changes_buffer_index; + /** Next available piece index. */ + uint32_t m_piece_index; + PagedBuffer m_changes; + uint32_t m_changes_index; + Piece * m_insert_before_piece; std::list> m_cursors; }; diff --git a/src/gui/Window.cc b/src/gui/Window.cc index 25adc7f..5996d6b 100644 --- a/src/gui/Window.cc +++ b/src/gui/Window.cc @@ -274,6 +274,9 @@ void Window::handle_key(uint32_t scancode, uint32_t mod) m_buffer->piece_table->undo(); redraw(); break; + case SDL_SCANCODE_I: + m_buffer->piece_table->begin_insert(*m_cursor, true); + break; } }