Add basic modes and mode-navigation

This commit is contained in:
2025-12-13 00:48:42 +00:00
parent dad7d844ca
commit ce06ca8057
4 changed files with 57 additions and 5 deletions

View File

@@ -6,7 +6,6 @@ A TUI IDE.
# TODO
- [ ] Add modes for editing - insert, select, normal, etc.
- [ ] Add line numbers.
- [ ] Add bg highlight for current line.
- [ ] Make function to get selected text. (selection itself is done)

View File

@@ -7,6 +7,7 @@
#define NORMAL 0
#define INSERT 1
#define SELECT 2
#define RUNNER 3
extern std::atomic<bool> running;

View File

@@ -37,8 +37,8 @@ void enqueue_bytes(const char *bytes, int len) {
}
int read_input(char *&buf) {
size_t cap = 32;
buf = (char *)malloc(cap);
size_t cap = 16;
buf = (char *)calloc(cap, sizeof(char));
size_t len = 0;
char header;
if (!get_next_byte(&header)) {
@@ -199,6 +199,9 @@ KeyEvent read_key() {
ret.key_type = KEY_CHAR;
ret.c = buf;
ret.len = n;
return ret;
}
if (n > 0)
free(buf);
return ret;
}

View File

@@ -10,7 +10,7 @@
std::atomic<bool> running{true};
Queue<KeyEvent> event_queue;
uint8_t mode = INSERT;
uint8_t mode = NORMAL;
void background_worker(Editor *editor) {
while (running) {
@@ -50,6 +50,30 @@ void handle_editor_event(Editor *editor, KeyEvent event) {
}
switch (mode) {
case NORMAL:
if (event.key_type == KEY_CHAR && event.len == 1) {
switch (event.c[0]) {
case 'a':
case 'i':
mode = INSERT;
break;
case 's':
case 'v':
mode = SELECT;
editor->selection_active = true;
editor->selection = editor->cursor;
break;
case ';':
case ':':
mode = RUNNER;
break;
case 0x7F:
cursor_left(editor, 1);
break;
case ' ':
cursor_right(editor, 1);
break;
}
}
break;
case INSERT:
if (event.key_type == KEY_CHAR) {
@@ -65,6 +89,8 @@ void handle_editor_event(Editor *editor, KeyEvent event) {
} else if (isprint((unsigned char)(event.c[0]))) {
edit_insert(editor, editor->cursor, event.c, 1);
cursor_right(editor, 1);
} else if (event.c[0] == 0x1B) {
mode = NORMAL;
}
} else if (event.len > 1) {
edit_insert(editor, editor->cursor, event.c, event.len);
@@ -74,8 +100,31 @@ void handle_editor_event(Editor *editor, KeyEvent event) {
if (event.key_type == KEY_SPECIAL && event.special_key == KEY_DELETE)
edit_erase(editor, editor->cursor, 1);
break;
case SELECT:
if (event.key_type == KEY_CHAR && event.len == 1) {
switch (event.c[0]) {
case 0x1B:
case 's':
case 'v':
editor->selection_active = false;
mode = NORMAL;
break;
}
}
break;
case RUNNER:
if (event.key_type == KEY_CHAR && event.len == 1) {
switch (event.c[0]) {
case 0x1B:
mode = NORMAL;
break;
}
}
break;
}
ensure_scroll(editor);
if (event.key_type == KEY_CHAR && event.c)
free(event.c);
}
int main(int argc, char *argv[]) {
@@ -100,7 +149,7 @@ int main(int argc, char *argv[]) {
render_editor(editor);
render();
std::this_thread::sleep_for(std::chrono::milliseconds(16));
std::this_thread::sleep_for(std::chrono::milliseconds(8));
}
input_thread.detach();