1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
#include "binding.h"
#include "command.h"
#include <stdlib.h>
#include <string.h>
struct keymap keymap_create(const char *name, uint32_t capacity) {
return (struct keymap){
.name = name,
.bindings = calloc(capacity, sizeof(struct binding)),
.nbindings = 0,
.capacity = capacity,
};
}
void keymap_bind_keys(struct keymap *keymap, struct binding *bindings,
uint32_t nbindings) {
if (keymap->nbindings + nbindings >= keymap->capacity) {
keymap->capacity =
nbindings > keymap->capacity * 2 ? nbindings * 2 : keymap->capacity * 2;
keymap->bindings =
realloc(keymap->bindings, sizeof(struct binding) * keymap->capacity);
}
memcpy(keymap->bindings + keymap->nbindings, bindings,
sizeof(struct binding) * nbindings);
keymap->nbindings += nbindings;
}
void keymap_destroy(struct keymap *keymap) {
free(keymap->bindings);
keymap->bindings = 0;
keymap->capacity = 0;
keymap->nbindings = 0;
}
struct lookup_result lookup_key(struct keymap *keymaps, uint32_t nkeymaps,
struct key *key, struct commands *commands) {
// lookup in order in the keymaps
for (uint32_t kmi = 0; kmi < nkeymaps; ++kmi) {
struct keymap *keymap = &keymaps[kmi];
for (uint32_t bi = 0; bi < keymap->nbindings; ++bi) {
struct binding *binding = &keymap->bindings[bi];
if (key_equal(key, &binding->key)) {
if (binding->type == BindingType_Command) {
return (struct lookup_result){
.found = true,
.type = BindingType_Command,
.command = lookup_command_by_hash(commands, binding->command),
};
} else if (binding->type == BindingType_Keymap) {
return (struct lookup_result){
.found = true,
.type = BindingType_Keymap,
.keymap = binding->keymap,
};
}
}
}
}
return (struct lookup_result){.found = false};
}
|