summaryrefslogtreecommitdiff
path: root/src/binding.c
blob: 5147c97a20930c5f7ff2516b87f7234d2d523162 (plain)
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};
}