CE edit modes

This commit is contained in:
2026-03-07 01:32:50 +01:00
parent 37d73f63e3
commit 75635bcc2e
2 changed files with 79 additions and 38 deletions

116
ce/edit.c
View File

@@ -27,6 +27,9 @@
struct edit_line {
struct list_node_link lines_link;
struct list_node_link select_link;
size_t select_start;
size_t select_end;
struct gapbuffer gb;
};
@@ -35,6 +38,18 @@ struct cursor {
size_t line;
};
#define EDIT_MODE_NORMAL 0
#define EDIT_MODE_COMAMND 1
static const char* string_modes[] = {
[EDIT_MODE_NORMAL] = "Normal",
[EDIT_MODE_COMAMND] = "Command",
};
struct edit_select {
struct list_node_link* lines;
};
struct editor {
struct list_node_link* lines;
struct edit_line* current_line;
@@ -42,6 +57,8 @@ struct editor {
size_t col_offset;
size_t row_offset;
size_t total_lines;
struct edit_select select;
int mode;
};
static struct editor editor;
@@ -207,8 +224,9 @@ void edit_start (const char* file_path, const char* text) {
bbptr += w;
bb_remaining -= w;
w = snprintf (bbptr, bb_remaining, " Editing %s; line %zu col %zu" ANSIQ_GR_RESET, file_path,
editor.cursor.line + 1, editor.cursor.col + 1);
w = snprintf (bbptr, bb_remaining, " Editing %s; line %zu col %zu; Mode: %s" ANSIQ_GR_RESET,
file_path, editor.cursor.line + 1, editor.cursor.col + 1,
string_modes[editor.mode]);
bbptr += w;
bb_remaining -= w;
@@ -225,50 +243,58 @@ void edit_start (const char* file_path, const char* text) {
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);
if (editor.mode == EDIT_MODE_NORMAL) {
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 '\t':
gapbuffer_move (&editor.current_line->gb, editor.cursor.col);
for (size_t i = 0; i < sizeof (TAB_INSERT) - 1; i++)
gapbuffer_insert (&wrealloc, NULL, &editor.current_line->gb, TAB_INSERT[i]);
if (editor.mode == EDIT_MODE_NORMAL) {
gapbuffer_move (&editor.current_line->gb, editor.cursor.col);
for (size_t i = 0; i < sizeof (TAB_INSERT) - 1; i++)
gapbuffer_insert (&wrealloc, NULL, &editor.current_line->gb, TAB_INSERT[i]);
editor.cursor.col += sizeof (TAB_INSERT) - 1;
editor.cursor.col += sizeof (TAB_INSERT) - 1;
}
break;
case '\n': {
gapbuffer_move (&editor.current_line->gb, editor.cursor.col);
if (editor.mode == EDIT_MODE_NORMAL) {
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));
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;
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, init_cap);
gapbuffer_init (&wmalloc, NULL, &new_line->gb, init_cap);
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;
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;
editor.cursor.line++;
editor.current_line = new_line;
}
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;
editor.cursor.line++;
editor.current_line = new_line;
} break;
case KB_DELETE:
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++;
if (editor.mode == EDIT_MODE_NORMAL) {
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:
@@ -305,14 +331,28 @@ void edit_start (const char* file_path, const char* text) {
case KB_END:
editor.cursor.col = gapbuffer_length (&editor.current_line->gb);
break;
case KB_CTRL ('Q'):
edit_run = false;
case KB_ESCAPE:
editor.mode = EDIT_MODE_NORMAL;
break;
case KB_CTRL ('X'):
editor.mode = EDIT_MODE_COMAMND;
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++;
if (editor.mode == EDIT_MODE_COMAMND) {
switch (ch) {
case 'q':
edit_run = false;
editor.mode = EDIT_MODE_NORMAL;
break;
default:
editor.mode = EDIT_MODE_NORMAL;
break;
}
} else if (editor.mode == EDIT_MODE_NORMAL) {
gapbuffer_move (&editor.current_line->gb, editor.cursor.col);
gapbuffer_insert (&wrealloc, NULL, &editor.current_line->gb, ch);
editor.cursor.col++;
}
}
break;
}