Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added new keymap for keebio/iris #16858

Merged
merged 6 commits into from
Jul 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions keyboards/keebio/iris/keymaps/emp/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
Copyright 2017 Danny Nguyen <danny@keeb.io>

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/>.
*/

#pragma once

/* Use I2C or Serial, not both */
#undef USE_I2C
#define USE_SERIAL

/* Select hand configuration */
#undef MASTER_LEFT
#undef MASTER_RIGHT
#define EE_HANDS

/* disable debugging features */
#ifndef NO_DEBUG
#define NO_DEBUG
#endif // #ifndef NO_DEBUG

/* disable printing features */
#ifndef NO_PRINT
#define NO_PRINT
#endif // #ifndef NO_PRINT

/* force n-key rollover to be enabled every boot */
#undef FORCE_NKRO

/* disable tap dance and other tapping features */
#undef NO_ACTION_TAPPING

/* disable one-shot modifiers */
#undef NO_ACTION_ONESHOT

/* PERMISSIVE_HOLD
* when on: tap-hold keys are held when typed fast, so long as the modifier key
* is pressed before and released after the rodified key(s)
* when off: tap-hold keys are both tapped when typed fast (within tapping term)
*/
#undef PERMISSIVE_HOLD

/* IGNORE_MOD_TAP_INTERRUPT
* when on: rolling tap-hold keys taps all keys
* when off: rolling tap-hold keys modifies keys
*/
#undef IGNORE_MOD_TAP_INTERRUPT

/* TAPPING_TERM x (ms)
* how long before a tap becomes a hold. if set above 500, a key tapped during
* the tapping term will turn it into a hold too
*/
#define TAPPING_TERM 200

/* TAPPING_TOGGLE x (count)
* If you hold a TT key down, layer is activated, and then is de-activated when
* you let go (like MO()). If you repeatedly tap it, the layer will be toggled
* on or off (like TG()). It needs 5 taps by default, but you can change this by
* defining TAPPING_TOGGLE to another number.
*/
// #define TAPPING_TOGGLE 1

/* RETRO_TAPPING
* tap anyway, even after TAPPING_TERM, if there was no other key interruption
* between press and release
*/
#undef RETRO_TAPPING

/* ONESHOT_TIMEOUT x (ms)
* how long before oneshot times out
*/
// #define ONESHOT_TIMEOUT 2000

/* TAP_CODE_DELAY x (ms)
* how long tapped keycodes are held down for
*/
// #define TAP_CODE_DELAY 100

/* NO_USB_STARTUP_CHECK
* according to:
* https://github.com/qmk/qmk_firmware/issues/12732
* defining this can help with boards not being recognized by virtual keymapping
* software
*/
#define NO_USB_STARTUP_CHECK
277 changes: 277 additions & 0 deletions keyboards/keebio/iris/keymaps/emp/keymap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,277 @@
/* Copyright 2022 elliotpatros
*
* 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/>.
*/

#include QMK_KEYBOARD_H
drashna marked this conversation as resolved.
Show resolved Hide resolved

// Layer definitions
enum custom_layers {
_COLEMAK,
_FUNCTION,
};

// Custom keycodes, implemented later, in function: process_record_user()
enum custom_keycodes {
CTL_ESC = SAFE_RANGE, // mod tap: left control / esc
SFT_ENT, // mod tap: left shift / enter
LST_PRN, // mod tap: left shift / left parenthesis
RST_PRN, // mod tap: right shift / right parenthesis
};

// Shorthand keycode definitions
#define OSM_CAG OSM(MOD_LCTL | MOD_LALT | MOD_LGUI)
#define LT_BSFN LT(_FUNCTION, KC_BSLS)

// The layout
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {

// Default layer
[_COLEMAK] = LAYOUT (

// ┌────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┐
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,
// ├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤
KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_EQL,
// ├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤
CTL_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT,
// ├────────┼────────┼────────┼────────┼────────┼────────┼────────┐┌────────┼────────┼────────┼────────┼────────┼────────┼────────┤
LST_PRN, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_SPC, KC_ENT, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, RST_PRN,
// └────────┴────────┴────────┴────────┼────────┼────────┼────────┘└────────┼────────┴────────┴────────┴────────┴────────┴────────┘
KC_LALT, KC_LGUI, SFT_ENT, KC_SPC, LT_BSFN, KC_BSPC
// └────────┴────────┴────────┘└────────┴────────┴────────┘
),

// Function (and I guess also media & navigation) layer
[_FUNCTION] = LAYOUT (

// ┌────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┐
_______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, _______,
// ├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤
_______, KC_GRV, KC_LPRN, KC_RPRN, KC_F11, KC_F12, KC_INS, KC_HOME, KC_UP, KC_PGUP, _______, _______,
// ├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤
_______, KC_LCBR, KC_LBRC, KC_RBRC, KC_RCBR, OSM_CAG, KC_VOLU, KC_LEFT, KC_DOWN, KC_RGHT, KC_BSPC, _______,
// ├────────┼────────┼────────┼────────┼────────┼────────┼────────┐┌────────┼────────┼────────┼────────┼────────┼────────┼────────┤
_______, _______, _______, _______, _______, KC_MUTE, _______, _______, KC_VOLD, KC_DEL, KC_END, KC_PGDN, _______, _______,
// └────────┴────────┴────────┴────────┼────────┼────────┼────────┘└────────┼────────┴────────┴────────┴────────┴────────┴────────┘
_______, _______, _______, _______, _______, _______
// └────────┴────────┴────────┘└────────┴────────┴────────┘
)

};

static inline bool dualfunckey_was_tapped(const uint16_t time_when_pressed) {
return timer_elapsed(time_when_pressed) < TAPPING_TERM;
}

bool process_record_user(uint16_t keycode, keyrecord_t* record) {

// Static variables
static uint16_t timer_control_escape = 0;
static uint16_t timer_shift_enter = 0;
static uint16_t timer_shift_lparen = 0;
static uint16_t timer_shift_rparen = 0;

static bool dualfunckey_pending = false;

static bool shift_enter_is_pressed = false;
static bool shift_lparen_is_pressed = false;

// Was this function called to handle a keydown? If not, it was called by a
// key up.
const bool pressed = record->event.pressed;

// Any keydown (at all) spends a pending dual function key check. Why? If,
// for example, you use shift to type a capital letter, and shift keys down
// and up faster than the tapping term, did you mean to call shift's tapping
// key? No. You just meant to call shift.
if (pressed) {
dualfunckey_pending = false;
}

// Only keycodes >= SAFE_RANGE are handled in this function
if (keycode < SAFE_RANGE) {
// This keypress was not handled
return true;
}

// Handle custom keypresses here
switch (keycode) {

// -------------------------------------------------------------------------
// Dual function key (hold: left shift; tap: enter)
// -------------------------------------------------------------------------
case SFT_ENT:

// There are multiple keys that are mapped to left shift. Keep track of
// which are pressed
shift_enter_is_pressed = pressed;

// Handle keypress routine
if (pressed) {

// The [left shift/enter] key was pressed
register_code(KC_LSFT);

// Save keydown time for checking hold/tap on keyup
timer_shift_enter = timer_read();

// Pressing a dual function key requires a hold/tap check on key up
dualfunckey_pending = true;

} else {

// The [left shift/enter] key was unpressed
// Note: unregister shift before pressing ENT so that ENT registers
// correctly

// If no other left shift keys are currently pressed, unregister it
if (! shift_lparen_is_pressed) {
unregister_code(KC_LSFT);
}

// If a pending dual function key hasn't been used yet, use it here
if (dualfunckey_pending && dualfunckey_was_tapped(timer_shift_enter)) {
tap_code(KC_ENT);
dualfunckey_pending = false;
}
}

// This keypress was handled
return false;

// -------------------------------------------------------------------------
// Dual function key (hold: left control; tap: escape)
// -------------------------------------------------------------------------
case CTL_ESC:

// Handle keypress routine
if (pressed) {

// Control/escape key was pressed
register_code(KC_LCTL);

// Save keydown time for checking hold/tap on keyup
timer_control_escape = timer_read();

// Pressing a dual function key requires a hold/tap check on key up
dualfunckey_pending = true;

} else {

// Control/escape key was unpressed
unregister_code(KC_LCTL);

// If a pending dual function key hasn't been used yet, use it here
if (dualfunckey_pending && dualfunckey_was_tapped(timer_control_escape)) {
tap_code(KC_ESC);
dualfunckey_pending = false;
}
}

// This keypress was handled
return false;

// -------------------------------------------------------------------------
// Dual function key (hold: left shift; tap: left parenthesis)
// -------------------------------------------------------------------------
case LST_PRN:

// There are multiple keys that are mapped to left shift. Keep track of
// which are pressed
shift_lparen_is_pressed = pressed;

// Handle keypress routine
if (pressed) {

// The [left shift/left parenthesis] key was pressed
register_code(KC_LSFT);

// Save keydown time for checking hold/tap on keyup
timer_shift_lparen = timer_read();

// Pressing a dual function key requires a hold/tap check on key up
dualfunckey_pending = true;

} else {

// The [left shift/left parenthesis] key was unpressed
// Note: unregister shift after tapping 9 so that left parenthesis
// registers correctly

// If a pending dual function key hasn't been used yet, use it here
if (dualfunckey_pending && dualfunckey_was_tapped(timer_shift_lparen)) {
tap_code(KC_9);
dualfunckey_pending = false;
}

// If no other left shift keys are currently pressed, unregister it
if (! shift_enter_is_pressed) {
unregister_code(KC_LSFT);
}
}

// This keypress was handled
return false;

// -------------------------------------------------------------------------
// Dual function key (hold: right shift; tap: right parenthesis)
// -------------------------------------------------------------------------
case RST_PRN:

// Handle keypress routine
if (pressed) {

// The [right shift/right parenthesis] key was pressed
register_code(KC_RSFT);

// Save keydown time for checking hold/tap on keyup
timer_shift_rparen = timer_read();

// Pressing a dual function key requires a hold/tap check on key up
dualfunckey_pending = true;

} else {

// The [right shift/right parenthesis] key was unpressed
// Note: unregister shift after tapping 0 so that right parenthesis
// registers correctly

// If a pending dual function key hasn't been used yet, use it here
if (dualfunckey_pending && dualfunckey_was_tapped(timer_shift_rparen)) {

// Space cadet shift: If the [left shift/left parenthesis] key
// is currently pressed, then tap the sequence ()
if (shift_lparen_is_pressed) {
tap_code(KC_9);
}

tap_code(KC_0);
dualfunckey_pending = false;
}

unregister_code(KC_RSFT);
}

// This keypress was handled
return false;

// -------------------------------------------------------------------------
// Some other key was pressed (this shouldn't happen)
// -------------------------------------------------------------------------
default:
// This keypress was not handled
return true;
}
}