summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--base.h8
-rw-r--r--buffer.c10
-rw-r--r--command.c108
-rw-r--r--command.h71
-rw-r--r--config.c12
-rw-r--r--main.c26
-rw-r--r--math.c8
-rw-r--r--ted.cfg6
-rw-r--r--util.c17
9 files changed, 244 insertions, 22 deletions
diff --git a/base.h b/base.h
index 9b0c805..c6e6de4 100644
--- a/base.h
+++ b/base.h
@@ -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
diff --git a/buffer.c b/buffer.c
index ee45d2c..cdc9f6a 100644
--- a/buffer.c
+++ b/buffer.c
@@ -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
+}
diff --git a/main.c b/main.c
index 325c7b2..27b5153 100644
--- a/main.c
+++ b/main.c
@@ -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);
diff --git a/math.c b/math.c
index cd121d0..2909c66 100644
--- a/math.c
+++ b/math.c
@@ -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;
}
diff --git a/ted.cfg b/ted.cfg
new file mode 100644
index 0000000..e6d223b
--- /dev/null
+++ b/ted.cfg
@@ -0,0 +1,6 @@
+[keyboard]
+# motion keys
+Left = :left
+Right = :right
+Up = :up
+Down = :down
diff --git a/util.c b/util.c
index 09da480..26a8d8e 100644
--- a/util.c
+++ b/util.c
@@ -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;
+}