aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vis-cmds.c4
-rw-r--r--vis-core.h1
-rw-r--r--vis-lua.c10
-rw-r--r--vis-modes.c29
-rw-r--r--vis.c4
-rw-r--r--vis.h3
6 files changed, 44 insertions, 7 deletions
diff --git a/vis-cmds.c b/vis-cmds.c
index 606699c..969eec7 100644
--- a/vis-cmds.c
+++ b/vis-cmds.c
@@ -791,7 +791,7 @@ static bool cmd_map(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor
const char *lhs = argv[2];
char *rhs = strdup(argv[3]);
- if (!rhs || !(binding = calloc(1, sizeof *binding)))
+ if (!rhs || !(binding = vis_binding_new(vis)))
goto err;
binding->alias = rhs;
@@ -804,7 +804,7 @@ static bool cmd_map(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor
err:
if (!mapped) {
free(rhs);
- free(binding);
+ vis_binding_free(vis, binding);
}
return mapped;
}
diff --git a/vis-core.h b/vis-core.h
index f6999dc..3abe1f5 100644
--- a/vis-core.h
+++ b/vis-core.h
@@ -188,6 +188,7 @@ struct Vis {
VisEvent *event;
Array motions;
Array textobjects;
+ Array bindings;
};
enum VisEvents {
diff --git a/vis-lua.c b/vis-lua.c
index e3f355b..2c41e0f 100644
--- a/vis-lua.c
+++ b/vis-lua.c
@@ -669,8 +669,11 @@ static int keymap(lua_State *L, Vis *vis, Win *win) {
if (!key || !lua_isfunction(L, 4))
goto err;
const char *help = luaL_optstring(L, 5, NULL);
- if (!(binding = calloc(1, sizeof *binding)) || !(action = calloc(1, sizeof *action)))
+ if (!(binding = vis_binding_new(vis)))
goto err;
+ if (!(action = calloc(1, sizeof *action)))
+ goto err;
+ binding->action = action;
/* store reference to function in the registry */
lua_pushvalue(L, 4);
@@ -687,8 +690,6 @@ static int keymap(lua_State *L, Vis *vis, Win *win) {
},
};
- binding->action = action;
-
if (win) {
if (!vis_window_mode_map(win, mode, true, key, binding))
goto err;
@@ -700,8 +701,7 @@ static int keymap(lua_State *L, Vis *vis, Win *win) {
lua_pushboolean(L, true);
return 1;
err:
- free(binding);
- free(action);
+ vis_binding_free(vis, binding);
lua_pushboolean(L, false);
return 1;
}
diff --git a/vis-modes.c b/vis-modes.c
index 7008161..68771ce 100644
--- a/vis-modes.c
+++ b/vis-modes.c
@@ -2,6 +2,35 @@
#include "vis-core.h"
#include "util.h"
+KeyBinding *vis_binding_new(Vis *vis) {
+ KeyBinding *binding = calloc(1, sizeof *binding);
+ if (binding && array_add_ptr(&vis->bindings, binding))
+ return binding;
+ free(binding);
+ return NULL;
+}
+
+void vis_binding_free(Vis *vis, KeyBinding *binding) {
+ if (!binding)
+ return;
+ size_t len = array_length(&vis->bindings);
+ for (size_t i = 0; i < len; i++) {
+ if (binding == array_get_ptr(&vis->bindings, i)) {
+ if (binding->alias)
+ free((char*)binding->alias);
+ const KeyAction *action = binding->action;
+ if (action) {
+ free((char*)action->name);
+ free((char*)action->help);
+ free((KeyAction*)action);
+ }
+ free(binding);
+ array_remove(&vis->bindings, i);
+ break;
+ }
+ }
+}
+
static Mode *mode_get(Vis *vis, enum VisMode mode) {
if (mode < LENGTH(vis_modes))
return &vis_modes[mode];
diff --git a/vis.c b/vis.c
index 43f9371..4943280 100644
--- a/vis.c
+++ b/vis.c
@@ -510,6 +510,7 @@ Vis *vis_new(Ui *ui, VisEvent *event) {
vis->registers[VIS_REG_CLIPBOARD].type = REGISTER_CLIPBOARD;
array_init(&vis->motions);
array_init(&vis->textobjects);
+ array_init(&vis->bindings);
action_reset(&vis->action);
buffer_init(&vis->input_queue);
vis->keys = &vis->input_queue;
@@ -570,6 +571,9 @@ void vis_free(Vis *vis) {
map_free(vis_modes[i].bindings);
array_release_full(&vis->motions);
array_release_full(&vis->textobjects);
+ while (array_length(&vis->bindings))
+ vis_binding_free(vis, array_get_ptr(&vis->bindings, 0));
+ array_release(&vis->bindings);
free(vis->shell);
free(vis);
}
diff --git a/vis.h b/vis.h
index 3b9ede7..ef8897d 100644
--- a/vis.h
+++ b/vis.h
@@ -152,6 +152,9 @@ void vis_exit(Vis*, int status);
/* emergency exit, print given message, perform minimal ui cleanup and exit process */
void vis_die(Vis*, const char *msg, ...) __attribute__((noreturn,format(printf, 2, 3)));
+KeyBinding *vis_binding_new(Vis*);
+void vis_binding_free(Vis*, KeyBinding*);
+
enum VisMode {
VIS_MODE_NORMAL,
VIS_MODE_OPERATOR_PENDING,