diff options
author | Drashna Jael're <drashna@live.com> | 2022-11-12 17:10:04 -0800 |
---|---|---|
committer | Drashna Jael're <drashna@live.com> | 2022-11-12 17:10:04 -0800 |
commit | 731633e133de428408cd313fbd65fb0a36145672 (patch) | |
tree | b788a9fe150a353ce20d338848d3dab2bbc42879 /users/ericgebhart/extensions/tap_hold.c | |
parent | 6cc9513ab0cd5e21354c51ab83a89af9f2eb517e (diff) | |
parent | 2e39647618295e4a2ba685cfb8e3ab36622e92ee (diff) |
Merge remote-tracking branch 'origin/master' into develop
Diffstat (limited to 'users/ericgebhart/extensions/tap_hold.c')
-rw-r--r-- | users/ericgebhart/extensions/tap_hold.c | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/users/ericgebhart/extensions/tap_hold.c b/users/ericgebhart/extensions/tap_hold.c new file mode 100644 index 0000000000..041b961e11 --- /dev/null +++ b/users/ericgebhart/extensions/tap_hold.c @@ -0,0 +1,165 @@ +/* + Copyright 2022 Eric Gebhart <e.a.gebhart@gmail.com> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* This is variations on custom tap hold functionality. It makes it easy */ +/* to maintain tap_hold keys and combinations. These combinations go into */ +/* the file "tap_hold.def". Here are two examples. */ +/* */ +/* This example is tap or tap for TAP_HOLD_TERM, It defines a key */ +/* KC_CCCV, which sends Control-c on tap, and Control-v on hold. */ +/* */ +/* TP_TPL(KC_CCCV, LCTL(KC_C), LCTL(KC_V)) */ +/* */ +/* This is an example of Open - Open and Close. */ +/* It defines a key, KC_OCPRN which when tapped gives an '(' and */ +/* when held gives '()' followed by a backarrow. */ +/* Which places the cursor between them.*/ +/* */ +/* OPEN_OCL(KC_OCPRN, KC_LPRN, KC_RPRN) */ +/* */ +/* To use this, add it to your src in rules.mk, and include */ +/* tap_hold.h in your code above process_record_user. */ +/* */ +/* Add a call like this to use it. */ +/* process_tap_hold_user(keycode, record); */ +/* */ +/* Note: You must add any custom keycodes to your keycodes enum */ +/* otherwise they will not exist. */ + + +#include USERSPACE_H +#include "stdint.h" +#include "tap_hold.h" +void update_smart_lock(uint16_t keycode); + + +void tap_taplong(uint16_t kc1, uint16_t kc2, keyrecord_t *record) { + if (record->event.pressed) { + tap_taplong_timer = timer_read(); + } else { + if (timer_elapsed(tap_taplong_timer) > TAP_HOLD_TERM) { + tap_code16(kc2); + } else { + tap_code16(kc1); + } + } +} + +void tap_sml(uint16_t kc1, uint16_t kc2, keyrecord_t *record) { + if (record->event.pressed) { + tap_taplong_timer = timer_read(); + } else { + if (timer_elapsed(tap_taplong_timer) > TAP_HOLD_TERM) { + update_smart_lock(kc2); + } else { + tap_code16(kc1); + } + } +} + +/* for (){}[]""''<>``. tap for open. Hold for open and close, ending inbetween. */ +/* Assumes a one character length. */ +void open_openclose(uint16_t kc1, uint16_t kc2, keyrecord_t *record) { + if (record->event.pressed) { + tap_taplong_timer = timer_read(); + }else{ + if (timer_elapsed(tap_taplong_timer) > TAP_HOLD_TERM) { + tap_code16(kc1); + tap_code16(kc2); + tap_code16(KC_LEFT); + + } else { + // is shifted + uint16_t mod_state = get_mods(); + if ((mod_state & MOD_MASK_SHIFT) || + (get_oneshot_mods() & MOD_MASK_SHIFT)){ + del_mods(MOD_MASK_SHIFT); + del_oneshot_mods(MOD_MASK_SHIFT); + + tap_code16(kc1); + tap_code16(kc1); + tap_code16(kc1); + + set_mods(mod_state); + }else{ + tap_code16(kc1); + } + } + } +} + +// open and open close for dead keys. +void open_openclose_not_dead(uint16_t kc1, uint16_t kc2, keyrecord_t *record) { + if (record->event.pressed) { + tap_taplong_timer = timer_read(); + }else{ + if (timer_elapsed(tap_taplong_timer) > TAP_HOLD_TERM) { + tap_code16(kc1); + tap_code16(KC_SPACE); + tap_code16(kc2); + tap_code16(KC_SPACE); + tap_code16(KC_LEFT); + } else { + // is shifted - give a triple + uint16_t mod_state = get_mods(); + if ((mod_state & MOD_MASK_SHIFT) || + (get_oneshot_mods() & MOD_MASK_SHIFT)){ + del_mods(MOD_MASK_SHIFT); + del_oneshot_mods(MOD_MASK_SHIFT); + + tap_code16(kc1); + tap_code16(KC_SPACE); + tap_code16(kc1); + tap_code16(KC_SPACE); + tap_code16(kc1); + tap_code16(KC_SPACE); + + set_mods(mod_state); + }else{ + tap_code16(kc1); + tap_code16(KC_SPACE); + } + } + } +} + +// macros for use in tap_hold.defs. +#define TP_TPL(KCKEY, KC01, KC02) \ + case KCKEY: \ + tap_taplong(KC01, KC02, record); \ + break; + +#define TP_SML(KCKEY, KC01, KC02) \ + case KCKEY: \ + tap_sml(KC01, KC02, record); \ + break; + +#define OPEN_OCL(KCKEY, KC01, KC02) \ + case KCKEY: \ + open_openclose(KC01, KC02, record); \ + break; + +#define OPEN_OCL_ND(KCKEY, KC01, KC02) \ + case KCKEY: \ + open_openclose_not_dead(KC01, KC02, record); \ + break; + +void process_tap_hold_user(uint16_t keycode, keyrecord_t *record) { + switch(keycode){ +#include "tap_hold.def" + } +} |