[Erez & Jack] Documents new Leader key functionality

daktil_thumb_popravljen
Erez Zukerman 2016-05-24 22:37:25 -04:00
parent 287eb7ad14
commit f4a426a0b1
5 changed files with 1217 additions and 1130 deletions

View File

@ -118,6 +118,42 @@ We've added shortcuts to make common modifier/tap (mod-tap) mappings more compac
* `LCAG_T(kc)` - is CtrlAltGui when held and *kc* when tapped * `LCAG_T(kc)` - is CtrlAltGui when held and *kc* when tapped
* `MEH_T(kc)` - is like Hyper, but not as cool -- does not include the Cmd/Win key, so just sends Alt+Ctrl+Shift. * `MEH_T(kc)` - is like Hyper, but not as cool -- does not include the Cmd/Win key, so just sends Alt+Ctrl+Shift.
### The Leader key: A new kind of modifier
If you've ever used Vim, you know what a Leader key is. If not, you're about to discover a wonderful concept. :) Instead of hitting Alt+Shift+W for example (holding down three keys at the same time), what if you could hit a _sequence_ of keys instead? So you'd hit our special modifier (the Leader key), followed by W and then C (just a rapid succession of keys), and something would happen.
That's what `KC_LEAD` does. Here's an example:
1. Pick a key on your keyboard you want to use as the Leader key. Assign it the keycode `KC_LEAD`. This key would be dedicated just for this -- it's a single action key, can't be used for anything else.
2. Include the line `#define LEADER_TIMEOUT 300` somewhere in your keymap.c file, probably near the top. The 300 there is 300ms -- that's how long you have for the sequence of keys following the leader. You can tweak this value for comfort, of course.
3. Within your `matrix_scan_user` function, do something like this:
```
void matrix_scan_user(void) {
LEADER_DICTIONARY() {
leading = false;
leader_end();
SEQ_ONE_KEY(KC_F) {
register_code(KC_S);
unregister_code(KC_S);
}
SEQ_TWO_KEYS(KC_A, KC_S) {
register_code(KC_H);
unregister_code(KC_H);
}
SEQ_THREE_KEYS(KC_A, KC_S, KC_D) {
register_code(KC_LGUI);
register_code(KC_S);
unregister_code(KC_S);
unregister_code(KC_LGUI);
}
}
}
```
As you can see, you have three function. you can use - `SEQ_ONE_KEY` for single-key sequences (Leader followed by just one key), and `SEQ_TWO_KEYS` and `SEQ_THREE_.EYS` for longer sequences. Each of these accepts one or more keycodes as arguments. This is an important point: You can use keycodes from **any layer on your keyboard**. That layer would need to be active for the leader macro to fire, obviously.
### Temporarily setting the default layer ### Temporarily setting the default layer
`DF(layer)` - sets default layer to *layer*. The default layer is the one at the "bottom" of the layer stack - the ultimate fallback layer. This currently does not persist over power loss. When you plug the keyboard back in, layer 0 will always be the default. It is theoretically possible to work around that, but that's not what `DF` does. `DF(layer)` - sets default layer to *layer*. The default layer is the one at the "bottom" of the layer stack - the ultimate fallback layer. This currently does not persist over power loss. When you plug the keyboard back in, layer 0 will always be the default. It is theoretically possible to work around that, but that's not what `DF` does.

View File

@ -1,13 +1,9 @@
#ifndef ERGODOX_EZ_H #ifndef ERGODOX_EZ_H
#define ERGODOX_EZ_H #define ERGODOX_EZ_H
#include "matrix.h" #include "quantum.h"
#include "keymap_common.h"
#include "backlight.h"
#include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <avr/io.h>
#include "i2cmaster.h" #include "i2cmaster.h"
#include <util/delay.h> #include <util/delay.h>

View File

@ -9,6 +9,7 @@
#define LSFTO M(0) // Left shift, open parens when tapped #define LSFTO M(0) // Left shift, open parens when tapped
#define RSFTC M(1) // Right shift, close parens when tapped #define RSFTC M(1) // Right shift, close parens when tapped
#define LEADER_TIMEOUT 300
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Basic layer /* Keymap 0: Basic layer
@ -27,23 +28,23 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* ,-------------. ,-------------. * ,-------------. ,-------------.
* | App | LGui | | Alt |Ctrl/Esc| * | App | LGui | | Alt |Ctrl/Esc|
* ,------|------|------| |------+--------+------. * ,------|------|------| |------+--------+------.
* | | L1 | Home | | PgUp | | | * | | | Home | | PgUp | | |
* | Space| Tap/ |------| |------| Tab/L1 |Enter | * | Space|Leader|------| |------| Tab/L1 |Enter |
* | |Toggle| End | | PgDn | | | * | | | End | | PgDn | | |
* `--------------------' `----------------------' * `--------------------' `----------------------'
*/ */
// If it accepts an argument (i.e, is a function), it doesn't need KC_. // If it accepts an argument (i.e, is a function), it doesn't need KC_.
// Otherwise, it needs KC_* // Otherwise, it needs KC_*
[BASE] = KEYMAP( // layer 0 : default [BASE] = KEYMAP( // layer 0 : default
// left hand // left hand
KC_EQL, KC_1, KC_2, KC_3, KC_4, KC_5, KC_LEFT, KC_EQL, KC_1, KC_2, KC_3, KC_4, KC_5, KC_LEFT,
KC_DELT, KC_Q, KC_W, KC_E, KC_R, KC_T, TG(SYMB), KC_DELT, KC_Q, KC_W, KC_E, KC_R, KC_T, TG(SYMB),
KC_BSPC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_BSPC, KC_A, KC_S, KC_D, KC_F, KC_G,
LSFTO, CTL_T(KC_Z), KC_X, KC_C, KC_V, KC_B, ALL_T(KC_LBRC), LSFTO, CTL_T(KC_Z), KC_X, KC_C, KC_V, KC_B, ALL_T(KC_LBRC),
LT(SYMB,KC_GRV),KC_QUOT, LALT(KC_LSFT), KC_LEFT, KC_RGHT, LT(SYMB,KC_GRV),KC_QUOT, LALT(KC_LSFT), KC_LEFT, KC_RGHT,
ALT_T(KC_APP), KC_LGUI, ALT_T(KC_APP), KC_LGUI,
KC_HOME, KC_HOME,
KC_SPC,KC_FN1,KC_END, KC_SPC,KC_LEAD,KC_END,
// right hand // right hand
KC_RGHT, KC_6,KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_RGHT, KC_6,KC_7, KC_8, KC_9, KC_0, KC_MINS,
TG(SYMB), KC_Y,KC_U, KC_I, KC_O, KC_P, KC_BSLS, TG(SYMB), KC_Y,KC_U, KC_I, KC_O, KC_P, KC_BSLS,
@ -198,28 +199,50 @@ void matrix_init_user(void) {
}; };
LEADER_EXTERNS();
// Runs constantly in the background, in a loop. // Runs constantly in the background, in a loop.
void matrix_scan_user(void) { void matrix_scan_user(void) {
uint8_t layer = biton32(layer_state); uint8_t layer = biton32(layer_state);
ergodox_board_led_off(); ergodox_board_led_off();
ergodox_right_led_1_off(); ergodox_right_led_1_off();
ergodox_right_led_2_off(); ergodox_right_led_2_off();
ergodox_right_led_3_off(); ergodox_right_led_3_off();
switch (layer) { switch (layer) {
// TODO: Make this relevant to the ErgoDox EZ. // TODO: Make this relevant to the ErgoDox EZ.
case 1: case 1:
ergodox_right_led_1_on(); ergodox_right_led_1_on();
break; break;
case 2: case 2:
ergodox_right_led_2_on(); ergodox_right_led_2_on();
break; break;
default: default:
// none // none
break; break;
}
LEADER_DICTIONARY() {
leading = false;
leader_end();
SEQ_ONE_KEY(KC_W) {
register_code(KC_LALT);
register_code(KC_F4);
unregister_code(KC_F4);
unregister_code(KC_LALT);
} }
SEQ_ONE_KEY(KC_O) {
register_code(KC_LCTL);
register_code(KC_LSFT);
register_code(KC_O);
unregister_code(KC_O);
unregister_code(KC_LSFT);
unregister_code(KC_LCTL);
}
}
}; };

View File

@ -4,6 +4,12 @@ This is my personal layout which I use to test out ideas which may or may not ma
Changelog: Changelog:
## May 24, 2016:
* Implements Leader key example
* Leader, W sends Alt-F4
* Leader, O sends Ctrl-shift-o (a shortcut I use in FrontApp)
## May 8, 2016: ## May 8, 2016:
* Makes bottom-right key send minus/underscore when tapped, L1 temporary toggle when held * Makes bottom-right key send minus/underscore when tapped, L1 temporary toggle when held