Преглед изворни кода

Adding support for arrow key in keybinds

Vinicius Teshima пре 1 година
родитељ
комит
976cde69df
4 измењених фајлова са 141 додато и 22 уклоњено
  1. 32 2
      src/app.h
  2. 19 10
      src/config.h
  3. 45 10
      src/keybind.h
  4. 45 0
      src/str.h

+ 32 - 2
src/app.h

@@ -257,10 +257,27 @@ app_calc_buffer_cam(struct app app, double dt)
 static SDL_KeyCode
 char_to_keycode(char c)
 {
-	/* Wrong */
 	return char_to_lower(c);
 }
 
+static SDL_KeyCode
+str_to_keycode(struct str str)
+{
+	if ( str_eq_cstr(str, "<left>", 6) ) {
+		return SDLK_LEFT;
+	}
+	if ( str_eq_cstr(str, "<down>", 6) ) {
+		return SDLK_DOWN;
+	}
+	if ( str_eq_cstr(str, "<up>", 4) ) {
+		return SDLK_UP;
+	}
+	if ( str_eq_cstr(str, "<right>", 7) ) {
+		return SDLK_RIGHT;
+	}
+	return SDLK_UNKNOWN;
+}
+
 static SDL_Keymod
 char_to_keymod(char c)
 {
@@ -286,6 +303,8 @@ char_to_keymod(char c)
 	}
 }
 
+
+
 #define IF_GOTO(cond, to)				\
 	if ( (cond) ) {				\
 		fprintf(stderr, #cond"\n");		\
@@ -309,7 +328,18 @@ app_add_global_keybind(struct app *app, const char *keybind,
 		HT_ISET(app->kbds, (int64_t)(key), kbd);
 		return;
 	}
-
+	if ( kbd_str.data[0] == '<' ) {
+		IF_GOTO(str_contain_char(kbd_str, '-'), invalid_key)
+		SDL_KeyCode key = str_to_keycode(kbd_str);
+		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);

+ 19 - 10
src/config.h

@@ -7,24 +7,31 @@
 #include "keybind.h"
 
 
+#define AAGK app_add_global_keybind
+
 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);
+	AAGK(app, "<left>", keybind_mv_cur_char, DIR_BACKWARD);
+	AAGK(app, "<down>", keybind_mv_cur_line, DIR_FORWARD);
+	AAGK(app, "<up>", keybind_mv_cur_line, DIR_BACKWARD);
+	AAGK(app, "<right>", keybind_mv_cur_char, DIR_FORWARD);
+
+	AAGK(app, "C-k", keybind_delete_to_edg_line, 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);
+	AAGK(app, "C-d", keybind_delete_char, DIR_FORWARD);
+	AAGK(app, "A-d", keybind_delete_word, DIR_FORWARD);
 
-	app_add_global_keybind(app, "C-s", keybind_save_buffer, DIR_NO);
+	AAGK(app, "C-e", keybind_mv_cur_edg_line, DIR_FORWARD);
+	AAGK(app, "C-a", keybind_mv_cur_edg_line, DIR_BACKWARD);
+	AAGK(app, "A-b", keybind_mv_cur_word, DIR_BACKWARD);
+	AAGK(app, "A-f", keybind_mv_cur_word, DIR_FORWARD);
+
+	AAGK(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);
+		AAGK(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>", */
@@ -35,6 +42,8 @@ void config(struct app *app) {
 	/* exit(1); */
 }
 
+#undef AAGK
+
 
 
 /* #define KEYBINDS_MAX_SIZE 1048 */

+ 45 - 10
src/keybind.h

@@ -15,8 +15,8 @@ void keybind_mv_cur_word(struct app *app, enum keybind_dir dir);
 void keybind_delete_word(struct app *app, enum keybind_dir dir);
 
 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);
+void keybind_mv_cur_edg_line(struct app *app, enum keybind_dir dir);
+void keybind_delete_to_edg_line(struct app *app, enum keybind_dir dir);
 
 void keybind_insert_newline(struct app *app, enum keybind_dir dir);
 
@@ -153,20 +153,55 @@ keybind_mv_cur_line(struct app *app, enum keybind_dir dir)
 }
 
 void
-keybind_mv_cur_beg_line(struct app *app, enum keybind_dir dir)
+keybind_mv_cur_edg_line(struct app *app, enum keybind_dir dir)
 {
-	(void) dir;
-	struct buffer_line l = buffer_find_line(app->cbuf, app->cbuf->cur-1);
-	app->cbuf->cur = l.start;
+	switch ( dir ) {
+	case DIR_FORWARD: {
+		struct buffer_line l = buffer_find_line(
+			app->cbuf, app->cbuf->cur+1);
+		app->cbuf->cur = l.end;
+	} break;
+	case DIR_BACKWARD: {
+		struct buffer_line l = buffer_find_line(
+			app->cbuf, app->cbuf->cur-1);
+		app->cbuf->cur = l.start;
+	} break;
+	default: {
+		fprintf(stderr, "Got invalid direction in %s: %d",
+			__func__, dir);
+		exit(EXIT_FAILURE);
+	} break;
+	}
 	app->cbuf->high_col = buffer_calc_cur_col(app->cbuf);
 }
 
 void
-keybind_mv_cur_end_line(struct app *app, enum keybind_dir dir)
+keybind_delete_to_edg_line(struct app *app, enum keybind_dir dir)
 {
-	(void) dir;
-	struct buffer_line l = buffer_find_line(app->cbuf, app->cbuf->cur+1);
-	app->cbuf->cur = l.end;
+	struct buffer_line l = buffer_find_line(app->cbuf, app->cbuf->cur);
+	size_t start;
+	size_t end;
+	switch ( dir ) {
+	case DIR_FORWARD: {
+		start = app->cbuf->cur;
+		end = l.end;
+	} break;
+	case DIR_BACKWARD: {
+		start = l.start;
+		end = app->cbuf->cur;
+		app->cbuf->cur = l.start;
+	} break;
+	default: {
+		fprintf(stderr, "Got invalid direction in %s: %d",
+			__func__, dir);
+		exit(EXIT_FAILURE);
+	} break;
+	}
+	enum buffer_err err;
+	buffer_remove_between(app->cbuf, start, end, &err);
+	if ( err != BUFFER_ERR_OK ) {
+		return;
+	}
 	app->cbuf->high_col = buffer_calc_cur_col(app->cbuf);
 }
 

+ 45 - 0
src/str.h

@@ -3,6 +3,7 @@
 
 #include <stdlib.h>
 #include <stddef.h>
+#include <stdbool.h>
 
 #include "da.h"
 
@@ -21,6 +22,12 @@ struct str str_strip_right(struct str str);
 struct str str_strip(struct str str);
 struct str_da str_split(struct str str, char c);
 
+bool str_eq(struct str str_a, struct str str_b);
+bool str_eq_cstr(struct str str, const char *cstr, size_t size);
+bool str_eq_cstr_ns(struct str str, const char *cstr);
+
+bool str_contain_char(struct str str, char c);
+
 #if defined(STR_IMP) || defined(IMP)
 
 
@@ -86,6 +93,44 @@ str_split(struct str str, char c)
 	return da;
 }
 
+bool
+str_eq(struct str str_a, struct str str_b)
+{
+	if ( str_a.size != str_b.size ) {
+		return false;
+	}
+	for ( size_t i = 0; i < str_a.size; ++i ) {
+		if ( str_a.data[i] != str_b.data[i] ) {
+			return false;
+		}
+	}
+	return true;
+}
+
+bool
+str_eq_cstr(struct str str, const char *cstr, size_t size)
+{
+	return str_eq(str, str_from_cstr(cstr, size));
+}
+
+bool
+str_eq_cstr_ns(struct str str, const char *cstr)
+{
+	return str_eq(str, str_from_cstr_ns(cstr));
+}
+
+bool
+str_contain_char(struct str str, char c)
+{
+	for ( size_t i = 0; i < str.size; ++i ) {
+		if ( str.data[i] == c ) {
+			return true;
+		}
+	}
+	return false;
+}
+
+
 #endif /* defined(STR_IMP) || defined(IMP) */
 
 #endif