add tap dance
This commit is contained in:
		
							parent
							
								
									5e5a529a37
								
							
						
					
					
						commit
						9d969f7eed
					
				
					 6 changed files with 509 additions and 50 deletions
				
			
		| 
						 | 
				
			
			@ -6,15 +6,17 @@
 | 
			
		|||
      "Bash(qmk compile:*)",
 | 
			
		||||
      "Bash(make:*)",
 | 
			
		||||
      "Bash(where:*)",
 | 
			
		||||
      "Read(C:\\Users\\pablo\\qmk_firmware/**)",
 | 
			
		||||
      "Read(C:\\Users\\pablo\\qmk_firmware\\keyboards\\crkbd/**)",
 | 
			
		||||
      "Read(C:\\Users\\pablo\\qmk_firmware\\keyboards\\crkbd\\rev1/**)",
 | 
			
		||||
      "Read(*)",
 | 
			
		||||
      "WebFetch(domain:github.com)",
 | 
			
		||||
      "WebFetch(domain:raw.githubusercontent.com)",
 | 
			
		||||
      "Bash(curl:*)",
 | 
			
		||||
      "WebSearch"
 | 
			
		||||
      "WebSearch",
 | 
			
		||||
      "WebFetch(domain:docs.qmk.fm)"
 | 
			
		||||
    ],
 | 
			
		||||
    "deny": [],
 | 
			
		||||
    "ask": []
 | 
			
		||||
    "ask": [],
 | 
			
		||||
    "additionalDirectories": [
 | 
			
		||||
      "C:\\Users\\pablo\\qmk_firmware"
 | 
			
		||||
    ]
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								CLAUDE.md
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								CLAUDE.md
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -9,6 +9,7 @@ This is a QMK userspace repository for custom keyboard keymaps. It contains conf
 | 
			
		|||
## Build Commands
 | 
			
		||||
 | 
			
		||||
### Basic compilation
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
# Compile a specific keymap
 | 
			
		||||
qmk compile -kb your_keyboard -km your_keymap
 | 
			
		||||
| 
						 | 
				
			
			@ -21,6 +22,7 @@ qmk userspace-compile
 | 
			
		|||
```
 | 
			
		||||
 | 
			
		||||
### Configuration commands
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
# Add a keymap to build targets
 | 
			
		||||
qmk userspace-add -kb <keyboard> -km <keymap>
 | 
			
		||||
| 
						 | 
				
			
			@ -36,12 +38,15 @@ qmk config user.overlay_dir="$(realpath .)"
 | 
			
		|||
```
 | 
			
		||||
 | 
			
		||||
### Current Build Targets
 | 
			
		||||
 | 
			
		||||
Based on `qmk.json`, the currently configured build target is:
 | 
			
		||||
 | 
			
		||||
- `crkbd/rev1:pones`
 | 
			
		||||
 | 
			
		||||
## Repository Structure
 | 
			
		||||
 | 
			
		||||
### Keyboard Configurations
 | 
			
		||||
 | 
			
		||||
- `keyboards/crkbd/rev1/keymaps/` - Corne keyboard keymaps
 | 
			
		||||
  - `pones/` - Main active keymap with home row mods, layers for symbols/numbers/navigation
 | 
			
		||||
  - `pones-old/` - Previous version keymap
 | 
			
		||||
| 
						 | 
				
			
			@ -51,6 +56,7 @@ Based on `qmk.json`, the currently configured build target is:
 | 
			
		|||
  - `pones_old/` - Previous version
 | 
			
		||||
 | 
			
		||||
### Key Files
 | 
			
		||||
 | 
			
		||||
- `qmk.json` - Userspace configuration and build targets
 | 
			
		||||
- `Makefile` - Forwards make commands to QMK firmware with proper userspace path
 | 
			
		||||
- `*.hex` - Compiled firmware files ready for flashing
 | 
			
		||||
| 
						 | 
				
			
			@ -60,6 +66,7 @@ Based on `qmk.json`, the currently configured build target is:
 | 
			
		|||
The main keymap (`keyboards/crkbd/rev1/keymaps/pones/`) uses a sophisticated layer system:
 | 
			
		||||
 | 
			
		||||
### Layers
 | 
			
		||||
 | 
			
		||||
- `_QWERTY` - Base QWERTY layout with home row modifiers
 | 
			
		||||
- `_NUMBER` - Number pad and arithmetic operators  
 | 
			
		||||
- `_SYMBOL` - Symbol keys and brackets
 | 
			
		||||
| 
						 | 
				
			
			@ -71,12 +78,16 @@ The main keymap (`keyboards/crkbd/rev1/keymaps/pones/`) uses a sophisticated lay
 | 
			
		|||
- `_UTIL` - RGB lighting controls
 | 
			
		||||
 | 
			
		||||
### Home Row Modifiers
 | 
			
		||||
 | 
			
		||||
The keymap implements home row mods for efficient modifier access:
 | 
			
		||||
 | 
			
		||||
- Left hand: GUI(A), Alt(S), Ctrl(D), Shift(F)
 | 
			
		||||
- Right hand: Shift(J), Ctrl(K), Alt(L), GUI(;)
 | 
			
		||||
 | 
			
		||||
### Layer Access
 | 
			
		||||
 | 
			
		||||
Layers are accessed via layer-tap keys on thumbs and specific positions:
 | 
			
		||||
 | 
			
		||||
- Space → Numbers layer
 | 
			
		||||
- Tab → Symbols layer  
 | 
			
		||||
- Escape → Symbols2 layer
 | 
			
		||||
| 
						 | 
				
			
			@ -87,6 +98,7 @@ Layers are accessed via layer-tap keys on thumbs and specific positions:
 | 
			
		|||
- Quote → Utilities layer
 | 
			
		||||
 | 
			
		||||
### Custom Features
 | 
			
		||||
 | 
			
		||||
- OLED display support with layer and modifier status
 | 
			
		||||
- RGB Matrix with selective animations enabled
 | 
			
		||||
- Custom macros for development workflows (VS Code shortcuts)
 | 
			
		||||
| 
						 | 
				
			
			@ -99,4 +111,5 @@ Layers are accessed via layer-tap keys on thumbs and specific positions:
 | 
			
		|||
- Uses split keyboard features extensively (OLED, RGB, etc.)
 | 
			
		||||
- Master hand is configured as left side
 | 
			
		||||
- Custom font included for OLED display
 | 
			
		||||
- RGB animations are selectively enabled to save firmware space
 | 
			
		||||
- RGB animations are selectively enabled to save firmware space
 | 
			
		||||
- Never compile
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,23 +57,48 @@ uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) {
 | 
			
		|||
- Respuesta más rápida en dedos fuertes
 | 
			
		||||
- Typing más natural y menos errores
 | 
			
		||||
 | 
			
		||||
### 2.2 Reorganización de Símbolos por Frecuencia
 | 
			
		||||
### 2.2 Implementación de Tap Dance para Símbolos
 | 
			
		||||
 | 
			
		||||
**Análisis actual**: 
 | 
			
		||||
- Paréntesis `()` en posiciones incómodas (anular derecho)
 | 
			
		||||
- Llaves `{}` en row inferior (menos accesible)
 | 
			
		||||
- Operadores `=+-` separados geográficamente
 | 
			
		||||
**Objetivo**: Consolidar 16+ símbolos frecuentes en 8 tap dances para máxima eficiencia
 | 
			
		||||
 | 
			
		||||
**Optimización propuesta**:
 | 
			
		||||
**Análisis de frecuencia personal**:
 | 
			
		||||
- `.` (1,054,817) - `,` (443,890) - `/` (543,499) - `-` (383,003)
 | 
			
		||||
- `()` (735,492 total) - `=` (342,151) - `{}` (462,028 total) - `<>` (267,609 total)
 | 
			
		||||
 | 
			
		||||
**SYMBOL_NEW layer (implementación con tap dance)**:
 | 
			
		||||
```
 | 
			
		||||
SYMBOL layer mejorada:
 | 
			
		||||
Row superior: Símbolos menos frecuentes
 | 
			
		||||
Home row:     () [] {} <> (brackets principales)
 | 
			
		||||
Row inferior: Operadores y símbolos especiales
 | 
			
		||||
Thumbs:       = - + (acceso inmediato)
 | 
			
		||||
Mano derecha optimizada:
 | 
			
		||||
┌─────┬─────┬─────┬─────┬─────┬─────┐
 | 
			
		||||
│  `  │TD_AM│  *  │TD_SL│  ^  │     │  Row superior
 | 
			
		||||
├─────┼─────┼─────┼─────┼─────┼─────┤
 | 
			
		||||
│TD_EQ│TD_J │TD_K │TD_SC│TD_L │     │  Home row (5 TDs)
 | 
			
		||||
├─────┼─────┼─────┼─────┼─────┼─────┤
 | 
			
		||||
│  ~  │TD_MN│  :  │TD_EX│  %  │     │  Row inferior
 | 
			
		||||
└─────┴─────┴─────┴─────┴─────┴─────┘
 | 
			
		||||
        Thumbs: @ # $
 | 
			
		||||
 | 
			
		||||
8 Tap Dances:
 | 
			
		||||
- TD_J:  { | {} | }
 | 
			
		||||
- TD_K:  ( | () | ("") | () => {} | )
 | 
			
		||||
- TD_SC: < | <> | <= | >
 | 
			
		||||
- TD_L:  [ | [] | [0] | ]
 | 
			
		||||
- TD_EQ: = | == | += | +
 | 
			
		||||
- TD_SL: / | // | \
 | 
			
		||||
- TD_MN: - | -- | => | _
 | 
			
		||||
- TD_AM: & | && | || | |
 | 
			
		||||
- TD_EX: ! | != | ?
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
**Impacto**: Reducción 30% en movimiento lateral para programación
 | 
			
		||||
**Estrategia de implementación**:
 | 
			
		||||
- **L_TAB → SYMBOL_NEW** (nueva capa optimizada)
 | 
			
		||||
- **L_ESC → SYMBOL** (mantener como backup temporal)
 | 
			
		||||
- Período de evaluación: 2-3 semanas
 | 
			
		||||
- Una vez validado → eliminar SYMBOL antigua
 | 
			
		||||
 | 
			
		||||
**Impacto**: 
 | 
			
		||||
- 16 símbolos consolidados en 8 teclas
 | 
			
		||||
- Reducción 50% en cambios de layer
 | 
			
		||||
- Patrones de código comunes en 2-4 taps
 | 
			
		||||
 | 
			
		||||
### 2.3 Optimización de Navegación
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -91,20 +116,33 @@ Thumbs:       = - + (acceso inmediato)
 | 
			
		|||
 | 
			
		||||
## 🟡 Fase 3 - Impacto Alto (2-3 semanas adaptación)
 | 
			
		||||
 | 
			
		||||
### 3.1 Fusión de Capas SYMBOL
 | 
			
		||||
### 3.1 Transición Gradual y Eliminación de Capas
 | 
			
		||||
 | 
			
		||||
**Problema actual**: SYMBOL y SYMBOL2 fragmentan símbolos relacionados
 | 
			
		||||
**Problema resuelto**: SYMBOL y SYMBOL2 fragmentaban símbolos relacionados
 | 
			
		||||
 | 
			
		||||
**Nueva organización**:
 | 
			
		||||
```
 | 
			
		||||
Unified SYMBOL layer:
 | 
			
		||||
- Brackets y parentheses agrupados
 | 
			
		||||
- Operadores matemáticos juntos  
 | 
			
		||||
- Símbolos de programación ($, @, #, %, etc.) organizados por frecuencia
 | 
			
		||||
- Eliminación de redundancias
 | 
			
		||||
```
 | 
			
		||||
**Implementación por fases**:
 | 
			
		||||
 | 
			
		||||
**Beneficio**: Una capa menos que memorizar, símbolos más lógicamente agrupados
 | 
			
		||||
**Fase A - Transición (2-3 semanas)**:
 | 
			
		||||
- L_TAB → SYMBOL_NEW (tap dances optimizados)
 | 
			
		||||
- L_ESC → SYMBOL (backup de seguridad)
 | 
			
		||||
- Entrenamiento gradual en tap dances
 | 
			
		||||
- Fallback a SYMBOL cuando sea necesario
 | 
			
		||||
 | 
			
		||||
**Fase B - Consolidación (evaluación)**:
 | 
			
		||||
- Medir eficiencia y comfort con SYMBOL_NEW
 | 
			
		||||
- Identificar patrones problemáticos
 | 
			
		||||
- Ajustar timings y configuraciones si necesario
 | 
			
		||||
 | 
			
		||||
**Fase C - Finalización**:
 | 
			
		||||
- Eliminar SYMBOL y SYMBOL2 completamente
 | 
			
		||||
- Liberar L_ESC para otros usos (UTIL, macros, etc.)
 | 
			
		||||
- Una sola capa de símbolos ultra-optimizada
 | 
			
		||||
 | 
			
		||||
**Beneficios finales**:
 | 
			
		||||
- 2 capas eliminadas (SYMBOL + SYMBOL2)
 | 
			
		||||
- 1 tecla de thumb liberada (L_ESC)
 | 
			
		||||
- Símbolos más eficientes por tap dance
 | 
			
		||||
- Patrones de programación integrados
 | 
			
		||||
 | 
			
		||||
### 3.2 Reasignación de Layer-Tap Problemático
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -173,32 +211,100 @@ Combos propuestos:
 | 
			
		|||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## 🔧 Fase 5 - Optimizaciones Avanzadas
 | 
			
		||||
## 🔧 Configuración Técnica de Tap Dance
 | 
			
		||||
 | 
			
		||||
### 5.1 Análisis de Bigrams Personalizado
 | 
			
		||||
### Configuración QMK necesaria:
 | 
			
		||||
 | 
			
		||||
**Metodología**:
 | 
			
		||||
1. Recopilar datos reales de typing (1-2 semanas)
 | 
			
		||||
2. Analizar patrones específicos de tu código
 | 
			
		||||
3. Identificar same-finger bigrams (SFBs) problemáticos
 | 
			
		||||
4. Reorganizar layout basado en datos personales
 | 
			
		||||
```c
 | 
			
		||||
// En config.h
 | 
			
		||||
#define TAP_DANCE_ENABLE
 | 
			
		||||
#define TAPPING_TERM 200
 | 
			
		||||
#define TAPPING_TERM_PER_KEY
 | 
			
		||||
 | 
			
		||||
### 5.2 Configuración Adaptativa
 | 
			
		||||
// Enum para tap dances
 | 
			
		||||
enum tap_dances {
 | 
			
		||||
    TD_J_BRACES,    // Llaves
 | 
			
		||||
    TD_K_PARENS,    // Paréntesis
 | 
			
		||||
    TD_SC_ANGLES,   // Ángulos
 | 
			
		||||
    TD_L_BRACKETS,  // Corchetes
 | 
			
		||||
    TD_EQ_PLUS,     // Equal/Plus
 | 
			
		||||
    TD_SL_BACK,     // Slash/Backslash
 | 
			
		||||
    TD_MN_UNDER,    // Minus/Underscore
 | 
			
		||||
    TD_AM_PIPE,     // Ampersand/Pipe
 | 
			
		||||
    TD_EX_QUEST,    // Exclamation/Question
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
**Features avanzadas**:
 | 
			
		||||
- Profiles automáticos por contexto
 | 
			
		||||
- Machine learning para optimización continua
 | 
			
		||||
- Integration con IDEs y herramientas
 | 
			
		||||
// Funciones personalizadas para cada tap dance
 | 
			
		||||
void td_k_finished(qk_tap_dance_state_t *state, void *user_data) {
 | 
			
		||||
    switch (state->count) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            if (state->pressed) {
 | 
			
		||||
                register_code16(KC_RPRN);  // Hold = )
 | 
			
		||||
            } else {
 | 
			
		||||
                register_code16(KC_LPRN);  // 1 tap = (
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case 2:
 | 
			
		||||
            SEND_STRING("()");
 | 
			
		||||
            tap_code(KC_LEFT);              // 2 taps = ()←
 | 
			
		||||
            break;
 | 
			
		||||
        case 3:
 | 
			
		||||
            SEND_STRING("(\"\"");
 | 
			
		||||
            tap_code(KC_LEFT);
 | 
			
		||||
            tap_code(KC_LEFT);              // 3 taps = ("")←←
 | 
			
		||||
            break;
 | 
			
		||||
        case 4:
 | 
			
		||||
            SEND_STRING("() => {}");
 | 
			
		||||
            tap_code(KC_LEFT);
 | 
			
		||||
            tap_code(KC_LEFT);
 | 
			
		||||
            tap_code(KC_LEFT);              // 4 taps = () => {}←←←
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Timing optimizado por dedo:
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) {
 | 
			
		||||
    switch (keycode) {
 | 
			
		||||
        case TD_J_BRACES:
 | 
			
		||||
        case TD_K_PARENS:  return 180;  // Índice/medio más rápidos
 | 
			
		||||
        case TD_L_BRACKETS: return 220; // Meñique más lento
 | 
			
		||||
        case TD_SC_ANGLES:  return 200; // Anular estándar
 | 
			
		||||
        default: return TAPPING_TERM;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## 🔧 Fase 5 - Optimizaciones Futuras
 | 
			
		||||
 | 
			
		||||
### 5.1 Análisis Post-Implementación
 | 
			
		||||
 | 
			
		||||
**Métricas a evaluar** (post tap dance):
 | 
			
		||||
- Velocidad de typing en símbolos frecuentes
 | 
			
		||||
- Tasa de error en tap dances vs teclas simples
 | 
			
		||||
- Fatiga subjetiva después de sesiones largas
 | 
			
		||||
- Patrones de uso real de cada tap dance
 | 
			
		||||
 | 
			
		||||
### 5.2 Expansiones Avanzadas
 | 
			
		||||
 | 
			
		||||
**Si tap dance funciona bien**:
 | 
			
		||||
- Combos adicionales para símbolos menos frecuentes
 | 
			
		||||
- Macros contextuales por aplicación
 | 
			
		||||
- Auto-shift para pares de símbolos
 | 
			
		||||
- Integration con snippets de código
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## 📈 Métricas de Éxito
 | 
			
		||||
 | 
			
		||||
### Objetivos Cuantificables
 | 
			
		||||
- **Reducción de SFBs**: 40% menos same-finger bigrams
 | 
			
		||||
- **Velocidad**: +10-15% en typing de código
 | 
			
		||||
- **Fatiga**: 30% menos movimiento lateral de dedos
 | 
			
		||||
- **Ergonomía**: Eliminación de painful stretches
 | 
			
		||||
- **Consolidación**: 16+ símbolos en 8 tap dances
 | 
			
		||||
- **Reducción de capas**: Eliminar SYMBOL y SYMBOL2 (2 capas → 1)
 | 
			
		||||
- **Eficiencia**: Patrones comunes en 2-4 taps (!=, ==, &&, ||, =>, //)
 | 
			
		||||
- **Ergonomía**: Todo en mano derecha, sin stretching con pulgar ocupado
 | 
			
		||||
- **Velocidad**: Símbolos frecuentes en 1 tap sin latencia adicional
 | 
			
		||||
 | 
			
		||||
### Métricas de Seguimiento
 | 
			
		||||
- WPM antes/después de cada fase
 | 
			
		||||
| 
						 | 
				
			
			@ -256,8 +362,9 @@ Mes 4+:      Fases 4-5 para usuarios power
 | 
			
		|||
 | 
			
		||||
- **v1.0**: Análisis inicial y Fase 1 (Enero 2025)  
 | 
			
		||||
- **v1.1**: Corrección HM_L y combos optimizados
 | 
			
		||||
- **v2.0**: (Planificado) Implementación Fase 2
 | 
			
		||||
- **v3.0**: (Planificado) Unificación de capas SYMBOL
 | 
			
		||||
- **v2.0**: (Planificado) Implementación Tap Dance para símbolos
 | 
			
		||||
- **v2.1**: (Planificado) Transición gradual con backup SYMBOL
 | 
			
		||||
- **v3.0**: (Planificado) Eliminación final de capas redundantes
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,7 +15,10 @@
 | 
			
		|||
#   define OLED_TIMEOUT 30000
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define DYNAMIC_KEYMAP_LAYER_COUNT 9
 | 
			
		||||
#define DYNAMIC_KEYMAP_LAYER_COUNT 10
 | 
			
		||||
 | 
			
		||||
// Tap dance configuration
 | 
			
		||||
#define TAPPING_TERM_PER_KEY
 | 
			
		||||
 | 
			
		||||
// Home row mods optimization
 | 
			
		||||
#define PERMISSIVE_HOLD
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,6 +60,7 @@ enum layer_names {
 | 
			
		|||
  _NUMBER,
 | 
			
		||||
  _SYMBOL,
 | 
			
		||||
  _SYMBOL2,
 | 
			
		||||
  _SYMBOL_NEW,
 | 
			
		||||
  _NAV,
 | 
			
		||||
  _FUNC,
 | 
			
		||||
  _DEV,
 | 
			
		||||
| 
						 | 
				
			
			@ -67,9 +68,22 @@ enum layer_names {
 | 
			
		|||
  _MEDIA,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Tap dance definitions
 | 
			
		||||
enum tap_dances {
 | 
			
		||||
    TD_J_BRACES,    // { | {} | }
 | 
			
		||||
    TD_K_PARENS,    // ( | () | ("") | () => {} | )
 | 
			
		||||
    TD_SC_ANGLES,   // < | <> | <= | >
 | 
			
		||||
    TD_L_BRACKETS,  // [ | [] | [0] | ]
 | 
			
		||||
    TD_EQ_PLUS,     // = | == | += | +
 | 
			
		||||
    TD_SL_BACK,     // / | // | backslash
 | 
			
		||||
    TD_MN_UNDER,    // - | -- | => | _
 | 
			
		||||
    TD_AM_PIPE,     // & | && | || | |
 | 
			
		||||
    TD_EX_QUEST,    // ! | != | ?
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define L_SPC LT(_NUMBER, KC_SPACE)
 | 
			
		||||
#define L_TAB LT(_SYMBOL, KC_TAB)
 | 
			
		||||
#define L_ESC LT(_SYMBOL2, KC_ESCAPE)
 | 
			
		||||
#define L_TAB LT(_SYMBOL_NEW, KC_TAB)
 | 
			
		||||
#define L_ESC LT(_SYMBOL, KC_ESCAPE)
 | 
			
		||||
#define L_ENT LT(_DEV, KC_ENTER)
 | 
			
		||||
#define L_DEL LT(_MEDIA, KC_DEL)
 | 
			
		||||
#define L_BK LT(_FUNC, KC_BSPC)
 | 
			
		||||
| 
						 | 
				
			
			@ -103,6 +117,300 @@ enum custom_keycodes {
 | 
			
		|||
  KVM_NEXT, // KVM next port
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Tap dance functions
 | 
			
		||||
void td_j_finished(tap_dance_state_t *state, void *user_data) {
 | 
			
		||||
    switch (state->count) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            if (state->pressed) {
 | 
			
		||||
                register_code16(KC_RCBR);  // Hold = }
 | 
			
		||||
            } else {
 | 
			
		||||
                register_code16(KC_LCBR);  // 1 tap = {
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case 2:
 | 
			
		||||
            SEND_STRING("{}");
 | 
			
		||||
            tap_code(KC_LEFT);              // 2 taps = {}←
 | 
			
		||||
            break;
 | 
			
		||||
        case 3:
 | 
			
		||||
            register_code16(KC_RCBR);       // 3 taps = }
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void td_j_reset(tap_dance_state_t *state, void *user_data) {
 | 
			
		||||
    switch (state->count) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            if (state->pressed) {
 | 
			
		||||
                unregister_code16(KC_RCBR);
 | 
			
		||||
            } else {
 | 
			
		||||
                unregister_code16(KC_LCBR);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case 3:
 | 
			
		||||
            unregister_code16(KC_RCBR);
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void td_k_finished(tap_dance_state_t *state, void *user_data) {
 | 
			
		||||
    switch (state->count) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            if (state->pressed) {
 | 
			
		||||
                register_code16(KC_RPRN);  // Hold = )
 | 
			
		||||
            } else {
 | 
			
		||||
                register_code16(KC_LPRN);  // 1 tap = (
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case 2:
 | 
			
		||||
            SEND_STRING("()");
 | 
			
		||||
            tap_code(KC_LEFT);              // 2 taps = ()←
 | 
			
		||||
            break;
 | 
			
		||||
        case 3:
 | 
			
		||||
            SEND_STRING("(\"\")");
 | 
			
		||||
            tap_code(KC_LEFT);
 | 
			
		||||
            tap_code(KC_LEFT);              // 3 taps = ("")←←
 | 
			
		||||
            break;
 | 
			
		||||
        case 4:
 | 
			
		||||
            SEND_STRING("() => {}");
 | 
			
		||||
            tap_code(KC_LEFT);              // 4 taps = () => {}←
 | 
			
		||||
            break;
 | 
			
		||||
        case 5:
 | 
			
		||||
            register_code16(KC_RPRN);       // 5 taps = )
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void td_k_reset(tap_dance_state_t *state, void *user_data) {
 | 
			
		||||
    switch (state->count) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            if (state->pressed) {
 | 
			
		||||
                unregister_code16(KC_RPRN);
 | 
			
		||||
            } else {
 | 
			
		||||
                unregister_code16(KC_LPRN);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case 5:
 | 
			
		||||
            unregister_code16(KC_RPRN);
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void td_sc_finished(tap_dance_state_t *state, void *user_data) {
 | 
			
		||||
    switch (state->count) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            if (state->pressed) {
 | 
			
		||||
                register_code16(KC_GT);     // Hold = >
 | 
			
		||||
            } else {
 | 
			
		||||
                register_code16(KC_LT);     // 1 tap = <
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case 2:
 | 
			
		||||
            SEND_STRING("<>");
 | 
			
		||||
            tap_code(KC_LEFT);              // 2 taps = <>←
 | 
			
		||||
            break;
 | 
			
		||||
        case 3:
 | 
			
		||||
            SEND_STRING("<=");              // 3 taps = <=
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void td_sc_reset(tap_dance_state_t *state, void *user_data) {
 | 
			
		||||
    switch (state->count) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            if (state->pressed) {
 | 
			
		||||
                unregister_code16(KC_GT);
 | 
			
		||||
            } else {
 | 
			
		||||
                unregister_code16(KC_LT);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void td_l_finished(tap_dance_state_t *state, void *user_data) {
 | 
			
		||||
    switch (state->count) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            if (state->pressed) {
 | 
			
		||||
                register_code16(KC_RBRC);   // Hold = ]
 | 
			
		||||
            } else {
 | 
			
		||||
                register_code16(KC_LBRC);   // 1 tap = [
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case 2:
 | 
			
		||||
            SEND_STRING("[]");
 | 
			
		||||
            tap_code(KC_LEFT);              // 2 taps = []←
 | 
			
		||||
            break;
 | 
			
		||||
        case 3:
 | 
			
		||||
            SEND_STRING("[0]");
 | 
			
		||||
            tap_code(KC_LEFT);              // 3 taps = [0]←
 | 
			
		||||
            break;
 | 
			
		||||
        case 4:
 | 
			
		||||
            register_code16(KC_RBRC);       // 4 taps = ]
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void td_l_reset(tap_dance_state_t *state, void *user_data) {
 | 
			
		||||
    switch (state->count) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            if (state->pressed) {
 | 
			
		||||
                unregister_code16(KC_RBRC);
 | 
			
		||||
            } else {
 | 
			
		||||
                unregister_code16(KC_LBRC);
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case 4:
 | 
			
		||||
            unregister_code16(KC_RBRC);
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void td_eq_finished(tap_dance_state_t *state, void *user_data) {
 | 
			
		||||
    switch (state->count) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            register_code16(KC_EQL);        // 1 tap = =
 | 
			
		||||
            break;
 | 
			
		||||
        case 2:
 | 
			
		||||
            SEND_STRING("==");              // 2 taps = ==
 | 
			
		||||
            break;
 | 
			
		||||
        case 3:
 | 
			
		||||
            SEND_STRING("+=");              // 3 taps = +=
 | 
			
		||||
            break;
 | 
			
		||||
        case 4:
 | 
			
		||||
            register_code16(KC_PLUS);       // 4 taps = +
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void td_eq_reset(tap_dance_state_t *state, void *user_data) {
 | 
			
		||||
    switch (state->count) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            unregister_code16(KC_EQL);
 | 
			
		||||
            break;
 | 
			
		||||
        case 4:
 | 
			
		||||
            unregister_code16(KC_PLUS);
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void td_sl_finished(tap_dance_state_t *state, void *user_data) {
 | 
			
		||||
    switch (state->count) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            register_code16(KC_SLSH);       // 1 tap = /
 | 
			
		||||
            break;
 | 
			
		||||
        case 2:
 | 
			
		||||
            SEND_STRING("//");              // 2 taps = //
 | 
			
		||||
            break;
 | 
			
		||||
        case 3:
 | 
			
		||||
            register_code16(KC_BSLS);       // 3 taps = backslash
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void td_sl_reset(tap_dance_state_t *state, void *user_data) {
 | 
			
		||||
    switch (state->count) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            unregister_code16(KC_SLSH);
 | 
			
		||||
            break;
 | 
			
		||||
        case 3:
 | 
			
		||||
            unregister_code16(KC_BSLS);
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void td_mn_finished(tap_dance_state_t *state, void *user_data) {
 | 
			
		||||
    switch (state->count) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            register_code16(KC_MINS);       // 1 tap = -
 | 
			
		||||
            break;
 | 
			
		||||
        case 2:
 | 
			
		||||
            SEND_STRING("--");              // 2 taps = --
 | 
			
		||||
            break;
 | 
			
		||||
        case 3:
 | 
			
		||||
            SEND_STRING("=>");              // 3 taps = =>
 | 
			
		||||
            break;
 | 
			
		||||
        case 4:
 | 
			
		||||
            register_code16(KC_UNDS);       // 4 taps = _
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void td_mn_reset(tap_dance_state_t *state, void *user_data) {
 | 
			
		||||
    switch (state->count) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            unregister_code16(KC_MINS);
 | 
			
		||||
            break;
 | 
			
		||||
        case 4:
 | 
			
		||||
            unregister_code16(KC_UNDS);
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void td_am_finished(tap_dance_state_t *state, void *user_data) {
 | 
			
		||||
    switch (state->count) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            register_code16(KC_AMPR);       // 1 tap = &
 | 
			
		||||
            break;
 | 
			
		||||
        case 2:
 | 
			
		||||
            SEND_STRING("&&");              // 2 taps = &&
 | 
			
		||||
            break;
 | 
			
		||||
        case 3:
 | 
			
		||||
            SEND_STRING("||");              // 3 taps = ||
 | 
			
		||||
            break;
 | 
			
		||||
        case 4:
 | 
			
		||||
            register_code16(KC_PIPE);       // 4 taps = |
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void td_am_reset(tap_dance_state_t *state, void *user_data) {
 | 
			
		||||
    switch (state->count) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            unregister_code16(KC_AMPR);
 | 
			
		||||
            break;
 | 
			
		||||
        case 4:
 | 
			
		||||
            unregister_code16(KC_PIPE);
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void td_ex_finished(tap_dance_state_t *state, void *user_data) {
 | 
			
		||||
    switch (state->count) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            register_code16(KC_EXLM);       // 1 tap = !
 | 
			
		||||
            break;
 | 
			
		||||
        case 2:
 | 
			
		||||
            SEND_STRING("!=");              // 2 taps = !=
 | 
			
		||||
            break;
 | 
			
		||||
        case 3:
 | 
			
		||||
            register_code16(KC_QUES);       // 3 taps = ?
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void td_ex_reset(tap_dance_state_t *state, void *user_data) {
 | 
			
		||||
    switch (state->count) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            unregister_code16(KC_EXLM);
 | 
			
		||||
            break;
 | 
			
		||||
        case 3:
 | 
			
		||||
            unregister_code16(KC_QUES);
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Tap dance actions
 | 
			
		||||
tap_dance_action_t tap_dance_actions[] = {
 | 
			
		||||
    [TD_J_BRACES] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, td_j_finished, td_j_reset),
 | 
			
		||||
    [TD_K_PARENS] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, td_k_finished, td_k_reset),
 | 
			
		||||
    [TD_SC_ANGLES] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, td_sc_finished, td_sc_reset),
 | 
			
		||||
    [TD_L_BRACKETS] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, td_l_finished, td_l_reset),
 | 
			
		||||
    [TD_EQ_PLUS] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, td_eq_finished, td_eq_reset),
 | 
			
		||||
    [TD_SL_BACK] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, td_sl_finished, td_sl_reset),
 | 
			
		||||
    [TD_MN_UNDER] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, td_mn_finished, td_mn_reset),
 | 
			
		||||
    [TD_AM_PIPE] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, td_am_finished, td_am_reset),
 | 
			
		||||
    [TD_EX_QUEST] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, td_ex_finished, td_ex_reset),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		||||
    [_QWERTY] = LAYOUT_split_3x6_3(
 | 
			
		||||
  //,-----------------------------------------------------.                    ,-----------------------------------------------------.
 | 
			
		||||
| 
						 | 
				
			
			@ -152,6 +460,18 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
                                      //`--------------------------'  `--------------------------'
 | 
			
		||||
  ),
 | 
			
		||||
 | 
			
		||||
    [_SYMBOL_NEW] = LAYOUT_split_3x6_3(
 | 
			
		||||
  //,-----------------------------------------------------.                    ,-----------------------------------------------------.
 | 
			
		||||
      XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,                      KC_GRV,TD(TD_AM_PIPE), KC_ASTR, TD(TD_SL_BACK), KC_CIRC, XXXXXXX,
 | 
			
		||||
  //|--------+--------+--------+--------+--------+--------|                    |--------+--------+--------+--------+--------+--------|
 | 
			
		||||
      XXXXXXX, KC_LGUI, KC_LALT, KC_LCTL, KC_LSFT, XXXXXXX,                     TD(TD_EQ_PLUS),TD(TD_J_BRACES),TD(TD_K_PARENS),TD(TD_SC_ANGLES),TD(TD_L_BRACKETS), XXXXXXX,
 | 
			
		||||
  //|--------+--------+--------+--------+--------+--------|                    |--------+--------+--------+--------+--------+--------|
 | 
			
		||||
      XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,                      KC_TILD,TD(TD_MN_UNDER), KC_COLN,TD(TD_EX_QUEST), KC_PERC, XXXXXXX,
 | 
			
		||||
  //|--------+--------+--------+--------+--------+--------+--------|  |--------+--------+--------+--------+--------+--------+--------|
 | 
			
		||||
                                          XXXXXXX, XXXXXXX, XXXXXXX,      KC_AT, KC_HASH,  KC_DLR
 | 
			
		||||
                                      //`--------------------------'  `--------------------------'
 | 
			
		||||
  ),
 | 
			
		||||
 | 
			
		||||
    [_NAV] = LAYOUT_split_3x6_3(
 | 
			
		||||
  //,-----------------------------------------------------.                    ,-----------------------------------------------------.
 | 
			
		||||
      XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,                     XXXXXXX, KC_HOME,   KC_UP,  KC_END, XXXXXXX, XXXXXXX,
 | 
			
		||||
| 
						 | 
				
			
			@ -257,6 +577,19 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
 | 
			
		|||
  return true;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Per-key tapping term optimization
 | 
			
		||||
uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) {
 | 
			
		||||
    switch (keycode) {
 | 
			
		||||
        case TD_J_BRACES:
 | 
			
		||||
        case TD_K_PARENS:  return 180;  // Index/middle fingers more responsive
 | 
			
		||||
        case TD_L_BRACKETS: return 220; // Pinky finger needs more time
 | 
			
		||||
        case TD_SC_ANGLES:  return 200; // Ring finger standard
 | 
			
		||||
        case HM_F: case HM_J: return 180;  // Strong index fingers
 | 
			
		||||
        case HM_A: case HM_SCLN: return 250;  // Weak pinkies need more time
 | 
			
		||||
        default: return TAPPING_TERM;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef OLED_ENABLE
 | 
			
		||||
oled_rotation_t oled_init_user(oled_rotation_t rotation) { return OLED_ROTATION_270; }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,3 +14,4 @@ SPACE_CADET_ENABLE = no
 | 
			
		|||
GRAVE_ESC_ENABLE = no
 | 
			
		||||
MAGIC_ENABLE = no
 | 
			
		||||
COMBO_ENABLE = yes
 | 
			
		||||
TAP_DANCE_ENABLE = yes
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue