Browse Source

Merge remote-tracking branch 'origin/develop' into xap

Drashna Jael're 4 years ago
parent
commit
15e0964108
32 changed files with 1838 additions and 2 deletions
  1. 17 0
      docs/cli_commands.md
  2. 37 0
      keyboards/crkbd/keymaps/antosha417/config.h
  3. 401 0
      keyboards/crkbd/keymaps/antosha417/keymap.c
  4. 15 0
      keyboards/crkbd/keymaps/antosha417/mod_tap_keys.h
  5. 5 0
      keyboards/crkbd/keymaps/antosha417/rules.mk
  6. 13 0
      keyboards/crkbd/keymaps/antosha417/todo.md
  7. 20 0
      keyboards/evyd13/nt210/config.h
  8. 84 0
      keyboards/evyd13/nt210/info.json
  9. 21 0
      keyboards/evyd13/nt210/keymaps/default/keymap.c
  10. 48 0
      keyboards/evyd13/nt210/keymaps/via/keymap.c
  11. 2 0
      keyboards/evyd13/nt210/keymaps/via/rules.mk
  12. 27 0
      keyboards/evyd13/nt210/readme.md
  13. 1 0
      keyboards/evyd13/nt210/rules.mk
  14. 34 0
      keyboards/planck/keymaps/antosha417/config.h
  15. 452 0
      keyboards/planck/keymaps/antosha417/keymap.c
  16. 14 0
      keyboards/planck/keymaps/antosha417/mod_tap_keys.h
  17. 11 0
      keyboards/planck/keymaps/antosha417/readme.md
  18. 4 0
      keyboards/planck/keymaps/antosha417/rules.mk
  19. 57 0
      keyboards/ydkb/grape/config.h
  20. 16 0
      keyboards/ydkb/grape/grape.c
  21. 47 0
      keyboards/ydkb/grape/grape.h
  22. 130 0
      keyboards/ydkb/grape/info.json
  23. 29 0
      keyboards/ydkb/grape/keymaps/default/keymap.c
  24. 51 0
      keyboards/ydkb/grape/keymaps/via/keymap.c
  25. 2 0
      keyboards/ydkb/grape/keymaps/via/rules.mk
  26. 96 0
      keyboards/ydkb/grape/matrix.c
  27. 23 0
      keyboards/ydkb/grape/readme.md
  28. 22 0
      keyboards/ydkb/grape/rules.mk
  29. 1 0
      lib/python/qmk/cli/__init__.py
  30. 145 0
      lib/python/qmk/cli/via2json.py
  31. 7 1
      lib/python/qmk/json_encoders.py
  32. 6 1
      lib/python/qmk/keymap.py

+ 17 - 0
docs/cli_commands.md

@@ -335,6 +335,23 @@ This command cleans up the `.build` folder. If `--all` is passed, any .hex or .b
 qmk clean [-a]
 ```
 
+## `qmk via2json`
+
+This command an generate a keymap.json from a VIA keymap backup. Both the layers and the macros are converted, enabling users to easily move away from a VIA-enabled firmware without writing any code or reimplementing their keymaps in QMK Configurator.
+
+**Usage**:
+
+```
+qmk via2json -kb KEYBOARD [-l LAYOUT] [-km KEYMAP] [-o OUTPUT] filename
+```
+
+**Example:**
+
+```
+$ qmk via2json -kb ai03/polaris -o polaris_keymap.json polaris_via_backup.json
+Ψ Wrote keymap to /home/you/qmk_firmware/polaris_keymap.json
+```
+
 ---
 
 # Developer Commands

+ 37 - 0
keyboards/crkbd/keymaps/antosha417/config.h

@@ -0,0 +1,37 @@
+// Copyright 2021 Anton Kavalkou (@antosha417)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#pragma once
+
+
+/* Select hand configuration */
+
+//#define MASTER_LEFT
+// #define MASTER_RIGHT
+#define EE_HANDS
+
+
+#define TAPPING_FORCE_HOLD
+
+#ifdef RGBLIGHT_ENABLE
+    #undef RGBLED_NUM
+    #define RGBLIGHT_EFFECT_BREATHING
+    #define RGBLIGHT_EFFECT_RAINBOW_MOOD
+    #define RGBLIGHT_EFFECT_RAINBOW_SWIRL
+    #define RGBLIGHT_EFFECT_SNAKE
+    #define RGBLIGHT_EFFECT_KNIGHT
+    #define RGBLIGHT_EFFECT_CHRISTMAS
+    #define RGBLIGHT_EFFECT_STATIC_GRADIENT
+    #define RGBLIGHT_EFFECT_RGB_TEST
+    #define RGBLIGHT_EFFECT_ALTERNATING
+    #define RGBLIGHT_EFFECT_TWINKLE
+    #define RGBLED_NUM 27
+    #define RGBLIGHT_LIMIT_VAL 120
+    #define RGBLIGHT_HUE_STEP 10
+    #define RGBLIGHT_SAT_STEP 17
+    #define RGBLIGHT_VAL_STEP 17
+#endif
+
+#define TAPPING_TERM 200
+#define IGNORE_MOD_TAP_INTERRUPT
+#define COMBO_TERM 30
+

+ 401 - 0
keyboards/crkbd/keymaps/antosha417/keymap.c

@@ -0,0 +1,401 @@
+// Copyright 2021 Anton Kavalkou (@antosha417)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include QMK_KEYBOARD_H
+#include "sendstring_dvorak.h"
+
+typedef union {
+  uint32_t raw;
+  struct {
+    bool is_macos :1;
+  };
+} user_config;
+
+user_config config;
+
+enum layers {
+  _QWERTY,
+  _DVORAK,
+  _LOWER,
+  _RAISE,
+  _TOP,
+  _BOTTOM,
+};
+
+enum keycodes {
+  QWERTY = SAFE_RANGE,
+
+  RUS_LANG,
+  EN_LANG,
+  HEB_LANG,
+
+  VIM_SAVE,
+
+  CHNGE_OS,
+  DELETE_WORD,
+
+#define MOD_TAP_KEY(keycode, tap_action, mod_on_action, mod_off_action)   \
+  keycode,
+#include "mod_tap_keys.h"
+#undef MOD_TAP_KEY
+};
+
+
+#define LOWER MO(_LOWER)
+#define RAISE MO(_RAISE)
+#define TOP MO(_TOP)
+#define BOTTOM MO(_BOTTOM)
+#define LANG  TG(_DVORAK)
+#define KC_CAD LALT(LCTL(KC_DEL))
+#define KC_CAH LALT(LCTL(KC_HOME))
+
+#define E_SFT LSFT_T(KC_E)
+#define D_SFT LSFT_T(KC_D)
+#define A_ALT LALT_T(KC_A)
+#define O_GUI LGUI_T(KC_O)
+#define U_CTRL LCTL_T(KC_U)
+
+#define T_SFT RSFT_T(KC_T)
+#define K_SFT RSFT_T(KC_K)
+#define S_ALT RALT_T(KC_S)
+#define N_GUI RGUI_T(KC_N)
+#define H_CTRL RCTL_T(KC_H)
+
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+[_QWERTY] = LAYOUT_split_3x6_3(
+//,-----------------------------------------------------.                    ,-----------------------------------------------------.
+     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,  A_ALTQ,  S_GUIQ,   D_SFT,  F_CTLQ,    KC_G,                         KC_H,  J_CTLQ,   K_SFT,  L_GUIQ,  SCLN_Q, KC_QUOT,
+//|--------+--------+--------+--------+--------+--------|                    |--------+--------+--------+--------+--------+--------|
+    KC_LSFT,    KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,                         KC_N,    KC_M, KC_COMM,  KC_DOT, KC_SLSH,  KC_ENT,
+//|--------+--------+--------+--------+--------+--------+--------|  |--------+--------+--------+--------+--------+--------+--------|
+					BOTTOM,   KC_SPC,   LOWER,      RAISE,  KC_SPC,     TOP
+				    //`--------------------------'  `--------------------------'
+),
+
+[_DVORAK] = LAYOUT_split_3x6_3(
+//,-----------------------------------------------------.                    ,-----------------------------------------------------.
+     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_LCTL,   A_ALT,   O_GUI,   E_SFT,  U_CTRL,    KC_I,                         KC_D,  H_CTRL,   T_SFT,   N_GUI,   S_ALT, KC_QUOT,
+//|--------+--------+--------+--------+--------+--------|                    |--------+--------+--------+--------+--------+--------|
+    KC_LSFT, KC_SCLN,    KC_Q,    KC_J,    KC_K,    KC_X,                         KC_B,    KC_M,    KC_W,    KC_V,   KC_Z,  KC_ESC,
+//|--------+--------+--------+--------+--------+--------+--------|  |--------+--------+--------+--------+--------+--------+--------|
+					_______, _______, _______,    _______, _______, _______
+				    //`--------------------------'  `--------------------------'
+),
+
+[_LOWER] = LAYOUT_split_3x6_3(
+//,-----------------------------------------------------.                    ,-----------------------------------------------------.
+     KC_F11, KC_UNDS, KC_MINS, KC_TILD, KC_PERC, KC_QUOT,                      _______, KC_CIRC,  KC_GRV, KC_BSLS, KC_PIPE, KC_MINS,
+//|--------+--------+--------+--------+--------+--------|                    |--------+--------+--------+--------+--------+--------|
+     KC_DEL, KC_LBRC, KC_LCBR, KC_PLUS, KC_LPRN,  KC_EQL,                      KC_ASTR, KC_RPRN, KC_EXLM, KC_RCBR, KC_RBRC, KC_BSPC,
+//|--------+--------+--------+--------+--------+--------|                    |--------+--------+--------+--------+--------+--------|
+    _______,  KC_CAD,  KC_CAH, _______,    LANG, _______,                      _______,HEB_LANG, EN_LANG,RUS_LANG, _______, _______,
+//|--------+--------+--------+--------+--------+--------+--------|  |--------+--------+--------+--------+--------+--------+--------|
+					_______, _______, _______,    _______, _______, _______
+				    //`--------------------------'  `--------------------------'
+                                                        //^^^^^^^
+),
+
+
+[_RAISE] = LAYOUT_split_3x6_3(
+//,-----------------------------------------------------.                    ,-----------------------------------------------------.
+     KC_F11, _______, _______, KC_DLR,  KC_AMPR, _______,                     KC_COLON, KC_QUES,   KC_AT, KC_HASH, KC_SLSH, KC_F12,
+//|--------+--------+--------+--------+--------+--------|                    |--------+--------+--------+--------+--------+--------|
+    _______,    KC_7,    KC_5,    KC_3,    KC_1,    KC_9,                         KC_0,    KC_2,    KC_4,    KC_6,    KC_8, KC_BSPC,
+//|--------+--------+--------+--------+--------+--------|                    |--------+--------+--------+--------+--------+--------|
+    _______,   KC_F7,   KC_F5,   KC_F3,   KC_F1,   KC_F9,                       KC_F10,   KC_F2,   KC_F4,   KC_F6,   KC_F8, _______,
+//|--------+--------+--------+--------+--------+--------+--------|  |--------+--------+--------+--------+--------+--------+--------|
+					_______, _______, _______,    _______, _______, _______
+				    //`--------------------------'  `--------------------------'
+                                                                    //^^^^^^^
+),
+
+[_TOP] = LAYOUT_split_3x6_3(
+//,-----------------------------------------------------.                    ,-----------------------------------------------------.
+    _______,CHNGE_OS, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD,                      RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, _______, _______,
+//|--------+--------+--------+--------+--------+--------|                    |--------+--------+--------+--------+--------+--------|
+    _______, _______, _______, _______, _______, _______,                      _______, _______, _______, _______, _______, _______,
+//|--------+--------+--------+--------+--------+--------|                    |--------+--------+--------+--------+--------+--------|
+    _______, _______, _______, KC_DOWN, KC_UP,   _______,                      _______, _______, _______, _______, _______, _______,
+//|--------+--------+--------+--------+--------+--------+--------|  |--------+--------+--------+--------+--------+--------+--------|
+					_______, _______, _______,    _______, _______, _______
+				    //`--------------------------'  `--------------------------'
+                                                                                      //^^^^^^^
+),
+
+[_BOTTOM] = LAYOUT_split_3x6_3(
+//,-----------------------------------------------------.                    ,-----------------------------------------------------.
+    _______, _______, _______, _______, _______, _______,                      _______, _______, _______, _______, KC_RGHT, _______,
+//|--------+--------+--------+--------+--------+--------|                    |--------+--------+--------+--------+--------+--------|
+    _______, _______, _______, _______, _______, _______,                      _______, KC_LEFT, _______, _______, _______, _______,
+//|--------+--------+--------+--------+--------+--------|                    |--------+--------+--------+--------+--------+--------|
+    _______, _______, _______, _______, _______, _______,                      _______, KC_VOLD, KC_VOLU, _______, _______, _______,
+//|--------+--------+--------+--------+--------+--------+--------|  |--------+--------+--------+--------+--------+--------+--------|
+					_______, _______, _______,    _______, _______, _______
+				    //`--------------------------'  `--------------------------'
+                                      //^^^^^^^
+)
+
+};
+
+enum combo_events {
+  // combos for dvorak layer
+  RU_COMBO,
+  EN_COMBO,
+  HEB_COMBO,
+  ESC_COMBO,
+  TAB_COMBO,
+  ENT_COMBO,
+  DEL_COMBO,
+  SAVE_COMBO,
+  BSPC_COMBO,
+  BSPCW_COMBO,
+
+  // combos for qwerty layer
+  RUQ_COMBO,
+  ENQ_COMBO,
+  HEBQ_COMBO,
+  ESCQ_COMBO,
+  TABQ_COMBO,
+  ENTQ_COMBO,
+  DELQ_COMBO,
+  SAVEQ_COMBO,
+  BSPCQ_COMBO,
+  BSPCWQ_COMBO,
+
+  COMBO_LENGTH
+};
+uint16_t COMBO_LEN = COMBO_LENGTH;
+
+const uint16_t PROGMEM ru_combo[] = {KC_R, U_CTRL, COMBO_END};
+const uint16_t PROGMEM en_combo[] = {U_CTRL, S_ALT, COMBO_END};
+const uint16_t PROGMEM heb_combo[] = {KC_I, KC_V, COMBO_END};
+const uint16_t PROGMEM esc_combo[] = {H_CTRL, U_CTRL, COMBO_END};
+const uint16_t PROGMEM tab_combo[] = {T_SFT, A_ALT, COMBO_END};
+const uint16_t PROGMEM ent_combo[]= {E_SFT, N_GUI, COMBO_END};
+const uint16_t PROGMEM del_combo[] = {KC_D, E_SFT, COMBO_END};
+const uint16_t PROGMEM bspc_combo[] = {KC_C, H_CTRL, COMBO_END};
+const uint16_t PROGMEM bspcw_combo[] = {N_GUI, U_CTRL, COMBO_END};
+const uint16_t PROGMEM save_combo[] = {O_GUI, H_CTRL, COMBO_END};
+
+const uint16_t PROGMEM ruq_combo[] = {KC_O, F_CTLQ, COMBO_END};
+const uint16_t PROGMEM enq_combo[] = {F_CTLQ, SCLN_Q, COMBO_END};
+const uint16_t PROGMEM hebq_combo[] = {KC_G, KC_DOT, COMBO_END};
+const uint16_t PROGMEM escq_combo[] = {F_CTLQ, J_CTLQ, COMBO_END};
+const uint16_t PROGMEM tabq_combo[] = {K_SFT, A_ALTQ, COMBO_END};
+const uint16_t PROGMEM entq_combo[] = {D_SFT, L_GUIQ, COMBO_END};
+const uint16_t PROGMEM delq_combo[] = {KC_H, D_SFT, COMBO_END};
+const uint16_t PROGMEM bspcq_combo[] = {KC_I, J_CTLQ, COMBO_END};
+const uint16_t PROGMEM bspcwq_combo[] = {L_GUIQ, F_CTLQ, COMBO_END};
+const uint16_t PROGMEM saveq_combo[] = {S_GUIQ, J_CTLQ, COMBO_END};
+
+combo_t key_combos[] = {
+    [RU_COMBO] = COMBO(ru_combo, RUS_LANG),
+    [EN_COMBO] = COMBO(en_combo, EN_LANG),
+    [HEB_COMBO] = COMBO(heb_combo, HEB_LANG),
+    [ESC_COMBO] = COMBO(esc_combo, KC_ESC),
+    [TAB_COMBO] = COMBO(tab_combo, KC_TAB),
+    [ENT_COMBO] = COMBO(ent_combo, KC_ENT),
+    [DEL_COMBO] = COMBO(del_combo, KC_DEL),
+    [BSPC_COMBO] = COMBO(bspc_combo, KC_BSPC),
+    [SAVE_COMBO] = COMBO(save_combo, VIM_SAVE),
+    [BSPCW_COMBO] = COMBO(bspcw_combo, DELETE_WORD),
+
+    [RUQ_COMBO] = COMBO(ruq_combo, RUS_LANG),
+    [ENQ_COMBO] = COMBO(enq_combo, EN_LANG),
+    [HEBQ_COMBO] = COMBO(hebq_combo, HEB_LANG),
+    [ESCQ_COMBO] = COMBO(escq_combo, KC_ESC),
+    [TABQ_COMBO] = COMBO(tabq_combo, KC_TAB),
+    [ENTQ_COMBO] = COMBO(entq_combo, KC_ENT),
+    [DELQ_COMBO] = COMBO(delq_combo, KC_DEL),
+    [BSPCQ_COMBO] = COMBO(bspcq_combo, KC_BSPC),
+    [SAVEQ_COMBO] = COMBO(saveq_combo, VIM_SAVE),
+    [BSPCWQ_COMBO] = COMBO(bspcwq_combo, DELETE_WORD),
+};
+ 
+
+#ifdef OLED_ENABLE
+oled_rotation_t oled_init_user(oled_rotation_t rotation) {
+  if (!is_keyboard_master()) {
+    return OLED_ROTATION_180;  // flips the display 180 degrees if offhand
+  }
+  return rotation;
+}
+
+void oled_render_layer_state(void) {
+    oled_write_P(PSTR("layer: "), false);
+    switch (get_highest_layer(layer_state|default_layer_state)) {
+      case _QWERTY:
+        oled_write_ln_P(PSTR("qwerty"), false);
+        break
+      case _DVORAK:
+        oled_write_ln_P(PSTR("dvorak"), false);
+        break;
+      case _LOWER:
+        oled_write_ln_P(PSTR("lower"), false);
+        break;
+      case_RAISE:
+        oled_write_ln_P(PSTR("raise"), false);
+        break;
+      case _TOP:
+        oled_write_ln_P(PSTR("top"), false);
+        break;
+      case _BOTTOM:
+        oled_write_ln_P(PSTR("bottom"), false);
+        break;
+      default:
+        oled_write_ln_P(PSTR("unknown"), false);
+        break;
+    }
+}
+
+void render_bootmagic_status(bool status) {
+    /* Show Ctrl-Gui Swap options */
+    static const char PROGMEM logo[][2][3] = {
+        {{0x97, 0x98, 0}, {0xb7, 0xb8, 0}},
+        {{0x95, 0x96, 0}, {0xb5, 0xb6, 0}},
+    };
+    if (status) {
+        oled_write_ln_P(logo[0][0], false);
+        oled_write_ln_P(logo[0][1], false);
+    } else {
+        oled_write_ln_P(logo[1][0], false);
+        oled_write_ln_P(logo[1][1], false);
+    }
+}
+
+void oled_render_logo(void) {
+    static const char PROGMEM crkbd_logo[] = {
+        0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94,
+        0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4,
+        0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4,
+        0};
+    oled_write_P(crkbd_logo, false);
+}
+
+bool oled_task_user(void) {
+    if (is_keyboard_master()) {
+        oled_write_ln_P(PSTR("nice cock"), false);
+        oled_render_layer_state();
+    } else {
+        oled_render_logo();
+    }
+    return false;
+}
+
+#endif // OLED_ENABLE
+
+void keyboard_post_init_user(void) {
+  config.raw = eeconfig_read_user();
+  layer_on(_DVORAK);
+}
+
+void set_english_language(void) {
+  layer_on(_DVORAK);
+  tap_code16(LSFT(LCTL(LGUI(KC_1))));
+}
+
+void set_russian_language(void) {
+  layer_off(_DVORAK);
+  tap_code16(LSFT(LCTL(LGUI(KC_2))));
+}
+
+void set_hebrew_language(void) {
+  layer_off(_DVORAK);
+  tap_code16(LSFT(LCTL(LGUI(KC_3))));
+}
+
+void delete_word(void) {
+  if (config.is_macos) {
+    tap_code16(A(KC_BSPC));
+  } else {
+    tap_code16(C(KC_BSPC));
+  }
+}
+
+#define CASE(keycode, key_pressed_action, key_released_action)   \
+  case (keycode):                                               \
+    if (record->event.pressed) {                                \
+      key_pressed_action;                                       \
+    } else {                                                    \
+      key_released_action;                                      \
+    }                                                           \
+    return false;                                               \
+    break;
+
+#define CASE_PRESSED(keycode, key_pressed_action) CASE(keycode, key_pressed_action, {});
+
+#define CASE_MOD_TAP_KEY(keycode, tap_action, mod_off_action) \
+  CASE(keycode, {                                  \
+    keycode ## _TIMER = timer_read();                         \
+    IS_ ## keycode ## _ACTIVE = true;                         \
+  }, {                                                        \
+    if(IS_ ## keycode ## _MOD_ACTIVE) {                       \
+      mod_off_action;                          		      \
+    } else if (IS_ ## keycode ## _ACTIVE) {                   \
+      tap_action;                                             \
+    }                                                         \
+    IS_ ## keycode ## _MOD_ACTIVE = false; 		      \
+    IS_ ## keycode ## _ACTIVE = false;                        \
+  });
+
+#define MOD_TAP_KEY(keycode, tap_action, mod_on_action, mod_off_action) \
+uint16_t keycode ## _TIMER = 0;                                 	\
+bool IS_ ## keycode ## _ACTIVE = false; 		                \
+bool IS_ ## keycode ## _MOD_ACTIVE = false;
+#include "mod_tap_keys.h"
+#undef MOD_TAP_KEY
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+
+  #ifdef OLED_ENABLE
+  if (record->event.pressed) {
+    set_keylog(keycode, record);
+  }
+#endif //OLED_ENABLE
+
+  switch (keycode) {
+    CASE_PRESSED(EN_LANG, set_english_language());
+    CASE_PRESSED(RUS_LANG, set_russian_language());
+    CASE_PRESSED(HEB_LANG, set_hebrew_language());
+
+    CASE_PRESSED(VIM_SAVE, {set_english_language(); SEND_STRING(SS_TAP(X_ESC)SS_LSFT(SS_TAP(X_SCLN))SS_TAP(X_W)SS_TAP(X_ENT));});
+
+    CASE_PRESSED(CHNGE_OS, {config.is_macos ^= 1; eeconfig_update_user(config.raw);});
+    CASE_PRESSED(DELETE_WORD, delete_word());
+
+    #define MOD_TAP_KEY(keycode, tap_action, mod_on_action, mod_off_action) \
+    CASE_MOD_TAP_KEY(keycode, tap_action, mod_off_action);
+    #include "mod_tap_keys.h"
+    #undef MOD_TAP_KEY
+  }
+
+  #define MOD_TAP_KEY(keycode, tap_action, mod_on_action, mod_off_action) \
+  if (IS_ ## keycode ## _ACTIVE && !IS_ ## keycode ## _MOD_ACTIVE) {      \
+    if (timer_elapsed(keycode ## _TIMER) <= TAPPING_TERM) {               \
+      tap_action;                                                         \
+      IS_ ## keycode ## _ACTIVE = false;                                  \
+    }                                                    		  \
+  }
+  #include "mod_tap_keys.h"
+  #undef MOD_TAP_KEY
+
+  return true;
+}
+
+void matrix_scan_user(void) {
+  #define MOD_TAP_KEY(keycode, tap_action, mod_on_action, mod_off_action) \
+  if (IS_ ## keycode ## _ACTIVE) {                                        \
+    if (timer_elapsed(keycode ## _TIMER) > TAPPING_TERM) {                \
+      mod_on_action;                                                      \
+      IS_ ## keycode ## _MOD_ACTIVE = true;                               \
+    }                                                    		  \
+  }
+  #include "mod_tap_keys.h"
+  #undef MOD_TAP_KEY
+}
+

+ 15 - 0
keyboards/crkbd/keymaps/antosha417/mod_tap_keys.h

@@ -0,0 +1,15 @@
+// Copyright 2021 Anton Kavalkou (@antosha417)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+// MOD_TAP_KEY(key, tap_action, mod_on_action, mod_off_action)
+
+MOD_TAP_KEY(S_GUIQ, tap_code(KC_S), {layer_on(_DVORAK); register_code(KC_LGUI);}, {layer_off(_DVORAK); unregister_code(KC_LGUI);})
+MOD_TAP_KEY(L_GUIQ, tap_code(KC_L), {layer_on(_DVORAK); register_code(KC_RGUI);}, {layer_off(_DVORAK); unregister_code(KC_RGUI);})
+
+MOD_TAP_KEY(F_CTLQ, tap_code(KC_F), {layer_on(_DVORAK); register_code(KC_LCTL);}, {layer_off(_DVORAK); unregister_code(KC_LCTL);})
+MOD_TAP_KEY(J_CTLQ, tap_code(KC_J), {layer_on(_DVORAK); register_code(KC_RCTL);}, {layer_off(_DVORAK); unregister_code(KC_RCTL);})
+
+MOD_TAP_KEY(A_ALTQ, tap_code(KC_A), {layer_on(_DVORAK); register_code(KC_LALT);}, {layer_off(_DVORAK); unregister_code(KC_LALT);})
+MOD_TAP_KEY(SCLN_Q, tap_code(KC_SCLN), {layer_on(_DVORAK); register_code(KC_RALT);},{layer_off(_DVORAK); unregister_code(KC_RALT);})
+
+ 

+ 5 - 0
keyboards/crkbd/keymaps/antosha417/rules.mk

@@ -0,0 +1,5 @@
+OLED_ENABLE = yes
+COMBO_ENABLE = yes
+
+LTO_ENABLE = yes #enable link time optimization to reduce binary size
+

+ 13 - 0
keyboards/crkbd/keymaps/antosha417/todo.md

@@ -0,0 +1,13 @@
+# Notes:
+  * to flush firmware to keyboard use:
+    ```
+    $ make crkbd/rev1:antosha417:avrdude-split-right
+    $ make crkbd/rev1:antosha417:avrdude-split-left
+    ```
+
+# Todo:
+  [ ] do something with displayig symbols on oled screen
+  [ ] count wpm
+  [ ] load images
+  [X] figure out how to delete word on linux
+  [X] fix oled layer names

+ 20 - 0
keyboards/evyd13/nt210/config.h

@@ -0,0 +1,20 @@
+// Copyright 2022 Evelien Dekkers (@evyd13)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+/*
+ * Feature disable options
+ *  These options are also useful to firmware size reduction.
+ */
+
+/* disable debug print */
+//#define NO_DEBUG
+
+/* disable print */
+//#define NO_PRINT
+
+/* disable action features */
+//#define NO_ACTION_LAYER
+//#define NO_ACTION_TAPPING
+//#define NO_ACTION_ONESHOT

+ 84 - 0
keyboards/evyd13/nt210/info.json

@@ -0,0 +1,84 @@
+{
+    "manufacturer": "Evelien Dekkers",
+    "keyboard_name": "nt210",
+    "maintainer": "evyd13",
+    "bootloader": "atmel-dfu",
+    "diode_direction": "COL2ROW",
+    "features": {
+        "bootmagic": true,
+        "command": false,
+        "console": false,
+        "extrakey": true,
+        "mousekey": false,
+        "nkro": true
+    },
+    "matrix_pins": {
+        "cols": ["B0", "D6", "D5", "D4"],
+        "rows": ["C4", "C5", "C6", "C7", "B7", "B6"]
+    },
+    "processor": "atmega32u2",
+    "url": "https://github.com/evyd13/nt-series/tree/main/nt-210",
+    "usb": {
+        "device_version": "1.0.0",
+        "pid": "0x4705",
+        "vid": "0xCC3F"
+    },
+    "indicators": {
+        "num_lock": "B4"
+    },
+    "layouts": {
+        "LAYOUT_numpad_6x4": {
+            "layout": [
+                { "matrix": [0, 0], "x": 0, "y": 0 },
+                { "matrix": [0, 1], "x": 1, "y": 0 },
+                { "matrix": [0, 2], "x": 2, "y": 0 },
+                { "matrix": [0, 3], "x": 3, "y": 0 },
+                { "matrix": [1, 0], "x": 0, "y": 1.5 },
+                { "matrix": [1, 1], "x": 1, "y": 1.5 },
+                { "matrix": [1, 2], "x": 2, "y": 1.5 },
+                { "matrix": [1, 3], "x": 3, "y": 1.5 },
+                { "matrix": [2, 0], "x": 0, "y": 2.5 },
+                { "matrix": [2, 1], "x": 1, "y": 2.5 },
+                { "matrix": [2, 2], "x": 2, "y": 2.5 },
+                { "h": 2, "matrix": [2, 3], "x": 3, "y": 2.5 },
+                { "matrix": [3, 0], "x": 0, "y": 3.5 },
+                { "matrix": [3, 1], "x": 1, "y": 3.5 },
+                { "matrix": [3, 2], "x": 2, "y": 3.5 },
+                { "matrix": [4, 0], "x": 0, "y": 4.5 },
+                { "matrix": [4, 1], "x": 1, "y": 4.5 },
+                { "matrix": [4, 2], "x": 2, "y": 4.5 },
+                { "h": 2, "matrix": [4, 3], "x": 3, "y": 4.5 },
+                { "matrix": [5, 0], "w": 2, "x": 0, "y": 5.5 },
+                { "matrix": [5, 2], "x": 2, "y": 5.5 }
+            ]
+        },
+        "LAYOUT_ortho_6x4": {
+            "layout": [
+                { "matrix": [0, 0], "x": 0, "y": 0 },
+                { "matrix": [0, 1], "x": 1, "y": 0 },
+                { "matrix": [0, 2], "x": 2, "y": 0 },
+                { "matrix": [0, 3], "x": 3, "y": 0 },
+                { "matrix": [1, 0], "x": 0, "y": 1.5 },
+                { "matrix": [1, 1], "x": 1, "y": 1.5 },
+                { "matrix": [1, 2], "x": 2, "y": 1.5 },
+                { "matrix": [1, 3], "x": 3, "y": 1.5 },
+                { "matrix": [2, 0], "x": 0, "y": 2.5 },
+                { "matrix": [2, 1], "x": 1, "y": 2.5 },
+                { "matrix": [2, 2], "x": 2, "y": 2.5 },
+                { "matrix": [2, 3], "x": 3, "y": 2.5 },
+                { "matrix": [3, 0], "x": 0, "y": 3.5 },
+                { "matrix": [3, 1], "x": 1, "y": 3.5 },
+                { "matrix": [3, 2], "x": 2, "y": 3.5 },
+                { "matrix": [3, 3], "x": 3, "y": 3.5 },
+                { "matrix": [4, 0], "x": 0, "y": 4.5 },
+                { "matrix": [4, 1], "x": 1, "y": 4.5 },
+                { "matrix": [4, 2], "x": 2, "y": 4.5 },
+                { "matrix": [4, 3], "x": 3, "y": 4.5 },
+                { "matrix": [5, 0], "x": 0, "y": 5.5 },
+                { "matrix": [5, 1], "x": 1, "y": 5.5 },
+                { "matrix": [5, 2], "x": 2, "y": 5.5 },
+                { "matrix": [5, 3], "x": 3, "y": 5.5 }
+            ]
+        }
+    }
+}

+ 21 - 0
keyboards/evyd13/nt210/keymaps/default/keymap.c

@@ -0,0 +1,21 @@
+// Copyright 2022 Evelien Dekkers (@evyd13)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include QMK_KEYBOARD_H
+
+// Defines names for use in layer keycodes and the keymap
+enum layer_names {
+    _BASE,
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+[_BASE] = LAYOUT_ortho_6x4(
+  KC_ESC, KC_TAB,  KC_EQL,  KC_BSPC,
+  KC_NUM, KC_PSLS, KC_PAST, KC_PMNS,
+  KC_P7,  KC_P8,   KC_P9,   KC_PPLS,
+  KC_P4,  KC_P5,   KC_P6,   KC_NO,
+  KC_P1,  KC_P2,   KC_P3,   KC_PENT,
+  KC_P0,  KC_NO,   KC_PDOT, KC_NO),
+
+};

+ 48 - 0
keyboards/evyd13/nt210/keymaps/via/keymap.c

@@ -0,0 +1,48 @@
+// Copyright 2022 Evelien Dekkers (@evyd13)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include QMK_KEYBOARD_H
+
+// Defines names for use in layer keycodes and the keymap
+enum layer_names {
+    _BASE,
+    _FN1,
+    _FN2,
+    _FN3,
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+[_BASE] = LAYOUT_ortho_6x4(
+  KC_ESC, KC_TAB,   KC_EQL,  KC_BSPC,
+  KC_NUM, KC_PSLS,  KC_PAST, KC_PMNS,
+  KC_P7,  KC_P8,    KC_P9,   KC_PPLS,
+  KC_P4,  KC_P5,    KC_P6,   KC_NO,
+  KC_P1,  KC_P2,    KC_P3,   KC_PENT,
+  KC_P0,  KC_NO,    KC_PDOT, KC_NO),
+
+[_FN1] = LAYOUT_ortho_6x4(
+  _______, _______, _______, _______,
+  _______, _______, _______, _______,
+  _______, _______, _______, _______,
+  _______, _______, _______, _______,
+  _______, _______, _______, _______,
+  _______, _______, _______, _______),
+
+[_FN2] = LAYOUT_ortho_6x4(
+  _______, _______, _______, _______,
+  _______, _______, _______, _______,
+  _______, _______, _______, _______,
+  _______, _______, _______, _______,
+  _______, _______, _______, _______,
+  _______, _______, _______, _______),
+
+[_FN3] = LAYOUT_ortho_6x4(
+  _______, _______, _______, _______,
+  _______, _______, _______, _______,
+  _______, _______, _______, _______,
+  _______, _______, _______, _______,
+  _______, _______, _______, _______,
+  _______, _______, _______, _______),
+
+};

+ 2 - 0
keyboards/evyd13/nt210/keymaps/via/rules.mk

@@ -0,0 +1,2 @@
+VIA_ENABLE = yes
+LTO_ENABLE = yes

+ 27 - 0
keyboards/evyd13/nt210/readme.md

@@ -0,0 +1,27 @@
+# nt210
+
+![nt120 PCB](https://i.imgur.com/DZAfoOlh.jpg)
+
+A custom PCB for the Leopold FC210TP.
+
+* Keyboard Maintainer: [Evelien Dekkers](https://github.com/evyd13)
+* Hardware Supported: nt-120 PCB
+* Hardware Availability: [Open source on GitHub](https://github.com/evyd13/nt-series/tree/main/nt-210)
+
+Make example for this keyboard (after setting up your build environment):
+
+    make evyd13/nt210:default
+
+Flashing example for this keyboard:
+
+    make evyd13/nt210:default:flash
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
+
+## Bootloader
+
+Enter the bootloader in 3 ways:
+
+* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard
+* **Physical reset button**: Briefly press the button on the back of the PCB - some may have pads you must short instead
+* **Keycode in layout**: Press the key mapped to `RESET` if it is available

+ 1 - 0
keyboards/evyd13/nt210/rules.mk

@@ -0,0 +1 @@
+# This file intentionally left blank

+ 34 - 0
keyboards/planck/keymaps/antosha417/config.h

@@ -0,0 +1,34 @@
+// Copyright 2021 Anton Kavalkou (@antosha417)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#pragma once
+
+#ifdef AUDIO_ENABLE
+    #define STARTUP_SONG SONG(PLANCK_SOUND)
+    // #define STARTUP_SONG SONG(NO_SOUND)
+#endif
+
+/*
+ * MIDI options
+ */
+
+/* enable basic MIDI features:
+   - MIDI notes can be sent when in Music mode is on
+*/
+
+#define MIDI_BASIC
+
+/* enable advanced MIDI features:
+   - MIDI notes can be added to the keymap
+   - Octave shift and transpose
+   - Virtual sustain, portamento, and modulation wheel
+   - etc.
+*/
+//#define MIDI_ADVANCED
+
+// Most tactile encoders have detents every 4 stages
+#define ENCODER_RESOLUTION 4
+
+#define TAPPING_TERM 200
+#define IGNORE_MOD_TAP_INTERRUPT
+#define COMBO_TERM 30
+

+ 452 - 0
keyboards/planck/keymaps/antosha417/keymap.c

@@ -0,0 +1,452 @@
+// Copyright 2021 Anton Kavalkou (@antosha417)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include QMK_KEYBOARD_H
+#include "sendstring_dvorak.h"
+#include "muse.h"
+
+enum layers {
+  _QWERTY,
+  _DVORAK,
+  _LOWER,
+  _RAISE,
+  _TOP,
+  _BOTTOM,
+  _ADJUST
+};
+
+float USSR_SONG[][2] = SONG(B__NOTE(_G6),
+  B__NOTE(_C7), W__NOTE(_G6), H__NOTE(_A6),
+  B__NOTE(_B6), W__NOTE(_E6), W__NOTE(_E6),
+  B__NOTE(_A6), W__NOTE(_G6), H__NOTE(_F6),
+  B__NOTE(_G6), W__NOTE(_C6), W__NOTE(_C6),
+  B__NOTE(_D6), W__NOTE(_D6), W__NOTE(_E6),
+  B__NOTE(_D6), W__NOTE(_D6), W__NOTE(_G6),
+  B__NOTE(_F6), W__NOTE(_G6), W__NOTE(_A6),
+  B__NOTE(_B6),
+  );
+
+enum keycodes {
+  QWERTY = SAFE_RANGE,
+
+  RUS_LANG,
+  EN_LANG,
+  HEB_LANG,
+
+  BRUDERSCHAFT,
+  VIM_SAVE,
+
+#define MOD_TAP_KEY(keycode, tap_action, mod_on_action, mod_off_action)   \
+  keycode,
+#include "mod_tap_keys.h"
+#undef MOD_TAP_KEY
+};
+
+#define LOWER MO(_LOWER)
+#define RAISE MO(_RAISE)
+#define TOP MO(_TOP)
+#define BOTTOM MO(_BOTTOM)
+#define LANG  TG(_DVORAK)
+#define KC_CAD LALT(LCTL(KC_DEL))
+#define KC_CAH LALT(LCTL(KC_HOME))
+
+#define E_SFT LSFT_T(KC_E)
+#define D_SFT LSFT_T(KC_D)
+#define A_ALT LALT_T(KC_A)
+#define O_GUI LGUI_T(KC_O)
+#define U_CTRL LCTL_T(KC_U)
+
+#define T_SFT RSFT_T(KC_T)
+#define K_SFT RSFT_T(KC_K)
+#define S_ALT RALT_T(KC_S)
+#define N_GUI RGUI_T(KC_N)
+#define H_CTRL RCTL_T(KC_H)
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+/* Qwerty
+ * ,-----------------------------------------------------------------------------------.
+ * |      |   Q  |   W  |   E  |   R  |   T  |   Y  |   U  |   I  |   O  |   P  |      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |   A  |   S  |   D  |   F  |   G  |   H  |   J  |   K  |   L  |   ;  |      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |   Z  |   X  |   C  |   V  |   B  |   N  |   M  |   ,  |   .  |   /  |      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |Bottom| SPC  |Lower |Raise | SPC  | TOP  |      |      |      |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_QWERTY] = LAYOUT_planck_grid(
+    _______,  KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,    KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    _______,
+    _______,  A_ALTQ,  S_GUIQ,  D_SFT,   F_CTLQ,  KC_G,    KC_H,    J_CTLQ,  K_SFT,   L_GUIQ,  SCLN_Q,  _______,
+    _______,  KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, _______,
+    _______, _______, _______, BOTTOM,  KC_SPC,  LOWER,   RAISE,   KC_SPC,   TOP,     _______, _______, _______
+),
+
+/* Dvorak
+ * ,-----------------------------------------------------------------------------------.
+ * |      |   '  |   ,  |   .  |   P  |   Y  |   F  |   G  |   C  |   R  |   L  |      |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * |      |   A  |   O  |   E  |   U  |   I  |   D  |   H  |   T  |   N  |   S  |      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |   ;  |   Q  |   J  |   K  |   X  |   B  |   M  |   W  |   V  |   Z  |      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      |      |      |      |      |      |      |      |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_DVORAK] = LAYOUT_planck_grid(
+    _______, KC_QUOT, KC_COMM, KC_DOT,  KC_P,    KC_Y,    KC_F,    KC_G,     KC_C,    KC_R,    KC_L,    _______,
+    _______, A_ALT,   O_GUI,   E_SFT,   U_CTRL,  KC_I,    KC_D,    H_CTRL,   T_SFT,   N_GUI,   S_ALT,   _______,
+    _______, KC_SCLN, KC_Q,    KC_J,    KC_K,    KC_X,    KC_B,    KC_M,     KC_W,    KC_V,    KC_Z,    _______,
+    _______,  _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+),
+
+
+/* Lower
+ * ,-----------------------------------------------------------------------------------.
+ * | F11  | _    |  -   |  ~   |  %   | '    |      |  ^   |  `   |  \   |  |   |  -   |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | Del  |  [   |  {   |  +   |  (   |  =   |  *   |   )  |   !  |  }   |  ]   | Bksp |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      | CAD  | CAH  |      | LANG |      |      | EN   | HEB  | RUS  |      |      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      | RCTL |      |      |      | [{}] |      |      | PSCR | PGDN | PGUP |      |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_LOWER] = LAYOUT_planck_grid(
+    KC_F11,  KC_UNDS, KC_MINS,  KC_TILD, KC_PERC, KC_QUOT, _______, KC_CIRC,  KC_GRV,  KC_BSLS,  KC_PIPE, KC_MINS,
+    KC_DEL,  KC_LBRC, KC_LCBR,  KC_PLUS, KC_LPRN, KC_EQL,  KC_ASTR, KC_RPRN,  KC_EXLM, KC_RCBR,  KC_RBRC, KC_BSPC,
+    _______, KC_CAD,  KC_CAH,   _______, LANG,    _______, _______, HEB_LANG, EN_LANG, RUS_LANG, _______, _______,
+    _______, KC_RCTL, _______,  _______, _______, _______, _______, _______,  KC_PSCR, KC_PGDN,  KC_PGUP, _______
+),
+
+/* Raise
+ * ,-----------------------------------------------------------------------------------.
+ * | F11  |      |      |  $   |  &   |      | :    |   ?  |   @  |   #  |   /  | F12  |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * |      |  7   |  5   |  3   |  1   |  9   |  0   |  2   |  4   |  6   |  8   | Bksp |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |  F7  |  F5  |  F3  |  F1  |  F9  |  F10 |  F2  |  F4  |  F6  |  F8  |      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      |      | [{}] |      | Vol- | End  | Home | Vol+ |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_RAISE] = LAYOUT_planck_grid(
+    KC_F11,  _______, _______, KC_DLR,  KC_AMPR, _______, KC_COLON, KC_QUES, KC_AT,   KC_HASH, KC_SLSH, KC_F12,
+    _______, KC_7,    KC_5,    KC_3,    KC_1,    KC_9,    KC_0,    KC_2,    KC_4,    KC_6,    KC_8,    KC_BSPC,
+    _______, KC_F7,   KC_F5,   KC_F3,   KC_F1,   KC_F9,   KC_F10,  KC_F2,   KC_F4,   KC_F6,   KC_F8,   _______,
+    _______, _______, _______, _______, _______, _______, _______, _______, KC_VOLD, KC_END,  KC_HOME, KC_VOLU
+),
+
+/* TOP
+ * ,-----------------------------------------------------------------------------------
+ * |      |      |      |      |      |      |      |      |      |      |      |      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      |      |      |      |      |      |      |      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      | Down | Up   |      |      |      |      |      |      |      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      |      |      |      | [{}] |      |      |      |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_TOP] = LAYOUT_planck_grid(
+    _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+    _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+    _______, _______, _______, KC_DOWN, KC_UP,   _______, _______, _______, _______, _______, _______, _______,
+    _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+),
+
+/* BOTTOM
+ * ,-----------------------------------------------------------------------------------
+ * |      |      |      |      |      |      |      |      |      |      | ->   |      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      |      |      | <-   |      |      |      |      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      |      |      | vold | volu |      |      |      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      | [{}] |      |      |      |      |      |      |      |      |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_BOTTOM] = LAYOUT_planck_grid(
+    _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_RGHT, _______,
+    _______, _______, _______, _______, _______, _______, _______, KC_LEFT, _______, _______, _______, _______,
+    _______, _______, _______, _______, _______, _______, _______, KC_VOLD, KC_VOLU, _______, _______, _______,
+    _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+),
+
+/* Adjust (Lower + Raise)
+ *                      v------------------------RGB CONTROL--------------------v
+ * ,-----------------------------------------------------------------------------------
+ * |      | Reset|Debug | RGB  |RGBMOD| HUE+ | HUE- | SAT+ | SAT- |BRGTH+|BRGTH-|  Del |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |Aud on|Audoff|      |      |      |      |      |      |Dvorak|      |      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |Mus on|Musoff|      |      |      |      |      |      |      |      | USSR |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      | [{}] | [{}] |      |      |      |      |      |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_ADJUST] = LAYOUT_planck_grid(
+    _______, RESET,   DEBUG,   RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_DEL ,
+    _______, AU_ON,   AU_OFF,  _______, _______, _______, _______, _______, _______, _______, _______, _______,
+    _______, MU_ON,   MU_OFF,  _______, _______, _______, _______, _______, _______, _______, _______, BRUDERSCHAFT,
+    _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+)
+
+};
+
+void keyboard_post_init_user(void) {
+  layer_on(_DVORAK);
+}
+
+void set_english_language(void) {
+    layer_on(_DVORAK);
+    SEND_STRING(SS_LSFT(SS_LCTL(SS_LGUI(SS_TAP(X_1)))));
+}
+
+void set_russian_language(void) {
+    layer_off(_DVORAK);
+    SEND_STRING(SS_LSFT(SS_LCTL(SS_LGUI(SS_TAP(X_2)))));
+}
+
+void set_hebrew_language(void) {
+    layer_off(_DVORAK);
+    SEND_STRING(SS_LSFT(SS_LCTL(SS_LGUI(SS_TAP(X_3)))));
+}
+
+
+#define CASE(keycode, key_pressed_action, key_released_action)   \
+  case (keycode):                                               \
+    if (record->event.pressed) {                                \
+      key_pressed_action;                                       \
+    } else {                                                    \
+      key_released_action;                                      \
+    }                                                           \
+    return false;                                               \
+    break;
+
+#define CASE_PRESSED(keycode, key_pressed_action) CASE(keycode, key_pressed_action, {});
+
+#define CASE_MOD_TAP_KEY(keycode, tap_action, mod_off_action) \
+  CASE(keycode, {                                  \
+    keycode ## _TIMER = timer_read();                         \
+    IS_ ## keycode ## _ACTIVE = true;                         \
+  }, {                                                        \
+    if(IS_ ## keycode ## _MOD_ACTIVE) {                       \
+      mod_off_action;                          		      \
+    } else if (IS_ ## keycode ## _ACTIVE) {                   \
+      tap_action;                                             \
+    }                                                         \
+    IS_ ## keycode ## _MOD_ACTIVE = false; 		      \
+    IS_ ## keycode ## _ACTIVE = false;                        \
+  });
+
+#define MOD_TAP_KEY(keycode, tap_action, mod_on_action, mod_off_action) \
+uint16_t keycode ## _TIMER = 0;                                 	\
+bool IS_ ## keycode ## _ACTIVE = false; 		                \
+bool IS_ ## keycode ## _MOD_ACTIVE = false;
+#include "mod_tap_keys.h"
+#undef MOD_TAP_KEY
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+  switch (keycode) {
+    CASE_PRESSED(BRUDERSCHAFT, PLAY_SONG(USSR_SONG));
+
+    CASE_PRESSED(EN_LANG, set_english_language());
+    CASE_PRESSED(RUS_LANG, set_russian_language());
+    CASE_PRESSED(HEB_LANG, set_hebrew_language());
+
+    CASE_PRESSED(VIM_SAVE, {set_english_language(); SEND_STRING(SS_TAP(X_ESC)SS_LSFT(SS_TAP(X_SCLN))SS_TAP(X_W)SS_TAP(X_ENT));});
+
+    #define MOD_TAP_KEY(keycode, tap_action, mod_on_action, mod_off_action) \
+    CASE_MOD_TAP_KEY(keycode, tap_action, mod_off_action);
+    #include "mod_tap_keys.h"
+    #undef MOD_TAP_KEY
+  }
+
+  #define MOD_TAP_KEY(keycode, tap_action, mod_on_action, mod_off_action) \
+  if (IS_ ## keycode ## _ACTIVE && !IS_ ## keycode ## _MOD_ACTIVE) {      \
+    if (timer_elapsed(keycode ## _TIMER) <= TAPPING_TERM) {               \
+      tap_action;                                                         \
+      IS_ ## keycode ## _ACTIVE = false;                                  \
+    }                                                    		  \
+  }
+  #include "mod_tap_keys.h"
+  #undef MOD_TAP_KEY
+
+  return true;
+}
+
+bool muse_mode = false;
+uint8_t last_muse_note = 0;
+uint16_t muse_counter = 0;
+uint8_t muse_offset = 70;
+uint16_t muse_tempo = 50;
+
+bool encoder_update_user(uint8_t index, bool clockwise) {
+  if (muse_mode) {
+    if (IS_LAYER_ON(_RAISE)) {
+      if (clockwise) {
+        muse_offset++;
+      } else {
+        muse_offset--;
+      }
+    } else {
+      if (clockwise) {
+        muse_tempo+=1;
+      } else {
+        muse_tempo-=1;
+      }
+    }
+  } else {
+    if (clockwise) {
+      #ifdef MOUSEKEY_ENABLE
+        tap_code(KC_MS_WH_DOWN);
+      #else
+        tap_code(KC_PGDN);
+      #endif
+    } else {
+      #ifdef MOUSEKEY_ENABLE
+        tap_code(KC_MS_WH_UP);
+      #else
+        tap_code(KC_PGUP);
+      #endif
+    }
+  }
+  return false;
+}
+
+bool dip_switch_update_user(uint8_t index, bool active) {
+  switch (index) {
+    case 0:
+      if (active) {
+        layer_off(_ADJUST);
+      }
+      break;
+    case 1:
+      if (active) {
+        muse_mode = true;
+      } else {
+        muse_mode = false;
+        #ifdef AUDIO_ENABLE
+          stop_all_notes();
+        #endif
+      }
+   }
+  return true;
+}
+
+void matrix_scan_user(void) {
+  #define MOD_TAP_KEY(keycode, tap_action, mod_on_action, mod_off_action) \
+  if (IS_ ## keycode ## _ACTIVE) {                                        \
+    if (timer_elapsed(keycode ## _TIMER) > TAPPING_TERM) {                \
+      mod_on_action;                                                      \
+      IS_ ## keycode ## _MOD_ACTIVE = true;                               \
+    }                                                    		  \
+  }
+  #include "mod_tap_keys.h"
+  #undef MOD_TAP_KEY
+
+  #ifdef AUDIO_ENABLE
+    if (muse_mode) {
+      if (muse_counter == 0) {
+        uint8_t muse_note = muse_offset + SCALE[muse_clock_pulse()];
+        if (muse_note != last_muse_note) {
+          stop_note(compute_freq_for_midi_note(last_muse_note));
+          play_note(compute_freq_for_midi_note(muse_note), 0xF);
+          last_muse_note = muse_note;
+        }
+      }
+      muse_counter = (muse_counter + 1) % muse_tempo;
+    }
+  #endif
+}
+
+bool music_mask_user(uint16_t keycode) {
+  switch (keycode) {
+    case RAISE:
+    case LOWER:
+      return false;
+    default:
+      return true;
+  }
+}
+
+layer_state_t layer_state_set_user(layer_state_t state) {
+  return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
+}
+
+enum combo_events {
+  // combos for dvorak layer
+  RU_COMBO,
+  EN_COMBO,
+  HEB_COMBO,
+  ESC_COMBO,
+  TAB_COMBO,
+  ENT_COMBO,
+  DEL_COMBO,
+  SAVE_COMBO,
+  BSPC_COMBO,
+  BSPCW_COMBO,
+
+  // combos for qwerty layer
+  RUQ_COMBO,
+  ENQ_COMBO,
+  HEBQ_COMBO,
+  ESCQ_COMBO,
+  TABQ_COMBO,
+  ENTQ_COMBO,
+  DELQ_COMBO,
+  SAVEQ_COMBO,
+  BSPCQ_COMBO,
+  BSPCWQ_COMBO,
+
+  COMBO_LENGTH
+};
+uint16_t COMBO_LEN = COMBO_LENGTH;
+
+const uint16_t PROGMEM ru_combo[] = {KC_R, U_CTRL, COMBO_END};
+const uint16_t PROGMEM en_combo[] = {U_CTRL, S_ALT, COMBO_END};
+const uint16_t PROGMEM heb_combo[] = {KC_I, KC_V, COMBO_END};
+const uint16_t PROGMEM esc_combo[] = {H_CTRL, U_CTRL, COMBO_END};
+const uint16_t PROGMEM tab_combo[] = {T_SFT, A_ALT, COMBO_END};
+const uint16_t PROGMEM ent_combo[] = {E_SFT, N_GUI, COMBO_END};
+const uint16_t PROGMEM del_combo[] = {KC_D, E_SFT, COMBO_END};
+const uint16_t PROGMEM bspc_combo[] = {KC_C, H_CTRL, COMBO_END};
+const uint16_t PROGMEM bspcw_combo[] = {N_GUI, U_CTRL, COMBO_END};
+const uint16_t PROGMEM save_combo[] = {O_GUI, H_CTRL, COMBO_END};
+
+const uint16_t PROGMEM ruq_combo[] = {KC_O, F_CTLQ, COMBO_END};
+const uint16_t PROGMEM enq_combo[] = {F_CTLQ, SCLN_Q, COMBO_END};
+const uint16_t PROGMEM hebq_combo[] = {KC_G, KC_DOT, COMBO_END};
+const uint16_t PROGMEM escq_combo[] = {F_CTLQ, J_CTLQ, COMBO_END};
+const uint16_t PROGMEM tabq_combo[] = {K_SFT, A_ALTQ, COMBO_END};
+const uint16_t PROGMEM entq_combo[] = {D_SFT, L_GUIQ, COMBO_END};
+const uint16_t PROGMEM delq_combo[] = {KC_H, D_SFT, COMBO_END};
+const uint16_t PROGMEM bspcq_combo[] = {KC_I, J_CTLQ, COMBO_END};
+const uint16_t PROGMEM bspcwq_combo[] = {L_GUIQ, F_CTLQ, COMBO_END};
+const uint16_t PROGMEM saveq_combo[] = {S_GUIQ, J_CTLQ, COMBO_END};
+
+combo_t key_combos[] = {
+    [RU_COMBO] = COMBO(ru_combo, RUS_LANG),
+    [EN_COMBO] = COMBO(en_combo, EN_LANG),
+    [HEB_COMBO] = COMBO(heb_combo, HEB_LANG),
+    [ESC_COMBO] = COMBO(esc_combo, KC_ESC),
+    [TAB_COMBO] = COMBO(tab_combo, KC_TAB),
+    [ENT_COMBO] = COMBO(ent_combo, KC_ENT),
+    [DEL_COMBO] = COMBO(del_combo, KC_DEL),
+    [BSPC_COMBO] = COMBO(bspc_combo, KC_BSPC),
+    [SAVE_COMBO] = COMBO(save_combo, VIM_SAVE),
+    [BSPCW_COMBO] = COMBO(bspcw_combo, A(KC_BSPC)),
+
+    [RUQ_COMBO] = COMBO(ruq_combo, RUS_LANG),
+    [ENQ_COMBO] = COMBO(enq_combo, EN_LANG),
+    [HEBQ_COMBO] = COMBO(hebq_combo, HEB_LANG),
+    [ESCQ_COMBO] = COMBO(escq_combo, KC_ESC),
+    [TABQ_COMBO] = COMBO(tabq_combo, KC_TAB),
+    [ENTQ_COMBO] = COMBO(entq_combo, KC_ENT),
+    [DELQ_COMBO] = COMBO(delq_combo, KC_DEL),
+    [BSPCQ_COMBO] = COMBO(bspcq_combo, KC_BSPC),
+    [SAVEQ_COMBO] = COMBO(saveq_combo, VIM_SAVE),
+    [BSPCWQ_COMBO] = COMBO(bspcwq_combo, A(KC_BSPC)),
+};
+
+

+ 14 - 0
keyboards/planck/keymaps/antosha417/mod_tap_keys.h

@@ -0,0 +1,14 @@
+// Copyright 2021 Anton Kavalkou (@antosha417)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+// MOD_TAP_KEY(key, tap_action, mod_on_action, mod_off_action)
+
+MOD_TAP_KEY(S_GUIQ, tap_code(KC_S), {layer_on(_DVORAK); register_code(KC_LGUI);}, {layer_off(_DVORAK); unregister_code(KC_LGUI);})
+MOD_TAP_KEY(L_GUIQ, tap_code(KC_L), {layer_on(_DVORAK); register_code(KC_RGUI);}, {layer_off(_DVORAK); unregister_code(KC_RGUI);})
+
+MOD_TAP_KEY(F_CTLQ, tap_code(KC_F), {layer_on(_DVORAK); register_code(KC_LCTL);}, {layer_off(_DVORAK); unregister_code(KC_LCTL);})
+MOD_TAP_KEY(J_CTLQ, tap_code(KC_J), {layer_on(_DVORAK); register_code(KC_RCTL);}, {layer_off(_DVORAK); unregister_code(KC_RCTL);})
+
+MOD_TAP_KEY(A_ALTQ, tap_code(KC_A), {layer_on(_DVORAK); register_code(KC_LALT);}, {layer_off(_DVORAK); unregister_code(KC_LALT);})
+MOD_TAP_KEY(SCLN_Q, tap_code(KC_SCLN), {layer_on(_DVORAK); register_code(KC_RALT);}, {layer_off(_DVORAK); unregister_code(KC_RALT);})
+

+ 11 - 0
keyboards/planck/keymaps/antosha417/readme.md

@@ -0,0 +1,11 @@
+# How to install:
+
+    make planck/rev6:antosha417:flash
+
+# Useful:
+  * [keycodes](https://docs.qmk.fm/#/keycodes)
+  * [string keycodes](https://github.com/qmk/qmk_firmware/blob/master/quantum/send_string_keycodes.h)
+
+# Todo:
+  [ ] sync with corne
+

+ 4 - 0
keyboards/planck/keymaps/antosha417/rules.mk

@@ -0,0 +1,4 @@
+SRC += muse.c
+AUDIO_ENABLE = yes
+COMBO_ENABLE = yes
+

+ 57 - 0
keyboards/ydkb/grape/config.h

@@ -0,0 +1,57 @@
+/* Copyright 2022 somepin
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include "config_common.h"
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID       0x5945 // "YE"
+#define PRODUCT_ID      0x6772 // "GR"
+#define DEVICE_VER      0x0001
+#define MANUFACTURER    YDKB
+#define PRODUCT         Grape
+
+/* key matrix size */
+#define MATRIX_ROWS 7
+#define MATRIX_COLS 18
+
+#define MATRIX_COL_PINS { F4, F5, F6, F7, C7, C6, B6, B5, B4, D7, D6, D4, D5, D3, B3, B2, B1, B0 }
+
+#define SN74X138_ADDRESS_PINS { D2, D1, D0 }
+
+#define LED_NUM_LOCK_PIN F1
+#define LED_CAPS_LOCK_PIN F0
+#define LED_SCROLL_LOCK_PIN E6
+#define LED_PIN_ON_STATE 0
+
+#define BACKLIGHT_PIN B7
+#define BACKLIGHT_BREATHING
+#define BACKLIGHT_LEVELS 3
+
+#ifdef RGBLIGHT_ENABLE
+#define RGB_DI_PIN E6
+#define RGBLED_NUM 4
+#endif
+
+/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
+#define DEBOUNCE 5
+
+/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
+#define LOCKING_SUPPORT_ENABLE
+/* Locking resynchronize hack */
+#define LOCKING_RESYNC_ENABLE
+
+#define DYNAMIC_KEYMAP_LAYER_COUNT 3

+ 16 - 0
keyboards/ydkb/grape/grape.c

@@ -0,0 +1,16 @@
+/* Copyright 2022 somepin
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "grape.h"

+ 47 - 0
keyboards/ydkb/grape/grape.h

@@ -0,0 +1,47 @@
+/* Copyright 2022 somepin
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include "quantum.h"
+
+#define XXX KC_NO
+
+/* This is a shortcut to help you visually see your layout.
+ *
+ * The first section contains all of the arguments representing the physical
+ * layout of the board and position of the keys.
+ *
+ * The second converts the arguments into a two-dimensional array which
+ * represents the switch matrix.
+ */
+#define LAYOUT_all( \
+    K0A,      K0C, K0D, K0E, K0F, K0G, K0H, K0I, K0J, K0K, K0L,      K0N,          K0P, K0Q, K0R, K0S, \
+              K1C, K1D, K1E, K1F, K1G, K1H, K1I, K1J, K1K, K1L,                    K1P, K1Q, K1R, K1S, \
+                                                                                   K2P, K2Q, K2R, K2S, \
+    K2A, K2B, K2C, K2D, K2E, K2F, K2G, K2H, K2I, K2J, K2K, K2L, K2M, K2N, K1N,     K3P, K3Q, K3R, K3S, \
+    K3A, K3B, K3C, K3D, K3E, K3F, K3G, K3H, K3I, K3J, K3K, K3L, K3M, K3N,          K4P, K4Q, K4R, K4S, \
+    K4A, K4B, K4C, K4D, K4E, K4F, K4G, K4H, K4I, K4J, K4K, K4L,      K4N,             K5Q, K5R, K5S,   \
+    K5A, K5B, K5C, K5D, K5E, K5F, K5G, K5H, K5I, K5J, K5K, K5L, K5M, K4M, K5N,        K6Q, K6R, K6S,   \
+    K6A, K6B, K6C,      K6E, K6F,      K6H, K6I, K6J, K6K,           K6L, K6M, K6N,      K5P, K6P      \
+) { \
+    { K0A,  XXX,  K0C,  K0D,  K0E,  K0F,  K0G,  K0H,  K0I,  K0J,  K0K,  K0L,  XXX,  K0N,  K0P,  K0Q,  K0R,  K0S }, \
+    { XXX,  XXX,  K1C,  K1D,  K1E,  K1F,  K1G,  K1H,  K1I,  K1J,  K1K,  K1L,  XXX,  K1N,  K1P,  K1Q,  K1R,  K1S }, \
+    { K2A,  K2B,  K2C,  K2D,  K2E,  K2F,  K2G,  K2H,  K2I,  K2J,  K2K,  K2L,  K2M,  K2N,  K2P,  K2Q,  K2R,  K2S }, \
+    { K3A,  K3B,  K3C,  K3D,  K3E,  K3F,  K3G,  K3H,  K3I,  K3J,  K3K,  K3L,  K3M,  K3N,  K3P,  K3Q,  K3R,  K3S }, \
+    { K4A,  K4B,  K4C,  K4D,  K4E,  K4F,  K4G,  K4H,  K4I,  K4J,  K4K,  K4L,  K4M,  K4N,  K4P,  K4Q,  K4R,  K4S }, \
+    { K5A,  K5B,  K5C,  K5D,  K5E,  K5F,  K5G,  K5H,  K5I,  K5J,  K5K,  K5L,  K5M,  K5N,  K5P,  K5Q,  K5R,  K5S }, \
+    { K6A,  K6B,  K6C,  XXX,  K6E,  K6F,  XXX,  K6H,  K6I,  K6J,  K6K,  K6L,  K6M,  K6N,  K6P,  K6Q,  K6R,  K6S }  \
+}

+ 130 - 0
keyboards/ydkb/grape/info.json

@@ -0,0 +1,130 @@
+{
+    "keyboard_name": "Grape",
+    "url": "https://item.taobao.com/item.htm?id=642205244150",
+    "maintainer": "Gacathon",
+    "layouts": {
+        "LAYOUT_all": {
+            "layout": [
+                { "label": "Esc", "x": 0, "y": 0 },
+                { "label": "F1", "x": 2, "y": 0 },
+                { "label": "F2", "x": 3, "y": 0 },
+                { "label": "F3", "x": 4, "y": 0 },
+                { "label": "F4", "x": 5, "y": 0 },
+                { "label": "F5", "x": 6, "y": 0 },
+                { "label": "F6", "x": 7, "y": 0 },
+                { "label": "Insert", "x": 8.5, "y": 0 },
+                { "label": "Home", "x": 9.5, "y": 0 },
+                { "label": "PgUp", "x": 10.5, "y": 0 },
+                { "label": "PrtSc", "x": 11.5, "y": 0 },
+                { "label": "Pause", "x": 13, "y": 0 },
+                { "label": "Num Lock", "x": 16, "y": 0 },
+                { "label": "/", "x": 17, "y": 0 },
+                { "label": "*", "x": 18, "y": 0 },
+                { "label": "-", "x": 19, "y": 0 },
+                { "label": "F7", "x": 2, "y": 1 },
+                { "label": "F8", "x": 3, "y": 1 },
+                { "label": "F9", "x": 4, "y": 1 },
+                { "label": "F10", "x": 5, "y": 1 },
+                { "label": "F11", "x": 6, "y": 1 },
+                { "label": "F12", "x": 7, "y": 1 },
+                { "label": "Delete", "x": 8.5, "y": 1 },
+                { "label": "End", "x": 9.5, "y": 1 },
+                { "label": "PgDn", "x": 10.5, "y": 1 },
+                { "label": "Scroll Lock", "x": 11.5, "y": 1 },
+                { "label": "7", "x": 16, "y": 1 },
+                { "label": "8", "x": 17, "y": 1 },
+                { "label": "9", "x": 18, "y": 1 },
+                { "label": "+", "x": 19, "y": 1 },
+                { "label": "4", "x": 16, "y": 2 },
+                { "label": "5", "x": 17, "y": 2 },
+                { "label": "6", "x": 18, "y": 2 },
+                { "label": "+", "x": 19, "y": 2 },
+                { "label": "~", "x": 0, "y": 3 },
+                { "label": "!", "x": 1, "y": 3 },
+                { "label": "@", "x": 2, "y": 3 },
+                { "label": "#", "x": 3, "y": 3 },
+                { "label": "$", "x": 4, "y": 3 },
+                { "label": "%", "x": 5, "y": 3 },
+                { "label": "^", "x": 6, "y": 3 },
+                { "label": "&", "x": 7, "y": 3 },
+                { "label": "*", "x": 8, "y": 3 },
+                { "label": "(", "x": 9, "y": 3 },
+                { "label": ")", "x": 10, "y": 3 },
+                { "label": "_", "x": 11, "y": 3 },
+                { "label": "+", "x": 12, "y": 3 },
+                { "label": "Bksp", "x": 13, "y": 3 },
+                { "label": "Bksp", "x": 14, "y": 3 },
+                { "label": "1", "x": 16, "y": 3 },
+                { "label": "2", "x": 17, "y": 3 },
+                { "label": "3", "x": 18, "y": 3 },
+                { "label": "Enter", "x": 19, "y": 3 },
+                { "label": "Tab", "x": 0, "y": 4, "w": 1.5 },
+                { "label": "Q", "x": 1.5, "y": 4 },
+                { "label": "W", "x": 2.5, "y": 4 },
+                { "label": "E", "x": 3.5, "y": 4 },
+                { "label": "R", "x": 4.5, "y": 4 },
+                { "label": "T", "x": 5.5, "y": 4 },
+                { "label": "Y", "x": 6.5, "y": 4 },
+                { "label": "U", "x": 7.5, "y": 4 },
+                { "label": "I", "x": 8.5, "y": 4 },
+                { "label": "O", "x": 9.5, "y": 4 },
+                { "label": "P", "x": 10.5, "y": 4 },
+                { "label": "{", "x": 11.5, "y": 4 },
+                { "label": "}", "x": 12.5, "y": 4 },
+                { "label": "|", "x": 13.5, "y": 4, "w": 1.5 },
+                { "label": "0", "x": 16, "y": 4 },
+                { "label": "0", "x": 17, "y": 4 },
+                { "label": ".", "x": 18, "y": 4 },
+                { "label": "Enter", "x": 19, "y": 4 },
+                { "label": "Caps Lock", "x": 0, "y": 5, "w": 1.75 },
+                { "label": "A", "x": 1.75, "y": 5 },
+                { "label": "S", "x": 2.75, "y": 5 },
+                { "label": "D", "x": 3.75, "y": 5 },
+                { "label": "F", "x": 4.75, "y": 5 },
+                { "label": "G", "x": 5.75, "y": 5 },
+                { "label": "H", "x": 6.75, "y": 5 },
+                { "label": "J", "x": 7.75, "y": 5 },
+                { "label": "K", "x": 8.75, "y": 5 },
+                { "label": "L", "x": 9.75, "y": 5 },
+                { "label": ":", "x": 10.75, "y": 5 },
+                { "label": "\"", "x": 11.75, "y": 5 },
+                { "label": "Enter", "x": 12.75, "y": 5, "w": 2.25 },
+                { "label": "F13", "x": 16.5, "y": 5.25 },
+                { "label": "F14", "x": 17.5, "y": 5.25 },
+                { "label": "F15", "x": 18.5, "y": 5.25 },
+                { "label": "Shift", "x": 0, "y": 6, "w": 1.25 },
+                { "label": "Shift", "x": 1.25, "y": 6 },
+                { "label": "Z", "x": 2.25, "y": 6 },
+                { "label": "X", "x": 3.25, "y": 6 },
+                { "label": "C", "x": 4.25, "y": 6 },
+                { "label": "V", "x": 5.25, "y": 6 },
+                { "label": "B", "x": 6.25, "y": 6 },
+                { "label": "N", "x": 7.25, "y": 6 },
+                { "label": "M", "x": 8.25, "y": 6 },
+                { "label": "<", "x": 9.25, "y": 6 },
+                { "label": ">", "x": 10.25, "y": 6 },
+                { "label": "?", "x": 11.25, "y": 6 },
+                { "label": "Shift", "x": 12.25, "y": 6 },
+                { "label": "Shift", "x": 13.25, "y": 6 },
+                { "label": "\u2191", "x": 14.5, "y": 6.25 },
+                { "label": "F16", "x": 16.5, "y": 6.25 },
+                { "label": "F17", "x": 17.5, "y": 6.25 },
+                { "label": "F18", "x": 18.5, "y": 6.25 },
+                { "label": "Ctrl", "x": 0, "y": 7 },
+                { "label": "Win", "x": 1, "y": 7 },
+                { "label": "Alt", "x": 2, "y": 7 },
+                { "x": 3, "y": 7, "w": 3 },
+                { "x": 6, "y": 7, "w": 3 },
+                { "label": "Alt", "x": 9, "y": 7 },
+                { "label": "Win", "x": 10, "y": 7 },
+                { "label": "Menu", "x": 11, "y": 7 },
+                { "label": "Ctrl", "x": 12, "y": 7 },
+                { "label": "\u2190", "x": 13.5, "y": 7.25 },
+                { "label": "\u2193", "x": 14.5, "y": 7.25 },
+                { "label": "\u2192", "x": 15.5, "y": 7.25 },
+                { "label": "BTN1", "x": 17, "y": 7.25 },
+                { "label": "BTN2", "x": 18, "y": 7.25 }
+            ]
+        }
+    }
+}

+ 29 - 0
keyboards/ydkb/grape/keymaps/default/keymap.c

@@ -0,0 +1,29 @@
+/* Copyright 2022 somepin
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+    [0] = LAYOUT_all(
+        KC_ESC,           KC_F1,   KC_F2,  KC_F3,  KC_F4,  KC_F5,  KC_F6,  KC_INS,  KC_HOME, KC_PGUP, KC_PSCR,          KC_PAUS,              KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS,
+                          KC_F7,   KC_F8,  KC_F9,  KC_F10, KC_F11, KC_F12, KC_DEL,  KC_END,  KC_PGDN, KC_SLCK,                                KC_P7,   KC_P8,   KC_P9,   KC_PPLS,
+                                                                                                                                              KC_P4,   KC_P5,   KC_P6,   KC_PPLS,
+        KC_GRV,  KC_1,    KC_2,    KC_3,   KC_4,   KC_5,   KC_6,   KC_7,   KC_8,    KC_9,    KC_0,    KC_MINS, KC_EQL,  KC_BSPC, KC_BSPC,     KC_P1,   KC_P2,   KC_P3,   KC_PENT,
+        KC_TAB,  KC_Q,    KC_W,    KC_E,   KC_R,   KC_T,   KC_Y,   KC_U,   KC_I,    KC_O,    KC_P,    KC_LBRC, KC_RBRC, KC_BSLS,              KC_P0,   KC_P0,   KC_PDOT, KC_PENT,
+        KC_CAPS, KC_A,    KC_S,    KC_D,   KC_F,   KC_G,   KC_H,   KC_J,   KC_K,    KC_L,    KC_SCLN, KC_QUOT,          KC_ENT,                   KC_F13,   KC_F14,   KC_F15,   
+        KC_LSFT, KC_LSFT, KC_Z,    KC_X,   KC_C,   KC_V,   KC_B,   KC_N,   KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_RSFT, KC_RSFT, KC_UP,           KC_F16,   KC_F17,   KC_F18,   
+        KC_LCTL, KC_LGUI, KC_LALT,                 KC_SPC, KC_SPC,         KC_RALT, KC_RGUI, KC_APP,  KC_RCTL,          KC_LEFT, KC_DOWN, KC_RGHT,     KC_BTN1, KC_BTN2    
+    )
+};

+ 51 - 0
keyboards/ydkb/grape/keymaps/via/keymap.c

@@ -0,0 +1,51 @@
+/* Copyright 2022 somepin
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+    [0] = LAYOUT_all(
+        KC_ESC,           KC_F1,   KC_F2,  KC_F3,  KC_F4,  KC_F5,  KC_F6,  KC_INS,  KC_HOME, KC_PGUP, KC_PSCR,          KC_PAUS,              KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS,
+                          KC_F7,   KC_F8,  KC_F9,  KC_F10, KC_F11, KC_F12, KC_DEL,  KC_END,  KC_PGDN, KC_SLCK,                                KC_P7,   KC_P8,   KC_P9,   KC_PPLS,
+                                                                                                                                              KC_P4,   KC_P5,   KC_P6,   KC_PPLS,
+        KC_GRV,  KC_1,    KC_2,    KC_3,   KC_4,   KC_5,   KC_6,   KC_7,   KC_8,    KC_9,    KC_0,    KC_MINS, KC_EQL,  KC_BSPC, KC_BSPC,     KC_P1,   KC_P2,   KC_P3,   KC_PENT,
+        KC_TAB,  KC_Q,    KC_W,    KC_E,   KC_R,   KC_T,   KC_Y,   KC_U,   KC_I,    KC_O,    KC_P,    KC_LBRC, KC_RBRC, KC_BSLS,              KC_P0,   KC_P0,   KC_PDOT, KC_PENT,
+        KC_CAPS, KC_A,    KC_S,    KC_D,   KC_F,   KC_G,   KC_H,   KC_J,   KC_K,    KC_L,    KC_SCLN, KC_QUOT,          KC_ENT,                   KC_F13,   KC_F14,   KC_F15,   
+        KC_LSFT, KC_LSFT, KC_Z,    KC_X,   KC_C,   KC_V,   KC_B,   KC_N,   KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_RSFT, KC_RSFT, KC_UP,           KC_F16,   KC_F17,   KC_F18,   
+        KC_LCTL, KC_LGUI, KC_LALT,                 KC_SPC, KC_SPC,         KC_RALT, KC_RGUI, KC_APP,  KC_RCTL,          KC_LEFT, KC_DOWN, KC_RGHT,     KC_BTN1, KC_BTN2    
+    ),
+
+    [1] = LAYOUT_all(
+        _______,          _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______,              _______, _______, _______, _______,
+                          _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,                                _______, _______, _______, _______,
+                                                                                                                                                   _______, _______, _______, _______,
+        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,     _______, _______, _______, _______,
+        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,              _______, _______, _______, _______,
+        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______,                _______,   _______,   _______,   
+        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,       _______,   _______,   _______,   
+        _______, _______, _______,               _______, _______,         _______, _______, _______,  _______,              _______, _______, _______,      _______, _______    
+    ),
+
+    [2] = LAYOUT_all(
+        _______,          _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______,              _______, _______, _______, _______,
+                          _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,                                _______, _______, _______, _______,
+                                                                                                                                                   _______, _______, _______, _______,
+        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,     _______, _______, _______, _______,
+        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,              _______, _______, _______, _______,
+        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______,                _______,   _______,   _______,   
+        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,       _______,   _______,   _______,   
+        _______, _______, _______,               _______, _______,         _______, _______, _______,  _______,              _______, _______, _______,      _______, _______    
+    ),
+};

+ 2 - 0
keyboards/ydkb/grape/keymaps/via/rules.mk

@@ -0,0 +1,2 @@
+VIA_ENABLE = yes
+LTO_ENABLE = yes

+ 96 - 0
keyboards/ydkb/grape/matrix.c

@@ -0,0 +1,96 @@
+/*
+Copyright 2022 somepin
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "matrix.h"
+#include "quantum.h"
+#include "sn74x138.h"
+
+static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
+
+/* All rows use a 74HC138 3 to 8 bit demultiplexer.
+ *
+ *     A2   A1   A0
+ *     D0   D1   D2
+ * 0:   0    0    0
+ * 1:   0    0    1
+ * 2:   0    1    0
+ * 3:   0    1    1
+ * 4:   1    0    0
+ * 5:   1    0    1
+ * 6:   1    1    0
+ */
+static void select_row(uint8_t row) {
+    sn74x138_set_addr(row);
+}
+
+static void init_pins(void) {
+    for (uint8_t x = 0; x < MATRIX_COLS; x++) {
+        setPinInputHigh(col_pins[x]);
+    }
+}
+
+static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
+    bool matrix_changed = false;
+
+    // Store last value of row prior to reading
+    matrix_row_t last_row_value = current_matrix[current_row];
+
+    // Start with a clear matrix row
+    current_matrix[current_row] = 0;
+
+    // Select row and wait for row selection to stabilize
+    select_row(current_row);
+    matrix_io_delay();
+
+    // For each col...
+    matrix_row_t row_shifter = MATRIX_ROW_SHIFTER;
+    for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
+
+        // Select the col pin to read (active low)
+        uint8_t pin_state = readPin(col_pins[col_index]);
+
+        // Populate the matrix row with the state of the col pin
+        current_matrix[current_row] |=  pin_state ? 0 : (row_shifter << col_index);
+    }
+    
+    // Determine if matrix changed state
+    if ((last_row_value != current_matrix[current_row]) && !(matrix_changed)) {
+        matrix_changed = true;
+    }
+
+    return matrix_changed;
+}
+
+void matrix_init_custom(void) {
+    // initialize demultiplexer
+    sn74x138_init();
+    // initialize key pins
+    init_pins();
+}
+
+bool matrix_scan_custom(matrix_row_t current_matrix[]) {
+    bool changed = false;
+
+    // Set row, read cols
+    for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) {
+        changed |= read_cols_on_row(current_matrix, current_row);
+    }
+
+    return changed;
+}

+ 23 - 0
keyboards/ydkb/grape/readme.md

@@ -0,0 +1,23 @@
+# YDKB Grape
+
+![YDKB Grape](https://i.imgur.com/TZjgC9yh.jpg)
+
+The YDKB Grape is a Cherry G80-11800/11900 replacement PCB utilizing the ATmega32U4 microcontroller.
+
+* Keyboard Maintainer: [Gacathon](https://github.com/Gacathon)
+* Hardware Supported: YDKB Grape (ATmega32U4)
+* Hardware Availability: [TaoBao](https://item.taobao.com/item.htm?id=642205244150)
+
+Make example for this keyboard (after setting up your build environment):
+
+    make ydkb/grape:default
+
+Flashing example for this keyboard:
+
+    make ydkb/grape:default:flash
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
+
+## Bootloader
+
+To enter the bootloader, briefly press the physical reset button between Num Lock and Numpad 8 on the front of the PCB.

+ 22 - 0
keyboards/ydkb/grape/rules.mk

@@ -0,0 +1,22 @@
+# MCU name
+MCU = atmega32u4
+
+# Bootloader selection
+BOOTLOADER = atmel-dfu
+
+# Build Options
+#   change yes to no to disable
+#
+BOOTMAGIC_ENABLE = yes      # Enable Bootmagic Lite
+MOUSEKEY_ENABLE = yes       # Mouse keys
+EXTRAKEY_ENABLE = yes       # Audio control and System control
+CONSOLE_ENABLE = no         # Console for debug
+COMMAND_ENABLE = no         # Commands for debug and configuration
+NKRO_ENABLE = yes           # Enable N-Key Rollover
+BACKLIGHT_ENABLE = yes      # Enable keyboard backlight functionality
+RGBLIGHT_ENABLE = no        # Enable keyboard RGB underglow
+AUDIO_ENABLE = no           # Audio output
+
+CUSTOM_MATRIX = lite
+VPATH += drivers/gpio
+SRC += matrix.c sn74x138.c

+ 1 - 0
lib/python/qmk/cli/__init__.py

@@ -70,6 +70,7 @@ subcommands = [
     'qmk.cli.new.keymap',
     'qmk.cli.pyformat',
     'qmk.cli.pytest',
+    'qmk.cli.via2json',
     'qmk.cli.xap',
     'qmk.cli.xap.generate_docs',
     'qmk.cli.xap.generate_json',

+ 145 - 0
lib/python/qmk/cli/via2json.py

@@ -0,0 +1,145 @@
+"""Generate a keymap.c from a configurator export.
+"""
+import json
+import re
+
+from milc import cli
+
+import qmk.keyboard
+import qmk.path
+from qmk.info import info_json
+from qmk.json_encoders import KeymapJSONEncoder
+from qmk.commands import parse_configurator_json, dump_lines
+from qmk.keymap import generate_json, list_keymaps, locate_keymap, parse_keymap_c
+
+
+def _find_via_layout_macro(keyboard):
+    keymap_layout = None
+    if 'via' in list_keymaps(keyboard):
+        keymap_path = locate_keymap(keyboard, 'via')
+        if keymap_path.suffix == '.json':
+            keymap_layout = parse_configurator_json(keymap_path)['layout']
+        else:
+            keymap_layout = parse_keymap_c(keymap_path)['layers'][0]['layout']
+    return keymap_layout
+
+
+def _convert_macros(via_macros):
+    via_macros = list(filter(lambda f: bool(f), via_macros))
+    if len(via_macros) == 0:
+        return list()
+    split_regex = re.compile(r'(}\,)|(\,{)')
+    macros = list()
+    for via_macro in via_macros:
+        # Split VIA macro to its elements
+        macro = split_regex.split(via_macro)
+        # Remove junk elements (None, '},' and ',{')
+        macro = list(filter(lambda f: False if f in (None, '},', ',{') else True, macro))
+        macro_data = list()
+        for m in macro:
+            if '{' in m or '}' in m:
+                # Found keycode(s)
+                keycodes = m.split(',')
+                # Remove whitespaces and curly braces from around keycodes
+                keycodes = list(map(lambda s: s.strip(' {}'), keycodes))
+                # Remove the KC prefix
+                keycodes = list(map(lambda s: s.replace('KC_', ''), keycodes))
+                macro_data.append({"action": "tap", "keycodes": keycodes})
+            else:
+                # Found text
+                macro_data.append(m)
+        macros.append(macro_data)
+
+    return macros
+
+
+def _fix_macro_keys(keymap_data):
+    macro_no = re.compile(r'MACRO0?([0-9]{1,2})')
+    for i in range(0, len(keymap_data)):
+        for j in range(0, len(keymap_data[i])):
+            kc = keymap_data[i][j]
+            m = macro_no.match(kc)
+            if m:
+                keymap_data[i][j] = f'MACRO_{m.group(1)}'
+    return keymap_data
+
+
+def _via_to_keymap(via_backup, keyboard_data, keymap_layout):
+    # Check if passed LAYOUT is correct
+    layout_data = keyboard_data['layouts'].get(keymap_layout)
+    if not layout_data:
+        cli.log.error(f'LAYOUT macro {keymap_layout} is not a valid one for keyboard {cli.args.keyboard}!')
+        exit(1)
+
+    layout_data = layout_data['layout']
+    sorting_hat = list()
+    for index, data in enumerate(layout_data):
+        sorting_hat.append([index, data['matrix']])
+
+    sorting_hat.sort(key=lambda k: (k[1][0], k[1][1]))
+
+    pos = 0
+    for row_num in range(0, keyboard_data['matrix_size']['rows']):
+        for col_num in range(0, keyboard_data['matrix_size']['cols']):
+            if pos >= len(sorting_hat) or sorting_hat[pos][1][0] != row_num or sorting_hat[pos][1][1] != col_num:
+                sorting_hat.insert(pos, [None, [row_num, col_num]])
+            else:
+                sorting_hat.append([None, [row_num, col_num]])
+            pos += 1
+
+    keymap_data = list()
+    for layer in via_backup['layers']:
+        pos = 0
+        layer_data = list()
+        for key in layer:
+            if sorting_hat[pos][0] is not None:
+                layer_data.append([sorting_hat[pos][0], key])
+            pos += 1
+        layer_data.sort()
+        layer_data = [kc[1] for kc in layer_data]
+        keymap_data.append(layer_data)
+
+    return keymap_data
+
+
+@cli.argument('-o', '--output', arg_only=True, type=qmk.path.normpath, help='File to write to')
+@cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages")
+@cli.argument('filename', type=qmk.path.FileType('r'), arg_only=True, help='VIA Backup JSON file')
+@cli.argument('-kb', '--keyboard', type=qmk.keyboard.keyboard_folder, completer=qmk.keyboard.keyboard_completer, arg_only=True, required=True, help='The keyboard\'s name')
+@cli.argument('-km', '--keymap', arg_only=True, default='via2json', help='The keymap\'s name')
+@cli.argument('-l', '--layout', arg_only=True, help='The keymap\'s layout')
+@cli.subcommand('Convert a VIA backup json to keymap.json format.')
+def via2json(cli):
+    """Convert a VIA backup json to keymap.json format.
+
+    This command uses the `qmk.keymap` module to generate a keymap.json from a VIA backup json. The generated keymap is written to stdout, or to a file if -o is provided.
+    """
+    # Find appropriate layout macro
+    keymap_layout = cli.args.layout if cli.args.layout else _find_via_layout_macro(cli.args.keyboard)
+    if not keymap_layout:
+        cli.log.error(f"Couldn't find LAYOUT macro for keyboard {cli.args.keyboard}. Please specify it with the '-l' argument.")
+        exit(1)
+
+    # Load the VIA backup json
+    with cli.args.filename.open('r') as fd:
+        via_backup = json.load(fd)
+
+    # Generate keyboard metadata
+    keyboard_data = info_json(cli.args.keyboard)
+
+    # Get keycode array
+    keymap_data = _via_to_keymap(via_backup, keyboard_data, keymap_layout)
+
+    # Convert macros
+    macro_data = list()
+    if via_backup.get('macros'):
+        macro_data = _convert_macros(via_backup['macros'])
+
+        # Replace VIA macro keys with JSON keymap ones
+        keymap_data = _fix_macro_keys(keymap_data)
+
+    # Generate the keymap.json
+    keymap_json = generate_json(cli.args.keymap, cli.args.keyboard, keymap_layout, keymap_data, macro_data)
+
+    keymap_lines = [json.dumps(keymap_json, cls=KeymapJSONEncoder)]
+    dump_lines(cli.args.output, keymap_lines, cli.args.quiet)

+ 7 - 1
lib/python/qmk/json_encoders.py

@@ -146,7 +146,13 @@ class KeymapJSONEncoder(QMKJSONEncoder):
                 if key == 'JSON_NEWLINE':
                     layer.append([])
                 else:
-                    layer[-1].append(f'"{key}"')
+                    if isinstance(key, dict):
+                        # We have a macro
+
+                        # TODO: Add proper support for nicely formatting keymap.json macros
+                        layer[-1].append(f'{self.encode(key)}')
+                    else:
+                        layer[-1].append(f'"{key}"')
 
             layer = [f"{self.indent_str*indent_level}{', '.join(row)}" for row in layer]
 

+ 6 - 1
lib/python/qmk/keymap.py

@@ -158,7 +158,7 @@ def is_keymap_dir(keymap, c=True, json=True, additional_files=None):
             return True
 
 
-def generate_json(keymap, keyboard, layout, layers):
+def generate_json(keymap, keyboard, layout, layers, macros=None):
     """Returns a `keymap.json` for the specified keyboard, layout, and layers.
 
     Args:
@@ -173,11 +173,16 @@ def generate_json(keymap, keyboard, layout, layers):
 
         layers
             An array of arrays describing the keymap. Each item in the inner array should be a string that is a valid QMK keycode.
+
+        macros
+            A sequence of strings containing macros to implement for this keyboard.
     """
     new_keymap = template_json(keyboard)
     new_keymap['keymap'] = keymap
     new_keymap['layout'] = layout
     new_keymap['layers'] = layers
+    if macros:
+        new_keymap['macros'] = macros
 
     return new_keymap