summaryrefslogtreecommitdiff
path: root/src/main/bindings.c
diff options
context:
space:
mode:
authorAlbert Cervin <albert@acervin.com>2023-11-26 23:08:06 +0100
committerAlbert Cervin <albert@acervin.com>2024-01-15 10:39:56 +0100
commit64d6816a36567274551dd4f067fe4d05b1445cc0 (patch)
tree50f8dc895d363ab391d30226f665870d8ce263b5 /src/main/bindings.c
parentc87888f10dfb54590c5aae8311b7aff887193d9a (diff)
downloaddged-64d6816a36567274551dd4f067fe4d05b1445cc0.tar.gz
dged-64d6816a36567274551dd4f067fe4d05b1445cc0.tar.xz
dged-64d6816a36567274551dd4f067fe4d05b1445cc0.zip
Completion rework
- Add support for building with clang Also fix some annoying bugs: - Visual column was wrong when using tabs - Add shift-tab for inserting an actual tab - Fix minibuffer sometimes having dot above it
Diffstat (limited to 'src/main/bindings.c')
-rw-r--r--src/main/bindings.c129
1 files changed, 65 insertions, 64 deletions
diff --git a/src/main/bindings.c b/src/main/bindings.c
index 0e01306..32dcbdb 100644
--- a/src/main/bindings.c
+++ b/src/main/bindings.c
@@ -3,16 +3,19 @@
#include "dged/minibuffer.h"
#include "dged/vec.h"
+#include "bindings.h"
+
static struct keymap g_global_keymap, g_ctrlx_map, g_windows_keymap,
g_buffer_default_keymap;
struct buffer_keymap {
+ buffer_keymap_id id;
struct buffer *buffer;
- bool active;
struct keymap keymap;
};
static VEC(struct buffer_keymap) g_buffer_keymaps;
+static buffer_keymap_id g_current_keymap_id;
void set_default_buffer_bindings(struct keymap *keymap) {
struct binding buffer_bindings[] = {
@@ -46,6 +49,7 @@ void set_default_buffer_bindings(struct keymap *keymap) {
BINDING(ENTER, "newline"),
BINDING(TAB, "indent"),
+ BINDING(Spec, 'Z', "insert-tab"),
BINDING(Ctrl, 'K', "kill-line"),
BINDING(DELETE, "delete-char"),
@@ -68,7 +72,18 @@ void set_default_buffer_bindings(struct keymap *keymap) {
sizeof(buffer_bindings) / sizeof(buffer_bindings[0]));
}
-struct keymap *register_bindings() {
+int32_t execute(struct command_ctx ctx, int argc, const char *argv[]) {
+ // TODO: this should be more lib-like
+ return minibuffer_execute();
+}
+
+static struct command execute_minibuffer_command = {
+ .fn = execute,
+ .name = "minibuffer-execute",
+ .userdata = NULL,
+};
+
+void init_bindings() {
g_global_keymap = keymap_create("global", 32);
g_ctrlx_map = keymap_create("c-x", 32);
g_windows_keymap = keymap_create("c-x w", 32);
@@ -122,93 +137,79 @@ struct keymap *register_bindings() {
sizeof(ctrlx_bindings) / sizeof(ctrlx_bindings[0]));
VEC_INIT(&g_buffer_keymaps, 32);
+ g_current_keymap_id = 0;
- return &g_global_keymap;
+ /* Minibuffer binds.
+ * This map is actually never removed so forget about the id.
+ */
+ struct binding minibuffer_binds[] = {
+ ANONYMOUS_BINDING(ENTER, &execute_minibuffer_command),
+ };
+ struct keymap minibuffer_map = keymap_create("minibuffer", 8);
+ keymap_bind_keys(&minibuffer_map, minibuffer_binds,
+ sizeof(minibuffer_binds) / sizeof(minibuffer_binds[0]));
+ buffer_add_keymap(minibuffer_buffer(), minibuffer_map);
}
-struct keymap *buffer_default_bindings() {
- return &g_buffer_default_keymap;
-}
+buffer_keymap_id buffer_add_keymap(struct buffer *buffer,
+ struct keymap keymap) {
+ buffer_keymap_id id = ++g_current_keymap_id;
+ VEC_PUSH(&g_buffer_keymaps, ((struct buffer_keymap){
+ .id = id,
+ .buffer = buffer,
+ .keymap = keymap,
+ }));
-int32_t execute(struct command_ctx ctx, int argc, const char *argv[]) {
- // TODO: this should be more lib-like
- return minibuffer_execute();
+ return id;
}
-static struct command execute_minibuffer_command = {
- .fn = execute,
- .name = "minibuffer-execute",
- .userdata = NULL,
-};
-
-void buffer_bind_keys(struct buffer *buffer, struct binding *bindings,
- uint32_t nbindings) {
- struct buffer_keymap *target = NULL;
- VEC_FOR_EACH(&g_buffer_keymaps, struct buffer_keymap * km) {
- if (buffer == km->buffer) {
- target = km;
+void buffer_remove_keymap(buffer_keymap_id id) {
+ VEC_FOR_EACH_INDEXED(&g_buffer_keymaps, struct buffer_keymap * km, i) {
+ if (km->id == id) {
+ VEC_SWAP(&g_buffer_keymaps, i, VEC_SIZE(&g_buffer_keymaps) - 1);
+ VEC_POP(&g_buffer_keymaps, struct buffer_keymap removed);
+ keymap_destroy(&removed.keymap);
}
}
+}
- if (target == NULL) {
- struct buffer_keymap new = (struct buffer_keymap){
- .buffer = buffer,
- .active = false,
- };
- VEC_PUSH(&g_buffer_keymaps, new);
- target = VEC_BACK(&g_buffer_keymaps);
- }
+uint32_t buffer_keymaps(struct buffer *buffer, struct keymap *keymaps[],
+ uint32_t max_nkeymaps) {
+ uint32_t nkeymaps = 0;
- if (!target->active) {
- target->keymap = keymap_create("buffer-overlay-keys", 32);
- target->active = true;
- set_default_buffer_bindings(&target->keymap);
+ // global keybinds
+ if (nkeymaps < max_nkeymaps) {
+ keymaps[nkeymaps] = &g_global_keymap;
+ ++nkeymaps;
}
- keymap_bind_keys(&target->keymap, bindings, nbindings);
-}
-
-// TODO: do something better
-void reset_buffer_keys(struct buffer *buffer) {
- VEC_FOR_EACH(&g_buffer_keymaps, struct buffer_keymap * km) {
- if (buffer == km->buffer) {
- keymap_destroy(&km->keymap);
- km->active = false;
- }
+ // buffer keybinds
+ if (nkeymaps < max_nkeymaps) {
+ keymaps[nkeymaps] = &g_buffer_default_keymap;
+ ++nkeymaps;
}
-}
-struct keymap *buffer_keymap(struct buffer *buffer) {
- VEC_FOR_EACH(&g_buffer_keymaps, struct buffer_keymap * km) {
- if (buffer == km->buffer && km->active) {
- return &km->keymap;
+ // keybinds specific to this buffer
+ if (nkeymaps < max_nkeymaps) {
+ VEC_FOR_EACH(&g_buffer_keymaps, struct buffer_keymap * km) {
+ if (buffer == km->buffer && nkeymaps < max_nkeymaps) {
+ keymaps[nkeymaps] = &km->keymap;
+ ++nkeymaps;
+ }
}
}
- return &g_buffer_default_keymap;
+ return nkeymaps;
}
-void reset_minibuffer_keys(struct buffer *minibuffer) {
- reset_buffer_keys(minibuffer);
- struct binding bindings[] = {
- ANONYMOUS_BINDING(ENTER, &execute_minibuffer_command),
- };
-
- buffer_bind_keys(minibuffer, bindings,
- sizeof(bindings) / sizeof(bindings[0]));
-}
-
-void destroy_keymaps() {
+void destroy_bindings() {
keymap_destroy(&g_windows_keymap);
keymap_destroy(&g_global_keymap);
keymap_destroy(&g_ctrlx_map);
keymap_destroy(&g_buffer_default_keymap);
VEC_FOR_EACH(&g_buffer_keymaps, struct buffer_keymap * km) {
- if (km->active) {
- keymap_destroy(&km->keymap);
- km->active = false;
- }
+ keymap_destroy(&km->keymap);
}
VEC_DESTROY(&g_buffer_keymaps);