diff options
-rw-r--r-- | base.h | 8 | ||||
-rw-r--r-- | buffer.c | 10 | ||||
-rw-r--r-- | command.c | 108 | ||||
-rw-r--r-- | command.h | 71 | ||||
-rw-r--r-- | config.c | 12 | ||||
-rw-r--r-- | main.c | 26 | ||||
-rw-r--r-- | math.c | 8 | ||||
-rw-r--r-- | ted.cfg | 6 | ||||
-rw-r--r-- | util.c | 17 |
9 files changed, 244 insertions, 22 deletions
@@ -51,6 +51,14 @@ typedef unsigned long ulong; typedef long long llong; typedef unsigned long long ullong; +#if __clang__ +#define ENUM_U16 typedef enum : u16 +#define ENUM_U16_END(name) name +#else +#define ENUM_U16 enum +#define ENUM_U16_END(name) ; typedef u16 name +#endif + #ifdef __GNUC__ #define WarnUnusedResult __attribute__((warn_unused_result)) #else @@ -542,7 +542,7 @@ Status buffer_load_file(TextBuffer *buffer, char const *filename) { } } -Status buffer_save(TextBuffer *buffer) { +bool buffer_save(TextBuffer *buffer) { FILE *out = fopen(buffer->filename, "wb"); if (out) { bool success = true; @@ -755,16 +755,16 @@ static void buffer_scroll_to_cursor(TextBuffer *buffer) { // scroll left if cursor is off screen in that direction double max_scroll_x = (double)(cursor_col - scroll_padding); - scroll_x = util_mind(scroll_x, max_scroll_x); + scroll_x = mind(scroll_x, max_scroll_x); // scroll right double min_scroll_x = (double)(cursor_col - display_cols + scroll_padding); - scroll_x = util_maxd(scroll_x, min_scroll_x); + scroll_x = maxd(scroll_x, min_scroll_x); // scroll up double max_scroll_y = (double)(cursor_line - scroll_padding); - scroll_y = util_mind(scroll_y, max_scroll_y); + scroll_y = mind(scroll_y, max_scroll_y); // scroll down double min_scroll_y = (double)(cursor_line - display_lines + scroll_padding); - scroll_y = util_maxd(scroll_y, min_scroll_y); + scroll_y = maxd(scroll_y, min_scroll_y); buffer->scroll_x = scroll_x; buffer->scroll_y = scroll_y; diff --git a/command.c b/command.c new file mode 100644 index 0000000..12bd1c8 --- /dev/null +++ b/command.c @@ -0,0 +1,108 @@ +Command command_from_str(char const *str) { + // @OPTIMIZE: sort command_names, do a binary search + for (int i = 0; i < CMD_COUNT; ++i) { + if (streq(command_names[i].name, str)) + return command_names[i].cmd; + } + return CMD_UNKNOWN; +} + +// Returns string representation of command +char const *command_to_str(Command c) { + // NOTE: this probably won't need to be optimized. + for (int i = 0; i < CMD_COUNT; ++i) { + if (command_names[i].cmd == c) + return command_names[i].name; + } + return "???"; +} + +void command_execute(Ted *ted, Command c, i64 argument) { + TextBuffer *buffer = ted->active_buffer; + switch (c) { + case CMD_UNKNOWN: + case CMD_COUNT: + assert(0); + break; + case CMD_NOOP: + break; + + case CMD_LEFT: + buffer_cursor_move_left(buffer, argument); + break; + case CMD_RIGHT: + buffer_cursor_move_right(buffer, argument); + break; + case CMD_UP: + buffer_cursor_move_up(buffer, argument); + break; + case CMD_DOWN: + buffer_cursor_move_down(buffer, argument); + break; + case CMD_SELECT_LEFT: + buffer_select_left(buffer, argument); + break; + case CMD_SELECT_RIGHT: + buffer_select_right(buffer, argument); + break; + case CMD_SELECT_UP: + buffer_select_up(buffer, argument); + break; + case CMD_SELECT_DOWN: + buffer_select_down(buffer, argument); + break; + case CMD_LEFT_WORD: + buffer_cursor_move_left_words(buffer, argument); + break; + case CMD_RIGHT_WORD: + buffer_cursor_move_right_words(buffer, argument); + break; + case CMD_SELECT_LEFT_WORD: + buffer_select_left_words(buffer, argument); + break; + case CMD_SELECT_RIGHT_WORD: + buffer_select_right_words(buffer, argument); + break; + case CMD_START_OF_LINE: + buffer_cursor_move_to_start_of_line(buffer); + break; + case CMD_END_OF_LINE: + buffer_cursor_move_to_end_of_line(buffer); + break; + case CMD_SELECT_START_OF_LINE: + buffer_select_to_start_of_line(buffer); + break; + case CMD_SELECT_END_OF_LINE: + buffer_select_to_end_of_line(buffer); + break; + case CMD_START_OF_FILE: + buffer_cursor_move_to_start_of_file(buffer); + break; + case CMD_END_OF_FILE: + buffer_cursor_move_to_end_of_file(buffer); + break; + case CMD_SELECT_START_OF_FILE: + buffer_select_to_start_of_file(buffer); + break; + case CMD_SELECT_END_OF_FILE: + buffer_select_to_end_of_file(buffer); + break; + + case CMD_BACKSPACE: + buffer_backspace_at_cursor(buffer, argument); + break; + case CMD_DELETE: + buffer_delete_chars_at_cursor(buffer, argument); + break; + case CMD_BACKSPACE_WORDS: + buffer_backspace_words_at_cursor(buffer, argument); + break; + case CMD_DELETE_WORDS: + buffer_delete_words_at_cursor(buffer, argument); + break; + + case CMD_SAVE: + buffer_save(buffer); + break; + } +} diff --git a/command.h b/command.h new file mode 100644 index 0000000..d4df03a --- /dev/null +++ b/command.h @@ -0,0 +1,71 @@ +ENUM_U16 { + CMD_UNKNOWN, + CMD_NOOP, + // movement commands + CMD_LEFT, + CMD_RIGHT, + CMD_UP, + CMD_DOWN, + CMD_SELECT_LEFT, + CMD_SELECT_RIGHT, + CMD_SELECT_UP, + CMD_SELECT_DOWN, + CMD_LEFT_WORD, + CMD_RIGHT_WORD, + CMD_SELECT_LEFT_WORD, + CMD_SELECT_RIGHT_WORD, + CMD_START_OF_LINE, + CMD_END_OF_LINE, + CMD_SELECT_START_OF_LINE, + CMD_SELECT_END_OF_LINE, + CMD_START_OF_FILE, + CMD_END_OF_FILE, + CMD_SELECT_START_OF_FILE, + CMD_SELECT_END_OF_FILE, + + // deletion + CMD_BACKSPACE, + CMD_DELETE, + CMD_BACKSPACE_WORDS, + CMD_DELETE_WORDS, + + CMD_SAVE, + + CMD_COUNT +} ENUM_U16_END(Command); + +typedef struct { + char const *name; + Command cmd; +} CommandName; + +static CommandName const command_names[CMD_COUNT] = { + {"unknown", CMD_UNKNOWN}, + {"noop", CMD_NOOP}, + {"left", CMD_LEFT}, + {"right", CMD_RIGHT}, + {"up", CMD_UP}, + {"down", CMD_DOWN}, + {"select-left", CMD_SELECT_LEFT}, + {"select-right", CMD_SELECT_RIGHT}, + {"select-up", CMD_SELECT_UP}, + {"select-down", CMD_SELECT_DOWN}, + {"left-word", CMD_LEFT_WORD}, + {"right-word", CMD_RIGHT_WORD}, + {"select-left-word", CMD_SELECT_LEFT_WORD}, + {"select-right-word", CMD_SELECT_RIGHT_WORD}, + {"start-of-line", CMD_START_OF_LINE}, + {"end-of-line", CMD_END_OF_LINE}, + {"select-start-of-line", CMD_SELECT_START_OF_LINE}, + {"select-end-of-line", CMD_SELECT_END_OF_LINE}, + {"start-of-file", CMD_START_OF_FILE}, + {"end-of-file", CMD_END_OF_FILE}, + {"select-start-of-file", CMD_SELECT_START_OF_FILE}, + {"select-end-of-file", CMD_SELECT_END_OF_FILE}, + {"backspace", CMD_BACKSPACE}, + {"delete", CMD_DELETE}, + {"backspace-words", CMD_BACKSPACE}, + {"delete-words", CMD_DELETE}, + {"save", CMD_SAVE} +}; + diff --git a/config.c b/config.c new file mode 100644 index 0000000..4ae3dbb --- /dev/null +++ b/config.c @@ -0,0 +1,12 @@ +// Read a configuration file. +// Config files are formatted as several sections, each containing key = value pairs. +// e.g.: +// [section1] +// thing1 = 33 +// thing2 = 454 +// [section2] +// asdf = 123 +void config_read(Ted *ted, char const *filename) { + char section_name[32] = {0}; + // @TODO +} @@ -9,6 +9,8 @@ no_warn_end #include <GL/gl.h> #include <locale.h> #include <wctype.h> + +#include "command.h" #include "time.c" #include "unicode.h" #include "util.c" @@ -19,6 +21,23 @@ no_warn_end #include "arr.c" #include "buffer.c" +typedef struct { + Command cmd; + i64 argument; +} KeyAction; + +#define SCANCODE_COUNT 0x120 // SDL scancodes should be less than this value. +// a "key combo" is some subset of {control, shift, alt} + some key. +#define KEY_COMBO_COUNT (SCANCODE_COUNT << 3) + +typedef struct { + TextBuffer *active_buffer; + KeyAction key_actions[KEY_COMBO_COUNT]; + char error[256]; +} Ted; + +#include "command.c" + static void die(char const *fmt, ...) { char buf[256] = {0}; @@ -84,7 +103,7 @@ int main(void) { Uint32 time_at_last_frame = SDL_GetTicks(); while (!quit) { - #if DEBUG + #if DEBUG&&0 printf("\033[H\033[2J"); #endif @@ -116,7 +135,8 @@ int main(void) { } break; case SDL_KEYDOWN: { - switch (event.key.keysym.sym) { + SDL_Keycode keycode = event.key.keysym.sym; + switch (keycode) { case SDLK_PAGEUP: buffer_scroll(buffer, 0, -buffer_display_lines(buffer)); break; @@ -306,7 +326,7 @@ int main(void) { #if DEBUG //buffer_print_debug(buffer); buffer_check_valid(buffer); - buffer_print_undo_history(buffer); + //buffer_print_undo_history(buffer); #endif SDL_GL_SwapWindow(window); @@ -66,6 +66,14 @@ static float maxf(float a, float b) { return a > b ? a : b; } +static double maxd(double a, double b) { + return a > b ? a : b; +} + +static double mind(double a, double b) { + return a < b ? a : b; +} + static u32 minu32(u32 a, u32 b) { return a < b ? a : b; } @@ -0,0 +1,6 @@ +[keyboard] +# motion keys +Left = :left +Right = :right +Up = :up +Down = :down @@ -1,8 +1,3 @@ -#ifndef UTIL_C_ -#define UTIL_C_ - -#include "base.h" - static u32 util_popcount(u64 x) { #ifdef __GNUC__ return (u32)__builtin_popcountll(x); @@ -25,14 +20,6 @@ static void util_zero_memory(void *mem, size_t size) { memset(mem, 0, size); } -static double util_maxd(double a, double b) { - return a > b ? a : b; -} - -static double util_mind(double a, double b) { - return a < b ? a : b; -} - // for finding a character in a char32 string static char32_t *util_mem32chr(char32_t *s, char32_t c, size_t n) { for (size_t i = 0; i < n; ++i) { @@ -52,4 +39,6 @@ static char32_t const *util_mem32chr_const(char32_t const *s, char32_t c, size_t return NULL; } -#endif +static bool streq(char const *a, char const *b) { + return strcmp(a, b) == 0; +} |