diff options
Diffstat (limited to 'users/muppetjones')
23 files changed, 1715 insertions, 0 deletions
diff --git a/users/muppetjones/.clang-format b/users/muppetjones/.clang-format new file mode 100644 index 0000000000..df3dbd17b4 --- /dev/null +++ b/users/muppetjones/.clang-format @@ -0,0 +1,26 @@ +--- +BasedOnStyle: Google +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: 'true' +AlignConsecutiveDeclarations: 'true' +AlignOperands: 'true' +AllowAllParametersOfDeclarationOnNextLine: 'false' +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: 'false' +BinPackArguments: 'true' +BinPackParameters: 'true' +ColumnLimit: '160' +IndentCaseLabels: 'true' +IndentPPDirectives: AfterHash +IndentWidth: '4' +MaxEmptyLinesToKeep: '1' +PointerAlignment: Right +SortIncludes: 'false' +SpaceBeforeAssignmentOperators: 'true' +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: 'false' +TabWidth: '4' +UseTab: Never + +... diff --git a/users/muppetjones/config.h b/users/muppetjones/config.h new file mode 100644 index 0000000000..e8afa9d8c5 --- /dev/null +++ b/users/muppetjones/config.h @@ -0,0 +1,44 @@ +/* Copyright 2020 Stephen J. Bush @muppetjones + * + * 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 + +#ifdef RGBLIGHT_ENABLE +// # define RGBLIGHT_ANIMATIONS +# define RGBLIGHT_HUE_STEP 8 +# define RGBLIGHT_SAT_STEP 16 +# define RGBLIGHT_VAL_STEP 16 +# define RGBLIGHT_LIMIT_VAL 150 +# define RGBLIGHT_SLEEP +// # define RGBLIGHT_LAYERS +#endif + +#ifdef TAP_DANCE_ENABLE +// Change "hold" time (default is 200 ms) +// -- used for tap dance and other tap mods +# define TAPPING_TERM 175 + +// Prevent normal rollover on alphas from accidentally triggering mods. +# define IGNORE_MOD_TAP_INTERRUPT + +// Enable rapid switch from tap to hold, disables double tap hold auto-repeat. +# define TAPPING_FORCE_HOLD + +#endif + + +#define COMBO_COUNT 3 +#define COMBO_TERM 40 diff --git a/users/muppetjones/features/casemodes.c b/users/muppetjones/features/casemodes.c new file mode 100644 index 0000000000..da7c5e8fa9 --- /dev/null +++ b/users/muppetjones/features/casemodes.c @@ -0,0 +1,247 @@ +/* Copyright 2021 Andrew Rae ajrae.nv@gmail.com @andrewjrae + * + * 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 "casemodes.h" + +/* The caps word concept started with me @iaap on splitkb.com discord. + * However it has been implemented and extended by many splitkb.com users: + * - @theol0403 made many improvements to initial implementation + * - @precondition used caps lock rather than shifting + * - @dnaq his own implementation which also used caps lock + * - @sevanteri added underscores on spaces + * - @metheon extended on @sevanteri's work and added specific modes for + * snake_case and SCREAMING_SNAKE_CASE + * - @baffalop came up with the idea for xcase, which he implements in his own + * repo, however this is implemented by @iaap with support also for one-shot-shift. + * - @sevanteri + * - fixed xcase waiting mode to allow more modified keys and keys from other layers. + * - Added @baffalop's separator defaulting on first keypress, with a + * configurable default separator and overrideable function to determine + * if the default should be used. + */ + +#ifndef DEFAULT_XCASE_SEPARATOR +# define DEFAULT_XCASE_SEPARATOR KC_UNDS +#endif + +#define IS_OSM(keycode) (keycode >= QK_ONE_SHOT_MOD && keycode <= QK_ONE_SHOT_MOD_MAX) + +// bool to keep track of the caps word state +static bool caps_word_on = false; + +// enum to keep track of the xcase state +static enum xcase_state xcase_state = XCASE_OFF; +// the keycode of the xcase delimiter +static uint16_t xcase_delimiter; +// the number of keys to the last delimiter +static int8_t distance_to_last_delim = -1; + +// Check whether caps word is on +bool caps_word_enabled(void) { return caps_word_on; } + +// Enable caps word +void enable_caps_word(void) { + caps_word_on = true; +#ifndef CAPSWORD_USE_SHIFT + if (!host_keyboard_led_state().caps_lock) { + tap_code(KC_CAPS); + } +#endif +} + +// Disable caps word +void disable_caps_word(void) { + caps_word_on = false; +#ifndef CAPSWORD_USE_SHIFT + if (host_keyboard_led_state().caps_lock) { + tap_code(KC_CAPS); + } +#else + unregister_mods(MOD_LSFT); +#endif +} + +// Toggle caps word +void toggle_caps_word(void) { + if (caps_word_on) { + disable_caps_word(); + } else { + enable_caps_word(); + } +} + +// Get xcase state +enum xcase_state get_xcase_state(void) { return xcase_state; } + +// Enable xcase and pickup the next keystroke as the delimiter +void enable_xcase(void) { xcase_state = XCASE_WAIT; } + +// Enable xcase with the specified delimiter +void enable_xcase_with(uint16_t delimiter) { + xcase_state = XCASE_ON; + xcase_delimiter = delimiter; + distance_to_last_delim = -1; +} + +// Disable xcase +void disable_xcase(void) { xcase_state = XCASE_OFF; } + +// Place the current xcase delimiter +static void place_delimiter(void) { + if (IS_OSM(xcase_delimiter)) { + // apparently set_oneshot_mods() is dumb and doesn't deal with handedness for you + uint8_t mods = xcase_delimiter & 0x10 ? (xcase_delimiter & 0x0F) << 4 : xcase_delimiter & 0xFF; + set_oneshot_mods(mods); + } else { + tap_code16(xcase_delimiter); + } +} + +// Removes a delimiter, used for double tap space exit +static void remove_delimiter(void) { + if (IS_OSM(xcase_delimiter)) { + clear_oneshot_mods(); + } else { + tap_code(KC_BSPC); + } +} + +// overrideable function to determine whether the case mode should stop +__attribute__((weak)) bool terminate_case_modes(uint16_t keycode, const keyrecord_t *record) { + switch (keycode) { + // Keycodes to ignore (don't disable caps word) + case KC_A ... KC_Z: + case KC_1 ... KC_0: + case KC_MINS: + case KC_BSPC: + // If mod chording disable the mods + if (record->event.pressed && (get_mods() != 0)) { + return true; + } + break; + case KC_UNDS: + // Allow to be pressed with or without a modifier (prob w/ shift) + break; + default: + if (record->event.pressed) { + return true; + } + break; + } + return false; +} + +/* overrideable function to determine whether to use the default separator on + * first keypress when waiting for the separator. */ +__attribute__((weak)) bool use_default_xcase_separator(uint16_t keycode, const keyrecord_t *record) { + // for example: + /* switch (keycode) { */ + /* case KC_A ... KC_Z: */ + /* case KC_1 ... KC_0: */ + /* return true; */ + /* } */ + return false; +} + +bool process_case_modes(uint16_t keycode, const keyrecord_t *record) { + if (caps_word_on || xcase_state) { + if ((QK_MOD_TAP <= keycode && keycode <= QK_MOD_TAP_MAX) || (QK_LAYER_TAP <= keycode && keycode <= QK_LAYER_TAP_MAX)) { + // Earlier return if this has not been considered tapped yet + if (record->tap.count == 0) return true; + keycode = keycode & 0xFF; + } + + if (keycode >= QK_LAYER_TAP && keycode <= QK_ONE_SHOT_LAYER_MAX) { + // let special keys and normal modifiers go through + return true; + } + + if (xcase_state == XCASE_WAIT) { + // grab the next input to be the delimiter + if (use_default_xcase_separator(keycode, record)) { + enable_xcase_with(DEFAULT_XCASE_SEPARATOR); + } else if (record->event.pressed) { + // factor in mods + if (get_mods() & MOD_MASK_SHIFT) { + keycode = LSFT(keycode); + } else if (get_mods() & MOD_BIT(KC_RALT)) { + keycode = RALT(keycode); + } + enable_xcase_with(keycode); + return false; + } else { + if (IS_OSM(keycode)) { + // this catches the OSM release if no other key was pressed + set_oneshot_mods(0); + enable_xcase_with(keycode); + return false; + } + // let other special keys go through + return true; + } + } + + if (record->event.pressed) { + // handle xcase mode + if (xcase_state == XCASE_ON) { + // place the delimiter if space is tapped + if (keycode == KC_SPACE) { + if (distance_to_last_delim != 0) { + place_delimiter(); + distance_to_last_delim = 0; + return false; + } + // remove the delimiter and disable modes + else { + remove_delimiter(); + disable_xcase(); + disable_caps_word(); + return true; + } + } + // decrement distance to delimiter on back space + else if (keycode == KC_BSPC) { + --distance_to_last_delim; + } + // don't increment distance to last delim if negative + else if (distance_to_last_delim >= 0) { + // puts back a one shot delimiter if you we're back to the delimiter pos + if (distance_to_last_delim == 0 && (IS_OSM(xcase_delimiter))) { + place_delimiter(); + } + ++distance_to_last_delim; + } + + } // end XCASE_ON + + // check if the case modes have been terminated + if (terminate_case_modes(keycode, record)) { + disable_caps_word(); + disable_xcase(); + } +#ifdef CAPSWORD_USE_SHIFT + else if (keycode >= KC_A && keycode <= KC_Z) { + tap_code16(LSFT(keycode)); + return false; + } +#endif + + } // end if event.pressed + + return true; + } + return true; +} diff --git a/users/muppetjones/features/casemodes.h b/users/muppetjones/features/casemodes.h new file mode 100644 index 0000000000..4a8c00b3d2 --- /dev/null +++ b/users/muppetjones/features/casemodes.h @@ -0,0 +1,47 @@ +/* Copyright 2021 Andrew Rae ajrae.nv@gmail.com @andrewjrae + * + * 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 + +#include QMK_KEYBOARD_H + +// Check whether caps word is on +bool caps_word_enabled(void); +// Enable caps word +void enable_caps_word(void); +// Disable caps word +void disable_caps_word(void); +// Toggle caps word +void toggle_caps_word(void); + +// enum for the xcase states +enum xcase_state { + XCASE_OFF = 0, // xcase is off + XCASE_ON, // xcase is actively on + XCASE_WAIT, // xcase is waiting for the delimiter input +}; + +// Get xcase state +enum xcase_state get_xcase_state(void); +// Enable xcase and pickup the next keystroke as the delimiter +void enable_xcase(void); +// Enable xcase with the specified delimiter +void enable_xcase_with(uint16_t delimiter); +// Disable xcase +void disable_xcase(void); + +// Function to be put in process user +bool process_case_modes(uint16_t keycode, const keyrecord_t *record); diff --git a/users/muppetjones/features/combos.c b/users/muppetjones/features/combos.c new file mode 100644 index 0000000000..a6d14bb25c --- /dev/null +++ b/users/muppetjones/features/combos.c @@ -0,0 +1,36 @@ +/* Copyright 2020 Stephen J. Bush + * + * 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/>. + */ + +#ifdef COMBO_ENABLE +# include QMK_KEYBOARD_H + +enum combos { + H_COMM_TAB, + L_U_SCLN, + J_M_CAPS, +}; + +const uint16_t PROGMEM h_comm_tab[] = {KC_H, KC_COMM, COMBO_END}; +const uint16_t PROGMEM l_u_scln[] = {KC_L, KC_U, COMBO_END}; +const uint16_t PROGMEM j_m_caps[] = {KC_J, KC_M, COMBO_END}; + +// COMBO_COUNT defined in config.h +combo_t key_combos[COMBO_COUNT] = { + [H_COMM_TAB] = COMBO(h_comm_tab, KC_TAB), + [L_U_SCLN] = COMBO(l_u_scln, KC_SCLN), + [J_M_CAPS] = COMBO(j_m_caps, KC_CAPS), +}; +#endif diff --git a/users/muppetjones/features/combos.h b/users/muppetjones/features/combos.h new file mode 100644 index 0000000000..af092904e4 --- /dev/null +++ b/users/muppetjones/features/combos.h @@ -0,0 +1,17 @@ +/* Copyright 2020 Stephen J. Bush + * + * 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 diff --git a/users/muppetjones/features/dancelayers.c b/users/muppetjones/features/dancelayers.c new file mode 100644 index 0000000000..e7e5f2a6f2 --- /dev/null +++ b/users/muppetjones/features/dancelayers.c @@ -0,0 +1,98 @@ +/* Copyright 2020 Stephen J. Bush + * + * 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/>. + */ + +#ifdef TAP_DANCE_ENABLE + +# include QMK_KEYBOARD_H +# include "muppetjones.h" +# include "dancelayers.h" + +// Initialize tap structure associated with example tap dance key +static td_tap_t lyr_tap_state = {.is_press_action = true, .state = TD_NONE}; + +/* @brief Determine the current tap dance state + * @param A tap dance state struct. + * @return A struct. + */ +td_state_t cur_dance(qk_tap_dance_state_t *state) { + switch (state->count) { + case 1: + if (!state->pressed) + return TD_1X_TAP; + else + return TD_1X_HOLD; + case 2: + return TD_2X_TAP; + break; + case 3: + return TD_3X_TAP; + break; + case 4: + return TD_4X_TAP; + break; + default: + return TD_UNKNOWN; + } +} + +// Functions that control what our tap dance key does +__attribute__((weak)) void td_layer_finished(qk_tap_dance_state_t *state, void *user_data) { + lyr_tap_state.state = cur_dance(state); + switch (lyr_tap_state.state) { + case TD_1X_TAP: + if (layer_state_is(_MOUSE)) + layer_off(_MOUSE); + else + layer_on(_MOUSE); + break; + case TD_1X_HOLD: + layer_on(_ADJUST); + break; + case TD_2X_TAP: + // Toggle lower layer + if (layer_state_is(_LOWER)) + layer_off(_LOWER); + else + layer_on(_LOWER); + break; + case TD_3X_TAP: + // Toggle lower layer + if (layer_state_is(_RAISE)) + layer_off(_RAISE); + else + layer_on(_RAISE); + break; + case TD_4X_TAP: + // Toggle lower layer + if (layer_state_is(_ADJUST)) + layer_off(_ADJUST); + else + layer_on(_ADJUST); + break; + default: + break; + } +} + +__attribute__((weak)) void td_layer_reset(qk_tap_dance_state_t *state, void *user_data) { + // If the key was held down and now is released then switch off the layer + if (lyr_tap_state.state == TD_1X_HOLD) { + layer_off(_ADJUST); + } + lyr_tap_state.state = TD_NONE; +} + +#endif diff --git a/users/muppetjones/features/dancelayers.h b/users/muppetjones/features/dancelayers.h new file mode 100644 index 0000000000..23defcca92 --- /dev/null +++ b/users/muppetjones/features/dancelayers.h @@ -0,0 +1,82 @@ +/* Copyright 2020 Stephen J. Bush + * + * 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 +#ifdef TAP_DANCE_ENABLE +# include QMK_KEYBOARD_H + +/* + * TAP DANCE + * https://docs.qmk.fm/#/feature_tap_dance + */ + +// Define a type for as many tap dance states as you need +typedef enum { + TD_NONE = 0, + TD_UNKNOWN, + TD_1X_TAP, + TD_1X_HOLD, + TD_2X_TAP, + TD_3X_TAP, + TD_4X_TAP, +} td_state_t; + +// Our custom tap dance key; add any other tap dance keys to this enum +enum { + TD_LAYERS = 0, // NOTE: Start at 0 as this is also an array index +}; +# define TD_LAYR TD(TD_LAYERS) + +typedef struct { + bool is_press_action; + td_state_t state; +} td_tap_t; + +// Declare the functions to be used with your tap dance key(s) + +/* @brief Determine the current tap dance state + * @param A tap dance state struct. + * @return A struct. + */ +td_state_t cur_dance(qk_tap_dance_state_t *state); + +// Functions associated with individual tap dances + +/* @brief Associate tap actions with layers. + * + * NOTE: Weak attribute. Can (and should) be defined in keymap.c + * + * @param state Pointer to a tap dance state object. + * @param user_data Pointer to user data. + * @return None. + */ +void td_layer_finished(qk_tap_dance_state_t *state, void *user_data); + +/* @brief Reset tap dance actions. + * + * NOTE: Weak attribute. Can (and should) be defined in keymap.c + * + * @param state Pointer to a tap dance state object. + * @param user_data Pointer to user data. + * @return None. + */ +void td_layer_reset(qk_tap_dance_state_t *state, void *user_data); + +/* Define tap dance actions. + */ +__attribute__((weak)) +qk_tap_dance_action_t tap_dance_actions[1] = {[TD_LAYERS] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, td_layer_finished, td_layer_reset, 275)}; +#endif diff --git a/users/muppetjones/features/etchamouse.c b/users/muppetjones/features/etchamouse.c new file mode 100644 index 0000000000..e1d4c38e81 --- /dev/null +++ b/users/muppetjones/features/etchamouse.c @@ -0,0 +1,101 @@ +/* Copyright 2020 Stephen J. Bush + * + * 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 +#include "etchamouse.h" +#include "pointing_device.h" + +#if defined(POINTING_DEVICE_ENABLE) && defined(ENCODER_ENABLE) + +/** Track movement separately in both directions. This will allow us to + * smooth out the movement along diagonals + */ +typedef struct { + bool clockwise : 1; + uint8_t count : 7; + uint16_t timer : 16; + uint16_t elapsed : 16; +} key_tracker_t; + +static key_tracker_t tracker_x = {false, 0, 0, 0}; +static key_tracker_t tracker_y = {false, 0, 0, 0}; + +/** + * @brief Calculate the mouse move units for the given tracker. + * + * By using a key tracker rederence, we can minimize the amount of space + * required on the stack. As we will have the tracker object, we will also + * take the clockwise direction into account, which completely internalizes + * the movement unit logic within this single function. + * + * @param tracker: Pointer to a key tracker object. + * @return A integer from -127 to 127 + */ +static int8_t move_unit(key_tracker_t *tracker) { + if (0 == tracker->count) return 0; + + const uint16_t modifier = TAPPING_TERM_MOUSE_ENCODER < tracker->elapsed ? 1 : (TAPPING_TERM_MOUSE_ENCODER - tracker->elapsed) >> 1; + uint16_t speed = MOUSEKEY_INITIAL_SPEED + MOUSEKEY_MOVE_DELTA * modifier * (tracker->count >> 1); + + /* convert speed to USB mouse speed 1 to 127 */ + speed = (uint8_t)(speed / (1000.0f / MOUSEKEY_INTERVAL)); + speed = speed < 1 ? 1 : speed; + + return (tracker->clockwise ? 1 : -1) * (speed > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : speed); +} + +/** + * @brief Update key press tracker + * + * Update the time elapsed since the last keypress. + * If the key has not been pressed since the tapping term, then reset the count to zero. + * If the key was pressed, update the timer and increment the count. + * Number of keypresses will degrade based on tapping term and zero out based + * on the persistenc term. + * + * @param tracker: The object to update + * @param pressed: A boolean indicating whether or not the key was pressed + * @return None. + */ +static void update_tracker(key_tracker_t *tracker, bool pressed, bool clockwise) { + tracker->elapsed = timer_elapsed(tracker->timer); + if (pressed) { + tracker->timer = timer_read(); + tracker->count += 1; + tracker->clockwise = clockwise; + } else if (TAPPING_TERM_PERSISTENCE < tracker->elapsed) { + tracker->count = 0; + } else if (TAPPING_TERM_MOUSE_ENCODER < tracker->elapsed) { + tracker->count >>= 1; + } +} + +bool encoder_update_mouse(uint8_t index, bool clockwise) { + report_mouse_t curr_report = pointing_device_get_report(); + + update_tracker(&tracker_x, 0 == index, clockwise); + update_tracker(&tracker_y, 1 == index, clockwise); + + curr_report.x += move_unit(&tracker_x); + curr_report.y += move_unit(&tracker_y); + + pointing_device_set_report(curr_report); + pointing_device_send(); + + return true; +} + +#endif diff --git a/users/muppetjones/features/etchamouse.h b/users/muppetjones/features/etchamouse.h new file mode 100644 index 0000000000..86b0d03c6e --- /dev/null +++ b/users/muppetjones/features/etchamouse.h @@ -0,0 +1,59 @@ +/* Copyright 2020 Stephen J. Bush + * + * 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 + +#if defined(POINTING_DEVICE_ENABLE) && defined(ENCODER_ENABLE) + +/* max value on report descriptor */ +# ifndef MOUSEKEY_MOVE_MAX +# define MOUSEKEY_MOVE_MAX 127 +# elif MOUSEKEY_MOVE_MAX > 127 +# error MOUSEKEY_MOVE_MAX needs to be smaller than 127 +# endif +# ifndef MOUSEKEY_MOVE_DELTA +# define MOUSEKEY_MOVE_DELTA 25 +# endif +# ifndef MOUSEKEY_INITIAL_SPEED +# define MOUSEKEY_INITIAL_SPEED 100 +# endif +# ifndef MOUSEKEY_INTERVAL +# define MOUSEKEY_INTERVAL 75 +# endif + +/** Amount of time (ms) before zeroing out the count. + * A higher value will result in smoother curves but may lower accuracy + */ +# ifndef TAPPING_TERM_PERSISTENCE +# define TAPPING_TERM_PERSISTENCE 150 +# endif + +/** Amount of time (ms) to register consecutive key presses + * A higher value will smooth out mouse movement and increase speed for + * consecutive presses. + */ +# ifndef TAPPING_TERM_MOUSE_ENCODER +# define TAPPING_TERM_MOUSE_ENCODER 50 +# endif + +/** @brief Update mouse position based on encoder movement. + * @param index The encoder index. 0 controls x-axis; 1 controls y-axis. + * @param clockwise Indicates direction encoder was turned. + * @returns None. + */ +bool encoder_update_mouse(uint8_t index, bool clockwise); + +#endif diff --git a/users/muppetjones/features/rgblayers.c b/users/muppetjones/features/rgblayers.c new file mode 100644 index 0000000000..46858ae671 --- /dev/null +++ b/users/muppetjones/features/rgblayers.c @@ -0,0 +1,69 @@ +/* Copyright 2020 Stephen J. Bush + * + * 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/>. + */ + +#ifdef RGBLIGHT_ENABLE +# include QMK_KEYBOARD_H +# include "rgblayers.h" + +static rgblight_config_t home_rgb; + +__attribute__((weak)) void set_layer_hsv(layer_state_t state, HSV* offset) {} + +/* Placeholder function + * If defined in a keymap.c, this will be ignored. + */ +__attribute__((weak)) void post_process_record_keymap(uint16_t keycode, keyrecord_t* record) { return; } + +void post_process_record_user(uint16_t keycode, keyrecord_t* record) { + // Regular user keycode case statement + switch (keycode) { +# ifdef RGBLIGHT_ENABLE + case RGB_HUD: + case RGB_HUI: + case RGB_SAD: + case RGB_SAI: + case RGB_VAD: + case RGB_VAI: + set_rgb_home(); + break; +# endif + default: + break; + } +} + +void set_rgb_home(void) { + home_rgb.raw = eeconfig_read_rgblight(); + // these get the current -- not eeprom + // home_rgb.hue = rgblight_get_hue(); + // home_rgb.sat = rgblight_get_sat(); + // home_rgb.val = rgblight_get_val(); +} + +void set_rgb_by_layer(layer_state_t state) { + if (!rgblight_is_enabled()) { + return; // lighting not enabled + } + + HSV layer_color = {home_rgb.hue, home_rgb.sat, home_rgb.val}; + set_layer_hsv(state, &layer_color); + rgblight_sethsv_noeeprom( // + layer_color.h, // all 3 MUST be btwn 0 and 255 + layer_color.s, // + layer_color.v // + ); +} +#endif diff --git a/users/muppetjones/features/rgblayers.h b/users/muppetjones/features/rgblayers.h new file mode 100644 index 0000000000..35be7d7fe4 --- /dev/null +++ b/users/muppetjones/features/rgblayers.h @@ -0,0 +1,22 @@ +/* Copyright 2020 Stephen J. Bush + * + * 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 +#ifdef RGBLIGHT_ENABLE + +void set_rgb_by_layer(layer_state_t); +void set_rgb_home(void); +#endif diff --git a/users/muppetjones/muppetjones.c b/users/muppetjones/muppetjones.c new file mode 100644 index 0000000000..55051bdbcd --- /dev/null +++ b/users/muppetjones/muppetjones.c @@ -0,0 +1,57 @@ +/* Copyright 2020 Stephen J. Bush @muppetjones + * + * 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 +#include "muppetjones.h" +#include "tapmods.h" +#include "features/casemodes.h" + +/* Placeholder function + * If defined in a keymap.c, this will be ignored. + */ +__attribute__((weak)) bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { return true; } + +/* Handle keypresses + */ +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + if (!process_case_modes(keycode, record)) { + return false; + } + // Regular user keycode case statement + switch (keycode) { + case CLMK_DH: + if (record->event.pressed) { + set_single_persistent_default_layer(_CLMK_DH); + } + return false; + break; + case QWERTY: + if (record->event.pressed) { + // print("mode just switched to qwerty and this is a huge string\n"); + set_single_persistent_default_layer(_QWERTY); + } + return false; + break; + case CAPSWRD: + if (record->event.pressed) { + toggle_caps_word(); + } + return false; + default: + break; + } + return process_record_keymap(keycode, record); +} diff --git a/users/muppetjones/muppetjones.h b/users/muppetjones/muppetjones.h new file mode 100644 index 0000000000..f5b2a3a465 --- /dev/null +++ b/users/muppetjones/muppetjones.h @@ -0,0 +1,56 @@ +/* Copyright 2020 Stephen J. Bush @muppetjones + * + * 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 +#include QMK_KEYBOARD_H + +#include "tapmods.h" +#include "wrappers.h" +#include "features/casemodes.h" + +#ifdef COMBO_ENABLE +# include "features/combos.h" +#endif + +#ifdef ENCODER_ENABLE +# include "features/etchamouse.h" +#endif + +#ifdef RGBLIGHT_ENABLE +# include "features/rgblayers.h" +#endif + +#ifdef TAP_DANCE_ENABLE +# include "features/dancelayers.h" +#endif + +/* Define layer names */ +enum userspace_layers { + _CLMK_DH = 0, + _QWERTY, + _MOUSE, // Intended for encoders. Mostly pass through. + _LOWER, + _RAISE, + _NAV, + _ADJUST, +}; + +// for casemodes +enum custom_keycodes { + CLMK_DH = SAFE_RANGE, + QWERTY, + CAPSWRD, +}; diff --git a/users/muppetjones/readme.md b/users/muppetjones/readme.md new file mode 100644 index 0000000000..6569c01d95 --- /dev/null +++ b/users/muppetjones/readme.md @@ -0,0 +1,23 @@ +# License + +Copyright 2020 Stephen J. Bush @muppetjones + +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/>. + +# FEATURES + +- [Etch-a-sketch Encoders](readme/etchamouse.md) +- [RGB Layers](readme/rgblayers.md) +- [Tap Dance Layers](readme/dancelayers.md) +- [Tap Mods](readme/tapmods.md) diff --git a/users/muppetjones/readme/dancelayers.md b/users/muppetjones/readme/dancelayers.md new file mode 100644 index 0000000000..85c4b7cad9 --- /dev/null +++ b/users/muppetjones/readme/dancelayers.md @@ -0,0 +1,73 @@ +# Tap Dance Layers + +This feature creates a key that changes the current layer via tap dance. By +default, this assumes that you have the following layers defined: + +- `_ADJUST` +- `_LOWER` +- `_RAISE` +- `_MOUSE` + +And sets up the following tap dance: + +| Count | Action | Layer | +| ----- | ------ | --------- | +| 1x | hold | `_ADJUST` | +| 1x | tap | `_MOUSE` | +| 2x | tap | `_LOWER` | +| 3x | tap | `_RAISE` | +| 4x | tap | `_ADJUST` | + +## Usage + +> NOTE: If you use other tap-dance functions, you may require additonal setup. + +1. Copy `features/dancelayers.{c,h}` into your keymap or userspace directory. +2. Add the following to your `rules.mk` + + ``` + TAP_DANCE_ENABLE = yes + + SRC += ./features/dancelayers.c + ``` + +3. Add the following to your `keymap.c`: + + ``` + #ifdef TAP_DANCE_ENABLE + # include "features/dancelayers.h" + # define TD_LAYR TD(TD_LAYERS) + #else + # define TD_LAYR XXXXXXX + #endif + ``` + +4. Add `TD_LYR` to your keymap. + +## Functions and Enumerations + +The following functions are available for use: + +- `cur_dance` + +The following tap dance enumerations are defined: + +- `TD_1X_HOLD` +- `TD_1X_TAP` +- `TD_2X_TAP` +- `TD_3X_TAP` +- `TD_4X_TAP` + +## Overriding the Defaults + +If you want to define different layers to tap dance actions, you'll need to +define two additional functions in your `keymap.c`: + +- `td_lyr_finished` +- `td_lyr_reset` + +Both of these functions are necessary and require a certain pattern for each +layer. "Tap" actions are handled in `*_finished` while "hold" actions are +resolved in `*_finished` and `*_reset`. + +See the implementation in `dancelayers.c` for an example. diff --git a/users/muppetjones/readme/etchamouse.md b/users/muppetjones/readme/etchamouse.md new file mode 100644 index 0000000000..efcf718b22 --- /dev/null +++ b/users/muppetjones/readme/etchamouse.md @@ -0,0 +1,69 @@ +# Etch-a-Mouse + +Encoder-based mouse movement with acceleration! + +## Usage + +- Add the following to your rules.mk + + ``` + ENCODER_ENABLE = yes + POINTING_DEVICE_ENABLE = yes + ``` + +- Add the following block to your keymap.c + + ``` + #ifdef ENCODER_ENABLE + void encoder_update_user(uint8_t index, bool clockwise) { + # ifdef POINTING_DEVICE_ENABLE + encoder_update_mouse(index, clockwise); + # endif + return; + #endif + ``` + +> NOTE: I use the mousekey keycodes to add button one and two into my keymap. + +## How It Works + +> This implementation uses the pointing device library, but it reuses several +> of the same parameters from the mouse key acceleration. + +> The PD library is very light weight, but it does not animate cursor movement. +> tl;dr: The mouse movement will not be smooth! + +The acceleration has four parts: + +``` +initial speed + (delta * time * count) +``` + +1. **Initial Speed**. Uses the `MOUSEKEY_INITIAL_SPEED` parameter. +2. **Delta**. Uses the `MOUSEKEY_MOVE_DELTA` parameter. +3. **Time**. The faster you turn, the faster you move. + + Subtract the time elapsed since the last actuation from a tapping term, + defined by `TAPPING_TERM_MOUSE_ENCODER`†, with a minimum value of 1. + +4. **Count**. The more you turn, the faster you move. + + Count of the total number of actuations. This value will decay over time. + +† _I probably could and will eventually use `TAPPING_TERM`, but I did not want +to mess up my tap mods while experimenting with acceleration._ + +## Diagonal Movement + +Counting the number of actuations for a given axis allows us to persist movement +along a given axis to give us some diagonal movement when moving both axes, +which also helps with the acceleration a bit and makes the movement less blocky. + +## Time-based Decay (a.k.a., Deceleration) + +Originally, the actuation count zeroed out once the tapping term elapsed, but +this made the movement very choppy. Instead, the count will degrade on every +refresh after the tapping term has been exceeded; unfortunately, a refresh only +occurs on an actuation on either axis, so once the time elapsed exceeds the +persistence term, the count is cleared, which also removes any movement in that +axis. diff --git a/users/muppetjones/readme/rgblayers.md b/users/muppetjones/readme/rgblayers.md new file mode 100644 index 0000000000..fb69800177 --- /dev/null +++ b/users/muppetjones/readme/rgblayers.md @@ -0,0 +1,60 @@ +# Dynamic Underglow Lighting Per-Layer + +This bit of code allows you to define layer lighting that respects your current eeprom settings, e.g., brightness. It does this by storing the base state rgb + +## Setup + +1. Enable RGB underglow in your `rules.mk` + + ``` + RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow + ``` + +2. (Optional) Add RGB configuration to your `config.h` + + ``` + #ifdef RGBLIGHT_ENABLE + // # define RGBLIGHT_ANIMATIONS + # define RGBLIGHT_HUE_STEP 8 + # define RGBLIGHT_SAT_STEP 16 + # define RGBLIGHT_VAL_STEP 16 + # define RGBLIGHT_LIMIT_VAL 150 + # define RGBLIGHT_SLEEP + // # define RGBLIGHT_LAYERS + #endif + ``` + +3. Add `set_layer_hsv` function. This is where you define your layer-specific colors by setting the HSV properties on the `layer_color` pointer. This example uses the QMK RGB configuration parameters to keep the layer colors offset based on the current EEPROM HSV. + + > NOTE: The HSV values should be between 0 and 255, but setting the modulus on saturation causes the lights to go white on my board. I _think_ this is due to overflow, but I haven't had the chance to try and resolve it yet. + + + ``` + #ifdef RGBLIGHT_ENABLE + void set_layer_hsv(layer_state_t state, HSV* layer_color) { + int32_t h = layer_color->h, s = layer_color->s, v = layer_color->v; + switch (get_highest_layer(state)) { + case _RAISE: + h += 2 * RGBLIGHT_HUE_STEP; + break; + case _LOWER: + h += -2 * RGBLIGHT_HUE_STEP; + break; + case _NAV: + h += 1 * RGBLIGHT_HUE_STEP; + break; + case _MOUSE: + h += -7 * RGBLIGHT_HUE_STEP; + break; + default: + break; + } + layer_color->h = h % 255; + layer_color->s = s; + layer_color->v = v % 255; + return; + } + #endif + ``` + +4. (Optional) If you're using `post_process_record_user`, you'll need to change the name in your keymap to `post_process_record_keymap`. We use the user function to update the HSV state after one of the RGB keycodes is pressed. diff --git a/users/muppetjones/readme/tapmods.md b/users/muppetjones/readme/tapmods.md new file mode 100644 index 0000000000..eb707e05d9 --- /dev/null +++ b/users/muppetjones/readme/tapmods.md @@ -0,0 +1,25 @@ +# Tap Mods + +## Standard Keys + +| Keycode | Tap | Hold | Description | +| -------- | ------- | ----- | ---------------------------------------------------- | +| `HY_ESC` | Esc | Hyper | Esc on tap; hyper when held | +| `HR_*` | A, O | LGUI | Home-row for Colemak mod-DH and right-handed numpad. | +| \'\' | R, I, 6 | LALT | Home-row for Colemak mod-DH and right-handed numpad. | +| \'\' | S, E, 5 | LCTL | Home-row for Colemak mod-DH and right-handed numpad. | +| \'\' | T, N, 4 | LSFT | Home-row for Colemak mod-DH and right-handed numpad. | + +## Layers + +| Keycode | Tap | Hold | Description | +| ------- | ----- | ----- | --------------------------- | +| LOWER | -- | Lower | Temporarily activate layer. | +| RAISE | -- | Raise | Temporarily activate layer. | +| NAV | -- | Nav | Temporarily activate layer. | +| LOW_ENT | Enter | Lower | | +| LOW_SPC | Space | Lower | | +| NAV_SPC | Space | Nav | | +| RAI_ENT | Enter | Raise | | +| RAI_SPC | Space | Raise | | +| RAI_TAB | Tab | Raise | | diff --git a/users/muppetjones/readme/wrappers.md b/users/muppetjones/readme/wrappers.md new file mode 100644 index 0000000000..e8365ab7ad --- /dev/null +++ b/users/muppetjones/readme/wrappers.md @@ -0,0 +1,153 @@ +# Keymap Wrappers + +> Pattern adapted from users/drashna/wrapper.h + +Defines several object macros for common keycode sets. Each macro typically +covers 5 keycodes with a left- or right-hand orientation, and macros are +generally grouped into rows of three or four. + +> TODO: Use keymap builder to generate images. + +## Example + +``` +#define LAYOUT_wrapper(...) LAYOUT(__VA_ARGS__) + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { +// clang-format off +[_MODS] = LAYOUT_wrapper( + _______, ___________________BLANK___________________, ... + ... +), +//clang-format on +} +``` + +Substitute the appropriate `LAYOUT` function, e.g., `LAYOUT_planck_grid` for your board. + +## Wrappers + +> **How to Read the Tables** +> +> - Headers are numbered when wrapper is not hand-specific +> - Headers use `L` and `R` to indicate handedness +> - Headers use `P`, `R`, `M`, and `I` to indicate pinky, ring, middle, and index, respectively +> - Wrappers define a maximum of **five** keycodes -- hands are shown on the same row for readability + +### Alpha: Colemak mod-DH + +| # | LP | LR | LM | LI | LI+ | RI+ | RI | RM | RR | RP | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| 1 | Q | W | F | P | B | J | L | U | Y | ;ˆ | +| 2 | A° | R° | S° | T° | G | M | N° | E° | I° | O° | +| 3 | Z | X | C | D | V˜ | K | H | , | . | / | + +- **ˆ:** (Optional) Replace `;` with `'` (top-right) +- **°:** (Optional) Home row modifiers on tap-hold (GACS, SCAG) +- **˜:** (Optional) Tap-hold `shift` on `v` + +### Alpha: QWERTY + +| # | LP | LR | LM | LI | LI+ | RI+ | RI | RM | RR | RP | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| 1 | Q | W | E | R | T | Y | U | I | O | P | +| 2 | A | S | D | F | G | H | J | K | L | ; | +| 3 | Z | X | C | V | B | N | M | , | . | / | + +### Blank(-ish) + +Defines macros for common filler. + +| 1 | 2 | 3 | 4 | 5 | +| ---- | ---- | ---- | ---- | ---- | +| TRNS | TRNS | TRNS | TRNS | TRNS | +| xxxx | xxxx | xxxx | xxxx | xxxx | + +| LP | LR | LM | LI | LI+ | RI+ | RI | RM | RR | RP | +| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | +| LGUI | LALT | LCTL | LSFT | TRNS | TRNS | RSFT | RCTL | LALT | RGUI | + +### Adjust + +| # | LP | LR | LM | LI | LI+ | RI+ | RI | RM | RR | RP | +| --- | ------ | ----- | ---- | ----- | ------ | ---- | ------ | ------ | ---- | ---- | +| 1 | Reset | Debug | xxxx | Term+ | Term- | xxxx | AGNORM | AGSWAP | xxxx | xxxx | +| 2 | RgbTog | Hue+ | Sat+ | Val+ | RgbMod | xxxx | CLMKDH | QWERTY | xxxx | xxxx | +| 3 | xxxx | Hue- | Sat- | Val- | xxxx | xxxx | xxxx | xxxx | xxxx | xxxx | + +> Recommend: Define Right side per-board + +### Function + +| # | 1 | 2 | 3 | 4 | +| --- | --- | --- | --- | --- | +| 1 | F1 | F2 | F3 | F4 | +| 2 | F5 | F6 | F7 | F8 | +| 3 | F9 | F10 | F11 | F12 | + +### Media + +| # | 1 | 2 | 3 | 4 | 5 | +| --- | ----- | ----- | ----- | ---- | ---- | +| 1 | AuOn | MiOn | MuOn | Brm+ | Vol+ | +| 2 | AuOff | MiOff | MuOff | Brm- | Vol- | +| 3 | Play | Stop | Next | Prev | Mute | + +### Nav + +| # | RI+ | RI | RM | RR | RP | +| --- | ----- | ---- | ----- | ----- | ----- | +| 1 | Pg Up | Home | Wh Dn | Wh Up | End | +| 2 | Pg Dn | Left | Down | Up | Right | +| 3 | xxxx | xxxx | xxxx | xxxx | xxxx | + +### Numpad + +- `X Y` indicates the character `X` on keypress and character `Y` on `shift` keypress +- Second table shows characters with `alt` keypress + +| # | RI+ | RI | RM | RR | RP | +| --- | ----- | ----- | ----- | ----- | ----- | +| 1 | Del | `7 &` | `8 _` | `9 (` | | +| 2 | `- _` | `4 $` | `5 %` | `6 ^` | `*` | +| 3 | `= +` | `1 !` | `2 @` | `3 #` | `, <` | +| 4 | | `0 )` | `. >` | | | + +| # | RI+ | RI | RM | RR | RP | +| --- | ----- | ----- | ----- | ----- | ----- | +| 1 | | `¶ ‡` | `• °` | `ª ·` | `« »` | +| 2 | `– —` | `¢ ›` | `∞ fi` | `§ fl` | `° °` | +| 3 | `≠ ±` | `¡ ⁄` | `™ €` | `£ ‹` | `≤ ¯` | +| 4 | | | `º ‚` | | | + +### Symbols + +| # | LP | LR | LM | LI | LI+ | +| --- | ---- | ---- | ---- | ---- | ---- | +| 1 | ~ | \` | ( | ) | | +| 2 | LGUI | LALT | \[ ° | \] ° | \_ - | +| 3 | xxxx | xxxx | { | } | LSFT | + +- **°:** Home row modifiers on tap-hold (GACS, SCAG) + +### VIM + +| # | LP | LR | LM | LI | LI+ | +| --- | --- | --- | --- | --- | --- | +| 1 | Q° | W° | : | | | + +- **°:** Via transparency + +## Typical Layers + +My keymaps typically use the following layers. + +| # | Name | Via | Left | Right | +| --- | ---------- | ------------- | --------- | ------ | +| 0 | Colemak DH | Adjust | | | +| 1 | QWERTY | Adjust | | | +| 2 | Mouse | tap-dance | n/a | n/a | +| 3 | Lower | L home thumb | symbols | numpad | +| 4 | Raise | L outer thumb | | | +| 5 | Nav | R home thumb | home mods | nav | +| 6 | Adjust | tap-dance | RGB | MEDIA | diff --git a/users/muppetjones/rules.mk b/users/muppetjones/rules.mk new file mode 100644 index 0000000000..1decc2ed98 --- /dev/null +++ b/users/muppetjones/rules.mk @@ -0,0 +1,25 @@ +# Reduce firmware size +# https://thomasbaart.nl/2018/12/01/reducing-firmware-size-in-qmk/ +# also requires in config.h +# NO_ACTION_MACRO +# NO_ACTION_FUNCTION +LTO_ENABLE = yes + +SRC += muppetjones.c +SRC += features/casemodes.c + +ifdef COMBO_ENABLE + SRC += ./features/combos.c +endif + +ifdef ENCODER_ENABLE + SRC += ./features/etchamouse.c +endif + +ifdef RGBLIGHT_ENABLE + SRC += ./features/rgblayers.c +endif + +ifdef TAP_DANCE_ENABLE + SRC += ./features/dancelayers.c +endif diff --git a/users/muppetjones/tapmods.h b/users/muppetjones/tapmods.h new file mode 100644 index 0000000000..af3d160c5b --- /dev/null +++ b/users/muppetjones/tapmods.h @@ -0,0 +1,77 @@ +/* Copyright 2020 Stephen Bush + * + * 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 +#include QMK_KEYBOARD_H + +/* Define a stand-in from dancelayers.h in case tap-dance isn't enabled */ +#ifndef TAP_DANCE_ENABLE +# define TD_LAYR XXXXXXX +#endif + +/* Misc */ + +#define HY_ESC HYPR_T(KC_ESC) +#define HY_BSPC HYPR_T(KC_BSPC) + +/* Tap Mod Layers */ + +#define LOWER MO(_LOWER) +#define RAISE MO(_RAISE) +#define NAV MO(_NAV) + +#define ADJ_DEL LT(_ADJUST, KC_DEL) +#define LOW_ENT LT(_LOWER, KC_ENT) +#define LOW_SPC LT(_LOWER, KC_SPC) +#define LOW_BSP LT(_LOWER, KC_BSPC) +#define NAV_SPC LT(_NAV, KC_SPC) +#define RAI_BSP LT(_RAISE, KC_BSPC) +#define RAI_ENT LT(_RAISE, KC_ENT) +#define RAI_SPC LT(_RAISE, KC_SPC) +#define RAI_TAB LT(_RAISE, KC_TAB) + +/* Miryoku Home-row Mods + +NOTE: Uses GACS. +*/ + +// Left-hand home row mods (colemak) +#define HR_A LGUI_T(KC_A) +#define HR_R LALT_T(KC_R) +#define HR_S LCTL_T(KC_S) +#define HR_T LSFT_T(KC_T) + +// Right-hand home row mods (colemak) +#define HR_N RSFT_T(KC_N) +#define HR_E RCTL_T(KC_E) +#define HR_I LALT_T(KC_I) +#define HR_O RGUI_T(KC_O) + +// Right-hand Numpad +#define HR_4 RSFT_T(KC_4) +#define HR_5 RCTL_T(KC_5) +#define HR_6 LALT_T(KC_6) + +// Layout-specific mods +#define TM_VSFT LSFT_T(KC_V) // For Using V in layer combos (e.g., planck) + +// GACS (Lower) +#define HR_LBRC LCTL_T(KC_LBRC) +#define HR_RBRC LSFT_T(KC_RBRC) + +// Left-hand home row mods (lower)--- +// #define HOME_UND LCTL_T(KC_UNDS) // NOTE: Mod-tap restricted to basic keycodes +#define HOME_MIN LSFT_T(KC_MINS) diff --git a/users/muppetjones/wrappers.h b/users/muppetjones/wrappers.h new file mode 100644 index 0000000000..301554f5d5 --- /dev/null +++ b/users/muppetjones/wrappers.h @@ -0,0 +1,249 @@ +/* Copyright 2020 Stephen Bush + * + * 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 +#include "muppetjones.h" +#include "tapmods.h" + +/* Pattern adapted from users/drashna/wrapper.h + Define per-layout keymap sections. Also requires a wrapper. + + Example: + + #define LAYOUT_:name_wrapper(...) LAYOUT_:name(__VA_ARGS__) + + const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [_MODS] = LAYOUT_:name _wrapper( + _______, ___________________BLANK___________________, ... + ... + ), + } +*/ + +#ifdef MOUSEKEY_ENABLE +# define MK_WH_D KC_WH_D +# define MK_WH_U KC_WH_U +#else +# define MK_WH_D XXXXXXX +# define MK_WH_U XXXXXXX +#endif + +// clang-format off +/* Blank-ish + * ,----------------------------------. * ,----------------------------------. + * | TRNS | TRNS | TRNS | TRNS | TRNS | * | xxxx | xxxx | xxxx | xxxx | xxxx | + * `----------------------------------' * `----------------------------------' + * ,----------------------------------. * ,----------------------------------. + * | LGUI | LALT | LCTL | LSFT | TRNS | * | TRNS | RSFT | RCTL | LALT | RGUI | + * `----------------------------------' * `----------------------------------' +*/ +#define __BLANK____________________________________ _______, _______, _______, _______, _______ +#define __BLANK_NOOP_______________________________ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX +#define __BLANK_W_GACS_____________________________ KC_LGUI, KC_LALT, KC_LCTL, KC_LSFT, _______ +#define __BLANK_W_SCAG_____________________________ _______, KC_RSFT, KC_RCTL, KC_LALT, KC_RGUI + +/* Adjust LH + * ,----------------------------------. ,----------------------------------. + * |Reset |Debug | xxxx |Term+ |Term- | | xxxx |AGNORM|AGSWAP| xxxx | xxxx | + * |------+------+------+------+------| |------+------+------+------+------| + * |RgbTog| Hue+ | Sat+ | Val+ |RgbMod| | xxxx |CLMKDH|QWERTY| xxxx | xxxx | + * |------+------+------+------+------| |------+------+------+------+------| + * | xxxx | Hue- | Sat- | Val- | xxxx | | xxxx | xxxx | xxxx | xxxx | xxxx | + * `----------------------------------' `----------------------------------' + */ + // NOTE: The "BACKLIT" keycode is planck specific +#define __ADJUST_L1________________________________ RESET, DEBUG, XXXXXXX, TERM_ON, TERM_OFF +#define __ADJUST_L2________________________________ RGB_TOG, RGB_HUI, RGB_SAI, RGB_VAI, RGB_MOD +#define __ADJUST_L3________________________________ XXXXXXX, RGB_HUD, RGB_SAD, RGB_VAD, XXXXXXX + +#define __ADJUST_R1________________________________ XXXXXXX, AG_NORM, AG_SWAP, XXXXXXX, XXXXXXX +#define __ADJUST_R2________________________________ XXXXXXX, CLMK_DH, QWERTY, XXXXXXX, XXXXXXX +#define __ADJUST_R3________________________________ __BLANK_NOOP_______________________________ + +/* Colemak mod-DH + * ,----------------------------------. ,----------------------------------. + * | Q | W | F | P | B | | J | L | U | Y | ;ˆ | + * |------+------+------+------+------| |------+------+------+------+------| + * | A | R | S | T | G | | M | N | E | I | O | + * |------+------+------+------+------| |------+------+------+------+------| + * | Z | X | C | D | V˜ | | K | H | , | . | / | + * `----------------------------------' `----------------------------------' + * ˆ Alternate: KC_QUOT + * ° Alternate: Home row mods (GASC, SCAG) + * ˜ Alternate: Hold for shift + * + * Colemak mod-DH (alt and alt+shift) + * ,----------------------------------. ,----------------------------------. + * | œ Œ | ∑ „ | | π ∏ | ı | | ∆ Ô | | | ¥ Á | æ Æ | + * |------+------+------+------+------| |------+------+------+------+------| + * | å Å | ® ‰ | ß Í | † ˇ | © ˝ | | µ  | ˜ ˜ | ´ ´ | ˆ ˆ | Ø | + * |------+------+------+------+------| |------+------+------+------+------| + * | Ω ¸ | ≈ ˛ | ç Ç | Î | √ ◊ | | ˚ | Ó | ≤ ¯ | ≥ ˘ | ÷ ¿ | + * `----------------------------------' `----------------------------------' + */ +#define __COLEMAK_MOD_DH_L1________________________ KC_Q, KC_W, KC_F, KC_P, KC_B +#define __COLEMAK_MOD_DH_L2_W_GACS_________________ HR_A, HR_R, HR_S, HR_T, KC_G +#define __COLEMAK_MOD_DH_L3________________________ KC_Z, KC_X, KC_C, KC_D, KC_V +#define __COLEMAK_MOD_DH_L3_W_SFTV_________________ KC_Z, KC_X, KC_C, KC_D, TM_VSFT + +#define __COLEMAK_MOD_DH_R1_W_QUOT_________________ KC_J, KC_L, KC_U, KC_Y, KC_QUOT +#define __COLEMAK_MOD_DH_R1________________________ KC_J, KC_L, KC_U, KC_Y, KC_SCLN +#define __COLEMAK_MOD_DH_R2_W_SCAG_________________ KC_M, HR_N, HR_E, HR_I, HR_O +#define __COLEMAK_MOD_DH_R3________________________ KC_K, KC_H, KC_COMM, KC_DOT, KC_SLASH + +/* Function (4 columns) + * ,---------------------------. + * | F1 | F2 | F3 | F4 | + * |------+------+------+------| + * | F5 | F6 | F7 | F8 | + * |------+------+------+------| + * | F9 | F10 | F11 | F12 | + * `---------------------------' + */ +#define __FUNC_X1_________________________ KC_F1, KC_F2, KC_F3, KC_F4 +#define __FUNC_X2_________________________ KC_F5, KC_F6, KC_F7, KC_F8 +#define __FUNC_X3_________________________ KC_F9, KC_F10, KC_F11, KC_F12 + +/* Game + */ +#define __GAME_L1__________________________________ KC_BTN3, KC_BTN2, KC_UP, KC_BTN1, KC_BTN5 +#define __GAME_L2__________________________________ KC_BTN4, KC_LEFT, KC_DOWN, KC_RIGHT,XXXXXXX +#define __GAME_L3__________________________________ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX + +#define __GAME_R1__________________________________ KC_Q, KC_1, KC_2, KC_3, XXXXXXX +#define __GAME_R2__________________________________ XXXXXXX, KC_4, KC_5, KC_6, XXXXXXX +#define __GAME_R3__________________________________ XXXXXXX, KC_7, KC_8, KC_9, XXXXXXX + + +/* Guitar + * ,----------------------------------. ,----------------------------------. + * | E | F |• F♯ | G |• G♯ | | A |• A♯ | B |• C | C♯ | + * | A | A♯ |• B | C |• C♯ | | D |• D♯ | E |• F | F♯ | + * | D | D♯ |• E | F |• F♯ | | G |• G♯ | A |• A♯ | B | + * | G | G♯ |• A | A♯ |• B | | C |• C♯ | D |• D♯ | E | + * | B | C |• C♯ | D |• D♯ | | E |• F | F♯ |• G | G♯ | + * | E | F |• F♯ | G |• G♯ | | A |• A♯ | B |• C | C♯ | + * `----------------------------------' `----------------------------------' + */ +// Not sure why, but this does not work (possibly due to the lowercase 's'?) +// #ifdef MIDI_ADVANCED +// #define __GUITAR_1E_L______________________________ MI_E_1, MI_F_1, MI_Fs_1, MI_G_1, MI_Gs_1 +// #define __GUITAR_2A_L______________________________ MI_A_1, MI_As_1, MI_B_1, MI_C_2, MI_Cs_2 +// #define __GUITAR_3D_L______________________________ MI_D_2, MI_Ds_2, MI_E_2, MI_F_2, MI_Fs_2 +// #define __GUITAR_4G_L______________________________ MI_G_2, MI_Gs_2, MI_A_2, MI_As_2, MI_B_2 +// #define __GUITAR_5B_L______________________________ MI_B_2, MI_C_3, MI_Cs_3, MI_D_3, MI_Ds_3 +// #define __GUITAR_6E_L______________________________ MI_E_3, MI_F_3, MI_Fs_3, MI_G_3, MI_Gs_3 +// +// #define __GUITAR_1E_R______________________________ MI_A_1, MI_As_1, MI_B_1, MI_C_2, MI_Cs_2 +// #define __GUITAR_2A_R______________________________ MI_D_2, MI_Ds_2, MI_E_2, MI_F_2, MI_Fs_2 +// #define __GUITAR_3D_R______________________________ MI_G_2, MI_Gs_2, MI_A_2, MI_As_2, MI_B_2 +// #define __GUITAR_4G_R______________________________ MI_C_3, MI_Cs_3, MI_D_3, MI_Ds_3, MI_E_3 +// #define __GUITAR_5B_R______________________________ MI_E_3, MI_F_3, MI_Fs_3, MI_G_3, MI_Gs_3 +// #define __GUITAR_6E_R______________________________ MI_A_3, MI_As_3, MI_B_3, MI_C_4, MI_Cs_4 +// #endif + + +/* MEDIA + * ,----------------------------------. + * | AuOn | MiOn | MuOn | Brm+ | Vol+ | + * |------+------+------+------+------| + * | AuOff| MiOff| MuOff| Brm- | Vol- | + * |------+------+------+------+------| + * | Play | Stop | Next | Prev | Mute | + * `----------------------------------' + */ +// What it MUV_IN and MUV_DE (5C2A and B)? +// https://github.com/qmk/qmk_firmware/blob/7e832e46de26989b81f2fbf58a0f391b2b0c1aaf/quantum/quantum_keycodes.h#L135 +#define __MEDIA_R1_________________________________ AU_ON, MI_ON, MU_ON, KC_BRMU, KC_VOLU +#define __MEDIA_R2_________________________________ AU_OFF, MI_OFF, MU_OFF, KC_BRMD, KC_VOLD +#define __MEDIA_R3_________________________________ KC_MPLY, KC_MSTP, KC_MNXT, KC_MPRV, KC_MUTE + + +/* NAV + * ,----------------------------------. + * | Pg Up| Home | Wh Dn| Wh Up| End | + * |------+------+------+------+------| + * | Pg Dn| Left | Down | Up | Right| + * |------+------+------+------+------| + * | xxxx | xxxx | xxxx | xxxx | xxxx | + * `----------------------------------' + */ +#define __NAV_R1___________________________________ KC_PGUP, KC_HOME, KC_WH_D, KC_WH_U, KC_END +#define __NAV_R2___________________________________ KC_PGDN, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT +#define __NAV_R3___________________________________ __BLANK_NOOP_______________________________ + +/* NUMPAD * (alt, alt+shift) + * ,----------------------------------. * ,----------------------------------. + * | Del | 7 & | 8 * | 9 ( | \ | | * | | ¶ ‡ | • ° | ª · | « » | + * |------+------+------+------+------| * |------+------+------+------+------| + * | - _ | 4 $ | 5 % | 6 ^ | * | * | – — | ¢ › | ∞ fi | § fl | ° ° | + * |------+------+------+------+------| * |------+------+------+------+------| + * | = + | 1 ! | 2 @ | 3 # | , | * | ≠ ± | ¡ ⁄ | ™ € | £ ‹ | ≤ ¯ | + * |------+------+------+------+------| * |------+------+------+------+------| + * | | 0 ) | . > | | | * | | | º ‚ | | | + * `----------------------------------' * `----------------------------------' + */ +#define __NUMPAD_R1________________________________ KC_GRV, KC_7, KC_8, KC_9, KC_BSLS +#define __NUMPAD_R2________________________________ KC_MINS, HR_4, HR_5, HR_6, KC_COMM +#define __NUMPAD_R3________________________________ KC_EQL, KC_1, KC_2, KC_3, KC_DOT +#define __NUMPAD_R4________________________________ _______, KC_0, KC_DOT, _______, _______ + +#define __NUMPAD_R3_ALT____________________________ KC_0, KC_1, KC_2, KC_3, KC_EQ + +/* Qwerty + * ,----------------------------------. ,----------------------------------. + * | Q | W | E | R | T | | Y | U | I | O | P | + * |------+------+------+------+------| |------+------+------+------+------| + * | A | S | D | F | G | | H | J | K | L | ; | + * |------+------+------+------+------| |------+------+------+------+------| + * | Z | X | C | V | B | | N | M | , | . | / | + * `----------------------------------' `----------------------------------' + */ +#define __QWERTY_L1________________________________ KC_Q, KC_W, KC_E, KC_R, KC_T +#define __QWERTY_L2________________________________ KC_A, KC_S, KC_D, KC_F, KC_G +#define __QWERTY_L3________________________________ KC_Z, KC_X, KC_C, KC_V, KC_B + +#define __QWERTY_R1________________________________ KC_Y, KC_U, KC_I, KC_O, KC_P +#define __QWERTY_R2________________________________ KC_H, KC_J, KC_K, KC_L, KC_SCLN +#define __QWERTY_R3________________________________ KC_N, KC_M, KC_COMM, KC_DOT, KC_SLASH + +/* SYMBOLS + * ,----------------------------------. + * | ~ | ` | ( | ) | | + * |------+------+------+------+------| + * | LGUI | LALT |LCTL [|LSFT ]| _ - | + * |------+------+------+------+------| + * | xxxx | xxxx | { | } | LSFT | + * `----------------------------------' + */ +#define __SYMBOLS_L1_______________________________ KC_TILD, KC_GRV, KC_LPRN, KC_RPRN, XXXXXXX +#define __SYMBOLS_L2_______________________________ KC_LGUI, KC_LALT, HR_LBRC, HR_RBRC, KC_UNDS +#define __SYMBOLS_L3_______________________________ XXXXXXX, XXXXXXX, KC_LCBR, KC_RCBR, KC_LSFT + +#define __SYMBOLS_R1_______________________________ KC_TILD, KC_LPRN, KC_RPRN, XXXXXXX, XXXXXXX +#define __SYMBOLS_R2_______________________________ KC_UNDS, HR_LBRC, HR_RBRC, XXXXXXX, XXXXXXX +#define __SYMBOLS_R3_______________________________ KC_PLUS, KC_LCBR, KC_RCBR, XXXXXXX, XXXXXXX + +/* VIM + * -- Roll through ":wq" via transparency + * ,----------------------------------. + * | Q | W | : | | | + * `----------------------------------' + */ +#define __VIM_L1___________________________________ _______, _______, KC_COLN, _______, _______ + +// clang-format on +// __END__ |