create users/datagrok (#7653)
* users/datagrok: add shared functions * users/datagrok: improve base-layer selection feature * users/datagrok: add README.md
This commit is contained in:
parent
05d6e6ca78
commit
5fb95c5f94
63
users/datagrok/README.md
Normal file
63
users/datagrok/README.md
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
# datagrok's QMK user-space code
|
||||||
|
|
||||||
|
## cdeq "comma dot exclamation question"
|
||||||
|
|
||||||
|
This is a hack to place `question mark` on `shift-comma` and `exclamation mark` on `shift-period`.
|
||||||
|
|
||||||
|
When using an operating system configured for a US/qwerty layout this replaces the angle brackets `<` `>` with `?` `!`. This helps on small keyboards to keep symbols for prose co-located in one layer, and symbols for programming in another.
|
||||||
|
|
||||||
|
It's a "hack" because the "proper" way to accomplish this would be to edit the operating system's keymap.
|
||||||
|
|
||||||
|
### setup
|
||||||
|
|
||||||
|
in your `keymap.c`:
|
||||||
|
|
||||||
|
#include "feature_cdeq.h"
|
||||||
|
|
||||||
|
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
return process_record_cdeq(keycode, record);
|
||||||
|
}
|
||||||
|
|
||||||
|
in your `rules.mk`,
|
||||||
|
|
||||||
|
SRC += feature_cdeq.c
|
||||||
|
|
||||||
|
### examples
|
||||||
|
|
||||||
|
- atreus:datagrok
|
||||||
|
- bm43a:datagrok
|
||||||
|
- mitosis:datagrok
|
||||||
|
|
||||||
|
## base layer selector
|
||||||
|
|
||||||
|
Defines a keycode `KF_LAYO` to rotate between available default layers.
|
||||||
|
|
||||||
|
`Shift`+`KF_LAYO` makes the currently selected one persistent across reboots.
|
||||||
|
|
||||||
|
This is useful if you'd like your keyboard to support and toggle between QWERTY, Dvorak, Colemak, Workman, and other layouts while keeping a common arrangement of modifier and function keys.
|
||||||
|
|
||||||
|
Since toggling layouts seems like something one does infrequently, I wanted to be able to operate this feature with a single key, instead of one for each layer like planck:default or bootmagic.
|
||||||
|
|
||||||
|
### setup
|
||||||
|
|
||||||
|
in your `keymap.c`:
|
||||||
|
|
||||||
|
#define KF_LAYO SAFE_RANGE
|
||||||
|
#include "feature_default_layers_selector.h"
|
||||||
|
const uint8_t highest_base_layer = 4;
|
||||||
|
|
||||||
|
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
return \
|
||||||
|
process_record_save_default_layer(keycode, record) && \
|
||||||
|
process_record_select_default_layer(keycode, record);
|
||||||
|
}
|
||||||
|
|
||||||
|
in your `rules.mk`,
|
||||||
|
|
||||||
|
SRC += feature_default_layers_selector.c
|
||||||
|
|
||||||
|
### examples
|
||||||
|
|
||||||
|
- atreus:datagrok
|
||||||
|
- bm43a:datagrok
|
||||||
|
- mitosis:datagrok
|
47
users/datagrok/feature_cdeq.c
Normal file
47
users/datagrok/feature_cdeq.c
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// This is a hack to place <question mark> on <shift-comma> and <exclamation
|
||||||
|
// mark> on <shift-period>, when using an operating system configured for a
|
||||||
|
// US/qwerty layout.
|
||||||
|
//
|
||||||
|
// cdeq = "comma dot exclamation question"
|
||||||
|
|
||||||
|
#include QMK_KEYBOARD_H
|
||||||
|
|
||||||
|
bool comm_shifted = false;
|
||||||
|
bool ques_shifted = false;
|
||||||
|
|
||||||
|
bool process_record_cdeq(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
uint8_t shifted;
|
||||||
|
uint16_t s_keycode;
|
||||||
|
bool *k_shifted;
|
||||||
|
|
||||||
|
switch (keycode) {
|
||||||
|
case KC_COMM:
|
||||||
|
s_keycode = KC_SLSH;
|
||||||
|
k_shifted = &comm_shifted;
|
||||||
|
break;
|
||||||
|
case KC_DOT:
|
||||||
|
s_keycode = KC_1;
|
||||||
|
k_shifted = &ques_shifted;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
shifted = get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT));
|
||||||
|
|
||||||
|
// Keydown. If shift is currently pressed, register its alternate keycode.
|
||||||
|
if (record->event.pressed && shifted) {
|
||||||
|
*k_shifted = true;
|
||||||
|
register_code(s_keycode);
|
||||||
|
return false;
|
||||||
|
// Keyup. If shift was pressed back when the key was pressed, unregister
|
||||||
|
// its alternate keycode.
|
||||||
|
} else if (!(record->event.pressed) && *k_shifted) {
|
||||||
|
*k_shifted = false;
|
||||||
|
unregister_code(s_keycode);
|
||||||
|
return false;
|
||||||
|
// Otherwise, behave as normal.
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
2
users/datagrok/feature_cdeq.h
Normal file
2
users/datagrok/feature_cdeq.h
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#include QMK_KEYBOARD_H
|
||||||
|
bool process_record_cdeq(uint16_t keycode, keyrecord_t *record);
|
46
users/datagrok/feature_default_layers_selector.c
Normal file
46
users/datagrok/feature_default_layers_selector.c
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#include "feature_default_layers_selector.h"
|
||||||
|
|
||||||
|
#ifdef AUDIO_ENABLE
|
||||||
|
#include "audio.h"
|
||||||
|
#ifdef DEFAULT_LAYER_SONGS
|
||||||
|
extern float default_layer_songs[][16][2];
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool process_record_save_default_layer(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
|
||||||
|
#if defined(AUDIO_ENABLE)
|
||||||
|
float saved_song[][2] = SONG(COIN_SOUND);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!(keycode == KF_LAYO
|
||||||
|
&& record->event.pressed
|
||||||
|
&& get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
eeconfig_update_default_layer(default_layer_state);
|
||||||
|
#if defined(AUDIO_ENABLE)
|
||||||
|
PLAY_SONG(saved_song);
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool process_record_select_default_layer(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
if (!(keycode == KF_LAYO
|
||||||
|
&& record->event.pressed)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!default_layer_state) {
|
||||||
|
default_layer_set(2);
|
||||||
|
} else {
|
||||||
|
default_layer_set(
|
||||||
|
(((1U<<(highest_base_layer+1))-1) & (default_layer_state<<1))
|
||||||
|
| (default_layer_state>>highest_base_layer));
|
||||||
|
}
|
||||||
|
led_set(host_keyboard_leds());
|
||||||
|
#if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
|
||||||
|
PLAY_SONG(default_layer_songs[get_highest_layer(default_layer_state)]);
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
69
users/datagrok/feature_default_layers_selector.h
Normal file
69
users/datagrok/feature_default_layers_selector.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#include QMK_KEYBOARD_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
Define a keycode KF_LAYO to rotate between available default layers.
|
||||||
|
Shift+KF_LAYO makes the current one persistent.
|
||||||
|
|
||||||
|
To use:
|
||||||
|
|
||||||
|
in your keymap.c, define KF_LAYO so it does not conflict with anything else.
|
||||||
|
then include this header and set highest_base_layer.
|
||||||
|
|
||||||
|
#define KF_LAYO SAFE_RANGE
|
||||||
|
#include "feature_default_layers_selector.h"
|
||||||
|
|
||||||
|
const uint8_t highest_base_layer = 4; // the index
|
||||||
|
|
||||||
|
and in your rules.mk,
|
||||||
|
|
||||||
|
SRC += feature_default_layers_selector.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
See https://docs.qmk.fm/#/keymap for docs about layers including the concept
|
||||||
|
of "base" or "default" layers.
|
||||||
|
|
||||||
|
This is broken into two functions so that:
|
||||||
|
|
||||||
|
- If you don't want to store the default layer state in eeprom, don't call
|
||||||
|
process_record_save_default_layer.
|
||||||
|
|
||||||
|
- If you have your own mechanism for setting the default layer state (to one
|
||||||
|
or multiple layers), do that instead of process_record_select_default_layer.
|
||||||
|
|
||||||
|
If you call both functions, call process_record_save_default_layer first.
|
||||||
|
|
||||||
|
The QMK docs seem to assume that you will have only one layer as your
|
||||||
|
default layer at any time, but the source code actually supports an arbitrary
|
||||||
|
default_layer_state (composition of layers)
|
||||||
|
|
||||||
|
quantum has "set_single_persistent_default_layer" but that writes to eeprom
|
||||||
|
every time you change your default layer preference. i wanted a behavior
|
||||||
|
instead which lets you switch default layers all you want, then store the
|
||||||
|
current configuration once you're happy with it. that way if you get into an
|
||||||
|
unusable state you can just unplug and replug your keyboard to escape from it.
|
||||||
|
|
||||||
|
this code assumes:
|
||||||
|
|
||||||
|
1. each default layer state that you would select among consists of a single
|
||||||
|
layer, which we will call a "base" layer.
|
||||||
|
|
||||||
|
2. all your "base" layers are stored contiguously at the bottom of your
|
||||||
|
keymaps[] stack, and there are no non-"base" layers mixed in.
|
||||||
|
|
||||||
|
3. you have a maximum of 8 "base" layers. that is, the highest base layer is
|
||||||
|
index 7.
|
||||||
|
|
||||||
|
while 16 and 32 bit platforms might allow default_layer_state to include more
|
||||||
|
and higher-numbered layers, eeconfig_update_default_layer saves only the first
|
||||||
|
8 bits of default_layer_state to eeprom.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef KF_LAYO
|
||||||
|
#define KF_LAYO SAFE_RANGE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const uint8_t highest_base_layer;
|
||||||
|
bool process_record_save_default_layer(uint16_t keycode, keyrecord_t *record);
|
||||||
|
bool process_record_select_default_layer(uint16_t keycode, keyrecord_t *record);
|
Loading…
Reference in New Issue
Block a user