Эх сурвалжийг харах

Changing way to add keybind

Vinicius Teshima 1 жил өмнө
parent
commit
1a37218e4e
4 өөрчлөгдсөн 345 нэмэгдсэн , 277 устгасан
  1. 131 16
      src/app.h
  2. 88 99
      src/config.h
  3. 95 130
      src/keybind.h
  4. 31 32
      src/main.c

+ 131 - 16
src/app.h

@@ -4,6 +4,7 @@
 #include <GL/glew.h>
 #include <SDL2/SDL.h>
 
+#include "ht.h"
 #include "da.h"
 
 #include "vec2.h"
@@ -11,11 +12,30 @@
 
 #include "buffer.h"
 
+DA_DEF_STRUCT(struct buffer, app_buffers);
+
+enum keybind_dir {
+	DIR_NO = -1,
+	DIR_FORWARD = 0,
+	DIR_BACKWARD,
+};
+struct app;
+typedef void (*keybind_func)(struct app *, enum keybind_dir);
+
+struct app_kbd {
+	SDL_Keymod mod;
+	keybind_func func;
+	enum keybind_dir dir;
+};
+
+HT_DEF_STRUCT(struct app_kbd, app_kbd_ht);
+
 struct app {
 	struct window win;
 	SDL_Renderer *rdr;
 	SDL_GLContext glctx;
-	struct buffer buf;
+	struct buffer *cbuf;
+	struct app_buffers bufs;
 	bool running;
 	uint64_t target_fps;
 	double dt;
@@ -26,6 +46,7 @@ struct app {
 	bool show_fps;
 	struct free_glyph_atlas *fga;
 	struct cursor_render *cr;
+	struct app_kbd_ht kbds;
 };
 
 #include "free_glyph.h"
@@ -61,6 +82,9 @@ struct vec2i app_calc_cursor(struct app app);
 
 struct ret_app_vec2 app_calc_buffer_cam(struct app app, double dt);
 
+void app_add_global_keybind(struct app *app, const char *keybind,
+			    keybind_func func, enum keybind_dir dir);
+
 #if defined(APP_IMP) || defined(IMP)
 
 #define UNHEX_COLOR(hex)			\
@@ -69,9 +93,9 @@ struct ret_app_vec2 app_calc_buffer_cam(struct app app, double dt);
 	(uint8_t) ((hex >> 8 ) & 0xFF),	\
 	(uint8_t) ((hex >> 0 ) & 0xFF)
 
-#include <GL/glew.h>
-
 #include "sc.h"
+#include "str.h"
+#include "char.h"
 
 struct app
 app_create(const char *win_title)
@@ -82,12 +106,16 @@ app_create(const char *win_title)
 		.win = window_create(win_title),
 		.rdr = NULL,
 		.running = true,
-		.buf = buffer_create(),
 		.cfg = {
 			.tab_size = 8
 		},
 		.target_fps = 120,
 	};
+	HT_CREATE(app.kbds, 16);
+	app.kbds.hash = ht_hash_nop;
+	DA_CREATE(app.bufs);
+	DA_APPEND(app.bufs, buffer_create());
+	app.cbuf = &app.bufs.items[0];
 
 	app.dt = (1.0 / (double)app.target_fps) * 3;
 
@@ -148,7 +176,7 @@ app_destroy(struct app app)
 {
 	SDL_DestroyWindow(app.win.ptr);
 	SDL_GL_DeleteContext(app.glctx);
-	free(app.buf.data.items);
+	free(app.cbuf->data.items);
 	SDL_Quit();
 }
 
@@ -160,21 +188,21 @@ struct vec2
 app_calc_cur_pos(struct app app)
 {
 	size_t col = 0;
-	size_t row = buffer_calc_cur_row(&app.buf);
+	size_t row = buffer_calc_cur_row(app.cbuf);
 	enum buffer_err err;
 	/* RET_UNWRAP2(col, row, */
 	/* 	    struct ret_size_t_size_t, */
 	/* 	    buffer_calc_cur_pos(app.buf)); */
 	size_t start_line;
-	start_line = buffer_index_bw_char(&app.buf, '\n', app.buf.cur, &err);
-	col = (app.buf.cur - start_line) - 1;
+	start_line = buffer_index_bw_char(app.cbuf, '\n', app.cbuf->cur, &err);
+	col = (app.cbuf->cur - start_line) - 1;
 	if ( err == BUFFER_ERR_NOT_FOUND ) {
-		col = app.buf.cur;
+		col = app.cbuf->cur;
 	}
 
 	size_t tabs_n = 0;
-	tabs_n = buffer_count_char_between(&app.buf, '\t', start_line,
-					   app.buf.cur, &err);
+	tabs_n = buffer_count_char_between(app.cbuf, '\t', start_line,
+					   app.cbuf->cur, &err);
 	col += ( tabs_n > 0 ) * ((tabs_n * app.cfg.tab_size) - tabs_n);
 	double row_px = -(((double)row)
 			  * app.fga->atlas_dim.y);
@@ -204,7 +232,7 @@ app_calc_cursor(struct app app)
 {
 	size_t row, col;
 	RET_UNWRAP2(col, row,
-		    struct ret_size_t_size_t, buffer_calc_cur_pos(&app.buf));
+		    struct ret_size_t_size_t, buffer_calc_cur_pos(app.cbuf));
 
 	return vec2i((int32_t)col, (int32_t)row);
 }
@@ -213,18 +241,105 @@ struct ret_app_vec2
 app_calc_buffer_cam(struct app app, double dt)
 {
 	struct vec2 cur_pos = app_calc_cur_pos(app);
-	struct vec2 cpos = app.buf.cam.pos;
-	struct vec2 cvel = app.buf.cam.vel;
+	struct vec2 cpos = app.cbuf->cam.pos;
+	struct vec2 cvel = app.cbuf->cam.vel;
 	cvel = vec2_sub(cur_pos, cpos);
 	cpos = vec2_add(cpos, vec2_mul(cvel, vec2s(dt)));
-	app.buf.cam.pos = cpos;
-	app.buf.cam.vel = cvel;
+	app.cbuf->cam.pos = cpos;
+	app.cbuf->cam.vel = cvel;
 	return (struct ret_app_vec2) {
 		.f1 = app,
 		.f2 = cpos
 	};
 }
 
+static SDL_KeyCode
+char_to_keycode(char c)
+{
+	/* Wrong */
+	return char_to_lower(c);
+}
+
+static SDL_Keymod
+char_to_keymod(char c)
+{
+	switch ( c ) {
+	case 'N': return KMOD_NONE; break;
+	/* case '': return KMOD_LSHIFT; break; */
+	/* case '': return KMOD_RSHIFT; break; */
+	/* case '': return KMOD_LCTRL; break; */
+	/* case '': return KMOD_RCTRL; break; */
+	/* case '': return KMOD_LALT; break; */
+	/* case '': return KMOD_RALT; break; */
+	/* case '': return KMOD_LGUI; break; */
+	/* case '': return KMOD_RGUI; break; */
+	/* case '': return KMOD_NUM; break; */
+	/* case '': return KMOD_CAPS; break; */
+	/* case '': return KMOD_MODE; break; */
+	/* case '': return KMOD_SCROLL; break; */
+	case 'C': return KMOD_CTRL; break;
+	case 'S': return KMOD_SHIFT; break;
+	case 'A': return KMOD_ALT; break;
+	case 'M': return KMOD_GUI; break;
+	default: return -1; break;
+	}
+}
+
+
+void
+app_add_global_keybind(struct app *app, const char *keybind,
+		       keybind_func func,
+		       enum keybind_dir dir)
+{
+	(void) app;
+	(void) func;
+	(void) dir;
+	struct str kbd_str = str_from_cstr_ns(keybind);
+	struct str_da words = str_split(kbd_str, ' ');
+	if ( words.size != 1 ) {
+		goto invalid_key;
+	}
+	/* for */ {
+		struct str_da chars = str_split(words.items[0], '-');
+		if ( chars.size != 2 ) {
+			goto invalid_key;
+		}
+		if ( chars.items[0].size != 1 ) {
+			goto invalid_key;
+		}
+		if ( chars.items[1].size != 1 ) {
+			goto invalid_key;
+		}
+
+		SDL_Keymod mod = char_to_keymod(chars.items[0].data[0]);
+		if ( (int32_t)(mod) == -1 ) {
+			fprintf(stderr, "[ERROR] Invalid mod in `%s`\n",
+				keybind);
+			exit(EXIT_FAILURE);
+		}
+		SDL_KeyCode key = char_to_keycode(chars.items[1].data[0]);
+		if ( key == SDLK_UNKNOWN ) {
+			goto invalid_key;
+		}
+		DA_DESTROY(chars);
+
+		struct app_kbd kbd = {
+			.mod = mod,
+			.func = func,
+			.dir = dir
+		};
+		HT_ISET(app->kbds, (int64_t)key, kbd);
+	}
+
+	DA_DESTROY(words);
+
+	return;
+invalid_key: ;
+	fprintf(stderr, "[ERROR] Invalid keybind `%s`\n",
+		keybind);
+	exit(EXIT_FAILURE);
+}
+
 #endif /* defined(APP_IMP) || defined(IMP) */
 
 #endif

+ 88 - 99
src/config.h

@@ -1,108 +1,97 @@
 #ifndef CONFIG_H
 #define CONFIG_H
 
+
+#include "app.h"
+#include "buffer.h"
 #include "keybind.h"
 
-#define KEYBINDS_MAX_SIZE 1048
-#define KMS KEYBINDS_MAX_SIZE
-static struct keybinds keybinds[KMS] = {
-	[SDLK_LEFT % KMS] = {
-		.size = 1,
-		.binds = {
-			{KMOD_NONE, keybind_mv_cur_char, {.dir = DIR_BACKWARD}}
-		}
-	},
-	[SDLK_RIGHT % KMS] = {
-		.size = 1,
-		.binds = {
-			{KMOD_NONE, keybind_mv_cur_char, {.dir = DIR_FORWARD}}
-		}
-	},
-	[SDLK_DELETE % KMS] = {
-		.size = 1,
-		.binds = {
-			{KMOD_NONE, keybind_delete_char, {.dir = DIR_FORWARD}},
-		}
-	},
-	[SDLK_UP % KMS] = {
-		.size = 1,
-		.binds = {
-			{KMOD_NONE, keybind_mv_cur_line, {.dir = DIR_BACKWARD}}
-		}
-	},
-	[SDLK_DOWN % KMS] = {
-		.size = 1,
-		.binds = {
-			{KMOD_NONE, keybind_mv_cur_line, {.dir = DIR_FORWARD}}
-		}
-	},
-	[SDLK_RETURN % KMS] = {
-		.size = 1,
-		.binds = {
-			{KMOD_NONE, keybind_insert_newline, {.ptr = NULL}}
-		}
-	},
-	[SDLK_BACKSPACE % KMS] = {
-		.size = 2,
-		.binds = {
-			{KMOD_NONE, keybind_delete_char, {.dir = DIR_BACKWARD}},
-			{KMOD_CTRL, keybind_delete_word, {.dir = DIR_BACKWARD}}
-		}
-	},
-	[SDLK_f % KMS] = {
-		.size = 2,
-		.binds = {
-			{KMOD_ALT, keybind_mv_cur_word, {.dir = DIR_FORWARD}},
-			{KMOD_CTRL, keybind_toggle_fps, {.ptr = NULL}}
-		}
-	},
-	[SDLK_b % KMS] = {
-		.size = 1,
-		.binds = {
-			{KMOD_ALT, keybind_mv_cur_word, {.dir = DIR_BACKWARD}}
-		}
-	},
-	[SDLK_d % KMS] = {
-		.size = 1,
-		.binds = {
-			{KMOD_ALT, keybind_delete_word, {.dir = DIR_FORWARD}}
-		}
-	},
-	[SDLK_a % KMS] = {
-		.size = 1,
-		.binds = {
-			{KMOD_CTRL, keybind_mv_cur_beg_line, {.ptr = NULL}}
-		}
-	},
-	[SDLK_e % KMS] = {
-		.size = 1,
-		.binds = {
-			{KMOD_CTRL, keybind_mv_cur_end_line, {.ptr = NULL}}
-		}
-	},
-	[SDLK_s % KMS] = {
-		.size = 1,
-		.binds = {
-			{KMOD_CTRL, keybind_save_buffer, {.ptr = NULL}}
-		}
-	},
-	[SDLK_PERIOD % KMS] = {
-		.size = 1,
-		.binds = {
-			{KMOD_ALT | KMOD_SHIFT, keybind_mv_cur_end_buffer,
-			 {.dir = DIR_FORWARD}}
-		}
-	},
-	[SDLK_COMMA % KMS] = {
-		.size = 1,
-		.binds = {
-			{KMOD_ALT | KMOD_SHIFT, keybind_mv_cur_end_buffer,
-			 {.dir = DIR_BACKWARD}}
-		}
-	},
-};
+
+void config(struct app *app);
+void config(struct app *app) {
+	/* app_add_global_keybing(app, "C-u", keybing_universal_cmd, -1); */
+	app_add_global_keybind(app, "C-d", keybind_delete_char, DIR_FORWARD);
+	app_add_global_keybind(app, "A-d", keybind_delete_word, DIR_FORWARD);
+
+	app_add_global_keybind(app, "C-e", keybind_mv_cur_end_line, DIR_NO);
+	app_add_global_keybind(app, "C-a", keybind_mv_cur_beg_line, DIR_NO);
+	app_add_global_keybind(app, "A-b", keybind_mv_cur_word, DIR_BACKWARD);
+	app_add_global_keybind(app, "A-f", keybind_mv_cur_word, DIR_FORWARD);
+
+	app_add_global_keybind(app, "C-s", keybind_save_buffer, DIR_NO);
+	/* app_add_mode_keybing(app, BUFFER_MODE_TEXT, "<delete>", */
+	/* 		     keybing_delete_char, DIR_FORWARD); */
+	/* app_add_mode_keybing(app, BUFFER_MODE_TEXT, "<return>", */
+	/* 		     keybing_insert_newline, 0); */
+	/* printf("config\n"); */
+	/* exit(1); */
+}
+
+
+
+/* #define KEYBINDS_MAX_SIZE 1048 */
+/* #define KMS KEYBINDS_MAX_SIZE */
+/* static struct keybinds keybinds[KMS] = { */
+/* 	[SDLK_LEFT % KMS] = { */
+/* 		.size = 1, */
+/* 		.binds = { */
+/* 			{KMOD_NONE, keybind_mv_cur_char, {.dir = DIR_BACKWARD}} */
+/* 		} */
+/* 	}, */
+/* 	[SDLK_RIGHT % KMS] = { */
+/* 		.size = 1, */
+/* 		.binds = { */
+/* 			{KMOD_NONE, keybind_mv_cur_char, {.dir = DIR_FORWARD}} */
+/* 		} */
+/* 	}, */
+/* 	[SDLK_DELETE % KMS] = { */
+/* 		.size = 1, */
+/* 		.binds = { */
+/* 			{KMOD_NONE, keybind_delete_char, {.dir = DIR_FORWARD}}, */
+/* 		} */
+/* 	}, */
+/* 	[SDLK_UP % KMS] = { */
+/* 		.size = 1, */
+/* 		.binds = { */
+/* 			{KMOD_NONE, keybind_mv_cur_line, {.dir = DIR_BACKWARD}} */
+/* 		} */
+/* 	}, */
+/* 	[SDLK_DOWN % KMS] = { */
+/* 		.size = 1, */
+/* 		.binds = { */
+/* 			{KMOD_NONE, keybind_mv_cur_line, {.dir = DIR_FORWARD}} */
+/* 		} */
+/* 	}, */
+/* 	[SDLK_RETURN % KMS] = { */
+/* 		.size = 1, */
+/* 		.binds = { */
+/* 			{KMOD_NONE, keybind_insert_newline, {.ptr = NULL}} */
+/* 		} */
+/* 	}, */
+/* 	[SDLK_BACKSPACE % KMS] = { */
+/* 		.size = 2, */
+/* 		.binds = { */
+/* 			{KMOD_NONE, keybind_delete_char, {.dir = DIR_BACKWARD}}, */
+/* 			{KMOD_CTRL, keybind_delete_word, {.dir = DIR_BACKWARD}} */
+/* 		} */
+/* 	}, */
+/* 	[SDLK_PERIOD % KMS] = { */
+/* 		.size = 1, */
+/* 		.binds = { */
+/* 			{KMOD_ALT | KMOD_SHIFT, keybind_mv_cur_end_buffer, */
+/* 			 {.dir = DIR_FORWARD}} */
+/* 		} */
+/* 	}, */
+/* 	[SDLK_COMMA % KMS] = { */
+/* 		.size = 1, */
+/* 		.binds = { */
+/* 			{KMOD_ALT | KMOD_SHIFT, keybind_mv_cur_end_buffer, */
+/* 			 {.dir = DIR_BACKWARD}} */
+/* 		} */
+/* 	}, */
+/* }; */
 
 
-#undef KMS
+/* #undef KMS */
 
 #endif

+ 95 - 130
src/keybind.h

@@ -5,237 +5,202 @@
 
 #include "app.h"
 
-enum direction {
-	DIR_FORWARD,
-	DIR_BACKWARD,
-};
+void keybind_save_buffer(struct app *app, enum keybind_dir dir);
 
-union keybind_args {
-	enum direction dir;
-	void *ptr;
-};
+void keybind_mv_cur_char(struct app *app, enum keybind_dir dir);
+void keybind_forward_char(struct app *app, enum keybind_dir dir);
+void keybind_delete_char(struct app *app, enum keybind_dir dir);
 
-typedef struct app (*keybind_func)(struct app, union keybind_args);
+void keybind_mv_cur_word(struct app *app, enum keybind_dir dir);
+void keybind_delete_word(struct app *app, enum keybind_dir dir);
 
-struct bind {
-	const SDL_Keymod mod;
-	keybind_func func;
-	union keybind_args args;
-};
+void keybind_mv_cur_line(struct app *app, enum keybind_dir dir);
+void keybind_mv_cur_beg_line(struct app *app, enum keybind_dir dir);
+void keybind_mv_cur_end_line(struct app *app, enum keybind_dir dir);
 
-#define BINDS_SIZE 10
-struct keybinds {
-	uint8_t size;
-	const struct bind binds[BINDS_SIZE];
-};
+void keybind_insert_newline(struct app *app, enum keybind_dir dir);
 
-struct app keybind_save_buffer(struct app app, union keybind_args args);
+void keybind_toggle_fps(struct app *app, enum keybind_dir dir);
 
-struct app keybind_mv_cur_char(struct app app, union keybind_args args);
-struct app keybind_forward_char(struct app app, union keybind_args args);
-struct app keybind_delete_char(struct app app, union keybind_args args);
-
-struct app keybind_mv_cur_word(struct app app, union keybind_args args);
-struct app keybind_delete_word(struct app app, union keybind_args args);
-
-struct app keybind_mv_cur_line(struct app app, union keybind_args args);
-struct app keybind_mv_cur_beg_line(struct app app, union keybind_args args);
-struct app keybind_mv_cur_end_line(struct app app, union keybind_args args);
-
-struct app keybind_insert_newline(struct app app, union keybind_args args);
-
-struct app keybind_toggle_fps(struct app app, union keybind_args args);
-
-struct app keybind_mv_cur_end_buffer(struct app app, union keybind_args args);
+void keybind_mv_cur_end_buffer(struct app *app, enum keybind_dir dir);
 
 #if defined(KEYBIND_IMP) || defined(IMP)
 
-struct app
-keybind_save_buffer(struct app app, union keybind_args args)
+void
+keybind_save_buffer(struct app *app, enum keybind_dir dir)
 {
-	(void) args;
+	(void) dir; (void) app;
 	/* buffer_save(app.buf); */
-	return app;
 }
 
-struct app
-keybind_mv_cur_char(struct app app, union keybind_args args)
+void
+keybind_mv_cur_char(struct app *app, enum keybind_dir dir)
 {
-	if ( args.dir == DIR_FORWARD ) {
-		buffer_mv_cur_right(&app.buf);
+	if ( dir == DIR_FORWARD ) {
+		buffer_mv_cur_right(app->cbuf);
 	}
-	if ( args.dir == DIR_BACKWARD ) {
-		buffer_mv_cur_left(&app.buf);
+	if ( dir == DIR_BACKWARD ) {
+		buffer_mv_cur_left(app->cbuf);
 	}
-	app.buf.high_col = buffer_calc_cur_col(&app.buf);
-	return app;
+	app->cbuf->high_col = buffer_calc_cur_col(app->cbuf);
 }
 
-struct app
-keybind_delete_char(struct app app, union keybind_args args)
+void
+keybind_delete_char(struct app *app, enum keybind_dir dir)
 {
-	if ( args.dir == DIR_FORWARD ) {
-		buffer_remove_char(&app.buf, app.buf.cur);
+	if ( dir == DIR_FORWARD ) {
+		buffer_remove_char(app->cbuf, app->cbuf->cur);
 	}
-	if ( args.dir == DIR_BACKWARD ) {
-		if ( app.buf.cur == 0 ) {
-			return app;
+	if ( dir == DIR_BACKWARD ) {
+		if ( app->cbuf->cur == 0 ) {
+			return;
 		}
-		buffer_remove_char(&app.buf, --app.buf.cur);
+		buffer_remove_char(app->cbuf, --app->cbuf->cur);
 	}
-	app.buf.high_col = buffer_calc_cur_col(&app.buf);
-	return app;
+	app->cbuf->high_col = buffer_calc_cur_col(app->cbuf);
 }
 
-struct app
-keybind_mv_cur_word(struct app app, union keybind_args args)
+void
+keybind_mv_cur_word(struct app *app, enum keybind_dir dir)
 {
 	size_t index;
 	enum buffer_err err;
-	if ( args.dir == DIR_FORWARD ) {
-		index = buffer_index_fw_word(&app.buf, &err);
+	if ( dir == DIR_FORWARD ) {
+		index = buffer_index_fw_word(app->cbuf, &err);
 		if ( err != BUFFER_ERR_OK ) {
 			if ( err == BUFFER_ERR_INVALID_CUR_POS ) {
-				app.buf.cur = app.buf.data.size;
+				app->cbuf->cur = app->cbuf->data.size;
 			}
-			return app;
+			return;
 		}
-		app.buf.cur = index;
+		app->cbuf->cur = index;
 	}
-	if ( args.dir == DIR_BACKWARD ) {
-		index = buffer_index_bw_word(&app.buf, &err);
+	if ( dir == DIR_BACKWARD ) {
+		index = buffer_index_bw_word(app->cbuf, &err);
 		if ( err != BUFFER_ERR_OK ) {
 			if ( err == BUFFER_ERR_INVALID_CUR_POS ) {
-				app.buf.cur = app.buf.data.size;
+				app->cbuf->cur = app->cbuf->data.size;
 			}
-			return app;
+			return;
 		}
-		app.buf.cur = index;
+		app->cbuf->cur = index;
 	}
-	app.buf.high_col = buffer_calc_cur_col(&app.buf);
-	return app;
+	app->cbuf->high_col = buffer_calc_cur_col(app->cbuf);
 }
 
 
-struct app
-keybind_delete_word(struct app app, union keybind_args args)
+void
+keybind_delete_word(struct app *app, enum keybind_dir dir)
 {
 	size_t index, n_rm;
 	size_t start, end ;
 	enum buffer_err err;
-	switch ( args.dir ) {
+	switch ( dir ) {
 	case DIR_BACKWARD: {
-		index = buffer_index_bw_word(&app.buf, &err);
+		index = buffer_index_bw_word(app->cbuf, &err);
 		if ( err != BUFFER_ERR_OK ) {
 			if ( err == BUFFER_ERR_INVALID_CUR_POS ) {
-				app.buf.cur = app.buf.data.size;
+				app->cbuf->cur = app->cbuf->data.size;
 			}
-			return app;
+			return;
 		}
 		start = index;
-		end = app.buf.cur;
+		end = app->cbuf->cur;
 	} break;
 	case DIR_FORWARD: {
-		index = buffer_index_fw_word(&app.buf, &err);
+		index = buffer_index_fw_word(app->cbuf, &err);
 		if ( err != BUFFER_ERR_OK ) {
 			if ( err == BUFFER_ERR_INVALID_CUR_POS ) {
-				app.buf.cur = app.buf.data.size;
+				app->cbuf->cur = app->cbuf->data.size;
 			}
-			return app;
+			return;
 		}
-		start = app.buf.cur;
+		start = app->cbuf->cur;
 		end = index;
 	} break;
 	default: {
 		fprintf(stderr, "Got invalid direction in %s: %d",
-			__func__, args.dir);
+			__func__, dir);
 		exit(EXIT_FAILURE);
 	} break;
 	}
-	n_rm = buffer_remove_between(&app.buf, start, end, &err);
+	n_rm = buffer_remove_between(app->cbuf, start, end, &err);
 	if ( err != BUFFER_ERR_OK ) {
-		return app;
+		return;
 	}
-	app.buf.cur -= ( args.dir == DIR_BACKWARD ) * n_rm;
-	app.buf.high_col = buffer_calc_cur_col(&app.buf);
-	return app;
+	app->cbuf->cur -= ( dir == DIR_BACKWARD ) * n_rm;
+	app->cbuf->high_col = buffer_calc_cur_col(app->cbuf);
 }
 
-struct app
-keybind_mv_cur_line(struct app app, union keybind_args args)
+void
+keybind_mv_cur_line(struct app *app, enum keybind_dir dir)
 {
-	(void) args;
-	switch ( args.dir ) {
+	(void) dir;
+	switch ( dir ) {
 	case DIR_FORWARD: {
-		buffer_mv_cur_down(&app.buf);
+		buffer_mv_cur_down(app->cbuf);
 	} break;
 	case DIR_BACKWARD: {
-		buffer_mv_cur_up(&app.buf);
+		buffer_mv_cur_up(app->cbuf);
 	} break;
 	default: {
 		fprintf(stderr, "Got invalid direction in %s: %d",
-			__func__, args.dir);
+			__func__, dir);
 		exit(EXIT_FAILURE);
 	} break;
 	}
-	return app;
 }
 
-struct app
-keybind_mv_cur_beg_line(struct app app, union keybind_args args)
+void
+keybind_mv_cur_beg_line(struct app *app, enum keybind_dir dir)
 {
-	(void) args;
-	struct buffer_line l = buffer_find_line(&app.buf, app.buf.cur-1);
-	app.buf.cur = l.start;
-	app.buf.high_col = buffer_calc_cur_col(&app.buf);
-	return app;
+	(void) dir;
+	struct buffer_line l = buffer_find_line(app->cbuf, app->cbuf->cur-1);
+	app->cbuf->cur = l.start;
+	app->cbuf->high_col = buffer_calc_cur_col(app->cbuf);
 }
 
-struct app
-keybind_mv_cur_end_line(struct app app, union keybind_args args)
+void
+keybind_mv_cur_end_line(struct app *app, enum keybind_dir dir)
 {
-	(void) args;
-	struct buffer_line l = buffer_find_line(&app.buf, app.buf.cur+1);
-	app.buf.cur = l.end;
-	app.buf.high_col = buffer_calc_cur_col(&app.buf);
-	return app;
+	(void) dir;
+	struct buffer_line l = buffer_find_line(app->cbuf, app->cbuf->cur+1);
+	app->cbuf->cur = l.end;
+	app->cbuf->high_col = buffer_calc_cur_col(app->cbuf);
 }
 
-struct app
-keybind_insert_newline(struct app app, union keybind_args args)
+void
+keybind_insert_newline(struct app *app, enum keybind_dir dir)
 {
-	(void) args;
-	buffer_insert_char(&app.buf, '\n', app.buf.cur);
-	app.buf.high_col = buffer_calc_cur_col(&app.buf);
-	return app;
+	(void) dir;
+	buffer_insert_char(app->cbuf, '\n', app->cbuf->cur);
+	app->cbuf->high_col = buffer_calc_cur_col(app->cbuf);
 }
 
-struct app
-keybind_toggle_fps(struct app app, union keybind_args args)
+void
+keybind_toggle_fps(struct app *app, enum keybind_dir dir)
 {
-	(void) args;
-	app.show_fps = ! app.show_fps;
-	return app;
+	(void) dir;
+	app->show_fps = ! app->show_fps;
 }
 
-struct app
-keybind_mv_cur_end_buffer(struct app app, union keybind_args args)
+void
+keybind_mv_cur_end_buffer(struct app *app, enum keybind_dir dir)
 {
-	switch ( args.dir ) {
+	switch ( dir ) {
 	case DIR_FORWARD: {
-		app.buf.cur = app.buf.data.size;
+		app->cbuf->cur = app->cbuf->data.size;
 	} break;
 	case DIR_BACKWARD: {
-		app.buf.cur = 0;
+		app->cbuf->cur = 0;
 	} break;
 	default: {
 		fprintf(stderr, "Got invalid direction in %s: %d",
-			__func__, args.dir);
+			__func__, dir);
 		exit(EXIT_FAILURE);
 	} break;
 	}
-	app.buf.high_col = buffer_calc_cur_col(&app.buf);
-	return app;
+	app->cbuf->high_col = buffer_calc_cur_col(app->cbuf);
 }
 
 #endif /* defined(KEYBIND_IMP) || defined(IMP) */

+ 31 - 32
src/main.c

@@ -1,4 +1,5 @@
 #define IMP
+#include "dir.h"
 #include "simple_render.h"
 #include "app.h"
 #include "vec2.h"
@@ -42,11 +43,6 @@ main(int32_t argc, char **argv)
 {
 	enum buffer_err buffer_err;
 
-	if ( argc != 2 ) {
-		fprintf(stderr, "MUST pass file to open\n");
-		exit(EXIT_FAILURE);
-	}
-
 	const char *ffont_path = "./fonts/ComicMono-Regular.ttf";
 
 	FT_Face face;
@@ -78,12 +74,19 @@ main(int32_t argc, char **argv)
 		}
 	}
 
+
 	struct app app = app_create("ged");
+	config(&app);
 
-	buffer_load_from_file(&app.buf, argv[1], &buffer_err);
-	if ( buffer_err != BUFFER_ERR_OK ) {
-		fprintf(stderr, "Failed to open buffer: %d\n", buffer_err);
-		exit(EXIT_FAILURE);
+	if ( argc== 2 ) {
+		buffer_load_from_file(app.cbuf, argv[1], &buffer_err);
+		if ( buffer_err != BUFFER_ERR_OK ) {
+			fprintf(stderr, "Failed to open buffer: %d\n",
+				buffer_err);
+			exit(EXIT_FAILURE);
+		}
+	} else {
+		DA_APPEND(app.bufs, buffer_list_dir("."));
 	}
 
 
@@ -148,21 +151,17 @@ handle_events(struct app *app)
 
 			SDL_KeyboardEvent key = e.key;
 			SDL_Keysym ks = key.keysym;
-			struct keybinds kb = keybinds[ks.sym
-						      % KEYBINDS_MAX_SIZE];
-			for ( size_t i = 0; i < kb.size; ++i ) {
-				struct bind b = kb.binds[i];
-				if ( b.func == NULL ) {
-					continue;
-				}
-				if ( (! (b.mod == KMOD_NONE
-					 && b.mod == ks.mod))
-				     && (! (b.mod & ks.mod)) ) {
-					continue;
-				}
-				*app = b.func(*app, b.args);
-				done = true;
+			struct app_kbd kbd = {0};
+			HT_IGET(app->kbds, (int64_t)ks.sym, kbd);
+
+			if ( kbd.func == NULL ) {
+				break;
+			}
+			if ( ! (kbd.mod & ks.mod) ) {
+				break;
 			}
+			kbd.func(app, kbd.dir);
+			return;
 		} break;
 		case SDL_TEXTINPUT: {
 			if ( done == true ) {
@@ -170,10 +169,10 @@ handle_events(struct app *app)
 			}
 			char *t = e.text.text;
 			while( *t != '\0' ) {
-				buffer_insert_char(&app->buf, *t++,
-						   app->buf.cur);
+				buffer_insert_char(app->cbuf, *t++,
+						   app->cbuf->cur);
 			}
-			app->buf.high_col = buffer_calc_cur_col(&app->buf);
+			app->cbuf->high_col = buffer_calc_cur_col(app->cbuf);
 		} break;
 		case SDL_WINDOWEVENT: {
 			WINDOW_UP_SIZE(app->win);
@@ -181,7 +180,7 @@ handle_events(struct app *app)
 		} break;
 		}
 	}
-	buffer_check_and_fix_cur(&app->buf);
+	buffer_check_and_fix_cur(app->cbuf);
 }
 
 void
@@ -189,17 +188,17 @@ render_buffer_into_fgr(struct free_glyph_atlas *fga, struct simple_render *sr,
 		       struct app *app)
 {
 	uint32_t ticks = SDL_GetTicks();
-	float cur_row = (float)(buffer_calc_cur_row(&app->buf)
+	float cur_row = (float)(buffer_calc_cur_row(app->cbuf)
 				* fga->atlas_dim.y);
 	float cur_col = fga_calc_col_buffer(fga, app);
 
 	struct vec2 cur_pos = vec2((double) cur_col, -(double) cur_row);
-	struct vec2 cpos = app->buf.cam.pos;
-	struct vec2 cvel = app->buf.cam.vel;
+	struct vec2 cpos = app->cbuf->cam.pos;
+	struct vec2 cvel = app->cbuf->cam.vel;
 	cvel = vec2_sub(cur_pos, cpos);
 	cpos = vec2_add(cpos, vec2_mul(cvel, vec2s(app->dt)));
-	app->buf.cam.pos = cpos;
-	app->buf.cam.vel = cvel;
+	app->cbuf->cam.pos = cpos;
+	app->cbuf->cam.vel = cvel;
 
 	float time = ((float) ticks) / 1000.0f;