forked from getreuer/qmk-keymap
-
Notifications
You must be signed in to change notification settings - Fork 0
/
repeat_key.h
247 lines (219 loc) · 9.54 KB
/
repeat_key.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
// Copyright 2022-2023 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.
/**
* @file repeat_key.h
* @brief Repeat Key - an extensible "repeat last key" implementation.
*
* @note Repeat Key is now a core QMK feature! See
* <https://docs.qmk.fm/#/feature_repeat_key>
*
* Repeat Key performs the action of last pressed key. Tapping the Repeat Key
* after tapping the Z key types another "z." Repeat Key remembers the modifiers
* that were active with the last key press. These modifiers are combined with
* any additional active modifiers while pressing the Repeat Key. For instance,
* if the last press key was Ctrl + Z, then Shift + Repeat Key performs Ctrl +
* Shift + Z.
*
* Also included is an Alternate Repeat Key, performing the "alternate" if there
* is one for the last key. By default it is defined for navigation keys to act
* in the reverse direction. If Page Down was the last key, the Alternate Repeat
* performs Page Up.
*
* The implementation is a generic event-plumbing strategy that interoperates
* predictably with most QMK features, including tap-hold keys, Auto Shift,
* Combos, and userspace macros.
*
* For full documentation, see
* <https://getreuer.info/posts/keyboards/repeat-key>
*/
#pragma once
#include "quantum.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Handler function for Repeat Key. Call either this function or
* `process_repeat_key_with_rev()` (but not both) from `process_record_user()`
* to implement Repeat Key in your keymap.
*
* If your `process_record_user()` has other handlers or macros, Repeat Key’s
* handler `process_repeat_key()` should preferably be called before anything
* else. (If you also use Achordion, then call Achordion's handler first, Repeat
* Key's handler second, and then other handlers.)
*/
bool process_repeat_key(uint16_t keycode, keyrecord_t* record,
uint16_t repeat_keycode);
/** Handler function for Repeat Key and Alternate Repeat Key. */
bool process_repeat_key_with_alt(uint16_t keycode, keyrecord_t* record,
uint16_t repeat_keycode,
uint16_t alt_repeat_keycode);
/**
* @brief Signed count of times the key has been repeated or alternate repeated.
*
* @note The count is nonzero only while a repeated or alternate-repeated key is
* being processed.
*
* When a key is pressed normally, the count is 0. When the Repeat Key is used
* to repeat a key, the count is 1 on the first repeat, 2 on the second repeat,
* and continuing up to 127.
*
* Negative counts are used similarly for alternate repeating. When the
* Alternate Repeat Key is used, the count is -1 on the first alternate repeat,
* -2 on the second, continuing down to -127.
*/
int8_t get_repeat_key_count(void);
/** @brief Keycode of the last key. */
uint16_t get_last_keycode(void);
/** @brief Mods that were active with the last key. */
uint8_t get_last_mods(void);
/** @brief Sets the last keycode. */
void set_last_keycode(uint16_t keycode);
/** @brief Sets the last mods. */
void set_last_mods(uint8_t mods);
/**
* @brief Callback defining which keys are remembered.
*
* @param keycode Keycode that was just pressed
* @param record keyrecord_t structure
* @param remembered_mods Mods that will be remembered with this key
* @return true Key is remembered (eligible for repeating)
* @return false Key is ignored
*
* Modifier and layer switch keys are always ignored. For all other keys, this
* callback is called on every key press. Returning true means that the key is
* remembered, false means it is ignored. By default, all non-modifier,
* non-layer switch keys are remembered.
*
* The `remembered_mods` arg represents the mods that will be remembered with
* this key. It can be modified to forget certain mods, for instance to forget
* capitalization when repeating shifted letters:
*
* // Forget Shift on letter keys.
* if (KC_A <= keycode && keycode <= KC_Z &&
* (*remembered_mods & ~MOD_MASK_SHIFT) == 0) {
* *remembered_mods = 0;
* }
*/
bool remember_last_key_user(uint16_t keycode, keyrecord_t* record,
uint8_t* remembered_mods);
/**
* @brief Keycode to be used for alternate repeating.
*
* Alternate Repeat performs this keycode based on the last eligible pressed key
* and mods, get_last_keycode() and get_last_mods(). For example, when the last
* key was KC_UP, this function returns KC_DOWN. The function returns KC_NO if
* the last key doesn't have a defined alternate.
*/
uint16_t get_alt_repeat_key_keycode(void);
/**
* @brief Optional user callback to define additional alternate keys.
*
* When `get_alt_repeat_key_keycode()` is called, it first calls this callback.
* It should return a keycode representing the "alternate" of the given keycode
* and mods. Returning KC_NO defers to the default definitions in
* `get_alt_repeat_key_keycode()`.
*
* This callback can be used to define additional pairs of keys that "reverse"
* each other. More generally, Alternate Repeat can be configured to perform an
* action that "complements" the last key---Alternate Repeat not limited to
* reverse repeating, and it need not be symmetric. For instance, you can use it
* to eliminate the worst same-finger bigrams in your layout.
*/
uint16_t get_alt_repeat_key_keycode_user(uint16_t keycode, uint8_t mods);
/**
* Registers (presses down) the Repeat Key. This is useful for invoking Repeat
* as part of a tap dance or other custom handler. Note that if doing so, you
* likely want to define `repeat_key_press_user()` to ignore the key associated
* with that handler so that the Repeat Key does not attempt to repeat itself.
*/
void repeat_key_register(void);
/** Unregisters (releases) the Repeat Key. */
void repeat_key_unregister(void);
/** Taps the Repeat Key with a delay of `TAP_CODE_DELAY`. */
void repeat_key_tap(void);
/**
* Registers (presses down) the Alternate Repeat Key, performing the alternate,
* if there is one, for the last pressed key. If no alternate is found, the
* function takes no action and returns false.
*
* @return True if an alternate key was found.
*/
bool alt_repeat_key_register(void);
/**
* Unregisters (releases) the Alternate Repeat Key.
*
* @return True if an alternate key was found.
*/
bool alt_repeat_key_unregister(void);
/**
* Taps the Alternate Repeat Key with a delay of TAP_CODE_DELAY.
*
* @return True if an alternate key was found.
*/
bool alt_repeat_key_tap(void);
// Deprecated APIs.
/** @deprecated Use `process_repeat_key_with_alt()` instead. */
static inline bool process_repeat_key_with_rev(uint16_t keycode,
keyrecord_t* record,
uint16_t repeat_keycode,
uint16_t rev_repeat_keycode) {
return process_repeat_key_with_alt(keycode, record, repeat_keycode,
rev_repeat_keycode);
}
/** @deprecated Use `get_repeat_key_count()` instead. */
static inline int8_t repeat_key_count(void) { return get_repeat_key_count(); }
/** @deprecated Use `get_last_keycode()` instead. */
static inline uint16_t get_repeat_key_keycode(void) {
return get_last_keycode();
}
/** @deprecated Use `get_last_keycode()` instead. */
static inline uint16_t repeat_key_keycode(void) { return get_last_keycode(); }
/** @deprecated Use `get_last_mods()` instead. */
static inline uint8_t get_repeat_key_mods(void) { return get_last_mods(); }
/** @deprecated Use `get_last_mods()` instead. */
static inline uint8_t repeat_key_mods(void) { return get_last_mods(); }
/** @deprecated Use `set_last_keycode()` instead. */
static inline void set_repeat_key_keycode(uint16_t keycode) {
set_last_keycode(keycode);
}
/** @deprecated Use `set_last_mods()` instead. */
static inline void set_repeat_key_mods(uint8_t mods) { set_last_mods(mods); }
/** @deprecated Use `remember_last_key_user()` instead. */
bool get_repeat_key_eligible_user(uint16_t keycode, keyrecord_t* record,
uint8_t* remembered_mods);
/** @deprecated Use `remember_last_key_user()` instead. */
bool get_repeat_key_eligible(uint16_t keycode, keyrecord_t* record);
/** @deprecated Use `get_alt_repeat_key_keycode()` instead. */
static inline uint16_t rev_repeat_key_keycode(void) {
return get_alt_repeat_key_keycode();
}
/** @deprecated Use `get_alt_repeat_key_keycode()` instead. */
static inline uint16_t get_rev_repeat_key_keycode(void) {
return get_alt_repeat_key_keycode();
}
/** @deprecated Use `get_alt_repeat_key_keycode_user()` instead. */
uint16_t get_rev_repeat_key_keycode_user(uint16_t keycode, uint8_t mods);
/** @deprecated Use `alt_repeat_key_register()` instead. */
static inline bool rev_repeat_key_register(void) {
return alt_repeat_key_register();
}
/** @deprecated Use `alt_repeat_key_unregister()` instead. */
static inline bool rev_repeat_key_unregister(void) {
return alt_repeat_key_unregister();
}
/** @deprecated Use `alt_repeat_key_tap()` instead. */
static inline bool rev_repeat_key_tap(void) { return alt_repeat_key_tap(); }
#ifdef __cplusplus
}
#endif