qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

auto_shift.md (14428B)


      1 # Auto Shift: Why Do We Need a Shift Key?
      2 
      3 Tap a key and you get its character. Tap a key, but hold it *slightly* longer
      4 and you get its shifted state. VoilĂ ! No shift key needed!
      5 
      6 ## Why Auto Shift?
      7 
      8 Many people suffer from various forms of RSI. A common cause is stretching your
      9 fingers repetitively long distances. For us on the keyboard, the pinky does that
     10 all too often when reaching for the shift key. Auto Shift looks to alleviate that
     11 problem.
     12 
     13 ## How Does It Work?
     14 
     15 When you tap a key, it stays depressed for a short period of time before it is
     16 then released. This depressed time is a different length for everyone. Auto Shift
     17 defines a constant `AUTO_SHIFT_TIMEOUT` which is typically set to twice your
     18 normal pressed state time. When you press a key, a timer starts, and if you
     19 have not released the key after the `AUTO_SHIFT_TIMEOUT` period, then a shifted
     20 version of the key is emitted. If the time is less than the `AUTO_SHIFT_TIMEOUT`
     21 time, or you press another key, then the normal state is emitted.
     22 
     23 If `AUTO_SHIFT_REPEAT` is defined, there is keyrepeat support. Holding the key
     24 down will repeat the shifted key, though this can be disabled with
     25 `AUTO_SHIFT_NO_AUTO_REPEAT`. If you want to repeat the normal key, then tap it
     26 once then immediately (within `TAPPING_TERM`) hold it down again (this works
     27 with the shifted value as well if auto-repeat is disabled).
     28 
     29 There are also the `get_auto_shift_repeat` and `get_auto_shift_no_auto_repeat`
     30 functions for more granular control. Neither will have an effect unless
     31 `AUTO_SHIFT_REPEAT_PER_KEY` or `AUTO_SHIFT_NO_AUTO_REPEAT_PER_KEY` respectively
     32 are defined.
     33 
     34 ## Are There Limitations to Auto Shift?
     35 
     36 Yes, unfortunately.
     37 
     38 1. You will have characters that are shifted when you did not intend on shifting, and
     39    other characters you wanted shifted, but were not. This simply comes down to
     40    practice. As we get in a hurry, we think we have hit the key long enough for a
     41    shifted version, but we did not. On the other hand, we may think we are tapping
     42    the keys, but really we have held it for a little longer than anticipated.
     43 2. Additionally, with keyrepeat the desired shift state can get mixed up. It will
     44    always 'belong' to the last key pressed. For example, keyrepeating a capital
     45    and then tapping something lowercase (whether or not it's an Auto Shift key)
     46    will result in the capital's *key* still being held, but shift not.
     47 3. Auto Shift does not apply to Tap Hold keys. For automatic shifting of Tap Hold
     48    keys see [Retro Shift](#retro-shift).
     49 
     50 ## How Do I Enable Auto Shift?
     51 
     52 Add to your `rules.mk` in the keymap folder:
     53 
     54 ```
     55 AUTO_SHIFT_ENABLE = yes
     56 ```
     57 
     58 If no `rules.mk` exists, you can create one.
     59 
     60 Then compile and install your new firmware with Auto Key enabled! That's it!
     61 
     62 ## Modifiers
     63 
     64 By default, Auto Shift is disabled for any key press that is accompanied by one or more
     65 modifiers. Thus, Ctrl+A that you hold for a really long time is not the same
     66 as Ctrl+Shift+A.
     67 
     68 You can re-enable Auto Shift for modifiers by adding a define to your `config.h`
     69 
     70 ```c
     71 #define AUTO_SHIFT_MODIFIERS
     72 ```
     73 
     74 In which case, Ctrl+A held past the `AUTO_SHIFT_TIMEOUT` will be sent as Ctrl+Shift+A
     75 
     76 
     77 ## Configuring Auto Shift
     78 
     79 If desired, there is some configuration that can be done to change the
     80 behavior of Auto Shift. This is done by setting various variables the
     81 `config.h` file located in your keymap folder. If no `config.h` file exists, you can create one.
     82 
     83 A sample is
     84 
     85 ```c
     86 #pragma once
     87 
     88 #define AUTO_SHIFT_TIMEOUT 150
     89 #define NO_AUTO_SHIFT_SPECIAL
     90 ```
     91 
     92 ### AUTO_SHIFT_TIMEOUT (Value in ms)
     93 
     94 This controls how long you have to hold a key before you get the shifted state.
     95 Obviously, this is different for everyone. For the common person, a setting of
     96 135 to 150 works great. However, one should start with a value of at least 175, which
     97 is the default value. Then work down from there. The idea is to have the shortest time required to get the shifted state without having false positives.
     98 
     99 Play with this value until things are perfect. Many find that all will work well
    100 at a given value, but one or two keys will still emit the shifted state on
    101 occasion. This is simply due to habit and holding some keys a little longer
    102 than others. Once you find this value, work on tapping your problem keys a little
    103 quicker than normal and you will be set.
    104 
    105 ::: tip
    106 Auto Shift has three special keys that can help you get this value right very quick. See "Auto Shift Setup" for more details!
    107 :::
    108 
    109 For more granular control of this feature, you can add the following to your `config.h`:
    110 
    111 ```c
    112 #define AUTO_SHIFT_TIMEOUT_PER_KEY
    113 ```
    114 
    115 You can then add the following function to your keymap:
    116 
    117 ```c
    118 uint16_t get_autoshift_timeout(uint16_t keycode, keyrecord_t *record) {
    119     switch(keycode) {
    120         case AUTO_SHIFT_NUMERIC:
    121             return 2 * get_generic_autoshift_timeout();
    122         case AUTO_SHIFT_SPECIAL:
    123             return get_generic_autoshift_timeout() + 50;
    124         case AUTO_SHIFT_ALPHA:
    125         default:
    126             return get_generic_autoshift_timeout();
    127     }
    128 }
    129 ```
    130 
    131 Note that you cannot override individual keys that are in one of those groups
    132 if you are using them; trying to add a case for `KC_A` in the above example will
    133 not compile as `AUTO_SHIFT_ALPHA` is there. A possible solution is a second switch
    134 above to handle individual keys with no default case and only referencing the
    135 groups in the below fallback switch.
    136 
    137 ### NO_AUTO_SHIFT_SPECIAL (simple define)
    138 
    139 Do not Auto Shift special keys, which include -\_, =+, [{, ]}, ;:, '", ,<, .>,
    140 /?, and the KC_TAB.
    141 
    142 ### NO_AUTO_SHIFT_TAB (simple define)
    143 
    144 Do not Auto Shift KC_TAB but leave Auto Shift enabled for the other special
    145 characters.
    146 
    147 ### NO_AUTO_SHIFT_SYMBOLS (simple define)
    148 
    149 Do not Auto Shift symbol keys, which include -\_, =+, [{, ]}, ;:, '", ,<, .>,
    150 and /?.
    151 
    152 ### NO_AUTO_SHIFT_NUMERIC (simple define)
    153 
    154 Do not Auto Shift numeric keys, zero through nine.
    155 
    156 ### NO_AUTO_SHIFT_ALPHA (simple define)
    157 
    158 Do not Auto Shift alpha characters, which include A through Z.
    159 
    160 ### AUTO_SHIFT_ENTER (simple define)
    161 
    162 Auto Shift the enter key.
    163 
    164 ### Auto Shift Per Key
    165 
    166 There are functions that allows you to determine which keys should be autoshifted, much like the tap-hold keys.
    167 
    168 The first of these, used to simply add a key to Auto Shift, is `get_custom_auto_shifted_key`:
    169 
    170 ```c
    171 bool get_custom_auto_shifted_key(uint16_t keycode, keyrecord_t *record) {
    172     switch(keycode) {
    173         case KC_DOT:
    174             return true;
    175         default:
    176             return false;
    177     }
    178 }
    179 ```
    180 
    181 For more granular control, there is `get_auto_shifted_key`. The default function looks like this:
    182 
    183 ```c
    184 bool get_auto_shifted_key(uint16_t keycode, keyrecord_t *record) {
    185     switch (keycode) {
    186 # ifndef NO_AUTO_SHIFT_ALPHA
    187         case AUTO_SHIFT_ALPHA:
    188 # endif
    189 # ifndef NO_AUTO_SHIFT_NUMERIC
    190         case AUTO_SHIFT_NUMERIC:
    191 # endif
    192 # ifndef NO_AUTO_SHIFT_SPECIAL
    193 # ifndef NO_AUTO_SHIFT_TAB
    194         case KC_TAB:
    195 #        endif
    196 # ifndef NO_AUTO_SHIFT_SYMBOLS
    197         case AUTO_SHIFT_SYMBOLS:
    198 #        endif
    199 # endif
    200 # ifdef AUTO_SHIFT_ENTER
    201         case KC_ENT:
    202 # endif
    203             return true;
    204     }
    205     return get_custom_auto_shifted_key(keycode, record);
    206 }
    207 ```
    208 
    209 This functionality is enabled by default, and does not need a define.
    210 
    211 ### AUTO_SHIFT_REPEAT (simple define)
    212 
    213 Enables keyrepeat.
    214 
    215 ### AUTO_SHIFT_NO_AUTO_REPEAT (simple define)
    216 
    217 Disables automatically keyrepeating when `AUTO_SHIFT_TIMEOUT` is exceeded.
    218 
    219 
    220 ### AUTO_SHIFT_ALPHA (predefined key group)
    221 
    222 A predefined group of keys representing A through Z.
    223 
    224 ### AUTO_SHIFT_NUMERIC (predefined key group)
    225 
    226 A predefined group of keys representing 0 through 9. Note, these are defined as
    227 1 through 0 since that is the order they normally appear in.
    228 
    229 ### AUTO_SHIFT_SYMBOLS (predefined key group)
    230 
    231 A predefined group of keys representing symbolic characters which include -\_, =+, [{, ]}, ;:, '", ,<, .>,
    232 and /?.
    233 
    234 ### AUTO_SHIFT_SPECIAL (predefined key group)
    235 
    236 A predefined group of keys that combines AUTO_SHIFT_SYMBOLS and KC_TAB.
    237 
    238 ## Custom Shifted Values
    239 
    240 Especially on small keyboards, the default shifted value for many keys is not
    241 optimal. To provide more customizability, there are two user-definable
    242 functions, `autoshift_press/release_user`. These register or unregister the
    243 correct value for the passed key. Below is an example adding period to Auto
    244 Shift and making its shifted value exclamation point. Make sure to use weak
    245 mods - setting real would make any keys following it use their shifted values
    246 as if you were holding the key. Clearing of modifiers is handled by Auto Shift,
    247 and the OS-sent shift value if keyrepeating multiple keys is always that of
    248 the last key pressed (whether or not it's an Auto Shift key).
    249 
    250 You can also have non-shifted keys for the shifted values (or even no shifted
    251 value), just don't set a shift modifier!
    252 
    253 ```c
    254 bool get_custom_auto_shifted_key(uint16_t keycode, keyrecord_t *record) {
    255     switch(keycode) {
    256         case KC_DOT:
    257             return true;
    258         default:
    259             return false;
    260     }
    261 }
    262 
    263 void autoshift_press_user(uint16_t keycode, bool shifted, keyrecord_t *record) {
    264     switch(keycode) {
    265         case KC_DOT:
    266             register_code16((!shifted) ? KC_DOT : KC_EXLM);
    267             break;
    268         default:
    269             if (shifted) {
    270                 add_weak_mods(MOD_BIT(KC_LSFT));
    271             }
    272             // & 0xFF gets the Tap key for Tap Holds, required when using Retro Shift
    273             register_code16((IS_RETRO(keycode)) ? keycode & 0xFF : keycode);
    274     }
    275 }
    276 
    277 void autoshift_release_user(uint16_t keycode, bool shifted, keyrecord_t *record) {
    278     switch(keycode) {
    279         case KC_DOT:
    280             unregister_code16((!shifted) ? KC_DOT : KC_EXLM);
    281             break;
    282         default:
    283             // & 0xFF gets the Tap key for Tap Holds, required when using Retro Shift
    284             // The IS_RETRO check isn't really necessary here, always using
    285             // keycode & 0xFF would be fine.
    286             unregister_code16((IS_RETRO(keycode)) ? keycode & 0xFF : keycode);
    287     }
    288 }
    289 ```
    290 
    291 ## Retro Shift
    292 
    293 Holding and releasing a Tap Hold key without pressing another key will ordinarily
    294 result in only the hold. With `retro shift` enabled this action will instead
    295 produce a shifted version of the tap keycode on release.
    296 
    297 It does not require [Retro Tapping](../tap_hold#retro-tapping) to be enabled, and
    298 if both are enabled the state of `retro tapping` will only apply if the tap keycode
    299 is not matched by Auto Shift. `RETRO_TAPPING_PER_KEY` and its corresponding
    300 function, however, are checked before `retro shift` is applied.
    301 
    302 To enable `retro shift`, add the following to your `config.h`:
    303 
    304 ```c
    305 #define RETRO_SHIFT
    306 ```
    307 
    308 If `RETRO_SHIFT` is defined to a value, hold times greater than that value will
    309 not produce a tap on release for Mod Taps, and instead triggers the hold action.
    310 This enables modifiers to be held for combining with mouse clicks without
    311 generating taps on release. For example:
    312 
    313 ```c
    314 #define RETRO_SHIFT 500
    315 ```
    316 
    317 Without a value set, holds of any length without an interrupting key will produce the shifted value.
    318 
    319 This value (if set) must be greater than one's `TAPPING_TERM`, as the key press
    320 must be designated as a 'hold' by `process_tapping` before we send the modifier.
    321 [Per-key tapping terms](../tap_hold#tapping-term) can be used as a workaround.
    322 There is no such limitation in regards to `AUTO_SHIFT_TIMEOUT` for normal keys.
    323 
    324 **Note:** Tap Holds must be added to Auto Shift, see [here.](auto_shift#auto-shift-per-key)
    325 `IS_RETRO` may be helpful if one wants all Tap Holds retro shifted.
    326 
    327 ### Retro Shift and Tap Hold Configurations
    328 
    329 Tap Hold Configurations work a little differently when using Retro Shift.
    330 Referencing `TAPPING_TERM` makes little sense, as holding longer would result in
    331 shifting one of the keys.
    332 
    333 `RETRO_SHIFT` enables [`PERMISSIVE_HOLD`-like behaviour](../tap_hold#permissive-hold) (even if not explicitly enabled) on all mod-taps for which `RETRO_SHIFT` applies.
    334 
    335 ## Using Auto Shift Setup
    336 
    337 This will enable you to define three keys temporarily to increase, decrease and report your `AUTO_SHIFT_TIMEOUT`.
    338 
    339 ### Setup
    340 
    341 Map three keys temporarily in your keymap:
    342 
    343 |Keycode               |Aliases  |Description                                 |
    344 |----------------------|---------|--------------------------------------------|
    345 |`QK_AUTO_SHIFT_DOWN`  |`AS_DOWN`|Lower the Auto Shift timeout variable (down)|
    346 |`QK_AUTO_SHIFT_UP`    |`AS_UP`  |Raise the Auto Shift timeout variable (up)  |
    347 |`QK_AUTO_SHIFT_REPORT`|`AS_RPT` |Report your current Auto Shift timeout value|
    348 |`QK_AUTO_SHIFT_ON`    |`AS_ON`  |Turns on the Auto Shift Function            |
    349 |`QK_AUTO_SHIFT_OFF`   |`AS_OFF` |Turns off the Auto Shift Function           |
    350 |`QK_AUTO_SHIFT_TOGGLE`|`AS_TOGG`|Toggles the state of the Auto Shift feature |
    351 
    352 Compile and upload your new firmware.
    353 
    354 ### Use
    355 
    356 It is important to note that during these tests, you should be typing
    357 completely normal and with no intention of shifted keys.
    358 
    359 1. Type multiple sentences of alphabetical letters.
    360 2. Observe any upper case letters.
    361 3. If there are none, press the key you have mapped to `AS_DOWN` to decrease
    362    time Auto Shift timeout value and go back to step 1.
    363 4. If there are some upper case letters, decide if you need to work on tapping
    364    those keys with less down time, or if you need to increase the timeout.
    365 5. If you decide to increase the timeout, press the key you have mapped to
    366    `AS_UP` and go back to step 1.
    367 6. Once you are happy with your results, press the key you have mapped to
    368    `AS_RPT`. The keyboard will type by itself the value of your
    369    `AUTO_SHIFT_TIMEOUT`.
    370 7. Update `AUTO_SHIFT_TIMEOUT` in your `config.h` with the value reported.
    371 8. Add `AUTO_SHIFT_NO_SETUP` to your `config.h`.
    372 9. Remove the key bindings `AS_DOWN`, `AS_UP` and `AS_RPT`.
    373 10. Compile and upload your new firmware.
    374 
    375 #### An Example Run
    376 
    377 ```
    378 hello world. my name is john doe. i am a computer programmer playing with
    379 keyboards right now.
    380 
    381 [PRESS AS_DOWN quite a few times]
    382 
    383 heLLo woRLd. mY nAMe is JOHn dOE. i AM A compUTeR proGRaMMER PlAYiNG witH
    384 KEYboArDS RiGHT NOw.
    385 
    386 [PRESS AS_UP a few times]
    387 
    388 hello world. my name is john Doe. i am a computer programmer playing with
    389 keyboarDs right now.
    390 
    391 [PRESS AS_RPT]
    392 
    393 115
    394 ```
    395 
    396 The keyboard typed `115` which represents your current `AUTO_SHIFT_TIMEOUT`
    397 value. You are now set! Practice on the *D* key a little bit that showed up
    398 in the testing and you'll be golden.