summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcflip <cflip@cflip.net>2023-01-12 12:19:08 -0700
committercflip <cflip@cflip.net>2023-01-12 12:21:03 -0700
commit4c150aab138f5733d29ad4548d66764fe19ffc44 (patch)
tree6559f4cfafb7abb9a10b4a12be0ec79ee5b93df7
parentab00e1e288743496e75c5e54c0e6abdecf439642 (diff)
Make the editor modal and refactor keyboard events
This makes the editor behave more like vi, with a seperate insert mode. This also refactors the keyboard input code to pass the SDL_Keysym structure to input.c and to use the SDL_TEXTINPUT event for editing text. SDL's text input event already fixes typing capital letters with shift, and should make it possible to enter text using an IME, however most unicode characters aren't properly rendered.
-rw-r--r--editor.c3
-rw-r--r--editor.h7
-rw-r--r--input.c92
-rw-r--r--input.h18
-rw-r--r--window.c41
5 files changed, 60 insertions, 101 deletions
diff --git a/editor.c b/editor.c
index 58f18c9..d52d553 100644
--- a/editor.c
+++ b/editor.c
@@ -26,6 +26,7 @@ void init_editor(struct editor_state* editor)
editor->status_message[0] = '\0';
editor->status_message_time = 0;
editor->syntax = NULL;
+ editor->mode = EDITOR_MODE_NORMAL;
window_get_size(&editor->screen_rows, &editor->screen_cols);
@@ -153,6 +154,7 @@ static void editor_find_callback(struct editor_state* editor, char* query, int k
saved_highlight = NULL;
}
+ /* TODO:
if (key == '\r' || key == '\x1b') {
last_match = -1;
direction = 1;
@@ -165,6 +167,7 @@ static void editor_find_callback(struct editor_state* editor, char* query, int k
last_match = -1;
direction = 1;
}
+ */
if (last_match == -1)
direction = 1;
diff --git a/editor.h b/editor.h
index 63f6c76..7df152a 100644
--- a/editor.h
+++ b/editor.h
@@ -4,6 +4,12 @@
#include <time.h>
#include "buffer.h"
+enum editor_mode {
+ EDITOR_MODE_NORMAL,
+ EDITOR_MODE_INSERT,
+ EDITOR_MODE_COMMAND
+};
+
struct editor_state {
int cursor_x, cursor_y;
int cursor_display_x;
@@ -18,6 +24,7 @@ struct editor_state {
char status_message[80];
time_t status_message_time;
struct editor_syntax* syntax;
+ int mode;
};
void init_editor(struct editor_state* editor);
diff --git a/input.c b/input.c
index 50191e7..7a18441 100644
--- a/input.c
+++ b/input.c
@@ -1,82 +1,76 @@
#include "input.h"
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include "file.h"
+#include "editor.h"
#include "row.h"
-void editor_process_keypress(struct editor_state* editor, int c)
+void editor_process_keypress(struct editor_state *editor, SDL_Keysym *keysym)
{
static int quit_message = 1;
- switch (c) {
+ /* Handle keypresses for typing modes separately. */
+ if (editor->mode != EDITOR_MODE_NORMAL) {
+ if (keysym->sym == SDLK_BACKSPACE)
+ editor_delete_char(editor);
+
+ if (keysym->sym == SDLK_RETURN)
+ editor_insert_newline(editor);
+
+ if (keysym->sym == SDLK_ESCAPE)
+ editor->mode = EDITOR_MODE_NORMAL;
+ return;
+ }
+
+ switch (keysym->sym) {
case '\r':
editor_insert_newline(editor);
break;
- case CTRL_KEY('q'):
- if (editor->dirty && quit_message) {
- editor_set_status_message(editor, "This file has unsaved changes. Press Ctrl+Q again to quit");
- quit_message = 0;
- return;
+ case SDLK_q:
+ if (keysym->mod & KMOD_CTRL) {
+ if (editor->dirty && quit_message) {
+ editor_set_status_message(editor, "This file has unsaved changes. Press Ctrl+Q again to quit");
+ quit_message = 0;
+ return;
+ }
+ exit(0);
}
- exit(0);
break;
- case CTRL_KEY('s'):
- editor_save(editor);
+ case SDLK_s:
+ if (keysym->mod & KMOD_CTRL)
+ editor_save(editor);
break;
- case HOME_KEY:
+ case SDLK_0:
editor->cursor_x = 0;
break;
- case END_KEY:
- if (editor->cursor_y < editor->row_count)
+ case SDLK_4:
+ if (keysym->mod & KMOD_SHIFT && editor->cursor_y < editor->row_count)
editor->cursor_x = editor->rows[editor->cursor_y].size;
break;
- case CTRL_KEY('f'):
+ case SDLK_SLASH:
editor_find(editor);
break;
- case BACKSPACE:
- case DELETE_KEY:
- if (c == DELETE_KEY)
- editor_move_right(editor);
+ case SDLK_x:
+ editor_move_right(editor);
editor_delete_char(editor);
break;
- case PAGE_UP:
- case PAGE_DOWN:
- {
- if (c == PAGE_UP) {
- editor->cursor_y = editor->row_offset;
- } else {
- editor->cursor_y = editor->row_offset + editor->screen_rows -1;
- if (editor->cursor_y > editor->row_count)
- editor->cursor_y = editor->row_count;
- }
- /*
- * TODO: Reimplement pageup/pagedown, this time by scrolling the
- * screen without necessarily changing the position of the
- * cursor relative to the screen
- */
- }
+ case SDLK_PAGEUP:
+ case SDLK_PAGEDOWN:
+ /* TODO: Reimplement page up & page down. */
break;
- case ARROW_UP:
+ case SDLK_i:
+ editor->mode = EDITOR_MODE_INSERT;
+ break;
+ case SDLK_k:
editor_move_up(editor);
break;
- case ARROW_DOWN:
+ case SDLK_j:
editor_move_down(editor);
break;
- case ARROW_LEFT:
+ case SDLK_h:
editor_move_left(editor);
break;
- case ARROW_RIGHT:
+ case SDLK_l:
editor_move_right(editor);
break;
- case CTRL_KEY('l'):
- case '\x1b':
- break;
- default:
- editor_insert_char(editor, c);
- break;
}
quit_message = 1;
diff --git a/input.h b/input.h
index 33f349f..85dbdde 100644
--- a/input.h
+++ b/input.h
@@ -2,22 +2,8 @@
#define _INPUT_H
#include "editor.h"
+#include <SDL2/SDL_keyboard.h>
-enum editor_key {
- BACKSPACE = 127,
- ARROW_LEFT = 1000,
- ARROW_RIGHT,
- ARROW_UP,
- ARROW_DOWN,
- DELETE_KEY,
- HOME_KEY,
- END_KEY,
- PAGE_UP,
- PAGE_DOWN
-};
-
-#define CTRL_KEY(k) ((k) & 0x1f)
-
-void editor_process_keypress(struct editor_state *editor, int keycode);
+void editor_process_keypress(struct editor_state *editor, SDL_Keysym *keysym);
#endif
diff --git a/window.c b/window.c
index b87188d..9d10f85 100644
--- a/window.c
+++ b/window.c
@@ -44,43 +44,12 @@ int window_handle_event(struct editor_state *editor)
case SDL_QUIT:
return 0;
case SDL_KEYDOWN:
- int keycode = e.key.keysym.sym;
- switch (e.key.keysym.sym) {
- case SDLK_BACKSPACE:
- keycode = BACKSPACE;
- break;
- case SDLK_LEFT:
- keycode = ARROW_LEFT;
- break;
- case SDLK_RIGHT:
- keycode = ARROW_RIGHT;
- break;
- case SDLK_UP:
- keycode = ARROW_UP;
- break;
- case SDLK_DOWN:
- keycode = ARROW_DOWN;
- break;
- case SDLK_DELETE:
- keycode = DELETE_KEY;
- break;
- case SDLK_HOME:
- keycode = HOME_KEY;
- break;
- case SDLK_END:
- keycode = END_KEY;
- break;
- case SDLK_PAGEUP:
- keycode = PAGE_UP;
- break;
- case SDLK_PAGEDOWN:
- keycode = PAGE_DOWN;
+ editor_process_keypress(editor, &e.key.keysym);
+ break;
+ case SDL_TEXTINPUT:
+ if (editor->mode == EDITOR_MODE_NORMAL)
break;
- }
- if (e.key.keysym.mod & KMOD_CTRL) {
- keycode = CTRL_KEY(keycode);
- }
- editor_process_keypress(editor, keycode);
+ editor_insert_char(editor, *e.text.text);
break;
}
return 1;