add PieceTable::begin_insert()
This commit is contained in:
parent
807eba4448
commit
99bbe81f6b
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<Cursor> 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<Cursor> 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<uint8_t> m_append_buffer;
|
||||
uint32_t m_append_buffer_index;
|
||||
PagedBuffer<Piece> m_pieces;
|
||||
PagedBuffer<Change> m_changes_buffer;
|
||||
uint32_t m_changes_buffer_index;
|
||||
/** Next available piece index. */
|
||||
uint32_t m_piece_index;
|
||||
PagedBuffer<Change> m_changes;
|
||||
uint32_t m_changes_index;
|
||||
Piece * m_insert_before_piece;
|
||||
|
||||
std::list<std::shared_ptr<Cursor>> m_cursors;
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user