diff --git a/keyboards/fingerpunch/sweeeeep/smathev/KEYMAP_LAYOUT.md b/keyboards/fingerpunch/sweeeeep/smathev/KEYMAP_LAYOUT.md new file mode 100644 index 00000000..80bc1a20 --- /dev/null +++ b/keyboards/fingerpunch/sweeeeep/smathev/KEYMAP_LAYOUT.md @@ -0,0 +1,271 @@ +# Sweeeeep Keyboard Layout - smathev + +## Overview +This is a 36-key split keyboard layout using the Norto layout (Danish optimized) with 4 layers. + +--- + +## Layer 0: NORTO (Base Layer) +**Default typing layer - Danish optimized layout** + +``` +┌─────┬─────┬─────┬─────┬─────┐ ┌─────┬─────┬─────┬─────┬─────┐ +│ Ø │ Æ │ U │ G │ J │ │ B │ F │ L │ H │ X │ +├─────┼─────┼─────┼─────┼─────┤ ├─────┼─────┼─────┼─────┼─────┤ +│ O │ I │ A │ T │ M │ │ P │ N │ R │ S │ D │ +├─────┼─────┼─────┼─────┼─────┤ ├─────┼─────┼─────┼─────┼─────┤ +│GUI ,│ALT Y│SFT Å│CTL V│ C │ │ W │CTL K│SFT Z│ALT Q│GUI .│ +└─────┴─────┴─────┴─────┴─────┘ └─────┴─────┴─────┴─────┴─────┘ + ┌─────┬─────┬─────┐ ┌─────┬─────┬─────┐ + │ NAV │ - │ E │ │SPC │BSPC │ SYM │ + │ LT │ │ │ │ │ │ LT │ + └─────┴─────┴─────┘ └─────┴─────┴─────┘ +``` + +**Key Features:** +- **Home row mods**: GUI, ALT, SHIFT, CTRL on bottom row (left and right) +- **Layer access**: Left thumb activates Navigation layer, Right thumb activates Symbol/FKey layer +- **Optimized for Danish**: Ø, Æ, Å in easy reach + +--- + +## Layer 1: QWERTY +**Alternative QWERTY layout for compatibility** + +``` +┌─────┬─────┬─────┬─────┬─────┐ ┌─────┬─────┬─────┬─────┬─────┐ +│ Q │ W │ E │ R │ T │ │ Y │ U │ I │ O │ P │ +├─────┼─────┼─────┼─────┼─────┤ ├─────┼─────┼─────┼─────┼─────┤ +│ A │ S │ D │ F │ G │ │ H │ J │ K │ L │ Å │ +├─────┼─────┼─────┼─────┼─────┤ ├─────┼─────┼─────┼─────┼─────┤ +│GUI Z│ALT X│SFT C│CTL V│ B │ │ N │CTL M│SFT Æ│ALT Ø│GUI -│ +└─────┴─────┴─────┴─────┴─────┘ └─────┴─────┴─────┴─────┴─────┘ + ┌─────┬─────┬─────┐ ┌─────┬─────┬─────┐ + │ NAV │ , │BSPC │ │SPC │ . │ ENT │ + │ LT │ │ │ │ │ │ │ + └─────┴─────┴─────┘ └─────┴─────┴─────┘ +``` + +**Toggling Layers:** +- Access from Navigation or Symbol layer toggle keys + +--- + +## Layer 2: NORTNAVIGATION (Navigation + Numpad) +**Activated by holding left thumb key** + +``` +┌─────┬─────┬─────┬─────┬─────┐ ┌─────┬─────┬─────┬─────┬─────┐ +│ ESC │PGUP │ ↑ │PGDN │STAB │ │ * │ 7 │ 8 │ 9 │ + │ +├─────┼─────┼─────┼─────┼─────┤ ├─────┼─────┼─────┼─────┼─────┤ +│HOME │ ← │ ↓ │ → │ END │ │ / │ 4 │ 5 │ 6 │ - │ +├─────┼─────┼─────┼─────┼─────┤ ├─────┼─────┼─────┼─────┼─────┤ +│ GUI │ ALT │SHFT │CTRL │ │ │ ( │CTL 1│SFT 2│ALT 3│GUI 0│ +└─────┴─────┴─────┴─────┴─────┘ └─────┴─────┴─────┴─────┴─────┘ + ┌─────┬─────┬─────┐ ┌─────┬─────┬─────┐ + │ │NORTO│QWRT │ │QWRT │NORTO│ │ + │ │ TG │ TG │ │ TG │ TG │ │ + └─────┴─────┴─────┘ └─────┴─────┴─────┘ +``` + +**Key Features:** +- **Left side**: Full navigation cluster (arrows, home, end, page up/down) +- **Right side**: Complete numpad with operators +- **Super Tab** (STAB): Special tab switching macro +- **Layer toggles**: Quick access to switch between NORTO and QWERTY base layers +- **Home row mods**: Maintained on left side for modifier combinations + +--- + +## Layer 3: SYMFKEYS (Symbols + Function Keys) +**Activated by holding right thumb key** + +``` +┌─────┬─────┬─────┬─────┬─────┐ ┌─────┬─────┬─────┬─────┬─────┐ +│ F1 │ F2 │ F3 │ F4 │ F5 │ │ @ │ [ │ { │ ^ │ │ +├─────┼─────┼─────┼─────┼─────┤ ├─────┼─────┼─────┼─────┼─────┤ +│ F6 │ F7 │ F8 │ F9 │ F10 │ │ ' │ < │ $ │ | │ ` │ +├─────┼─────┼─────┼─────┼─────┤ ├─────┼─────┼─────┼─────┼─────┤ +│GUI │ALT │SHFT │CTRL │ B │ │ │CAPS │ ___ │ - │ GUI │ +│ F11 │ F12 │ C │ V │ │ │ │WORD │CASE │CASE │ │ +└─────┴─────┴─────┴─────┴─────┘ └─────┴─────┴─────┴─────┴─────┘ + ┌─────┬─────┬─────┐ ┌─────┬─────┬─────┐ + │ │NORTO│QWRT │ │QWRT │NORTO│ │ + │ │ TG │ TG │ │ TG │ TG │ │ + └─────┴─────┴─────┘ └─────┴─────┴─────┘ +``` + +**Key Features:** +- **Left side**: Complete F-key row (F1-F12) with home row mods on F11/F12 +- **Right top row**: Common programming symbols (@, [, {, ^) +- **Right middle row**: Quote/bracket symbols (', <, $, |, `) +- **Right bottom row**: **CASEMODES KEYS!** + - **CAPSWORD**: Tap to enable caps word mode (hold with Ctrl for tap) + - **___CASE** (underscore): Tap to enable snake_case mode (hold with Shift for tap) + - **-CASE** (hyphen): Tap to enable kebab-case mode (hold with Alt for tap) + +**Symbol Notes:** +- Danish keyboard layout symbols: + - `DK_AT` (@) + - `DK_LBRC` ([) - Shift for ] + - `DK_LCBR` ({) - Shift for } + - `DK_QUOT` (') - Shift for " + - `DK_LABK` (<) - Shift for > + - `DK_DLR` ($) - Shift for € + - `DK_PIPE` (|) + - `DK_GRV` (`) - Shift for ¨ + - `DK_CIRC` (^) + +--- + +## Special Features + +### Home Row Mods +All layers maintain home row mods for ergonomic modifier access: +- **Left**: GUI (pinky) → ALT (ring) → SHIFT (middle) → CTRL (index) +- **Right**: CTRL (index) → SHIFT (middle) → ALT (ring) → GUI (pinky) + +### Tap/Hold Keys +- **Bottom row keys**: Tap for letter, hold for modifier +- **Thumb keys**: Tap for key, hold for layer +- **Symbol layer bottom row**: Tap for casemode, hold for modifier + +### Casemodes (Layer 3, Right Bottom Row) + +#### C_CAPSWORD +**Location**: Right bottom row, 2nd key (with Ctrl hold) + +**Usage:** +1. Hold right thumb (activate Symbol layer) +2. Tap the CAPSWORD key +3. Release thumb +4. Start typing: `hello world` → `HELLO WORLD` +5. Press space twice to exit + +**What it does:** +- Automatically capitalizes all letters +- Continues until you press space twice or punctuation +- Perfect for typing `CONSTANT_NAMES` or `ALL_CAPS_TEXT` + +#### C_UNDERSCORECASE (Snake Case) +**Location**: Right bottom row, 3rd key (with Shift hold) + +**Usage:** +1. Hold right thumb (activate Symbol layer) +2. Tap the ___CASE key +3. Release thumb +4. Type: `hello world` → `hello_world` +5. Press space to insert underscores +6. Press space twice to exit + +**What it does:** +- Converts spaces to underscores +- Perfect for `variable_names`, `function_names`, `file_names` + +#### C_HYPHENCASE (Kebab Case) +**Location**: Right bottom row, 4th key (with Alt hold) + +**Usage:** +1. Hold right thumb (activate Symbol layer) +2. Tap the -CASE key +3. Release thumb +4. Type: `hello world` → `hello-world` +5. Press space to insert hyphens +6. Press space twice to exit + +**What it does:** +- Converts spaces to hyphens +- Perfect for `css-class-names`, `url-slugs`, `command-line-options` + +### Auto Shift +- Enabled with 170ms timeout +- Hold any letter key slightly longer to get the shifted version +- No need to use Shift for capital letters when typing slowly + +### Combos +- 17 combos defined (see combos.c for specific combinations) +- Combo reference layer: NORTO + +### OLED Display Features +- **Master side**: Shows logo, current layer, modifier status, WPM +- **Secondary side**: Shows logo with WPM counter +- **Auto sleep**: Screen turns off after 15 seconds of inactivity +- **Auto wake**: Screen turns on when you start typing + +--- + +## Layer Toggle Matrix + +| From Layer | To Layer | Method | +|------------|----------|--------| +| Any | NORTO | Hold Nav or Sym layer, tap NORTO toggle | +| Any | QWERTY | Hold Nav or Sym layer, tap QWERTY toggle | +| NORTO/QWERTY | Navigation | Hold left thumb | +| NORTO/QWERTY | Symbol/FKeys | Hold right thumb | + +--- + +## Firmware Configuration + +### Enabled Features +- ✅ OLED Display (128x32) +- ✅ Split keyboard support +- ✅ Combos (17 defined) +- ✅ Auto Shift (170ms) +- ✅ Casemodes +- ✅ WPM tracking (split) +- ✅ Modifier state tracking (split) +- ✅ Layer state tracking (split) +- ✅ Deferred execution +- ✅ Permissive hold +- ✅ Retro shift +- ✅ Retro tapping + +### Timing Settings +- **Tapping term**: 140ms +- **Auto shift timeout**: 170ms +- **OLED timeout**: 15 seconds + +### Custom Features +- Custom OLED font (glcdfont.c) +- Master/slave split configuration +- Super Tab macro (FP_SUPER_TAB) + +--- + +## Tips for New Users + +1. **Start with NORTO layer**: It's optimized for Danish typing +2. **Learn home row mods**: Keep fingers on home row, use pinky/ring for GUI/ALT +3. **Use casemodes**: They're incredibly useful for coding and writing +4. **Practice layer switching**: Get comfortable with thumb-activated layers +5. **Double-tap space**: Quick way to exit any casemode +6. **OLED feedback**: Watch the OLED to see which modifiers/layers are active + +--- + +## Quick Reference Card + +``` +┌───────────────────────────────────────────────────┐ +│ Most Used Key Combinations │ +├───────────────────────────────────────────────────┤ +│ Left Thumb Hold → Navigation + Numpad │ +│ Right Thumb Hold → Symbols + Function Keys │ +│ Both Thumbs → Access layer toggles │ +│ │ +│ Casemodes (Right thumb + right bottom row): │ +│ Thumb + 2nd key → CAPS WORD │ +│ Thumb + 3rd key → snake_case │ +│ Thumb + 4th key → kebab-case │ +│ │ +│ Exit any casemode: Press SPACE twice │ +└───────────────────────────────────────────────────┘ +``` + +--- + +**Generated**: October 6, 2025 +**Keyboard**: Fingerpunch Sweeeeep +**Layout**: Custom NORTO (Danish optimized) +**Keymap**: smathev diff --git a/keyboards/fingerpunch/sweeeeep/smathev/glcdfont.c b/keyboards/fingerpunch/sweeeeep/smathev/glcdfont.c new file mode 100644 index 00000000..6fbc1af8 --- /dev/null +++ b/keyboards/fingerpunch/sweeeeep/smathev/glcdfont.c @@ -0,0 +1,232 @@ +#include "progmem.h" + +// Corne 8x6 font with QMK Firmware Logo +// Online editor: https://helixfonteditor.netlify.com/ +// See also: https://github.com/soundmonster/glcdfont_converter + +const unsigned char font[] PROGMEM = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x00, + 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x00, + 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x00, + 0x18, 0x3C, 0x7E, 0x3C, 0x18, 0x00, + 0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x00, + 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00, + 0x00, 0x18, 0x3C, 0x18, 0x00, 0x00, + 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00, + 0x00, 0x18, 0x24, 0x18, 0x00, 0x00, + 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x00, + 0x30, 0x48, 0x3A, 0x06, 0x0E, 0x00, + 0x26, 0x29, 0x79, 0x29, 0x26, 0x00, + 0x40, 0x7F, 0x05, 0x05, 0x07, 0x00, + 0x40, 0x7F, 0x05, 0x25, 0x3F, 0x00, + 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0x00, + 0x7F, 0x3E, 0x1C, 0x1C, 0x08, 0x00, + 0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x00, + 0x14, 0x22, 0x7F, 0x22, 0x14, 0x00, + 0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0x00, + 0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00, + 0x00, 0x66, 0x89, 0x95, 0x6A, 0x00, + 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, + 0x94, 0xA2, 0xFF, 0xA2, 0x94, 0x00, + 0x08, 0x04, 0x7E, 0x04, 0x08, 0x00, + 0x10, 0x20, 0x7E, 0x20, 0x10, 0x00, + 0x08, 0x08, 0x2A, 0x1C, 0x08, 0x00, + 0x08, 0x1C, 0x2A, 0x08, 0x08, 0x00, + 0x1E, 0x10, 0x10, 0x10, 0x10, 0x00, + 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0x00, + 0x30, 0x38, 0x3E, 0x38, 0x30, 0x00, + 0x06, 0x0E, 0x3E, 0x0E, 0x06, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, + 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00, + 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00, + 0x23, 0x13, 0x08, 0x64, 0x62, 0x00, + 0x36, 0x49, 0x56, 0x20, 0x50, 0x00, + 0x00, 0x08, 0x07, 0x03, 0x00, 0x00, + 0x00, 0x1C, 0x22, 0x41, 0x00, 0x00, + 0x00, 0x41, 0x22, 0x1C, 0x00, 0x00, + 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x00, + 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, + 0x00, 0x80, 0x70, 0x30, 0x00, 0x00, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, + 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, + 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, + 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, + 0x00, 0x42, 0x7F, 0x40, 0x00, 0x00, + 0x72, 0x49, 0x49, 0x49, 0x46, 0x00, + 0x21, 0x41, 0x49, 0x4D, 0x33, 0x00, + 0x18, 0x14, 0x12, 0x7F, 0x10, 0x00, + 0x27, 0x45, 0x45, 0x45, 0x39, 0x00, + 0x3C, 0x4A, 0x49, 0x49, 0x31, 0x00, + 0x41, 0x21, 0x11, 0x09, 0x07, 0x00, + 0x36, 0x49, 0x49, 0x49, 0x36, 0x00, + 0x46, 0x49, 0x49, 0x29, 0x1E, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x34, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x14, 0x22, 0x41, 0x00, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, + 0x00, 0x41, 0x22, 0x14, 0x08, 0x00, + 0x02, 0x01, 0x59, 0x09, 0x06, 0x00, + 0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00, + 0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00, + 0x7F, 0x49, 0x49, 0x49, 0x36, 0x00, + 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00, + 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00, + 0x7F, 0x49, 0x49, 0x49, 0x41, 0x00, + 0x7F, 0x09, 0x09, 0x09, 0x01, 0x00, + 0x3E, 0x41, 0x41, 0x51, 0x73, 0x00, + 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, + 0x00, 0x41, 0x7F, 0x41, 0x00, 0x00, + 0x20, 0x40, 0x41, 0x3F, 0x01, 0x00, + 0x7F, 0x08, 0x14, 0x22, 0x41, 0x00, + 0x7F, 0x40, 0x40, 0x40, 0x40, 0x00, + 0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x00, + 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00, + 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00, + 0x7F, 0x09, 0x09, 0x09, 0x06, 0x00, + 0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00, + 0x7F, 0x09, 0x19, 0x29, 0x46, 0x00, + 0x26, 0x49, 0x49, 0x49, 0x32, 0x00, + 0x03, 0x01, 0x7F, 0x01, 0x03, 0x00, + 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00, + 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00, + 0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00, + 0x63, 0x14, 0x08, 0x14, 0x63, 0x00, + 0x03, 0x04, 0x78, 0x04, 0x03, 0x00, + 0x61, 0x59, 0x49, 0x4D, 0x43, 0x00, + 0x00, 0x7F, 0x41, 0x41, 0x41, 0x00, + 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, + 0x00, 0x41, 0x41, 0x41, 0x7F, 0x00, + 0x04, 0x02, 0x01, 0x02, 0x04, 0x00, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, + 0x00, 0x03, 0x07, 0x08, 0x00, 0x00, + 0x20, 0x54, 0x54, 0x78, 0x40, 0x00, + 0x7F, 0x28, 0x44, 0x44, 0x38, 0x00, + 0x38, 0x44, 0x44, 0x44, 0x28, 0x00, + 0x38, 0x44, 0x44, 0x28, 0x7F, 0x00, + 0x38, 0x54, 0x54, 0x54, 0x18, 0x00, + 0x00, 0x08, 0x7E, 0x09, 0x02, 0x00, + 0x18, 0x24, 0x24, 0x1C, 0x78, 0x00, + 0x7F, 0x08, 0x04, 0x04, 0x78, 0x00, + 0x00, 0x44, 0x7D, 0x40, 0x00, 0x00, + 0x20, 0x40, 0x40, 0x3D, 0x00, 0x00, + 0x7F, 0x10, 0x28, 0x44, 0x00, 0x00, + 0x00, 0x41, 0x7F, 0x40, 0x00, 0x00, + 0x7C, 0x04, 0x78, 0x04, 0x78, 0x00, + 0x7C, 0x08, 0x04, 0x04, 0x78, 0x00, + 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, + 0x7C, 0x18, 0x24, 0x24, 0x18, 0x00, + 0x18, 0x24, 0x24, 0x18, 0x7C, 0x00, + 0x7C, 0x08, 0x04, 0x04, 0x08, 0x00, + 0x48, 0x54, 0x54, 0x54, 0x24, 0x00, + 0x04, 0x04, 0x3F, 0x44, 0x24, 0x00, + 0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00, + 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00, + 0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00, + 0x44, 0x28, 0x10, 0x28, 0x44, 0x00, + 0x4C, 0x90, 0x90, 0x90, 0x7C, 0x00, + 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00, + 0x00, 0x08, 0x36, 0x41, 0x00, 0x00, + 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, + 0x00, 0x41, 0x36, 0x08, 0x00, 0x00, + 0x02, 0x01, 0x02, 0x04, 0x02, 0x00, + 0x3C, 0x26, 0x23, 0x26, 0x3C, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xE0, 0x78, + 0x7C, 0x7E, 0x7E, 0x7F, 0x7F, 0x7F, + 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, + 0x7F, 0x7F, 0x7E, 0x7E, 0x7C, 0x78, + 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xF8, 0x04, 0x22, 0x52, 0xE2, + 0x42, 0x42, 0x42, 0xE2, 0x52, 0x22, + 0x22, 0x22, 0x42, 0x82, 0x02, 0x02, + 0x22, 0x22, 0x02, 0x04, 0xF8, 0x00, + 0x00, 0xF8, 0x04, 0x02, 0x02, 0x82, + 0x42, 0x22, 0x42, 0x82, 0x02, 0x02, + 0x02, 0x82, 0x42, 0x22, 0x12, 0x22, + 0x42, 0x82, 0x02, 0x04, 0xF8, 0x00, + 0x00, 0xF8, 0xFC, 0xDE, 0xAE, 0x1E, + 0xBE, 0xBE, 0xBE, 0x1E, 0xAE, 0xDE, + 0xDE, 0xDE, 0xBE, 0x7E, 0xFE, 0xFE, + 0xDE, 0xDE, 0xFE, 0xFC, 0xF8, 0x00, + 0x00, 0xF8, 0xFC, 0xFE, 0xFE, 0x7E, + 0xBE, 0xDE, 0xBE, 0x7E, 0xFE, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, + 0x10, 0x10, 0x08, 0x08, 0x10, 0x10, + 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, + 0x80, 0x80, 0xC0, 0xC0, 0xE0, 0xE0, + 0xF0, 0xF0, 0xF8, 0xF8, 0xF0, 0xF0, + 0xE0, 0xE0, 0xC0, 0xC0, 0x80, 0x80, + 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, + 0x10, 0x10, 0x08, 0x08, 0x10, 0x10, + 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, + 0x80, 0x80, 0x40, 0xC0, 0x60, 0xA0, + 0x50, 0xB0, 0x58, 0xA8, 0x50, 0xB0, + 0x60, 0xA0, 0x40, 0xC0, 0x80, 0x80, + 0x00, 0x00, 0xC0, 0x67, 0xBF, 0x67, + 0xCC, 0xF8, 0xF8, 0xFC, 0xFC, 0xFC, + 0x7E, 0x7E, 0x3F, 0x7E, 0x7E, 0xFC, + 0xFC, 0xFC, 0xF8, 0xF8, 0xCC, 0x67, + 0xBF, 0x67, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x1F, 0x20, 0x44, 0x4A, 0x47, + 0x42, 0x42, 0x42, 0x47, 0x4A, 0x44, + 0x40, 0x40, 0x40, 0x40, 0x41, 0x42, + 0x44, 0x44, 0x40, 0x20, 0x1F, 0x00, + 0x00, 0x1F, 0x20, 0x40, 0x41, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x41, 0x40, + 0x41, 0x41, 0x4F, 0x48, 0x48, 0x48, + 0x4F, 0x41, 0x41, 0x20, 0x1F, 0x00, + 0x00, 0x1F, 0x3F, 0x7B, 0x75, 0x78, + 0x7D, 0x7D, 0x7D, 0x78, 0x75, 0x7B, + 0x7F, 0x7F, 0x7F, 0x7F, 0x7E, 0x7D, + 0x7B, 0x7B, 0x7F, 0x3F, 0x1F, 0x00, + 0x00, 0x1F, 0x3F, 0x7F, 0x7E, 0x7F, + 0x7F, 0x7F, 0x7F, 0x7F, 0x7E, 0x7F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x88, 0x88, 0x5D, 0x5D, 0x3E, 0x3E, + 0x7C, 0x7C, 0xF8, 0xF8, 0x7C, 0x7C, + 0x3E, 0x3E, 0x5D, 0x5D, 0x88, 0x88, + 0x88, 0x88, 0x55, 0x55, 0x23, 0x23, + 0x47, 0x47, 0x8F, 0x8F, 0x47, 0x47, + 0x23, 0x23, 0x55, 0x55, 0x88, 0x88, + 0x88, 0x88, 0xD5, 0xD5, 0xE2, 0xE2, + 0xC4, 0xC4, 0x88, 0x88, 0xC4, 0xC4, + 0xE2, 0xE2, 0xD5, 0xD5, 0x88, 0x88, + 0x88, 0x88, 0x5D, 0xD5, 0x6B, 0xB6, + 0x6D, 0xD6, 0xAD, 0xDA, 0x6D, 0xD6, + 0x6B, 0xB6, 0x5D, 0xD5, 0x88, 0x88, + 0x00, 0x00, 0x03, 0x0F, 0x1E, 0x3D, + 0x7A, 0x9F, 0xAB, 0x89, 0x9D, 0x7C, + 0x5E, 0x8E, 0xF7, 0x8E, 0x5E, 0x7C, + 0x9D, 0x89, 0xAB, 0x9F, 0x7A, 0x3D, + 0x1E, 0x0F, 0x03, 0x00, 0x00, 0x00, + 0x04, 0xF8, 0x00, 0x00, 0xF8, 0x04, + 0x20, 0x1F, 0x00, 0x00, 0x1F, 0x20, + 0xFC, 0xF8, 0x00, 0x00, 0xF8, 0x04, + 0x3F, 0x1F, 0x00, 0x00, 0x1F, 0x20, + 0x04, 0xF8, 0x00, 0x00, 0xF8, 0xFC, + 0x20, 0x1F, 0x00, 0x00, 0x1F, 0x3F, + 0xFC, 0xF8, 0x00, 0x00, 0xF8, 0xFC, + 0x3F, 0x1F, 0x00, 0x00, 0x1F, 0x3F, + 0xFE, 0x7E, 0xBE, 0xDE, 0xEE, 0xDE, + 0xBE, 0x7E, 0xFE, 0xFC, 0xF8, 0x00, + 0x7E, 0x7E, 0x70, 0x77, 0x77, 0x77, + 0x70, 0x7E, 0x7E, 0x3F, 0x1F, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, + 0x04, 0x04, 0x08, 0x08, 0x04, 0x04, + 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, + 0x04, 0x04, 0x08, 0x08, 0x04, 0x04, + 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x03, 0x03, + 0x07, 0x07, 0x0F, 0x0F, 0x07, 0x07, + 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x03, 0x02, + 0x05, 0x06, 0x0D, 0x0A, 0x05, 0x06, + 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, +}; diff --git a/keyboards/fingerpunch/sweeeeep/smathev/keymap.c b/keyboards/fingerpunch/sweeeeep/smathev/keymap.c new file mode 100644 index 00000000..447706c1 --- /dev/null +++ b/keyboards/fingerpunch/sweeeeep/smathev/keymap.c @@ -0,0 +1,313 @@ +/* Copyright 2021 Sadek Baroudi + * + * 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, see . + */ +#include "smathev.h" +#include +#include "wrappers.h" +#include "casemodes.h" +#include QMK_KEYBOARD_H + +extern keymap_config_t keymap_config; +char wpm_str[6]; + +// clang-format off +#define LAYOUT_sweeeeep_base( \ + K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, \ + K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, \ + K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, \ + K33, K34, K35, K36, K37, K38 \ + ) \ + LAYOUT_wrapper( \ + K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, \ + K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, \ + K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, \ + LT(_NORTNAVIGATION, K33), K34, K35, K36, K37, LT(_SYMFKEYS, K38) \ + ) + +/* Re-pass though to allow templates to be used */ +#define LAYOUT_sweeeeep_base_wrapper(...) LAYOUT_sweeeeep_base(__VA_ARGS__) + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [_NORTO] = LAYOUT_sweeeeep_base_wrapper( + __________________NORTO_L1____________________, __________________NORTO_R1____________________, + __________________NORTO_L2____________________, __________________NORTO_R2____________________, + __________________NORTO_L3____________________, __________________NORTO_R3____________________, + __NORTO_THUMBS_6__ + ), + + [_QWERTY] = LAYOUT_sweeeeep_base_wrapper( + __________________QWERTY_L1____________________, __________________QWERTY_R1____________________, + __________________QWERTY_L2____________________, __________________QWERTY_R2____________________, + __________________QWERTY_L3____________________, __________________QWERTY_R3____________________, + __QWERTY_THUMBS_6__ + ), + + [_NORTNAVIGATION] = LAYOUT_sweeeeep_base_wrapper( + ____________NORTNAVIGATION_1_______________, _________________NUMPAD_1__________________, + ____________NORTNAVIGATION_2_______________, _________________NUMPAD_2__________________, + ____________NORTNAVIGATION_3_______________, _________________NUMPAD_3__________________, + _______, TG(_NORTO), TG(_QWERTY), TG(_QWERTY), TG(_NORTO), _______ + ), + + [_SYMFKEYS] = LAYOUT_sweeeeep_base_wrapper( + ___________________FKEY______L1________________, ________________NORTSYMBOLS_R1_________________, + ___________________FKEY______L2________________, ________________NORTSYMBOLS_R2_________________, + ___________________FKEY______L3________________, ________________NORTSYMBOLS_R3_________________, + _______, TG(_NORTO), TG(_QWERTY), TG(_QWERTY), TG(_NORTO), _______ + ) +}; + + +#ifdef OLED_ENABLE +// static uint32_t oled_timer = 0; + bool process_record_oled(uint16_t keycode, keyrecord_t *record); + oled_rotation_t oled_init_user(oled_rotation_t rotation); + void render_layer_symbol(void); + void render_layer_name(void); + void render_mod_state(uint8_t modifiers); + void render_status(void); + bool oled_task_user(void); +#endif +#ifdef OLED_ENABLE +oled_rotation_t oled_init_user(oled_rotation_t rotation) { return OLED_ROTATION_270; } + +void render_space(void) { + oled_write_P(PSTR(" "), false); +} + +void render_mod_status_gui_alt(uint8_t modifiers) { + static const char PROGMEM gui_off_1[] = {0x85, 0x86, 0}; + static const char PROGMEM gui_off_2[] = {0xa5, 0xa6, 0}; + static const char PROGMEM gui_on_1[] = {0x8d, 0x8e, 0}; + static const char PROGMEM gui_on_2[] = {0xad, 0xae, 0}; + + static const char PROGMEM alt_off_1[] = {0x87, 0x88, 0}; + static const char PROGMEM alt_off_2[] = {0xa7, 0xa8, 0}; + static const char PROGMEM alt_on_1[] = {0x8f, 0x90, 0}; + static const char PROGMEM alt_on_2[] = {0xaf, 0xb0, 0}; + + // fillers between the modifier icons bleed into the icon frames + static const char PROGMEM off_off_1[] = {0xc5, 0}; + static const char PROGMEM off_off_2[] = {0xc6, 0}; + static const char PROGMEM on_off_1[] = {0xc7, 0}; + static const char PROGMEM on_off_2[] = {0xc8, 0}; + static const char PROGMEM off_on_1[] = {0xc9, 0}; + static const char PROGMEM off_on_2[] = {0xca, 0}; + static const char PROGMEM on_on_1[] = {0xcb, 0}; + static const char PROGMEM on_on_2[] = {0xcc, 0}; + + if(modifiers & MOD_MASK_GUI) { + oled_write_P(gui_on_1, false); + } else { + oled_write_P(gui_off_1, false); + } + + if ((modifiers & MOD_MASK_GUI) && (modifiers & MOD_MASK_ALT)) { + oled_write_P(on_on_1, false); + } else if(modifiers & MOD_MASK_GUI) { + oled_write_P(on_off_1, false); + } else if(modifiers & MOD_MASK_ALT) { + oled_write_P(off_on_1, false); + } else { + oled_write_P(off_off_1, false); + } + + if(modifiers & MOD_MASK_ALT) { + oled_write_P(alt_on_1, false); + } else { + oled_write_P(alt_off_1, false); + } + + if(modifiers & MOD_MASK_GUI) { + oled_write_P(gui_on_2, false); + } else { + oled_write_P(gui_off_2, false); + } + + if ((modifiers & MOD_MASK_GUI) && (modifiers & MOD_MASK_ALT)) { + oled_write_P(on_on_2, false); + } else if(modifiers & MOD_MASK_GUI) { + oled_write_P(on_off_2, false); + } else if(modifiers & MOD_MASK_ALT) { + oled_write_P(off_on_2, false); + } else { + oled_write_P(off_off_2, false); + } + + if(modifiers & MOD_MASK_ALT) { + oled_write_P(alt_on_2, false); + } else { + oled_write_P(alt_off_2, false); + } +} + + +void render_mod_status_ctrl_shift(uint8_t modifiers) { + static const char PROGMEM ctrl_off_1[] = {0x89, 0x8a, 0}; + static const char PROGMEM ctrl_off_2[] = {0xa9, 0xaa, 0}; + static const char PROGMEM ctrl_on_1[] = {0x91, 0x92, 0}; + static const char PROGMEM ctrl_on_2[] = {0xb1, 0xb2, 0}; + + static const char PROGMEM shift_off_1[] = {0x8b, 0x8c, 0}; + static const char PROGMEM shift_off_2[] = {0xab, 0xac, 0}; + static const char PROGMEM shift_on_1[] = {0xcd, 0xce, 0}; + static const char PROGMEM shift_on_2[] = {0xcf, 0xd0, 0}; + + // fillers between the modifier icons bleed into the icon frames + static const char PROGMEM off_off_1[] = {0xc5, 0}; + static const char PROGMEM off_off_2[] = {0xc6, 0}; + static const char PROGMEM on_off_1[] = {0xc7, 0}; + static const char PROGMEM on_off_2[] = {0xc8, 0}; + static const char PROGMEM off_on_1[] = {0xc9, 0}; + static const char PROGMEM off_on_2[] = {0xca, 0}; + static const char PROGMEM on_on_1[] = {0xcb, 0}; + static const char PROGMEM on_on_2[] = {0xcc, 0}; + + if(modifiers & MOD_MASK_CTRL) { + oled_write_P(ctrl_on_1, false); + } else { + oled_write_P(ctrl_off_1, false); + } + + if ((modifiers & MOD_MASK_CTRL) && (modifiers & MOD_MASK_SHIFT)) { + oled_write_P(on_on_1, false); + } else if(modifiers & MOD_MASK_CTRL) { + oled_write_P(on_off_1, false); + } else if(modifiers & MOD_MASK_SHIFT) { + oled_write_P(off_on_1, false); + } else { + oled_write_P(off_off_1, false); + } + + if(modifiers & MOD_MASK_SHIFT) { + oled_write_P(shift_on_1, false); + } else { + oled_write_P(shift_off_1, false); + } + + if(modifiers & MOD_MASK_CTRL) { + oled_write_P(ctrl_on_2, false); + } else { + oled_write_P(ctrl_off_2, false); + } + + if ((modifiers & MOD_MASK_CTRL) && (modifiers & MOD_MASK_SHIFT)) { + oled_write_P(on_on_2, false); + } else if(modifiers & MOD_MASK_CTRL) { + oled_write_P(on_off_2, false); + } else if(modifiers & MOD_MASK_SHIFT) { + oled_write_P(off_on_2, false); + } else { + oled_write_P(off_off_2, false); + } + + if(modifiers & MOD_MASK_SHIFT) { + oled_write_P(shift_on_2, false); + } else { + oled_write_P(shift_off_2, false); + } +} + +void render_logo(void) { + static const char PROGMEM corne_logo[] = { + 0x80, 0x81, 0x82, 0x83, 0x84, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0}; + oled_write_P(corne_logo, false); + oled_write_P(PSTR("Gio*K"), false); +} + +void render_logo2(void) { + static const char PROGMEM corne_logo[] = { + 0x80, 0x81, 0x82, 0x83, 0x84, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0}; + oled_write_P(corne_logo, false); + sprintf(wpm_str,">>%03d", get_current_wpm()); + oled_write(wpm_str,false); +} + + +void render_layer_state(void) { + static const char PROGMEM default_layer[] = { + 0x20, 0x94, 0x95, 0x96, 0x20, + 0x20, 0xb4, 0xb5, 0xb6, 0x20, + 0x20, 0xd4, 0xd5, 0xd6, 0x20, 0}; + static const char PROGMEM raise_layer[] = { + 0x20, 0x97, 0x98, 0x99, 0x20, + 0x20, 0xb7, 0xb8, 0xb9, 0x20, + 0x20, 0xd7, 0xd8, 0xd9, 0x20, 0}; + static const char PROGMEM lower_layer[] = { + 0x20, 0x9a, 0x9b, 0x9c, 0x20, + 0x20, 0xba, 0xbb, 0xbc, 0x20, + 0x20, 0xda, 0xdb, 0xdc, 0x20, 0}; + if(layer_state_is(_SYMBOLS)) { + oled_write_P(lower_layer, false); + } else if(layer_state_is(_NAVIGATION)) { + oled_write_P(raise_layer, false); + } else { + oled_write_P(default_layer, false); + } +} + +void render_status_main(void) { + render_logo(); + render_space(); + render_layer_state(); + render_space(); + render_mod_status_gui_alt(get_mods()|get_oneshot_mods()); + render_mod_status_ctrl_shift(get_mods()|get_oneshot_mods()); +} + +void render_status_secondary(void) { + render_logo2(); + render_space(); + render_layer_state(); + render_space(); + render_mod_status_gui_alt(get_mods()|get_oneshot_mods()); + render_mod_status_ctrl_shift(get_mods()|get_oneshot_mods()); +} + + static bool oled_active = true; + + bool process_record_user_keymap(uint16_t keycode, keyrecord_t *record) { + return true; + } + + bool oled_task_user(void) { + if (last_input_activity_elapsed() > 15000) { + if (oled_active) { // Only turn off if it's currently on + oled_off(); + oled_active = false; + } + return false; // Don't render while sleeping + } + + // If we get here, there's been recent activity + if (!oled_active) { + oled_on(); + oled_active = true; + } + + if (is_keyboard_master()) { + render_status_main(); + } else { + render_status_secondary(); + } + return false; + } + +#endif + diff --git a/users/smathev/autoshift.c b/users/smathev/autoshift.c new file mode 100644 index 00000000..0174b6c1 --- /dev/null +++ b/users/smathev/autoshift.c @@ -0,0 +1,84 @@ +bool get_custom_auto_shifted_key(uint16_t keycode, keyrecord_t *record) { + switch(keycode) { + case DK_MINS: + case DK_SLSH: + case DK_LPRN: + case DK_LBRC: + case DK_LCBR: + case DK_LABK: + case DK_QUOT: + return true; + default: + // Enable Auto-Shift for mod-tap keys (for Retro-Shift to work) + if (IS_RETRO(keycode)) { + return true; + } + return false; + } +} + +void autoshift_press_user(uint16_t keycode, bool shifted, keyrecord_t *record) { + switch(keycode) { + case DK_MINS: + register_code16((!shifted) ? DK_MINS : DK_UNDS); + break; + case DK_SLSH: + register_code16((!shifted) ? DK_SLSH : DK_BSLS); + break; + case DK_LPRN: + register_code16((!shifted) ? DK_LPRN : DK_RPRN); + break; + case DK_LBRC: + register_code16((!shifted) ? DK_LBRC : DK_RBRC); + break; + case DK_LCBR: + register_code16((!shifted) ? DK_LCBR : DK_RCBR); + break; + case DK_LABK: + register_code16((!shifted) ? DK_LABK : DK_RABK); + break; + case DK_QUOT: + register_code16((!shifted) ? DK_QUOT : DK_DQUO); + break; + case DK_DLR: + register_code16((!shifted) ? DK_DLR : DK_EURO); + break; + default: + if (shifted) { + add_weak_mods(MOD_BIT(KC_LSFT)); + } + // & 0xFF gets the Tap key for Tap Holds, required when using Retro Shift + register_code16((IS_RETRO(keycode)) ? keycode & 0xFF : keycode); + } +} + +void autoshift_release_user(uint16_t keycode, bool shifted, keyrecord_t *record) { + switch(keycode) { + case DK_MINS: + unregister_code16((!shifted) ? DK_MINS : DK_UNDS); + break; + case DK_SLSH: + unregister_code16((!shifted) ? DK_SLSH : DK_BSLS); + break; + case DK_LPRN: + unregister_code16((!shifted) ? DK_LPRN : DK_RPRN); + break; + case DK_LBRC: + unregister_code16((!shifted) ? DK_LBRC : DK_RBRC); + break; + case DK_LCBR: + unregister_code16((!shifted) ? DK_LCBR : DK_RCBR); + break; + case DK_LABK: + unregister_code16((!shifted) ? DK_LABK : DK_RABK); + break; + case DK_QUOT: + unregister_code16((!shifted) ? DK_QUOT : DK_DQUO); + break; + default: + // & 0xFF gets the Tap key for Tap Holds, required when using Retro Shift + // The IS_RETRO check isn't really necessary here, always using + // keycode & 0xFF would be fine. + unregister_code16((IS_RETRO(keycode)) ? keycode & 0xFF : keycode); + } +} \ No newline at end of file diff --git a/users/smathev/casemodes.c b/users/smathev/casemodes.c new file mode 100644 index 00000000..480a628c --- /dev/null +++ b/users/smathev/casemodes.c @@ -0,0 +1,266 @@ +/* Copyright 2021 Andrew Rae ajrae.nv@gmail.com @andrewjrae + * + * 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, see . + */ + +#include "casemodes.h" + +/* The caps word concept started with me @iaap on splitkb.com discord. + * However it has been implemented and extended by many splitkb.com users: + * - @theol0403 made many improvements to initial implementation + * - @precondition used caps lock rather than shifting + * - @dnaq his own implementation which also used caps lock + * - @sevanteri added underscores on spaces + * - @metheon extended on @sevanteri's work and added specific modes for + * snake_case and SCREAMING_SNAKE_CASE + * - @baffalop came up with the idea for xcase, which he implements in his own + * repo, however this is implemented by @iaap with support also for one-shot-shift. + * - @sevanteri + * - fixed xcase waiting mode to allow more modified keys and keys from other layers. + * - Added @baffalop's separator defaulting on first keypress, with a + * configurable default separator and overrideable function to determine + * if the default should be used. + */ + + +#ifndef DEFAULT_XCASE_SEPARATOR +#define DEFAULT_XCASE_SEPARATOR KC_UNDS +#endif + +#define IS_OSM(keycode) (keycode >= QK_ONE_SHOT_MOD && keycode <= QK_ONE_SHOT_MOD_MAX) + +// bool to keep track of the caps word state +static bool caps_word_on = false; + +// enum to keep track of the xcase state +static enum xcase_state xcase_state = XCASE_OFF; +// the keycode of the xcase delimiter +static uint16_t xcase_delimiter; +// the number of keys to the last delimiter +static int8_t distance_to_last_delim = -1; + +// Check whether caps word is on +bool caps_word_enabled(void) { + return caps_word_on; +} + +// Enable caps word +void enable_caps_word(void) { + caps_word_on = true; +#ifndef CAPSWORD_USE_SHIFT + if (!host_keyboard_led_state().caps_lock) { + tap_code(KC_CAPS); + } +#endif +} + +// Disable caps word +void disable_caps_word(void) { + caps_word_on = false; +#ifndef CAPSWORD_USE_SHIFT + if (host_keyboard_led_state().caps_lock) { + tap_code(KC_CAPS); + } +#else + unregister_mods(MOD_LSFT); +#endif +} + +// Toggle caps word +void toggle_caps_word(void) { + if (caps_word_on) { + disable_caps_word(); + } + else { + enable_caps_word(); + } +} + +// Get xcase state +enum xcase_state get_xcase_state(void) { + return xcase_state; +} + +// Enable xcase and pickup the next keystroke as the delimiter +void enable_xcase(void) { + xcase_state = XCASE_WAIT; +} + +// Enable xcase with the specified delimiter +void enable_xcase_with(uint16_t delimiter) { + xcase_state = XCASE_ON; + xcase_delimiter = delimiter; + distance_to_last_delim = -1; +} + +// Disable xcase +void disable_xcase(void) { + xcase_state = XCASE_OFF; +} + +// Place the current xcase delimiter +static void place_delimiter(void) { + if (IS_OSM(xcase_delimiter)) { + // apparently set_oneshot_mods() is dumb and doesn't deal with handedness for you + uint8_t mods = xcase_delimiter & 0x10 ? (xcase_delimiter & 0x0F) << 4 : xcase_delimiter & 0xFF; + set_oneshot_mods(mods); + } else { + tap_code16(xcase_delimiter); + } +} + +// Removes a delimiter, used for double tap space exit +static void remove_delimiter(void) { + if (IS_OSM(xcase_delimiter)) { + clear_oneshot_mods(); + } else { + tap_code(KC_BSPC); + } +} + +// overrideable function to determine whether the case mode should stop +__attribute__ ((weak)) +bool terminate_case_modes(uint16_t keycode, const keyrecord_t *record) { + switch (keycode) { + // Keycodes to ignore (don't disable caps word) + case KC_A ... KC_Z: + case KC_1 ... KC_0: + case KC_MINS: + case KC_UNDS: + case KC_BSPC: + case DK_ARNG: + case DK_OSTR: + case DK_AE: + // If mod chording disable the mods + if (record->event.pressed && (get_mods() != 0)) { + return true; + } + break; + default: + if (record->event.pressed) { + return true; + } + break; + } + return false; +} + +/* overrideable function to determine whether to use the default separator on + * first keypress when waiting for the separator. */ +__attribute__ ((weak)) +bool use_default_xcase_separator(uint16_t keycode, const keyrecord_t *record) { + // for example: + /* switch (keycode) { */ + /* case KC_A ... KC_Z: */ + /* case KC_1 ... KC_0: */ + /* return true; */ + /* } */ + return false; +} + +bool process_case_modes(uint16_t keycode, const keyrecord_t *record) { + if (caps_word_on || xcase_state) { + if ((QK_MOD_TAP <= keycode && keycode <= QK_MOD_TAP_MAX) + || (QK_LAYER_TAP <= keycode && keycode <= QK_LAYER_TAP_MAX)) { + // Earlier return if this has not been considered tapped yet + if (record->tap.count == 0) + return true; + keycode = keycode & 0xFF; + } + + if (keycode >= QK_LAYER_TAP && keycode <= QK_ONE_SHOT_LAYER_MAX) { + // let special keys and normal modifiers go through + return true; + } + + if (xcase_state == XCASE_WAIT) { + // grab the next input to be the delimiter + if (use_default_xcase_separator(keycode, record)) { + enable_xcase_with(DEFAULT_XCASE_SEPARATOR); + } + else if (record->event.pressed) { + // factor in mods + if (get_mods() & MOD_MASK_SHIFT) { + keycode = LSFT(keycode); + } + else if (get_mods() & MOD_BIT(KC_RALT)) { + keycode = RALT(keycode); + } + enable_xcase_with(keycode); + return false; + } + else { + if (IS_OSM(keycode)) { + // this catches the OSM release if no other key was pressed + set_oneshot_mods(0); + enable_xcase_with(keycode); + return false; + } + // let other special keys go through + return true; + } + } + + if (record->event.pressed) { + // handle xcase mode + if (xcase_state == XCASE_ON) { + // place the delimiter if space is tapped + if (keycode == KC_SPACE) { + if (distance_to_last_delim != 0) { + place_delimiter(); + distance_to_last_delim = 0; + return false; + } + // remove the delimiter and disable modes + else { + remove_delimiter(); + disable_xcase(); + disable_caps_word(); + return true; + } + } + // decrement distance to delimiter on back space + else if (keycode == KC_BSPC) { + --distance_to_last_delim; + } + // don't increment distance to last delim if negative + else if (distance_to_last_delim >= 0) { + // puts back a one shot delimiter if you we're back to the delimiter pos + if (distance_to_last_delim == 0 && (IS_OSM(xcase_delimiter))) { + place_delimiter(); + } + ++distance_to_last_delim; + } + + } // end XCASE_ON + + // check if the case modes have been terminated + if (terminate_case_modes(keycode, record)) { + disable_caps_word(); + disable_xcase(); + } + +#ifdef CAPSWORD_USE_SHIFT + else if (keycode >= KC_A && keycode <= KC_Z){ + tap_code16(LSFT(keycode)); + return false; + } +#endif + + } // end if event.pressed + + return true; + } + return true; +} diff --git a/users/smathev/casemodes.h b/users/smathev/casemodes.h new file mode 100644 index 00000000..78d4efcf --- /dev/null +++ b/users/smathev/casemodes.h @@ -0,0 +1,51 @@ +/* Copyright 2021 Andrew Rae ajrae.nv@gmail.com @andrewjrae + * + * 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, see . + */ + +#pragma once + +#include QMK_KEYBOARD_H + +#ifndef CASEMODES_ENABLE +#define CASEMODES_ENABLE true +#endif + +// Check whether caps word is on +bool caps_word_enabled(void); +// Enable caps word +void enable_caps_word(void); +// Disable caps word +void disable_caps_word(void); +// Toggle caps word +void toggle_caps_word(void); + +// enum for the xcase states +enum xcase_state { + XCASE_OFF = 0, // xcase is off + XCASE_ON, // xcase is actively on + XCASE_WAIT, // xcase is waiting for the delimiter input +}; + +// Get xcase state +enum xcase_state get_xcase_state(void); +// Enable xcase and pickup the next keystroke as the delimiter +void enable_xcase(void); +// Enable xcase with the specified delimiter +void enable_xcase_with(uint16_t delimiter); +// Disable xcase +void disable_xcase(void); + +// Function to be put in process user +bool process_case_modes(uint16_t keycode, const keyrecord_t *record); diff --git a/users/smathev/combos.c b/users/smathev/combos.c new file mode 100644 index 00000000..85b70b0d --- /dev/null +++ b/users/smathev/combos.c @@ -0,0 +1,43 @@ +#include "combos.h" +#include "smathev.h" + +// COMBOS - https://github.com/qmk/qmk_firmware/blob/master/docs/feature_combo.md +const uint16_t PROGMEM undo_combo[] = {KC_Y, DK_ARNG, COMBO_END}; // L3_K1 + L3_K2 +const uint16_t PROGMEM ent_combo[] = {KC_S, KC_D, COMBO_END}; // R2_K4 + R2_K5 +const uint16_t PROGMEM tab_combo[] = {KC_O, KC_I, COMBO_END}; // L2_K1 + L2_K2 +const uint16_t PROGMEM cut_combo[] = {DK_ARNG, KC_V, COMBO_END}; //L3_K2 + L3_K3 +const uint16_t PROGMEM copy_combo[] = {KC_V, KC_C, COMBO_END}; // L3_K3 + L3_K4 +const uint16_t PROGMEM paste_combo[] = {KC_C, KC_COMM, COMBO_END}; // L3_K4 + L3_K5 +const uint16_t PROGMEM del_combo[] = {KC_L, KC_H, COMBO_END}; // R1_K3 + R1_K4 +const uint16_t PROGMEM bcksp_combo[] = {KC_H, KC_X, COMBO_END}; // R1_K4 + R1_K5 +const uint16_t PROGMEM cttb_combo[] = {KC_G, KC_J, COMBO_END}; // L1_K4 + L1_K5 +const uint16_t PROGMEM esc_combo[] = {DK_OSTR, DK_AE, COMBO_END}; // L1_K1 + L1_K2 +const uint16_t PROGMEM svfile_combo[] = {KC_Q, KC_Z, COMBO_END}; // R3_K3 + R3_K4 +const uint16_t PROGMEM srch_combo[] = {KC_F, KC_B, COMBO_END}; // R1_K1 + R1_K2 +const uint16_t PROGMEM ctcl_combo[] = {FP_SUPER_TAB, KC_PGDN, COMBO_END}; // L1_K4 + L1_K5 +const uint16_t PROGMEM cancel_combo[] = {KC_LEFT, KC_HOME, COMBO_END}; // l2_K1 + L2_K2 +const uint16_t PROGMEM ctrop_combo[] = {FP_SUPER_TAB, KC_PGDN, KC_UP, COMBO_END}; // L1_K3 + L1_K4 + L1_K5 +const uint16_t PROGMEM ffive_combo[] = {KC_U, KC_G, COMBO_END}; // L1_K3 + L1_K4 +const uint16_t PROGMEM reset_keyboard_combo[] = {KC_U, KC_G, KC_J, COMBO_END}; // L1_K3 + L1_K4 + L1_K5 +combo_t key_combos[COMBO_COUNT] = { + COMBO(undo_combo, LCTL(KC_Z)), + COMBO(copy_combo, LCTL(KC_C)), + COMBO(cut_combo, LCTL(KC_X)), + COMBO(paste_combo, LCTL(KC_V)), + COMBO(cttb_combo, LCTL(KC_T)), + COMBO(ctcl_combo, LCTL(KC_W)), + COMBO(cancel_combo, LCTL(KC_C)), + COMBO(ctrop_combo, RCS(KC_T)), + COMBO(svfile_combo, LCTL(KC_S)), + COMBO(srch_combo, LCTL(KC_F)), + COMBO(ffive_combo, KC_F5), + COMBO(ent_combo, KC_ENT), + COMBO(tab_combo, KC_TAB), + COMBO(bcksp_combo, KC_BSPC), + COMBO(del_combo, KC_DEL), + COMBO(esc_combo, KC_ESC), + COMBO(reset_keyboard_combo, QK_BOOT), +}; + + + diff --git a/users/smathev/combos.h b/users/smathev/combos.h new file mode 100644 index 00000000..512c76b8 --- /dev/null +++ b/users/smathev/combos.h @@ -0,0 +1,28 @@ +#pragma once + +#include QMK_KEYBOARD_H + +// Explicit extern declaration for introspection system with correct size +extern combo_t key_combos[COMBO_COUNT]; + +enum combo_events { + UNDO, + ENT, + TAB, + CUT, + COPY, + PASTE, + DEL, + BCKSP, + CTTB, + ESC, + SVFILE, + SRCH, + CTCL, + CANCEL, + CTROP, + FFIVE, + RESET_KEYBOARD +}; + +extern combo_t key_combos[]; diff --git a/users/smathev/config.h b/users/smathev/config.h new file mode 100644 index 00000000..2bf1d37e --- /dev/null +++ b/users/smathev/config.h @@ -0,0 +1,91 @@ +/* Copyright 2022 Sadek Baroudi + *#define TAPPING_TERM 140 +#define AUTO_SHIFT_TIMEOUT 170 // Slightly longer than TAPPING_TERM +#define RETRO_SHIFT +#define RETRO_TAPPINGThis 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, see . + */ +#define ENABLE_COMPILE_KEYCODE +#pragma once + +// #include "config_common.h" + +/* + * Keyboard Matrix Assignments + * + * Change this to how you wired your keyboard + * COLS: AVR pins used for columns, left to right + * ROWS: AVR pins used for rows, top to bottom + * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode) + * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode) + * NO_DIODE = switches are directly connected to AVR pins + * +*/ +#define DIRECT_PINS { \ + { B5, F7, F6, F5, F4 }, \ + { B4, D4, C6, D7, E6 }, \ + { B3, B2, B6, B7, D5 }, \ + { F0, F1, C7, NO_PIN, NO_PIN } \ +} + +#ifdef OLED_ENABLE +#define OLED_DISPLAY_128X32 +#endif + +// #define SSD1306OLED +#undef USE_I2C +//#undef SSD1306OLED + +/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ +#define DEBOUNCE 5 + +/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ +#define LOCKING_SUPPORT_ENABLE +/* Locking resynchronize hack */ +#define LOCKING_RESYNC_ENABLE + +/* Serial settings */ +#define USE_SERIAL +/* serial.c configuration for split keyboard */ +#define SOFT_SERIAL_PIN D2 + +#define TAPPING_TERM 140 +#define PERMISSIVE_HOLD // Activate mod immediately when another key pressed +#define AUTO_SHIFT_TIMEOUT 170 +#define RETRO_SHIFT +#define RETRO_TAPPING + +// #define MASTER_LEFT + +// Use EE_HANDS to allow USB connection on either side +// Flash each half with appropriate handedness bootloader +#define EE_HANDS + +/*#define SPLIT_USB_DETECT +#define SPLIT_LAYER_STATE_ENABLE */ +#define SPLIT_WPM_ENABLE +#define SPLIT_MODS_ENABLE +#define SPLIT_LAYER_STATE_ENABLE +// Smathev - define combos +#define COMBO_COUNT 17 + +#define CASEMODES_ENABLE + +#define COMBO_REF_DEFAULT _NORTO + +/* Backwards compatibility with existing out-of-tree keymaps */ +#define LAYOUT_sweeeeep LAYOUT_split_3x5_3 + + + +#define OLED_FONT_H "keyboards/fingerpunch/sweeeeep/keymaps/smathev/glcdfont.c" diff --git a/users/smathev/process_records.c b/users/smathev/process_records.c new file mode 100644 index 00000000..5f727866 --- /dev/null +++ b/users/smathev/process_records.c @@ -0,0 +1,60 @@ +#include "smathev.h" +#include "casemodes.h" +#include "autoshift.c" + + // for alternating between 45 degree angle routing and free angle routing with one key +bool kicad_free_angle_routing = false; + +__attribute__((weak)) bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { return true; } + +__attribute__((weak)) bool process_record_secrets(uint16_t keycode, keyrecord_t *record) { return true; } + +// Defines actions tor my global custom keycodes. Defined in smathev.h file +// Then runs the _keymap's record handler if not processed here +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + #ifdef CASEMODES_ENABLE + // Process case modes + if (!process_case_modes(keycode, record)) { + return false; + } + // If console is enabled, it will print the matrix position and status of each key pressed + #endif + + if (!(process_record_keymap(keycode, record) && process_record_secrets(keycode, record))) { + return false; + } + + switch (keycode) { + case C_CAPSWORD: + // NOTE: if you change this behavior, may want to update in keymap.c for COMBO behavior + #ifdef CASEMODES_ENABLE + if (record->event.pressed) { + enable_caps_word(); + } + #endif + break; + case C_HYPHENCASE: + #ifdef CASEMODES_ENABLE + if (record->event.pressed) { + enable_xcase_with(KC_MINS); + } + #endif + break; + case C_ANYCASE: + #ifdef CASEMODES_ENABLE + if (record->event.pressed) { + enable_xcase(); + } + #endif + break; + case C_UNDERSCORECASE: + #ifdef CASEMODES_ENABLE + if (record->event.pressed) { + enable_xcase_with(KC_UNDS); + } + #endif + break; + // COMMENT TO DISABLE MACROS + } + return true; +} diff --git a/users/smathev/process_records.h b/users/smathev/process_records.h new file mode 100644 index 00000000..01e2bdba --- /dev/null +++ b/users/smathev/process_records.h @@ -0,0 +1,31 @@ +#pragma once +#include "smathev.h" + +#if defined(KEYBOARD_fingerpunch_arachnophobe) \ + || defined(KEYBOARD_fingerpunch_sweeeeep) +# define PLACEHOLDER_SAFE_RANGE FP_SAFE_RANGE +#elif defined(KEYMAP_SAFE_RANGE) +# define PLACEHOLDER_SAFE_RANGE KEYMAP_SAFE_RANGE +#else +# define PLACEHOLDER_SAFE_RANGE SAFE_RANGE +#endif + +enum userspace_custom_keycodes { + C_CAPSWORD = PLACEHOLDER_SAFE_RANGE, // Toggles RGB Layer Indication mode + C_HYPHENCASE, + C_UNDERSCORECASE, + C_ANYCASE, + NEW_SAFE_RANGE +}; + +bool process_record_secrets(uint16_t keycode, keyrecord_t *record); +bool process_record_keymap(uint16_t keycode, keyrecord_t *record); + +#define KC_SEC1 KC_SECRET_1 +#define KC_SEC2 KC_SECRET_2 +#define KC_SEC3 KC_SECRET_3 +#define KC_SEC4 KC_SECRET_4 +#define KC_SEC5 KC_SECRET_5 + +#define KC_RESET RESET +#define KC_RST KC_RESET diff --git a/users/smathev/rules.mk b/users/smathev/rules.mk new file mode 100644 index 00000000..1e12f416 --- /dev/null +++ b/users/smathev/rules.mk @@ -0,0 +1,53 @@ +SRC += smathev.c \ + process_records.c \ + combos.c \ + casemodes.c + +# Build Options +# change yes to no to disable +# +BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration +EXTRAKEY_ENABLE = yes # Audio control and System control +CONSOLE_ENABLE = no # Console for debug +COMMAND_ENABLE = no # Commands for debug and configuration +# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE +SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend +# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work +NKRO_ENABLE = no # USB Nkey Rollover +BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality + +MIDI_ENABLE = no # MIDI support +UNICODE_ENABLE = no # Unicode +BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID +AUDIO_ENABLE = no # Audio output on port C6 +FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches +ENCODER_ENABLE = no +OLED_ENABLE = YES +OLED_DRIVER_ENABLE = yes +OLED_DRIVER = ssd1306 +# EXTRAFLAGS += -flto # macros disabled, if you need the extra space +MOUSEKEY_ENABLE = no + +SPLIT_KEYBOARD = yes # Use shared split_common code + +LAYOUTS = split_3x5_3 # Community layout support + +DEFERRED_EXEC_ENABLE = yes +# Smathev added from: https://getreuer.info/posts/keyboards/repeat-key/index.html +COMBO_ENABLE = yes + +# Smathev implemented from: https://docs.qmk.fm/#/feature_auto_shift +AUTO_SHIFT_ENABLE = yes + +# Implemented from https://github.com/samhocevar-forks/qmk-firmware/blob/master/docs/feature_tap_dance.md +# TAP_DANCE_ENABLE = yes + +# https://github.com/qmk/qmk_firmware/blob/master/docs/feature_leader_key.md +# LEADER_ENABLE = yes + +# CASEMODE_ENABLE +CASEMODE_ENABLE = yes + +#WPM ENABLE +WPM_ENABLE = yes + diff --git a/users/smathev/smathev.c b/users/smathev/smathev.c new file mode 100644 index 00000000..db463842 --- /dev/null +++ b/users/smathev/smathev.c @@ -0,0 +1,145 @@ +#include "smathev.h" + + +userspace_config_t userspace_config; + +__attribute__((weak)) void keyboard_pre_init_keymap(void) {} + +void keyboard_pre_init_user(void) { + // Set our LED pin as output + setPinOutput(24); + // Turn the LED off + // (Due to technical reasons, high is off and low is on) + writePinHigh(24); + userspace_config.raw = eeconfig_read_user(); + + // hack for a weird issue where userspace_config.val gets set to 0 on keyboard restart + userspace_config.val = 255; + + keyboard_pre_init_keymap(); +} +// Add reconfigurable functions here, for keymap customization +// This allows for a global, userspace functions, and continued +// customization of the keymap. Use _keymap instead of _user +// functions in the keymaps +__attribute__((weak)) void matrix_init_keymap(void) {} + +// Call user matrix init, set default RGB colors and then +// call the keymap's init function +void matrix_init_user(void) { + matrix_init_keymap(); +} + +__attribute__((weak)) void keyboard_post_init_keymap(void) {} + +void keyboard_post_init_user(void) { + #if defined(PIMORONI_TRACKBALL_ENABLE) && !defined(USERSPACE_RGBLIGHT_ENABLE) + pimoroni_trackball_set_rgbw(RGB_BLUE, 0x00); + #endif +#if defined(USERSPACE_RGBLIGHT_ENABLE) + keyboard_post_init_rgb_light(); +#endif + keyboard_post_init_keymap(); +} + +__attribute__((weak)) void shutdown_keymap(void) {} + +void rgb_matrix_update_pwm_buffers(void); + +bool shutdown_user(bool jump_to_bootloader) { + shutdown_keymap(); + return true; +} + +__attribute__((weak)) void suspend_power_down_keymap(void) {} + +void suspend_power_down_user(void) { suspend_power_down_keymap(); } + +__attribute__((weak)) void suspend_wakeup_init_keymap(void) {} + +void suspend_wakeup_init_user(void) { suspend_wakeup_init_keymap(); } + +__attribute__((weak)) void matrix_scan_keymap(void) {} + +__attribute__((weak)) layer_state_t layer_state_set_keymap(layer_state_t state) { return state; } + +// on layer change, no matter where the change was initiated +// Then runs keymap's layer change check +layer_state_t layer_state_set_user(layer_state_t state) { +#if defined(USERSPACE_RGBLIGHT_ENABLE) + state = layer_state_set_rgb_light(state); +#endif // USERSPACE_RGBLIGHT_ENABLE +#if defined(HAPTIC_ENABLE) + state = layer_state_set_haptic(state); +#endif // HAPTIC_ENABLE +#if defined(POINTING_DEVICE_ENABLE) +// all handled in keyboards/fingerpunch/fp_pointing.c now +// state = layer_state_set_pointing(state); +#endif // HAPTIC_ENABLE + return layer_state_set_keymap(state); +} + +__attribute__((weak)) layer_state_t default_layer_state_set_keymap(layer_state_t state) { return state; } + +// Runs state check and changes underglow color and animation +layer_state_t default_layer_state_set_user(layer_state_t state) { + state = default_layer_state_set_keymap(state); + return state; +} + +__attribute__((weak)) void led_set_keymap(uint8_t usb_led) {} + +// Any custom LED code goes here. +// So far, I only have keyboard specific code, +// So nothing goes here. +void led_set_user(uint8_t usb_led) { led_set_keymap(usb_led); } + +__attribute__((weak)) void eeconfig_init_keymap(void) {} + +void eeconfig_init_user(void) { + userspace_config.raw = 0; + userspace_config.rgb_base_layer_override = false; + userspace_config.rgb_layer_change = true; + #ifdef USERSPACE_RGBLIGHT_ENABLE + userspace_config.mode = RGBLIGHT_MODE_STATIC_LIGHT; + #endif + userspace_config.hue = 167; // BLUE + userspace_config.sat = 255; + userspace_config.val = 255; + userspace_config.speed = 1; + eeconfig_update_user(userspace_config.raw); + eeconfig_init_keymap(); + keyboard_init(); +} + +bool hasAllBitsInMask(uint8_t value, uint8_t mask) { + value &= 0xF; + mask &= 0xF; + + return (value & mask) == mask; +} + +uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + // I always type the shift keys too fast, so tapping term of 200 is way too high + case LSFT_T(KC_T): + case RSFT_T(KC_N): + return 75; + default: + return TAPPING_TERM; + } +} + + +// This was added to deal with this issue: +// * https://www.reddit.com/r/olkb/comments/mwf5re/help_needed_controlling_individual_rgb_leds_on_a/ +// * https://github.com/qmk/qmk_firmware/issues/12037 +#ifdef SPLIT_KEYBOARD +void housekeeping_task_user(void) { + static layer_state_t old_layer_state = 0; + if (!is_keyboard_master() && old_layer_state != layer_state) { + old_layer_state = layer_state; + layer_state_set_user(layer_state); + } +} +#endif diff --git a/users/smathev/smathev.h b/users/smathev/smathev.h new file mode 100644 index 00000000..9191da43 --- /dev/null +++ b/users/smathev/smathev.h @@ -0,0 +1,74 @@ +/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) + * + * 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, see . + */ + +#pragma once +#include QMK_KEYBOARD_H + +#include "version.h" +#include "eeprom.h" +#include "wrappers.h" +#include "process_records.h" +#include "keymap_danish.h" + +#if defined(USERSPACE_RGBLIGHT_ENABLE) +# include "rgb_stuff.h" +#endif +#if defined(HAPTIC_ENABLE) +# include "haptic_stuff.h" +#endif + +/* Define layer names */ +enum userspace_layers { + _NORTO= 0, + _QWERTY, + _NORTNAVIGATION, + _SYMFKEYS +}; + +void press_super_alt_tab(bool shift); +void matrix_init_keymap(void); +void shutdown_keymap(void); +void suspend_power_down_keymap(void); +void suspend_wakeup_init_keymap(void); +void matrix_scan_keymap(void); +layer_state_t layer_state_set_keymap(layer_state_t state); +layer_state_t default_layer_state_set_keymap(layer_state_t state); +void led_set_keymap(uint8_t usb_led); +void eeconfig_init_keymap(void); +bool hasAllBitsInMask(uint8_t value, uint8_t mask); + +// clang-format off +typedef union { + uint32_t raw; + struct { + bool rgb_layer_change :1; + bool rgb_base_layer_override :1; + bool rgb_matrix_idle_anim :1; + uint8_t mode; + uint8_t hue; + uint8_t sat; + uint8_t val; + uint8_t speed; + uint8_t caps_lock_hue; + }; +} userspace_config_t; +// clang-format on + +extern userspace_config_t userspace_config; + +#if defined(COMBO_ENABLE) +# include "combos.h" +#endif diff --git a/users/smathev/wrappers.h b/users/smathev/wrappers.h new file mode 100644 index 00000000..11174228 --- /dev/null +++ b/users/smathev/wrappers.h @@ -0,0 +1,302 @@ +#pragma once +#include "smathev.h" +#include "keymap_danish.h" +//#include "features/repeat_key.h" +//#include "features/sentence_case.h" + +/* +Since our quirky block definitions are basically a list of comma separated +arguments, we need a wrapper in order for these definitions to be +expanded before being used as arguments to the LAYOUT_xxx macro. +*/ + +// Since sweeeeep uses the name LAYOUT_sweeeeep instead of LAYOUT +#if (!defined(LAYOUT) && defined(LAYOUT_sweeeeep)) +# define LAYOUT LAYOUT_sweeeeep +#endif + +// clang-format off +#define LAYOUT_ergodox_wrapper(...) LAYOUT_ergodox(__VA_ARGS__) +#define LAYOUT_ergodox_pretty_wrapper(...) LAYOUT_ergodox_pretty(__VA_ARGS__) +#define KEYMAP_wrapper(...) LAYOUT(__VA_ARGS__) +#define LAYOUT_wrapper(...) LAYOUT(__VA_ARGS__) +#define LAYOUT_ortho_4x12_wrapper(...) LAYOUT_ortho_4x12(__VA_ARGS__) +#define LAYOUT_ortho_5x12_wrapper(...) LAYOUT_ortho_5x12(__VA_ARGS__) +#define LAYOUT_gergo_wrapper(...) LAYOUT_gergo(__VA_ARGS__) +#define LAYOUT_split_3x6_3_wrapper(...) LAYOUT_split_3x6_3(__VA_ARGS__) +#define LAYOUT_reviung39_wrapper(...) LAYOUT_reviung39(__VA_ARGS__) +#define LAYOUT_pteron38_wrapper(...) LAYOUT_pteron38(__VA_ARGS__) +#define LAYOUT_ffkbhw_wrapper(...) LAYOUT_ffkbhw(__VA_ARGS__) + +/* +Blocks for each of the four major keyboard layouts +Organized so we can quickly adapt and modify all of them +at once, rather than for each keyboard, one at a time. +And this allows for much cleaner blocks in the keymaps. +For instance Tap/Hold for Control on all of the layouts + +NOTE: These are all the same length. If you do a search/replace + then you need to add/remove underscores to keep the + lengths consistent. +*/ + + +#define ____QWERTY_L1_K1__ KC_Q +#define ____QWERTY_L1_K2__ KC_W +#define ____QWERTY_L1_K3__ KC_E +#define ____QWERTY_L1_K4__ KC_R +#define ____QWERTY_L1_K5__ KC_T + +#define ____QWERTY_L2_K1__ KC_A +#define ____QWERTY_L2_K2__ KC_S +#define ____QWERTY_L2_K3__ KC_D +#define ____QWERTY_L2_K4__ KC_F +#define ____QWERTY_L2_K5__ KC_G + +#define ____QWERTY_L3_K1__ LGUI_T(KC_Z) +#define ____QWERTY_L3_K2__ LALT_T(KC_X) +#define ____QWERTY_L3_K3__ LSFT_T(KC_C) +#define ____QWERTY_L3_K4__ LCTL_T(KC_V) +#define ____QWERTY_L3_K5__ KC_B + + + +#define ____QWERTY_R1_K1__ KC_Y +#define ____QWERTY_R1_K2__ KC_U +#define ____QWERTY_R1_K3__ KC_I +#define ____QWERTY_R1_K4__ KC_O +#define ____QWERTY_R1_K5__ KC_P + +#define ____QWERTY_R2_K1__ KC_H +#define ____QWERTY_R2_K2__ KC_J +#define ____QWERTY_R2_K3__ KC_K +#define ____QWERTY_R2_K4__ KC_L +#define ____QWERTY_R2_K5__ DK_ARNG + +#define ____QWERTY_R3_K1__ KC_N +#define ____QWERTY_R3_K2__ RCTL_T(KC_M) +#define ____QWERTY_R3_K3__ RSFT_T(DK_AE) +#define ____QWERTY_R3_K4__ RALT_T(DK_OSTR) +#define ____QWERTY_R3_K5__ RGUI_T(KC_MINS) + +#define __________________QWERTY_L1____________________ ____QWERTY_L1_K1__, ____QWERTY_L1_K2__, ____QWERTY_L1_K3__, ____QWERTY_L1_K4__, ____QWERTY_L1_K5__ +#define __________________QWERTY_L2____________________ ____QWERTY_L2_K1__, ____QWERTY_L2_K2__, ____QWERTY_L2_K3__, ____QWERTY_L2_K4__, ____QWERTY_L2_K5__ +#define __________________QWERTY_L3____________________ ____QWERTY_L3_K1__, ____QWERTY_L3_K2__, ____QWERTY_L3_K3__, ____QWERTY_L3_K4__, ____QWERTY_L3_K5__ + +#define __________________QWERTY_R1____________________ ____QWERTY_R1_K1__, ____QWERTY_R1_K2__, ____QWERTY_R1_K3__, ____QWERTY_R1_K4__, ____QWERTY_R1_K5__ +#define __________________QWERTY_R2____________________ ____QWERTY_R2_K1__, ____QWERTY_R2_K2__, ____QWERTY_R2_K3__, ____QWERTY_R2_K4__, ____QWERTY_R2_K5__ +#define __________________QWERTY_R3____________________ ____QWERTY_R3_K1__, ____QWERTY_R3_K2__, ____QWERTY_R3_K3__, ____QWERTY_R3_K4__, ____QWERTY_R3_K5__ + + +#define _QWERTY_THUMB_L1__ KC_DEL +#define _QWERTY_THUMB_L2__ DK_COMM +#define _QWERTY_THUMB_L3__ KC_BSPC + +#define _QWERTY_THUMB_R1__ KC_SPACE +#define _QWERTY_THUMB_R2__ DK_DOT +#define _QWERTY_THUMB_R3__ KC_ENT + +#define _QWERTY_THUMBS_LEFT_2__ _QWERTY_THUMB_L2__, _QWERTY_THUMB_L3__ +#define _QWERTY_THUMBS_RIGHT_2__ _QWERTY_THUMB_R1__, _QWERTY_THUMB_R2__ + +#define _QWERTY_THUMBS_LEFT_3__ _QWERTY_THUMB_L1__, _QWERTY_THUMB_L2__, _QWERTY_THUMB_L3__ +#define _QWERTY_THUMBS_RIGHT_3__ _QWERTY_THUMB_R1__, _QWERTY_THUMB_R2__, _QWERTY_THUMB_R3__ + +#define __QWERTY_THUMBS_4__ _QWERTY_THUMBS_LEFT_2__, _QWERTY_THUMBS_RIGHT_2__ +#define __QWERTY_THUMBS_5__ _QWERTY_THUMB_L1__, _QWERTY_THUMB_L2__, _QWERTY_THUMB_R1__, _QWERTY_THUMB_R2__, _QWERTY_THUMB_R3__ +#define __QWERTY_THUMBS_6__ _QWERTY_THUMBS_LEFT_3__, _QWERTY_THUMBS_RIGHT_3__ + +/* Norto https://lykt.xyz/skl/norto/#da + * + * ,----------------------------------. ,----------------------------------. + * | Ø | Æ | U | G | J | | B | F | L | H | X | + * |------+------+------+------+------| |------+------+------+------+------| + * | O | I | A | T | M | | P | N | R | S | D | + * |------+------+------+------+------| |------+------+------+------+------| + * | Y | Å | V | C | , | | . | W | K | Z | Q | + * `----------------------------------' `----------------------------------' + * ,--------------------. ,--------------------. + * | LOWER| Enter| E | |BckSpc| Space| RAISE| + * `--------------------' `--------------------. + */ + +#define __NORTO_THUMB_L1__ _______ +#define __NORTO_THUMB_L2__ DK_MINS +#define __NORTO_THUMB_L3__ KC_E +#define __NORTO_THUMB_R1__ KC_SPACE +#define __NORTO_THUMB_R2__ KC_BSPC +#define __NORTO_THUMB_R3__ _______ + +#define __NORTO_THUMBS_LEFT_2__ __NORTO_THUMB_L2__, __NORTO_THUMB_L3__ +#define __NORTO_THUMBS_RIGHT_2__ __NORTO_THUMB_R1__, __NORTO_THUMB_R2__ + +#define __NORTO_THUMBS_LEFT_3__ __NORTO_THUMB_L1__, __NORTO_THUMB_L2__, __NORTO_THUMB_L3__ +#define __NORTO_THUMBS_RIGHT_3__ __NORTO_THUMB_R1__, __NORTO_THUMB_R2__, __NORTO_THUMB_R3__ + +#define __NORTO_THUMBS_4__ __NORTO_THUMBS_LEFT_2__, __NORTO_THUMBS_RIGHT_2__ +#define __NORTO_THUMBS_5__ __NORTO_THUMB_L1__, __NORTO_THUMB_L2__, __NORTO_THUMB_R1__, __NORTO_THUMB_R2__, __NORTO_THUMB_R3__ +#define __NORTO_THUMBS_6__ __NORTO_THUMBS_LEFT_3__, __NORTO_THUMBS_RIGHT_3__ + +#define ____NORTO_L1_K1__ DK_OSTR +#define ____NORTO_L1_K2__ DK_AE +#define ____NORTO_L1_K3__ KC_U +#define ____NORTO_L1_K4__ KC_G +#define ____NORTO_L1_K5__ KC_J + +#define ____NORTO_L2_K1__ KC_O +#define ____NORTO_L2_K2__ KC_I +#define ____NORTO_L2_K3__ KC_A +#define ____NORTO_L2_K4__ KC_T +#define ____NORTO_L2_K5__ KC_M + +#define ____NORTO_L3_K1__ LGUI_T(DK_COMM) +#define ____NORTO_L3_K2__ LALT_T(KC_Y) +#define ____NORTO_L3_K3__ LSFT_T(DK_ARNG) +#define ____NORTO_L3_K4__ LCTL_T(KC_V) +#define ____NORTO_L3_K5__ KC_C + +#define ____NORTO_R1_K1__ KC_B +#define ____NORTO_R1_K2__ KC_F +#define ____NORTO_R1_K3__ KC_L +#define ____NORTO_R1_K4__ KC_H +#define ____NORTO_R1_K5__ KC_X + +#define ____NORTO_R2_K1__ KC_P +#define ____NORTO_R2_K2__ KC_N +#define ____NORTO_R2_K3__ KC_R +#define ____NORTO_R2_K4__ KC_S +#define ____NORTO_R2_K5__ KC_D + +#define ____NORTO_R3_K1__ KC_W +#define ____NORTO_R3_K2__ RCTL_T(KC_K) +#define ____NORTO_R3_K3__ RSFT_T(KC_Z) +#define ____NORTO_R3_K4__ RALT_T(KC_Q) +#define ____NORTO_R3_K5__ RGUI_T(KC_DOT) + +#define __________________NORTO_L1____________________ ____NORTO_L1_K1__, ____NORTO_L1_K2__, ____NORTO_L1_K3__, ____NORTO_L1_K4__, ____NORTO_L1_K5__ +#define __________________NORTO_L2____________________ ____NORTO_L2_K1__, ____NORTO_L2_K2__, ____NORTO_L2_K3__, ____NORTO_L2_K4__, ____NORTO_L2_K5__ +#define __________________NORTO_L3____________________ ____NORTO_L3_K1__, ____NORTO_L3_K2__, ____NORTO_L3_K3__, ____NORTO_L3_K4__, ____NORTO_L3_K5__ + +#define __________________NORTO_R1____________________ ____NORTO_R1_K1__, ____NORTO_R1_K2__, ____NORTO_R1_K3__, ____NORTO_R1_K4__, ____NORTO_R1_K5__ +#define __________________NORTO_R2____________________ ____NORTO_R2_K1__, ____NORTO_R2_K2__, ____NORTO_R2_K3__, ____NORTO_R2_K4__, ____NORTO_R2_K5__ +#define __________________NORTO_R3____________________ ____NORTO_R3_K1__, ____NORTO_R3_K2__, ____NORTO_R3_K3__, ____NORTO_R3_K4__, ____NORTO_R3_K5__ + +// BLANK FULL LINE +#define ___________________BLANK___________________ _______, _______, _______, _______, _______ + +// NAVNORT + +#define __NORTNAV_L1_K1__ KC_ESC +#define __NORTNAV_L1_K2__ KC_PGUP +#define __NORTNAV_L1_K3__ KC_UP +#define __NORTNAV_L1_K4__ KC_PGDN +#define __NORTNAV_L1_K5__ FP_SUPER_TAB + +#define __NORTNAV_L2_K1__ KC_HOME +#define __NORTNAV_L2_K2__ KC_LEFT +#define __NORTNAV_L2_K3__ KC_DOWN +#define __NORTNAV_L2_K4__ KC_RGHT +#define __NORTNAV_L2_K5__ KC_END + +#define __NORTNAV_L3_K1__ LGUI_T(_______) +#define __NORTNAV_L3_K2__ LALT_T(_______) +#define __NORTNAV_L3_K3__ LSFT_T(_______) +#define __NORTNAV_L3_K4__ LCTL_T(_______) +#define __NORTNAV_L3_K5__ _______ + +#define ____________NORTNAVIGATION_1_______________ __NORTNAV_L1_K1__, __NORTNAV_L1_K2__, __NORTNAV_L1_K3__, __NORTNAV_L1_K4__, __NORTNAV_L1_K5__ +#define ____________NORTNAVIGATION_2_______________ __NORTNAV_L2_K1__, __NORTNAV_L2_K2__, __NORTNAV_L2_K3__, __NORTNAV_L2_K4__, __NORTNAV_L2_K5__ +#define ____________NORTNAVIGATION_3_______________ __NORTNAV_L3_K1__, __NORTNAV_L3_K2__, __NORTNAV_L3_K3__, __NORTNAV_L3_K4__, __NORTNAV_L3_K5__ + +#define __NUMPAD_R1_K1__ DK_ASTR +#define __NUMPAD_R1_K2__ KC_7 +#define __NUMPAD_R1_K3__ KC_8 +#define __NUMPAD_R1_K4__ KC_9 +#define __NUMPAD_R1_K5__ DK_PLUS + +#define __NUMPAD_R2_K1__ DK_SLSH +#define __NUMPAD_R2_K2__ KC_4 +#define __NUMPAD_R2_K3__ KC_5 +#define __NUMPAD_R2_K4__ KC_6 +#define __NUMPAD_R2_K5__ DK_MINS + +#define __NUMPAD_R3_K1__ DK_LPRN +#define __NUMPAD_R3_K2__ RCTL_T(KC_1) +#define __NUMPAD_R3_K3__ RSFT_T(KC_2) +#define __NUMPAD_R3_K4__ RALT_T(KC_3) +#define __NUMPAD_R3_K5__ RGUI_T(KC_0) + +#define _________________NUMPAD_1__________________ __NUMPAD_R1_K1__, __NUMPAD_R1_K2__, __NUMPAD_R1_K3__, __NUMPAD_R1_K4__, __NUMPAD_R1_K5__ +#define _________________NUMPAD_2__________________ __NUMPAD_R2_K1__, __NUMPAD_R2_K2__, __NUMPAD_R2_K3__, __NUMPAD_R2_K4__, __NUMPAD_R2_K5__ +#define _________________NUMPAD_3__________________ __NUMPAD_R3_K1__, __NUMPAD_R3_K2__, __NUMPAD_R3_K3__, __NUMPAD_R3_K4__, __NUMPAD_R3_K5__ + +// FKeys + SYM +#define ______FKEY____L1_K1__ KC_F1 +#define ______FKEY____L1_K2__ KC_F2 +#define ______FKEY____L1_K3__ KC_F3 +#define ______FKEY____L1_K4__ KC_F4 +#define ______FKEY____L1_K5__ KC_F5 + +#define ______FKEY____L2_K1__ KC_F6 +#define ______FKEY____L2_K2__ KC_F7 +#define ______FKEY____L2_K3__ KC_F8 +#define ______FKEY____L2_K4__ KC_F9 +#define ______FKEY____L2_K5__ KC_F10 + +#define ______FKEY____L3_K1__ LGUI_T(KC_F11) +#define ______FKEY____L3_K2__ LALT_T(KC_F12) +#define ______FKEY____L3_K3__ LSFT_T(KC_C) +#define ______FKEY____L3_K4__ LCTL_T(KC_V) +#define ______FKEY____L3_K5__ KC_B + +#define __NORTSYMBOLS_R1_K1__ DK_AT // @ +#define __NORTSYMBOLS_R1_K2__ DK_LBRC // [ - Shifted ] +#define __NORTSYMBOLS_R1_K3__ DK_LCBR // { - Shifted {} +#define __NORTSYMBOLS_R1_K4__ DK_CIRC +#define __NORTSYMBOLS_R1_K5__ _______ + +#define __NORTSYMBOLS_R2_K1__ DK_QUOT // ' SHFITED " +#define __NORTSYMBOLS_R2_K2__ DK_LABK // < - Shifted > +#define __NORTSYMBOLS_R2_K3__ DK_DLR // $ - Shifted € +#define __NORTSYMBOLS_R2_K4__ DK_PIPE // | +#define __NORTSYMBOLS_R2_K5__ DK_GRV // ` - Shifted ¨ + +#define __NORTSYMBOLS_R3_K1__ _______ +#define __NORTSYMBOLS_R3_K2__ RCTL_T(C_CAPSWORD) +#define __NORTSYMBOLS_R3_K3__ RSFT_T(C_UNDERSCORECASE) +#define __NORTSYMBOLS_R3_K4__ RALT_T(C_HYPHENCASE) +#define __NORTSYMBOLS_R3_K5__ RGUI_T(_______) + + + +#define ___________________FKEY______L1________________ ______FKEY____L1_K1__, ______FKEY____L1_K2__, ______FKEY____L1_K3__, ______FKEY____L1_K4__, ______FKEY____L1_K5__ +#define ___________________FKEY______L2________________ ______FKEY____L2_K1__, ______FKEY____L2_K2__, ______FKEY____L2_K3__, ______FKEY____L2_K4__, ______FKEY____L2_K5__ +#define ___________________FKEY______L3________________ ______FKEY____L3_K1__, ______FKEY____L3_K2__, ______FKEY____L3_K3__, ______FKEY____L3_K4__, ______FKEY____L3_K5__ + +#define ________________NORTSYMBOLS_R1_________________ __NORTSYMBOLS_R1_K1__, __NORTSYMBOLS_R1_K2__, __NORTSYMBOLS_R1_K3__, __NORTSYMBOLS_R1_K4__, __NORTSYMBOLS_R1_K5__ +#define ________________NORTSYMBOLS_R2_________________ __NORTSYMBOLS_R2_K1__, __NORTSYMBOLS_R2_K2__, __NORTSYMBOLS_R2_K3__, __NORTSYMBOLS_R2_K4__, __NORTSYMBOLS_R2_K5__ +#define ________________NORTSYMBOLS_R3_________________ __NORTSYMBOLS_R3_K1__, __NORTSYMBOLS_R3_K2__, __NORTSYMBOLS_R3_K3__, __NORTSYMBOLS_R3_K4__, __NORTSYMBOLS_R3_K5__ + +// GAMES_LAYER? + +#define ___________________GAMES_0_________________ KC_F1, KC_F2, KC_C, KC_V, KC_G +#define ___________________GAMES_1_________________ KC_Q, KC_W, KC_E, KC_R, KC_D +#define ___________________GAMES_2_________________ KC_A, KC_F, KC_TAB, KC_L, KC_H +#define ___________________GAMES_3_________________ KC_T, KC_COMM, KC_K, KC_SCLN, KC_DOT +#define __GAMES_R0_L__ KC_F4 +#define __GAMES_R1_L__ KC_Z +#define __GAMES_R2_L__ KC_P +#define __GAMES_R3_L__ KC_LSFT +#define __GAMES_R0_R__ KC_N +#define __GAMES_R1_R__ KC_Y +#define __GAMES_R2_R__ KC_F7 +#define __GAMES_R3_R__ KC_ESC +#define __GAMES_TH_L__ KC_LALT +#define __GAMES_TH_C__ KC_X +#define __GAMES_TH_R__ KC_B +#define __GAMES_R4_1__ KC_J +#define __GAMES_R4_2__ __GAMES_R3_R__ +#define __GAMES_R4_3__ KC_LCTL + + +// clang-format on