~ruther/qmk_firmware

8ec22695199e9f3ae52e83d945763ba892f5bcd9 — Harry Mills 7 years ago 5226e4c
Add magic backspace to my layout (#2758)

* Add Haegin's keymap

* Potential improvements to the keyboard

* Add haegin minidox layout

* Add Haegin's keyboard to ergodox layouts

* Update Haegin's minidox keymap

* Add home, end, and page up and down

* Magic Backspace

Backspace still acts as control when you hold it down, but if you tap it
twice and hold it's a held backspace. Tapping it more than twice it
continues to act as backspace, but it deletes more characters with each
tap with the quantity deleted based on the fibonacci sequence.

* Switch to deleting words after 4 taps

When hitting backspace, after 4 taps this switches to deleting by word
because if you're hitting backspace that frantically you must need to
delete a lot of stuff. Holding backspace after 4 taps will delete words
in the same way that holding alt+backspace deletes words on a normal
keyboard.
2 files changed, 85 insertions(+), 6 deletions(-)

M layouts/community/ergodox/haegin/keymap.c
A layouts/community/ergodox/haegin/rules.mk
M layouts/community/ergodox/haegin/keymap.c => layouts/community/ergodox/haegin/keymap.c +84 -6
@@ 11,6 11,10 @@

#define _______ KC_TRNS

enum {
  TD_BSPC = 0
};

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {

/* Keymap 0: Basic layer


@@ 46,7 50,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
        LT(SYMBOLS,KC_GRV),  KC_QUOT,            KC_SLSH,         KC_LALT,  SFT_T(KC_RGHT),
                                                                                             KC_HOME,            KC_END,
                                                                                                                 KC_PGUP,
                                                                            GUI_T(KC_SPC),   CTL_T(KC_BSPC),     LGUI(KC_SPC),
                                                                            GUI_T(KC_SPC),   TD(TD_BSPC),     LGUI(KC_SPC),

        // Right hand
        KC_RGHT,        KC_6,              KC_7,                KC_8,        KC_9,        KC_0,                LGUI(KC_SPC),


@@ 136,17 140,91 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
                                                    _______,
                                  _______, _______, _______,
    // right hand
       _______,  _______, _______, _______, _______, _______, _______,
       _______,  _______, _______,   KC_UP, _______, _______, _______,
                 KC_VOLU, KC_LEFT, KC_DOWN, KC_RGHT, _______, KC_MPLY,
       _______,  KC_VOLD, KC_MPRV, KC_MPLY, KC_MFFD, _______, _______,
                          KC_MUTE, _______, _______, _______, _______,
       _______, _______, _______, _______, _______, _______, _______,
       _______, _______, KC_HOME,   KC_UP,  KC_END, KC_PGUP, _______,
                KC_VOLU, KC_LEFT, KC_DOWN, KC_RGHT, KC_PGDN, KC_MPLY,
       KC_MUTE, KC_VOLD, KC_MPRV, KC_MPLY, KC_MFFD, _______, _______,
                          _______, _______, _______, _______, _______,
       _______, _______,
       _______,
       _______, _______,  KC_WBAK
),
};

enum {
  BSPC_LETTER = 0,
  BSPC_WORD = 1,
  HOLD_CTRL = 2
};

typedef struct {
  int a;
  int b;
  int state;
} fib_tap;

static fib_tap fib_bspc = {
  .a = 0,
  .b = 1,
  .state = BSPC_LETTER
};

void cur_backspace (qk_tap_dance_state_t *state) {
  int next_fib = fib_bspc.a + fib_bspc.b;
  fib_bspc.a = fib_bspc.b;
  fib_bspc.b = next_fib;
  for (int i=0; i < next_fib; i++) {
    unregister_code(KC_BSPC);
    register_code(KC_BSPC);
  }
}

void dance_backspace (qk_tap_dance_state_t *state, void *user_data) {
  // If we're at the fifth tap, switch to deleting by words, and reset the fib
  // counter
  if (state->count == 4) {
    register_code(KC_LALT);
    fib_bspc.state = BSPC_WORD;
    fib_bspc.a = 0;
    fib_bspc.b = 1;
  }
  // If we're on the first press, wait to find out if it's being held
  // If we're on the second tap, process the first tap, because we're past
  // holding for ctrl now, then act normally
  if (state->count == 2) {
    register_code(KC_BSPC);
  }
  if (state->count > 1) {
    cur_backspace(state);
  }
};

void dance_backspace_ended (qk_tap_dance_state_t *state, void *user_data) {
  if (state->count == 1) {
    if (state->pressed) {
      fib_bspc.state = HOLD_CTRL;
      register_code(KC_LCTRL);
    } else {
      register_code(KC_BSPC);
    }
  }
};

void dance_backspace_reset (qk_tap_dance_state_t *state, void *user_data) {
  switch (fib_bspc.state) {
    case HOLD_CTRL: unregister_code(KC_LCTRL); break;
    case BSPC_WORD: unregister_code(KC_BSPC); unregister_code(KC_LALT); break;
    case BSPC_LETTER: unregister_code(KC_BSPC); break;
  }
  fib_bspc.a = 0;
  fib_bspc.b = 1;
  fib_bspc.state = BSPC_LETTER;
};

qk_tap_dance_action_t tap_dance_actions[] = {
  [TD_BSPC] = ACTION_TAP_DANCE_FN_ADVANCED (dance_backspace, dance_backspace_ended, dance_backspace_reset)
};

const uint16_t PROGMEM fn_actions[] = {
    [1] = ACTION_LAYER_TAP_TOGGLE(SYMBOLS)                // FN1 - Momentary Layer 1 (Symbols)
};

A layouts/community/ergodox/haegin/rules.mk => layouts/community/ergodox/haegin/rules.mk +1 -0
@@ 0,0 1,1 @@
TAP_DANCE_ENABLE=yes