Skip to content

Commit b9b7d28

Browse files
committed
Select Word: Revise to avoid possible edge cases.
Motivated by #26, this commit makes a few tweaks to avoid what look like bugs in certain edge case situations. Thanks to @windhausen for reporting this: * On initial press, always clear the non-Shift mods. * Change uses of `register_code()` on mod keys to `register_mods()`. * Change uses of `SEND_STRING` to `tap_code()` calls, since the former is not supported on non-Latin layouts. * Mac, don't use the Ctrl+A / Crtl+E , since KC_A and KC_E might be remapped to other meanings if the OS is set to a non-US QWERTY layout. Instead use GUI+Left / GUI+Right. * Streamline to eliminate sending a unnecessary keyboard reports around setting and clearing mods.
1 parent 2abf74d commit b9b7d28

File tree

1 file changed

+25
-18
lines changed

1 file changed

+25
-18
lines changed

features/select_word.c

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2021-2022 Google LLC
1+
// Copyright 2021-2023 Google LLC
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -38,32 +38,40 @@ bool process_select_word(uint16_t keycode, keyrecord_t* record,
3838
if (keycode == sel_keycode && record->event.pressed) { // On key press.
3939
const uint8_t mods = get_mods();
4040
#ifndef NO_ACTION_ONESHOT
41-
const uint8_t all_mods = mods | get_oneshot_mods();
41+
const bool shifted = (mods | get_oneshot_mods()) & MOD_MASK_SHIFT;
42+
clear_oneshot_mods();
4243
#else
43-
const uint8_t all_mods = mods;
44+
const bool shifted = mods & MOD_MASK_SHIFT;
4445
#endif // NO_ACTION_ONESHOT
45-
if ((all_mods & MOD_MASK_SHIFT) == 0) { // Select word.
46+
47+
if (!shifted) { // Select word.
4648
#ifdef MAC_HOTKEYS
47-
register_code(KC_LALT);
49+
set_mods(MOD_BIT(KC_LALT));
4850
#else
49-
register_code(KC_LCTL);
51+
set_mods(MOD_BIT(KC_LCTL));
5052
#endif // MAC_HOTKEYS
5153
if (state == STATE_NONE) {
52-
SEND_STRING(SS_TAP(X_RGHT) SS_TAP(X_LEFT));
54+
send_keyboard_report();
55+
tap_code(KC_RGHT);
56+
tap_code(KC_LEFT);
5357
}
54-
register_code(KC_LSFT);
58+
register_mods(MOD_BIT(KC_LSFT));
5559
register_code(KC_RGHT);
5660
state = STATE_WORD;
5761
} else { // Select line.
5862
if (state == STATE_NONE) {
59-
clear_mods();
60-
#ifndef NO_ACTION_ONESHOT
61-
clear_oneshot_mods();
62-
#endif // NO_ACTION_ONESHOT
6363
#ifdef MAC_HOTKEYS
64-
SEND_STRING(SS_LCTL("a" SS_LSFT("e")));
64+
set_mods(MOD_BIT(KC_LGUI));
65+
send_keyboard_report();
66+
tap_code(KC_LEFT);
67+
register_mods(MOD_BIT(KC_LSFT));
68+
tap_code(KC_RGHT);
6569
#else
66-
SEND_STRING(SS_TAP(X_HOME) SS_LSFT(SS_TAP(X_END)));
70+
clear_mods();
71+
send_keyboard_report();
72+
tap_code(KC_HOME);
73+
register_mods(MOD_BIT(KC_LSFT));
74+
tap_code(KC_END);
6775
#endif // MAC_HOTKEYS
6876
set_mods(mods);
6977
state = STATE_FIRST_LINE;
@@ -79,11 +87,10 @@ bool process_select_word(uint16_t keycode, keyrecord_t* record,
7987
switch (state) {
8088
case STATE_WORD:
8189
unregister_code(KC_RGHT);
82-
unregister_code(KC_LSFT);
8390
#ifdef MAC_HOTKEYS
84-
unregister_code(KC_LALT);
91+
unregister_mods(MOD_BIT(KC_LSFT) | MOD_BIT(KC_LALT));
8592
#else
86-
unregister_code(KC_LCTL);
93+
unregister_mods(MOD_BIT(KC_LSFT) | MOD_BIT(KC_LCTL));
8794
#endif // MAC_HOTKEYS
8895
state = STATE_SELECTED;
8996
break;
@@ -103,7 +110,7 @@ bool process_select_word(uint16_t keycode, keyrecord_t* record,
103110
state = STATE_NONE;
104111
return false;
105112
}
106-
// Fallthrough.
113+
// Fallthrough intended.
107114
default:
108115
state = STATE_NONE;
109116
}

0 commit comments

Comments
 (0)