Przeglądaj źródła

Bettering keybind

Vinicius Teshima 1 rok temu
rodzic
commit
a0b5f181a6
5 zmienionych plików z 69 dodań i 38 usunięć
  1. 27 24
      src/app.h
  2. 8 0
      src/config.h
  3. 4 0
      src/ht.h
  4. 15 0
      src/keybind.h
  5. 15 14
      src/main.c

+ 27 - 24
src/app.h

@@ -40,6 +40,7 @@ struct app {
 	uint64_t target_fps;
 	double dt;
 	uint32_t last_press;
+	SDL_KeyCode last_pressed_key;
 	struct {
 		uint8_t tab_size;
 	} cfg;
@@ -285,42 +286,44 @@ char_to_keymod(char c)
 	}
 }
 
+#define IF_GOTO(cond, to)				\
+	if ( (cond) ) {				\
+		fprintf(stderr, #cond"\n");		\
+		goto to;				\
+	}
 
 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;
+	if ( kbd_str.size == 1 ) {
+		SDL_KeyCode key = char_to_keycode(kbd_str.data[0]);
+		IF_GOTO(key == SDLK_UNKNOWN, invalid_key);
+		struct app_kbd kbd = {
+			.mod = KMOD_NONE,
+			.func = func,
+			.dir = dir
+		};
+		HT_ISET(app->kbds, (int64_t)(key), kbd);
+		return;
 	}
+
+
+	struct str_da words = str_split(kbd_str, ' ');
+	IF_GOTO(words.size != 1, 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;
-		}
+		IF_GOTO(chars.size != 2, invalid_key)
+		IF_GOTO(chars.items[0].size != 1, invalid_key)
+		IF_GOTO(chars.items[1].size != 1, 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);
-		}
+		IF_GOTO((int32_t)(mod) == -1, invalid_key);
+
 		SDL_KeyCode key = char_to_keycode(chars.items[1].data[0]);
-		if ( key == SDLK_UNKNOWN ) {
-			goto invalid_key;
-		}
+		IF_GOTO(key == SDLK_UNKNOWN, invalid_key);
 		DA_DESTROY(chars);
 
 		struct app_kbd kbd = {
@@ -328,7 +331,7 @@ app_add_global_keybind(struct app *app, const char *keybind,
 			.func = func,
 			.dir = dir
 		};
-		HT_ISET(app->kbds, (int64_t)key, kbd);
+		HT_ISET(app->kbds, (int64_t)(key + mod), kbd);
 	}
 
 	DA_DESTROY(words);

+ 8 - 0
src/config.h

@@ -19,6 +19,14 @@ void config(struct app *app) {
 	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);
+
+	char *k = calloc(sizeof(char), 2);
+	for ( char c = 32; c < 127; ++c) {
+		k[0] = c;
+		app_add_global_keybind(app, k,
+				       keybind_insert_last_pressed_key, DIR_NO);
+	}
+	/* 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>", */

+ 4 - 0
src/ht.h

@@ -80,6 +80,7 @@ uint64_t ht_default_hash(const char *str, size_t str_size);
 	do {								\
 		typeof((ht)) _ht = {0};				\
 		HT_CREATE(_ht, (ht).cap*2);				\
+		_ht.hash = ht.hash;					\
 		for ( size_t _i = 0; _i < (ht).keys.size; ++_i ) {	\
 			uint64_t _k = (ht).keys.items[_i];		\
 			typeof(*(ht).items) _hi = (ht).items[_k % (ht).cap]; \
@@ -151,6 +152,9 @@ uint64_t ht_default_hash(const char *str, size_t str_size);
 		while ( _it->key != _k && _it->key != 0 ) {		\
 			_it = &(ht).items[(_k + (++_i)) % (ht).cap];	\
 		}							\
+		if ( _it->key == 0 ) {					\
+			break;						\
+		}							\
 		(ret) = _it->data;					\
 	} while(0)
 

+ 15 - 0
src/keybind.h

@@ -23,6 +23,7 @@ void keybind_insert_newline(struct app *app, enum keybind_dir dir);
 void keybind_toggle_fps(struct app *app, enum keybind_dir dir);
 
 void keybind_mv_cur_end_buffer(struct app *app, enum keybind_dir dir);
+void keybind_insert_last_pressed_key(struct app *app, enum keybind_dir dir);
 
 #if defined(KEYBIND_IMP) || defined(IMP)
 
@@ -203,6 +204,20 @@ keybind_mv_cur_end_buffer(struct app *app, enum keybind_dir dir)
 	app->cbuf->high_col = buffer_calc_cur_col(app->cbuf);
 }
 
+void
+keybind_insert_last_pressed_key(struct app *app, enum keybind_dir dir)
+{
+	(void)dir;
+	char c = (char)app->last_pressed_key;
+	if ( (c < 32 || c > 126) && c != '\t' ) {
+		return;
+	}
+
+	buffer_insert_char(app->cbuf, c, app->cbuf->cur);
+	app->cbuf->high_col = buffer_calc_cur_col(app->cbuf);
+}
+
+
 #endif /* defined(KEYBIND_IMP) || defined(IMP) */
 
 #endif

+ 15 - 14
src/main.c

@@ -140,7 +140,6 @@ void
 handle_events(struct app *app)
 {
 	SDL_Event e = {0};
-	bool done = false;
 	while ( SDL_PollEvent(&e) ) {
 		switch ( e.type ) {
 		case SDL_QUIT: {
@@ -151,29 +150,31 @@ handle_events(struct app *app)
 
 			SDL_KeyboardEvent key = e.key;
 			SDL_Keysym ks = key.keysym;
+			app->last_pressed_key = ks.sym;
+
+			int32_t mod = 0;
+			int32_t mods[] = {
+				KMOD_CTRL, KMOD_SHIFT, KMOD_ALT, KMOD_GUI
+			};
+			size_t mods_size = 4;
+			for ( size_t i = 0; i < mods_size; ++i ) {
+				if ( ks.mod & mods[i] ) {
+					mod |= mods[i];
+				}
+			}
+
 			struct app_kbd kbd = {0};
-			HT_IGET(app->kbds, (int64_t)ks.sym, kbd);
+			HT_IGET(app->kbds, (int64_t)(ks.sym + mod), kbd);
 
 			if ( kbd.func == NULL ) {
 				break;
 			}
-			if ( ! (kbd.mod & ks.mod) ) {
+			if ( (! (kbd.mod & ks.mod)) && (kbd.mod != KMOD_NONE)) {
 				break;
 			}
 			kbd.func(app, kbd.dir);
 			return;
 		} break;
-		case SDL_TEXTINPUT: {
-			if ( done == true ) {
-				break;
-			}
-			char *t = e.text.text;
-			while( *t != '\0' ) {
-				buffer_insert_char(app->cbuf, *t++,
-						   app->cbuf->cur);
-			}
-			app->cbuf->high_col = buffer_calc_cur_col(app->cbuf);
-		} break;
 		case SDL_WINDOWEVENT: {
 			WINDOW_UP_SIZE(app->win);
 			glViewport(0, 0 ,app->win.w, app->win.h);