]> git.donarmstrong.com Git - qmk_firmware.git/blobdiff - users/talljoe/tapdance.c
[Keymap] Jarred's Plaid keymap (#6049)
[qmk_firmware.git] / users / talljoe / tapdance.c
index 3198fc67f0577b0f7f85b6c8375c756086066288..c4d6025f0f77a12711b2f92904c987852cd3eee9 100644 (file)
 //Tap Dance
 #include "talljoe.h"
 
-// Send semin-colon + enter on two taps
-void tap_dance_semicolon(qk_tap_dance_state_t *state, void *user_data) {
+enum {
+  SINGLE_TAP = 1,
+  SINGLE_HOLD = 2,
+  DOUBLE_TAP = 3,
+  DOUBLE_HOLD = 4,
+  DOUBLE_SINGLE_TAP = 5, //send two single taps
+  TRIPLE_TAP = 6,
+  TRIPLE_HOLD = 7,
+  SPECIAL = 8
+};
+
+static struct {
+  int quote;
+  int semicolon;
+} tap_state = {0};
+
+int cur_dance (qk_tap_dance_state_t *state) {
+  if (state->count == 1) {
+    //If count = 1, and it has been interrupted - it doesn't matter if it is pressed or not: Send SINGLE_TAP
+    if (state->interrupted) {
+      //     if (!state->pressed) return SINGLE_TAP;
+      //need "permissive hold" here.
+      //     else return SINGLE_HOLD;
+      //If the interrupting key is released before the tap-dance key, then it is a single HOLD
+      //However, if the tap-dance key is released first, then it is a single TAP
+      //But how to get access to the state of the interrupting key????
+      return SINGLE_TAP;
+    }
+    else {
+      if (!state->pressed) return SINGLE_TAP;
+      else return SINGLE_HOLD;
+    }
+  }
+  //If count = 2, and it has been interrupted - assume that user is trying to type the letter associated
+  //with single tap.
+  else if (state->count == 2) {
+    if (state->interrupted) return DOUBLE_SINGLE_TAP;
+    else if (state->pressed) return DOUBLE_HOLD;
+    else return DOUBLE_TAP;
+  }
+  else if ((state->count == 3) && ((state->interrupted) || (!state->pressed))) return TRIPLE_TAP;
+  else if (state->count == 3) return TRIPLE_HOLD;
+  else return SPECIAL;
+}
+
+int hold_cur_dance (qk_tap_dance_state_t *state) {
+  if (state->count == 1) {
+    if (state->interrupted) {
+      if (!state->pressed) return SINGLE_TAP;
+      else return SINGLE_HOLD;
+    }
+    else {
+      if (!state->pressed) return SINGLE_TAP;
+      else return SINGLE_HOLD;
+    }
+  }
+  //If count = 2, and it has been interrupted - assume that user is trying to type the letter associated
+  //with single tap.
+  else if (state->count == 2) {
+    if (state->pressed) return DOUBLE_HOLD;
+    else return DOUBLE_TAP;
+  }
+  else if (state->count == 3) {
+    if (!state->pressed) return TRIPLE_TAP;
+    else return TRIPLE_HOLD;
+  }
+  else return SPECIAL;
+}
+
+// Send semi-colon + enter on two taps
+void tap_dance_semicolon_finished(qk_tap_dance_state_t *state, void *user_data) {
+  tap_state.semicolon = hold_cur_dance(state);
+  switch (tap_state.semicolon) {
+    case SINGLE_TAP: case DOUBLE_HOLD: register_code(KC_SCLN); break;
+    case SINGLE_HOLD: layer_on(_NUM); break;
+  }
+}
+
+void tap_dance_semicolon_reset(qk_tap_dance_state_t *state, void *user_data) {
+  switch (tap_state.semicolon) {
+    case SINGLE_TAP: case DOUBLE_HOLD: unregister_code(KC_SCLN); break;
+    case DOUBLE_TAP: {
+      if (get_mods()) {
+        SEND_STRING(";;"); // send normal when mods are pressed
+      }
+      else {
+        SEND_STRING(";\n");
+      }
+      break;
+    }
+    case TRIPLE_TAP: {
+      SEND_STRING(";\n\n");
+    }
+    case SPECIAL: layer_invert(_NUM); break;
+    case SINGLE_HOLD: layer_off(_NUM); break;
+  }
+  tap_state.semicolon = 0;
+}
+
+// Send `. ~. ```
+void tap_dance_grave_finished(qk_tap_dance_state_t *state, void *user_data) {
   switch(state->count) {
     case 1:
-      register_code(KC_SCLN);
-      unregister_code(KC_SCLN);
+      SEND_STRING("`");
       break;
     case 2:
-      register_code(KC_SCLN);
-      unregister_code(KC_SCLN);
+      SEND_STRING("~");
+      break;
+  }
+}
 
-      uint8_t mods = get_mods();
-      if (mods) {
-        clear_mods();
-      }
+void tap_dance_grave_each(qk_tap_dance_state_t *state, void *user_data) {
+  if(state->count == 3) {
+    SEND_STRING("```");
+  } else if (state->count > 3) {
+    SEND_STRING("`");
+  }
+}
 
-      register_code(KC_ENT);
-      unregister_code(KC_ENT);
 
-      if (mods) {
-        set_mods(mods);
-      }
+void tap_dance_quote_finished(qk_tap_dance_state_t *state, void *user_data) {
+  tap_state.quote = hold_cur_dance(state);
+  switch (tap_state.quote) {
+    case SINGLE_TAP: case DOUBLE_HOLD: register_code(KC_QUOT); break;
+    case SINGLE_HOLD: layer_on(_NAV); break;
+  }
+}
 
-      reset_tap_dance(state);
-      break;
+void tap_dance_quote_reset(qk_tap_dance_state_t *state, void *user_data) {
+  switch (tap_state.quote) {
+    case SINGLE_TAP: case DOUBLE_HOLD: unregister_code(KC_QUOTE); break;
+    case DOUBLE_TAP: SEND_STRING("\""); break;
+    case TRIPLE_TAP: layer_invert(_NAV); break;
+    case SINGLE_HOLD: layer_off(_NAV); break;
   }
+  tap_state.quote = 0;
 }
 
 qk_tap_dance_action_t tap_dance_actions[] = {
-  [TD_SEMICOLON]  = ACTION_TAP_DANCE_FN(tap_dance_semicolon),
+  [TD_SEMICOLON] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, tap_dance_semicolon_finished, tap_dance_semicolon_reset),
+  [TD_GRAVE]     = ACTION_TAP_DANCE_FN_ADVANCED(tap_dance_grave_each, tap_dance_grave_finished, NULL),
+  [TD_QUOTE]     = ACTION_TAP_DANCE_FN_ADVANCED(NULL, tap_dance_quote_finished, tap_dance_quote_reset),
 };