7k2mpa.c
#include "7k2mpa.h"
#include "quantum.h"
#include "action.h"
#include "process_keycode/process_tap_dance.h"
/* Return an integer that corresponds to what kind of tap dance should be executed.
*
* How to figure out tap dance state: interrupted and pressed.
*
* Interrupted: If the state of a dance dance is "interrupted", that means that another key has been hit
* under the tapping term. This is typically indicitive that you are trying to "tap" the key.
*
* Pressed: Whether or not the key is still being pressed. If this value is true, that means the tapping term
* has ended, but the key is still being pressed down. This generally means the key is being "held".
*
* One thing that is currenlty not possible with qmk software in regards to tap dance is to mimic the "permissive hold"
* feature. In general, advanced tap dances do not work well if they are used with commonly typed letters.
* For example "A". Tap dances are best used on non-letter keys that are not hit while typing letters.
*
* Good places to put an advanced tap dance:
* z,q,x,j,k,v,b, any function key, home/end, comma, semi-colon
*
* Criteria for "good placement" of a tap dance key:
* Not a key that is hit frequently in a sentence
* Not a key that is used frequently to double tap, for example 'tab' is often double tapped in a terminal, or
* in a web form. So 'tab' would be a poor choice for a tap dance.
* Letters used in common words as a double. For example 'p' in 'pepper'. If a tap dance function existed on the
* letter 'p', the word 'pepper' would be quite frustating to type.
*
* For the third point, there does exist the 'DOUBLE_SINGLE_TAP', however this is not fully tested
*
*/
int cur_dance (qk_tap_dance_state_t *state) {
if (state->count == 1) {
if (state->interrupted || !state->pressed) return SINGLE_TAP;
//key has not been interrupted, but they key is still held. Means you want to send a 'HOLD'.
else return SINGLE_HOLD;
}
else if (state->count == 2) {
/*
* DOUBLE_SINGLE_TAP is to distinguish between typing "pepper", and actually wanting a double tap
* action when hitting 'pp'. Suggested use case for this return value is when you want to send two
* keystrokes of the key, and not the 'double tap' action/macro.
*/
if (state->interrupted) return DOUBLE_SINGLE_TAP;
else if (state->pressed) return DOUBLE_HOLD;
else return DOUBLE_TAP;
}
//Assumes no one is trying to type the same letter three times (at least not quickly).
//If your tap dance key is 'KC_W', and you want to type "www." quickly - then you will need to add
//an exception here to return a 'TRIPLE_SINGLE_TAP', and define that enum just like 'DOUBLE_SINGLE_TAP'
if (state->count == 3) {
if (state->interrupted || !state->pressed) return TRIPLE_TAP;
else return TRIPLE_HOLD;
}
else return 8; //magic number. At some point this method will expand to work for more presses
}
//instanalize an instance of 'tap' for the 'x' tap dance.
static tap xtap_state = {
.is_press_action = true,
.state = 0
};
void rthumb_finished (qk_tap_dance_state_t *state, void *user_data) {
xtap_state.state = cur_dance(state);
switch (xtap_state.state) {
case SINGLE_TAP: register_code(KC_LGUI); break;
case SINGLE_HOLD: register_code(KC_LGUI); break;
case DOUBLE_TAP: register_code(KC_F14); break;
case DOUBLE_HOLD: register_code(KC_LALT); break;
case DOUBLE_SINGLE_TAP: register_code(KC_LGUI); unregister_code(KC_LGUI); register_code(KC_LGUI);
//Last case is for fast typing. Assuming your key is `f`:
//For example, when typing the word `buffer`, and you want to make sure that you send `ff` and not `Esc`.
//In order to type `ff` when typing fast, the next character will have to be hit within the `TAPPING_TERM`, which by default is 200ms.
}
}
void rthumb_reset (qk_tap_dance_state_t *state, void *user_data) {
switch (xtap_state.state) {
case SINGLE_TAP: unregister_code(KC_LGUI); break;
case SINGLE_HOLD: unregister_code(KC_LGUI); break;
case DOUBLE_TAP: unregister_code(KC_F14); break;
case DOUBLE_HOLD: unregister_code(KC_LALT);
case DOUBLE_SINGLE_TAP: unregister_code(KC_LGUI);
}
xtap_state.state = 0;
}
void lthumb_finished (qk_tap_dance_state_t *state, void *user_data) {
xtap_state.state = cur_dance(state);
switch (xtap_state.state) {
case SINGLE_TAP: register_code(KC_LALT); break;
case SINGLE_HOLD: register_code(KC_LALT); break;
case DOUBLE_TAP: register_code(KC_F13); break;
case DOUBLE_HOLD: register_code(KC_APP); break;
case DOUBLE_SINGLE_TAP: register_code(KC_LALT); unregister_code(KC_LALT); register_code(KC_LALT);
}
}
void lthumb_reset (qk_tap_dance_state_t *state, void *user_data) {
switch (xtap_state.state) {
case SINGLE_TAP: unregister_code(KC_LALT); break;
case SINGLE_HOLD: unregister_code(KC_LALT); break;
case DOUBLE_TAP: unregister_code(KC_F13); break;
case DOUBLE_HOLD: unregister_code(KC_APP);
case DOUBLE_SINGLE_TAP: unregister_code(KC_LALT);
}
xtap_state.state = 0;
}
void lithumb_finished (qk_tap_dance_state_t *state, void *user_data) {
xtap_state.state = cur_dance(state);
switch (xtap_state.state) {
case SINGLE_TAP: register_code(KC_TAB); break;
case SINGLE_HOLD: register_code(KC_LCTL); break;
case DOUBLE_TAP: register_code(KC_TAB);unregister_code(KC_TAB);register_code(KC_TAB); break;
case DOUBLE_HOLD: register_code(KC_RGUI); break;
case DOUBLE_SINGLE_TAP: register_code(KC_TAB); unregister_code(KC_TAB); register_code(KC_TAB);
}
}
void lithumb_reset (qk_tap_dance_state_t *state, void *user_data) {
switch (xtap_state.state) {
case SINGLE_TAP: unregister_code(KC_TAB); break;
case SINGLE_HOLD: unregister_code(KC_LCTL); break;
case DOUBLE_TAP: unregister_code(KC_TAB); break;
case DOUBLE_HOLD: unregister_code(KC_RGUI);
case DOUBLE_SINGLE_TAP: unregister_code(KC_TAB);
}
xtap_state.state = 0;
}
void rithumb_finished (qk_tap_dance_state_t *state, void *user_data) {
xtap_state.state = cur_dance(state);
switch (xtap_state.state) {
case SINGLE_TAP: register_code(KC_BSPACE); break;
case SINGLE_HOLD: register_code(KC_LALT); break;
case DOUBLE_TAP: register_code(KC_BSPACE);unregister_code(KC_BSPACE);register_code(KC_BSPACE); break;
case DOUBLE_HOLD: register_code(KC_LCTL); break;
case DOUBLE_SINGLE_TAP: register_code(KC_BSPACE); unregister_code(KC_BSPACE); register_code(KC_BSPACE);
}
}
void rithumb_reset (qk_tap_dance_state_t *state, void *user_data) {
switch (xtap_state.state) {
case SINGLE_TAP: unregister_code(KC_BSPACE); break;
case SINGLE_HOLD: unregister_code(KC_LALT); break;
case DOUBLE_TAP: unregister_code(KC_BSPACE); break;
case DOUBLE_HOLD: unregister_code(KC_LCTL);
case DOUBLE_SINGLE_TAP: unregister_code(KC_BSPACE);
}
xtap_state.state = 0;
}
7k2mpa.h
#pragma once
#include "quantum.h"
#include "process_keycode/process_tap_dance.h"
typedef struct {
bool is_press_action;
int state;
} tap;
enum {
SINGLE_TAP = 1,
SINGLE_HOLD = 2,
DOUBLE_TAP = 3,
DOUBLE_HOLD = 4,
DOUBLE_SINGLE_TAP = 5, //send two single taps
TRIPLE_TAP = 6,
TRIPLE_HOLD = 7
};
//Tap dance enums
enum {
TD_RTHUMB = 0,
TD_LTHUMB,
TD_RITHUMB,
TD_LITHUMB
};
int cur_dance (qk_tap_dance_state_t *state);
//for the x tap dance. Put it here so it can be used in any keymap
void rthumb_finished (qk_tap_dance_state_t *state, void *user_data);
void rthumb_reset (qk_tap_dance_state_t *state, void *user_data);
void lthumb_finished (qk_tap_dance_state_t *state, void *user_data);
void lthumb_reset (qk_tap_dance_state_t *state, void *user_data);
void rithumb_finished (qk_tap_dance_state_t *state, void *user_data);
void rithumb_reset (qk_tap_dance_state_t *state, void *user_data);
void lithumb_finished (qk_tap_dance_state_t *state, void *user_data);
void lithumb_reset (qk_tap_dance_state_t *state, void *user_data);
keymap.c
#include "iris.h"
#include "action_layer.h"
#include "eeconfig.h"
#include "7k2mpa.h"
extern keymap_config_t keymap_config;
#define _QWERTY 0
#define _LOWER 1
#define _RAISE 2
#define _NUMPAD 4
#define _MOUSECURSOR 8
#define _ADJUST 16
enum custom_keycodes {
QWERTY = SAFE_RANGE,
LOWER,
RAISE,
NUMPAD,
MOUSECURSOR,
ADJUST,
};
/* Tap Dance */
enum {
// TD_LGUIESC=0,
// TD_LGUIAPP,
// TD_LALTAPP,
TD_SHIFTCAPS = 10,
TD_LGUINMPD,
TD_LGUIMSCS,
TD_GRAVEESC,
X_TAP_DANCE
};
/* Tap Dance */
#define KC_ KC_TRNS
#define _______ KC_TRNS
#define KC_LOWR LOWER
#define KC_RASE RAISE
#define KC_RST RESET
#define KC_BL_S BL_STEP
#define KC_DBUG DEBUG
#define KC_RTOG RGB_TOG
#define KC_RMOD RGB_MOD
#define KC_RHUI RGB_HUI
#define KC_RHUD RGB_HUD
#define KC_RSAI RGB_SAI
#define KC_RSAD RGB_SAD
#define KC_RVAI RGB_VAI
#define KC_RVAD RGB_VAD
#define KC_MCPW KC_POWER
#define KC_MCVU KC__VOLUP
#define KC_MCVD KC__VOLDOWN
//#define KC_BSGU MT(MOD_LGUI, KC_BSPC) // tap BackSpace , Hold RGUI
#define KC_BSAL MT(MOD_LALT, KC_BSPC) // tap BackSpace , Hold LALT
#define KC_DLAL MT(MOD_LALT, KC_DEL) // tap Delete , Hold LALT
//#define KC_GRGU MT(MOD_LGUI, KC_GRV)// tap Delete , Hold LALT
#define KC_TBAL MT(MOD_LALT, KC_TAB) // tap TAB , Hold LALT
#define KC_SLGU MT(MOD_LGUI, KC_SLSH) // tap Slash , Hold LGUI
#define KC_DOAL MT(MOD_LALT, KC_DOT) // tap Dot , Hold LALT
#define KC_COCT MT(MOD_LCTL, KC_COMM) // tap Comma , Hold LCTL
#define KC_BLRS MT(MOD_RSFT, KC_BSLS) // tap BackSlash , Hold RSFT
//#define KC_SPAT MT(MOD_LALT, KC_SPC) // tap Space , Hold LALT
#define KC_ESCT MT(MOD_LCTL, KC_ESC) // tap Escape , Hold LCTL
#define KC_TBCT MT(MOD_LCTL, KC_TAB) // tap TAB , Hold LCTL
//#define KC_CMZ LGUI(KC_Z)
//#define KC_CMX LGUI(KC_X)
//#define KC_CMC LGUI(KC_C)
//#define KC_CMV LGUI(KC_V)
#define KC_CADL ALTG(KC_DEL)
#define KC_STAB S(KC_TAB)
#define KC_SPLW LT(_LOWER,KC_SPC) // tap Space , Hold LowerLayer
#define KC_ENLW LT(_LOWER,KC_ENTER) // tap Enter , Hold LowerLayer
#define KC_ESRA LT(_RAISE,KC_ESC) // tap ESC , Hold RaiseLayer
//#define KC_TBRA LT(_RAISE,KC_TAB) // tap TAB , Hold RaiseLayer
#define KC_DLRA LT(_RAISE,KC_DEL) // tap Delete , Hold RaiseLayer
//#define KC_NPD TT(_NUMPAD) // tap Momentary NUMPAD , DualTap toggle NUMPAD
//#define KC_MSC TT(_MOUSECURSOR) // tap Momentary NUMPAD , DualTap toggle Mousecursor
/* Tap Dance */
//#define KC_LGES TD(TD_LGUIESC)
//#define KC_LGAP TD(TD_LGUIAPP)
//#define KC_LAAP TD(TD_LALTAPP)
#define KC_SHCP TD(TD_SHIFTCAPS)
#define KC_LGNP TD(TD_LGUINMPD)
#define KC_LGMC TD(TD_LGUIMSCS)
#define KC_GRES TD(TD_GRAVEESC)
#define KC_RTUB TD(TD_RTHUMB)
#define KC_LTUB TD(TD_LTHUMB)
#define KC_RITB TD(TD_RITHUMB)
#define KC_LITB TD(TD_LITHUMB)
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_QWERTY] = LAYOUT_kc(
//,----+----+----+----+----+----. ,----+----+----+----+----+----.
GRES, 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 0 ,MINS,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
TBAL, Q , W , E , R , T , Y , U , I , O , P ,EQL ,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
LCTL, A , S , D , F , G , H , J , K , L ,SCLN,QUOT,
//|----+----+----+----+----+----+----. ,----|----+----+----+----+----+----|
SHCP, Z , X , C , V , B ,ESRA, DLRA, N , M ,COCT,DOAL,SLGU,BLRS,
//`----+----+----+--+-+----+----+----/ \----+----+----+----+----+----+----'
LTUB,SPLW,LITB, RITB,ENLW,RTUB
// `----+----+----' `----+----+----'
),
[_LOWER] = LAYOUT_kc(
//,----+----+----+----+----+----. ,----+----+----+----+----+----.
ESC ,EXLM, AT ,HASH,DLR ,PERC, CIRC,AMPR,ASTR,LPRN,RPRN,DEL ,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
,TILD,UNDS,PLUS,PIPE,LABK, RABK,PGUP, UP ,PGDN,HOME,BSPC,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
,GRV ,MINS,EQL ,BSLS,LBRC, RBRC,LEFT,DOWN,RGHT,END ,ENT ,
//|----+----+----+----+----+----+----. ,----|----+----+----+----+----+----|
, RO ,JYEN,QUES,LPRN,LCBR,RASE, RASE,RCBR,RPRN, , , , ,
//`----+----+----+--+-+----+----+----/ \----+----+----+----+----+----+----'
, ,ESCT, DLAL, ,LGNP
// `----+----+----' `----+----+----'
),
[_RAISE] = LAYOUT_kc(
//,----+----+----+----+----+----. ,----+----+----+----+----+----.
F12 , F1 , F2 , F3 , F4 , F5 , F6 , F7 , F8 , F9 ,F10 ,F11 ,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
CADL, 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 0 ,BSPC,
//|----+----+----+----+----+----+ |----+----+----+----+----+----|
,EXLM, AT ,HASH,DLR ,PERC, CIRC,AMPR,ASTR,LPRN,RPRN,ENT ,
//|----+----+----+----+----+----|----. ,----|----+----+----+----+----+----|
,PLUS,MINS,EQL ,BSLS,QUOT, , ,DQUO,SLSH, , , , ,
//`----+----+----+--+-+----+----+----/ \----+----+----+----+----+----+----'
, , , , ,LGMC
// `----+----+----' `----+----+----'
),
[_NUMPAD] = LAYOUT_kc(
//,----+----+----+----+----+----. ,----+----+----+----+----+----.
NLCK, , , , , , , P7 , P8 , P9 ,PMNS,DEL ,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
,HOME,PGUP, UP ,PGDN,LABK, RABK, P4 , P5 , P6 ,PPLS,BSPC,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
,END ,LEFT,DOWN,RGHT,LPRN, RPRN, P1 , P2 , P3 ,PAST,COLN,
//|----+----+----+----+----+----+----. ,----|----+----+----+----+----+----|
, , , , ,STAB, , P0 ,EQL , P0 ,COMM,DOT ,PSLS,PENT,
//`----+----+----+--+-+----+----+----/ \----+----+----+----+----+----+----'
, , , , ,
// `----+----+----' `----+----+----'
),
[_MOUSECURSOR] = LAYOUT_kc(
//,----+----+----+----+----+----. ,----+----+----+----+----+----.
, , , , , , , , , , , ,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
,HOME,PGUP, UP ,PGDN, , WH_D,BTN1,MS_U,BTN2,BTN3,ACL0,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
,END ,LEFT,DOWN,RGHT, , WH_L,MS_L,MS_D,MS_R,WH_R,ACL1,
//|----+----+----+----+----+----+----. ,----|----+----+----+----+----+----|
, , , , , , , ,WH_U,LEFT,DOWN, UP ,RGHT,ACL2,
//`----+----+----+----+----+----+----/ \----+----+----+----+----+----+----'
, , , , ,
// `----+----+----' `----+----+----'
),
[_ADJUST] = LAYOUT_kc(
//,----+----+----+----+----+----. ,----+----+----+----+----+----.
RST ,MUTE,VOLD,VOLU, , , , , , , ,PSCR,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
, , , , , , RTOG,RMOD,RHUI,RSAI,RVAI, ,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
MCPW,EJCT,MCVD,MCVU, , , ,DBUG,RHUD,RSAD,RVAD, ,
//|----+----+----+----+----+----+----. ,----|----+----+----+----+----+----|
MUTE, ,VOLD,VOLU, , , , , , , , , ,BL_S,
//`----+----+----+--+-+----+----+----/ \----+----+----+----+----+----+----'
, , , , ,
// `----+----+----' `----+----+----'
)
};
/* TAP DANCE */
void shift_caps_down (qk_tap_dance_state_t *state, void *user_data) {
if (state->count >= 3) {
register_code (KC_CAPS);
} else {
register_code (KC_RSFT);
}
}
void shift_caps_up (qk_tap_dance_state_t *state, void *user_data) {
if (state->count >= 3) {
unregister_code (KC_CAPS);
} else {
unregister_code (KC_RSFT);
}
}
void dance_lgui_numpad_finished(qk_tap_dance_state_t* state, void* user_data)
{
if (state->count == 1)
{
register_code(KC_LGUI);
}
}
void dance_lgui_numpad_reset(qk_tap_dance_state_t* state, void* user_data)
{
if (state->count == 1)
{
unregister_code(KC_LGUI);
}
else
{
uint8_t layer = biton32(layer_state);
if (layer == _NUMPAD)
{
layer_off(_NUMPAD);
} else {
layer_on(_NUMPAD);
layer_off(_MOUSECURSOR);
}
}
}
void dance_lgui_mousecursor_finished(qk_tap_dance_state_t* state, void* user_data)
{
if (state->count == 1)
{
register_code(KC_LGUI);
}
}
void dance_lgui_mousecursor_reset(qk_tap_dance_state_t* state, void* user_data)
{
if (state->count == 1)
{
unregister_code(KC_LGUI);
}
else
{
uint8_t layer = biton32(layer_state);
if (layer == _MOUSECURSOR)
{
layer_off(_MOUSECURSOR);
} else {
layer_on(_MOUSECURSOR);
layer_off(_NUMPAD);
}
}
}
qk_tap_dance_action_t tap_dance_actions[] = {
// Tap once for L-GUI(Windows), twice for Escape
// [TD_LGUIESC] = ACTION_TAP_DANCE_DOUBLE(KC_LGUI, KC_ESC),
// Tap once for L-GUI(Windows), twice for APP
// [TD_LGUIAPP] = ACTION_TAP_DANCE_DOUBLE(KC_LGUI, KC_APP),
// Tap once for R-Alt, twice for APP
// [TD_LALTAPP] = ACTION_TAP_DANCE_DOUBLE(KC_LALT, KC_APP),
// Tap once for Left Shift , trice for CAPS Lock
[TD_SHIFTCAPS] = ACTION_TAP_DANCE_FN_ADVANCED (NULL, shift_caps_down, shift_caps_up),
// [TD_SHIFTCAPS] = ACTION_TAP_DANCE_DOUBLE (KC_Z,KC_X),
// Tap once for Left Shift , trice for CAPS Lock
[TD_GRAVEESC] = ACTION_TAP_DANCE_DOUBLE (KC_GRAVE, KC_ESC),
// tap once for LGUI , twice for move to NUMPAD layer
[TD_LGUINMPD] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance_lgui_numpad_finished, dance_lgui_numpad_reset),
// tap once for LGUI , twice for move to MOUSECURSOR layer
[TD_LGUIMSCS] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance_lgui_mousecursor_finished, dance_lgui_mousecursor_reset),
[TD_RTHUMB] = ACTION_TAP_DANCE_FN_ADVANCED(NULL,rthumb_finished, rthumb_reset),
[TD_LTHUMB] = ACTION_TAP_DANCE_FN_ADVANCED(NULL,lthumb_finished, lthumb_reset),
[TD_RITHUMB] = ACTION_TAP_DANCE_FN_ADVANCED(NULL,rithumb_finished, rithumb_reset),
[TD_LITHUMB] = ACTION_TAP_DANCE_FN_ADVANCED(NULL,lithumb_finished, lithumb_reset)
};
/* END TAP DANCE */
void persistent_default_layer_set(uint16_t default_layer) {
eeconfig_update_default_layer(default_layer);
default_layer_set(default_layer);
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case QWERTY:
if (record->event.pressed) {
persistent_default_layer_set(1UL<<_qwerty break="" case="" false="" if="" lower:="" record-="" return="">event.pressed) {
layer_on(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
}
return false;
break;
case RAISE:
if (record->event.pressed) {
layer_on(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
}
return false;
break;
case ADJUST:
if (record->event.pressed) {
layer_on(_ADJUST);
} else {
layer_off(_ADJUST);
}
return false;
break;
}
return true;
}
rules.mk
RGBLIGHT_ENABLE = no
BACKLIGHT_ENABLE = no
TAP_DANCE_ENABLE=yes
SRC += 7k2mpa.c
ifndef QUANTUM_DIR
include ../../../../Makefile
endif
0 コメント:
コメントを投稿