243 lines
5.9 KiB
C++
243 lines
5.9 KiB
C++
#include "editor/editor.h"
|
|
#include "editor/helpers.h"
|
|
#include "io/sysio.h"
|
|
#include "main.h"
|
|
#include "utils/utils.h"
|
|
|
|
void handle_editor_event(Editor *editor, KeyEvent event) {
|
|
uint8_t old_mode = mode;
|
|
if (editor->hover_active)
|
|
editor->hover_active = false;
|
|
handle_mouse(editor, event);
|
|
if (event.key_type == KEY_SPECIAL) {
|
|
switch (event.special_modifier) {
|
|
case 0:
|
|
switch (event.special_key) {
|
|
case KEY_DOWN:
|
|
cursor_down(editor, 1);
|
|
break;
|
|
case KEY_UP:
|
|
cursor_up(editor, 1);
|
|
break;
|
|
case KEY_LEFT:
|
|
cursor_left(editor, 1);
|
|
break;
|
|
case KEY_RIGHT:
|
|
cursor_right(editor, 1);
|
|
break;
|
|
}
|
|
break;
|
|
case CNTRL:
|
|
switch (event.special_key) {
|
|
case KEY_DOWN:
|
|
cursor_down(editor, 5);
|
|
break;
|
|
case KEY_UP:
|
|
cursor_up(editor, 5);
|
|
break;
|
|
case KEY_LEFT:
|
|
cursor_prev_word(editor);
|
|
case KEY_RIGHT:
|
|
cursor_next_word(editor);
|
|
break;
|
|
}
|
|
break;
|
|
case ALT:
|
|
switch (event.special_key) {
|
|
case KEY_DOWN:
|
|
move_line_down(editor);
|
|
break;
|
|
case KEY_UP:
|
|
move_line_up(editor);
|
|
break;
|
|
case KEY_LEFT:
|
|
cursor_left(editor, 8);
|
|
break;
|
|
case KEY_RIGHT:
|
|
cursor_right(editor, 8);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
switch (mode) {
|
|
case NORMAL:
|
|
if (event.key_type == KEY_CHAR && event.len == 1) {
|
|
switch (event.c[0]) {
|
|
case 'u':
|
|
select_all(editor);
|
|
break;
|
|
case CTRL('h'):
|
|
editor->hover.scroll(-1);
|
|
editor->hover_active = true;
|
|
break;
|
|
case CTRL('l'):
|
|
editor->hover.scroll(1);
|
|
editor->hover_active = true;
|
|
break;
|
|
case 'h':
|
|
fetch_lsp_hover(editor);
|
|
break;
|
|
case 'a': {
|
|
mode = INSERT;
|
|
Coord start = editor->cursor;
|
|
cursor_right(editor, 1);
|
|
if (start.row != editor->cursor.row)
|
|
cursor_left(editor, 1);
|
|
} break;
|
|
case 'i':
|
|
mode = INSERT;
|
|
break;
|
|
case 'n':
|
|
mode = JUMPER;
|
|
editor->jumper_set = true;
|
|
break;
|
|
case 'm':
|
|
mode = JUMPER;
|
|
editor->jumper_set = false;
|
|
break;
|
|
case 'N':
|
|
clear_hooks_at_line(editor, editor->cursor.row);
|
|
break;
|
|
case 's':
|
|
case 'v':
|
|
mode = SELECT;
|
|
editor->selection_active = true;
|
|
editor->selection = editor->cursor;
|
|
editor->selection_type = CHAR;
|
|
break;
|
|
case ';':
|
|
case ':':
|
|
mode = RUNNER;
|
|
break;
|
|
case 0x7F:
|
|
cursor_left(editor, 1);
|
|
break;
|
|
case ' ':
|
|
cursor_right(editor, 1);
|
|
break;
|
|
case '\r':
|
|
case '\n':
|
|
cursor_down(editor, 1);
|
|
break;
|
|
case '\\':
|
|
case '|':
|
|
cursor_up(editor, 1);
|
|
break;
|
|
case CTRL('d'):
|
|
scroll_down(editor, 1);
|
|
ensure_cursor(editor);
|
|
break;
|
|
case CTRL('u'):
|
|
scroll_up(editor, 1);
|
|
ensure_cursor(editor);
|
|
break;
|
|
case '>':
|
|
case '.':
|
|
indent_current_line(editor);
|
|
break;
|
|
case '<':
|
|
case ',':
|
|
dedent_current_line(editor);
|
|
break;
|
|
case CTRL('s'):
|
|
save_file(editor);
|
|
break;
|
|
case 'p':
|
|
paste(editor);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case INSERT:
|
|
if (event.key_type == KEY_CHAR) {
|
|
if (event.len == 1) {
|
|
if (event.c[0] == '\t') {
|
|
editor->indents.insert_tab(editor->cursor);
|
|
} else if (event.c[0] == '\n' || event.c[0] == '\r') {
|
|
editor->indents.insert_new_line(editor->cursor);
|
|
} else if (event.c[0] == CTRL('W')) {
|
|
delete_prev_word(editor);
|
|
} else if (isprint((unsigned char)(event.c[0]))) {
|
|
insert_char(editor, event.c[0]);
|
|
} else if (event.c[0] == 0x7F || event.c[0] == 0x08) {
|
|
backspace_edit(editor);
|
|
} else if (event.c[0] == 0x1B) {
|
|
normal_mode(editor);
|
|
}
|
|
} else if (event.len > 1) {
|
|
edit_insert(editor, editor->cursor, event.c, event.len);
|
|
cursor_right(editor, 1);
|
|
}
|
|
} else if (event.key_type == KEY_SPECIAL &&
|
|
event.special_key == KEY_DELETE) {
|
|
switch (event.special_modifier) {
|
|
case 0:
|
|
edit_erase(editor, editor->cursor, 1);
|
|
break;
|
|
case CNTRL:
|
|
delete_next_word(editor);
|
|
break;
|
|
}
|
|
} else if (event.key_type == KEY_PASTE) {
|
|
insert_str(editor, event.c, event.len);
|
|
}
|
|
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;
|
|
case 'y':
|
|
copy(editor);
|
|
mode = NORMAL;
|
|
break;
|
|
case 'x':
|
|
cut(editor);
|
|
mode = NORMAL;
|
|
break;
|
|
case 'p':
|
|
paste(editor);
|
|
mode = NORMAL;
|
|
break;
|
|
case '<':
|
|
case ',':
|
|
dedent_selection(editor);
|
|
break;
|
|
case '>':
|
|
case '.':
|
|
indent_selection(editor);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case JUMPER:
|
|
if (event.key_type == KEY_CHAR && event.len == 1 &&
|
|
(event.c[0] >= '!' && event.c[0] <= '~')) {
|
|
if (editor->jumper_set) {
|
|
for (uint8_t i = 0; i < 94; i++)
|
|
if (editor->hooks[i] == editor->cursor.row + 1) {
|
|
editor->hooks[i] = 0;
|
|
break;
|
|
}
|
|
editor->hooks[event.c[0] - '!'] = editor->cursor.row + 1;
|
|
} else {
|
|
uint32_t line = editor->hooks[event.c[0] - '!'] - 1;
|
|
if (line > 0) {
|
|
editor->cursor = {line, 0};
|
|
editor->cursor_preffered = UINT32_MAX;
|
|
}
|
|
}
|
|
}
|
|
mode = NORMAL;
|
|
break;
|
|
}
|
|
if (old_mode == mode || mode != INSERT)
|
|
handle_completion(editor, event);
|
|
ensure_scroll(editor);
|
|
}
|