CE improve editor performace by reducing amount of copying
All checks were successful
Build documentation / build-and-deploy (push) Successful in 2m31s
All checks were successful
Build documentation / build-and-deploy (push) Successful in 2m31s
This commit is contained in:
2
ce/ce.c
2
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);
|
||||
|
||||
60
ce/edit.c
60
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++;
|
||||
}
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user