~ruther/qmk_firmware

61a7aebd1630b35e177dcd4e49694756593428a1 — Jeremy Bernhardt 6 years ago a6857d1
[Keyboard] Georgi FW updates (#5609)

* Working on chording

* Working on chording

* Got layouts in order

* Initial Georgi support

* forgot to add keymaps

* Updated readme

* Update keyboards/georgi/keymaps/template/readme.md

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/georgi.h

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/keymaps/default/keymap.c

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/keymaps/default/keymap.c

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/rules.mk

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/rules.mk

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/matrix.c

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/georgi.c

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/georgi.c

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/rules.mk

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/keymaps/default/keymap.c

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/keymaps/template/keymap.c

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/matrix.c

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Disabled features, updated info

* Update keyboards/georgi/config.h

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Update keyboards/georgi/config.h

Co-Authored-By: germ <jeremythegeek@gmail.com>

* Fixed info.json

* Split the number button and fixed gaming mode.

* started work on history feature

* Working history/multikeyfuckery

* type

* inital code reduction refactor

* Got multikey patched up, optimizing for size

* Forgot to remove stuff

* fixed key repeat

* Key repeat added.

* Symshift locking

* Midchord Sym shenanigans.

* Added only QWERTY mode

* Split out header

* Added stickybits, minimal layour

* Fixing user layout

* Whitespace fixing

* Fixing Version name
M keyboards/georgi/config.h => keyboards/georgi/config.h +2 -4
@@ 23,15 23,13 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.

/* Defaults */

#define VERSION "Alpha 01: Ted "
#define VERSION "v1.0: Stenoknight"
#define VERBOSE

#define FORCE_NKRO
#define NO_ACTION_MACRO
#define NO_ACTION_FUNCTION
#define NO_DEBUG
#define NO_ACTION_ONESHOT
#define NO_ACTION_FUNCTION
#define NO_ACTION_MACRO

/* USB Device descriptor parameter */
#define VENDOR_ID       0xFEED

M keyboards/georgi/keymaps/default/keymap.c => keyboards/georgi/keymaps/default/keymap.c +200 -191
@@ 1,4 1,4 @@
/* 
/*
 * Good on you for modifying your layout, this is the most nonQMK layout you will come across
 * There are three modes, Steno (the default), QWERTY (Toggleable) and a Momentary symbol layer
 *


@@ 15,215 15,224 @@
#include "keymap_steno.h"
#define IGNORE_MOD_TAP_INTERRUPT

int getKeymapCount(void);

// Proper Layers
#define FUNCT   (LSD | LK | LP | LH)
#define MEDIA   (LSD | LK | LW | LR)
#define MOVE    (ST1 | ST2)

// QMK Layers
#define STENO_LAYER   0
#define GAMING        1
#define GAMING_2      2

/* Keyboard Layout
 * ,---------------------------------.    ,------------------------------.
 * | FN  | LSU | LFT | LP | LH | ST1 |    | ST3 | RF | RP | RL | RT | RD |
 * |-----+-----+-----+----+----|-----|    |-----|----+----+----+----+----|
 * | PWR | LSD | LK  | LW | LR | ST2 |    | ST4 | RR | RG | RB | RS | RZ |
 * | PWR | LSD | LK  | LW | LR | ST2 |    | ST4 | RR | BB | RG | RS | RZ |
 * `---------------------------------'    `------------------------------'
 *                   ,---------------,    .---------------.
 *                   | NUM | LA | LO |    | RE | RU | NUM |
 *                   | LNO | LA | LO |    | RE | RU | RNO |
 *                   `---------------'    `---------------'
 */

// YOU MUST ORDER THIS!
// P   Will return from processing on the first match it finds. Therefore
// PJ  Will run the requested action, remove the matched chord and continue 
//
// First any chords that would conflict with PJs need to be checked, then PJs, lastly Ps.
// For all chords should be ordered by length in their section!
// Note: You can only use basic keycodes here!
// P() is just a wrapper to make your life easier.
//
// http://docs.gboards.ca
bool processQwerty(void) {
	// Place P's that would be trashed by PJ's here
	P( RT  | RS  | RD  | RZ | NUM,		SEND_STRING(VERSION); SEND_STRING(__DATE__));
	P( NUM | LA  | LO  | RE | RU,		SEND(KC_MPLY));
	P( ST1 | ST2 | ST3 | ST4,			SEND(KC_BSPC));

	// Thumb Chords
	P(  LA  | LO  | RE  | RU,			SEND(KC_CAPS));
	P(  LA  | RU,						SEND(KC_ESC));
	PJ( LO  | RE,						SEND(KC_LCTL));
	PJ( NUM | LA | RU,					SEND(KC_LCTL); SEND(KC_LSFT));
	PJ( NUM | LA | RE,					SEND(KC_LCTL); SEND(KC_LSFT); SEND(KC_LALT));
	
	// Mods 
	PJ( RT | RD | RS | RZ,				SEND(KC_LGUI));
	PJ( RT | RD,						SEND(KC_LCTL));
	PJ( RS | RZ,						SEND(KC_LALT));
	PJ( LA | NUM,						SEND(KC_LCTL));
	PJ( LA | LO,						SEND(KC_LALT));
	PJ( LO,								SEND(KC_LSFT));

	// Function Layer 
	P( FUNCT | RF | RR,					SEND(KC_F5));
	P( FUNCT | RP | RB,					SEND(KC_F6));
	P( FUNCT | RL | RG,					SEND(KC_F7));
	P( FUNCT | RT | RS,					SEND(KC_F8));
	P( FUNCT | RF,						SEND(KC_F1));
	P( FUNCT | RP,						SEND(KC_F2));
	P( FUNCT | RL,						SEND(KC_F3));
	P( FUNCT | RT,						SEND(KC_F4));
	P( FUNCT | RR,						SEND(KC_F9));
	P( FUNCT | RG,						SEND(KC_F10));
	P( FUNCT | RB,						SEND(KC_F11));
	P( FUNCT | RS,						SEND(KC_F12));

	// Movement Layer
	P( MOVE | RF,						SEND(KC_LEFT));
	P( MOVE | RP,						SEND(KC_DOWN));
	P( MOVE | RL,						SEND(KC_UP));
	P( MOVE | RT,						SEND(KC_RIGHT));
	P( MOVE | ST3,						SEND(KC_PGUP));
	P( MOVE | ST4,						SEND(KC_PGDN));

	// Media Layer
	P( MEDIA | RF,						SEND(KC_MPRV));
	P( MEDIA | RP,						SEND(KC_MPLY));
	P( MEDIA | RL,						SEND(KC_MPLY));
	P( MEDIA | RT,						SEND(KC_MNXT));
	P( MEDIA | RD,						SEND(KC_VOLU));
	P( MEDIA | RZ,						SEND(KC_VOLD));
	P( MEDIA | RS,						SEND(KC_MUTE));

	// Mouse Keys
	P( LP | LH,							clickMouse(KC_MS_BTN1));
	P( LW | LR,							clickMouse(KC_MS_BTN2));
	
	// Number Row
	P( NUM | LSU,						SEND(KC_1));
	P( NUM | LFT,						SEND(KC_2));
	P( NUM | LP,						SEND(KC_3));
	P( NUM | LH,						SEND(KC_4));
	P( NUM | ST1,						SEND(KC_5));
	P( NUM | ST3,						SEND(KC_6));
	P( NUM | RF,						SEND(KC_7));
	P( NUM | RP,						SEND(KC_8));
	P( NUM | RL,						SEND(KC_9));
	P( NUM | RT,						SEND(KC_0));
	P( NUM | LA,						SEND(KC_5));
	P( NUM | RT,						SEND(KC_0));
	
	// Specials
	P( LA | NUM,						SEND(KC_ESC));
	P( RU | NUM,						SEND(KC_TAB));
	P( RE | RU,							SEND(KC_BSPC));
	P( RD | RZ,							SEND(KC_ENT));
	P( RE,								SEND(KC_ENT));
	P( RD,								SEND(KC_BSPC));	
	P( NUM,								SEND(KC_BSPC));
	P( LA,								SEND(KC_SPC));
	P( RU,								SEND(KC_SPC));
	P( RZ,								SEND(KC_ESC));

	// Letters
	P( LSU | LSD,						SEND(KC_A));
	P( LFT | LK,						SEND(KC_S));
	P( LP  | LW,						SEND(KC_D));
	P( LH  | LR,						SEND(KC_F));
	P( ST1 | ST2,						SEND(KC_G));
	P( ST3 | ST4,						SEND(KC_H));
	P( RF  | RR,						SEND(KC_J));
	P( RT  | RS,						SEND(KC_SCLN))
	P( RG  | RL,						SEND(KC_L));
	P( RP  | RB,						SEND(KC_K));
	P( LSU,								SEND(KC_Q));
	P( LSD,								SEND(KC_Z));
	P( LFT,								SEND(KC_W));
	P( LK,								SEND(KC_X));
	P( LP,								SEND(KC_E));
	P( LW,								SEND(KC_C));
	P( LH,								SEND(KC_R));
	P( LR,								SEND(KC_V));
	P( ST1,								SEND(KC_T));
	P( ST2,								SEND(KC_B));
	P( ST3,								SEND(KC_Y));
	P( ST4,								SEND(KC_N));
	P( RF,								SEND(KC_U));
	P( RR,								SEND(KC_M));
	P( RP,								SEND(KC_I));
	P( RB,								SEND(KC_COMM));
	P( RL,								SEND(KC_O));
	P( RG,								SEND(KC_DOT));
	P( RT,								SEND(KC_P));
	P( RS,								SEND(KC_SLSH));

	// Symbols and Numbers
	P( PWR | RE | RU,					SEND(KC_ENT));
	P( PWR | LA | LO,					SEND(KC_SPC));
	P( PWR | LP | LW,					SEND(KC_LSFT); SEND(KC_9));			// (
	P( PWR | LH | LR,					SEND(KC_LSFT); SEND(KC_0));			// )
	P( PWR | ST1 | ST2,					SEND(KC_GRV));						// `
	P( PWR | RD | RZ,					SEND(KC_ESC));							
	P( PWR | LSU | LSD,					SEND(KC_LSFT); SEND(KC_3));			// #
	P( PWR | LFT | LK,					SEND(KC_LSFT); SEND(KC_4));			// $
	P( PWR | LSU,						SEND(KC_LSFT); SEND(KC_1));			// !
	P( PWR | LSD,						SEND(KC_LSFT); SEND(KC_5));			// %
	P( PWR | LFT,						SEND(KC_LSFT); SEND(KC_2));			// @
	P( PWR | LK,						SEND(KC_LSFT); SEND(KC_6));			// ^
	P( PWR | LP,						SEND(KC_LSFT); SEND(KC_LBRC));		// {
	P( PWR | LW,						SEND(KC_LBRC));
	P( PWR | LH,						SEND(KC_LSFT); SEND(KC_RBRC));		// }
	P( PWR | LR,						SEND(KC_RBRC));
	P( PWR | ST1,						SEND(KC_LSFT); SEND(KC_BSLS));		// |
	P( PWR | ST2,						SEND(KC_LSFT); SEND(KC_GRV));		// ~
	P( PWR | ST3,						SEND(KC_QUOT));
	P( PWR | ST4,						SEND(KC_LSFT); SEND(KC_QUOT));		// "
	P( PWR | RF,						SEND(KC_KP_PLUS));
	P( PWR | RR,						SEND(KC_LSFT); SEND(KC_7));			// &
	P( PWR | RP,						SEND(KC_MINS));
	P( PWR | RB,						SEND(KC_EQL));
	P( PWR | RL,						SEND(KC_SLSH));
	P( PWR | RG,						SEND(KC_COMM));
	P( PWR | RT,						SEND(KC_PAST));
	P( PWR | RS,						SEND(KC_DOT));
	P( PWR | RD,						SEND(KC_TAB));
	P( PWR | LA,						SEND(KC_SCLN));
	P( PWR | LO,						SEND(KC_SLSH));
	P( PWR | RE,						SEND(KC_SCLN));
	P( PWR | RU,						SEND(KC_SLSH));


	// If we make here, send as a steno chord
	// If plover is running we can hook that host side
	return false;
uint32_t processQwerty(bool lookup) {
    // Specials
    P( RT  | RS  | RD  | RZ | LNO,        SEND_STRING(VERSION); SEND_STRING(__DATE__));
    P( LNO | RNO | LA  | LO | RE | RU,    SEND(KC_MPLY));
    P( LFT | LK  | LP  | LW,              REPEAT());
    P( ST1 | ST2 | LW  | ST4,             SEND(KC_BSPC));

    // Mouse Keys
    P( LO  | LSD | LK,    CLICK_MOUSE(KC_MS_BTN2));
    P( LO  | LR  | LW,    CLICK_MOUSE(KC_MS_BTN1));

    // Thumb Chords
    P( LA  | LO  | RE  | RU,    SEND(KC_CAPS));
    P( LA  | RU,                SEND(KC_ESC));
    P( LO  | RE,                SEND(KC_LCTL));
    P( LNO | RNO | LA | RU,     SEND(KC_LCTL); SEND(KC_LSFT));
    P( LNO | LA  | RE,          SEND(KC_LCTL); SEND(KC_LSFT); SEND(KC_LALT));

    // Mods
    P( RT | RD   | RS | RZ,    SEND(KC_LGUI));
    P( RT | RD,                SEND(KC_LCTL));
    P( RS | RZ,                SEND(KC_LALT));
    P( LA | LNO,               SEND(KC_LCTL));
    P( LA | LO,                SEND(KC_LALT));
    P( LO,                     SEND(KC_LSFT));

    // Function Layer
    P( FUNCT | RF | RR,    SEND(KC_F5));
    P( FUNCT | RP | RB,    SEND(KC_F6));
    P( FUNCT | RL | RG,    SEND(KC_F7));
    P( FUNCT | RT | RS,    SEND(KC_F8));
    P( FUNCT | RF,         SEND(KC_F1));
    P( FUNCT | RP,         SEND(KC_F2));
    P( FUNCT | RL,         SEND(KC_F3));
    P( FUNCT | RT,         SEND(KC_F4));
    P( FUNCT | RR,         SEND(KC_F9));
    P( FUNCT | RG,         SEND(KC_F10));
    P( FUNCT | RB,         SEND(KC_F11));
    P( FUNCT | RS,         SEND(KC_F12));

    // Movement Layer
    P( MOVE | RF,     SEND(KC_LEFT));
    P( MOVE | RP,     SEND(KC_DOWN));
    P( MOVE | RL,     SEND(KC_UP));
    P( MOVE | RT,     SEND(KC_RIGHT));
    P( MOVE | ST3,    SEND(KC_PGUP));
    P( MOVE | ST4,    SEND(KC_PGDN));

    // Media Layer
    P( MEDIA | RF,    SEND(KC_MPRV));
    P( MEDIA | RP,    SEND(KC_MPLY));
    P( MEDIA | RL,    SEND(KC_MPLY));
    P( MEDIA | RT,    SEND(KC_MNXT));
    P( MEDIA | RD,    SEND(KC_VOLU));
    P( MEDIA | RZ,    SEND(KC_VOLD));
    P( MEDIA | RS,    SEND(KC_MUTE));

    // Number Row, Left
    P( LNO | LSU,    SEND(KC_1));
    P( LNO | LFT,    SEND(KC_2));
    P( LNO | LP,     SEND(KC_3));
    P( LNO | LH,     SEND(KC_4));
    P( LNO | ST1,    SEND(KC_5));
    P( LNO | ST3,    SEND(KC_6));
    P( LNO | RF,     SEND(KC_7));
    P( LNO | RP,     SEND(KC_8));
    P( LNO | RL,     SEND(KC_9));
    P( LNO | RT,     SEND(KC_0));

    // Number Row, Right
    P( RNO | LSU,    SEND(KC_1));
    P( RNO | LFT,    SEND(KC_2));
    P( RNO | LP,     SEND(KC_3));
    P( RNO | LH,     SEND(KC_4));
    P( RNO | ST1,    SEND(KC_5));
    P( RNO | ST3,    SEND(KC_6));
    P( RNO | RF,     SEND(KC_7));
    P( RNO | RP,     SEND(KC_8));
    P( RNO | RL,     SEND(KC_9));
    P( RNO | RT,     SEND(KC_0));
    P( RNO | LA,     SEND(KC_5));

    // Specials
    P( RU | RNO,    SEND(KC_TAB));
    P( RE | RU,     SEND(KC_BSPC));
    P( RD | RZ,     SEND(KC_ENT));
    P( RE,          SEND(KC_ENT));
    P( RD,          SEND(KC_BSPC));
    P( LNO,         SEND(KC_BSPC));
    P( RNO,         SEND(KC_BSPC));
    P( LA,          SEND(KC_SPC));
    P( RU,          SEND(KC_SPC));
    P( RZ,          SEND(KC_ESC));

    // Symbols and Numbers
    P( PWR | RE | RU,      SEND(KC_ENT));
    P( PWR | LA | LO,      SEND(KC_SPC));
    P( PWR | LP | LW,      SEND(KC_LSFT); SEND(KC_9));       // (
    P( PWR | LH | LR,      SEND(KC_LSFT); SEND(KC_0));       // )
    P( PWR | ST1 | ST2,    SEND(KC_GRV));                    // `
    P( PWR | RD | RZ,      SEND(KC_ESC));
    P( PWR | LSU | LSD,    SEND(KC_LSFT); SEND(KC_3));       // #
    P( PWR | LFT | LK,     SEND(KC_LSFT); SEND(KC_4));       // $
    P( PWR | LSU,          SEND(KC_LSFT); SEND(KC_1));       // !
    P( PWR | LSD,          SEND(KC_LSFT); SEND(KC_5));       // %
    P( PWR | LFT,          SEND(KC_LSFT); SEND(KC_2));       // @
    P( PWR | LK,           SEND(KC_LSFT); SEND(KC_6));       // ^
    P( PWR | LP,           SEND(KC_LSFT); SEND(KC_LBRC));    // {
    P( PWR | LW,           SEND(KC_LBRC));
    P( PWR | LH,           SEND(KC_LSFT); SEND(KC_RBRC));    // }
    P( PWR | LR,           SEND(KC_RBRC));
    P( PWR | ST1,          SEND(KC_LSFT); SEND(KC_BSLS));    // |
    P( PWR | ST2,          SEND(KC_LSFT); SEND(KC_GRV));     // ~
    P( PWR | ST3,          SEND(KC_QUOT));
    P( PWR | ST4,          SEND(KC_LSFT); SEND(KC_QUOT));    // "
    P( PWR | RF,           SEND(KC_KP_PLUS));
    P( PWR | RR,           SEND(KC_LSFT); SEND(KC_7));       // &
    P( PWR | RP,           SEND(KC_MINS));
    P( PWR | RB,           SEND(KC_EQL));
    P( PWR | RL,           SEND(KC_SLSH));
    P( PWR | RG,           SEND(KC_COMM));
    P( PWR | RT,           SEND(KC_PAST));
    P( PWR | RS,           SEND(KC_DOT));
    P( PWR | RD,           SEND(KC_TAB));
    P( PWR | LA,           SEND(KC_LSFT));
    P( PWR | LO,           SEND(KC_SLSH));
    P( PWR | RE,           SEND(KC_SCLN));
    P( PWR | RU,           SEND(KC_BSLS));
    P( PWR | LNO,          SEND(KC_BSLS));

    // Letters
    P( LSU | LSD,    SEND(KC_A));
    P( LFT | LK,     SEND(KC_S));
    P( LP  | LW,     SEND(KC_D));
    P( LH  | LR,     SEND(KC_F));
    P( ST1 | ST2,    SEND(KC_G));
    P( ST3 | ST4,    SEND(KC_H));
    P( RF  | RR,     SEND(KC_J));
    P( RT  | RS,     SEND(KC_SCLN));
    P( RG  | RL,     SEND(KC_L));
    P( RP  | RB,     SEND(KC_K));
    P( LSU,          SEND(KC_Q));
    P( LSD,          SEND(KC_Z));
    P( LFT,          SEND(KC_W));
    P( LK,           SEND(KC_X));
    P( LP,           SEND(KC_E));
    P( LW,           SEND(KC_C));
    P( LH,           SEND(KC_R));
    P( LR,           SEND(KC_V));
    P( ST1,          SEND(KC_T));
    P( ST2,          SEND(KC_B));
    P( ST3,          SEND(KC_Y));
    P( ST4,          SEND(KC_N));
    P( RF,           SEND(KC_U));
    P( RR,           SEND(KC_M));
    P( RP,           SEND(KC_I));
    P( RB,           SEND(KC_COMM));
    P( RL,           SEND(KC_O));
    P( RG,           SEND(KC_DOT));
    P( RT,           SEND(KC_P));
    P( RS,           SEND(KC_SLSH));
    P( RNO,          SEND(KC_BSPC));
    P( LNO,          SEND(KC_BSPC));

    return 0;
}

#define STENO_LAYER  	0
#define GAMING			1
#define GAMING_2		2

// "Layers"
// Steno layer should be first in your map.
// When PWR | FN | RR | RG | RB | RS is pressed, the layer is increased to the next map. You must return to STENO_LAYER at the end.
// If you have only a single layer, you must set SINGLELAYER = yes in your rules.mk, otherwise you may experince undefined behaviour
// When PWR | FN | ST3 | ST4 is pressed, the layer is increased to the next map. You must return to STENO_LAYER at the end.
// If you need more space for chords, remove the two gaming layers.
// Note: If using NO_ACTION_TAPPING, LT will not work!

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Main layer, everything goes through here
[STENO_LAYER] = LAYOUT_georgi(  
STN_FN,  STN_S1, STN_TL, STN_PL, STN_HL, STN_ST1,       STN_ST3, STN_FR, STN_PR, STN_LR, STN_TR, STN_DR,
STN_PWR, STN_S2, STN_KL, STN_WL, STN_RL, STN_ST2,       STN_ST4, STN_RR, STN_BR, STN_GR, STN_SR, STN_ZR,
						 STN_N1, STN_A,  STN_O,			STN_E,   STN_U,  STN_N1)
,
// Gaming layer with Numpad, Very limited
[GAMING] = LAYOUT_georgi(  
KC_LSFT, KC_Q, KC_W, KC_E, KC_R, KC_T,       KC_Y,   KC_U, KC_I, KC_O, KC_P,    KC_ENT,
KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G,       KC_H,   KC_J, KC_K, KC_L, KC_SCLN, KC_DQUO,
KC_LALT, KC_SPC, LT(GAMING_2, KC_ENT),	     KC_DEL, KC_ASTR,  TO(STENO_LAYER)), 

[GAMING_2] = LAYOUT_georgi(  
KC_LSFT, KC_1, KC_2, KC_3, KC_4, KC_5,       KC_6, KC_7, KC_8,  KC_9,  KC_0, KC_MINS,
KC_LCTL, KC_Z, KC_X, KC_C, KC_V, KC_B,       KC_N, KC_M, KC_LT, KC_GT, KC_QUES, KC_RSFT,
			  KC_LALT, KC_SPC, KC_ENT,	     KC_DEL, KC_ASTR,  TO(STENO_LAYER))
}; 

int getKeymapCount(void) {
	return sizeof(keymaps)/sizeof(keymaps[0]);
}
    // Main layer, everything goes through here
    [STENO_LAYER] = LAYOUT_georgi(
        STN_FN,  STN_S1,  STN_TL,  STN_PL,  STN_HL,  STN_ST1,       STN_ST3, STN_FR,  STN_PR,  STN_LR,  STN_TR,  STN_DR,
        STN_PWR, STN_S2,  STN_KL,  STN_WL,  STN_RL,  STN_ST2,       STN_ST4, STN_RR,  STN_BR,  STN_GR,  STN_SR,  STN_ZR,
                                   STN_N1,  STN_A,   STN_O,         STN_E,   STN_U,   STN_N7
    ),
    // Gaming layer with Numpad, Very limited
    [GAMING] = LAYOUT_georgi(
        KC_LSFT, KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,                       KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_ENT,
        KC_LCTL, KC_A,    KC_S,    KC_D,    KC_F,    KC_G,                       KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, KC_DQUO,
                                   KC_LALT, KC_SPC,  LT(GAMING_2, KC_ENT),       KC_DEL,  KC_ASTR, TO(STENO_LAYER)
    ),

    [GAMING_2] = LAYOUT_georgi(
        KC_LSFT, KC_1,    KC_2,    KC_3,    KC_4,    KC_5,          KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_MINS,
        KC_LCTL, KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,          KC_N,    KC_M,    KC_LT,   KC_GT,   KC_QUES, KC_RSFT,
                                   KC_LALT, KC_SPC,  KC_ENT,        KC_DEL,  KC_ASTR, TO(STENO_LAYER)
    )
};

// Don't fuck with this, thanks.
size_t keymapsCount  = sizeof(keymaps)/sizeof(keymaps[0]);

M keyboards/georgi/keymaps/default/rules.mk => keyboards/georgi/keymaps/default/rules.mk +23 -9
@@ 1,18 1,23 @@
#----------------------------------------------------------------------------
# make georgi:extrakey:dfu
# make georgi:default:dfu
# Make sure you have dfu-programmer installed!
#----------------------------------------------------------------------------

#Debug options
NO_REPEAT				 = no
VERBOSE					 = yes
CONSOLE_ENABLE			 = yes
DEBUG_MATRIX_SCAN_RATE   = no
DEBUG_MATRIX			 = no
KEYBOARD_SHARED_EP       = yes
CUSTOM_MATRIX			 = yes
MOUSEKEY_ENABLE			 = yes
SINGLE_LAYER			 = no

#Firmware reduction options
MOUSEKEY_ENABLE			 = yes 		# 1500 bytes
NO_TAPPING				 = no 	    # 2000 bytes
NO_PRINT				 = yes		

#Debug options
CONSOLE_ENABLE			 = no
DEBUG_MATRIX_SCAN_RATE   = no
DEBUG_MATRIX			 = no
ONLY_QWERTY				 = no

# A bunch of stuff that you shouldn't touch unless you
# know what you're doing.


@@ 22,6 27,15 @@ SRC += matrix.c i2c_master.c
ifeq ($(strip $(DEBUG_MATRIX)), yes)
    OPT_DEFS += -DDEBUG_MATRIX
endif
ifeq ($(strip $(SINGLE_LAYER)), yes)
    OPT_DEFS += -DSINGLE_LAYER
ifeq ($(strip $(NO_REPEAT)), yes)
    OPT_DEFS += -DNO_REPEAT
endif
ifeq ($(strip $(NO_PRINT)), yes)
    OPT_DEFS += -DNO_PRINT -DNO_DEBUG
endif
ifeq ($(strip $(ONLY_QWERTY)), yes)
    OPT_DEFS += -DONLYQWERTY
endif
ifeq ($(strip $(NO_TAPPING)), yes)
    OPT_DEFS += -DNO_ACTION_TAPPING
endif

A keyboards/georgi/keymaps/minimal/keymap.c => keyboards/georgi/keymaps/minimal/keymap.c +223 -0
@@ 0,0 1,223 @@
/*
 * Good on you for modifying your layout, this is the most nonQMK layout you will come across
 * There are three modes, Steno (the default), QWERTY (Toggleable) and a Momentary symbol layer
 *
 * Don't modify the steno layer directly, instead add chords using the keycodes and macros
 * from sten.h to the layout you want to modify.
 *
 * Observe the comment above processQWERTY!
 *
 * http://docs.gboards.ca
 */

#include QMK_KEYBOARD_H
#include "sten.h"
#include "keymap_steno.h"
#define IGNORE_MOD_TAP_INTERRUPT

// Proper Layers
#define FUNCT   (LSD | LK | LP | LH)
#define MEDIA   (LSD | LK | LW | LR)
#define MOVE    (ST1 | ST2)

// QMK Layers
#define STENO_LAYER   0

/* Keyboard Layout
 * ,---------------------------------.    ,------------------------------.
 * | FN  | LSU | LFT | LP | LH | ST1 |    | ST3 | RF | RP | RL | RT | RD |
 * |-----+-----+-----+----+----|-----|    |-----|----+----+----+----+----|
 * | PWR | LSD | LK  | LW | LR | ST2 |    | ST4 | RR | BB | RG | RS | RZ |
 * `---------------------------------'    `------------------------------'
 *                   ,---------------,    .---------------.
 *                   | LNO | LA | LO |    | RE | RU | RNO |
 *                   `---------------'    `---------------'
 */

// Note: You can only use basic keycodes here!
// P() is just a wrapper to make your life easier.
//
// http://docs.gboards.ca
uint32_t processQwerty(bool lookup) {
    // Specials
    P( RT  | RS  | RD  | RZ | LNO,        SEND_STRING(VERSION); SEND_STRING(__DATE__));
    P( LNO | RNO | LA  | LO | RE | RU,    SEND(KC_MPLY));
    P( LFT | LK  | LP  | LW,              REPEAT());
    P( ST1 | ST2 | LW  | ST4,             SEND(KC_BSPC));

    // Mouse Keys
    P( LO  | LSD | LK,    CLICK_MOUSE(KC_MS_BTN2));
    P( LO  | LR  | LW,    CLICK_MOUSE(KC_MS_BTN1));

    // Thumb Chords
    P( LA  | LO  | RE  | RU,    SEND(KC_CAPS));
    P( LA  | RU,                SEND(KC_ESC));
    P( LO  | RE,                SEND(KC_LCTL));
    P( LNO | RNO | LA | RU,     SEND(KC_LCTL); SEND(KC_LSFT));
    P( LNO | LA  | RE,          SEND(KC_LCTL); SEND(KC_LSFT); SEND(KC_LALT));

    // Mods
    P( RT | RD   | RS | RZ,    SEND(KC_LGUI));
    P( RT | RD,                SEND(KC_LCTL));
    P( RS | RZ,                SEND(KC_LALT));
    P( LA | LNO,               SEND(KC_LCTL));
    P( LA | LO,                SEND(KC_LALT));
    P( LO,                     SEND(KC_LSFT));

    // Function Layer
    P( FUNCT | RF | RR,    SEND(KC_F5));
    P( FUNCT | RP | RB,    SEND(KC_F6));
    P( FUNCT | RL | RG,    SEND(KC_F7));
    P( FUNCT | RT | RS,    SEND(KC_F8));
    P( FUNCT | RF,         SEND(KC_F1));
    P( FUNCT | RP,         SEND(KC_F2));
    P( FUNCT | RL,         SEND(KC_F3));
    P( FUNCT | RT,         SEND(KC_F4));
    P( FUNCT | RR,         SEND(KC_F9));
    P( FUNCT | RG,         SEND(KC_F10));
    P( FUNCT | RB,         SEND(KC_F11));
    P( FUNCT | RS,         SEND(KC_F12));

    // Movement Layer
    P( MOVE | RF,     SEND(KC_LEFT));
    P( MOVE | RP,     SEND(KC_DOWN));
    P( MOVE | RL,     SEND(KC_UP));
    P( MOVE | RT,     SEND(KC_RIGHT));
    P( MOVE | ST3,    SEND(KC_PGUP));
    P( MOVE | ST4,    SEND(KC_PGDN));

    // Media Layer
    P( MEDIA | RF,    SEND(KC_MPRV));
    P( MEDIA | RP,    SEND(KC_MPLY));
    P( MEDIA | RL,    SEND(KC_MPLY));
    P( MEDIA | RT,    SEND(KC_MNXT));
    P( MEDIA | RD,    SEND(KC_VOLU));
    P( MEDIA | RZ,    SEND(KC_VOLD));
    P( MEDIA | RS,    SEND(KC_MUTE));

    // Number Row, Left
    P( LNO | LSU,    SEND(KC_1));
    P( LNO | LFT,    SEND(KC_2));
    P( LNO | LP,     SEND(KC_3));
    P( LNO | LH,     SEND(KC_4));
    P( LNO | ST1,    SEND(KC_5));
    P( LNO | ST3,    SEND(KC_6));
    P( LNO | RF,     SEND(KC_7));
    P( LNO | RP,     SEND(KC_8));
    P( LNO | RL,     SEND(KC_9));
    P( LNO | RT,     SEND(KC_0));

    // Number Row, Right
    P( RNO | LSU,    SEND(KC_1));
    P( RNO | LFT,    SEND(KC_2));
    P( RNO | LP,     SEND(KC_3));
    P( RNO | LH,     SEND(KC_4));
    P( RNO | ST1,    SEND(KC_5));
    P( RNO | ST3,    SEND(KC_6));
    P( RNO | RF,     SEND(KC_7));
    P( RNO | RP,     SEND(KC_8));
    P( RNO | RL,     SEND(KC_9));
    P( RNO | RT,     SEND(KC_0));
    P( RNO | LA,     SEND(KC_5));

    // Specials
    P( RU | RNO,    SEND(KC_TAB));
    P( RE | RU,     SEND(KC_BSPC));
    P( RD | RZ,     SEND(KC_ENT));
    P( RE,          SEND(KC_ENT));
    P( RD,          SEND(KC_BSPC));
    P( LNO,         SEND(KC_BSPC));
    P( RNO,         SEND(KC_BSPC));
    P( LA,          SEND(KC_SPC));
    P( RU,          SEND(KC_SPC));
    P( RZ,          SEND(KC_ESC));

    // Symbols and Numbers
    P( PWR | RE | RU,      SEND(KC_ENT));
    P( PWR | LA | LO,      SEND(KC_SPC));
    P( PWR | LP | LW,      SEND(KC_LSFT); SEND(KC_9));       // (
    P( PWR | LH | LR,      SEND(KC_LSFT); SEND(KC_0));       // )
    P( PWR | ST1 | ST2,    SEND(KC_GRV));                    // `
    P( PWR | RD | RZ,      SEND(KC_ESC));
    P( PWR | LSU | LSD,    SEND(KC_LSFT); SEND(KC_3));       // #
    P( PWR | LFT | LK,     SEND(KC_LSFT); SEND(KC_4));       // $
    P( PWR | LSU,          SEND(KC_LSFT); SEND(KC_1));       // !
    P( PWR | LSD,          SEND(KC_LSFT); SEND(KC_5));       // %
    P( PWR | LFT,          SEND(KC_LSFT); SEND(KC_2));       // @
    P( PWR | LK,           SEND(KC_LSFT); SEND(KC_6));       // ^
    P( PWR | LP,           SEND(KC_LSFT); SEND(KC_LBRC));    // {
    P( PWR | LW,           SEND(KC_LBRC));
    P( PWR | LH,           SEND(KC_LSFT); SEND(KC_RBRC));    // }
    P( PWR | LR,           SEND(KC_RBRC));
    P( PWR | ST1,          SEND(KC_LSFT); SEND(KC_BSLS));    // |
    P( PWR | ST2,          SEND(KC_LSFT); SEND(KC_GRV));     // ~
    P( PWR | ST3,          SEND(KC_QUOT));
    P( PWR | ST4,          SEND(KC_LSFT); SEND(KC_QUOT));    // "
    P( PWR | RF,           SEND(KC_KP_PLUS));
    P( PWR | RR,           SEND(KC_LSFT); SEND(KC_7));       // &
    P( PWR | RP,           SEND(KC_MINS));
    P( PWR | RB,           SEND(KC_EQL));
    P( PWR | RL,           SEND(KC_SLSH));
    P( PWR | RG,           SEND(KC_COMM));
    P( PWR | RT,           SEND(KC_PAST));
    P( PWR | RS,           SEND(KC_DOT));
    P( PWR | RD,           SEND(KC_TAB));
    P( PWR | LA,           SEND(KC_LSFT));
    P( PWR | LO,           SEND(KC_SLSH));
    P( PWR | RE,           SEND(KC_SCLN));
    P( PWR | RU,           SEND(KC_BSLS));
    P( PWR | LNO,          SEND(KC_BSLS));

    // Letters
    P( LSU | LSD,    SEND(KC_A));
    P( LFT | LK,     SEND(KC_S));
    P( LP  | LW,     SEND(KC_D));
    P( LH  | LR,     SEND(KC_F));
    P( ST1 | ST2,    SEND(KC_G));
    P( ST3 | ST4,    SEND(KC_H));
    P( RF  | RR,     SEND(KC_J));
    P( RT  | RS,     SEND(KC_SCLN));
    P( RG  | RL,     SEND(KC_L));
    P( RP  | RB,     SEND(KC_K));
    P( LSU,          SEND(KC_Q));
    P( LSD,          SEND(KC_Z));
    P( LFT,          SEND(KC_W));
    P( LK,           SEND(KC_X));
    P( LP,           SEND(KC_E));
    P( LW,           SEND(KC_C));
    P( LH,           SEND(KC_R));
    P( LR,           SEND(KC_V));
    P( ST1,          SEND(KC_T));
    P( ST2,          SEND(KC_B));
    P( ST3,          SEND(KC_Y));
    P( ST4,          SEND(KC_N));
    P( RF,           SEND(KC_U));
    P( RR,           SEND(KC_M));
    P( RP,           SEND(KC_I));
    P( RB,           SEND(KC_COMM));
    P( RL,           SEND(KC_O));
    P( RG,           SEND(KC_DOT));
    P( RT,           SEND(KC_P));
    P( RS,           SEND(KC_SLSH));
    P( RNO,          SEND(KC_BSPC));
    P( LNO,          SEND(KC_BSPC));

    return 0;
}

// "Layers"
// Steno layer should be first in your map.
// When PWR | FN | ST3 | ST4 is pressed, the layer is increased to the next map. You must return to STENO_LAYER at the end.
// If you need more space for chords, remove the two gaming layers.
// Note: If using NO_ACTION_TAPPING, LT will not work!

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    // Main layer, everything goes through here
    [STENO_LAYER] = LAYOUT_georgi(
    STN_FN,  STN_S1,  STN_TL,  STN_PL,  STN_HL,  STN_ST1,       STN_ST3, STN_FR,  STN_PR,  STN_LR,  STN_TR,  STN_DR,
    STN_PWR, STN_S2,  STN_KL,  STN_WL,  STN_RL,  STN_ST2,       STN_ST4, STN_RR,  STN_BR,  STN_GR,  STN_SR,  STN_ZR,
                               STN_N1,  STN_A,   STN_O,         STN_E,   STN_U,  STN_N7
    )
};
// Don't fuck with this, thanks.
size_t keymapsCount  = sizeof(keymaps)/sizeof(keymaps[0]);

A keyboards/georgi/keymaps/minimal/readme.md => keyboards/georgi/keymaps/minimal/readme.md +11 -0
@@ 0,0 1,11 @@
# Georgi QWERTY/Steno firmware

This is the default keymap for Georgi, it's based heavily off of the naps62 ErgoDox and the Gergo layout. 
It is both a ergonomic and programmer friendly keymap.

Ideally you should copy this directory and make your changes there. If you come up with a good layout submit a PR!

## Space issues
If you find yourself running out of space for dictionary entries, disabling mousekeys in rules.mk will save
you about 4k for entries!
Get a free 1k by deleting the Gaming layers from the keymap!

A keyboards/georgi/keymaps/minimal/rules.mk => keyboards/georgi/keymaps/minimal/rules.mk +41 -0
@@ 0,0 1,41 @@
#----------------------------------------------------------------------------
# make georgi:default:dfu
# Make sure you have dfu-programmer installed!
#----------------------------------------------------------------------------

NO_REPEAT				 = no
VERBOSE					 = yes
KEYBOARD_SHARED_EP       = yes
CUSTOM_MATRIX			 = yes

#Firmware reduction options
MOUSEKEY_ENABLE			 = no 		# 1500 bytes
NO_TAPPING				 = yes		# 2000 bytes
NO_PRINT				 = yes		

#Debug options
CONSOLE_ENABLE			 = no
DEBUG_MATRIX_SCAN_RATE   = no
DEBUG_MATRIX			 = no
ONLY_QWERTY				 = no

# A bunch of stuff that you shouldn't touch unless you
# know what you're doing.
#
# No touchy, capiche?
SRC += matrix.c i2c_master.c
ifeq ($(strip $(DEBUG_MATRIX)), yes)
    OPT_DEFS += -DDEBUG_MATRIX
endif
ifeq ($(strip $(NO_REPEAT)), yes)
    OPT_DEFS += -DNO_REPEAT
endif
ifeq ($(strip $(NO_PRINT)), yes)
    OPT_DEFS += -DNO_PRINT -DNO_DEBUG
endif
ifeq ($(strip $(ONLY_QWERTY)), yes)
    OPT_DEFS += -DONLYQWERTY
endif
ifeq ($(strip $(NO_TAPPING)), yes)
    OPT_DEFS += -DNO_ACTION_TAPPING
endif

A keyboards/georgi/keymaps/norman/keymap.c => keyboards/georgi/keymaps/norman/keymap.c +267 -0
@@ 0,0 1,267 @@
/*
 * Good on you for modifying your layout, this is the most nonQMK layout you will come across
 * There are three modes, Steno (the default), QWERTY (Toggleable) and a Momentary symbol layer
 *
 * Don't modify the steno layer directly, instead add chords using the keycodes and macros
 * from sten.h to the layout you want to modify.
 *
 * Observe the comment above processQWERTY!
 *
 * http://docs.gboards.ca
 */

#include QMK_KEYBOARD_H
#include "sten.h"
#include "keymap_steno.h"
#define IGNORE_MOD_TAP_INTERRUPT

// Proper Layers
#define FUNCT   (LSD | LK | LP | LH)
#define MEDIA   (LSD | LK | LW | LR)
#define MOVE    (LH | ST2)

/* Keyboard Layout
 * ,---------------------------------.    ,------------------------------.
 * | FN  | LSU | LFT | LP | LH | ST1 |    | ST3 | RF | RP | RL | RT | RD |
 * |-----+-----+-----+----+----|-----|    |-----|----+----+----+----+----|
 * | PWR | LSD | LK  | LW | LR | ST2 |    | ST4 | RR | RB | RG | RS | RZ |
 * `---------------------------------'    `------------------------------'
 *                   ,---------------,    .---------------.
 *                   | LNO | LA | LO |    | RE | RU | RNO |
 *                   `---------------'    `---------------'
 */

// YOU MUST ORDER THIS!
// Order your chords from longest to shortest!
// You can only use basic keycodes here!
//
// P() is just a wrapper to make your life easier.
//
// http://docs.gboards.ca
uint32_t processQwerty(bool lookup) {
	// Specials
	P( RT  | RS  | RD  | RZ | LNO,		SEND_STRING(VERSION); SEND_STRING(__DATE__));
	P( LNO | LA  | LO  | RE | RU,		SEND(KC_MPLY));
	P( ST1 | ST2 | ST3 | ST4,			SEND(KC_BSPC));

	// Thumb Chords
	P(  LA  | LO  | RE  | RU,			SEND(KC_CAPS));
	P(  LA  | RU,						SEND(KC_ESC));
	P( LO  | RE,						SEND(KC_LCTL));
	P( LNO | LA | RU,					SEND(KC_LCTL); SEND(KC_LSFT));
	P( LNO | LA | RE,					SEND(KC_LCTL); SEND(KC_LSFT); SEND(KC_LALT));

	// Mods
	P( RT | RD | RS | RZ,				SEND(KC_LGUI));
	P( RT | RD,						SEND(KC_LCTL));
	P( RS | RZ,						SEND(KC_LALT));
	P( LA | LNO,						SEND(KC_LCTL));
	P( LA | LO,						SEND(KC_LALT));
	P( LO,								SEND(KC_LSFT));

	// Function Layer
	P( FUNCT | RF | RR,					SEND(KC_F6));
	P( FUNCT | RP | RB,					SEND(KC_F7));
	P( FUNCT | RL | RG,					SEND(KC_F8));
	P( FUNCT | ST3 | ST4,				SEND(KC_F5));
  P( FUNCT| ST3,              SEND(KC_F1));
  P( FUNCT| ST4,              SEND(KC_F9));
	P( FUNCT | RF,						SEND(KC_F2));
	P( FUNCT | RP,						SEND(KC_F3));
	P( FUNCT | RL,						SEND(KC_F4));
	P( FUNCT | RR,						SEND(KC_F10));
	P( FUNCT | RG,						SEND(KC_F12));
	P( FUNCT | RB,						SEND(KC_F11));
  P( FUNCT | RD,            SEND(KC_RALT); SEND(KC_T); SEND(KC_H); SEND(KC_U); SEND(KC_P));
  P( FUNCT | RZ,            SEND(KC_RALT); SEND(KC_T); SEND(KC_H); SEND(KC_D); SEND(KC_N));
  P( FUNCT | RT,            SEND(KC_RALT); SEND(KC_S); SEND(KC_F));
  P( FUNCT | RS,            SEND(KC_LALT); SEND(KC_SPC));
  P( FUNCT | RE,            SEND(KC_LCTL); SEND(KC_LSFT); SEND(KC_ESC));
  P( FUNCT | RU,            SEND(KC_LCTL); SEND(KC_LSFT); SEND(KC_0));

	// Movement Layer
	P( MOVE | RF,						 SEND(KC_LGUI); SEND(KC_LSFT); SEND(KC_LEFT));
	P( MOVE | RP,						SEND(KC_UP));
	P( MOVE | RL,						SEND(KC_LGUI); SEND(KC_LSFT); SEND(KC_RGHT));
	P( MOVE | RT,						SEND(KC_LALT); SEND(KC_LCTL); SEND(KC_LGUI); SEND(KC_C));
	P( MOVE | ST3,						SEND(KC_PGUP));
	P( MOVE | ST4,						SEND(KC_PGDN));
  P( MOVE | RD,           SEND(KC_HOME));
  P( MOVE | RZ,           SEND(KC_END));
  P( MOVE | RG,            SEND(KC_RIGHT));
  P( MOVE | RB,            SEND(KC_DOWN));
  P( MOVE | RR,            SEND(KC_LEFT));
  P( MOVE | RS,            SEND(KC_LSFT); SEND(KC_LCTL); SEND(KC_LGUI); SEND(KC_T));
  P( MOVE | RE,            SEND(KC_LSFT); SEND(KC_LALT); SEND(KC_LGUI); SEND(KC_S));
  P( MOVE | RU,            SEND(KC_LSFT); SEND(KC_LCTL); SEND(KC_1));


	// Media Layer
	P( MEDIA | RF,						SEND(KC_MEDIA_PREV_TRACK));
	P( MEDIA | RP,						SEND(KC_MPLY));
	P( MEDIA | RL,						SEND(KC_MPLY));
	P( MEDIA | RT,						SEND(KC_MEDIA_NEXT_TRACK));
	P( MEDIA | RD,						SEND(KC_VOLU));
	P( MEDIA | RZ,						SEND(KC_VOLD));
	P( MEDIA | RS,						SEND(KC_MUTE));
  P( MEDIA | ST3,           SEND(KC_LALT); SEND(KC_LCTL); SEND(KC_LGUI); SEND(KC_4));
  P( MEDIA | ST4,           SEND(KC_LALT); SEND(KC_LCTL); SEND(KC_LGUI); SEND(KC_2));
  P( MEDIA | RR,            SEND(KC_LALT); SEND(KC_LCTL); SEND(KC_LGUI); SEND(KC_3));
  P( MEDIA | RB,            SEND(KC_LCTL); SEND(KC_LSFT); SEND(KC_GRV));
  P( MEDIA | RG,            SEND(KC_LCTL); SEND(KC_LSFT); SEND(KC_8));
  P( MEDIA | RE,            SEND(KC_RALT); SEND(KC_F); SEND(KC_I); SEND(KC_R); SEND(KC_E));
  P( MEDIA | RU,            SEND(KC_RALT); SEND(KC_T); SEND(KC_A); SEND(KC_D));

	// Mouse Keys and Printscreen
	P( LFT | LH,							CLICK_MOUSE(KC_MS_BTN1));
	P( LK | LR,							CLICK_MOUSE(KC_MS_BTN2));
	P( RF | RT,							SEND(KC_PSCR););

	// Number Row Left
	P( LNO | LSU,						SEND(KC_1));
	P( LNO | LFT,						SEND(KC_2));
	P( LNO | LP,						SEND(KC_3));
	P( LNO | LH,						SEND(KC_4));
	P( LNO | ST1,						SEND(KC_5));
	P( LNO | ST3,						SEND(KC_6));
	P( LNO | RF,						SEND(KC_7));
	P( LNO | RP,						SEND(KC_8));
	P( LNO | RL,						SEND(KC_9));
	P( LNO | RT,						SEND(KC_0));
	P( LNO | LA,						SEND(KC_5));
	P( LNO | RT,						SEND(KC_0));

  // Number Row Right
	P( RNO | LSU,						SEND(KC_1));
	P( RNO | LFT,						SEND(KC_2));
	P( RNO | LP,						SEND(KC_3));
	P( RNO | LH,						SEND(KC_4));
	P( RNO | ST1,						SEND(KC_5));
	P( RNO | ST3,						SEND(KC_6));
	P( RNO | RF,						SEND(KC_7));
	P( RNO | RP,						SEND(KC_8));
	P( RNO | RL,						SEND(KC_9));
	P( RNO | RT,						SEND(KC_0));
	P( RNO | LA,						SEND(KC_5));
	P( RNO | RT,						SEND(KC_0));

	// Specials
	P( LA | LNO,						SEND(KC_ESC));
	P( RU | RNO,						SEND(KC_TAB));
	P( RE | RU,							SEND(KC_LSFT); SEND(KC_SLSH));
	P( RD | RZ,							SEND(KC_ENT));
	P( RE,								SEND(KC_ENT));
	//P( RD,								SEND(KC_BSPC));
	P( LNO,								SEND(KC_BSPC));
  P( RD,								SEND(KC_DEL));
	P( LA,								SEND(KC_SPC));
	P( RU,								SEND(KC_SPC));
	P( RZ,								SEND(KC_ESC));
  //P( RNO,               REPEAT());

	// Letters
	P( LSU | LSD,						SEND(KC_A));
	P( LFT | LK,						SEND(KC_S));
	P( LP  | LW,						SEND(KC_E));
	P( LH  | LR,						SEND(KC_T));
	P( ST1 | ST2,						SEND(KC_G));
	P( ST3 | ST4,						SEND(KC_Y));
	P( RF  | RR,						SEND(KC_N));
	P( RT  | RS,						SEND(KC_H))
	P( RG  | RL,						SEND(KC_O));
	P( RP  | RB,						SEND(KC_I));
	P( LSU,								SEND(KC_Q));
	P( LSD,								SEND(KC_Z));
	P( LFT,								SEND(KC_W));
	P( LK,								SEND(KC_X));
	P( LP,								SEND(KC_D));
	P( LW,								SEND(KC_C));
	P( LH,								SEND(KC_F));
	P( LR,								SEND(KC_V));
	P( ST1,								SEND(KC_K));
	P( ST2,								SEND(KC_B));
	P( ST3,								SEND(KC_J));
	P( ST4,								SEND(KC_P));
	P( RF,								SEND(KC_U));
	P( RR,								SEND(KC_M));
	P( RP,								SEND(KC_R));
	P( RB,								SEND(KC_COMM));
	P( RL,								SEND(KC_L));
	P( RG,								SEND(KC_DOT));
	P( RT,								SEND(KC_SCLN));
	P( RS,								SEND(KC_SLSH));

	// Symbols and Numbers
	P( PWR | RE | RU,					SEND(KC_ENT));
	P( PWR | LA | LO,					SEND(KC_SPC));
	P( PWR | LP | LW,					SEND(KC_LSFT); SEND(KC_9));			// (
	P( PWR | LH | LR,					SEND(KC_LSFT); SEND(KC_0));			// )
	P( PWR | ST1 | ST2,					SEND(KC_GRV));						// `
	P( PWR | RD | RZ,					SEND(KC_ESC));
	P( PWR | LSU | LSD,					SEND(KC_LSFT); SEND(KC_3));			// #
	P( PWR | LFT | LK,					SEND(KC_LSFT); SEND(KC_4));			// $
	P( PWR | LSU,						SEND(KC_LSFT); SEND(KC_1));			// !
	P( PWR | LSD,						SEND(KC_LSFT); SEND(KC_5));			// %
	P( PWR | LFT,						SEND(KC_LSFT); SEND(KC_2));			// @
	P( PWR | LK,						SEND(KC_LSFT); SEND(KC_6));			// ^
	P( PWR | LP,						SEND(KC_LSFT); SEND(KC_LBRC));		// {
	P( PWR | LW,						SEND(KC_LBRC));
	P( PWR | LH,						SEND(KC_LSFT); SEND(KC_RBRC));		// }
	P( PWR | LR,						SEND(KC_RBRC));
	P( PWR | ST1,						SEND(KC_LSFT); SEND(KC_BSLS));		// |
	P( PWR | ST2,						SEND(KC_LSFT); SEND(KC_GRV));		// ~
	P( PWR | ST3,						SEND(KC_QUOT));
	P( PWR | ST4,						SEND(KC_LSFT); SEND(KC_QUOT));		// "
	P( PWR | RF,						SEND(KC_KP_PLUS));
	P( PWR | RR,						SEND(KC_LSFT); SEND(KC_7));			// &
	P( PWR | RP,						SEND(KC_MINS));
	P( PWR | RB,						SEND(KC_EQL));
	P( PWR | RL,						SEND(KC_SLSH));
	P( PWR | RG,						SEND(KC_LSFT); SEND(KC_MINS));
	P( PWR | RT,						SEND(KC_PAST));
	P( PWR | RS,						SEND(KC_DOT));
	P( PWR | RD,						SEND(KC_TAB));
	P( PWR | LA,						SEND(KC_LSFT); SEND(KC_SCLN));
	P( PWR | LO,						SEND(KC_BSLS));
	P( PWR | RE,						SEND(KC_SCLN));
	P( PWR | RU,						SEND(KC_BSLS));
  P( PWR | RZ,						SEND(KC_LSFT));

	return 0;
}

#define STENO_LAYER		0
#define GAMING			1
#define GAMING_2		2
#define MOVEMENT    3

// "Layers"
// Steno layer should be first in your map.
// When PWR | FN | ST3 | ST4 is pressed, the layer is increased to the next map. You must return to STENO_LAYER at the end.
// If you need more space for chords, remove the two gaming layers.

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Main layer, everything goes through here
[STENO_LAYER] = LAYOUT_georgi(
STN_FN,  STN_S1, STN_TL, STN_PL, STN_HL, STN_ST1,       STN_ST3, STN_FR, STN_PR, STN_LR, STN_TR, STN_DR,
STN_PWR, STN_S2, STN_KL, STN_WL, STN_RL, STN_ST2,       STN_ST4, STN_RR, STN_BR, STN_GR, STN_SR, STN_ZR,
						 STN_N1, STN_A,  STN_O,			STN_E,   STN_U,  STN_N7)
,
// Gaming layer with Numpad, Very limited
[GAMING] = LAYOUT_georgi(
KC_LSFT, KC_Q, KC_W, KC_E, KC_R, KC_T,       KC_Y,   KC_U, KC_I, KC_O, KC_P,    KC_ENT,
KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G,       KC_H,   KC_J, KC_K, KC_L, KC_SCLN, KC_DQUO,
KC_LALT, KC_SPC, LT(GAMING_2, KC_ENT),	     KC_DEL, KC_ASTR,  TO(STENO_LAYER)),

[GAMING_2] = LAYOUT_georgi(
KC_LSFT, KC_1, KC_2, KC_3, KC_4, KC_5,       KC_6, KC_7, KC_8,  KC_9,  KC_0, KC_MINS,
KC_LCTL, KC_Z, KC_X, KC_C, KC_V, KC_B,       KC_N, KC_M, KC_LT, KC_GT, KC_QUES, KC_RSFT,
			  KC_LALT, KC_SPC, KC_NO,	             KC_DEL, KC_ASTR,  TO(STENO_LAYER)),

[MOVEMENT] = LAYOUT_georgi(
KC_TRNS, KC_TRNS, KC_TRNS,  KC_TRNS, KC_TRNS,KC_TRNS,       KC_PGUP, KC_TRNS, KC_UP,   KC_TRNS,  KC_TRNS, KC_HOME,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,       KC_PGDN, KC_LEFT, KC_DOWN, KC_RIGHT, KC_TRNS, KC_END,
			  KC_TRNS, KC_TRNS, KC_TRNS,	                        KC_TRNS, KC_TRNS, KC_TRNS)
};
// Don't fuck with this, thanks.
size_t keymapsCount  = sizeof(keymaps)/sizeof(keymaps[0]);

A keyboards/georgi/keymaps/norman/readme.md => keyboards/georgi/keymaps/norman/readme.md +11 -0
@@ 0,0 1,11 @@
# Georgi QWERTY/Steno firmware

This is the default keymap for Georgi, it's based heavily off of the naps62 ErgoDox and the Gergo layout. 
It is both a ergonomic and programmer friendly keymap.

Ideally you should copy this directory and make your changes there. If you come up with a good layout submit a PR!

## Space issues
If you find yourself running out of space for dictionary entries, disabling mousekeys in rules.mk will save
you about 4k for entries!
Get a free 1k by deleting the Gaming layers from the keymap!

R keyboards/georgi/keymaps/template/rules.mk => keyboards/georgi/keymaps/norman/rules.mk +17 -9
@@ 1,18 1,20 @@
#----------------------------------------------------------------------------
# make georgi:extrakey:dfu
# make georgi:default:dfu
# Make sure you have dfu-programmer installed!
#----------------------------------------------------------------------------

#Debug options
NO_REPEAT				 = yes
VERBOSE					 = yes
CONSOLE_ENABLE			 = yes
DEBUG_MATRIX_SCAN_RATE   = no
DEBUG_MATRIX			 = no
KEYBOARD_SHARED_EP       = yes
CUSTOM_MATRIX			 = yes
MOUSEKEY_ENABLE			 = no
SINGLE_LAYER			 = no
MOUSEKEY_ENABLE			 = yes

#Debug options
CONSOLE_ENABLE			 = no
DEBUG_MATRIX_SCAN_RATE   = no
DEBUG_MATRIX			 = no
NO_PRINT				 = yes
ONLY_QWERTY				 = no

# A bunch of stuff that you shouldn't touch unless you
# know what you're doing.


@@ 22,6 24,12 @@ SRC += matrix.c i2c_master.c
ifeq ($(strip $(DEBUG_MATRIX)), yes)
    OPT_DEFS += -DDEBUG_MATRIX
endif
ifeq ($(strip $(SINGLE_LAYER)), yes)
    OPT_DEFS += -DSINGLE_LAYER
ifeq ($(strip $(NO_REPEAT)), yes)
    OPT_DEFS += -DNO_REPEAT
endif
ifeq ($(strip $(NO_PRINT)), yes)
    OPT_DEFS += -DNO_PRINT -DNO_DEBUG
endif
ifeq ($(strip $(ONLY_QWERTY)), yes)
    OPT_DEFS += -DONLYQWERTY
endif

D keyboards/georgi/keymaps/template/keymap.c => keyboards/georgi/keymaps/template/keymap.c +0 -216
@@ 1,216 0,0 @@
/* 
 * Good on you for modifying your layout, this is the most nonQMK layout you will come across
 * There are three modes, Steno (the default), QWERTY (Toggleable) and a Momentary symbol layer
 *
 * Don't modify the steno layer directly, instead add chords using the keycodes and macros
 * from sten.h to the layout you want to modify.
 *
 * Observe the comment above processQWERTY!
 *
 * http://docs.gboards.ca
 */

#include QMK_KEYBOARD_H
#include "sten.h"
#include "keymap_steno.h"
#define IGNORE_MOD_TAP_INTERRUPT

int getKeymapCount(void);

// Proper Layers
#define FUNCT   (LSD | LK | LP | LH)
#define MEDIA   (LSD | LK | LW | LR)
#define MOVE    (ST1 | ST2)

/* Keyboard Layout
 * ,---------------------------------.    ,------------------------------.
 * | FN  | LSU | LFT | LP | LH | ST1 |    | ST3 | RF | RP | RL | RT | RD |
 * |-----+-----+-----+----+----|-----|    |-----|----+----+----+----+----|
 * | PWR | LSD | LK  | LW | LR | ST2 |    | ST4 | RR | RG | RB | RS | RZ |
 * `---------------------------------'    `------------------------------'
 *                   ,---------------,    .---------------.
 *                   | NUM | LA | LO |    | RE | RU | NUM |
 *                   `---------------'    `---------------'
 */

// YOU MUST ORDER THIS!
// P   Will return from processing on the first match it finds. Therefore
// PJ  Will run the requested action, remove the matched chord and continue 
//
// First any chords that would conflict with PJs need to be checked, then PJs, lastly Ps.
// For all chords should be ordered by length in their section!
//
// http://docs.gboards.ca
bool processQwerty(void) {
	// Place P's that would be trashed by PJ's here
	P( RT  | RS  | RD  | RZ | NUM,		SEND_STRING(VERSION); SEND_STRING(__DATE__));
	P( NUM | LA  | LO  | RE | RU,		SEND(KC_MPLY));
	P( ST1 | ST2 | ST3 | ST4,			SEND(KC_BSPC));

	// Thumb Chords
	P(  LA  | LO  | RE  | RU,			SEND(KC_CAPS));
	P(  LA  | RU,						SEND(KC_ESC));
	PJ( LO  | RE,						SEND(KC_LCTL));
	PJ( NUM | LA | RU,					SEND(KC_LCTL); SEND(KC_LSFT));
	PJ( NUM | LA | RE,					SEND(KC_LCTL); SEND(KC_LSFT); SEND(KC_LALT));
	
	// Mods 
	PJ( RT | RD | RS | RZ,				SEND(KC_LGUI));
	PJ( RT | RD,						SEND(KC_LCTL));
	PJ( RS | RZ,						SEND(KC_LALT));
	PJ( LA | NUM,						SEND(KC_LCTL));
	PJ( LA | LO,						SEND(KC_LALT));
	PJ( LO,								SEND(KC_LSFT));

	// Function Layer 
	P( FUNCT | RF | RR,					SEND(KC_F5));
	P( FUNCT | RP | RB,					SEND(KC_F6));
	P( FUNCT | RL | RG,					SEND(KC_F7));
	P( FUNCT | RT | RS,					SEND(KC_F8));
	P( FUNCT | RF,						SEND(KC_F1));
	P( FUNCT | RP,						SEND(KC_F2));
	P( FUNCT | RL,						SEND(KC_F3));
	P( FUNCT | RT,						SEND(KC_F4));
	P( FUNCT | RR,						SEND(KC_F9));
	P( FUNCT | RG,						SEND(KC_F10));
	P( FUNCT | RB,						SEND(KC_F11));
	P( FUNCT | RS,						SEND(KC_F12));

	// Movement Layer
	P( MOVE | RF,						SEND(KC_LEFT));
	P( MOVE | RP,						SEND(KC_DOWN));
	P( MOVE | RL,						SEND(KC_UP));
	P( MOVE | RT,						SEND(KC_RIGHT));
	P( MOVE | ST3,						SEND(KC_PGUP));
	P( MOVE | ST4,						SEND(KC_PGDN));

	// Media Layer
	P( MEDIA | RF,						SEND(KC_MPRV));
	P( MEDIA | RP,						SEND(KC_MPLY));
	P( MEDIA | RL,						SEND(KC_MPLY));
	P( MEDIA | RT,						SEND(KC_MNXT));
	P( MEDIA | RD,						SEND(KC_VOLU));
	P( MEDIA | RZ,						SEND(KC_VOLD));
	P( MEDIA | RS,						SEND(KC_MUTE));

	// Mouse Keys
	P( LP | LH,							clickMouse(KC_MS_BTN1));
	P( LW | LR,							clickMouse(KC_MS_BTN2));
	
	// Number Row
	P( NUM | LSU,						SEND(KC_1));
	P( NUM | LFT,						SEND(KC_2));
	P( NUM | LP,						SEND(KC_3));
	P( NUM | LH,						SEND(KC_4));
	P( NUM | ST1,						SEND(KC_5));
	P( NUM | ST3,						SEND(KC_6));
	P( NUM | RF,						SEND(KC_7));
	P( NUM | RP,						SEND(KC_8));
	P( NUM | RL,						SEND(KC_9));
	P( NUM | RT,						SEND(KC_0));
	P( NUM | LA,						SEND(KC_5));
	P( NUM | RT,						SEND(KC_0));
	
	// Specials
	P( LA | NUM,						SEND(KC_ESC));
	P( RU | NUM,						SEND(KC_TAB));
	P( RE | RU,							SEND(KC_BSPC));
	P( RD | RZ,							SEND(KC_ENT));
	P( RE,								SEND(KC_ENT));
	P( RD,								SEND(KC_BSPC));	
	P( NUM,								SEND(KC_BSPC));
	P( LA,								SEND(KC_SPC));
	P( RU,								SEND(KC_SPC));
	P( RZ,								SEND(KC_ESC));

	// Letters
	P( LSU | LSD,						SEND(KC_A));
	P( LFT | LK,						SEND(KC_S));
	P( LP  | LW,						SEND(KC_D));
	P( LH  | LR,						SEND(KC_F));
	P( ST1 | ST2,						SEND(KC_G));
	P( ST3 | ST4,						SEND(KC_H));
	P( RF  | RR,						SEND(KC_J));
	P( RT  | RS,						SEND(KC_SCLN))
	P( RG  | RL,						SEND(KC_L));
	P( RP  | RB,						SEND(KC_K));
	P( LSU,								SEND(KC_Q));
	P( LSD,								SEND(KC_Z));
	P( LFT,								SEND(KC_W));
	P( LK,								SEND(KC_X));
	P( LP,								SEND(KC_E));
	P( LW,								SEND(KC_C));
	P( LH,								SEND(KC_R));
	P( LR,								SEND(KC_V));
	P( ST1,								SEND(KC_T));
	P( ST2,								SEND(KC_B));
	P( ST3,								SEND(KC_Y));
	P( ST4,								SEND(KC_N));
	P( RF,								SEND(KC_U));
	P( RR,								SEND(KC_M));
	P( RP,								SEND(KC_I));
	P( RB,								SEND(KC_COMM));
	P( RL,								SEND(KC_O));
	P( RG,								SEND(KC_DOT));
	P( RT,								SEND(KC_P));
	P( RS,								SEND(KC_SLSH));

	// Symbols and Numbers
	P( PWR | RE | RU,					SEND(KC_ENT));
	P( PWR | LA | LO,					SEND(KC_SPC));
	P( PWR | LP | LW,					SEND(KC_LSFT); SEND(KC_9));			// (
	P( PWR | LH | LR,					SEND(KC_LSFT); SEND(KC_0));			// )
	P( PWR | ST1 | ST2,					SEND(KC_GRV));						// `
	P( PWR | RD | RZ,					SEND(KC_ESC));							
	P( PWR | LSU | LSD,					SEND(KC_LSFT); SEND(KC_3));			// #
	P( PWR | LFT | LK,					SEND(KC_LSFT); SEND(KC_4));			// $
	P( PWR | LSU,						SEND(KC_LSFT); SEND(KC_1));			// !
	P( PWR | LSD,						SEND(KC_LSFT); SEND(KC_5));			// %
	P( PWR | LFT,						SEND(KC_LSFT); SEND(KC_2));			// @
	P( PWR | LK,						SEND(KC_LSFT); SEND(KC_6));			// ^
	P( PWR | LP,						SEND(KC_LSFT); SEND(KC_LBRC));		// {
	P( PWR | LW,						SEND(KC_LBRC));
	P( PWR | LH,						SEND(KC_LSFT); SEND(KC_RBRC));		// }
	P( PWR | LR,						SEND(KC_RBRC));
	P( PWR | ST1,						SEND(KC_LSFT); SEND(KC_BSLS));		// |
	P( PWR | ST2,						SEND(KC_LSFT); SEND(KC_GRV));		// ~
	P( PWR | ST3,						SEND(KC_QUOT));
	P( PWR | ST4,						SEND(KC_LSFT); SEND(KC_QUOT));		// "
	P( PWR | RF,						SEND(KC_KP_PLUS));
	P( PWR | RR,						SEND(KC_LSFT); SEND(KC_7));			// &
	P( PWR | RP,						SEND(KC_MINS));
	P( PWR | RB,						SEND(KC_EQL));
	P( PWR | RL,						SEND(KC_SLSH));
	P( PWR | RG,						SEND(KC_COMM));
	P( PWR | RT,						SEND(KC_PAST));
	P( PWR | RS,						SEND(KC_DOT));
	P( PWR | RD,						SEND(KC_TAB));
	P( PWR | LA,						SEND(KC_SCLN));
	P( PWR | LO,						SEND(KC_SLSH));
	P( PWR | RE,						SEND(KC_SCLN));
	P( PWR | RU,						SEND(KC_SLSH));


	// If we make here, send as a steno chord
	// If plover is running we can hook that host side
	return false;
}

#define STENO_LAYER  	0

// "Layers"
// Steno layer should be first in your map.
// When PWR | FN | RR | RG | RB | RS is pressed, the layer is increased to the next map. You must return to STENO_LAYER at the end.
// If you have only a single layer, you must set SINGLELAYER = yes in your rules.mk, otherwise you may experince undefined behaviour

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Main layer, everything goes through here
[STENO_LAYER] = LAYOUT_georgi(  
STN_FN,  STN_S1, STN_TL, STN_PL, STN_HL, STN_ST1,       STN_ST3, STN_FR, STN_PR, STN_LR, STN_TR, STN_DR,
STN_PWR, STN_S2, STN_KL, STN_WL, STN_RL, STN_ST2,       STN_ST4, STN_RR, STN_BR, STN_GR, STN_SR, STN_ZR,
						 STN_N1, STN_A,  STN_O,			STN_E,   STN_U,  STN_N1)
}; 

int getKeymapCount(void) {
	return sizeof(keymaps)/sizeof(keymaps[0]);
}

D keyboards/georgi/keymaps/template/readme.md => keyboards/georgi/keymaps/template/readme.md +0 -6
@@ 1,6 0,0 @@
# Georgi QWERTY/Steno firmware

This is a blank template configured with 5K of free space for your onboard dictionary!  
Read the docs over at [gBoards](http://docs.gboards.ca)

Ideally you should copy this directory and make your changes there. If you come up with a good layout submit a PR!

M keyboards/georgi/readme.md => keyboards/georgi/readme.md +4 -1
@@ 21,8 21,11 @@ To just test your build with the default keymap

Build options can be enabled/disabled in keyboards/georgi/keymaps/default/rules.mk . Copy the default directory and make any changes to your layout, if you think they're worth sharing submit a PR!

## Documentation
Is hosted over on [docs.gboards.ca](http://docs.gboards.ca/). Please take a look at the docs for customizing your firmware!

# Space
The stock firmware uses nearly all of the flash avalible. For custom dictionary modifications, disable mousekeys in your keymaps rules.mk (4K of space) and remove the Gaming layers. I've done this already in the provided keymap 'template'.
The stock firmware leaves 7K free for custom entries. For extra space disable mousekeys in your keymaps rules.mk (3K of space) and remove the Gaming layers (1k). 

See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).


M keyboards/georgi/rules.mk => keyboards/georgi/rules.mk +3 -2
@@ 4,7 4,7 @@
# Do not edit this file! Make a copy of keymaps/default and modify that!
#----------------------------------------------------------------------------
# Source includes
SRC += matrix.c i2c_master.c
SRC += matrix.c i2c_master.c sten.c

# Hardware info
MCU = atmega32u4


@@ 15,8 15,9 @@ F_USB = $(F_CPU)
EXTRAFLAGS += -flto

CUSTOM_MATRIX 		= yes
MOUSEKEY_ENABLE		= no
STENO_ENABLE 		= yes
EXTRAKEY_ENABLE     = yes
CONSOLE_ENABLE      = no
CONSOLE_ENABLE      = yes
COMMAND_ENABLE      = no
NKRO_ENABLE			= yes

M keyboards/georgi/sten.c => keyboards/georgi/sten.c +405 -1
@@ 1,2 1,406 @@
#include "sten.h" 
#include "sten.h"

// Chord state
uint32_t cChord 		= 0;		// Current Chord
int		 chordIndex 	= 0;		// Keys in previousachord
int32_t  chordState[32];			// Full Chord history
#define  QWERBUF		24			// Size of chords to buffer for output

bool	 repeatFlag 	= false;	// Should we repeat?
uint32_t pChord 		= 0;		// Previous Chord
int		 pChordIndex 	= 0;		// Keys in previousachord
uint32_t pChordState[32];			// Previous chord sate 
uint32_t stickyBits = 0;			// Or'd with every incoming press

// Mode state
enum MODE { STENO = 0, QWERTY, COMMAND };
enum MODE pMode;
bool QWERSTENO = false;
#ifdef ONLYQWERTY
enum MODE cMode = QWERTY;
#else
enum MODE cMode = STENO;
#endif

// Command State
#define MAX_CMD_BUF   20
uint8_t	 CMDLEN 	= 0;
uint8_t	 CMDBUF[MAX_CMD_BUF];

// Key Repeat state
bool     inChord  		= false;
bool	 repEngaged 	= false;
uint16_t repTimer 		= 0;
#define  REP_INIT_DELAY 750
#define  REP_DELAY 		25

// Mousekeys state
bool	inMouse 		= false;
int8_t	mousePress;

// All processing done at chordUp goes through here
bool send_steno_chord_user(steno_mode_t mode, uint8_t chord[6]) { 
	// Check for mousekeys, this is release
#ifdef MOUSEKEY_ENABLE
	if (inMouse) {
		inMouse = false;
		mousekey_off(mousePress);
		mousekey_send();
	}
#endif

	// Toggle Serial/QWERTY steno
	if (cChord == (PWR | FN | ST1 | ST2)) {
#ifndef NO_DEBUG
		uprintf("Fallback Toggle\n");
#endif
		QWERSTENO = !QWERSTENO;
		
		goto out;
	}

	// handle command mode
	if (cChord == (PWR | FN | RD | RZ)) {
#ifndef NO_DEBUG
		uprintf("COMMAND Toggle\n");
#endif
		if (cMode != COMMAND) {   // Entering Command Mode
			CMDLEN = 0;
			pMode = cMode;
			cMode = COMMAND;
		} else {                  // Exiting Command Mode
			cMode = pMode;

			// Press all and release all
			for (int i = 0; i < CMDLEN; i++) {
				register_code(CMDBUF[i]);
			}
			clear_keyboard();
		}

		goto out;
	}

	// Handle Gaming Toggle,
	if (cChord == (PWR | FN | ST4 | ST3) && keymapsCount > 1) {
#ifndef NO_DEBUG
		uprintf("Switching to QMK\n");
#endif
		layer_on(1);
		goto out;
	}

	// Lone FN press, toggle QWERTY
#ifndef ONLYQWERTY
	if (cChord == FN) {
		(cMode == STENO) ? (cMode = QWERTY) : (cMode = STENO);
		goto out;
	}
#endif

	// Check for Plover momentary
	if (cMode == QWERTY && (cChord & FN)) {
		cChord ^= FN;
		goto steno;
	}

	// Do QWERTY and Momentary QWERTY
	if (cMode == QWERTY || (cMode == COMMAND) || (cChord & (FN | PWR))) {
		processChord(false);
		goto out;
	}

	// Fallback NKRO Steno
	if (cMode == STENO && QWERSTENO) {
		processChord(true);
		goto out;
	}

steno:
	// Hey that's a steno chord!
	inChord = false;
	chordIndex = 0;
	cChord = 0;
	return true; 

out:
	cChord = 0;
	inChord = false;
	chordIndex = 0;
	clear_keyboard();
	repEngaged  = false;
	for (int i = 0; i < 32; i++)
		chordState[i] = 0xFFFF;

	return false;
}

// Update Chord State 
bool process_steno_user(uint16_t keycode, keyrecord_t *record) { 
	// Everything happens in here when steno keys come in.
	// Bail on keyup
	if (!record->event.pressed) return true;

	// Update key repeat timers
	repTimer = timer_read();
	inChord  = true;

	// Switch on the press adding to chord
	bool pr = record->event.pressed;
	switch (keycode) {
			// Mods and stuff
			case STN_ST1:			pr ? (cChord |= (ST1)): (cChord &= ~(ST1)); break;
			case STN_ST2:			pr ? (cChord |= (ST2)): (cChord &= ~(ST2)); break;
			case STN_ST3:			pr ? (cChord |= (ST3)): (cChord &= ~(ST3)); break;
			case STN_ST4:			pr ? (cChord |= (ST4)): (cChord &= ~(ST4)); break;
			case STN_FN:			pr ? (cChord |= (FN)) : (cChord &= ~(FN)); break;
			case STN_PWR:			pr ? (cChord |= (PWR)): (cChord &= ~(PWR)); break;
			case STN_N1...STN_N6:	pr ? (cChord |= (LNO)): (cChord &= ~(LNO)); break;
			case STN_N7...STN_NC:	pr ? (cChord |= (RNO)): (cChord &= ~(RNO)); break;

			// All the letter keys
			case STN_S1:			pr ? (cChord |= (LSU)) : (cChord &= ~(LSU));  break;
			case STN_S2:			pr ? (cChord |= (LSD)) : (cChord &= ~(LSD));  break;
			case STN_TL:			pr ? (cChord |= (LFT)) : (cChord &= ~(LFT)); break;
			case STN_KL:			pr ? (cChord |= (LK)) : (cChord &= ~(LK)); break;
			case STN_PL:			pr ? (cChord |= (LP)) : (cChord &= ~(LP)); break;
			case STN_WL:			pr ? (cChord |= (LW)) : (cChord &= ~(LW)); break;
			case STN_HL:			pr ? (cChord |= (LH)) : (cChord &= ~(LH)); break;
			case STN_RL:			pr ? (cChord |= (LR)) : (cChord &= ~(LR)); break;
			case STN_A:				pr ? (cChord |= (LA)) : (cChord &= ~(LA)); break;
			case STN_O:				pr ? (cChord |= (LO)) : (cChord &= ~(LO)); break;
			case STN_E:				pr ? (cChord |= (RE)) : (cChord &= ~(RE)); break;
			case STN_U:				pr ? (cChord |= (RU)) : (cChord &= ~(RU)); break;
			case STN_FR:			pr ? (cChord |= (RF)) : (cChord &= ~(RF)); break;
			case STN_RR:			pr ? (cChord |= (RR)) : (cChord &= ~(RR)); break;
			case STN_PR:			pr ? (cChord |= (RP)) : (cChord &= ~(RP)); break;
			case STN_BR:			pr ? (cChord |= (RB)) : (cChord &= ~(RB)); break;
			case STN_LR:			pr ? (cChord |= (RL)) : (cChord &= ~(RL)); break;
			case STN_GR:			pr ? (cChord |= (RG)) : (cChord &= ~(RG)); break;
			case STN_TR:			pr ? (cChord |= (RT)) : (cChord &= ~(RT)); break;
			case STN_SR:			pr ? (cChord |= (RS)) : (cChord &= ~(RS)); break;
			case STN_DR:			pr ? (cChord |= (RD)) : (cChord &= ~(RD)); break;
			case STN_ZR:			pr ? (cChord |= (RZ)) : (cChord &= ~(RZ)); break;
	}

	// Store previous state for fastQWER
	if (pr) {
		chordState[chordIndex] = cChord; 
		chordIndex++;
	}

	return true; 
}
void matrix_scan_user(void) {
	// We abuse this for early sending of key
	// Key repeat only on QWER/SYMB layers
	if (cMode != QWERTY || !inChord) return;

	// Check timers
#ifndef NO_REPEAT
	if (repEngaged && timer_elapsed(repTimer) > REP_DELAY) {
		// Process Key for report
		processChord(false);

		// Send report to host
		send_keyboard_report();
		clear_keyboard();
		repTimer = timer_read();
	}

	if (!repEngaged && timer_elapsed(repTimer) > REP_INIT_DELAY) {
		repEngaged = true;
	}
#endif
};

// For Plover NKRO
uint32_t processFakeSteno(bool lookup) { 
	P( LSU,				SEND(KC_Q););
	P( LSD,				SEND(KC_A););
	P( LFT,				SEND(KC_W););
	P( LP,				SEND(KC_E););
	P( LH,				SEND(KC_R););
	P( LK,				SEND(KC_S););
	P( LW,				SEND(KC_D););
	P( LR,				SEND(KC_F););
	P( ST1,				SEND(KC_T););
	P( ST2,				SEND(KC_G););
	P( LA,				SEND(KC_C););
	P( LO,				SEND(KC_V););
	P( RE,				SEND(KC_N););
	P( RU,				SEND(KC_M););
	P( ST3,				SEND(KC_Y););
	P( ST4,				SEND(KC_H););
	P( RF,				SEND(KC_U););
	P( RP,				SEND(KC_I););
	P( RL,				SEND(KC_O););
	P( RT,				SEND(KC_P););
	P( RD,				SEND(KC_LBRC););
	P( RR,				SEND(KC_J););
	P( RB,				SEND(KC_K););
	P( RG,				SEND(KC_L););
	P( RS,				SEND(KC_SCLN););
	P( RZ,				SEND(KC_COMM););
	P( LNO,				SEND(KC_1););
	P( RNO,				SEND(KC_1););

	return 0;
}

// Traverse the chord history to a given point
// Returns the mask to use
void processChord(bool useFakeSteno) {
	// Save the clean chord state
	uint32_t savedChord = cChord;

	// Apply Stick Bits if needed
	if (stickyBits != 0) {
		cChord |= stickyBits;
		for (int i = 0; i <= chordIndex; i++)
			chordState[i] |= stickyBits;
	}

	// Strip FN
	if (cChord & FN) cChord ^= FN;

	// First we test if a whole chord was passsed
	// If so we just run it handling repeat logic
	if (useFakeSteno && processFakeSteno(true) == cChord) {
		processFakeSteno(false);
		return;
	} else if (processQwerty(true) == cChord) {
		processQwerty(false);
		// Repeat logic
		if (repeatFlag) {
			restoreState();
			repeatFlag = false;
			processChord(false);
		} else {
			saveState(cChord);
		}
		return;
	}

	// Iterate through chord picking out the individual 
	// and longest chords
	uint32_t bufChords[QWERBUF];
	int 	 bufLen		= 0;
	uint32_t mask		= 0;

	// We iterate over it multiple times to catch the longest
	// chord. Then that gets addded to the mask and re run.
	while (savedChord != mask) {
		uint32_t test  	 		= 0;
		uint32_t longestChord	= 0;

		for (int i = 0; i <= chordIndex; i++) {
			cChord = chordState[i] & ~mask;
			if (cChord == 0)
				continue;

			// Assume mid parse Sym is new chord
			if (i != 0 && test != 0 && (cChord ^ test) == PWR) {
				longestChord = test;
				break;
			}

			// Lock SYM layer in once detected
			if (mask & PWR)
				cChord |= PWR;


			// Testing for keycodes
			if (useFakeSteno) {
				test = processFakeSteno(true);
			} else {
				test = processQwerty(true);
			}
		 
			if (test != 0) {
				longestChord = test;
			}
		}
		
		mask |= longestChord;
		bufChords[bufLen] = longestChord;
		bufLen++;

		// That's a loop of sorts, halt processing
		if (bufLen >= QWERBUF) {
			return;
		}
	}
	
	// Now that the buffer is populated, we run it
	for (int i = 0; i < bufLen ; i++) {
		cChord = bufChords[i];
		if (useFakeSteno) {
			processFakeSteno(false);
		} else {
			processQwerty(false);
		}
	}

	// Save state in case of repeat
	if (!repeatFlag) {			
		saveState(savedChord);
	}

	// Restore cChord for held repeat
	cChord = savedChord;

	return;
}
void saveState(uint32_t cleanChord) {
	pChord = cleanChord;
	pChordIndex = chordIndex;
	for (int i = 0; i < 32; i++) 
		pChordState[i] = chordState[i];
}
void restoreState() {
	cChord = pChord;
	chordIndex = pChordIndex;
	for (int i = 0; i < 32; i++) 
		chordState[i] = pChordState[i];
}

// Macros for calling from keymap.c
void SEND(uint8_t kc) {
	// Send Keycode, Does not work for Quantum Codes
	if (cMode == COMMAND && CMDLEN < MAX_CMD_BUF) {
#ifndef NO_DEBUG
		uprintf("CMD LEN: %d BUF: %d\n", CMDLEN, MAX_CMD_BUF);
#endif
		CMDBUF[CMDLEN] = kc;
		CMDLEN++;
	} 

	if (cMode != COMMAND) register_code(kc);
	return;
}
void REPEAT(void) {
	if (cMode != QWERTY)
		return;

	repeatFlag = true;
	return;
}
void SET_STICKY(uint32_t stick) {
	stickyBits = stick;
	return;
}
void SWITCH_LAYER(int layer) {
	if (keymapsCount >= layer) 
		layer_on(layer);
}
void CLICK_MOUSE(uint8_t kc) {
#ifdef MOUSEKEY_ENABLE
	mousekey_on(kc);
	mousekey_send();

	// Store state for later use
	inMouse = true;
	mousePress = kc;
#endif
}

M keyboards/georgi/sten.h => keyboards/georgi/sten.h +32 -245
@@ 1,28 1,43 @@
// 2019, g Heavy Industries
// Blessed mother of Christ, please keep this readable
// and protect us from segfaults. For thine is the clock,
// the slave and the master. Until we return from main.
//
// Amen.

#include QMK_KEYBOARD_H
#include "mousekey.h"
#include "keymap.h"
#include "keymap_steno.h"
#include "wait.h"

// Bitfield representing the current chord
uint32_t cChord = 0;
extern size_t keymapsCount;			// Total keymaps
extern uint32_t cChord;				// Current Chord

// See if a given chord is pressed. 
// P will return 
// PJ will continue processing, removing the found chord 
#define P(chord, act)  if (cChord == (chord)) { act; return true; }
#define PJ(chord, act) if ((cChord & (chord)) == (chord)) { cChord ^= chord; act; }
// Function defs
void 			processChord(bool useFakeSteno);
uint32_t		processQwerty(bool lookup);
uint32_t 		processFakeSteno(bool lookup);
void 			saveState(uint32_t cChord);
void 			restoreState(void);

// Macros for use in keymap.c
void 			SEND(uint8_t kc);
void 			REPEAT(void);
void 			SET_STICKY(uint32_t);
void 			SWITCH_LAYER(int);
void 			CLICK_MOUSE(uint8_t);

// Keymap helper
#define P(chord, act) if (cChord == (chord)) { if (!lookup) {act;} return chord;}

// All Steno Codes
// Shift to internal representation
// i.e) S(teno)R(ight)F
#define STN(n) (1L<<n)

//i.e) S(teno)R(ight)F
enum ORDER { 
		SFN = 0, SPWR, SST1, SST2, SST3, SST4, SNUM,
		SFN = 0, SPWR, SST1, SST2, SST3, SST4, SNUML, SNUMR,
		SLSU, SLSD, SLT, SLK, SLP, SLW, SLH, SLR, SLA, SLO, 
		SRE, SRU, SRF, SRR, SRP, SRB, SRL, SRG, SRT, SRS, SRD, SRZ
		SRE, SRU, SRF, SRR, SRP, SRB, SRL, SRG, SRT, SRS, SRD, SRZ, SRES1, SRES2
};

// Break it all out


@@ 32,11 47,14 @@ enum ORDER {
#define ST2 STN(SST2)
#define ST3 STN(SST3)
#define ST4 STN(SST4)
#define NUM STN(SNUM) // No distinction between left and right
#define LNO STN(SNUML) 	// STN1-6
#define RNO STN(SNUMR) 	// STN7-C
#define RES1 STN(SRES1) // Use reserved for sticky state
#define RES2 STN(SRES2)

#define LSU STN(SLSU)
#define LSD STN(SLSD)
#define LFT STN(SLT)  // (L)e(F)t (T), preprocessor conflict
#define LFT STN(SLT)  	// (L)e(F)t (T), preprocessor conflict
#define LK  STN(SLK)
#define LP  STN(SLP)
#define LW  STN(SLW)


@@ 57,234 75,3 @@ enum ORDER {
#define RS  STN(SRS)
#define RD  STN(SRD)
#define RZ  STN(SRZ)

bool 		processQwerty(void);
bool 		processFakeSteno(void);
void 		clickMouse(uint8_t kc);
void 		SEND(uint8_t kc);
extern int 	getKeymapCount(void);

// Mode state
enum MODE { STENO = 0, QWERTY, COMMAND };
enum MODE cMode = STENO;
enum MODE pMode;
bool QWERSTENO = false;

// Command State
#define MAX_CMD_BUF 20
uint8_t CMDBUF[MAX_CMD_BUF];
uint8_t CMDLEN = 0;

// Key Repeat state
bool     inChord  = false;
uint16_t repTimer = 0;
#define  REP_DELAY 300

// Mousekeys state
bool	inMouse = false;
int8_t	mousePress;

// All processing done at chordUp goes through here
bool send_steno_chord_user(steno_mode_t mode, uint8_t chord[6]) { 
	// Check for mousekeys, this is release
#ifdef MOUSEKEY_ENABLE
	if (inMouse) {
		inMouse = false;
		mousekey_off(mousePress);
		mousekey_send();
	}
#endif

	// Toggle Serial/QWERTY steno
	if (cChord == (PWR | FN | ST1 | ST2)) {
		uprintf("Fallback Toggle\n");
		QWERSTENO = !QWERSTENO;
		
		goto out;
	}

	// handle command mode
	if (cChord == (PWR | FN | RD | RZ)) {
		uprintf("COMMAND Toggle\n");
		if (cMode != COMMAND) {   // Entering Command Mode
			CMDLEN = 0;
			pMode = cMode;
			cMode = COMMAND;
		} else {                  // Exiting Command Mode
			cMode = pMode;

			// Press all and release all
			for (int i = 0; i < CMDLEN; i++) {
				register_code(CMDBUF[i]);
			}
			clear_keyboard();
		}

		goto out;
	}

	// Handle Gaming Toggle,
	if (cChord == (PWR | FN | ST2 | ST3) && getKeymapCount() > 1) {
		uprintf("Switching to QMK\n");
		layer_on(1);
		goto out;
	}

	// Lone FN press, toggle QWERTY
	if (cChord == FN) {
		(cMode == STENO) ? (cMode = QWERTY) : (cMode = STENO);
		goto out;
	}

	// Check for Plover momentary
	if (cMode == QWERTY && (cChord & FN)) {
		cChord ^= FN;
		goto steno;
	}

	// Do QWERTY and Momentary QWERTY
	if (cMode == QWERTY || (cMode == COMMAND) || (cChord & (FN | PWR))) {
		if (cChord & FN)  cChord ^= FN;
		processQwerty();
		goto out;
	}

	// Fallback NKRO Steno
	if (cMode == STENO && QWERSTENO) {
		processFakeSteno();
		goto out;
	}

steno:
	// Hey that's a steno chord!
	inChord = false;
	cChord = 0;
	return true; 

out:
	inChord = false;
	clear_keyboard();
	cChord = 0;
	return false;
}

// Update Chord State 
bool process_steno_user(uint16_t keycode, keyrecord_t *record) { 
	// Everything happens in here when steno keys come in.
	// Bail on keyup
	if (!record->event.pressed) return true;

	// Update key repeat timers
	repTimer = timer_read();
	inChord  = true;

	// Switch on the press adding to chord
	bool pr = record->event.pressed;
	switch (keycode) {
			// Mods and stuff
			case STN_ST1:			pr ? (cChord |= (ST1)): (cChord &= ~(ST1)); break;
			case STN_ST2:			pr ? (cChord |= (ST2)): (cChord &= ~(ST2)); break;
			case STN_ST3:			pr ? (cChord |= (ST3)): (cChord &= ~(ST3)); break;
			case STN_ST4:			pr ? (cChord |= (ST4)): (cChord &= ~(ST4)); break;
			case STN_FN:			pr ? (cChord |= (FN)) : (cChord &= ~(FN)); break;
			case STN_PWR:			pr ? (cChord |= (PWR)): (cChord &= ~(PWR)); break;
			case STN_N1...STN_N6: 
			case STN_N7...STN_NC:	pr ? (cChord |= (NUM)): (cChord &= ~(NUM)); break;

			// All the letter keys
			case STN_S1:			pr ? (cChord |= (LSU)) : (cChord &= ~(LSU));  break;
			case STN_S2:			pr ? (cChord |= (LSD)) : (cChord &= ~(LSD));  break;
			case STN_TL:			pr ? (cChord |= (LFT)) : (cChord &= ~(LFT)); break;
			case STN_KL:			pr ? (cChord |= (LK)) : (cChord &= ~(LK)); break;
			case STN_PL:			pr ? (cChord |= (LP)) : (cChord &= ~(LP)); break;
			case STN_WL:			pr ? (cChord |= (LW)) : (cChord &= ~(LW)); break;
			case STN_HL:			pr ? (cChord |= (LH)) : (cChord &= ~(LH)); break;
			case STN_RL:			pr ? (cChord |= (LR)) : (cChord &= ~(LR)); break;
			case STN_A:				pr ? (cChord |= (LA)) : (cChord &= ~(LA)); break;
			case STN_O:				pr ? (cChord |= (LO)) : (cChord &= ~(LO)); break;
			case STN_E:				pr ? (cChord |= (RE)) : (cChord &= ~(RE)); break;
			case STN_U:				pr ? (cChord |= (RU)) : (cChord &= ~(RU)); break;
			case STN_FR:			pr ? (cChord |= (RF)) : (cChord &= ~(RF)); break;
			case STN_RR:			pr ? (cChord |= (RR)) : (cChord &= ~(RR)); break;
			case STN_PR:			pr ? (cChord |= (RP)) : (cChord &= ~(RP)); break;
			case STN_BR:			pr ? (cChord |= (RB)) : (cChord &= ~(RB)); break;
			case STN_LR:			pr ? (cChord |= (RL)) : (cChord &= ~(RL)); break;
			case STN_GR:			pr ? (cChord |= (RG)) : (cChord &= ~(RG)); break;
			case STN_TR:			pr ? (cChord |= (RT)) : (cChord &= ~(RT)); break;
			case STN_SR:			pr ? (cChord |= (RS)) : (cChord &= ~(RS)); break;
			case STN_DR:			pr ? (cChord |= (RD)) : (cChord &= ~(RD)); break;
			case STN_ZR:			pr ? (cChord |= (RZ)) : (cChord &= ~(RZ)); break;
	}

	// Check for key repeat in QWERTY mode
	return true; 
}
void matrix_scan_user(void) {
	// We abuse this for early sending of key
	// Key repeat only on QWER/SYMB layers
	if (cMode != QWERTY) return;

	// Check timers
	if (timer_elapsed(repTimer) > REP_DELAY) {
		// Process Key for report
		processQwerty();

		// Send report to host
		send_keyboard_report();
		repTimer = timer_read();
	}
};

// Helpers
bool processFakeSteno(void) {
	PJ( LSU,			SEND(KC_Q););
	PJ( LSD,			SEND(KC_A););
	PJ( LFT,			SEND(KC_W););
	PJ( LP,				SEND(KC_E););
	PJ( LH,				SEND(KC_R););
	PJ( LK,				SEND(KC_S););
	PJ( LW,				SEND(KC_D););
	PJ( LR,				SEND(KC_F););
	PJ( ST1,			SEND(KC_T););
	PJ( ST2,			SEND(KC_G););
	PJ( LA,				SEND(KC_C););
	PJ( LO,				SEND(KC_V););
	PJ( RE,				SEND(KC_N););
	PJ( RU,				SEND(KC_M););
	PJ( ST3,			SEND(KC_Y););
	PJ( ST4,			SEND(KC_H););
	PJ( RF,				SEND(KC_U););
	PJ( RP,				SEND(KC_I););
	PJ( RL,				SEND(KC_O););
	PJ( RT,				SEND(KC_P););
	PJ( RD,				SEND(KC_LBRC););
	PJ( RR,				SEND(KC_J););
	PJ( RB,				SEND(KC_K););
	PJ( RG,				SEND(KC_L););
	PJ( RS,				SEND(KC_SCLN););
	PJ( RZ,				SEND(KC_COMM););
	PJ( NUM,			SEND(KC_1););

	return false;
}
void clickMouse(uint8_t kc) {
#ifdef MOUSEKEY_ENABLE
	mousekey_on(kc);
	mousekey_send();

	// Store state for later use
	inMouse = true;
	mousePress = kc;
#endif
}
void SEND(uint8_t kc) {
	// Send Keycode, Does not work for Quantum Codes
	if (cMode == COMMAND && CMDLEN < MAX_CMD_BUF) {
		uprintf("CMD LEN: %d BUF: %d\n", CMDLEN, MAX_CMD_BUF);
		CMDBUF[CMDLEN] = kc;
		CMDLEN++;
	} 

	if (cMode != COMMAND) register_code(kc);
	return;
}

M keyboards/gergo/keymaps/default/rules.mk => keyboards/gergo/keymaps/default/rules.mk +1 -1
@@ 12,7 12,7 @@ MOUSEKEY_ENABLE = yes  		# Mouse keys(+4700), needed for baller
VERBOSE 		 = yes
DEBUG_MATRIX_SCAN_RATE   = no
DEBUG_BALLER 		 = no
DEBUG_MATRIX		 = no
DEBUG_MATRIX		 = yes

# A bunch of stuff that you shouldn't touch unless you
# know what you're doing.

A keyboards/gergo/keymaps/germ/keymap.c => keyboards/gergo/keymaps/germ/keymap.c +151 -0
@@ 0,0 1,151 @@
/* Good on you for modifying your layout! if you don't have 
 * time to read the QMK docs, a list of keycodes can be found at
 *
 * https://github.com/qmk/qmk_firmware/blob/master/docs/keycodes.md
 *
 * There's also a template for adding new layers at the bottom of this file!
 */

#include QMK_KEYBOARD_H

#define IGNORE_MOD_TAP_INTERRUPT
#define BASE 0 // default layer
#define SYMB 1 // symbols
#define NUMB 2 // numbers/motion

// Blank template at the bottom

enum customKeycodes {
	URL  = 1
};


const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Basic layer
 *
 * ,-------------------------------------------.                         ,-------------------------------------------.
 * | L1/ESC |   Q  |   W  |   E  |   R  |   T  |                         |   Y  |   U  |   I  |   O  |   P  |  | \   |
 * |--------+------+------+------+------+------|------.           .------|------+------+------+------+------+--------|
 * |Ctrl/BS |   A  |   S  |  D   |   F  |   G  | RMB  |           |      |   H  |   J  |   K  |   L  | ;  : |  ' "   |
 * |--------+------+------+------+------+------|------|           |------|------+------+------+------+------+--------|
 * | LShift |   Z  |   X  |   C  |   V  |   B  | LMB  |           |      |   N  |   M  | ,  < | . >  | /  ? |  - _   |
 * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
 *                    .----------.   .-------.                                 .------.   .-----.
 *                    | Super/Del|   |Ent/ALT|                                 | Tab  |   |BKSP |
 *                    '----------'   '-------'                                 `------.   '-----'
 *                                        ,-------.                      ,-------.
 *                                        | MMB   |                      | PgDn  |
 *                                 ,------|-------|                      |-------|------.
 *                                 | SYMB | NUMB  |                      | SYMB  | NUMB |
 *                                 | Space| Escape|                      | Mod   |Space |
 *                                 |      |       |                      |       |      |
 *                                 `--------------'                      `--------------'
 */
[BASE] = LAYOUT_GERGO(  
LT(NUMB, KC_ESC),       KC_Q,  KC_W,   KC_E,   KC_R, KC_T,                       KC_Y,    KC_U, KC_I, KC_O,   KC_P,    KC_PIPE, 
MT(MOD_LCTL, KC_BSPC),  KC_A,  KC_S,   KC_D,   KC_F, KC_G, KC_BTN2,       KC_TRNS,  KC_H,    KC_J, KC_K, KC_L,   KC_SCLN, KC_QUOT, 
KC_RSFT,                KC_Z,  KC_X,   KC_C,   KC_V, KC_B, KC_BTN1,       KC_BSPC,  KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_MINS, 
                                      
			              MT(MOD_LGUI, KC_DEL), MT(MOD_LALT, KC_ENT),       KC_TAB, KC_BSPC,

                                                           KC_BTN3,       KC_PGDN,
                                LT(SYMB, KC_SPC), LT(NUMB, KC_ESC),       LT(SYMB, KC_ENT), LT(NUMB, KC_SPC)),
/* Keymap 1: Symbols layer
 *
 * ,-------------------------------------------.                         ,-------------------------------------------.
 * |        |  !   |  @   |  {   |  }   |  |   |                         |      |      |      |      |      |  \ |   |
 * |--------+------+------+------+------+------|------.           .------|------+------+------+------+------+--------|
 * |        |  #   |  $   |  (   |  )   |  `   |      |           |      |   +  |  -   |  /   |  *   |  %   |  ' "   |
 * |--------+------+------+------+------+------|------|           |------|------+------+------+------+------+--------|
 * |        |  %   |  ^   |  [   |  ]   |  ~   |      |           |      |   &  |  =   |  ,   |  .   |  / ? | - _    |
 * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
 *                        .------.   .------.                                 .------.   .-----.
 *                        |      |   |      |                                 |      |   | DEL |
 *                        '------'   '------'                                 `------.   '-----'
 *                                        ,-------.                     ,-------.
 *                                        |       |                     | PgUp  |
 *                                 ,------|-------|                     |-------|------.
 *                                 |      |       |                     |       |      |
 *                                 |   ;  |   =   |                     |   =   |   ;  |
 *                                 |      |       |                     |       |      |
 *                                 `--------------'                     `--------------'
 */
[SYMB] = LAYOUT_GERGO(  
KC_TRNS, KC_EXLM, KC_AT,  KC_LCBR,KC_RCBR, KC_PIPE,                          KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_BSLS, 
KC_TRNS, KC_HASH, KC_DLR, KC_LPRN,KC_RPRN, KC_GRV,  KC_TRNS,       KC_TRNS,  KC_PLUS, KC_MINS, KC_SLSH, KC_ASTR, KC_PERC, KC_QUOT, 
KC_TRNS, KC_PERC, KC_CIRC,KC_LBRC,KC_RBRC, KC_TILD, KC_TRNS,       KC_TRNS,  KC_AMPR, KC_EQL,  KC_COMM, KC_DOT,  KC_SLSH, KC_MINS, 

                                                  KC_TRNS, KC_TRNS,       KC_PGUP, KC_DEL,
                                                           KC_TRNS,       KC_TRNS,
                                             	  KC_SCLN, KC_EQL,        KC_EQL, KC_SCLN),
/* Keymap 2: Pad/Function layer
 *
 * ,-------------------------------------------.                         ,-------------------------------------------.
 * |        |   1  |  2   |  3   |  4   |  5   |                         |  6   |  7   |  8   |  9   |  0   |        |
 * |--------+------+------+------+------+------|------.           .------|------+------+------+------+------+--------|
 * |  F1    |  F2  | F3   | F4   | F5   | F6   | BTN1 |           |      | LEFT | DOWN |  UP  | RIGHT|VolDn | VolUp  |
 * |--------+------+------+------+------+------|------|           |------|------+------+------+------+------+--------|
 * |  F7    |  F8  | F9   | F10  | F11  | F12  | BTN2 |           |      | MLFT | MDWN | MUP  | MRGHT|Ply/Pa|  Skip  |
 * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
 *                        .------.   .------.                                 .------.   .-----.
 *                        |      |   |      |                                 |      |   |     |
 *                        '------'   '------'                                 `------.   '-----'
 *                                        ,-------.                     ,-------.
 *                                        |       |                     | PgUp  |
 *                                 ,------|-------|                     |-------|------.
 *                                 |      |       |                     |       |      |
 *                                 |      |       |                     |       |      |
 *                                 |      |       |                     |       |      |
 *                                 `--------------'                     `--------------'
 */
[NUMB] = LAYOUT_GERGO(  
KC_TRNS, KC_1, 	  KC_2,    KC_3,    KC_4,    KC_5,                             KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_TRNS, 
KC_TRNS, KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,         KC_TRNS,  KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT, KC_VOLD, KC_VOLU, 
KC_TRNS, KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12,        KC_TRNS,  KC_MS_L, KC_MS_D, KC_MS_U, KC_MS_R, KC_MPLY, KC_MNXT, 

                                                  KC_TRNS, KC_TRNS,       KC_PGUP, KC_TRNS,
                                                           KC_TRNS,       KC_TRNS,
                                             	  KC_TRNS, KC_TRNS,       KC_TRNS, KC_TRNS)
};

/* Keymap template 
 *
 * ,-------------------------------------------.                         ,-------------------------------------------.
 * |        |      |      |      |      |      |                         |      |      |      |      |      |        |
 * |--------+------+------+------+------+------|------.           .------|------+------+------+------+------+--------|
 * |        |      |      |      |      |      |      |           |      |      |      |      |      |      |        |
 * |--------+------+------+------+------+------|------|           |------|------+------+------+------+------+--------|
 * |        |      |      |      |      |      |      |           |      |      |      |      |      |      |        |
 * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
 *                        .------.   .------.                                 .------.   .-----.
 *                        |      |   |      |                                 |      |   |     |
 *                        '------'   '------'                                 `------.   '-----'
 *                                        ,-------.       ,-------.
 *                                        |       |       |       |
 *                                 ,------|-------|       |-------|------.
 *                                 |      |       |       |       |      |
 *                                 |      |       |       |       |      |
 *                                 |      |       |       |       |      |
 *                                 `--------------'       `--------------'
[SYMB] = LAYOUT_GERGO(  
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,                          KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, 
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,       KC_TRNS,  KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, 
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,       KC_TRNS,  KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,  KC_TRNS, KC_TRNS, 

                                                  KC_TRNS, KC_TRNS,       KC_TRNS, KC_TRNS,
                                                           KC_TRNS,       KC_TRNS,
                                             	  KC_TRNS, KC_TRNS,       KC_TRNS, KC_TRNS),
 */

// Runs just one time when the keyboard initializes.
void matrix_init_user(void) {

};

// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
    //uint8_t layer = biton32(layer_state);
    biton32(layer_state);
};



A keyboards/gergo/keymaps/germ/readme.md => keyboards/gergo/keymaps/germ/readme.md +10 -0
@@ 0,0 1,10 @@
# [Gergo! By g Heavy Industries](http://gboards.ca)

![Gergo image](https://4.bp.blogspot.com/-889nMXxgSM0/XCNxwnO5kUI/AAAAAAAA6mI/tZbWgZVCBW0dyZOCGJDkjN06DVax7j8XwCLcBGAs/s1600/48422820_967732713413298_485744639215665152_n.jpg)

This is the default keymap for Gergo, it's based heavily off of the naps62 ErgoDox layout and is aimed at a programmer friendly keymap.

## Settings
To edit various settings, enable the 1u trackball and whatnot please modify /keyboards/gergo/keymaps/default/rules.mk

Ideally you should copy this directory and make your changes there. If you come up with a good layout submit a PR!

A keyboards/gergo/keymaps/germ/rules.mk => keyboards/gergo/keymaps/germ/rules.mk +36 -0
@@ 0,0 1,36 @@
#----------------------------------------------------------------------------
# make gergo:germ:dfu
# Make sure you have dfu-programmer installed!
#----------------------------------------------------------------------------
# Firmware options
BALLER = yes 			# Enable to ball out
BALLSTEP = 20  			# Multiple in px to move, multiplied by layer number
SCROLLSTEP = 1 			# Lines to scroll with ball
MOUSEKEY_ENABLE = yes  		# Mouse keys(+4700), needed for baller

#Debug options
VERBOSE 		 = yes
DEBUG_MATRIX_SCAN_RATE   = no
DEBUG_BALLER 		 = no
DEBUG_MATRIX		 = no

# A bunch of stuff that you shouldn't touch unless you
# know what you're doing.
#
# No touchy, capiche?
SRC += matrix.c i2c_master.c
ifneq ($(strip $(BALLSTEP)),)
    OPT_DEFS += -DTRKSTEP=$(strip $(BALLSTEP))
endif
ifneq ($(strip $(SCROLLSTEP)),)
    OPT_DEFS += -DSCROLLSTEP=$(strip $(SCROLLSTEP))
endif
ifeq ($(strip $(BALLER)), yes)
    OPT_DEFS += -DBALLER
endif
ifeq ($(strip $(DEBUG_BALLER)), yes)
    OPT_DEFS += -DDEBUG_BALLER
endif
ifeq ($(strip $(DEBUG_MATRIX)), yes)
    OPT_DEFS += -DDEBUG_MATRIX
endif