From 9d74c952152a4689e48c37f82a211c96a951c983 Mon Sep 17 00:00:00 2001 From: Aric Crosson Bouwers <48956351+ariccb@users.noreply.github.com> Date: Wed, 9 Feb 2022 18:03:43 -0700 Subject: [Keymap] submitting ariccb planck keymap (#16177) Co-authored-by: Ryan --- .../planck/keymaps/ariccb/features/caps_word.c | 122 +++++++++++++++++++++ .../planck/keymaps/ariccb/features/caps_word.h | 101 +++++++++++++++++ .../planck/keymaps/ariccb/features/select_word.c | 110 +++++++++++++++++++ .../planck/keymaps/ariccb/features/select_word.h | 37 +++++++ 4 files changed, 370 insertions(+) create mode 100644 keyboards/planck/keymaps/ariccb/features/caps_word.c create mode 100644 keyboards/planck/keymaps/ariccb/features/caps_word.h create mode 100644 keyboards/planck/keymaps/ariccb/features/select_word.c create mode 100644 keyboards/planck/keymaps/ariccb/features/select_word.h (limited to 'keyboards/planck/keymaps/ariccb/features') diff --git a/keyboards/planck/keymaps/ariccb/features/caps_word.c b/keyboards/planck/keymaps/ariccb/features/caps_word.c new file mode 100644 index 0000000000..c37e65d28a --- /dev/null +++ b/keyboards/planck/keymaps/ariccb/features/caps_word.c @@ -0,0 +1,122 @@ +// Copyright 2021-2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +// For full documentation, see +// https://getreuer.info/posts/keyboards/caps-word + +#include "caps_word.h" + +static bool caps_word_active = false; + +bool process_caps_word(uint16_t keycode, keyrecord_t* record) { +#ifndef NO_ACTION_ONESHOT + const uint8_t mods = get_mods() | get_oneshot_mods(); +#else + const uint8_t mods = get_mods(); +#endif // NO_ACTION_ONESHOT + + if (!caps_word_active) { + // Pressing both shift keys at the same time enables caps word. + if ((mods & MOD_MASK_SHIFT) == MOD_MASK_SHIFT) { + caps_word_set(true); // Activate Caps Word. + return false; + } + return true; + } + + if (!record->event.pressed) { return true; } + + if (!(mods & ~MOD_MASK_SHIFT)) { + switch (keycode) { + // Ignore MO, TO, TG, TT, and OSL layer switch keys. + case QK_MOMENTARY ... QK_MOMENTARY + 255: + case QK_TO ... QK_TO + 255: + case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER + 255: + case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE + 255: + case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER + 255: + return true; + +#ifndef NO_ACTION_TAPPING + case QK_MOD_TAP ... QK_MOD_TAP_MAX: + if (record->tap.count == 0) { + // Deactivate if a mod becomes active through holding a mod-tap key. + caps_word_set(false); + return true; + } + keycode &= 0xff; + break; + +#ifndef NO_ACTION_LAYER + case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: +#endif // NO_ACTION_LAYER + if (record->tap.count == 0) { return true; } + keycode &= 0xff; + break; +#endif // NO_ACTION_TAPPING + +#ifdef SWAP_HANDS_ENABLE + case QK_SWAP_HANDS ... QK_SWAP_HANDS_MAX: + if (keycode > 0x56F0 || record->tap.count == 0) { return true; } + keycode &= 0xff; + break; +#endif // SWAP_HANDS_ENABLE + } + + if (caps_word_press_user(keycode)) { + return true; + } + } + + caps_word_set(false); // Deactivate Caps Word. + return true; +} + +void caps_word_set(bool active) { + if (active != caps_word_active) { + if (active) { + clear_mods(); +#ifndef NO_ACTION_ONESHOT + clear_oneshot_mods(); +#endif // NO_ACTION_ONESHOT + } + + caps_word_active = active; + caps_word_set_user(active); + } +} + +bool caps_word_get(void) { return caps_word_active; } + +__attribute__((weak)) void caps_word_set_user(bool active) {} + +__attribute__((weak)) bool caps_word_press_user(uint16_t keycode) { + switch (keycode) { + // Keycodes that continue Caps Word, with shift applied. + case KC_A ... KC_Z: + add_weak_mods(MOD_BIT(KC_LSFT)); // Apply shift to the next key. + return true; + + // Keycodes that continue Caps Word, without shifting. + case KC_1 ... KC_0: + case KC_P1 ... KC_P0: + case KC_BSPC: + case KC_MINS: + case KC_UNDS: + return true; + + default: + return false; // Deactivate Caps Word. + } +} \ No newline at end of file diff --git a/keyboards/planck/keymaps/ariccb/features/caps_word.h b/keyboards/planck/keymaps/ariccb/features/caps_word.h new file mode 100644 index 0000000000..523c815157 --- /dev/null +++ b/keyboards/planck/keymaps/ariccb/features/caps_word.h @@ -0,0 +1,101 @@ +// Copyright 2021-2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +// Caps Word, activated by pressing both shift keys at the same time. +// +// This library implements "Caps Word", which is like conventional Caps Lock, +// but automatically disables itself at the end of the word. This is useful for +// typing all-caps identifiers like `MOD_MASK_ALT`. +// +// Caps Word is activated by pressing the left and right shift keys at the same +// time. This way you don't need a dedicated key for using Caps Word. I've +// tested that this works as expected with one-shot mods and Space Cadet Shift. +// If your shift keys are mod-taps, activate Caps Word by holding both shift +// mod-tap keys until the tapping term, release them, then begin typing. +// +// For full documentation, see +// https://getreuer.info/posts/keyboards/caps-word + +#pragma once + +#include QMK_KEYBOARD_H + +// Call this function from `process_record_user()` to implement Caps Word. +bool process_caps_word(uint16_t keycode, keyrecord_t* record); + +// Activates or deactivates Caps Word. For instance activate Caps Word with a +// combo by defining a `COMBO_ACTION` that calls `caps_word_set(true)`: +// +// void process_combo_event(uint16_t combo_index, bool pressed) { +// switch(combo_index) { +// case CAPS_COMBO: +// if (pressed) { +// caps_word_set(true); // Activate Caps Word. +// } +// break; +// +// // Other combos... +// } +// } +void caps_word_set(bool active); + +// Returns whether Caps Word is currently active. +bool caps_word_get(void); + +// An optional callback that gets called when Caps Word turns on or off. This is +// useful to represent the current Caps Word state, e.g. by setting an LED or +// playing a sound. In your keymap, define +// +// void caps_word_set_user(bool active) { +// if (active) { +// // Do something when Caps Word activates. +// } else { +// // Do something when Caps Word deactivates. +// } +// } +void caps_word_set_user(bool active); + +// An optional callback which is called on every key press while Caps Word is +// active. When the key should be shifted (that is, a letter key), the callback +// should call `add_weak_mods(MOD_BIT(KC_LSFT))` to shift the key. The callback +// also determines whether the key should continue Caps Word. Returning true +// continues the current "word", while returning false is "word breaking" and +// deactivates Caps Word. The default callback is +// +// bool caps_word_press_user(uint16_t keycode) { +// switch (keycode) { +// // Keycodes that continue Caps Word, with shift applied. +// case KC_A ... KC_Z: +// add_weak_mods(MOD_BIT(KC_LSFT)); // Apply shift to the next key. +// return true; +// +// // Keycodes that continue Caps Word, without shifting. +// case KC_1 ... KC_0: +// case KC_BSPC: +// case KC_MINS: +// case KC_UNDS: +// return true; +// +// default: +// return false; // Deactivate Caps Word. +// } +// } +// +// To customize, copy the above function into your keymap and add/remove +// keycodes to the above cases. +// +// NOTE: Outside of this callback, you can use `caps_word_set(false)` to +// deactivate Caps Word. +bool caps_word_press_user(uint16_t keycode); \ No newline at end of file diff --git a/keyboards/planck/keymaps/ariccb/features/select_word.c b/keyboards/planck/keymaps/ariccb/features/select_word.c new file mode 100644 index 0000000000..c0ffe0a90d --- /dev/null +++ b/keyboards/planck/keymaps/ariccb/features/select_word.c @@ -0,0 +1,110 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +// For full documentation, see +// https://getreuer.info/posts/keyboards/select-word + +#include "select_word.h" + +// Mac users, uncomment this line: +// #define MAC_HOTKEYS + +enum { STATE_NONE, STATE_SELECTED, STATE_WORD, STATE_FIRST_LINE, STATE_LINE }; + +bool process_select_word(uint16_t keycode, keyrecord_t* record, + uint16_t sel_keycode) { + static uint8_t state = STATE_NONE; + + if (keycode == KC_LSFT || keycode == KC_RSFT) { return true; } + + if (keycode == sel_keycode && record->event.pressed) { // On key press. + const uint8_t mods = get_mods(); +#ifndef NO_ACTION_ONESHOT + const uint8_t all_mods = mods | get_oneshot_mods(); +#else + const uint8_t all_mods = mods; +#endif // NO_ACTION_ONESHOT + if ((all_mods & MOD_MASK_SHIFT) == 0) { // Select word. +#ifdef MAC_HOTKEYS + register_code(KC_LALT); +#else + register_code(KC_LCTL); +#endif // MAC_HOTKEYS + if (state == STATE_NONE) { + tap_code(KC_RGHT); + tap_code(KC_LEFT); + } + register_code(KC_LSFT); + register_code(KC_RGHT); + state = STATE_WORD; + } else { // Select line. + if (state == STATE_NONE) { + clear_mods(); +#ifndef NO_ACTION_ONESHOT + clear_oneshot_mods(); +#endif // NO_ACTION_ONESHOT +#ifdef MAC_HOTKEYS + register_code16(LCTL(KC_A)); + tap_code16(LSFT(KC_E)); + unregister_code16(LCTL(KC_A)); +#else + tap_code(KC_HOME); + tap_code16(LSFT(KC_END)); +#endif // MAC_HOTKEYS + set_mods(mods); + state = STATE_FIRST_LINE; + } else { + register_code(KC_DOWN); + state = STATE_LINE; + } + } + return false; + } + + // `sel_keycode` was released, or another key was pressed. + switch (state) { + case STATE_WORD: + unregister_code(KC_RGHT); + unregister_code(KC_LSFT); +#ifdef MAC_HOTKEYS + unregister_code(KC_LALT); +#else + unregister_code(KC_LCTL); +#endif // MAC_HOTKEYS + state = STATE_SELECTED; + break; + + case STATE_FIRST_LINE: + state = STATE_SELECTED; + break; + + case STATE_LINE: + unregister_code(KC_DOWN); + state = STATE_SELECTED; + break; + + case STATE_SELECTED: + if (keycode == KC_ESC) { + tap_code(KC_RGHT); + state = STATE_NONE; + return false; + } + // Fallthrough. + default: + state = STATE_NONE; + } + + return true; +} diff --git a/keyboards/planck/keymaps/ariccb/features/select_word.h b/keyboards/planck/keymaps/ariccb/features/select_word.h new file mode 100644 index 0000000000..f762ba1179 --- /dev/null +++ b/keyboards/planck/keymaps/ariccb/features/select_word.h @@ -0,0 +1,37 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +// Select word/line button. +// +// Implements a button that selects the current word, assuming conventional text +// editor hotkeys. Pressing it again extends the selection to the following +// word. The effect is similar to word selection (W) in the Kakoune editor. +// +// Pressing the button with shift selects the current line, and pressing the +// button again extends the selection to the following line. +// +// Note for Mac users: Windows/Linux editing hotkeys are assumed by default. +// Uncomment the `#define MAC_HOTKEYS` line in select_word.c for Mac hotkeys. +// The Mac implementation is untested, let me know if it has problems. +// +// For full documentation, see +// https://getreuer.info/posts/keyboards/select-word + +#pragma once + +#include QMK_KEYBOARD_H + +bool process_select_word(uint16_t keycode, keyrecord_t* record, + uint16_t sel_keycode); -- cgit v1.2.3