]> git.donarmstrong.com Git - qmk_firmware.git/blob - docs/feature_userspace.md
Keyboard: fixed build break (size overflow) HelixPico with Backlight or Underglow...
[qmk_firmware.git] / docs / feature_userspace.md
1 # Userspace: Sharing Code Between Keymaps
2
3 If you use more than one keyboard with a similar keymap, you might see the benefit in being able to share code between them. Create your own folder in `users/` named the same as your keymap (ideally your github username, `<name>`) with the following structure:
4
5 * `/users/<name>/` (added to the path automatically)
6   * `readme.md` (optional, recommended)
7   * `rules.mk` (included automatically)
8   * `<name>.h` (optional)
9   * `<name>.c` (optional)
10   * `config.h` (optional)
11
12 `<name>.c` will need to be added to the SRC in `rules.mk` like this:
13
14     SRC += <name>.c
15
16 Additional files may be added in the same way - it's recommended you have one named `<name>`.c/.h though.
17
18 All this only happens when you build a keymap named `<name>`, like this:
19
20     make planck:<name>
21
22 For example,
23
24     make planck:jack
25
26 Will include the `/users/jack/` folder in the path, along with `/users/jack/rules.mk`.
27
28 Additionally, `config.h` here will be processed like the same file in your keymap folder.  This is handled separately from the `<name>.h` file.
29
30 The reason for this, is that `<name>.h` won't be added in time to add settings (such as `#define TAPPING_TERM 100`), and including the `<name.h>` file in any `config.h` files will result in compile issues.
31
32 So you should use the `config.h` for QMK settings, and the `<name>.h` file for user or keymap specific settings.
33
34 `/users/<name>/rules.mk` will be included in the build _after_ the `rules.mk` from your keymap. This allows you to have features in your userspace `rules.mk` that depend on individual QMK features that may or may not be available on a specific keyboard. For example, if you have RGB control features shared between all your keyboards that support RGB lighting, you can `define RGB_ENABLE` in your keymap `rules.mk` and then check for the variable in your userspace `rules.mk` like this:
35 ```make
36 ifdef RGB_ENABLE
37     # Include my fancy rgb functions source here
38 endif
39 ```
40 Because of this, any time you turn on QMK features in your `users/<name>/rules.mk`, you should conditionally enable them only if the flag isn't already defined, like this:
41 ```make
42 ifndef TAP_DANCE_ENABLE
43     TAP_DANCE_ENABLE = yes
44 endif
45 ```
46 This will ensure that you can explicitly turn off features for an individual keymap.
47
48 ## Readme
49
50 Please include authorship (your name, github username, email), and optionally [a license that's GPL compatible](https://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses).
51
52 ## `Config.h`
53
54 If you do add a `config,h` file, you want to make sure that it only gets processed once.  So you may want to start off with something like this:
55
56 ```c
57 #ifndef USERSPACE_CONFIG_H
58 #define USERSPACE_CONFIG_H
59
60 // Put normal config.h settings here:
61
62 #endif // !USERSPACE_CONFIG_H
63 ```
64
65 You can use any option hre that you could use in your keymap's `config.h` file. You can find a list of vales [here](config_options.md).
66
67 ## Example
68
69 For a brief example, checkout `/users/_example/` , or for a more detailed examples check out [`template.h`](https://github.com/qmk/qmk_firmware/blob/master/users/drashna/template.h) and [`template.c`](https://github.com/qmk/qmk_firmware/blob/master/users/drashna/template.c) in `/users/drashna/` .
70
71 ### Consolidated Macros
72
73 If you wanted to consolidate macros and other functions into your userspace for all of your keymaps, you can do that.  The issue is that you then cannot call any function defined in your userspace, or it gets complicated.  To better handle this, you can call the functions here and create new functions to use in individual keymaps.
74
75 First, you'd want to go through all of your `keymap.c` files and replace `process_record_user` with `process_record_keymap` instead.   This way, you can still use keyboard specific codes on those boards, and use your custom "global" keycodes as well.   You'll also want to replace `SAFE_RANGE` with `NEW_SAFE_RANGE` so that you wont have any overlapping keycodes
76
77 Then add `#include <name.h>` to all of your keymap.c files.  This allows you to use these new keycodes without having to redefine them in each keymap.
78
79 Once you've done that, you'll want to set the keycode definitions that you need to the `<name>.h`  file. For instance:
80 ```
81 #ifndef USERSPACE
82 #define USERSPACE
83
84 #include "quantum.h"
85
86 // Define all of
87 enum custom_keycodes {
88   KC_MAKE = SAFE_RANGE,
89   NEW_SAFE_RANGE  //use "NEW_SAFE_RANGE" for keymap specific codes
90 };
91
92 #endif
93 ```
94
95 Now you want to create the `<name>.c` file, and add this content to it:
96
97 ```
98 #include "<name>.h"
99 #include "quantum.h"
100 #include "action.h"
101 #include "version.h"
102
103 __attribute__ ((weak))
104 bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
105   return true;
106 }
107
108 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
109   switch (keycode) {
110   case KC_MAKE:
111     if (!record->event.pressed) {
112       SEND_STRING("make " QMK_KEYBOARD ":" QMK_KEYMAP
113 #if  (defined(BOOTLOADER_DFU) || defined(BOOTLOADER_LUFA_DFU) || defined(BOOTLOADER_QMK_DFU))
114        ":dfu "
115 #elif defined(BOOTLOADER_HALFKAY)
116       ":teensy "
117 #elif defined(BOOTLOADER_CATERINA)
118        ":avrdude "
119 #endif
120         SS_TAP(X_ENTER));
121     }
122     return false;
123     break;
124   }
125   return process_record_keymap(keycode, record);
126 }
127 ```
128
129 This will add a new `KC_MAKE`  keycode that can be used in any of your keymaps.  And this keycode will output `make <keyboard>:<keymap">`, making frequent compiling easier.  And this will work with any keyboard and any keymap as it will output the current boards info, so that you don't have to type this out every time.
130
131 Additionally, this should flash the newly compiled firmware automatically, using the correct utility, based on the bootloader settings (or default to just generating the HEX file). However, it should be noted that this may not work on all systems. AVRDUDE doesn't work on WSL, namely (and will dump the HEX in the ".build" folder instead).
132
133 ## Override default userspace
134
135 By default the userspace used will be the same as the keymap name. In some situations this isn't desirable. For instance, if you use the [layout](feature_layouts.md) feature you can't use the same name for different keymaps (e.g. ANSI and ISO). You can name your layouts `mylayout-ansi` and `mylayout-iso` and add the following line to your layout's `rules.mk`:
136
137 ```
138 USER_NAME := mylayout
139 ```