Quellcode durchsuchen

use action function for unicode

Manuel Barkhau vor 9 Jahren
Ursprung
Commit
381a9fd553

+ 158 - 115
keyboard/ergodox_ez/keymaps/german-manuneo/compile_keymap.py

@@ -20,6 +20,7 @@ import sys
 import json
 import unicodedata
 import collections
+import itertools as it
 
 PY2 = sys.version_info.major == 2
 
@@ -27,11 +28,6 @@ if PY2:
     chr = unichr
 
 
-BASEPATH = os.path.abspath(os.path.join(
-    os.path.dirname(__file__), "..", ".."
-))
-
-
 KEYBOARD_LAYOUTS = {
     # These map positions in the parsed layout to
     # positions in the KEYMAP MATRIX
@@ -73,34 +69,33 @@ BLANK_LAYOUTS = [
 
 # Wide Layout
 """
-.--------------------------------------------. .--------------------------------------------.
-|      |     |     |     |     |     |       | !       |     |     |     |     |     |      |
-!------+-----+-----+-----+-----+-------------! !-------+-----+-----+-----+-----+-----+------!
-|      |     |     |     |     |     |       | !       |     |     |     |     |     |      |
-!------+-----+-----+-----x-----x-----!       ! !       !-----x-----x-----+-----+-----+------!
-|      |     |     |     |     |     |-------! !-------!     |     |     |     |     |      |
-!------+-----+-----+-----x-----x-----!       ! !       !-----x-----x-----+-----+-----+------!
-|      |     |     |     |     |     |       | !       |     |     |     |     |     |      |
-'------+-----+-----+-----+-----+-------------' '-------------+-----+-----+-----+-----+------'
- |     |     |     |     |     |                             !     |     |     |     |     |
- '-----------------------------'                             '-----------------------------'
-                             .---------------. .---------------.
-                             |       |       | !       |       |
-                     .-------+-------+-------! !-------+-------+-------.
-                     !       !       |       | !       |       !       !
-                     !       !       !-------! !-------!       !       !
-                     |       |       |       | !       |       |       |
-                     '-----------------------' '-----------------------'
+.---------------------------------------------. .---------------------------------------------.
+|       |     |     |     |     |     |       | !       |     |     |     |     |     |       |
+!-------+-----+-----+-----+-----+-------------! !-------+-----+-----+-----+-----+-----+-------!
+|       |     |     |     |     |     |       | !       |     |     |     |     |     |       |
+!-------+-----+-----+-----x-----x-----!       ! !       !-----x-----x-----+-----+-----+-------!
+|       |     |     |     |     |     |-------! !-------!     |     |     |     |     |       |
+!-------+-----+-----+-----x-----x-----!       ! !       !-----x-----x-----+-----+-----+-------!
+|       |     |     |     |     |     |       | !       |     |     |     |     |     |       |
+'-------+-----+-----+-----+-----+-------------' '-------------+-----+-----+-----+-----+-------'
+ |      |     |     |     |     |                             !     |     |     |     |      |
+ '------------------------------'                             '------------------------------'
+                              .---------------. .---------------.
+                              |       |       | !       |       |
+                      .-------+-------+-------! !-------+-------+-------.
+                      !       !       |       | !       |       !       !
+                      !       !       !-------! !-------!       !       !
+                      |       |       |       | !       |       |       |
+                      '-----------------------' '-----------------------'
 """,
 ]
 
 
 DEFAULT_CONFIG = {
-    "includes_basedir": "quantum/",
     "keymaps_includes": [
         "keymap_common.h",
     ],
-    'filler': "-+.':x",
+    'filler': "-+.'!:x",
     'separator': "|",
     'default_key_prefix': ["KC_"],
 }
@@ -114,31 +109,34 @@ SECTIONS = [
 
 #       Markdown Parsing
 
+ONELINE_COMMENT_RE = re.compile(r"""
+    ^                       # comment must be at the start of the line
+    \s*                     # arbitrary whitespace
+    //                      # start of the comment
+    (.*)                    # the comment
+    $                       # until the end of line
+""", re.MULTILINE | re.VERBOSE
+)
+
+INLINE_COMMENT_RE = re.compile(r"""
+    ([\,\"\[\]\{\}\d])      # anythig that might end a expression
+    \s+                     # comment must be preceded by whitespace
+    //                      # start of the comment
+    \s                      # and succeded by whitespace
+    (?:[^\"\]\}\{\[]*)      # the comment (except things which might be json)
+    $                       # until the end of line
+""", re.MULTILINE | re.VERBOSE)
+
+TRAILING_COMMA_RE = re.compile(r"""
+    ,                       # the comma
+    (?:\s*)                 # arbitrary whitespace
+    $                       # only works if the trailing comma is followed by newline
+    (\s*)                   # arbitrary whitespace
+    ([\]\}])                # end of an array or object
+""", re.MULTILINE | re.VERBOSE)
+
+
 def loads(raw_data):
-    ONELINE_COMMENT_RE = re.compile(r"""
-        ^                       # comment must be at the start of the line
-        \s*                     # arbitrary whitespace
-        //                      # start of the comment
-        (.*)                    # the comment
-        $                       # until the end of line
-    """, re.MULTILINE | re.VERBOSE)
-    
-    INLINE_COMMENT_RE = re.compile(r"""
-        ([\,\"\[\]\{\}\d])      # anythig that might end a expression
-        \s+                     # comment must be preceded by whitespace
-        //                      # start of the comment
-        \s                      # and succeded by whitespace
-        (?:[^\"\]\}\{\[]*)      # the comment (except things which might be json)
-        $                       # until the end of line
-    """, re.MULTILINE | re.VERBOSE)
-    
-    TRAILING_COMMA_RE = re.compile(r"""
-        ,                       # the comma
-        (?:\s*)                 # arbitrary whitespace
-        $                       # only works if the trailing comma is followed by newline
-        (\s*)                   # arbitrary whitespace
-        ([\]\}])                # end of an array or object
-    """, re.MULTILINE | re.VERBOSE)
     if isinstance(raw_data, bytes):
         raw_data = raw_data.decode('utf-8')
 
@@ -164,6 +162,8 @@ def parse_config(path):
             name = line[2:]
         elif line.startswith("## "):
             name = line[3:]
+        else:
+            name = ""
 
         name = name.strip().replace(" ", "_").lower()
         if name in SECTIONS:
@@ -209,6 +209,7 @@ def parse_config(path):
                 pass
 
     end_section()
+    assert 'layout' in config
     return config
 
 #       header file parsing
@@ -218,16 +219,15 @@ IF0_RE = re.compile(r"""
     #if 0
     $.*?
     #endif
-    """, re.MULTILINE | re.DOTALL | re.VERBOSE
-)
+""", re.MULTILINE | re.DOTALL | re.VERBOSE)
 
 
 COMMENT_RE = re.compile(r"""
     /\*
     .*?
     \*/"
-    """, re.MULTILINE | re.DOTALL | re.VERBOSE
-)
+""", re.MULTILINE | re.DOTALL | re.VERBOSE)
+
 
 def read_header_file(path):
     with io.open(path, encoding="utf-8") as fh:
@@ -237,7 +237,7 @@ def read_header_file(path):
     return data
 
 
-def regex_partial(re_str_fmt, flags=re.MULTILINE | re.DOTALL | re.VERBOSE):
+def regex_partial(re_str_fmt, flags):
     def partial(*args, **kwargs):
         re_str = re_str_fmt.format(*args, **kwargs)
         return re.compile(re_str, flags)
@@ -251,8 +251,7 @@ KEYDEF_REP = regex_partial(r"""
         (?:{})          # the prefixes
         (?:\w+)         # the key name
     )                   # capture group end
-    """
-)
+""", re.MULTILINE | re.DOTALL | re.VERBOSE)
 
 
 ENUM_RE = re.compile(r"""
@@ -264,8 +263,7 @@ ENUM_RE = re.compile(r"""
         \}
         ;
     )                   # capture group end
-    """, re.MULTILINE | re.DOTALL | re.VERBOSE
-)
+""", re.MULTILINE | re.DOTALL | re.VERBOSE)
 
 
 ENUM_KEY_REP = regex_partial(r"""
@@ -273,8 +271,8 @@ ENUM_KEY_REP = regex_partial(r"""
         {}              # the prefixes
         \w+             # the key name
     )                   # capture group end
-    """
-)
+""", re.MULTILINE | re.DOTALL | re.VERBOSE)
+
 
 def parse_keydefs(config, data):
     prefix_options = "|".join(config['key_prefixes'])
@@ -289,26 +287,31 @@ def parse_keydefs(config, data):
             yield key_match.groups()[0]
 
 
-def parse_valid_keys(config):
-    valid_keycodes = set()
-    paths = [
-        os.path.join(BASEPATH, "tmk_core", "common", "keycode.h")
-    ] + [
-        os.path.join(
-            BASEPATH, config['includes_dir'], include_path
-        ) for include_path in config['keymaps_includes']
-    ]
+def parse_valid_keys(config, out_path):
+    basepath = os.path.abspath(os.path.join(os.path.dirname(out_path)))
+    dirpaths = []
+    subpaths = []
+    while len(subpaths) < 6:
+        path = os.path.join(basepath, *subpaths)
+        dirpaths.append(path)
+        dirpaths.append(os.path.join(path, "tmk_core", "common"))
+        dirpaths.append(os.path.join(path, "quantum"))
+        subpaths.append('..')
+
+    includes = set(config['keymaps_includes'])
+    includes.add("keycode.h")
 
-    for path in paths:
-        path = path.replace("/", os.sep)
-        # the config always uses forward slashe
-        if os.path.exists(path):
-            header_data = read_header_file(path)
+    valid_keycodes = set()
+    for dirpath, include in it.product(dirpaths, includes):
+        include_path = os.path.join(dirpath, include)
+        if os.path.exists(include_path):
+            header_data = read_header_file(include_path)
             valid_keycodes.update(
                 parse_keydefs(config, header_data)
             )
     return valid_keycodes
 
+
 #       Keymap Parsing
 
 def iter_raw_codes(layer_lines, filler, separator):
@@ -325,6 +328,7 @@ def iter_raw_codes(layer_lines, filler, separator):
 def iter_indexed_codes(raw_codes, key_indexes):
     key_rows = {}
     key_indexes_flat = []
+
     for row_index, key_indexes in enumerate(key_indexes):
         for key_index in key_indexes:
             key_rows[key_index] = row_index
@@ -384,8 +388,8 @@ def parse_code(raw_code, key_prefixes, valid_keycodes):
         return raw_code, None, None
 
     if MACRO_RE.match(raw_code):
-        code = macro_id = raw_code[2:-1]
-        return code, macro_id, None
+        macro_id = raw_code[2:-1]
+        return raw_code, macro_id, None
 
     if UNICODE_RE.match(raw_code):
         hex_code = raw_code[1:]
@@ -404,10 +408,17 @@ def parse_keymap(config, key_indexes, layer_lines, valid_keycodes):
         layer_lines, config['filler'], config['separator']
     ))
     indexed_codes = iter_indexed_codes(raw_codes, key_indexes)
+    key_prefixes = config['key_prefixes']
     for raw_code, key_index, row_index in indexed_codes:
         code, macro_id, uc_hex = parse_code(
-            raw_code, config['key_prefixes'], valid_keycodes
+            raw_code, key_prefixes, valid_keycodes
+        )
+        # TODO: line numbers for invalid codes
+        err_msg = "Could not parse key '{}' on row {}".format(
+            raw_code, row_index
         )
+        assert code is not None, err_msg
+        # print(repr(raw_code), repr(code), macro_id, uc_hex)
         if macro_id:
             config['macro_ids'].add(macro_id)
         if uc_hex:
@@ -482,9 +493,64 @@ void matrix_scan_user(void) {
 MACROCODE = """
 #define UC_MODE_WIN 0
 #define UC_MODE_LINUX 1
+#define UC_MODE_OSX 2
 
+// TODO: allow default mode to be configured
 static uint16_t unicode_mode = UC_MODE_WIN;
 
+uint16_t hextokeycode(uint8_t hex) {{
+    if (hex == 0x0) {{
+        return KC_P0;
+    }}
+    if (hex < 0xA) {{
+        return KC_P1 + (hex - 0x1);
+    }}
+    return KC_A + (hex - 0xA);
+}}
+
+void unicode_action_function(uint16_t hi, uint16_t lo) {{
+    switch (unicode_mode) {{
+    case UC_MODE_WIN:
+        register_code(KC_LALT);
+
+        register_code(KC_PPLS);
+        unregister_code(KC_PPLS);
+
+        register_code(hextokeycode((hi & 0xF0) >> 4));
+        unregister_code(hextokeycode((hi & 0xF0) >> 4));
+        register_code(hextokeycode((hi & 0x0F)));
+        unregister_code(hextokeycode((hi & 0x0F)));
+        register_code(hextokeycode((lo & 0xF0) >> 4));
+        unregister_code(hextokeycode((lo & 0xF0) >> 4));
+        register_code(hextokeycode((lo & 0x0F)));
+        unregister_code(hextokeycode((lo & 0x0F)));
+
+        unregister_code(KC_LALT);
+        break;
+    case UC_MODE_LINUX:
+        register_code(KC_LCTL);
+        register_code(KC_LSFT);
+
+        register_code(KC_U);
+        unregister_code(KC_U);
+
+        register_code(hextokeycode((hi & 0xF0) >> 4));
+        unregister_code(hextokeycode((hi & 0xF0) >> 4));
+        register_code(hextokeycode((hi & 0x0F)));
+        unregister_code(hextokeycode((hi & 0x0F)));
+        register_code(hextokeycode((lo & 0xF0) >> 4));
+        unregister_code(hextokeycode((lo & 0xF0) >> 4));
+        register_code(hextokeycode((lo & 0x0F)));
+        unregister_code(hextokeycode((lo & 0x0F)));
+
+        unregister_code(KC_LCTL);
+        unregister_code(KC_LSFT);
+        break;
+    case UC_MODE_OSX:
+        break;
+    }}
+}}
+
 const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {{
     if (!record->event.pressed) {{
         return MACRO_NONE;
@@ -494,57 +560,35 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {{
         case UM:
             unicode_mode = (unicode_mode + 1) % 2;
             break;
-        {macro_cases}
+{macro_cases}
+{unicode_macro_cases}
         default:
             break;
     }}
-    if (unicode_mode == UC_MODE_WIN) {{
-        switch(id) {{
-            {win_macro_cases}
-            default:
-                break;
-        }}
-    }} else if (unicode_mode == UC_MODE_LINUX) {{
-        switch(id) {{
-            {linux_macro_cases}
-            default:
-                break;
-        }}
-    }}
     return MACRO_NONE;
 }};
 """
 
-WIN_UNICODE_MACRO_TEMPLATE = """
-case {0}:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), {1}, U(LALT), END
-    );
-"""
 
-LINUX_UNICODE_MACRO_TEMPLATE = """
-case {0}:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), {1}, T(KP_ENTER), END
-    );
-"""
+UNICODE_MACRO_TEMPLATE = """
+case {macro_id}:
+    unicode_action_function(0x{hi:02x}, 0x{lo:02x});
+    break;
+""".strip()
 
-def macro_cases(config, mode):
-    if mode == 'win':
-        template = WIN_UNICODE_MACRO_TEMPLATE
-    elif mode == 'linux':
-        template = LINUX_UNICODE_MACRO_TEMPLATE
-    else:
-        raise ValueError("Invalid mode: ", mode)
-    template = template.strip()
 
+def unicode_macro_cases(config):
     for macro_id, uc_hex in config['unicode_macros'].items():
+        hi = int(uc_hex, 16) >> 8
+        lo = int(uc_hex, 16) & 0xFF
         unimacro_keys = ", ".join(
             "T({})".format(
                 "KP_" + digit if digit.isdigit() else digit
             ) for digit in uc_hex
         )
-        yield template.format(macro_id, unimacro_keys)
+        yield UNICODE_MACRO_TEMPLATE.format(
+            macro_id=macro_id, hi=hi, lo=lo
+        )
 
 
 def iter_keymap_lines(keymap):
@@ -599,8 +643,7 @@ def iter_keymap_parts(config, keymaps):
     # macros
     yield MACROCODE.format(
         macro_cases="",
-        win_macro_cases="\n".join(macro_cases(config, mode='win')),
-        linux_macro_cases="\n".join(macro_cases(config, mode='linux')),
+        unicode_macro_cases="\n".join(unicode_macro_cases(config)),
     )
 
     # TODO: dynamically create blinking lights
@@ -624,7 +667,7 @@ def main(argv=sys.argv[1:]):
         out_path = os.path.join(dirname, "keymap.c")
 
     config = parse_config(in_path)
-    valid_keys = parse_valid_keys(config)
+    valid_keys = parse_valid_keys(config, out_path)
     keymaps = parse_keymaps(config, valid_keys)
 
     with io.open(out_path, mode="w", encoding="utf-8") as fh:

BIN
keyboard/ergodox_ez/keymaps/german-manuneo/german-manuneo.hex


+ 250 - 754
keyboard/ergodox_ez/keymaps/german-manuneo/keymap.c

@@ -106,8 +106,6 @@
 #define L4   4      // layer_4
 #define L5   5      // layer_5
 #define L6   6      // layer_6
-#define L7   7      // layer_7
-#define L8   8      // layer_8
 
 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 /*
@@ -120,7 +118,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  * !-----+----+----+----x----x----!     !     !----x----x----+----+----+-----!
  * |MO(3)| UE | OE | AE | C  | V  |END  | TAB | B  | M  |COMM| DOT| UP |  Y  |
  * '-----+----+----+----+----+----------'----------+----+----+----+----+-----'
- *  |    |    |LGUI|LALT|LCTL|                     !LALT|    |LEFT|DOWN|RGHT|
+ *  |    |    |LGUI|LALT|LCTL|                     !RCTL|RALT|LEFT|DOWN|RGHT|
  *  '------------------------'                     '------------------------'
  *                         .-----------. .-----------.
  *                         |INS  |TG(2)| !M(UM)|DELT |
@@ -143,8 +141,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  TG(2), DE_H, DE_J, DE_K, DE_L, DE_Q, DE_Z,
  DE_S, DE_N, DE_R, DE_T, DE_D, DE_SS,
  KC_TAB, DE_B, DE_M, DE_COMM, DE_DOT, KC_UP, DE_Y,
- KC_LALT, KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT,
- UM, KC_DELT,
+ KC_RCTL, KC_RALT, KC_LEFT, KC_DOWN, KC_RGHT,
+ M(UM), KC_DELT,
  KC_PGUP,
  KC_PGDN, KC_ENTER, KC_SPACE
 ),
@@ -376,91 +374,70 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  KC_TRNS,
  KC_TRNS, KC_TRNS, KC_TRNS
 ),
-/*
- * .------------------------------------.------------------------------------.
- * |     |    |    |    |    |    |     |     |    |    |    |    |    |     |
- * !-----+----+----+----+----+----------!-----+----+----+----+----+----+-----!
- * |     |    |    |    |    |    |     |     |    |    |    |    |    |     |
- * !-----+----+----+----x----x----!     !     !----x----x----+----+----+-----!
- * |     |    |    |    |    |    |-----!-----!    |    |    |    |    |     |
- * !-----+----+----+----x----x----!     !     !----x----x----+----+----+-----!
- * |     |    |    |    |    |    |     |     |    |    |    |    |    |     |
- * '-----+----+----+----+----+----------'----------+----+----+----+----+-----'
- *  |    |    |    |    |    |                     !    |    |    |    |    |
- *  '------------------------'                     '------------------------'
- *                         .-----------. .-----------.
- *                         |     |     | !     |     |
- *                   .-----+-----+-----! !-----+-----+-----.
- *                   !     !     |     | !     |     !     !
- *                   !     !     !-----! !-----!     !     !
- *                   |     |     |     | !     |     |     |
- *                   '-----------------' '-----------------'
-*/
-[L7] = KEYMAP(
- 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, 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
-),
-/*
- * .------------------------------------.------------------------------------.
- * |     |    |    |    |    |    |     |     |    |    |    |    |    |     |
- * !-----+----+----+----+----+----------!-----+----+----+----+----+----+-----!
- * |     |    |    |    |    |    |     |     |    |    |    |    |    |     |
- * !-----+----+----+----x----x----!     !     !----x----x----+----+----+-----!
- * |     |    |    |    |    |    |-----!-----!    |    |    |    |    |     |
- * !-----+----+----+----x----x----!     !     !----x----x----+----+----+-----!
- * |     |    |    |    |    |    |     |     |    |    |    |    |    |     |
- * '-----+----+----+----+----+----------'----------+----+----+----+----+-----'
- *  |    |    |    |    |    |                     !    |    |    |    |    |
- *  '------------------------'                     '------------------------'
- *                         .-----------. .-----------.
- *                         |     |     | !     |     |
- *                   .-----+-----+-----! !-----+-----+-----.
- *                   !     !     |     | !     |     !     !
- *                   !     !     !-----! !-----!     !     !
- *                   |     |     |     | !     |     |     |
- *                   '-----------------' '-----------------'
-*/
-[L8] = KEYMAP(
- 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, 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
-),
 };
 
 const uint16_t PROGMEM fn_actions[] = {};
 
 #define UC_MODE_WIN 0
 #define UC_MODE_LINUX 1
+#define UC_MODE_OSX 2
 
+// TODO: allow default mode to be configured
 static uint16_t unicode_mode = UC_MODE_WIN;
 
+uint16_t hextokeycode(uint8_t hex) {
+    if (hex == 0x0) {
+        return KC_P0;
+    }
+    if (hex < 0xA) {
+        return KC_P1 + (hex - 0x1);
+    }
+    return KC_A + (hex - 0xA);
+}
+
+void unicode_action_function(uint16_t hi, uint16_t lo) {
+    switch (unicode_mode) {
+    case UC_MODE_WIN:
+        register_code(KC_LALT);
+
+        register_code(KC_PPLS);
+        unregister_code(KC_PPLS);
+
+        register_code(hextokeycode((hi & 0xF0) >> 4));
+        unregister_code(hextokeycode((hi & 0xF0) >> 4));
+        register_code(hextokeycode((hi & 0x0F)));
+        unregister_code(hextokeycode((hi & 0x0F)));
+        register_code(hextokeycode((lo & 0xF0) >> 4));
+        unregister_code(hextokeycode((lo & 0xF0) >> 4));
+        register_code(hextokeycode((lo & 0x0F)));
+        unregister_code(hextokeycode((lo & 0x0F)));
+
+        unregister_code(KC_LALT);
+        break;
+    case UC_MODE_LINUX:
+        register_code(KC_LCTL);
+        register_code(KC_LSFT);
+
+        register_code(KC_U);
+        unregister_code(KC_U);
+
+        register_code(hextokeycode((hi & 0xF0) >> 4));
+        unregister_code(hextokeycode((hi & 0xF0) >> 4));
+        register_code(hextokeycode((hi & 0x0F)));
+        unregister_code(hextokeycode((hi & 0x0F)));
+        register_code(hextokeycode((lo & 0xF0) >> 4));
+        unregister_code(hextokeycode((lo & 0xF0) >> 4));
+        register_code(hextokeycode((lo & 0x0F)));
+        unregister_code(hextokeycode((lo & 0x0F)));
+
+        unregister_code(KC_LCTL);
+        unregister_code(KC_LSFT);
+        break;
+    case UC_MODE_OSX:
+        break;
+    }
+}
+
 const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
     if (!record->event.pressed) {
         return MACRO_NONE;
@@ -470,772 +447,291 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
         case UM:
             unicode_mode = (unicode_mode + 1) % 2;
             break;
-        
-        default:
-            break;
-    }
-    if (unicode_mode == UC_MODE_WIN) {
-        switch(id) {
-            case UC_GREEK_SMALL_LETTER_OMICRON:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(B), T(F), U(LALT), END
-    );
-case UC_LEFTWARDS_ARROW:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_1), T(KP_9), T(KP_0), U(LALT), END
-    );
-case UC_GREEK_CAPITAL_LETTER_RHO:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(A), T(KP_1), U(LALT), END
-    );
-case UC_SUBSCRIPT_THREE:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_0), T(KP_8), T(KP_3), U(LALT), END
-    );
-case UC_VULGAR_FRACTION_ONE_EIGHTH:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_1), T(KP_5), T(B), U(LALT), END
-    );
-case UC_GREEK_SMALL_LETTER_LAMDA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(B), T(B), U(LALT), END
-    );
-case UC_VULGAR_FRACTION_ONE_THIRD:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_1), T(KP_5), T(KP_3), U(LALT), END
-    );
-case UC_GREEK_SMALL_LETTER_XI:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(B), T(E), U(LALT), END
-    );
-case UC_THERE_DOES_NOT_EXIST:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_2), T(KP_0), T(KP_4), U(LALT), END
-    );
-case UC_SUPERSCRIPT_ONE:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_0), T(B), T(KP_9), U(LALT), END
-    );
-case UC_GREEK_SMALL_LETTER_BETA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(B), T(KP_2), U(LALT), END
-    );
-case UC_SUBSCRIPT_FIVE:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_0), T(KP_8), T(KP_5), U(LALT), END
-    );
-case UC_GREEK_CAPITAL_LETTER_IOTA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(KP_9), T(KP_9), U(LALT), END
-    );
-case UC_VULGAR_FRACTION_ONE_FIFTH:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_1), T(KP_5), T(KP_5), U(LALT), END
-    );
-case UC_GREEK_SMALL_LETTER_PSI:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(C), T(KP_8), U(LALT), END
-    );
-case UC_SUBSCRIPT_NINE:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_0), T(KP_8), T(KP_9), U(LALT), END
-    );
-case UC_SUPERSCRIPT_FOUR:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_0), T(KP_7), T(KP_4), U(LALT), END
-    );
-case UC_RIGHTWARDS_ARROW:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_1), T(KP_9), T(KP_2), U(LALT), END
-    );
-case UC_SUPERSCRIPT_SIX:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_0), T(KP_7), T(KP_6), U(LALT), END
-    );
-case UC_DOWNWARDS_ARROW:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_1), T(KP_9), T(KP_3), U(LALT), END
-    );
-case UC_GREEK_SMALL_LETTER_PI:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(C), T(KP_0), U(LALT), END
-    );
-case UC_SUPERSCRIPT_TWO:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_0), T(B), T(KP_2), U(LALT), END
-    );
-case UC_GREEK_CAPITAL_LETTER_OMEGA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(A), T(KP_9), U(LALT), END
-    );
-case UC_GREEK_CAPITAL_LETTER_PSI:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(A), T(KP_8), U(LALT), END
-    );
-case UC_SUBSCRIPT_FOUR:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_0), T(KP_8), T(KP_4), U(LALT), END
-    );
-case UC_GREEK_CAPITAL_LETTER_NU:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(KP_9), T(D), U(LALT), END
-    );
-case UC_DIVISION_SIGN:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_0), T(F), T(KP_7), U(LALT), END
-    );
-case UC_GREEK_SMALL_LETTER_SIGMA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(C), T(KP_3), U(LALT), END
-    );
-case UC_GREEK_SMALL_LETTER_RHO:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(C), T(KP_1), U(LALT), END
-    );
-case UC_VULGAR_FRACTION_ONE_SIXTH:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_1), T(KP_5), T(KP_9), U(LALT), END
-    );
-case UC_GREEK_SMALL_LETTER_GAMMA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(B), T(KP_3), U(LALT), END
-    );
-case UC_VULGAR_FRACTION_TWO_THIRDS:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_1), T(KP_5), T(KP_4), U(LALT), END
-    );
-case UC_GREEK_SMALL_LETTER_NU:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(B), T(D), U(LALT), END
-    );
-case UC_GREEK_SMALL_LETTER_ZETA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(B), T(KP_6), U(LALT), END
-    );
-case UC_GREEK_SMALL_LETTER_EPSILON:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(B), T(KP_5), U(LALT), END
-    );
-case UC_GREEK_SMALL_LETTER_KAPPA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(B), T(A), U(LALT), END
-    );
-case UC_SUPERSCRIPT_SEVEN:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_0), T(KP_7), T(KP_7), U(LALT), END
-    );
-case UC_GREEK_CAPITAL_LETTER_PI:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(A), T(KP_0), U(LALT), END
-    );
-case UC_GREEK_SMALL_LETTER_FINAL_SIGMA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(C), T(KP_2), U(LALT), END
-    );
-case UC_GREEK_CAPITAL_LETTER_XI:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(KP_9), T(E), U(LALT), END
-    );
-case UC_GREEK_SMALL_LETTER_THETA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(B), T(KP_8), U(LALT), END
-    );
-case UC_GREEK_SMALL_LETTER_ETA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(B), T(KP_7), U(LALT), END
-    );
-case UC_SUBSCRIPT_TWO:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_0), T(KP_8), T(KP_2), U(LALT), END
-    );
-case UC_ASYMPTOTICALLY_EQUAL_TO:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_2), T(KP_4), T(KP_3), U(LALT), END
-    );
-case UC_GREEK_SMALL_LETTER_ALPHA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(B), T(KP_1), U(LALT), END
-    );
-case UC_GREEK_CAPITAL_LETTER_PHI:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(A), T(KP_6), U(LALT), END
-    );
-case UC_GREEK_SMALL_LETTER_PHI:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(C), T(KP_6), U(LALT), END
-    );
-case UC_INFINITY:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_2), T(KP_1), T(E), U(LALT), END
-    );
-case UC_GREEK_CAPITAL_LETTER_OMICRON:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(KP_9), T(F), U(LALT), END
-    );
-case UC_ELEMENT_OF:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_2), T(KP_0), T(KP_8), U(LALT), END
-    );
-case UC_MULTIPLICATION_SIGN:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_0), T(D), T(KP_7), U(LALT), END
-    );
-case UC_SUBSCRIPT_ZERO:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_0), T(KP_8), T(KP_0), U(LALT), END
-    );
-case UC_GREEK_CAPITAL_LETTER_SIGMA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(A), T(KP_3), U(LALT), END
-    );
-case UC_GREEK_SMALL_LETTER_OMEGA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(C), T(KP_9), U(LALT), END
-    );
-case UC_SUBSCRIPT_ONE:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_0), T(KP_8), T(KP_1), U(LALT), END
-    );
-case UC_GREEK_CAPITAL_LETTER_ZETA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(KP_9), T(KP_6), U(LALT), END
-    );
-case UC_GREEK_SMALL_LETTER_TAU:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(C), T(KP_4), U(LALT), END
-    );
-case UC_SUPERSCRIPT_FIVE:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_0), T(KP_7), T(KP_5), U(LALT), END
-    );
-case UC_THERE_EXISTS:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_2), T(KP_0), T(KP_3), U(LALT), END
-    );
-case UC_PLUS_MINUS_SIGN:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_0), T(B), T(KP_1), U(LALT), END
-    );
-case UC_VULGAR_FRACTION_THREE_QUARTERS:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_0), T(B), T(E), U(LALT), END
-    );
-case UC_SUPERSCRIPT_THREE:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_0), T(B), T(KP_3), U(LALT), END
-    );
-case UC_EMPTY_SET:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_2), T(KP_0), T(KP_5), U(LALT), END
-    );
-case UC_UPWARDS_ARROW:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_1), T(KP_9), T(KP_1), U(LALT), END
-    );
-case UC_SUPERSCRIPT_NINE:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_0), T(KP_7), T(KP_9), U(LALT), END
-    );
-case UC_GREEK_SMALL_LETTER_DELTA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(B), T(KP_4), U(LALT), END
-    );
-case UC_GREEK_SMALL_LETTER_MU:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(B), T(C), U(LALT), END
-    );
-case UC_GREEK_CAPITAL_LETTER_KAPPA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(KP_9), T(A), U(LALT), END
-    );
-case UC_SUBSCRIPT_EIGHT:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_0), T(KP_8), T(KP_8), U(LALT), END
-    );
-case UC_GREEK_CAPITAL_LETTER_ALPHA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(KP_9), T(KP_1), U(LALT), END
-    );
-case UC_SUBSCRIPT_SEVEN:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_0), T(KP_8), T(KP_7), U(LALT), END
-    );
-case UC_GREEK_CAPITAL_LETTER_BETA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(KP_9), T(KP_2), U(LALT), END
-    );
-case UC_GREEK_CAPITAL_LETTER_ETA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(KP_9), T(KP_7), U(LALT), END
-    );
-case UC_SUPERSCRIPT_EIGHT:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_0), T(KP_7), T(KP_8), U(LALT), END
-    );
-case UC_SUPERSCRIPT_ZERO:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_0), T(KP_7), T(KP_0), U(LALT), END
-    );
-case UC_NOT_AN_ELEMENT_OF:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_2), T(KP_0), T(KP_9), U(LALT), END
-    );
-case UC_GREEK_SMALL_LETTER_UPSILON:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(C), T(KP_5), U(LALT), END
-    );
-case UC_NOT_EQUAL_TO:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_2), T(KP_6), T(KP_0), U(LALT), END
-    );
-case UC_GREEK_CAPITAL_LETTER_CHI:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(A), T(KP_7), U(LALT), END
-    );
-case UC_FOR_ALL:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_2), T(KP_0), T(KP_0), U(LALT), END
-    );
-case UC_GREEK_CAPITAL_LETTER_TAU:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(A), T(KP_4), U(LALT), END
-    );
-case UC_VULGAR_FRACTION_ONE_QUARTER:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_0), T(B), T(C), U(LALT), END
-    );
-case UC_GREEK_SMALL_LETTER_CHI:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(C), T(KP_7), U(LALT), END
-    );
-case UC_GREEK_CAPITAL_LETTER_THETA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(KP_9), T(KP_8), U(LALT), END
-    );
-case UC_GREEK_SMALL_LETTER_IOTA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(B), T(KP_9), U(LALT), END
-    );
-case UC_GREEK_CAPITAL_LETTER_LAMDA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(KP_9), T(B), U(LALT), END
-    );
-case UC_SUPERSCRIPT_LATIN_SMALL_LETTER_N:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_0), T(KP_7), T(F), U(LALT), END
-    );
-case UC_GREEK_CAPITAL_LETTER_UPSILON:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(A), T(KP_5), U(LALT), END
-    );
-case UC_GREEK_CAPITAL_LETTER_MU:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(KP_9), T(C), U(LALT), END
-    );
-case UC_GREEK_CAPITAL_LETTER_EPSILON:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(KP_9), T(KP_5), U(LALT), END
-    );
-case UC_GREEK_CAPITAL_LETTER_GAMMA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(KP_9), T(KP_3), U(LALT), END
-    );
-case UC_SUBSCRIPT_SIX:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_2), T(KP_0), T(KP_8), T(KP_6), U(LALT), END
-    );
-case UC_GREEK_CAPITAL_LETTER_DELTA:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_3), T(KP_9), T(KP_4), U(LALT), END
-    );
-case UC_VULGAR_FRACTION_ONE_HALF:
-    return MACRODOWN(
-        D(LALT), T(KP_PLUS), T(KP_0), T(KP_0), T(B), T(D), U(LALT), END
-    );
-            default:
-                break;
-        }
-    } else if (unicode_mode == UC_MODE_LINUX) {
-        switch(id) {
-            case UC_GREEK_SMALL_LETTER_OMICRON:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(B), T(F), T(KP_ENTER), END
-    );
+
+case UC_GREEK_SMALL_LETTER_OMICRON:
+    unicode_action_function(0x03, 0xbf);
+    break;
 case UC_LEFTWARDS_ARROW:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_1), T(KP_9), T(KP_0), T(KP_ENTER), END
-    );
+    unicode_action_function(0x21, 0x90);
+    break;
 case UC_GREEK_CAPITAL_LETTER_RHO:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(A), T(KP_1), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xa1);
+    break;
 case UC_SUBSCRIPT_THREE:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_0), T(KP_8), T(KP_3), T(KP_ENTER), END
-    );
+    unicode_action_function(0x20, 0x83);
+    break;
 case UC_VULGAR_FRACTION_ONE_EIGHTH:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_1), T(KP_5), T(B), T(KP_ENTER), END
-    );
+    unicode_action_function(0x21, 0x5b);
+    break;
 case UC_GREEK_SMALL_LETTER_LAMDA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(B), T(B), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xbb);
+    break;
 case UC_VULGAR_FRACTION_ONE_THIRD:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_1), T(KP_5), T(KP_3), T(KP_ENTER), END
-    );
+    unicode_action_function(0x21, 0x53);
+    break;
 case UC_GREEK_SMALL_LETTER_XI:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(B), T(E), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xbe);
+    break;
 case UC_THERE_DOES_NOT_EXIST:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_2), T(KP_0), T(KP_4), T(KP_ENTER), END
-    );
+    unicode_action_function(0x22, 0x04);
+    break;
 case UC_SUPERSCRIPT_ONE:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_0), T(B), T(KP_9), T(KP_ENTER), END
-    );
+    unicode_action_function(0x00, 0xb9);
+    break;
 case UC_GREEK_SMALL_LETTER_BETA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(B), T(KP_2), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xb2);
+    break;
 case UC_SUBSCRIPT_FIVE:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_0), T(KP_8), T(KP_5), T(KP_ENTER), END
-    );
+    unicode_action_function(0x20, 0x85);
+    break;
 case UC_GREEK_CAPITAL_LETTER_IOTA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(KP_9), T(KP_9), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0x99);
+    break;
 case UC_VULGAR_FRACTION_ONE_FIFTH:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_1), T(KP_5), T(KP_5), T(KP_ENTER), END
-    );
+    unicode_action_function(0x21, 0x55);
+    break;
 case UC_GREEK_SMALL_LETTER_PSI:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(C), T(KP_8), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xc8);
+    break;
 case UC_SUBSCRIPT_NINE:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_0), T(KP_8), T(KP_9), T(KP_ENTER), END
-    );
+    unicode_action_function(0x20, 0x89);
+    break;
 case UC_SUPERSCRIPT_FOUR:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_0), T(KP_7), T(KP_4), T(KP_ENTER), END
-    );
+    unicode_action_function(0x20, 0x74);
+    break;
 case UC_RIGHTWARDS_ARROW:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_1), T(KP_9), T(KP_2), T(KP_ENTER), END
-    );
+    unicode_action_function(0x21, 0x92);
+    break;
 case UC_SUPERSCRIPT_SIX:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_0), T(KP_7), T(KP_6), T(KP_ENTER), END
-    );
+    unicode_action_function(0x20, 0x76);
+    break;
 case UC_DOWNWARDS_ARROW:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_1), T(KP_9), T(KP_3), T(KP_ENTER), END
-    );
+    unicode_action_function(0x21, 0x93);
+    break;
 case UC_GREEK_SMALL_LETTER_PI:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(C), T(KP_0), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xc0);
+    break;
 case UC_SUPERSCRIPT_TWO:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_0), T(B), T(KP_2), T(KP_ENTER), END
-    );
+    unicode_action_function(0x00, 0xb2);
+    break;
 case UC_GREEK_CAPITAL_LETTER_OMEGA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(A), T(KP_9), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xa9);
+    break;
 case UC_GREEK_CAPITAL_LETTER_PSI:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(A), T(KP_8), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xa8);
+    break;
 case UC_SUBSCRIPT_FOUR:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_0), T(KP_8), T(KP_4), T(KP_ENTER), END
-    );
+    unicode_action_function(0x20, 0x84);
+    break;
 case UC_GREEK_CAPITAL_LETTER_NU:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(KP_9), T(D), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0x9d);
+    break;
 case UC_DIVISION_SIGN:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_0), T(F), T(KP_7), T(KP_ENTER), END
-    );
+    unicode_action_function(0x00, 0xf7);
+    break;
 case UC_GREEK_SMALL_LETTER_SIGMA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(C), T(KP_3), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xc3);
+    break;
 case UC_GREEK_SMALL_LETTER_RHO:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(C), T(KP_1), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xc1);
+    break;
 case UC_VULGAR_FRACTION_ONE_SIXTH:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_1), T(KP_5), T(KP_9), T(KP_ENTER), END
-    );
+    unicode_action_function(0x21, 0x59);
+    break;
 case UC_GREEK_SMALL_LETTER_GAMMA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(B), T(KP_3), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xb3);
+    break;
 case UC_VULGAR_FRACTION_TWO_THIRDS:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_1), T(KP_5), T(KP_4), T(KP_ENTER), END
-    );
+    unicode_action_function(0x21, 0x54);
+    break;
 case UC_GREEK_SMALL_LETTER_NU:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(B), T(D), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xbd);
+    break;
 case UC_GREEK_SMALL_LETTER_ZETA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(B), T(KP_6), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xb6);
+    break;
 case UC_GREEK_SMALL_LETTER_EPSILON:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(B), T(KP_5), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xb5);
+    break;
 case UC_GREEK_SMALL_LETTER_KAPPA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(B), T(A), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xba);
+    break;
 case UC_SUPERSCRIPT_SEVEN:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_0), T(KP_7), T(KP_7), T(KP_ENTER), END
-    );
+    unicode_action_function(0x20, 0x77);
+    break;
 case UC_GREEK_CAPITAL_LETTER_PI:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(A), T(KP_0), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xa0);
+    break;
 case UC_GREEK_SMALL_LETTER_FINAL_SIGMA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(C), T(KP_2), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xc2);
+    break;
 case UC_GREEK_CAPITAL_LETTER_XI:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(KP_9), T(E), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0x9e);
+    break;
 case UC_GREEK_SMALL_LETTER_THETA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(B), T(KP_8), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xb8);
+    break;
 case UC_GREEK_SMALL_LETTER_ETA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(B), T(KP_7), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xb7);
+    break;
 case UC_SUBSCRIPT_TWO:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_0), T(KP_8), T(KP_2), T(KP_ENTER), END
-    );
+    unicode_action_function(0x20, 0x82);
+    break;
 case UC_ASYMPTOTICALLY_EQUAL_TO:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_2), T(KP_4), T(KP_3), T(KP_ENTER), END
-    );
+    unicode_action_function(0x22, 0x43);
+    break;
 case UC_GREEK_SMALL_LETTER_ALPHA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(B), T(KP_1), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xb1);
+    break;
 case UC_GREEK_CAPITAL_LETTER_PHI:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(A), T(KP_6), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xa6);
+    break;
 case UC_GREEK_SMALL_LETTER_PHI:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(C), T(KP_6), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xc6);
+    break;
 case UC_INFINITY:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_2), T(KP_1), T(E), T(KP_ENTER), END
-    );
+    unicode_action_function(0x22, 0x1e);
+    break;
 case UC_GREEK_CAPITAL_LETTER_OMICRON:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(KP_9), T(F), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0x9f);
+    break;
 case UC_ELEMENT_OF:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_2), T(KP_0), T(KP_8), T(KP_ENTER), END
-    );
+    unicode_action_function(0x22, 0x08);
+    break;
 case UC_MULTIPLICATION_SIGN:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_0), T(D), T(KP_7), T(KP_ENTER), END
-    );
+    unicode_action_function(0x00, 0xd7);
+    break;
 case UC_SUBSCRIPT_ZERO:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_0), T(KP_8), T(KP_0), T(KP_ENTER), END
-    );
+    unicode_action_function(0x20, 0x80);
+    break;
 case UC_GREEK_CAPITAL_LETTER_SIGMA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(A), T(KP_3), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xa3);
+    break;
 case UC_GREEK_SMALL_LETTER_OMEGA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(C), T(KP_9), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xc9);
+    break;
 case UC_SUBSCRIPT_ONE:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_0), T(KP_8), T(KP_1), T(KP_ENTER), END
-    );
+    unicode_action_function(0x20, 0x81);
+    break;
 case UC_GREEK_CAPITAL_LETTER_ZETA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(KP_9), T(KP_6), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0x96);
+    break;
 case UC_GREEK_SMALL_LETTER_TAU:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(C), T(KP_4), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xc4);
+    break;
 case UC_SUPERSCRIPT_FIVE:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_0), T(KP_7), T(KP_5), T(KP_ENTER), END
-    );
+    unicode_action_function(0x20, 0x75);
+    break;
 case UC_THERE_EXISTS:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_2), T(KP_0), T(KP_3), T(KP_ENTER), END
-    );
+    unicode_action_function(0x22, 0x03);
+    break;
 case UC_PLUS_MINUS_SIGN:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_0), T(B), T(KP_1), T(KP_ENTER), END
-    );
+    unicode_action_function(0x00, 0xb1);
+    break;
 case UC_VULGAR_FRACTION_THREE_QUARTERS:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_0), T(B), T(E), T(KP_ENTER), END
-    );
+    unicode_action_function(0x00, 0xbe);
+    break;
 case UC_SUPERSCRIPT_THREE:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_0), T(B), T(KP_3), T(KP_ENTER), END
-    );
+    unicode_action_function(0x00, 0xb3);
+    break;
 case UC_EMPTY_SET:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_2), T(KP_0), T(KP_5), T(KP_ENTER), END
-    );
+    unicode_action_function(0x22, 0x05);
+    break;
 case UC_UPWARDS_ARROW:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_1), T(KP_9), T(KP_1), T(KP_ENTER), END
-    );
+    unicode_action_function(0x21, 0x91);
+    break;
 case UC_SUPERSCRIPT_NINE:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_0), T(KP_7), T(KP_9), T(KP_ENTER), END
-    );
+    unicode_action_function(0x20, 0x79);
+    break;
 case UC_GREEK_SMALL_LETTER_DELTA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(B), T(KP_4), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xb4);
+    break;
 case UC_GREEK_SMALL_LETTER_MU:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(B), T(C), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xbc);
+    break;
 case UC_GREEK_CAPITAL_LETTER_KAPPA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(KP_9), T(A), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0x9a);
+    break;
 case UC_SUBSCRIPT_EIGHT:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_0), T(KP_8), T(KP_8), T(KP_ENTER), END
-    );
+    unicode_action_function(0x20, 0x88);
+    break;
 case UC_GREEK_CAPITAL_LETTER_ALPHA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(KP_9), T(KP_1), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0x91);
+    break;
 case UC_SUBSCRIPT_SEVEN:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_0), T(KP_8), T(KP_7), T(KP_ENTER), END
-    );
+    unicode_action_function(0x20, 0x87);
+    break;
 case UC_GREEK_CAPITAL_LETTER_BETA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(KP_9), T(KP_2), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0x92);
+    break;
 case UC_GREEK_CAPITAL_LETTER_ETA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(KP_9), T(KP_7), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0x97);
+    break;
 case UC_SUPERSCRIPT_EIGHT:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_0), T(KP_7), T(KP_8), T(KP_ENTER), END
-    );
+    unicode_action_function(0x20, 0x78);
+    break;
 case UC_SUPERSCRIPT_ZERO:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_0), T(KP_7), T(KP_0), T(KP_ENTER), END
-    );
+    unicode_action_function(0x20, 0x70);
+    break;
 case UC_NOT_AN_ELEMENT_OF:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_2), T(KP_0), T(KP_9), T(KP_ENTER), END
-    );
+    unicode_action_function(0x22, 0x09);
+    break;
 case UC_GREEK_SMALL_LETTER_UPSILON:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(C), T(KP_5), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xc5);
+    break;
 case UC_NOT_EQUAL_TO:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_2), T(KP_6), T(KP_0), T(KP_ENTER), END
-    );
+    unicode_action_function(0x22, 0x60);
+    break;
 case UC_GREEK_CAPITAL_LETTER_CHI:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(A), T(KP_7), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xa7);
+    break;
 case UC_FOR_ALL:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_2), T(KP_0), T(KP_0), T(KP_ENTER), END
-    );
+    unicode_action_function(0x22, 0x00);
+    break;
 case UC_GREEK_CAPITAL_LETTER_TAU:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(A), T(KP_4), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xa4);
+    break;
 case UC_VULGAR_FRACTION_ONE_QUARTER:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_0), T(B), T(C), T(KP_ENTER), END
-    );
+    unicode_action_function(0x00, 0xbc);
+    break;
 case UC_GREEK_SMALL_LETTER_CHI:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(C), T(KP_7), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xc7);
+    break;
 case UC_GREEK_CAPITAL_LETTER_THETA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(KP_9), T(KP_8), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0x98);
+    break;
 case UC_GREEK_SMALL_LETTER_IOTA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(B), T(KP_9), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xb9);
+    break;
 case UC_GREEK_CAPITAL_LETTER_LAMDA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(KP_9), T(B), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0x9b);
+    break;
 case UC_SUPERSCRIPT_LATIN_SMALL_LETTER_N:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_0), T(KP_7), T(F), T(KP_ENTER), END
-    );
+    unicode_action_function(0x20, 0x7f);
+    break;
 case UC_GREEK_CAPITAL_LETTER_UPSILON:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(A), T(KP_5), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0xa5);
+    break;
 case UC_GREEK_CAPITAL_LETTER_MU:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(KP_9), T(C), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0x9c);
+    break;
 case UC_GREEK_CAPITAL_LETTER_EPSILON:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(KP_9), T(KP_5), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0x95);
+    break;
 case UC_GREEK_CAPITAL_LETTER_GAMMA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(KP_9), T(KP_3), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0x93);
+    break;
 case UC_SUBSCRIPT_SIX:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_2), T(KP_0), T(KP_8), T(KP_6), T(KP_ENTER), END
-    );
+    unicode_action_function(0x20, 0x86);
+    break;
 case UC_GREEK_CAPITAL_LETTER_DELTA:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_3), T(KP_9), T(KP_4), T(KP_ENTER), END
-    );
+    unicode_action_function(0x03, 0x94);
+    break;
 case UC_VULGAR_FRACTION_ONE_HALF:
-    return MACRODOWN(
-        D(LCTRL), D(LSHIFT), T(U), U(LCTRL), U(LSHIFT), T(KP_0), T(KP_0), T(B), T(D), T(KP_ENTER), END
-    );
-            default:
-                break;
-        }
+    unicode_action_function(0x00, 0xbd);
+    break;
+        default:
+            break;
     }
     return MACRO_NONE;
 };

+ 4 - 48
keyboard/ergodox_ez/keymaps/german-manuneo/keymap.md

@@ -2,14 +2,15 @@
 
 Compile this file to a `keymap.c` file using `compile_keymap.py`
 
-    compile_keymap.py keymaps/german-manuneo/keymap.md
+    python compile_keymap.py keymaps/german-manuneo/keymap.md
+
+Tested with python 2.7 and python 3.4
 
 
 # Layout Config
 
     {
         "layout": "ergodox_ez",
-        "includes_dir": "quantum/",
         "keymaps_includes": [
             "ergodox_ez.h",
             "action_layer.h",
@@ -17,8 +18,6 @@ Compile this file to a `keymap.c` file using `compile_keymap.py`
             "keymap_extras/keymap_german.h",
         ],
         "key_prefixes": ["DE_", "KC_"],
-        "filler": "-+.'!x",
-        "separator": "|",
         "macros": {
             // TODO: implement macros
             // "MUC": "",
@@ -41,7 +40,7 @@ Compile this file to a `keymap.c` file using `compile_keymap.py`
     !-----+----+----+----x----x----!     !     !----x----x----+----+----+-----!
     |MO(3)| UE | OE | AE | C  | V  |END  | TAB | B  | M  |COMM| DOT| UP |  Y  |
     '-----+----+----+----+----+----------'----------+----+----+----+----+-----'
-     |    |    |LGUI|LALT|LCTL|                     !LALT|    |LEFT|DOWN|RGHT|
+     |    |    |LGUI|LALT|LCTL|                     !RCTL|RALT|LEFT|DOWN|RGHT|
      '------------------------'                     '------------------------'
                             .-----------. .-----------.
                             |INS  |TG(2)| !M(UM)|DELT |
@@ -187,46 +186,3 @@ http://symbolcodes.tlt.psu.edu/bylanguage/mathchart.html
                       |     |     |     | !     |     |     |
                       '-----------------' '-----------------'
 
-
-## Layer 7
-
-    .------------------------------------.------------------------------------.
-    |     |    |    |    |    |    |     |     |    |    |    |    |    |     |
-    !-----+----+----+----+----+----------!-----+----+----+----+----+----+-----!
-    |     |    |    |    |    |    |     |     |    |    |    |    |    |     |
-    !-----+----+----+----x----x----!     !     !----x----x----+----+----+-----!
-    |     |    |    |    |    |    |-----!-----!    |    |    |    |    |     |
-    !-----+----+----+----x----x----!     !     !----x----x----+----+----+-----!
-    |     |    |    |    |    |    |     |     |    |    |    |    |    |     |
-    '-----+----+----+----+----+----------'----------+----+----+----+----+-----'
-     |    |    |    |    |    |                     !    |    |    |    |    |
-     '------------------------'                     '------------------------'
-                            .-----------. .-----------.
-                            |     |     | !     |     |
-                      .-----+-----+-----! !-----+-----+-----.
-                      !     !     |     | !     |     !     !
-                      !     !     !-----! !-----!     !     !
-                      |     |     |     | !     |     |     |
-                      '-----------------' '-----------------'
-
-
-## Layer 8
-
-    .------------------------------------.------------------------------------.
-    |     |    |    |    |    |    |     |     |    |    |    |    |    |     |
-    !-----+----+----+----+----+----------!-----+----+----+----+----+----+-----!
-    |     |    |    |    |    |    |     |     |    |    |    |    |    |     |
-    !-----+----+----+----x----x----!     !     !----x----x----+----+----+-----!
-    |     |    |    |    |    |    |-----!-----!    |    |    |    |    |     |
-    !-----+----+----+----x----x----!     !     !----x----x----+----+----+-----!
-    |     |    |    |    |    |    |     |     |    |    |    |    |    |     |
-    '-----+----+----+----+----+----------'----------+----+----+----+----+-----'
-     |    |    |    |    |    |                     !    |    |    |    |    |
-     '------------------------'                     '------------------------'
-                            .-----------. .-----------.
-                            |     |     | !     |     |
-                      .-----+-----+-----! !-----+-----+-----.
-                      !     !     |     | !     |     !     !
-                      !     !     !-----! !-----!     !     !
-                      |     |     |     | !     |     |     |
-                      '-----------------' '-----------------'