Last active
March 24, 2024 06:59
-
-
Save hnsol/edaf16fe5d4d679d980561923e048cad to your computer and use it in GitHub Desktop.
Advanced customization sketch for Keyboardio Atreus, featuring layered keymaps, macros and tap-dance functions.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* -*- mode: c++ -*- | |
* Atreus -- Chrysalis-enabled Sketch for the Keyboardio Atreus | |
* Copyright (C) 2018-2022 Keyboard.io, Inc | |
* | |
* This program is free software; you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License as published by | |
* the Free Software Foundation; either version 2 of the License, or | |
* (at your option) any later version. | |
* | |
* This program is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
* GNU General Public License for more details. | |
* | |
* You should have received a copy of the GNU General Public License along | |
* with this program; if not, write to the Free Software Foundation, Inc., | |
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
*/ | |
#ifndef BUILD_INFORMATION | |
#define BUILD_INFORMATION "locally built on " __DATE__ " at " __TIME__ | |
#endif | |
#include "Kaleidoscope.h" | |
#include "Kaleidoscope-EEPROM-Settings.h" | |
#include "Kaleidoscope-EEPROM-Keymap.h" | |
#include "Kaleidoscope-Escape-OneShot.h" | |
#include "Kaleidoscope-FirmwareVersion.h" | |
#include "Kaleidoscope-FocusSerial.h" | |
#include "Kaleidoscope-Macros.h" | |
#include "Kaleidoscope-MouseKeys.h" | |
#include "Kaleidoscope-OneShot.h" | |
#include "Kaleidoscope-Qukeys.h" | |
#include "Kaleidoscope-SpaceCadet.h" | |
#include "Kaleidoscope-DynamicMacros.h" | |
#include "Kaleidoscope-LayerNames.h" | |
#include <Kaleidoscope-TapDance.h> | |
#define MO(n) ShiftToLayer(n) | |
#define TG(n) LockLayer(n) | |
#define Key_Exclamation LSHIFT(Key_1) | |
#define Key_At LSHIFT(Key_2) | |
#define Key_Hash LSHIFT(Key_3) | |
#define Key_Dollar LSHIFT(Key_4) | |
#define Key_Percent LSHIFT(Key_5) | |
#define Key_Caret LSHIFT(Key_6) | |
#define Key_And LSHIFT(Key_7) | |
#define Key_Star LSHIFT(Key_8) | |
#define Key_Plus LSHIFT(Key_Equals) | |
#define Key_Colon LSHIFT(Key_Semicolon) | |
#define Key_Pipe LSHIFT(Key_Backslash) | |
// for layer | |
enum { | |
BASE, SYMBOL, NUMPAD, EMACS | |
}; | |
#define Key_Numpad MO(NUMPAD) | |
// for macro | |
enum { | |
MACRO_BASE, | |
MACRO_VERSION_INFO, | |
MACRO_SCM_4, | |
MACRO_SCM_5, | |
MACRO_LR_PAREN, | |
MACRO_LR_BRACKET, | |
MACRO_LR_CBRACKET, | |
MACRO_TAP_Q, | |
MACRO_EISU_MONUMPAD, | |
MACRO_CMD_ENTER, | |
}; | |
// for tapdance | |
enum { | |
TD_SAMPLE, | |
TD_PAREN, | |
TD_BRACKET, | |
TD_CBRACKET, | |
TD_MINUS, | |
}; | |
// clang-format off | |
KEYMAPS( | |
/* BASE | |
* +----------------------------------+ +----------------------------------+ | |
* | ESC/Q| W | E | R | T | | Y | U | I | O | P | | |
* | A/(3)| S | D/(2)| F | G +-------------+ H | J | K | L | ; | | |
* | Z/SHF| X | C | V | B | BS | TAB | N | M | , | Up | / | | |
* | TAB | Q | ALT |英LGui|英LCtl|Spc(2)|Ent/SH|か/(1)|かRGui| Left | Down | Right| | |
* +-----------------------------------------------------------------------------------+ | |
*/ | |
[BASE] = KEYMAP_STACKED | |
( | |
Key_Esc ,Key_W ,Key_E ,Key_R ,Key_T | |
,Key_A ,Key_S ,Key_D ,Key_F ,Key_G | |
,Key_Z ,Key_X ,Key_C ,Key_V ,Key_B ,Key_Backspace | |
,Key_LeftShift ,Key_Q ,Key_LeftAlt ,Key_Lang2 ,Key_Lang2 ,Key_Space | |
,Key_Y ,Key_U ,Key_I ,Key_O ,Key_P | |
,Key_H ,Key_J ,Key_K ,Key_L ,Key_Semicolon | |
,Key_Tab ,Key_N ,Key_M ,Key_Comma ,Key_UpArrow ,Key_Slash | |
,Key_Enter ,Key_Lang1 ,Key_Lang1 ,Key_LeftArrow ,Key_DownArrow ,Key_RightArrow | |
), | |
/* SYMBOL | |
* +----------------------------------+ +----------------------------------+ | |
* | ! | @ | # | $ | % | | ^ | & | * | (/() | ) | | |
* | 1/(3)| 2 | 3 | 4 | 5 +-------------+ 6 | 7 | 8 | 9 | 0 | | |
* | XXX | XXX | XXX | XXX | [/[] | (/() | ) | ] | XXX | XXX | XXX | \ | | |
* | ___ | ___ | ___ | ___ | ___ | TG(2)| ___ | ___ | XXX | XXX | XXX | = | | |
* +-----------------------------------------------------------------------------------+ | |
*/ | |
[SYMBOL] = KEYMAP_STACKED | |
( | |
Key_Exclamation ,Key_At ,Key_Hash ,Key_Dollar ,Key_Percent | |
,Key_1 ,Key_2 ,Key_3 ,Key_4 ,Key_5 | |
,XXX ,XXX ,XXX ,XXX ,TD(TD_BRACKET) ,TD(TD_PAREN) | |
,___ ,___ ,___ ,___ ,___ ,TG(NUMPAD) | |
,Key_Caret ,Key_And ,Key_Star ,TD(TD_PAREN) ,Key_RightParen | |
,Key_6 ,Key_7 ,Key_8 ,Key_9 ,Key_0 | |
,Key_RightParen ,Key_RightBracket ,XXX ,XXX ,XXX ,Key_Backslash | |
,___ ,___ ,XXX ,XXX ,XXX ,Key_Equals | |
), | |
/* NUMPAD | |
* +----------------------------------+ +----------------------------------+ | |
* | TG(0)| BriUp| ___ | ___ | ___ | | = | 7 | 8 | 9 | | | | |
* | /(3)| BriDn| ___ | ___ | ___ +-------------+ - | 4 | 5 | 6 | : | | |
* | ⌘S-5 | VolUp| ___ | ___ | Up | ___ | ___ | + | 1 | 2 | 3 | / | | |
* | ⌘S-4 | VolDn| ___ | Left | Down | Right| ___ | TG(2)| 0 | , | . | * | | |
* +-----------------------------------------------------------------------------------+ | |
*/ | |
[NUMPAD] = KEYMAP_STACKED | |
( | |
TG(BASE) ,Consumer_DisplayBrightnessIncrement ,___ ,___ ,___ | |
,___ ,Consumer_DisplayBrightnessDecrement ,___ ,___ ,___ | |
,M(MACRO_SCM_5) ,Consumer_VolumeIncrement ,___ ,___ ,Key_UpArrow ,___ | |
,M(MACRO_SCM_4) ,Consumer_VolumeDecrement ,___ ,Key_LeftArrow ,Key_DownArrow ,Key_RightArrow | |
,Key_Equals ,Key_7 ,Key_8 ,Key_9 ,Key_Pipe | |
,Key_Minus ,Key_4 ,Key_5 ,Key_6 ,Key_Colon | |
,___ ,Key_Plus ,Key_1 ,Key_2 ,Key_3 ,Key_Slash | |
,___ ,TG(NUMPAD) ,Key_0 ,Key_Comma ,Key_Period ,Key_Star | |
), | |
/* EMACS | |
* +----------------------------------+ +----------------------------------+ | |
* | XXX | XXX | C-e | XXX | XXX | | XXX | XXX | TAB | XXX | Up | | |
* | XXX | C-a | DEL | Right| ESC +-------------+ BS | C-j | C-k | - | XXX | | |
* | XXX | XXX | XXX | XXX | Left | XXX | XXX | Down | Enter| , | . | XXX | | |
* | XXX | XXX | XXX | XXX | XXX | XXX | XXX | XXX | XXX | - | ' | ` | | |
* +-----------------------------------------------------------------------------------+ | |
*/ | |
[EMACS] = KEYMAP_STACKED | |
( | |
XXX ,XXX ,LCTRL(Key_E) ,XXX ,XXX | |
,XXX ,LCTRL(Key_A) ,Key_Delete ,Key_RightArrow ,Key_Escape | |
,XXX ,XXX ,XXX ,XXX ,Key_LeftArrow ,XXX | |
,XXX ,XXX ,XXX ,XXX ,XXX ,XXX | |
,XXX ,XXX ,Key_Tab ,XXX ,Key_UpArrow | |
,Key_Backspace ,LCTRL(Key_J) ,LCTRL(Key_K) ,Key_Minus ,XXX | |
,XXX ,Key_DownArrow ,Key_Enter ,Key_Comma ,Key_Period ,XXX | |
,XXX ,XXX ,XXX ,Key_Minus ,Key_Quote ,Key_Backtick | |
) | |
) | |
// clang-format on | |
static void tapDanceEsc(uint8_t tap_dance_index, | |
uint8_t tap_count, | |
kaleidoscope::plugin::TapDance::ActionType tap_dance_action) { | |
tapDanceActionKeys(tap_count, tap_dance_action, Key_Escape, Key_Tab); | |
} | |
void tapDanceAction(uint8_t tap_dance_index, | |
KeyAddr key_addr, uint8_t tap_count, | |
kaleidoscope::plugin::TapDance::ActionType tap_dance_action) { | |
switch (tap_dance_index) { | |
// this is sample code | |
case TD_SAMPLE: | |
return tapDanceEsc(tap_dance_index, tap_count, tap_dance_action); | |
// my tapdance | |
case TD_PAREN: | |
return tapDanceActionKeys(tap_count, tap_dance_action, Key_LeftParen, M(MACRO_LR_PAREN)); | |
case TD_BRACKET: | |
return tapDanceActionKeys(tap_count, tap_dance_action, Key_LeftBracket, M(MACRO_LR_BRACKET)); | |
case TD_CBRACKET: | |
return tapDanceActionKeys(tap_count, tap_dance_action, Key_LeftCurlyBracket, M(MACRO_LR_CBRACKET)); | |
case TD_MINUS: | |
return tapDanceActionKeys(tap_count, tap_dance_action, Key_L, Key_Minus); | |
} | |
} | |
KALEIDOSCOPE_INIT_PLUGINS( | |
// ---------------------------------------------------------------------- | |
// Chrysalis plugins | |
// The EEPROMSettings & EEPROMKeymap plugins make it possible to have an | |
// editable keymap in EEPROM. | |
EEPROMSettings, | |
EEPROMKeymap, | |
// Focus allows bi-directional communication with the host, and is the | |
// interface through which the keymap in EEPROM can be edited. | |
Focus, | |
// FocusSettingsCommand adds a few Focus commands, intended to aid in | |
// changing some settings of the keyboard, such as the default layer (via the | |
// `settings.defaultLayer` command) | |
FocusSettingsCommand, | |
// FocusEEPROMCommand adds a set of Focus commands, which are very helpful in | |
// both debugging, and in backing up one's EEPROM contents. | |
FocusEEPROMCommand, | |
// The FirmwareVersion plugin lets Chrysalis query the version of the firmware | |
// programmatically. | |
// FirmwareVersion, | |
// The LayerNames plugin allows Chrysalis to display - and edit - custom layer | |
// names, to be shown instead of the default indexes. | |
LayerNames, | |
// ---------------------------------------------------------------------- | |
// Keystroke-handling plugins | |
// The Qukeys plugin enables the "Secondary action" functionality in | |
// Chrysalis. Keys with secondary actions will have their primary action | |
// performed when tapped, but the secondary action when held. | |
Qukeys, | |
// TapDance Plugin | |
TapDance, | |
// The macros plugin adds support for macros | |
Macros, | |
// Enables dynamic, Chrysalis-editable macros. | |
DynamicMacros, | |
// The MouseKeys plugin lets you add keys to your keymap which move the mouse. | |
MouseKeys, | |
MouseKeysConfig //, | |
); | |
const macro_t *macroAction(uint8_t macro_id, KeyEvent &event) { | |
if (keyToggledOn(event.state)) { | |
switch (macro_id) { | |
case MACRO_BASE: | |
// This macro is currently unused, but is kept around for compatibility | |
// reasons. We used to use it in place of `MoveToLayer(QWERTY/BASE)`, but no | |
// longer do. We keep it so that if someone still has the old layout with | |
// the macro in EEPROM, it will keep working after a firmware update. | |
Layer.move(BASE); | |
break; | |
case MACRO_VERSION_INFO: | |
Macros.type(PSTR("Keyboardio Atreus - Kaleidoscope ")); | |
Macros.type(PSTR(BUILD_INFORMATION)); | |
break; | |
case MACRO_SCM_4: | |
Macros.play(MACRO(D(LeftShift), D(LeftGui), T(4), U(LeftGui), U(LeftShift))); | |
break; | |
case MACRO_SCM_5: | |
Macros.play(MACRO(D(LeftShift), D(LeftGui), T(5), U(LeftGui), U(LeftShift))); | |
break; | |
case MACRO_LR_PAREN: | |
Macros.play(MACRO(T(LeftParen), T(RightParen), T(LeftArrow))); | |
break; | |
case MACRO_LR_BRACKET: | |
Macros.play(MACRO(T(LeftBracket), T(RightBracket), T(LeftArrow))); | |
break; | |
case MACRO_LR_CBRACKET: | |
Macros.play(MACRO(T(LeftCurlyBracket), T(RightCurlyBracket), T(LeftArrow))); | |
break; | |
case MACRO_TAP_Q: | |
Macros.play(MACRO(T(Q))); | |
break; | |
case MACRO_EISU_MONUMPAD: | |
Macros.play(MACRO(T(Lang2), D(Numpad))); | |
break; | |
case MACRO_CMD_ENTER: | |
Macros.play(MACRO(D(LeftGui), T(Enter))); | |
break; | |
default: | |
break; | |
} | |
} | |
return MACRO_NONE; | |
} | |
void setup() { | |
QUKEYS( | |
kaleidoscope::plugin::Qukey(0, KeyAddr(0, 0), M(MACRO_TAP_Q)), // ESC/Q(just 1 time) | |
kaleidoscope::plugin::Qukey(0, KeyAddr(1, 2), M(MACRO_EISU_MONUMPAD)), // D/英数+NUMPAD | |
kaleidoscope::plugin::Qukey(0, KeyAddr(2, 0), Key_LeftShift), // Z/Shift | |
// kaleidoscope::plugin::Qukey(0, KeyAddr(2, 11), Key_LeftShift), // //Shift | |
kaleidoscope::plugin::Qukey(0, KeyAddr(3, 3), Key_LeftGui), // 英数/LGui | |
kaleidoscope::plugin::Qukey(0, KeyAddr(3, 4), Key_LeftControl), // 英数/LControl | |
kaleidoscope::plugin::Qukey(0, KeyAddr(3, 5), MO(NUMPAD)), // Space/NUMPAD | |
kaleidoscope::plugin::Qukey(0, KeyAddr(3, 6), Key_RightShift), // Enter/Shift | |
kaleidoscope::plugin::Qukey(0, KeyAddr(3, 7), MO(SYMBOL)), // かな/SYMBOL | |
kaleidoscope::plugin::Qukey(0, KeyAddr(3, 8), Key_RightGui), // かな/RGui | |
kaleidoscope::plugin::Qukey(0, KeyAddr(1, 0), MO(EMACS)), // A/EMACS at (0) | |
kaleidoscope::plugin::Qukey(1, KeyAddr(1, 0), MO(EMACS)), // A/EMACS at (1) | |
kaleidoscope::plugin::Qukey(2, KeyAddr(1, 0), MO(EMACS)), // A/EMACS at (2) | |
) | |
// Qukeys.setHoldTimeout(250); // this is not the primary determining factor for a qukey’s state | |
Qukeys.setOverlapThreshold(65); // default:80 | |
Qukeys.setMaxIntervalForTapRepeat(0); | |
// Qukeys.activate(); | |
// milliseconds to wait before a tap-dance sequence times out | |
TapDance.setTimeout(250); | |
Kaleidoscope.setup(); | |
EEPROMKeymap.setup(9); | |
DynamicMacros.reserve_storage(48); | |
LayerNames.reserve_storage(63); | |
Layer.move(EEPROMSettings.default_layer()); | |
// To avoid any surprises, SpaceCadet is turned off by default. However, it | |
// can be permanently enabled via Chrysalis, so we should only disable it if | |
// no configuration exists. | |
SpaceCadetConfig.disableSpaceCadetIfUnconfigured(); | |
} | |
void loop() { | |
Kaleidoscope.loop(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment