#### 0.1.2 The default layer
The **default layer** is the base keymap layer (0-31) which is always active and considered the "bottom" of the stack. When the firmware boots, the default layer is the only active layer. It is set to layer 0 by default, though this can be changed ~~in *config.h*~~ via Boot Magic settings.
- Initial state of Keymap Change base layout
- ----------------------- ------------------
+ Initial state of Keymap Change base layout
+ ----------------------- ------------------
31 31
30 30
### 0.3 Keymap Example
-Keymap is **`keymaps[]`** C array in fact and you can define layers in it with **`KEYMAP()`** C macro and keycodes. To use complex actions you need to define `Fn` keycode in **`fn_actions[]`** array.
+The keymap is defined in the **`uint8_t keymaps[]`** array, a 2-dimensional array of rows and columns corresponding to positions in the keyboard matrix. But most often the layers are defined using C macros to allow for easier reading and editing of the keymap files. To use complex actions you need to define `Fn` action in the **`action_t fn_actions[]`** array.
-This is a keymap example for [HHKB](http://en.wikipedia.org/wiki/Happy_Hacking_Keyboard) keyboard.
-This example has three layers, 'Qwerty' as base layer, 'Cursor' and 'Mousekey'.
+This is a keymap example for the [HHKB](http://en.wikipedia.org/wiki/Happy_Hacking_Keyboard) keyboard.
+This example has three layers: the QWERTY base layer, and two overlay layers for cursor and mousekey control, respectively.
In this example,
- `Fn0` is a **momentary layer switching** key, you can use keys on Cursor layer while holding the key.
+ `Fn0` is a **momentary layer switching** key--you can use keys on the Cursor layer while holding the key.
- `Fn1` is a momentary layer switching key with tapping feature, you can get semicolon **';'** with taping the key and switch layers while holding the key. The word **'tap'** or **'tapping'** mean to press and release a key quickly.
+ `Fn1` is a momentary layer switching key with tapping function--tapping the key as one would normally use it, sends the semicolon **';'** keycode, while holding the key down switches layers.
- `Fn2` is a **toggle layer switch** key, you can stay switched layer after releasing the key unlike momentary switching.
+ `Fn2` is a **toggle layer switch** key--pressing the key toggles the layer on until you press it again.
You can find other keymap definitions in file `keymap.c` located on project directories.
- static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* 0: Qwerty
* ,-----------------------------------------------------------.
* |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \| `|
* `-----------------------------------------------------------'
* |Gui |Alt |Space |Alt |Gui|
* `--------------------------------------------'
- */
+ */
KEYMAP(PWR, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \
CAPS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PSCR,SLCK,PAUS,UP, TRNS,BSPC, \
LCTL,VOLD,VOLU,MUTE,TRNS,TRNS,PAST,PSLS,HOME,PGUP,LEFT,RGHT,ENT, \
* `-----------------------------------------------------------'
* |Gui |Alt |Mb1 |Alt | |
* `--------------------------------------------'
- * Mc: Mouse Cursor / Mb: Mouse Button / Mw: Mouse Wheel
+ * Mc: Mouse Cursor / Mb: Mouse Button / Mw: Mouse Wheel
*/
KEYMAP(ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \
TAB, TRNS,TRNS,TRNS,TRNS,TRNS,WH_L,WH_D,WH_U,WH_R,TRNS,TRNS,TRNS,BSPC, \
LGUI,LALT, BTN1, RALT,TRNS),
};
- static const uint16_t PROGMEM fn_actions[] = {
+ const action_t PROGMEM fn_actions[] = {
ACTION_LAYER_MOMENTARY(1), // FN0
ACTION_LAYER_TAP_KEY(2, KC_SCLN), // FN1
ACTION_LAYER_TOGGLE(2), // FN2
- `KC_P1` to `KC_P0`, `KC_PDOT`, `KC_PCMM`, `KC_PSLS`, `KC_PAST`, `KC_PMNS`, `KC_PPLS`, `KC_PEQL`, `KC_PENT` for keypad.
### 1.2 Modifier
-There are 8 modifiers which has discrimination between left and right.
+There are 8 modifiers which has discrimination between left and right.
- `KC_LCTL` and `KC_RCTL` for Control
- `KC_LSFT` and `KC_RSFT` for Shift
- `KC_WSCH`, `KC_WHOM`, `KC_WBAK`, `KC_WFWD`, `KC_WSTP`, `KC_WREF`, `KC_WFAV` for web browser operation
### 1.5 Fn key
-`KC_FNnn` are keycodes for `Fn` key which not given any actions at the beginning unlike most of keycodes has its own inborn action. To use these keycodes in `KEYMAP()` you need to assign action you want at first. Action of `Fn` key is defined in `fn_actions[]` and its index of the array is identical with number part of `KC_FNnn`. Thus `KC_FN0` keycode indicates the action defined in first element of the array. ***32 `Fn` keys can be defined at most.***
+`KC_FNnn` are keycodes for `Fn` key which not given any actions at the beginning unlike most of keycodes has its own inborn action. To use these keycodes in `KEYMAP()` you need to assign action you want at first. Action of `Fn` key is defined in `action_t fn_actions[]` and its index of the array is identical with number part of `KC_FNnn`. Thus `KC_FN0` keycode indicates the action defined in first element of the array. ***32 `Fn` keys can be defined at most.***
### 1.6 Keycode Table
See keycode table in [`doc/keycode.txt`](./keycode.txt) for description of keycodes.
ACTION_KEY(KC_LSFT)
#### 2.1.2 Modified key
-This action is comprised of strokes of modifiers and a key. `Macro` action is needed if you want more complex key strokes.
+This action is comprised of modifiers and a key.
-Say you want to assign a key to `Shift + 1` to get character *'!'* or `Alt + Tab` to switch application windows.
+Modified keys can be defined as below. Say you want to assign a key to `Shift + 1` to get character *'!'* or `Alt + Tab` to switch application windows.
ACTION_MODS_KEY(MOD_LSFT, KC_1)
ACTION_MODS_KEY(MOD_LALT, KC_TAB)
+ ACTION_MODS_KEY(MOD_LALT | MOD_LSFT, KC_TAB)
-Or `Alt,Shift + Tab` can be defined. `ACTION_MODS_KEY(mods, key)` requires **4-bit modifier state** and a **keycode** as arguments. See `keycode.h` for `MOD_BIT()` macro.
+These are identical to examples above.
- ACTION_MODS_KEY(MOD_LALT | MOD_LSFT, KC_TAB)
+ ACTION_KEY(MOD_LSFT | KC_1)
+ ACTION_KEY(MOD_LALT | KC_TAB)
+ ACTION_KEY(MOD_LSFT | MOD_LALT | KC_TAB)
#### 2.1.3 Multiple Modifiers
Registers multiple modifiers with pressing a key. To specify multiple modifiers use `|`.
- ACTION_MODS(MOD_ALT | MOD_LSFT)
+ ACTION_MODS(MOD_LALT | MOD_LSFT)
+ ACTION_MODS(MOD_LALT | MOD_LSFT | MOD_LCTL)
+
+These are identical to examples above.
+
+ ACTION_KEY(MOD_LALT | MOD_LSFT, KC_NO)
+ ACTION_KEY(MOD_LALT | MOD_LSFT | MOD_LCTL, KC_NO)
#### 2.1.3 Modifier with Tap key([Dual role][dual_role])
Works as a modifier key while holding, but registers a key on tap(press and release quickly).
ACTION_DEFAULT_LAYER_SET(layer)
-#### 2.2.2 Momentary
+#### 2.2.2 Momentary
Turns on `layer` momentarily while holding, in other words it activates when key is pressed and deactivate when released.
ACTION_LAYER_MOMENTARY(layer)
ACTION_DEFAULT_LAYER_BIT_SET(part, bits)
-
### 2.3 Macro action
-***TBD***
+`Macro` actions allow you to register a complex sequence of keystrokes when a key is pressed, where macros are simple sequences of keypresses.
+
+ ACTION_MACRO(id)
+ ACTION_MACRO_TAP(id)
+
+`id` is an 8-bit user-defined value the macro getter function can use to pick the specific macro.
+
+
+#### 2.3.1 Implementing Macro getter function
+To implement `macro` functions, the macro lookup list must be implemented:
-`Macro` action indicates complex key strokes.
-
- MACRO( D(LSHIFT), D(D), END )
- MACRO( U(D), U(LSHIFT), END )
- MACRO( I(255), T(H), T(E), T(L), T(L), W(255), T(O), END )
+ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt);
-#### 2.3.1 Macro Commands
-- **MACRO()**
-- **MACRO_NONE**
+The function must always return a valid macro, and default implementation of `action_get_macro` always returns `MACRO_NONE` which has no effect.
+
+#### 2.3.1.1 Limitations
+Similar to the Function Action system, the selector functions is passed a `keyrecord_t` object, so it can inspect the key state (e.g. different macros on key press or release), and key itself.
+
+Unlike the Function Action system,`macros` are pre-recorded key sequences, so you can only select from a list. If you want to use dynamic macros then you should look at the more complex function action system.
+
+#### 2.3.2 Implementing/Defining Macro sequences
+Macros are of the form (must be wrapped by the `MACRO` function, and end with an `END` mark)
+
+ MACRO( ..., END )
+
+Within each macro, the following commands can be used:
- **I()** change interval of stroke.
- **D()** press key
- **SM()** store modifier state
- **RM()** restore modifier state
- **CM()** clear modifier state
-- **END** end mark
+
+e.g.:
+
+ MACRO( D(LSHIFT), D(D), END ) // hold down LSHIFT and D - will print 'D'
+ MACRO( U(D), U(LSHIFT), END ) // release U and LSHIFT keys (an event.pressed == False counterpart for the one above)
+ MACRO( I(255), T(H), T(E), T(L), T(L), W(255), T(O), END ) // slowly print out h-e-l-l---o
#### 2.3.2 Examples
-***TBD***
+
+in keymap.c, define `action_get_macro`
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
switch (id) {
- case HELLO:
+ case 0:
return (record->event.pressed ?
MACRO( I(0), T(H), T(E), T(L), T(L), W(255), T(O), END ) :
MACRO_NONE );
- case ALT_TAB:
+ case 1:
return (record->event.pressed ?
MACRO( D(LALT), D(TAB), END ) :
MACRO( U(TAB), END ));
return MACRO_NONE;
}
+in keymap.c, bind items in `fn_actions` to the macro function
+ const action_t PROGMEM fn_actions[] = {
+ [0] = ACTION_MACRO(0), // will print 'hello' for example
+ [1] = ACTION_MACRO(1),
+ };
### 2.4 Function action
#### 2.4.3 Implement user function
`Function` actions can be defined freely with C by user in callback function:
- void keymap_call_function(keyrecord_t *event, uint8_t id, uint8_t opt)
+ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt);
This C function is called every time key is operated, argument `id` selects action to be performed and `opt` can be used for option. Function `id` can be 0-255 and `opt` can be 0-15.
ACTION_LAYER_MODS(2, MOD_LSFT | MOD_LALT)
+You can combine four modifiers at most but cannot use both left and right modifiers at a time, either left or right modiiers only can be allowed.
## 4. Tapping
In following setting example, `Fn0`, `Fn1` and `Fn2` switch layer to 1, 2 and 2 respectively. `Fn2` registers `Space` key when tapping while `Fn0` and `Fn1` doesn't send any key.
- static const uint8_t PROGMEM fn_layer[] = {
+ const uint8_t PROGMEM fn_layer[] = {
1, // Fn0
2, // Fn1
2, // Fn2
};
- static const uint8_t PROGMEM fn_keycode[] = {
+ const uint8_t PROGMEM fn_keycode[] = {
KC_NO, // Fn0
KC_NO, // Fn1
KC_SPC, // Fn2