浏览代码

[Erez & Jack] Documents new Leader key functionality

Erez Zukerman 9 年之前
父节点
当前提交
f4a426a0b1

+ 46 - 10
README.md

@@ -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
   * `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
 
 `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.
@@ -258,7 +294,7 @@ if (timer_elapsed(key_timer) < 100) {
 }
 ```
 
-It's best to declare the `static uint16_t key_timer;` outside of the macro block (top of file, etc). 
+It's best to declare the `static uint16_t key_timer;` outside of the macro block (top of file, etc).
 
 #### Example 1: Single-key copy/paste (hold to copy, tap to paste)
 
@@ -276,7 +312,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
         case 0: {
             if (record->event.pressed) {
                 key_timer = timer_read(); // if the key is being pressed, we start the timer.
-            } 
+            }
             else { // this means the key was just released, so we can figure out how long it was pressed for (tap or "held down").
                 if (timer_elapsed(key_timer) > 150) { // 150 being 150ms, the threshhold we pick for counting something as a tap.
                     return MACRO( D(LCTL), T(C), U(LCTL), END  );
@@ -312,7 +348,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
                 key_timer = timer_read(); // if the key is being pressed, we start the timer.
                 register_code(KC_LSFT); // we're now holding down Shift.
             } else { // this means the key was just released, so we can figure out how long it was pressed for (tap or "held down").
-                if (timer_elapsed(key_timer) < 150) { // 150 being 150ms, the threshhold we pick for counting something as a tap. 
+                if (timer_elapsed(key_timer) < 150) { // 150 being 150ms, the threshhold we pick for counting something as a tap.
                     register_code(KC_9); // sending 9 while Shift is held down gives us an opening paren
                     unregister_code(KC_9); // now let's let go of that key
                 }
@@ -323,13 +359,13 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
         case 1: {
             if (record->event.pressed) {
                 key_timer = timer_read(); // Now we're doing the same thing, only for the right shift/close paren key
-                register_code(KC_RSFT); 
-            } else { 
-                if (timer_elapsed(key_timer) < 150) { 
-                    register_code(KC_0); 
-                    unregister_code(KC_0); 
+                register_code(KC_RSFT);
+            } else {
+                if (timer_elapsed(key_timer) < 150) {
+                    register_code(KC_0);
+                    unregister_code(KC_0);
                 }
-                unregister_code(KC_RSFT); 
+                unregister_code(KC_RSFT);
             }
             break;
         }
@@ -510,4 +546,4 @@ what things are (and likely aren't) too risky.
 - EEPROM has around a 100000 write cycle.  You shouldn't rewrite the
   firmware repeatedly and continually; that'll burn the EEPROM
   eventually.
-					
+

+ 1 - 5
keyboard/ergodox_ez/ergodox_ez.h

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

文件差异内容过多而无法显示
+ 1113 - 1087
keyboard/ergodox_ez/keymaps/erez_experimental/erez_experimental.hex


+ 51 - 28
keyboard/ergodox_ez/keymaps/erez_experimental/keymap.c

@@ -9,6 +9,7 @@
 
 #define LSFTO M(0) // Left shift, open 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] = {
 /* Keymap 0: Basic layer
@@ -27,23 +28,23 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  *                                        ,-------------.       ,-------------.
  *                                        | App  | LGui |       | Alt  |Ctrl/Esc|
  *                                 ,------|------|------|       |------+--------+------.
- *                                 |      | L1   | Home |       | PgUp |        |      |
- *                                 | Space| Tap/ |------|       |------| Tab/L1 |Enter |
- *                                 |      |Toggle| End  |       | PgDn |        |      |
+ *                                 |      |      | Home |       | PgUp |        |      |
+ *                                 | Space|Leader|------|       |------| Tab/L1 |Enter |
+ *                                 |      |      | End  |       | PgDn |        |      |
  *                                 `--------------------'       `----------------------'
  */
 // If it accepts an argument (i.e, is a function), it doesn't need KC_.
 // Otherwise, it needs KC_*
 [BASE] = KEYMAP(  // layer 0 : default
         // left hand
-        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_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),
-        LT(SYMB,KC_GRV),KC_QUOT,      LALT(KC_LSFT),  KC_LEFT, KC_RGHT,
-                                              ALT_T(KC_APP),   KC_LGUI,
-                                                               KC_HOME,
-                                                 KC_SPC,KC_FN1,KC_END,
+        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_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),
+        LT(SYMB,KC_GRV),KC_QUOT,      LALT(KC_LSFT),  KC_LEFT,  KC_RGHT,
+                                              ALT_T(KC_APP),    KC_LGUI,
+                                                                KC_HOME,
+                                                 KC_SPC,KC_LEAD,KC_END,
         // right hand
              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,
@@ -198,28 +199,50 @@ void matrix_init_user(void) {
 
 };
 
+LEADER_EXTERNS();
+
 // Runs constantly in the background, in a loop.
 void matrix_scan_user(void) {
 
-    uint8_t layer = biton32(layer_state);
+  uint8_t layer = biton32(layer_state);
 
-    ergodox_board_led_off();
-    ergodox_right_led_1_off();
-    ergodox_right_led_2_off();
-    ergodox_right_led_3_off();
-    switch (layer) {
-      // TODO: Make this relevant to the ErgoDox EZ.
-        case 1:
-            ergodox_right_led_1_on();
-            break;
-        case 2:
-            ergodox_right_led_2_on();
-            break;
-        default:
-            // none
-            break;
-    }
+  ergodox_board_led_off();
+  ergodox_right_led_1_off();
+  ergodox_right_led_2_off();
+  ergodox_right_led_3_off();
+  switch (layer) {
+    // TODO: Make this relevant to the ErgoDox EZ.
+    case 1:
+      ergodox_right_led_1_on();
+      break;
+    case 2:
+      ergodox_right_led_2_on();
+      break;
+    default:
+      // none
+      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);
+    }
+  }
 };
 
 
+

+ 6 - 0
keyboard/ergodox_ez/keymaps/erez_experimental/readme.md

@@ -4,6 +4,12 @@ This is my personal layout which I use to test out ideas which may or may not ma
 
 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:
 
 * Makes bottom-right key send minus/underscore when tapped, L1 temporary toggle when held