diff options
author | cflip <cflip@cflip.net> | 2023-01-31 10:46:21 -0700 |
---|---|---|
committer | cflip <cflip@cflip.net> | 2023-01-31 12:20:03 -0700 |
commit | 757efb85045408e2601da0f53547941a40d2e960 (patch) | |
tree | 0ab46da5222222971d3dd4bd7319262c6842be8a | |
parent | c3da108c2d41853beb49a90a1f43a2a9a158c385 (diff) |
Start implementing editor commands
This first step allows you to press the semicolon key to enter command
mode, where you can type into a command line. Currently, pressing enter
when in command mode will clear the command line but since there are no
commands implemented it doesn't matter what you type in there.
-rw-r--r-- | editor.c | 14 | ||||
-rw-r--r-- | editor.h | 2 | ||||
-rw-r--r-- | input.c | 32 | ||||
-rw-r--r-- | input.h | 1 | ||||
-rw-r--r-- | window.c | 24 |
5 files changed, 59 insertions, 14 deletions
@@ -34,6 +34,7 @@ void init_editor(struct editor_state* editor) editor->status_message_time = 0; editor->syntax = NULL; editor->mode = EDITOR_MODE_NORMAL; + editor->cmdline = textbuf_init(); editor_update_screen_size(editor); window_set_filename("[New]"); @@ -58,6 +59,13 @@ char* editor_prompt(struct editor_state* editor, char* prompt, void (*callback)( return NULL; } +void editor_run_command(struct editor_state *editor) +{ + /* TODO: Do something here */ + editor->mode = EDITOR_MODE_NORMAL; + textbuf_clear(&editor->cmdline); +} + void editor_try_quit(struct editor_state *editor) { if (editor->dirty && quit_message_time == 0) { @@ -308,6 +316,11 @@ void editor_draw_message_bar(struct editor_state* editor, struct textbuf *buffer return; } + if (editor->mode == EDITOR_MODE_COMMAND) { + textbuf_append(buffer, editor->cmdline.buffer, editor->cmdline.length); + return; + } + int message_length = strlen(editor->status_message); if (message_length > editor->screen_cols) @@ -326,4 +339,5 @@ void editor_destroy(struct editor_state *editor) for (int i = 0; i < editor->num_lines; i++) free_line(&editor->lines[i]); free(editor->lines); + textbuf_free(&editor->cmdline); } @@ -33,12 +33,14 @@ struct editor_state { * letter will be inserted when entering insert mode. */ int pressed_insert_key; + struct textbuf cmdline; }; void init_editor(struct editor_state* editor); void editor_set_status_message(struct editor_state* editor, const char* format, ...); char* editor_prompt(struct editor_state* editor, char* prompt, void (*callback)(struct editor_state*, char*, int)); +void editor_run_command(struct editor_state *editor); void editor_try_quit(struct editor_state *editor); void editor_move_left(struct editor_state *); @@ -4,10 +4,25 @@ #include "file.h" #include "line.h" +void input_process_textinput(struct editor_state *editor, const char *text) +{ + /* Ignore the first letter after entering insert mode. */ + if (editor->pressed_insert_key) { + editor->pressed_insert_key = 0; + return; + } + + if (editor->mode == EDITOR_MODE_INSERT) { + editor_insert_char(editor, *text); + } else if (editor->mode == EDITOR_MODE_COMMAND) { + textbuf_append(&editor->cmdline, text, 1); + } +} + void editor_process_keypress(struct editor_state *editor, SDL_Keysym *keysym) { /* Handle keypresses for typing modes separately. */ - if (editor->mode != EDITOR_MODE_NORMAL) { + if (editor->mode == EDITOR_MODE_INSERT) { if (keysym->sym == SDLK_BACKSPACE) editor_delete_char(editor); @@ -22,6 +37,18 @@ void editor_process_keypress(struct editor_state *editor, SDL_Keysym *keysym) return; } + if (editor->mode == EDITOR_MODE_COMMAND) { + if (keysym->sym == SDLK_BACKSPACE) + textbuf_delete(&editor->cmdline); + + if (keysym->sym == SDLK_RETURN) + editor_run_command(editor); + + if (keysym->sym == SDLK_ESCAPE) + editor->mode = EDITOR_MODE_NORMAL; + return; + } + switch (keysym->sym) { /* TODO: Reimplement page up/down on Shift+W/S. */ case SDLK_w: @@ -80,5 +107,8 @@ void editor_process_keypress(struct editor_state *editor, SDL_Keysym *keysym) case SDLK_SLASH: editor_find(editor); break; + case SDLK_SEMICOLON: + editor->mode = EDITOR_MODE_COMMAND; + break; } } @@ -4,6 +4,7 @@ #include "editor.h" #include <SDL2/SDL_keyboard.h> +void input_process_textinput(struct editor_state *editor, const char *text); void editor_process_keypress(struct editor_state *editor, SDL_Keysym *keysym); #endif @@ -52,17 +52,7 @@ int window_handle_event(struct editor_state *editor) editor_process_keypress(editor, &e.key.keysym); break; case SDL_TEXTINPUT: - if (editor->mode == EDITOR_MODE_NORMAL) - break; - /* - * Ignore the first letter after entering insert mode, because it - * usually is just 'i'. - */ - if (editor->pressed_insert_key) { - editor->pressed_insert_key = 0; - break; - } - editor_insert_char(editor, *e.text.text); + input_process_textinput(editor, e.text.text); break; case SDL_WINDOWEVENT: if (e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { @@ -164,9 +154,17 @@ void window_redraw(struct editor_state *editor) editor_scroll(editor); draw_editor(editor); + int cursor_x = (editor->cursor_display_x - editor->col_offset); + int cursor_y = (editor->cursor_y - editor->line_offset); + + if (editor->mode == EDITOR_MODE_COMMAND) { + cursor_x = editor->cmdline.length; + cursor_y = editor->screen_rows + 1; + } + SDL_Rect cursor_rect; - cursor_rect.x = (editor->cursor_display_x - editor->col_offset) * font.width; - cursor_rect.y = (editor->cursor_y - editor->line_offset) * font.height; + cursor_rect.x = cursor_x * font.width; + cursor_rect.y = cursor_y * font.height; cursor_rect.w = font.width; cursor_rect.h = font.height; |