summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Kristoffersen <david.alta2010@gmail.com>2022-07-02 14:18:21 +0200
committerGitHub <noreply@github.com>2022-07-02 22:18:21 +1000
commita80943579c88255fff9de57978b8e577d184785c (patch)
treedba57e907e20f50f4c9cbee22866d99a620e5d0d
parentef633cf46139282daaca77939937f7ba2519f56b (diff)
[Keymap] Add prog_qgmlwb keymap (#16890)
-rw-r--r--keyboards/planck/keymaps/prog_qgmlwb/.gitignore3
-rw-r--r--keyboards/planck/keymaps/prog_qgmlwb/config.h12
-rw-r--r--keyboards/planck/keymaps/prog_qgmlwb/keymap.c4
-rw-r--r--keyboards/planck/keymaps/prog_qgmlwb/readme.md82
-rw-r--r--keyboards/planck/keymaps/prog_qgmlwb/rules.mk6
-rw-r--r--keyboards/planck/keymaps/prog_qgmlwb/src/enums.h23
-rw-r--r--keyboards/planck/keymaps/prog_qgmlwb/src/layouts.c25
-rw-r--r--keyboards/planck/keymaps/prog_qgmlwb/src/layouts.h27
-rw-r--r--keyboards/planck/keymaps/prog_qgmlwb/src/normal.h96
-rw-r--r--keyboards/planck/keymaps/prog_qgmlwb/src/qgmlwb.h63
-rw-r--r--keyboards/planck/keymaps/prog_qgmlwb/src/special.h43
-rw-r--r--users/davidkristoffersen/davidkristoffersen.h18
-rw-r--r--users/davidkristoffersen/hardware/readme.md3
-rw-r--r--users/davidkristoffersen/hardware/split_space.c23
-rw-r--r--users/davidkristoffersen/hardware/split_space.h16
-rw-r--r--users/davidkristoffersen/macros/debug.c36
-rw-r--r--users/davidkristoffersen/macros/language.c40
-rw-r--r--users/davidkristoffersen/macros/macros.c16
-rw-r--r--users/davidkristoffersen/macros/macros.h23
-rw-r--r--users/davidkristoffersen/macros/norwegian.h19
-rw-r--r--users/davidkristoffersen/macros/readme.md3
-rw-r--r--users/davidkristoffersen/post_config.h8
-rw-r--r--users/davidkristoffersen/readme.md3
-rw-r--r--users/davidkristoffersen/rules.mk12
-rw-r--r--users/davidkristoffersen/util/functions.c111
-rw-r--r--users/davidkristoffersen/util/functions.h32
-rw-r--r--users/davidkristoffersen/util/readme.md3
27 files changed, 750 insertions, 0 deletions
diff --git a/keyboards/planck/keymaps/prog_qgmlwb/.gitignore b/keyboards/planck/keymaps/prog_qgmlwb/.gitignore
new file mode 100644
index 0000000000..a39c642249
--- /dev/null
+++ b/keyboards/planck/keymaps/prog_qgmlwb/.gitignore
@@ -0,0 +1,3 @@
+build
+printout
+scripts
diff --git a/keyboards/planck/keymaps/prog_qgmlwb/config.h b/keyboards/planck/keymaps/prog_qgmlwb/config.h
new file mode 100644
index 0000000000..b52b41746a
--- /dev/null
+++ b/keyboards/planck/keymaps/prog_qgmlwb/config.h
@@ -0,0 +1,12 @@
+// Copyright 2022 David Kristoffersen (@davidkristoffersen)
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#define ENABLE_COMPILE_KEYCODE
+
+// Userspace defines
+// #define SPLIT_SPACE
+// #define NO_SPECIAL_SHIFT
+#define LAYER_EN QGMLWB_EN
+#define LAYER_NO QGMLWB_NO
diff --git a/keyboards/planck/keymaps/prog_qgmlwb/keymap.c b/keyboards/planck/keymaps/prog_qgmlwb/keymap.c
new file mode 100644
index 0000000000..72e67ac3e7
--- /dev/null
+++ b/keyboards/planck/keymaps/prog_qgmlwb/keymap.c
@@ -0,0 +1,4 @@
+// Copyright 2022 David Kristoffersen (@davidkristoffersen)
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "src/layouts.h"
diff --git a/keyboards/planck/keymaps/prog_qgmlwb/readme.md b/keyboards/planck/keymaps/prog_qgmlwb/readme.md
new file mode 100644
index 0000000000..e9117507cd
--- /dev/null
+++ b/keyboards/planck/keymaps/prog_qgmlwb/readme.md
@@ -0,0 +1,82 @@
+# PROG-QGMLWB
+
+The prog-qgmlwb layout is a QMK firmware layout for the Planck keyboard.
+
+For letter placement, the layout uses the optimized QGMLWB layout from the [Carpalx project](http://mkweb.bcgsc.ca/carpalx).
+
+> The carpalx project introduces a quantitative model for typing effort and applies it to (a) evaluate QWERTY and popular alternatives, such as Dvorak and Colemak and (b) find the keyboard layouts that minimize typing effort for a given set of input documents.
+
+Carpalx named "QGMLWB" as the fully optimized layout according to the English alphabet, with an effort reduction of approximately 44.4%.
+
+The programming part of the name is inspired by the modified version of Dvorak, [Programmer Dvorak](http://programmer-dvorak.appspot.com), where the symbols have been adjusted logically for developers.
+
+The final layout swaps some Dvorak symbols and combines them with the QGMLWB letters, giving it the name **prog-qgmlwb**.
+
+The layout includes an English and Norwegian layer, whereas the Norwegian one only adds the three letters; æ, ø, and å.
+
+## Typing layers
+
+![Typing layers](https://i.imgur.com/QaHnqW8.png)
+
+## Adjust layer
+
+![Adjust layer](https://i.imgur.com/63I69P0.png)
+
+## Usage
+
+### Clone the QMK Firmware repo
+
+```bash
+git clone --recurse-submodules https://github.com/qmk/qmk_firmware.git <path/name>
+```
+
+### Move into this keymap
+
+```bash
+cd <path/name>/keyboards/planck/keymaps/prog_qgmlwb
+```
+
+### Initialize QMK the first time
+
+Set default keyboard:
+
+```bash
+qmk config user.keyboard=planck/<rev>
+```
+
+Set default keymap:
+
+```bash
+qmk config user.keymap=prog_qgmlwb
+```
+
+Initialize libraries:
+
+```bash
+qmk setup
+```
+
+### Compile and flash the keyboard
+
+```bash
+qmk compile
+qmk flash
+```
+
+## QMK documentation
+
+Found in the QMK docs: <https://docs.qmk.fm>
+
+## Printing layout
+
+This keymap uses macros such that [qmk configurator](https://config.qmk.fm) cannot match its behavior. The images was designed using [Figma](https://figma.com).
+
+## Future additions
+
+Features disabled due to the lack of storage space in the Planck PCB version 5:
+
+- Audio
+- Plover mode
+- Use alt codes to fix missing characters in the english layout
+- Improve documentation of code and readme files
+- Reimplement right version of modifier keys through raise+space
diff --git a/keyboards/planck/keymaps/prog_qgmlwb/rules.mk b/keyboards/planck/keymaps/prog_qgmlwb/rules.mk
new file mode 100644
index 0000000000..7431d9e0b7
--- /dev/null
+++ b/keyboards/planck/keymaps/prog_qgmlwb/rules.mk
@@ -0,0 +1,6 @@
+# Compiler source files
+SRC += src/layouts.c
+
+USER_NAME := davidkristoffersen
+
+SIZE_OPTIMIZE = yes
diff --git a/keyboards/planck/keymaps/prog_qgmlwb/src/enums.h b/keyboards/planck/keymaps/prog_qgmlwb/src/enums.h
new file mode 100644
index 0000000000..0c03b5dd04
--- /dev/null
+++ b/keyboards/planck/keymaps/prog_qgmlwb/src/enums.h
@@ -0,0 +1,23 @@
+// Copyright 2022 David Kristoffersen (@davidkristoffersen)
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+// Layouts enum
+enum keyboard_layouts {
+ QGMLWB_NO,
+ QGMLWB_EN,
+
+ QWERTY,
+ COLEMAK,
+ DVORAK,
+
+ NORMAL_LOWER,
+ NORMAL_RAISE,
+
+ QGMLWB_LOWER,
+ QGMLWB_RAISE,
+
+ ADJUST,
+ NUMPAD,
+};
diff --git a/keyboards/planck/keymaps/prog_qgmlwb/src/layouts.c b/keyboards/planck/keymaps/prog_qgmlwb/src/layouts.c
new file mode 100644
index 0000000000..54ff411d86
--- /dev/null
+++ b/keyboards/planck/keymaps/prog_qgmlwb/src/layouts.c
@@ -0,0 +1,25 @@
+// Copyright 2022 David Kristoffersen (@davidkristoffersen)
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "layouts.h"
+#ifdef LAYER_NO
+# include "sendstring_norwegian.h"
+#endif
+
+KEYMAP keymaps [][MATRIX_ROWS][MATRIX_COLS] = {
+ [QGMLWB_NO] = qgmlwb_no_map,
+ [QGMLWB_EN] = qgmlwb_en_map,
+
+ [QWERTY] = qwerty_map,
+ [COLEMAK] = colemak_map,
+ [DVORAK] = dvorak_map,
+
+ [NORMAL_LOWER] = normal_lower_map,
+ [NORMAL_RAISE] = normal_raise_map,
+
+ [QGMLWB_LOWER] = qgmlwb_lower_map,
+ [QGMLWB_RAISE] = qgmlwb_raise_map,
+
+ [ADJUST] = adjust_map,
+ [NUMPAD] = numpad_map,
+};
diff --git a/keyboards/planck/keymaps/prog_qgmlwb/src/layouts.h b/keyboards/planck/keymaps/prog_qgmlwb/src/layouts.h
new file mode 100644
index 0000000000..19cbefb9ab
--- /dev/null
+++ b/keyboards/planck/keymaps/prog_qgmlwb/src/layouts.h
@@ -0,0 +1,27 @@
+// Copyright 2022 David Kristoffersen (@davidkristoffersen)
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include QMK_KEYBOARD_H
+
+#include "davidkristoffersen.h"
+#include "enums.h"
+
+#include "normal.h"
+#include "qgmlwb.h"
+#include "special.h"
+
+#define KEYMAP const uint16_t PROGMEM
+
+// Layouts keycodes
+#define lower MO(NORMAL_LOWER)
+#define raise MO(NORMAL_RAISE)
+
+#define QLower MO(QGMLWB_LOWER)
+#define QRaise MO(QGMLWB_RAISE)
+
+#define adjust MO(ADJUST)
+#define numpad MO(NUMPAD)
+
+extern KEYMAP keymaps [][MATRIX_ROWS][MATRIX_COLS];
diff --git a/keyboards/planck/keymaps/prog_qgmlwb/src/normal.h b/keyboards/planck/keymaps/prog_qgmlwb/src/normal.h
new file mode 100644
index 0000000000..fa5c84d217
--- /dev/null
+++ b/keyboards/planck/keymaps/prog_qgmlwb/src/normal.h
@@ -0,0 +1,96 @@
+// Copyright 2022 David Kristoffersen (@davidkristoffersen)
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include "layouts.h"
+
+/* Qwerty
+ * ,-----------------------------------------------------------------------------------.
+ * | Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Esc | A | S | D | F | G | H | J | K | L | ;: |Return|
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Shift| Z | X | C | V | B | N | M | ,< | .> | /? | Shift|
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Ctrl | Alt |NumPad| GUI | Lower| Space| Space| Raise| Left | Down | Up | Right|
+ * `-----------------------------------------------------------------------------------'
+*/
+#define qwerty_map LAYOUT_ortho_4x12(\
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC,\
+ KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_ENT,\
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSHIFT,\
+ KC_LCTL, KC_LALT, numpad, KC_LGUI, lower, KC_SPC, KC_SPC, raise, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT\
+)
+
+/* Colemak
+ * ,-----------------------------------------------------------------------------------.
+ * | Tab | Q | W | F | P | G | J | L | U | Y | ; | Bksp |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Esc | A | R | S | T | D | H | N | E | I | O |Return|
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Shift| Z | X | C | V | B | K | M | , | . | / | " |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Ctrl | Alt |NumPad| GUI | Lower| Space| Space| Raise| Left | Down | Up | Right|
+ * `-----------------------------------------------------------------------------------'
+*/
+#define colemak_map LAYOUT_ortho_4x12(\
+ KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC,\
+ KC_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_ENT,\
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_QUOT,\
+ KC_LCTL, KC_LALT, numpad, KC_LGUI, lower, KC_SPC, KC_SPC, raise, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT\
+)
+
+/* Dvorak
+ * ,-----------------------------------------------------------------------------------.
+ * | Tab | " | , | . | P | Y | F | G | C | R | L | Bksp |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Esc | A | O | E | U | I | D | H | T | N | S |Return|
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Shift| ; | Q | J | K | X | B | M | W | V | Z | \ |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Ctrl | Alt |NumPad| GUI | Lower| Space| Space| Raise| Left | Down | Up | Right|
+ * `-----------------------------------------------------------------------------------'
+*/
+#define dvorak_map LAYOUT_ortho_4x12(\
+ KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC,\
+ KC_ESC, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_ENT,\
+ KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_SLSH,\
+ KC_LCTL, KC_LALT, numpad, KC_LGUI, lower, KC_SPC, KC_SPC, raise, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT\
+)
+
+/* Lower - Normal
+ * ,-----------------------------------------------------------------------------------.
+ * | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Bksp |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Del | F1 | F2 | F3 | F4 | F5 | F6 | _ | + | { | } | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | F7 | F8 | F9 | F10 | F11 | F12 | End | Home | XXXX | XXXX | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | | | Next | Vol- | Vol+ | Play |
+ * `-----------------------------------------------------------------------------------'
+*/
+#define normal_lower_map LAYOUT_ortho_4x12(\
+ KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC,\
+ KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE,\
+ _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_END, KC_HOME, XXXXXXX, XXXXXXX, _______,\
+ _______, _______, _______, _______, _______, _______, _______, adjust, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY\
+)
+
+/* Raise - Normal
+ * ,-----------------------------------------------------------------------------------.
+ * | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Del | F1 | F2 | F3 | F4 | F5 | F6 | - | = | [ | ] | \ |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | F7 | F8 | F9 | F10 | F11 | F12 | # | \ | PgDn | PgUp | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | | | Next | Vol- | Vol+ | Play |
+ * `-----------------------------------------------------------------------------------'
+*/
+#define normal_raise_map LAYOUT_ortho_4x12(\
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC,\
+ KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS,\
+ _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_HASH, KC_BSLS, KC_PGDN, KC_PGUP, _______,\
+ _______, _______, _______, _______, adjust, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY\
+)
diff --git a/keyboards/planck/keymaps/prog_qgmlwb/src/qgmlwb.h b/keyboards/planck/keymaps/prog_qgmlwb/src/qgmlwb.h
new file mode 100644
index 0000000000..bad7a11615
--- /dev/null
+++ b/keyboards/planck/keymaps/prog_qgmlwb/src/qgmlwb.h
@@ -0,0 +1,63 @@
+// Copyright 2022 David Kristoffersen (@davidkristoffersen)
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include "layouts.h"
+
+/* QGMLWB
+ * ,-----------------------------------------------------------------------------------.
+ * | Tab | Q | G | M | L | W | B | Y | U | V | '" | Bksp |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Esc | D | S | T | N | R | I | A | E | O | H |Return|
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Shift| Z | X | C | F | J | K | P | ,; | .: | -_ | \| |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Ctrl | Alt |NumPad| GUI | Lower|LSpace|RSpace| Raise| Left | Down | Up | Right|
+ * `-----------------------------------------------------------------------------------'
+*/
+// English Layout
+#define qgmlwb_en_map LAYOUT_ortho_4x12(\
+ KC_TAB, KC_Q, KC_G, KC_M, KC_L, KC_W, KC_B, KC_Y, KC_U, KC_V, KC_QUOT, KC_BSPC,\
+ KC_ESC, KC_D, KC_S, KC_T, KC_N, KC_R, KC_I, KC_A, KC_E, KC_O, KC_H, KC_ENT,\
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_F, KC_J, KC_K, KC_P, KC_COMM, KC_DOT, KC_MINS, KC_BSLS,\
+ KC_LCTL, KC_LALT, numpad, KC_LGUI, QLower, KC_LSPC, KC_RSPC, QRaise, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT\
+)
+// Norwegian Layout
+#define qgmlwb_no_map qgmlwb_en_map
+
+/* Lower - QGMLWB
+ * ,-----------------------------------------------------------------------------------.
+ * | ! | % | [ | { | ( | < | > | ) | } | ] | & | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Del | Mute | XXXX | Refr | XXXX | XXXX | XXXX | = | + | * | / | ~ |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | Sleep|ScrLck| Caps |NumLck|PrtScr| Ins | End | Home | Æ | Ø | Å |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | |Adjust| Bri- | Vol- | Vol+ | Bri+ |
+ * `-----------------------------------------------------------------------------------'
+*/
+#define qgmlwb_lower_map LAYOUT_ortho_4x12(\
+ KC_EXLM, KC_PERC, KC_LBRC, KC_LCBR, KC_LPRN, KC_LT, KC_GT, KC_RPRN, KC_RCBR, KC_RBRC, KC_AMPR, _______,\
+ KC_DEL, KC_MUTE, XXXXXXX, KC_WREF, XXXXXXX, XXXXXXX, XXXXXXX, KC_EQL, KC_PLUS, KC_ASTR, KC_SLSH, KC_TILD,\
+ _______, KC_SLEP, KC_SLCK, KC_CAPS, KC_NLCK, KC_PSCR, KC_INS, KC_END, KC_HOME, KC_AE, KC_OE, KC_AA,\
+ _______, _______, _______, _______, _______, _______, _______, adjust, KC_BRID, KC_VOLD, KC_VOLU, KC_BRIU\
+)
+
+/* Raise - QGMLWB
+ * ,-----------------------------------------------------------------------------------.
+ * | ? | 9 | 7 | 5 | 3 | 1 | 0 | 2 | 4 | 6 | 8 | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Del+ | F1 | F2 | F3 | F4 | F5 | F6 | # | @ | ^ | $ | ` |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |RShift| F7 | F8 | F9 | F10 | F11 | F12 | PgDn | PgUp | XXXX | XXXX | XXXX |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | RCtrl| RAlt | | |Adjust| | | | Prev | Stop | Play | Next |
+ * `-----------------------------------------------------------------------------------'
+*/
+#define qgmlwb_raise_map LAYOUT_ortho_4x12(\
+ KC_QUES, KC_9, KC_7, KC_5, KC_3, KC_1, KC_0, KC_2, KC_4, KC_6, KC_8, _______,\
+ S(KC_DEL), KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_HASH, KC_AT, KC_CIRC, KC_DLR, KC_GRV,\
+ _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PGDN, KC_PGUP, XXXXXXX, XXXXXXX, XXXXXXX,\
+ _______, _______, _______, _______, adjust, _______, _______, _______, KC_MPRV, KC_MSTP, KC_MPLY, KC_MNXT\
+)
diff --git a/keyboards/planck/keymaps/prog_qgmlwb/src/special.h b/keyboards/planck/keymaps/prog_qgmlwb/src/special.h
new file mode 100644
index 0000000000..de05db2070
--- /dev/null
+++ b/keyboards/planck/keymaps/prog_qgmlwb/src/special.h
@@ -0,0 +1,43 @@
+// Copyright 2022 David Kristoffersen (@davidkristoffersen)
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include "layouts.h"
+
+/* Adjust
+ * v------------------------RGB CONTROL--------------------v
+ * ,-----------------------------------------------------------------------------------.
+ * | | Reset| Debug| RGB |RGBMod| Hue- | Hue+ | Sat- | Sat+ | Bri- | Bri+ | Del |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | XXXX |MusMod|AudOff| AudOn|AgNorm|AgSwap|Dvorak|Colmak|Qwerty|QgmlEN|QgmlNO|
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | |Voice-|Voice+|MusOff| MusOn|MIDIOf|MIDIOn|TermOf|TermOn| T0 | T1 | T2 |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | | XXXX | XXXX | XXXX | XXXX |
+ * `-----------------------------------------------------------------------------------'
+*/
+#define adjust_map LAYOUT_ortho_4x12(\
+ QK_RBT, QK_BOOT, DB_TOGG, RGB_TOG, RGB_MOD, RGB_HUD, RGB_HUI, RGB_SAD, RGB_SAI, RGB_VAD, RGB_VAI, KC_DEL,\
+ QK_MAKE, XXXXXXX, MU_MOD, AU_OFF, AU_ON, AG_NORM, AG_SWAP, DF(DVORAK), DF(COLEMAK), DF(QWERTY), DF(QGMLWB_EN), DF(QGMLWB_NO),\
+ _______, MUV_IN, MUV_DE, MU_OFF, MU_ON, MI_OFF, MI_ON, TERM_OFF, TERM_ON, KC_T0, KC_T1, KC_T2,\
+ _______, _______, _______, _______, _______, _______, _______, _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX\
+)
+
+/* Numpad
+ * ,-----------------------------------------------------------------------------------.
+ * | | XXXX | XXXX | XXXX | XXXX | XXXX | XXXX | 7 | 8 | 9 | / | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | XXXX | XXXX | XXXX | XXXX | XXXX | XXXX | 4 | 5 | 6 | * | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | XXXX | XXXX | XXXX | XXXX | XXXX | XXXX | 1 | 2 | 3 | - | XXXX |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | XXXX | | | 0 | , | . | + | XXXX |
+ * `-----------------------------------------------------------------------------------'
+*/
+#define numpad_map LAYOUT_ortho_4x12(\
+ _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_7, KC_8, KC_9, KC_KP_SLASH, _______,\
+ _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_4, KC_5, KC_6, KC_KP_ASTERISK, _______,\
+ _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_1, KC_2, KC_3, KC_KP_MINUS, XXXXXXX,\
+ _______, _______, _______, _______, XXXXXXX, _______, _______, KC_0, KC_COMM, KC_DOT, KC_KP_PLUS, XXXXXXX\
+)
diff --git a/users/davidkristoffersen/davidkristoffersen.h b/users/davidkristoffersen/davidkristoffersen.h
new file mode 100644
index 0000000000..0485e00013
--- /dev/null
+++ b/users/davidkristoffersen/davidkristoffersen.h
@@ -0,0 +1,18 @@
+// Copyright 2022 David Kristoffersen (@davidkristoffersen)
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include QMK_KEYBOARD_H
+
+#include "src/enums.h"
+
+#ifdef LAYER_NO
+# include "macros/norwegian.h"
+#endif
+
+#include "util/functions.h"
+
+#include "hardware/split_space.h"
+
+#include "macros/macros.h"
diff --git a/users/davidkristoffersen/hardware/readme.md b/users/davidkristoffersen/hardware/readme.md
new file mode 100644
index 0000000000..f31601812b
--- /dev/null
+++ b/users/davidkristoffersen/hardware/readme.md
@@ -0,0 +1,3 @@
+# Hardware
+
+This directory contains hardware related macros.
diff --git a/users/davidkristoffersen/hardware/split_space.c b/users/davidkristoffersen/hardware/split_space.c
new file mode 100644
index 0000000000..da25343f3d
--- /dev/null
+++ b/users/davidkristoffersen/hardware/split_space.c
@@ -0,0 +1,23 @@
+// Copyright 2022 David Kristoffersen (@davidkristoffersen)
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "split_space.h"
+
+#ifdef SPLIT_SPACE
+void handle_split_space(uint16_t keycode) {
+ // Disable modifiers when numpad is active
+ if (IS_LAYER_ON(NUMPAD)) clear_oneshot_mods();
+
+ if (keycode == KC_LSPC) {
+ // 2ng tap: Activate ctrl if shift is active
+ if (get_oneshot_mods() & MOD_MASK_SHIFT) {
+ clear_oneshot_mods();
+ set_oneshot_mods(MOD_LCTL);
+ }
+ // 1st. tap: Activate shift if no modifier is active
+ else {
+ set_oneshot_mods(MOD_LSFT);
+ }
+ }
+}
+#endif
diff --git a/users/davidkristoffersen/hardware/split_space.h b/users/davidkristoffersen/hardware/split_space.h
new file mode 100644
index 0000000000..a9736b5ca1
--- /dev/null
+++ b/users/davidkristoffersen/hardware/split_space.h
@@ -0,0 +1,16 @@
+// Copyright 2022 David Kristoffersen (@davidkristoffersen)
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include "davidkristoffersen.h"
+
+#define KC_RSPC KC_SPACE
+
+#ifdef SPLIT_SPACE
+# define KC_LSPC LT(NUMPAD, KC_NO)
+#else
+# define KC_LSPC KC_SPACE
+#endif
+
+void handle_split_space(uint16_t keycode);
diff --git a/users/davidkristoffersen/macros/debug.c b/users/davidkristoffersen/macros/debug.c
new file mode 100644
index 0000000000..64fdc4a702
--- /dev/null
+++ b/users/davidkristoffersen/macros/debug.c
@@ -0,0 +1,36 @@
+// Copyright 2022 David Kristoffersen (@davidkristoffersen)
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "macros.h"
+
+// Replace key records with macros
+bool handle_test(uint16_t keycode) {
+ switch (keycode) {
+ case KC_T0: {
+ // Test QK_MAKE command
+ SEND_STRING("qmk compile -kb " QMK_KEYBOARD " -km " QMK_KEYMAP);
+ break;
+ }
+ case KC_T1:
+ // Test ascii characters
+ SEND_STRING(" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~");
+ break;
+ case KC_T2:
+#ifdef LAYER_NO
+ // Test other characters
+ tap_code16(NO_AE);
+ tap_code16(NO_OE);
+ tap_code16(NO_AA);
+ tap_code16(S(NO_AE));
+ tap_code16(S(NO_OE));
+ tap_code16(S(NO_AA));
+#endif
+ return false;
+ }
+ return true;
+};
+
+bool process_debug(uint16_t keycode, keyrecord_t* record) {
+ HANDLE_FALSE(handle_test(keycode));
+ return true;
+}
diff --git a/users/davidkristoffersen/macros/language.c b/users/davidkristoffersen/macros/language.c
new file mode 100644
index 0000000000..9b6dca79ca
--- /dev/null
+++ b/users/davidkristoffersen/macros/language.c
@@ -0,0 +1,40 @@
+// Copyright 2022 David Kristoffersen (@davidkristoffersen)
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "macros.h"
+
+bool handle_language(uint16_t keycode) {
+#ifdef LAYER_NO
+ // Handle conversion of English to Norwegian codes
+ uint16_t org_keycode = keycode;
+ keycode = get_norwegian_code(keycode);
+#endif
+
+#ifndef NO_SPECIAL_SHIFT
+ // Handle conversion of special shift codes
+ if (get_mods() & MOD_MASK_SHIFT) {
+ uint16_t shifted_key = get_special_shifted_code(keycode);
+ if (shifted_key != keycode) {
+ // Tap shifted key while shift is disabled
+ unregister_code(KC_LSFT);
+ tap_code16(shifted_key);
+ register_code(KC_LSFT);
+ return false;
+ }
+ }
+#endif
+
+#ifdef LAYER_NO
+ // Tap new language key
+ if (keycode != org_keycode) {
+ tap_code16(keycode);
+ return false;
+ }
+#endif
+ return true;
+}
+
+bool process_language(uint16_t keycode, keyrecord_t* record) {
+ HANDLE_FALSE(handle_language(keycode));
+ return true;
+}
diff --git a/users/davidkristoffersen/macros/macros.c b/users/davidkristoffersen/macros/macros.c
new file mode 100644
index 0000000000..6d8c0b6f57
--- /dev/null
+++ b/users/davidkristoffersen/macros/macros.c
@@ -0,0 +1,16 @@
+// Copyright 2022 David Kristoffersen (@davidkristoffersen)
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "macros.h"
+
+// Prepend key records with macros
+bool process_record_user(uint16_t keycode, keyrecord_t* record) {
+ if (record->event.pressed) {
+#ifdef SPLIT_SPACE
+ handle_split_space(keycode, record);
+#endif
+ HANDLE_FALSE(process_debug(keycode, record));
+ HANDLE_FALSE(process_language(keycode, record));
+ }
+ return true;
+}
diff --git a/users/davidkristoffersen/macros/macros.h b/users/davidkristoffersen/macros/macros.h
new file mode 100644
index 0000000000..fb1e5c862c
--- /dev/null
+++ b/users/davidkristoffersen/macros/macros.h
@@ -0,0 +1,23 @@
+// Copyright 2022 David Kristoffersen (@davidkristoffersen)
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include "davidkristoffersen.h"
+
+enum keycodes {
+ // Test keys
+ KC_T0 = SAFE_RANGE,
+ KC_T1,
+ KC_T2,
+ // Norwegian Æ, Ø, Å
+ KC_AE,
+ KC_OE,
+ KC_AA
+};
+
+bool process_debug(uint16_t keycode, keyrecord_t* record);
+bool process_language(uint16_t keycode, keyrecord_t* record);
+
+// Prepend key records with macros
+bool process_record_user(uint16_t keycode, keyrecord_t* record);
diff --git a/users/davidkristoffersen/macros/norwegian.h b/users/davidkristoffersen/macros/norwegian.h
new file mode 100644
index 0000000000..575d1e9f2f
--- /dev/null
+++ b/users/davidkristoffersen/macros/norwegian.h
@@ -0,0 +1,19 @@
+// Copyright 2022 David Kristoffersen (@davidkristoffersen)
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include "keymap_extras/keymap_norwegian.h"
+#include "davidkristoffersen.h"
+
+// Better norwegian defines
+#undef NO_LESS
+#define NO_LESS KC_NUBS // <
+#undef NO_GRTR
+#define NO_GRTR S(NO_LESS) // >
+#undef NO_AE
+#define NO_AE KC_QUOT // Æ
+#undef NO_OE
+#define NO_OE KC_SCLN // Ø
+#undef NO_AA
+#define NO_AA KC_LBRC // Å
diff --git a/users/davidkristoffersen/macros/readme.md b/users/davidkristoffersen/macros/readme.md
new file mode 100644
index 0000000000..7c074b2bb5
--- /dev/null
+++ b/users/davidkristoffersen/macros/readme.md
@@ -0,0 +1,3 @@
+# Macros
+
+This directory contains any type of dynamic and static macros.
diff --git a/users/davidkristoffersen/post_config.h b/users/davidkristoffersen/post_config.h
new file mode 100644
index 0000000000..3d1f5a93f4
--- /dev/null
+++ b/users/davidkristoffersen/post_config.h
@@ -0,0 +1,8 @@
+// Copyright 2022 David Kristoffersen (@davidkristoffersen)
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#ifndef LAYER_EN
+# define LAYER_EN LAYER_DEFAULT
+#endif
diff --git a/users/davidkristoffersen/readme.md b/users/davidkristoffersen/readme.md
new file mode 100644
index 0000000000..20ff58003e
--- /dev/null
+++ b/users/davidkristoffersen/readme.md
@@ -0,0 +1,3 @@
+# Overview
+
+This userspace contains all the utility functions and macros related to my keymaps.
diff --git a/users/davidkristoffersen/rules.mk b/users/davidkristoffersen/rules.mk
new file mode 100644
index 0000000000..5901b68540
--- /dev/null
+++ b/users/davidkristoffersen/rules.mk
@@ -0,0 +1,12 @@
+SRC += $(USER_PATH)/util/functions.c \
+ $(USER_PATH)/hardware/split_space.c \
+ $(USER_PATH)/macros/macros.c \
+ $(USER_PATH)/macros/debug.c \
+ $(USER_PATH)/macros/language.c
+
+# Firmware size optimizations
+ifeq ($(strip $(SIZE_OPTIMIZE)), yes)
+ CONSOLE_ENABLE := no # 1646: Console for debug
+ AUDIO_ENABLE := no # 8682: Audio output on port C6
+ LTO_ENABLE := yes # 2772: Link time optimization
+endif
diff --git a/users/davidkristoffersen/util/functions.c b/users/davidkristoffersen/util/functions.c
new file mode 100644
index 0000000000..781d8f214d
--- /dev/null
+++ b/users/davidkristoffersen/util/functions.c
@@ -0,0 +1,111 @@
+// Copyright 2022 David Kristoffersen (@davidkristoffersen)
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "functions.h"
+
+#ifndef NO_SPECIAL_SHIFT
+// Code set to swap struct
+typedef struct code_set {
+ uint16_t pre;
+ uint16_t post;
+} code_set_t;
+
+// Shift codes conversion struct
+typedef struct shift_code {
+ int lang;
+ int size;
+ code_set_t* codes;
+} shift_code_t;
+
+#ifdef LAYER_NO
+code_set_t NO_SHIFT_CODES [] = {
+ {NO_QUOT, NO_DQUO},
+ {NO_BSLS, NO_PIPE},
+};
+#endif
+
+code_set_t EN_SHIFT_CODES [] = {
+ {KC_COMM, KC_SCLN},
+ {KC_DOT, KC_COLN},
+};
+
+// Array of shift code conversions
+const shift_code_t SHIFT_CODES [] = {
+#ifdef LAYER_NO
+ {.lang = LAYER_NO,
+ .size = ARR_LEN(NO_SHIFT_CODES),
+ .codes = NO_SHIFT_CODES},
+#endif
+ {.lang = LAYER_EN,
+ .size = ARR_LEN(EN_SHIFT_CODES),
+ .codes = EN_SHIFT_CODES},
+};
+const int SHIFT_CODES_SIZE = ARR_LEN(SHIFT_CODES);
+#endif
+
+#ifdef LAYER_NO
+// Array of English to Norwegian code translations
+const code_set_t EN2NO_CODES [] = {
+ {KC_QUOT, NO_QUOT},
+ {KC_MINS, NO_MINS},
+ {KC_BSLS, NO_BSLS},
+ {KC_LBRC, NO_LBRC},
+ {KC_LCBR, NO_LCBR},
+ {KC_LPRN, NO_LPRN},
+ {KC_LT, NO_LESS},
+ {KC_GT, NO_GRTR},
+ {KC_RPRN, NO_RPRN},
+ {KC_RCBR, NO_RCBR},
+ {KC_RBRC, NO_RBRC},
+ {KC_AMPR, NO_AMPR},
+ {KC_EQL, NO_EQL},
+ {KC_PLUS, NO_PLUS},
+ {KC_ASTR, NO_ASTR},
+ {KC_SLSH, NO_SLSH},
+ {KC_TILD, NO_TILD},
+ {KC_AE, NO_AE},
+ {KC_OE, NO_OE},
+ {KC_AA, NO_AA},
+ {KC_QUES, NO_QUES},
+ {KC_AT, NO_AT},
+ {KC_CIRC, NO_CIRC},
+ {KC_DLR, NO_DLR},
+ {KC_GRV, NO_GRV}
+};
+const int EN2NO_CODES_SIZE = ARR_LEN(EN2NO_CODES);
+#endif
+
+// Check if layer is an active default layer
+bool is_default_on(int layer) {
+ return layer == LAYER_DEFAULT
+ ? true
+ : layer_state_cmp(default_layer_state, layer);
+}
+
+#ifndef NO_SPECIAL_SHIFT
+// Get special shifted code
+uint16_t get_special_shifted_code(uint16_t keycode) {
+ for (int i = 0; i < SHIFT_CODES_SIZE; i++) {
+ if (IS_DEFAULT_OFF(SHIFT_CODES[i].lang)) continue;
+ for (int j = 0; j < SHIFT_CODES[i].size; j++) {
+ if (keycode == SHIFT_CODES[i].codes[j].pre)
+ return SHIFT_CODES[i].codes[j].post;
+ }
+ }
+ return keycode;
+}
+#endif
+
+#ifdef LAYER_NO
+// Get language specific code
+uint16_t get_norwegian_code(uint16_t keycode) {
+ if (IS_DEFAULT_ON(LAYER_NO)) {
+ for (int i = 0; i < EN2NO_CODES_SIZE; i++) {
+ if (keycode == EN2NO_CODES[i].pre) {
+ return EN2NO_CODES[i].post;
+ }
+ }
+ }
+ return keycode;
+}
+#endif
diff --git a/users/davidkristoffersen/util/functions.h b/users/davidkristoffersen/util/functions.h
new file mode 100644
index 0000000000..eee1dadc57
--- /dev/null
+++ b/users/davidkristoffersen/util/functions.h
@@ -0,0 +1,32 @@
+// Copyright 2022 David Kristoffersen (@davidkristoffersen)
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include "davidkristoffersen.h"
+
+// Default layer if none is specified
+#define LAYER_DEFAULT -1
+
+// Check if layer is an active default layer
+#define IS_DEFAULT_ON(layer) is_default_on(layer)
+// Check if layer is an inactive default layer
+#define IS_DEFAULT_OFF(layer) !is_default_on(layer)
+
+// Return false if test equal false
+#define HANDLE_FALSE(bool) if (!bool) return false;
+// Generic array lenght define
+#define ARR_LEN(arr) (sizeof(arr) / sizeof(arr)[0])
+// Printf-like functionality for send_string
+#define SEND_VAR(str, ...) \
+ do { \
+ char var[128]; \
+ sprintf(var, str, __VA_ARGS__); \
+ send_string(var); \
+ } while(0)
+
+// Get special shifted code
+uint16_t get_special_shifted_code(uint16_t keycode);
+
+// Get language specific code
+uint16_t get_norwegian_code(uint16_t keycode);
diff --git a/users/davidkristoffersen/util/readme.md b/users/davidkristoffersen/util/readme.md
new file mode 100644
index 0000000000..90635f30e5
--- /dev/null
+++ b/users/davidkristoffersen/util/readme.md
@@ -0,0 +1,3 @@
+# Utility
+
+This directory contains utility functions meant to assist the other files of the userspace.