1
1
export async function main ( ) {
2
2
registerKeybinds ( ) ;
3
+ showKeybinds ( ) ;
3
4
addStats ( ) ;
4
5
}
5
6
@@ -11,10 +12,14 @@ function eventGenerator(key: KeyboardEvent["key"]) {
11
12
}
12
13
13
14
const keys = {
14
- down : eventGenerator ( "ArrowDown" ) ,
15
- up : eventGenerator ( "ArrowUp" ) ,
16
- left : eventGenerator ( "ArrowLeft" ) ,
17
- right : eventGenerator ( "ArrowRight" ) ,
15
+ j : eventGenerator ( "ArrowDown" ) ,
16
+ k : eventGenerator ( "ArrowUp" ) ,
17
+ h : eventGenerator ( "ArrowLeft" ) ,
18
+ l : eventGenerator ( "ArrowRight" ) ,
19
+ m : eventGenerator ( "d" ) ,
20
+ "," : eventGenerator ( "s" ) ,
21
+ correct : eventGenerator ( "g" ) ,
22
+ incorrect : eventGenerator ( "r" ) ,
18
23
} as const ;
19
24
20
25
function isNotesFocused ( ) {
@@ -25,40 +30,79 @@ function isNotesFocused() {
25
30
26
31
function registerKeybinds ( ) {
27
32
document . addEventListener ( "keydown" , ( ev ) => {
28
- let key = null ;
33
+ if ( ! ev . key . match ( / ^ [ h j k l u i m , ] $ / i ) || isNotesFocused ( ) ) return ;
29
34
30
- if ( isNotesFocused ( ) ) return ;
35
+ const eventKey = ev . key . toLowerCase ( ) ;
31
36
32
- switch ( ev . key ) {
33
- case String ( ev . key . match ( / ^ j $ / i) ) :
34
- key = keys . down ;
35
- break ;
37
+ let key = null ;
36
38
37
- case String ( ev . key . match ( / ^ k $ / i) ) :
38
- key = keys . up ;
39
+ switch ( eventKey ) {
40
+ case "h" :
41
+ case "j" :
42
+ case "k" :
43
+ case "l" :
44
+ case "m" :
45
+ case "," :
46
+ key = keys [ eventKey ] ;
39
47
break ;
40
48
41
- case String ( ev . key . match ( / ^ l $ / i) ) :
42
- key = keys . right ;
49
+ case "u" :
50
+ document . body . dispatchEvent ( keys . correct ) ;
51
+ key = keys . j ;
43
52
break ;
44
53
45
- case String ( ev . key . match ( / ^ h $ / i) ) :
46
- key = keys . left ;
54
+ case "i" :
55
+ document . body . dispatchEvent ( keys . incorrect ) ;
56
+ key = keys . j ;
47
57
break ;
48
58
}
49
59
50
60
if ( ! key ) return ;
51
61
52
62
document . body . dispatchEvent ( key ) ;
53
63
} ) ;
64
+ }
65
+
66
+ async function showKeybinds ( ) {
67
+ await waitForElement ( "button[tabindex='-1']" ) ;
68
+
69
+ const shown = ! ! document . getElementById ( "buddy-nav" ) ;
70
+
71
+ if ( shown ) return ;
72
+
73
+ const container = document . querySelector (
74
+ ".flex.w-full.flex-row.flex-wrap.justify-center.space-x-6.mt-6.gap-y-2.gap-x-2"
75
+ ) ;
76
+
77
+ if ( ! container || container . childNodes . length < 6 ) return ;
78
+ const nodes = container . childNodes ;
54
79
55
- document . addEventListener ( "keyup" , ( ev ) => {
56
- if ( ! ev . key . match ( / ^ [ g r f ] $ / i) ) return ;
80
+ const vimNav = nodes [ 0 ] . cloneNode ( true ) as HTMLDivElement ;
81
+ vimNav . setAttribute ( "id" , "buddy-nav" ) ;
82
+ vimNav . classList . add ( "font-semibold" ) ;
57
83
58
- if ( isNotesFocused ( ) ) return ;
84
+ let idx = 0 ;
59
85
60
- document . body . dispatchEvent ( keys . down ) ;
86
+ vimNav . querySelectorAll ( "button" ) . forEach ( ( button ) => {
87
+ button . innerHTML = [ "k" , "h" , "j" , "l" ] [ idx ++ ] ;
61
88
} ) ;
89
+
90
+ idx = 0 ;
91
+
92
+ for ( let i = 1 ; i < 6 ; i ++ ) {
93
+ if ( i == 4 ) continue ;
94
+ const copy = ( nodes [ i ] as HTMLDivElement )
95
+ . querySelector ( ".flex.flex-row.justify-center.w-full" )
96
+ ?. cloneNode ( true ) ;
97
+
98
+ if ( ! copy ) return ;
99
+
100
+ copy . childNodes [ 0 ] . childNodes [ 0 ] . textContent = [ "m" , "u" , "i" , "," ] [ idx ++ ] ;
101
+
102
+ nodes [ i ] . childNodes [ 0 ] . appendChild ( copy ) ;
103
+ }
104
+
105
+ container . insertBefore ( vimNav , nodes [ 1 ] ) ;
62
106
}
63
107
64
108
async function addStats ( ) {
0 commit comments