renabled macros and added casemodes, which includes capsword, very cool

This commit is contained in:
Sadek Baroudi 2021-06-08 15:19:37 -07:00
parent e4b5879063
commit 7749a73fe4
7 changed files with 452 additions and 123 deletions

View File

@ -39,8 +39,8 @@
LAYOUT_wrapper( \
K01, K02, K03, K04, K05, K06, K07, LT(_WINNAV,K08), K09, K0A, \
LCTL_T(K11), LGUI_T(K12), LALT_T(K13), LSFT_T(K14), K15, K16, RSFT_T(K17), RALT_T(K18), RGUI_T(K19), RCTL_T(K1A), \
LSFT_T(K21), K22, K23, K24, K25, K26, K27, K28, K29, RSFT_T(K2A), \
KC_DEL, LT(_NAVIGATION,KC_ENT), LT(_FUNCTION,KC_TAB), _______, _______, LT(_FUNCTION,KC_BSPC), LT(_SYMBOLS,KC_SPACE), LT(_MOUSE,KC_QUOT) \
K21, K22, K23, K24, K25, K26, K27, K28, K29, LT(_MOUSE,K2A), \
KC_DEL, LT(_NAVIGATION,KC_ENT), LT(_FUNCTION,KC_TAB), _______, _______, LT(_FUNCTION,KC_BSPC), LT(_SYMBOLS,KC_SPACE), KC_QUOT \
)
/* Re-pass though to allow templates to be used */

263
users/sadekbaroudi/casemodes.c Executable file
View File

@ -0,0 +1,263 @@
/* 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_UNDS:
case KC_BSPC:
// If mod chording disable the mods
if (record->event.pressed && (get_mods() != 0)) {
return true;
}
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;
}

47
users/sadekbaroudi/casemodes.h Executable file
View File

@ -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);

View File

@ -1,4 +1,5 @@
#include "sadekbaroudi.h"
#include "casemodes.h"
#if defined(RGBLIGHT_ENABLE)
#include "rgb_stuff.h"
#endif
@ -10,6 +11,10 @@ __attribute__((weak)) bool process_record_secrets(uint16_t keycode, keyrecord_t
// Defines actions tor my global custom keycodes. Defined in sadekbaroudi.h file
// Then runs the _keymap's record handler if not processed here
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
// Process case modes
if (!process_case_modes(keycode, record)) {
return false;
}
// If console is enabled, it will print the matrix position and status of each key pressed
#ifdef KEYLOGGER_ENABLE
# if defined(KEYBOARD_ergodox_ez) || defined(KEYBOARD_keebio_iris_rev2)
@ -40,43 +45,43 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
}
}
break;
// UNCOMMENT TO REENABLE MACROS
// case KC_MAKE: // Compiles the firmware, and adds the flash command based on keyboard bootloader
// if (!record->event.pressed) {
// #ifndef MAKE_BOOTLOADER
// uint8_t temp_mod = mod_config(get_mods());
// uint8_t temp_osm = mod_config(get_oneshot_mods());
// clear_mods();
// clear_oneshot_mods();
// #endif
// send_string_with_delay_P(PSTR("qmk"), TAP_CODE_DELAY);
// #ifndef MAKE_BOOTLOADER
// if ((temp_mod | temp_osm) & MOD_MASK_SHIFT)
// #endif
// {
// send_string_with_delay_P(PSTR(" flash "), TAP_CODE_DELAY);
// #ifndef MAKE_BOOTLOADER
// } else {
// send_string_with_delay_P(PSTR(" compile "), TAP_CODE_DELAY);
// #endif
// }
// send_string_with_delay_P(PSTR("-kb " QMK_KEYBOARD " -km " QMK_KEYMAP), TAP_CODE_DELAY);
// #ifdef RGB_MATRIX_SPLIT_RIGHT
// send_string_with_delay_P(PSTR(" RGB_MATRIX_SPLIT_RIGHT=yes"), TAP_CODE_DELAY);
// # ifndef OLED_DRIVER_ENABLE
// send_string_with_delay_P(PSTR(" OLED_DRIVER_ENABLE=no"), TAP_CODE_DELAY);
// # endif
// #endif
// send_string_with_delay_P(PSTR(SS_TAP(X_ENTER)), TAP_CODE_DELAY);
// }
// COMMENT TO DISABLE MACROS
case KC_MAKE: // Compiles the firmware, and adds the flash command based on keyboard bootloader
if (!record->event.pressed) {
#ifndef MAKE_BOOTLOADER
uint8_t temp_mod = mod_config(get_mods());
uint8_t temp_osm = mod_config(get_oneshot_mods());
clear_mods();
clear_oneshot_mods();
#endif
send_string_with_delay_P(PSTR("qmk"), TAP_CODE_DELAY);
#ifndef MAKE_BOOTLOADER
if ((temp_mod | temp_osm) & MOD_MASK_SHIFT)
#endif
{
send_string_with_delay_P(PSTR(" flash "), TAP_CODE_DELAY);
#ifndef MAKE_BOOTLOADER
} else {
send_string_with_delay_P(PSTR(" compile "), TAP_CODE_DELAY);
#endif
}
send_string_with_delay_P(PSTR("-kb " QMK_KEYBOARD " -km " QMK_KEYMAP), TAP_CODE_DELAY);
#ifdef RGB_MATRIX_SPLIT_RIGHT
send_string_with_delay_P(PSTR(" RGB_MATRIX_SPLIT_RIGHT=yes"), TAP_CODE_DELAY);
# ifndef OLED_DRIVER_ENABLE
send_string_with_delay_P(PSTR(" OLED_DRIVER_ENABLE=no"), TAP_CODE_DELAY);
# endif
#endif
send_string_with_delay_P(PSTR(SS_TAP(X_ENTER)), TAP_CODE_DELAY);
}
// break;
// case VRSN: // Prints firmware version
// if (record->event.pressed) {
// send_string_with_delay_P(PSTR(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION ", Built on: " QMK_BUILDDATE), TAP_CODE_DELAY);
// }
// break;
break;
// COMMENT TO DISABLE MACROS
case VRSN: // Prints firmware version
if (record->event.pressed) {
send_string_with_delay_P(PSTR(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION ", Built on: " QMK_BUILDDATE), TAP_CODE_DELAY);
}
break;
case KC_RGB_T: // This allows me to use underglow as layer indication, or as normal
#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
@ -174,70 +179,76 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
}
break;
#endif
// UNCOMMENT TO REENABLE MACROS
// case L_GREP:
// if (record->event.pressed) {
// SEND_STRING("grep -rn \"");
// } else {
// // when keycode is released
// }
// break;
// case L_FIND:
// if (record->event.pressed) {
// SEND_STRING("find . -name \"");
// } else {
// // when keycode is released
// }
// break;
// case L_GITCOMMIT:
// if (record->event.pressed) {
// SEND_STRING("git commit -a -m \"\""SS_TAP(X_LEFT));
// } else {
// // when keycode is released
// }
// break;
// case P_ANGBRKT:
// if (record->event.pressed) {
// SEND_STRING("<>"SS_TAP(X_LEFT));
// } else {
// // when keycode is released
// }
// break;
// case P_PAREN:
// if (record->event.pressed) {
// SEND_STRING("()"SS_TAP(X_LEFT));
// } else {
// // when keycode is released
// }
// break;
// case P_CURLY:
// if (record->event.pressed) {
// SEND_STRING("{}"SS_TAP(X_LEFT));
// } else {
// // when keycode is released
// }
// break;
// case P_BRKT:
// if (record->event.pressed) {
// SEND_STRING("[]"SS_TAP(X_LEFT));
// } else {
// // when keycode is released
// }
// break;
// case E_ROBOT:
// if (record->event.pressed) {
// SEND_STRING("d[o_0]b");
// } else {
// // when keycode is released
// }
// break;
// case E_CAT:
// if (record->event.pressed) {
// SEND_STRING("=^..^=");
// } else {
// // when keycode is released
// }
// break;
case CAPSWORD:
if (record->event.pressed) {
enable_caps_word();
}
break;
// COMMENT TO DISABLE MACROS
case L_GREP:
if (record->event.pressed) {
SEND_STRING("grep -rn \"");
} else {
// when keycode is released
}
break;
case L_FIND:
if (record->event.pressed) {
SEND_STRING("find . -name \"");
} else {
// when keycode is released
}
break;
case L_GITCOMMIT:
if (record->event.pressed) {
SEND_STRING("git commit -a -m \"\""SS_TAP(X_LEFT));
} else {
// when keycode is released
}
break;
case P_ANGBRKT:
if (record->event.pressed) {
SEND_STRING("<>"SS_TAP(X_LEFT));
} else {
// when keycode is released
}
break;
case P_PAREN:
if (record->event.pressed) {
SEND_STRING("()"SS_TAP(X_LEFT));
} else {
// when keycode is released
}
break;
case P_CURLY:
if (record->event.pressed) {
SEND_STRING("{}"SS_TAP(X_LEFT));
} else {
// when keycode is released
}
break;
case P_BRKT:
if (record->event.pressed) {
SEND_STRING("[]"SS_TAP(X_LEFT));
} else {
// when keycode is released
}
break;
case E_ROBOT:
if (record->event.pressed) {
SEND_STRING("d[o_0]b");
} else {
// when keycode is released
}
break;
case E_CAT:
if (record->event.pressed) {
SEND_STRING("=^..^=");
} else {
// when keycode is released
}
break;
// COMMENT TO DISABLE MACROS
}
return true;
}

View File

@ -12,17 +12,18 @@ enum userspace_custom_keycodes {
KC_RGB_T, // Toggles RGB Layer Indication mode
KC_RGB_BLT, // Toggles RGB Base Layer Override mode
RGB_IDL, // RGB Idling animations
// UNCOMMENT TO REENABLE MACROS
// KC_MAKE, // Run keyboard's customized make command
// L_GREP,
// L_FIND,
// L_GITCOMMIT,
// P_ANGBRKT,
// P_PAREN,
// P_CURLY,
// P_BRKT,
// E_ROBOT,
// E_CAT,
// COMMENT TO DISABLE MACROS
KC_MAKE, // Run keyboard's customized make command
L_GREP,
L_FIND,
L_GITCOMMIT,
P_ANGBRKT,
P_PAREN,
P_CURLY,
P_BRKT,
E_ROBOT,
E_CAT,
CAPSWORD,
NEW_SAFE_RANGE // use "NEWPLACEHOLDER for keymap specific codes
};

View File

@ -9,8 +9,11 @@ MOUSEKEY_ENABLE = yes
BACKLIGHT_ENABLE = no
NKRO_ENABLE = no
RAW_ENABLE = yes
CASEMODES_ENABLE = yes
EXTRAFLAGS += -flto
# UNCOMMENT TO DISABLE MACROS
# EXTRAFLAGS += -flto
# UNCOMMENT TO DISABLE MACROS
SPACE_CADET_ENABLE = no
GRAVE_ESC_ENABLE = no
@ -46,3 +49,7 @@ endif
ifeq ($(strip $(RAW_ENABLE)), yes)
SRC += hid.c
endif
ifeq ($(strip $(CASEMODES_ENABLE)), yes)
SRC += casemodes.c
endif

View File

@ -72,7 +72,7 @@ NOTE: These are all the same length. If you do a search/replace
#define _________________META_NAV_1________________ KC_ESC, KC_PGUP, KC_UP, KC_PGDN, _______
#define _________________META_NAV_2________________ KC_HOME, KC_LEFT, KC_DOWN, KC_RGHT, KC_END
#define _________________META_NAV_L1_______________ KC_CAPS, KC_GRV, LCTL(LSFT(KC_TAB)), LCTL(LGUI(KC_LEFT)), _______
#define _________________META_NAV_L1_______________ KC_CAPS, KC_GRV, LCTL(LSFT(KC_TAB)), LCTL(LGUI(KC_LEFT)), CAPSWORD
#define _________________META_NAV_R1_______________ _______, LCTL(LGUI(KC_RIGHT)), LCTL(KC_TAB), _______, KC_BSLS
#define __________________WIN_NAV_1________________ _______, _______, LGUI(KC_UP), _______, _______
@ -145,14 +145,14 @@ NOTE: These are all the same length. If you do a search/replace
#define __________________MOUSE_3__________________ KC_MS_ACCEL0, KC_MS_ACCEL1, KC_MS_ACCEL2, _______, _______
// COMMENT TO REENABLE MACROS
#define _________________MACROS_1__________________ ___________________BLANK___________________
#define _________________MACROS_2__________________ ___________________BLANK___________________
#define _________________MACROS_3__________________ ___________________BLANK___________________
// // UNCOMMENT TO DISABLE MACROS
// #define _________________MACROS_1__________________ ___________________BLANK___________________
// #define _________________MACROS_2__________________ ___________________BLANK___________________
// #define _________________MACROS_3__________________ ___________________BLANK___________________
// UNCOMMENT TO REENABLE MACROS
// #define _________________MACROS_1__________________ VRSN, L_FIND, L_GITCOMMIT, _______, E_ROBOT
// #define _________________MACROS_2__________________ P_ANGBRKT, P_PAREN, P_CURLY, P_BRKT, _______
// #define _________________MACROS_3__________________ KC_MAKE, L_GREP, _______, _______, E_CAT
// COMMENT TO DISABLE MACROS
#define _________________MACROS_1__________________ VRSN, L_FIND, L_GITCOMMIT, _______, E_ROBOT
#define _________________MACROS_2__________________ P_ANGBRKT, P_PAREN, P_CURLY, P_BRKT, _______
#define _________________MACROS_3__________________ KC_MAKE, L_GREP, _______, _______, E_CAT
// clang-format on