1 """Functions that help you work with QMK keymaps.
6 from traceback import format_exc
9 from qmk.errors import NoSuchKeyboardError
11 # The `keymap.c` template to use when a keyboard doesn't have its own
12 DEFAULT_KEYMAP_C = """#include QMK_KEYBOARD_H
14 /* THIS FILE WAS GENERATED!
16 * This file was generated by qmk-compile-json. You may or may not want to
20 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
26 def template(keyboard):
27 """Returns the `keymap.c` template for a keyboard.
29 If a template exists in `keyboards/<keyboard>/templates/keymap.c` that
30 text will be used instead of `DEFAULT_KEYMAP_C`.
34 The keyboard to return a template for.
36 template_name = 'keyboards/%s/templates/keymap.c' % keyboard
38 if os.path.exists(template_name):
39 with open(template_name, 'r') as fd:
42 return DEFAULT_KEYMAP_C
45 def generate(keyboard, layout, layers):
46 """Returns a keymap.c for the specified keyboard, layout, and layers.
50 The name of the keyboard
53 The LAYOUT macro this keymap uses.
56 An array of arrays describing the keymap. Each item in the inner array should be a string that is a valid QMK keycode.
59 for layer_num, layer in enumerate(layers):
61 layer_txt[-1] = layer_txt[-1] + ','
62 layer_keys = ', '.join(layer)
63 layer_txt.append('\t[%s] = %s(%s)' % (layer_num, layout, layer_keys))
65 keymap = '\n'.join(layer_txt)
66 keymap_c = template(keyboard, keymap)
68 return keymap_c.replace('__KEYMAP_GOES_HERE__', keymap)
71 def write(keyboard, keymap, layout, layers):
72 """Generate the `keymap.c` and write it to disk.
74 Returns the filename written to.
78 The name of the keyboard
81 The name of the keymap
84 The LAYOUT macro this keymap uses.
87 An array of arrays describing the keymap. Each item in the inner array should be a string that is a valid QMK keycode.
89 keymap_c = generate(keyboard, layout, layers)
90 keymap_path = qmk.path.keymap(keyboard)
91 keymap_dir = os.path.join(keymap_path, keymap)
92 keymap_file = os.path.join(keymap_dir, 'keymap.c')
94 if not os.path.exists(keymap_dir):
95 os.makedirs(keymap_dir)
97 with open(keymap_file, 'w') as keymap_fd:
98 keymap_fd.write(keymap_c)