diff --git a/ce/ce.c b/ce/ce.c index d34127b..422e561 100644 --- a/ce/ce.c +++ b/ce/ce.c @@ -147,7 +147,7 @@ void app_main (void) { mprintf ("\n"); - render = gapbuffer_get_string (&warena_malloc, &arena, &edit_line.gb); + render = gapbuffer_string_at (&warena_malloc, &arena, &edit_line.gb, 0); if (render != NULL) exec_line (render); diff --git a/ce/edit.c b/ce/edit.c index ac386e3..38e3430 100644 --- a/ce/edit.c +++ b/ce/edit.c @@ -123,19 +123,40 @@ void edit_start (const char* file_path, const char* text) { bbptr += w; bb_remaining -= w; - char* render = gapbuffer_get_string (&warena_malloc, &temp_arena, &line->gb); - size_t len = strlen (render); + size_t part1_len = line->gb.gap_start; + size_t part2_len = line->gb.size - line->gb.gap_end; - if (len > editor.col_offset) { - char* visible = render + editor.col_offset; - size_t visible_len = len - editor.col_offset; + size_t current_col = 0; - if (visible_len > cols) - visible_len = cols; + if (part1_len > editor.col_offset) { + size_t start = editor.col_offset; + size_t len = part1_len - start; - w = snprintf (bbptr, bb_remaining, "%.*s", (int)visible_len, visible); + if (len > cols) + len = cols; + + w = snprintf (bbptr, bb_remaining, "%.*s", (int)len, &line->gb.buffer[start]); bbptr += w; bb_remaining -= w; + current_col += len; + } + + if (current_col < cols && part2_len > 0) { + size_t skip = 0; + if (editor.col_offset > part1_len) + skip = editor.col_offset - part1_len; + + if (skip < part2_len) { + size_t len = part2_len - skip; + + if (current_col + len > cols) + len = cols - current_col; + + w = snprintf (bbptr, bb_remaining, "%.*s", (int)len, + &line->gb.buffer[line->gb.gap_end + skip]); + bbptr += w; + bb_remaining -= w; + } } w = snprintf (bbptr, bb_remaining, ANSIQ_SCR_CLR2END "\n"); @@ -166,31 +187,35 @@ void edit_start (const char* file_path, const char* text) { uint8_t ch = 0; mail_receive (&ch, 1); - gapbuffer_move (&editor.current_line->gb, editor.cursor.col); - switch (ch) { case '\b': if (editor.cursor.col > 0) { + gapbuffer_move (&editor.current_line->gb, editor.cursor.col); editor.cursor.col--; gapbuffer_backspace (&editor.current_line->gb); } break; case '\n': { + gapbuffer_move (&editor.current_line->gb, editor.cursor.col); + struct edit_line* new_line = malloc (sizeof (*new_line)); memset (new_line, 0, sizeof (*new_line)); char* tail = gapbuffer_string_at (&warena_malloc, &temp_arena, &editor.current_line->gb, editor.cursor.col); size_t tail_size = strlen (tail); + size_t init_cap = tail_size > 0 ? tail_size : 32; - gapbuffer_init (&wmalloc, NULL, &new_line->gb, tail_size > 0 ? tail_size : 32); + gapbuffer_init (&wmalloc, NULL, &new_line->gb, init_cap); - for (size_t i = 0; i < tail_size; i++) { - char chr = gapbuffer_at (&editor.current_line->gb, editor.cursor.col); - gapbuffer_delete_at (&editor.current_line->gb, editor.cursor.col); - gapbuffer_insert (&wrealloc, NULL, &new_line->gb, chr); + if (tail_size > 0) { + memcpy (new_line->gb.buffer, + editor.current_line->gb.buffer + editor.current_line->gb.gap_end, tail_size); + new_line->gb.gap_start = tail_size; } + editor.current_line->gb.gap_end = editor.current_line->gb.size; + list_insert_after (editor.lines, &editor.current_line->lines_link, &new_line->lines_link); editor.cursor.col = 0; @@ -198,8 +223,10 @@ void edit_start (const char* file_path, const char* text) { editor.current_line = new_line; } break; case KB_DELETE: - if (editor.cursor.col < gapbuffer_length (&editor.current_line->gb)) + if (editor.cursor.col < gapbuffer_length (&editor.current_line->gb)) { + gapbuffer_move (&editor.current_line->gb, editor.cursor.col); editor.current_line->gb.gap_end++; + } break; case KB_LEFT: if (editor.cursor.col > 0) @@ -240,6 +267,7 @@ void edit_start (const char* file_path, const char* text) { break; default: if (isprint (ch)) { + gapbuffer_move (&editor.current_line->gb, editor.cursor.col); gapbuffer_insert (&wrealloc, NULL, &editor.current_line->gb, ch); editor.cursor.col++; } diff --git a/ce/gapbuffer.c b/ce/gapbuffer.c index 7015cc7..783c215 100644 --- a/ce/gapbuffer.c +++ b/ce/gapbuffer.c @@ -72,22 +72,6 @@ void gapbuffer_backspace (struct gapbuffer* gb) { gb->gap_start--; } -char* gapbuffer_get_string (gb_malloc_func_t mallocfn, void* ctx, struct gapbuffer* gb) { - size_t size = gb->size - (gb->gap_end - gb->gap_start); - - char* str = mallocfn (ctx, size + 1); - - if (str == NULL) - return NULL; - - memcpy (str, gb->buffer, gb->gap_start); - - memcpy (str + gb->gap_start, gb->buffer + gb->gap_end, gb->size - gb->gap_end); - - str[size] = '\0'; - return str; -} - size_t gapbuffer_length (struct gapbuffer* gb) { return gb->size - (gb->gap_end - gb->gap_start); } char* gapbuffer_string_at (gb_malloc_func_t mallocfn, void* ctx, struct gapbuffer* gb, size_t pos) { @@ -128,17 +112,3 @@ char* gapbuffer_string_at (gb_malloc_func_t mallocfn, void* ctx, struct gapbuffe res[written] = '\0'; return res; } - -char gapbuffer_at (struct gapbuffer* gb, size_t index) { - if (index < gb->gap_start) - return gb->buffer[index]; - else - return gb->buffer[index + (gb->gap_end - gb->gap_start)]; -} - -void gapbuffer_delete_at (struct gapbuffer* gb, size_t index) { - gapbuffer_move (gb, index); - - if (gb->gap_end < gb->size) - gb->gap_end++; -} diff --git a/ce/gapbuffer.h b/ce/gapbuffer.h index d865286..0e1c058 100644 --- a/ce/gapbuffer.h +++ b/ce/gapbuffer.h @@ -29,14 +29,8 @@ void gapbuffer_backspace (struct gapbuffer* gb); void gapbuffer_grow (gb_realloc_func_t reallocfn, void* ctx, struct gapbuffer* gb); -char* gapbuffer_get_string (gb_malloc_func_t mallocfn, void* ctx, struct gapbuffer* gb); - size_t gapbuffer_length (struct gapbuffer* gb); char* gapbuffer_string_at (gb_malloc_func_t mallocfn, void* ctx, struct gapbuffer* gb, size_t pos); -char gapbuffer_at (struct gapbuffer* gb, size_t index); - -void gapbuffer_delete_at (struct gapbuffer* gb, size_t index); - #endif // _GAPBUFFER_H