[Keymap] Add haervig userspace and keymaps (#13362)

master
Jakob Hærvig 2021-07-01 19:12:19 +02:00 committed by GitHub
parent c275828ac2
commit bef73f44aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 605 additions and 0 deletions

View File

@ -0,0 +1,36 @@
/*
Copyright 2021 Jakob Hærvig <jakob.haervig@gmail.com>
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
#include "haervig.h"
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT_65_ansi(
KC_GESC, DK_1, CU_2, DK_3, CU_4, DK_5, CU_6, CU_7, CU_8, CU_9, CU_0, CU_MINS, CU_EQL, CU_BSPC, KC_HOME,
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, CU_LBRC, CU_RBRC, CU_BSLS, KC_PGUP,
CTL_T(KC_CAPS), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, CU_SCLN, CU_QUOT, KC_ENT, KC_PGDN,
CU_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, CU_COMM, CU_DOT, CU_SLSH, CU_RSFT, KC_UP, KC_END,
KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, MO(1), KC_RALT, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
),
[1] = LAYOUT_65_ansi(
_______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______
)
};

View File

@ -0,0 +1,3 @@
# Userspace defines
DANISH_ENABLE = yes # Enable Custom US Ansi Keycodes for PC with Danish set as input language
RGB_MATRIX_ENABLE = no # Disable the ugly RGB light

19
users/haervig/config.h Normal file
View File

@ -0,0 +1,19 @@
/*
Copyright 2021 Jakob Hærvig <jakob.haervig@gmail.com>
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
#define TAPPING_TERM 200

234
users/haervig/haervig.c Normal file
View File

@ -0,0 +1,234 @@
/*
Copyright 2021 Jakob Hærvig <jakob.haervig@gmail.com>
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 "haervig.h"
#ifdef DANISH_ENABLE
// These indicate if left and right shift are physically pressed
bool lshift = false;
bool rshift = false;
// Interrupt and times for space cadet shift
bool lshiftp = false;
bool rshiftp = false;
uint16_t lshift_timer = 0;
uint16_t rshift_timer = 0;
// Number of items that are saved in prev_kcs
uint8_t prev_indx = 0;
// Used to save the last 6 actual keycodes activated by frankenkeycodes
uint16_t prev_kcs[6] = {0, 0, 0, 0, 0, 0};
// If true the deadkey characters grave and circonflexe are not automatically escaped
bool esct = false;
/*
Used to add a keycode to a prev_kcs to remember it.
When full the last code gets discarded and replaced by
the new one.
*/
void add_to_prev(uint16_t kc){
for (int i=0; i<prev_indx; i++){
if (kc == prev_kcs[i])
return;
}
if (prev_indx == 6){
for (int i=5; i>0; i--){
prev_kcs[i] = prev_kcs[i-1];
}
prev_kcs[0] = kc;
} else {
prev_kcs[prev_indx] = kc;
prev_indx++;
}
}
/*
Unregisters all codes saved in prev_kcs and resets prev_indx.
gets called on multiple occasions mainly when shift is released
and when frankenkeycodes are pressed. Prevents output of
wrong characters when really specific key combinations
that would never occur during normal usage are pressed.
*/
void unreg_prev(void){
if (prev_indx == 0)
return;
for (int i=0; i<prev_indx; i++){
unregister_code(prev_kcs[i]);
}
prev_indx = 0;
}
#endif
// Interrupt and times for Nav/Esc
bool navesc = false;
uint16_t navesc_timer = 0;
// Interrupts all timers
void timer_timeout(void){
#ifdef DANISH_ENABLE
lshiftp = false;
rshiftp = false;
#endif
navesc = false;
timer_timeout_keymap();
}
__attribute__((weak))
void timer_timeout_keymap(void){
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case KC_LGUI:
case KC_RGUI:
if (record->event.pressed)
timer_timeout();
return true;
case CU_NAV:
if(record->event.pressed) {
navesc = true;
navesc_timer = timer_read();
layer_on(_NAV);
} else {
if (timer_elapsed(navesc_timer) < TAPPING_TERM && navesc) {
tap_code(KC_ESC);
}
layer_off(_NAV);
}
return false;
#ifdef DANISH_ENABLE
case CU_LSFT:
if(record->event.pressed) {
lshiftp = true;
lshift_timer = timer_read();
unregister_code(KC_LSFT);
register_code(KC_LSFT);
lshift = true;
} else {
if (timer_elapsed(lshift_timer) < TAPPING_TERM && lshiftp) {
register_code(KC_LSFT);
tap_code(KC_8);
unregister_code(KC_LSFT);
}
unreg_prev();
if (!rshift)
unregister_code(KC_LSFT);
lshift = false;
}
return false;
case CU_RSFT:
if(record->event.pressed) {
rshiftp = true;
rshift_timer = timer_read();
unregister_code(KC_LSFT);
register_code(KC_LSFT);
rshift = true;
} else {
if (timer_elapsed(rshift_timer) < TAPPING_TERM && rshiftp) {
register_code(KC_LSFT);
tap_code(KC_9);
unregister_code(KC_LSFT);
}
unreg_prev();
if (!lshift)
unregister_code(KC_LSFT);
rshift = false;
}
return false;
case CU_COMM:
SHIFT_NO(DK_COMM, KC_GRV)
case CU_DOT:
SHIFT_NORM(DK_DOT, KC_GRV)
case CU_SLSH:
SHIFT_ALL(DK_7, KC_MINS)
case CU_SCLN:
SHIFT_ALL(DK_COMM, DK_DOT)
case CU_QUOT:
SHIFT_NORM(DK_QUOT, DK_2)
case CU_2:
NORM_ALGR(DK_2, KC_NUHS)
case CU_4:
if (record->event.pressed) { \
timer_timeout(); \
if (lshift || rshift) { \
register_code(KC_LSFT); \
register_code(KC_ALGR); \
unregister_code(KC_3); \
tap_code(KC_3); \
unregister_code(KC_3); \
} else { \
unregister_code(KC_4); \
tap_code(KC_4); \
} \
unregister_code(KC_ALGR); \
unregister_code(KC_LSFT); \
} \
return false;
case CU_6:
SHIFT_NORM(DK_6, KC_RBRC)
case CU_7:
SHIFT_NORM(DK_7, DK_6)
case CU_8:
SHIFT_NORM(DK_8, KC_NUHS)
case CU_9:
SHIFT_NORM(DK_9, DK_8)
case CU_0:
SHIFT_NORM(DK_0, DK_9)
case CU_MINS:
SHIFT_NORM(KC_SLSH, KC_SLSH)
case CU_EQL:
SHIFT_SWITCH(DK_0, DK_PLUS)
case CU_BSPC:
SHIFT_NO(KC_BSPC, KC_DEL)
case CU_LBRC:
NORM_ALGRSHIFT(DK_8, DK_8)
case CU_RBRC:
NORM_ALGRSHIFT(DK_9, DK_9)
case CU_BSLS:
ALGR_SWITCH(DK_7, DK_I)
case KC_LCTL:
case KC_RCTL:
if(!record->event.pressed) {
timer_timeout();
unregister_code(KC_Z);
unregister_code(KC_Y);
}
return true;
#endif
default:
if(record->event.pressed) {
timer_timeout();
#ifdef DANISH_ENABLE
if (lshift || rshift)
register_code(KC_LSFT);
else
unregister_code(KC_LSFT);
#endif
}
return process_record_keymap(keycode, record);
}
}
__attribute__((weak))
bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
return true;
}

297
users/haervig/haervig.h Normal file
View File

@ -0,0 +1,297 @@
/*
Copyright 2021 Jakob Hærvig <jakob.haervig@gmail.com>
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 "quantum.h"
#include "keymap_danish.h"
enum userspace_layers {
_DEADKEY = 14, // Change if more than 16 layers are required
_NAV
};
enum userspace_custom_keycodes {
//CU_GAME = SAFE_RANGE, // Toggle game mode on/off
CU_NAV = SAFE_RANGE, // NAV | ESC
#ifdef DANISH_ENABLE
CU_LSFT, // LSFT | (
CU_RSFT, // LSFT | )
CU_COMM, // , | <
CU_DOT, // . | >
CU_SLSH, // / | ?
CU_SCLN, // ; | :
CU_QUOT, // ' | "
CU_2, // 2 | @
CU_4, // 4 | $
CU_6, // 6 | ^
CU_7, // 7 | &
CU_8, // 8 | *
CU_9, // 9 | (
CU_0, // 0 | )
CU_MINS, // - | _
CU_EQL, // = | +
CU_BSPC, // backspace | delete
CU_LBRC, // [ | {
CU_RBRC, // ] | }
CU_BSLS, // \ | |
#endif
NEW_SAFE_RANGE // Use for keymap specific keycodes
};
#ifdef DANISH_ENABLE
extern bool lshift;
extern bool rshift;
extern bool lshiftp;
extern bool rshiftp;
extern uint16_t lshift_timer;
extern uint16_t rshift_timer;
extern uint8_t prev_indx;
extern uint16_t prev_kcs[6];
void add_to_prev(uint16_t kc);
void unreg_prev(void);
extern bool esct;
#endif
extern bool navesc;
extern uint16_t navesc_timer;
void timer_timeout(void);
void timer_timeout_keymap(void);
bool process_record_keymap(uint16_t keycode, keyrecord_t *record);
#define CTRLX LCTL(KC_X)
#define CTRLC LCTL(KC_C)
#define CTRLV LCTL(KC_V)
#define ALTF4 LALT(KC_F4)
#define GUIU LGUI(KC_UP)
#define GUID LGUI(KC_DOWN)
#define GUIL LGUI(KC_LEFT)
#define GUIR RGUI(KC_RIGHT)
#define CTLENT CTL_T(KC_ENT)
#define EMOJI LWIN(KC_DOT)
/*
Templates for Keys, with custom shifted and non shifted Characters
*/
// Normal shift status
#define SHIFT_NORM(kc1, kc2) \
if (record->event.pressed) { \
timer_timeout(); \
if (lshift || rshift) { \
register_code(KC_LSFT); \
unregister_code(kc2); \
register_code(kc2); \
add_to_prev(kc2); \
} else { \
unregister_code(KC_LSFT); \
unregister_code(kc1); \
register_code(kc1); \
} \
} else { \
unregister_code(kc1); \
unregister_code(kc2); \
} \
return false;
// Inverted shift status
#define SHIFT_SWITCH(kc1, kc2) \
if (record->event.pressed) { \
timer_timeout(); \
if (lshift || rshift) { \
unregister_code(KC_LSFT); \
unregister_code(kc2); \
register_code(kc2); \
add_to_prev(kc2); \
} else { \
register_code(KC_LSFT); \
unregister_code(kc1); \
register_code(kc1); \
add_to_prev(kc1); \
} \
} else { \
unregister_code(kc1); \
unregister_code(kc2); \
unreg_prev(); \
if (lshift || rshift) \
register_code(KC_LSFT); \
else \
unregister_code(KC_LSFT); \
} \
return false;
// Always shifted
#define SHIFT_ALL(kc1, kc2) \
if (record->event.pressed) { \
timer_timeout(); \
register_code(KC_LSFT); \
if (lshift || rshift) { \
tap_code(kc2); \
add_to_prev(kc2); \
} else { \
tap_code(kc1); \
add_to_prev(kc1); \
} \
} else { \
unregister_code(kc1); \
unregister_code(kc2); \
unreg_prev(); \
if (lshift || rshift) \
register_code(KC_LSFT); \
else \
unregister_code(KC_LSFT); \
} \
return false;
// Never shifted
#define SHIFT_NO(kc1, kc2) \
if (record->event.pressed) { \
timer_timeout(); \
unregister_code(KC_LSFT); \
if (lshift || rshift) { \
tap_code(kc2); \
add_to_prev(kc2); \
} else { \
tap_code(kc1); \
} \
} else { \
unregister_code(kc1); \
unregister_code(kc2); \
unreg_prev(); \
if (lshift || rshift) \
register_code(KC_LSFT); \
else \
unregister_code(KC_LSFT); \
} \
return false;
// Norm AltGr
#define NORM_ALGR(kc1, kc2) \
if (record->event.pressed) { \
timer_timeout(); \
if (lshift || rshift) { \
register_code(KC_ALGR); \
unregister_code(KC_LSFT); \
tap_code(kc2); \
unregister_code(KC_ALGR); \
} else { \
unregister_code(KC_ALGR); \
unregister_code(KC_LSFT); \
tap_code(kc1); \
} \
} else { \
unregister_code(kc1); \
unregister_code(kc2); \
} \
return false;
// Norm AltGr shift
#define NORM_ALGRSHIFT(kc1, kc2) \
if (record->event.pressed) { \
timer_timeout(); \
register_code(KC_LSFT); \
register_code(KC_ALGR); \
if (lshift || rshift) { \
unregister_code(kc2); \
tap_code(kc2); \
unregister_code(KC_LSFT); \
} else { \
unregister_code(KC_LSFT); \
unregister_code(kc1); \
register_code(kc1); \
} \
unregister_code(KC_ALGR); \
} else { \
unregister_code(kc1); \
unregister_code(kc2); \
} \
return false;
// Inverted altgr status
#define ALGR_SWITCH(kc1, kc2) \
if (record->event.pressed) { \
timer_timeout(); \
register_code(KC_ALGR); \
if (lshift || rshift) { \
unregister_code(KC_LSFT); \
unregister_code(kc2); \
register_code(kc2); \
unregister_code(KC_ALGR); \
add_to_prev(kc2); \
} else { \
register_code(KC_LSFT); \
unregister_code(kc1); \
register_code(kc1); \
unregister_code(KC_ALGR); \
add_to_prev(kc1); \
} \
} else { \
unregister_code(kc1); \
unregister_code(kc2); \
unreg_prev(); \
if (lshift || rshift) \
register_code(KC_LSFT); \
else \
unregister_code(KC_LSFT); \
} \
return false;
// Always AltGr
#define SHIFT_ALGR(kc1, kc2) \
if (record->event.pressed) { \
timer_timeout(); \
unregister_code(KC_LSFT); \
register_code(KC_ALGR); \
if (lshift || rshift) { \
unregister_code(kc2); \
tap_code(kc2); \
register_code(KC_LSFT); \
} else { \
unregister_code(kc1); \
tap_code(kc1); \
} \
unregister_code(KC_ALGR); \
} \
return false;
// Different keycode when Ctrl is pressed
#define CTRL(kc1, kc2) \
if(record->event.pressed) { \
timer_timeout(); \
if (lshift || rshift) \
register_code(KC_LSFT); \
else \
unregister_code(KC_LSFT); \
if (keyboard_report->mods & (MOD_BIT(KC_LCTL) | MOD_BIT(KC_RCTL))){ \
register_code(kc2); \
} else { \
register_code(kc1); \
} \
} else { \
unregister_code(kc1); \
unregister_code(kc2); \
} \
return false;

11
users/haervig/readme.md Normal file
View File

@ -0,0 +1,11 @@
# haervig Userspace
This userspace keeps my userdefined codes. I work on a ANSI keyboard on a Danish macOS system. I believe this code might be relevant for similar users. A big shout out to user spacebarracecar for the ideas on how to map keys, which served as the basis of this code.
## US Layout Keys for Danish PCs
By daily work involves a lot of coding. I find an ANSI layout superior and decided to buy a QMK keyboard. However, all PC's here in Denmark are set to input language Danish. Even though I could simply set input language language to US international, I find this inconvenient. I instead decided to map my keys so the ANSI keyboard would will function as expected when the OS inputn language is Danish.
## More details
Tracking the current state of the shift code is nessesary for it to work. User spacebarracecar has documented the idea thoroughly and should serve you as a starting point if you wish to implement this code. I modified the code to suit Danish input language. Additionally, a couple of functions were added to accomodate the altgr key.

5
users/haervig/rules.mk Normal file
View File

@ -0,0 +1,5 @@
SRC += haervig.c
ifeq ($(strip $(DANISH_ENABLE)), yes)
OPT_DEFS += -DDANISH_ENABLE
endif