From 74d2348558767c1d22d6fd68b38e6fae8621a083 Mon Sep 17 00:00:00 2001
From: Anonymus Raccoon
Date: Sun, 24 May 2020 15:32:20 +0200
Subject: [PATCH] Allowing editing of key bindings
---
include/my_ncurses.h | 1 +
src/builtin/builtin_bindkey.c | 73 +++++++++++++++++++++++++++++++----
src/main.c | 6 ++-
src/my_ncurses/string_utils.c | 12 ++++++
4 files changed, 82 insertions(+), 10 deletions(-)
diff --git a/include/my_ncurses.h b/include/my_ncurses.h
index f2109ae..8cac82c 100644
--- a/include/my_ncurses.h
+++ b/include/my_ncurses.h
@@ -43,6 +43,7 @@ void my_getcuryx(int *y, int *x);
void my_getmaxyx(int *y, int *x);
int my_getch(void);
const char *my_unctrl(int c);
+int my_parsechar(const char *c);
void my_addstr(my_window *window, const char *str);
#define my_mvaddstr(window, y, x, str) (my_move(window, y, x), \
diff --git a/src/builtin/builtin_bindkey.c b/src/builtin/builtin_bindkey.c
index 95e60dd..f28440d 100644
--- a/src/builtin/builtin_bindkey.c
+++ b/src/builtin/builtin_bindkey.c
@@ -14,9 +14,14 @@
void print_binding(binding_t *binding)
{
- const char *key = my_unctrl(binding->key);
- const char *func = NULL;
+ const char *key;
+ const char *func = key_functions[0].name;
+ if (binding->key == -1) {
+ puts("Unknown key.");
+ return;
+ }
+ key = my_unctrl(binding->key);
for (int i = 0; key_functions[i].run; i++) {
if (key_functions[i].run == binding->func) {
func = key_functions[i].name;
@@ -26,25 +31,77 @@ void print_binding(binding_t *binding)
printf("%s -> %s\n", key, func);
}
+static binding_t *get_binding(const char *c, env_t *env)
+{
+ int key = my_parsechar(c);
+
+ if (key == -1)
+ return (NULL);
+ for (int i = 0; env->bindings[i].func; i++)
+ if (env->bindings[i].key == key)
+ return (&env->bindings[i]);
+ return (NULL);
+}
+
+static void new_binding(const char *c, int (*func)(int, buffer_t *, env_t *), env_t *env)
+{
+ int key = my_parsechar(c);
+ int size = 0;
+
+ if (env->bindings)
+ while (env->bindings[size++].func);
+ if (key == -1) {
+ printf("Unknown key: %s\n", c);
+ return;
+ }
+ env->bindings = realloc(env->bindings, (size + 1) * sizeof(binding_t));
+ env->bindings[size - 1].key = key;
+ env->bindings[size - 1].func = func;
+ env->bindings[size].func = NULL;
+}
+
+static void set_binding(const char *c, const char *cmd, env_t *env)
+{
+ binding_t *binding = get_binding(c, env);
+ int (*func)(int, buffer_t *, env_t *) = NULL;
+
+ for (int i = 0; key_functions[i].run; i++) {
+ if (!strcmp(cmd, key_functions[i].name)) {
+ func = key_functions[i].run;
+ break;
+ }
+ }
+ if (!func) {
+ printf("No command found with the name %s\n", cmd);
+ return;
+ }
+ if (binding)
+ binding->func = func;
+ else
+ new_binding(c, func, env);
+}
+
int builtin_bindkey(char **argv, env_t *env)
{
binding_t *tmp;
+ binding_t new_binding = {.key = 0, .func = NULL};
if (!argv[1]) {
- if (!env->bindings)
- return (0);
- for (int i = 0; env->bindings[i].func; i++)
+ for (int i = 0; env->bindings && env->bindings[i].func; i++)
print_binding(&env->bindings[i]);
} else if (!strcmp(argv[1], "-l")) {
for (int i = 0; key_functions[i].name; i++)
puts(key_functions[i].name);
} else if (!argv[2]) {
- // for (tmp = env->bindings; tmp && tmp->key != )
+ tmp = get_binding(argv[1], env);
+ if (!tmp) {
+ new_binding.key = my_parsechar(argv[1]);
+ tmp = &new_binding;
+ }
print_binding(tmp);
} else if (!argv[3]) {
-
+ set_binding(argv[1], argv[2], env);
} else
puts("Invalid usage of bindkey.");
- free(argv);
return (0);
}
\ No newline at end of file
diff --git a/src/main.c b/src/main.c
index b4bab38..be7d890 100644
--- a/src/main.c
+++ b/src/main.c
@@ -18,10 +18,11 @@ env_t *create_env(char **env)
{
env_t *envt = malloc(sizeof(*envt));
char **envcp = malloc(sizeof(char *) * (env_get_length(env) + 1));
+ int i;
if (!env || !envcp)
return (NULL);
- for (int i = 0; env[i]; i++)
+ for (i = 0; env[i]; i++)
envcp[i] = strdup(env[i]);
envcp[env_get_length(env)] = NULL;
envt->env = envcp;
@@ -29,8 +30,9 @@ env_t *create_env(char **env)
envt->history = NULL;
envt->bindings = malloc(get_emacs_bindings_size());
if (envt->bindings) {
- for (int i = 0; emacs_bindings[i].func; i++)
+ for (i = 0; emacs_bindings[i].func; i++)
envt->bindings[i] = emacs_bindings[i];
+ envt->bindings[i].func = NULL;
}
envt->window = NULL;
envt->alias = NULL;
diff --git a/src/my_ncurses/string_utils.c b/src/my_ncurses/string_utils.c
index a7f76c3..abb577b 100644
--- a/src/my_ncurses/string_utils.c
+++ b/src/my_ncurses/string_utils.c
@@ -9,6 +9,7 @@
#include
#include
#include
+#include
#include
void my_addstr(my_window *window, const char *str)
@@ -49,6 +50,17 @@ const char *my_unctrl(int c)
return (unctrl(c));
}
+int my_parsechar(const char *c)
+{
+ if (!strcmp(c, "^?"))
+ return (KEY_DC);
+ if (c[0] == '^' && c[1] == '[')
+ return (CSI(c[2] | c[3] << 8u));
+ if (c[1])
+ return (-1);
+ return (c[0]);
+}
+
void my_getmaxyx(int *y, int *x)
{
struct winsize size;