Add basic modes and mode-navigation
This commit is contained in:
@@ -6,7 +6,6 @@ A TUI IDE.
|
|||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
- [ ] Add modes for editing - insert, select, normal, etc.
|
|
||||||
- [ ] Add line numbers.
|
- [ ] Add line numbers.
|
||||||
- [ ] Add bg highlight for current line.
|
- [ ] Add bg highlight for current line.
|
||||||
- [ ] Make function to get selected text. (selection itself is done)
|
- [ ] Make function to get selected text. (selection itself is done)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#define NORMAL 0
|
#define NORMAL 0
|
||||||
#define INSERT 1
|
#define INSERT 1
|
||||||
#define SELECT 2
|
#define SELECT 2
|
||||||
|
#define RUNNER 3
|
||||||
|
|
||||||
extern std::atomic<bool> running;
|
extern std::atomic<bool> running;
|
||||||
|
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ void enqueue_bytes(const char *bytes, int len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int read_input(char *&buf) {
|
int read_input(char *&buf) {
|
||||||
size_t cap = 32;
|
size_t cap = 16;
|
||||||
buf = (char *)malloc(cap);
|
buf = (char *)calloc(cap, sizeof(char));
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
char header;
|
char header;
|
||||||
if (!get_next_byte(&header)) {
|
if (!get_next_byte(&header)) {
|
||||||
@@ -199,6 +199,9 @@ KeyEvent read_key() {
|
|||||||
ret.key_type = KEY_CHAR;
|
ret.key_type = KEY_CHAR;
|
||||||
ret.c = buf;
|
ret.c = buf;
|
||||||
ret.len = n;
|
ret.len = n;
|
||||||
}
|
return ret;
|
||||||
|
}
|
||||||
|
if (n > 0)
|
||||||
|
free(buf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
53
src/main.cc
53
src/main.cc
@@ -10,7 +10,7 @@
|
|||||||
std::atomic<bool> running{true};
|
std::atomic<bool> running{true};
|
||||||
Queue<KeyEvent> event_queue;
|
Queue<KeyEvent> event_queue;
|
||||||
|
|
||||||
uint8_t mode = INSERT;
|
uint8_t mode = NORMAL;
|
||||||
|
|
||||||
void background_worker(Editor *editor) {
|
void background_worker(Editor *editor) {
|
||||||
while (running) {
|
while (running) {
|
||||||
@@ -50,6 +50,30 @@ void handle_editor_event(Editor *editor, KeyEvent event) {
|
|||||||
}
|
}
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case NORMAL:
|
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;
|
break;
|
||||||
case INSERT:
|
case INSERT:
|
||||||
if (event.key_type == KEY_CHAR) {
|
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]))) {
|
} else if (isprint((unsigned char)(event.c[0]))) {
|
||||||
edit_insert(editor, editor->cursor, event.c, 1);
|
edit_insert(editor, editor->cursor, event.c, 1);
|
||||||
cursor_right(editor, 1);
|
cursor_right(editor, 1);
|
||||||
|
} else if (event.c[0] == 0x1B) {
|
||||||
|
mode = NORMAL;
|
||||||
}
|
}
|
||||||
} else if (event.len > 1) {
|
} else if (event.len > 1) {
|
||||||
edit_insert(editor, editor->cursor, event.c, event.len);
|
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)
|
if (event.key_type == KEY_SPECIAL && event.special_key == KEY_DELETE)
|
||||||
edit_erase(editor, editor->cursor, 1);
|
edit_erase(editor, editor->cursor, 1);
|
||||||
break;
|
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);
|
ensure_scroll(editor);
|
||||||
|
if (event.key_type == KEY_CHAR && event.c)
|
||||||
|
free(event.c);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
@@ -100,7 +149,7 @@ int main(int argc, char *argv[]) {
|
|||||||
render_editor(editor);
|
render_editor(editor);
|
||||||
render();
|
render();
|
||||||
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(16));
|
std::this_thread::sleep_for(std::chrono::milliseconds(8));
|
||||||
}
|
}
|
||||||
|
|
||||||
input_thread.detach();
|
input_thread.detach();
|
||||||
|
|||||||
Reference in New Issue
Block a user