Commit ac778dd74275
Changed files (6)
keyboards
moonlander
keyboards/moonlander/config/config.h
@@ -28,6 +28,9 @@
#define COMBO_TERM 40
#define CHORDAL_HOLD
+// Numword configuration
+#define NUMWORD_TIMEOUT 5000 // Time in ms before numword auto-disables (optional)
+
/* #define DOUBLE_TAP_SHIFT_TURNS_ON_CAPS_WORD 1 */
/* #define CAPS_WORD_INVERT_ON_SHIFT 1 */
keyboards/moonlander/config/keymap.c
@@ -22,6 +22,7 @@
#include "version.h"
#include "keymap_us.h"
#include "keymap_us_international_linux.h"
+#include "layermodes.h"
enum layers {
BEPO,
@@ -46,6 +47,7 @@ enum custom_keycodes {
FR_E_GRAVE_CAPS,
FR_A_GRAVE,
FR_A_GRAVE_CAPS,
+ NUMWORD, // Numword layer activation
};
const key_override_t circ_exclamation_override = ko_make_with_layers(MOD_MASK_SHIFT, KC_CIRC, KC_EXLM, 1 << BEPO);
@@ -220,13 +222,13 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// $ " « » ( ) @ + - / * = %
// shift: # 1 2 3 4 5 6 7 8 9 0 ° `
// ralt : – — < > [ ] ^ ± − ÷ × ≠ ‰
- // shift+ralt : ¶ „ “ ” ≤ ≥ _ ¬ ¼ ½ ¾ ′ ″
+ // shift+ralt : ¶ „ " " ≤ ≥ _ ¬ ¼ ½ ¾ ′ ″
// FIXME: should I invert ?
KC_DLR, FR_DQUO, US_LDAQ, US_RDAQ, KC_LPRN, KC_RPRN, XXXXXXX, XXXXXXX, KC_AT, KC_PLUS, KC_PMNS, KC_PSLS, KC_PAST, KC_PERC,
KC_TAB, KC_B, FR_E_AIGU, KC_P, KC_O, FR_E_GRAVE, XXXXXXX, XXXXXXX, KC_CIRC, KC_V, KC_D, KC_L, KC_J, KC_Z,
LT(NUMB, KC_EQL), HM_GUI_A, HM_ALT_U, HM_SFT_I, HM_CTL_E, HM_HYP_COMM, XXXXXXX, XXXXXXX, HM_HYP_C, HM_CTL_T, HM_SFT_S, HM_ALT_R, HM_GUI_N, LT(SYMB,KC_M),
KC_GRV, FR_A_GRAVE, KC_Y, KC_X, KC_DOT, KC_K, FR_QUOT, KC_Q, KC_G, KC_H, KC_F, KC_W,
- XXXXXXX,XXXXXXX,XXXXXXX,XXXXXXX, LT(MODS, KC_DEL), QK_REP, QK_AREP, KC_RALT, XXXXXXX,XXXXXXX,XXXXXXX,XXXXXXX,
+ XXXXXXX,XXXXXXX,XXXXXXX,XXXXXXX, LT(MODS, KC_DEL), QK_REP, NUMWORD, KC_RALT, XXXXXXX,XXXXXXX,XXXXXXX,XXXXXXX,
LT(NUMB, KC_SPC), LT(NAVI,KC_BSPC), XXXXXXX, XXXXXXX, OS_LSFT, LT(SYMB, KC_ENT)
),
[ERGL] = LAYOUT(
@@ -234,7 +236,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, XXXXXXX, XXXXXXX, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC,
KC_EQL, HM_GUI_A, HM_ALT_S, HM_SFT_D, HM_CTL_F, HM_HYP_G, XXXXXXX, XXXXXXX, HM_HYP_H, HM_CTL_J, HM_SFT_K, HM_ALT_L, HM_GUI_SCLN, KC_QUOT,
KC_GRV, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RBRC,
- XXXXXXX,XXXXXXX,XXXXXXX,XXXXXXX, KC_DEL, QK_REP, QK_AREP, KC_RALT, XXXXXXX,XXXXXXX,XXXXXXX,XXXXXXX,
+ XXXXXXX,XXXXXXX,XXXXXXX,XXXXXXX, KC_DEL, QK_REP, NUMWORD, KC_RALT, XXXXXXX,XXXXXXX,XXXXXXX,XXXXXXX,
LT(NUMB, KC_SPC), LT(NAVI,KC_BSPC), XXXXXXX, XXXXXXX, OS_LSFT, LT(SYMB, KC_ENT)
),
[QWER] = LAYOUT(
@@ -242,7 +244,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, XXXXXXX, XXXXXXX, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC,
KC_EQL, HM_GUI_A, HM_ALT_S, HM_SFT_D, HM_CTL_F, HM_HYP_G, XXXXXXX, XXXXXXX, HM_HYP_H, HM_CTL_J, HM_SFT_K, HM_ALT_L, HM_GUI_SCLN, KC_QUOT,
KC_GRV, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RBRC,
- XXXXXXX,XXXXXXX,XXXXXXX,XXXXXXX, KC_DEL, QK_REP, QK_AREP, KC_RALT, XXXXXXX,XXXXXXX,XXXXXXX,XXXXXXX,
+ XXXXXXX,XXXXXXX,XXXXXXX,XXXXXXX, KC_DEL, QK_REP, NUMWORD, KC_RALT, XXXXXXX,XXXXXXX,XXXXXXX,XXXXXXX,
LT(NUMB, KC_SPC), LT(NAVI,KC_BSPC), XXXXXXX, XXXXXXX, OS_LSFT, LT(SYMB, KC_ENT)
),
@@ -292,6 +294,18 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
uint8_t current_layer = get_highest_layer(layer_state);
uint8_t mod_state = get_mods();
+
+ // Process numword before other logic
+ if (!process_num_word(keycode, record)) {
+ return false;
+ }
+
+ // Handle NUMWORD separately since it needs both press and release
+ if (keycode == NUMWORD) {
+ process_num_word_activation(NUMB, record);
+ return false;
+ }
+
if (record->event.pressed) {
switch (keycode) {
// FR_DQUO on bépo layout
keyboards/moonlander/config/layermodes.c
@@ -0,0 +1,99 @@
+// Numword layer implementation
+// Based on https://github.com/treeman/qmk_firmware/blob/master/keyboards/ferris/keymaps/treeman/layermodes.c
+// and https://www.jonashietala.se/blog/2022/09/06/the_current_t-34_keyboard_layout/#Numbers
+
+#include QMK_KEYBOARD_H
+#include "layermodes.h"
+
+static uint16_t num_word_timer;
+static bool _num_word_enabled = false;
+static uint8_t _num_word_layer = 0;
+
+void enable_num_word(uint8_t layer) {
+ _num_word_enabled = true;
+ _num_word_layer = layer;
+ layer_on(layer);
+}
+
+void disable_num_word(uint8_t layer) {
+ _num_word_enabled = false;
+ layer_off(layer);
+}
+
+bool is_num_word_enabled(void) {
+ return _num_word_enabled;
+}
+
+void process_num_word_activation(uint8_t layer, const keyrecord_t *record) {
+ if (record->event.pressed) {
+ layer_on(layer);
+ num_word_timer = timer_read();
+ } else {
+ if (timer_elapsed(num_word_timer) < TAPPING_TERM) {
+ // Tapped, enable numword
+ _num_word_enabled = true;
+ _num_word_layer = layer;
+ } else {
+ // Held, just turn off the layer
+ layer_off(layer);
+ }
+ }
+}
+
+// Returns true if numword should remain active after pressing this key
+static bool is_num_word_key(uint16_t keycode) {
+ switch (keycode) {
+ // Numbers
+ case KC_1 ... KC_0:
+ case KC_P1 ... KC_P0:
+ // Numpad operators
+ case KC_PAST: // *
+ case KC_PSLS: // /
+ case KC_PMNS: // -
+ case KC_PPLS: // +
+ case KC_PDOT: // .
+ case KC_PCMM: // ,
+ case KC_PEQL: // =
+ // Other operators and symbols commonly used with numbers
+ case KC_PLUS:
+ case KC_MINS:
+ case KC_EQL:
+ case KC_PERC:
+ case KC_DOT:
+ case KC_COMM:
+ case KC_COLN:
+ case KC_UNDS:
+ // Special keys
+ case KC_BSPC:
+ case KC_DEL:
+ case KC_ENT:
+ case KC_SPC:
+ case QK_REP: // Repeat key
+ case QK_AREP: // Alternate repeat key
+ // x for hexadecimal
+ case KC_X:
+ // Modifiers (so they don't disable numword)
+ case KC_LSFT ... KC_RGUI:
+ case OS_LSFT ... OS_RGUI:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool process_num_word(uint16_t keycode, const keyrecord_t *record) {
+ if (!_num_word_enabled) {
+ return true;
+ }
+
+ if (!record->event.pressed) {
+ return true;
+ }
+
+ // Check if this key should keep numword active
+ if (!is_num_word_key(keycode)) {
+ disable_num_word(_num_word_layer);
+ }
+
+ return true;
+}
keyboards/moonlander/config/layermodes.h
@@ -0,0 +1,17 @@
+// Numword layer mode header
+
+#pragma once
+
+#include QMK_KEYBOARD_H
+
+// Enable/disable numword mode with specific layer
+void enable_num_word(uint8_t layer);
+void disable_num_word(uint8_t layer);
+bool is_num_word_enabled(void);
+
+// Process numword activation (should be called from custom keycode handler)
+void process_num_word_activation(uint8_t layer, const keyrecord_t *record);
+
+// Process numword logic (should be called from process_record_user)
+// Returns true to continue processing, false to stop
+bool process_num_word(uint16_t keycode, const keyrecord_t *record);
keyboards/moonlander/config/rules.mk
@@ -11,4 +11,7 @@ SPACE_CADET_ENABLE = no
TAP_DANCE_ENABLE = yes
LAYER_LOCK_ENABLE = yes
+# Include numword layer modes
+SRC += layermodes.c
+
EXTRAFLAGS += -flto
CLAUDE.md
@@ -157,6 +157,16 @@ cd tools/<tool-name>
go test ./...
```
+### Keyboard Firmware
+
+```bash
+# Build Moonlander QMK firmware
+cd keyboards/moonlander && ./go.sh build
+
+# Build eyelash_corne ZMK firmware (if applicable)
+cd keyboards/eyelash_corne && <build command>
+```
+
## Special Notes
- The repository uses XDG base directories for Nix configuration (enabled via `use-xdg-base-directories = true`)