-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwaki_gen.rb
229 lines (199 loc) · 4.85 KB
/
waki_gen.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
require 'yaml'
require 'pp'
config = YAML.load(File.read('config.yml'))
class Chord
attr_reader :thumb
@fingers = ""
@thumb = ""
@action = ""
def initialize(action)
@action = action
end
def add_thumb(thumb)
@thumb = thumb
self
end
def add_fingers(fingers)
@fingers = fingers
self
end
def as_string
<<-EOK
case 0b#{@fingers}#{@thumb}: {
#{@action}
break;
}
EOK
end
end
class EmptyChord
def initalize (); end
def add_thumb (_); self; end
def add_fingers(_); self; end
def as_string (); ""; end
def thumb (); ""; end
end
def _generic_mod(chords, thumb)
chords.map { |chord| dochord(chord).add_thumb thumb }
end
def _normal (chords); _generic_mod chords, "000"; end
def _shift (chords); _generic_mod chords, "100"; end
def _symbol (chords); _generic_mod chords, "010"; end
def _function(chords); _generic_mod chords, "001"; end
def _control (chords); _generic_mod chords, "110"; end
def _macro (chords); _generic_mod chords, "011"; end
def iterate_generic_chord(bindings, init)
buf = ""
i = init
bindings.each do |b|
buf += yield b, i unless b == '_'
i -= 1
end
buf
end
def to_top(e)
e.to_s.rjust(4, "0") + "0000"
end
def to_bottom(e)
"0000" + e.to_s.rjust(4, "0")
end
class String
def downto8
if self.length > 8
self[0..7]
else
self
end
end
end
def _single(chords)
iterate_generic_chord(chords, 10) do |c, i|
if c.thumb == ""
c.as_string
elsif c.thumb == "000"
c.add_thumb("").add_fingers("#{10 ** i}".rjust(11, "0")).as_string
else
c.add_fingers("#{10 ** (i - 3)}".rjust(8, "0")).as_string
end
end
end
def _vertical(chords)
iterate_generic_chord(chords, 3) do |c, i|
c.add_fingers("#{10**i}".rjust(4, "0") * 2).as_string
end
end
def _double(chords)
[(chords[0].add_fingers to_top 1100),
(chords[1].add_fingers to_top 110),
(chords[2].add_fingers to_top 11),
(chords[3].add_fingers to_top 1001),
(chords[4].add_fingers to_top 1010),
(chords[5].add_fingers to_top 101),
(chords[6].add_fingers to_bottom 1100),
(chords[7].add_fingers to_bottom 110),
(chords[8].add_fingers to_bottom 11),
(chords[9].add_fingers to_bottom 1001),
(chords[10].add_fingers to_bottom 1010),
(chords[11].add_fingers to_bottom 101),
].map(&:as_string).join
end
def _triple(chords)
[(chords[0].add_fingers to_top 1110),
(chords[1].add_fingers to_top 1101),
(chords[2].add_fingers to_top 111),
(chords[3].add_fingers to_top 1011),
(chords[4].add_fingers to_bottom 1110),
(chords[5].add_fingers to_bottom 1101),
(chords[6].add_fingers to_bottom 111),
(chords[7].add_fingers to_bottom 1011),
].map(&:as_string).join
end
def _quadruple(chords)
[(chords[0].add_fingers to_top 1111),
(chords[1].add_fingers to_bottom 1111),
(chords[2].add_fingers '1100' * 2),
(chords[3].add_fingers '0110' * 2),
(chords[4].add_fingers '0011' * 2),
(chords[5].add_fingers '1001' * 2),
].map(&:as_string).join
end
def ind(text)
" "*2 + text
end
def type(str)
"Keyboard.press(#{str});\n" +
" "*12 + "Keyboard.release(#{str});"
end
def dochord(val)
val = val.to_s if val.is_a? Numeric
if val == '_'
EmptyChord.new
elsif val.is_a? Array
Chord.new val.join
elsif val.start_with? 'mod_'
action = "modif.start_mode(" +
val.
split('_')[1..-1].
map { |mod| "Mod::" + mod }.
join(' | ') +
", Layer::curr);"
Chord.new(action)
elsif val.start_with? '_'
action = "Keyboard.press(KEY#{val.upcase});\n" +
" "*12 + "Keyboard.release(KEY#{val.upcase});"
Chord.new(action)
elsif val == '\\\\'
Chord.new type "'\\\\'"
elsif val == "'"
Chord.new type "'\\''"
elsif val.length == 1
Chord.new type "'#{val}'"
else
Chord.new "Keyboard.print(\"#{val}\");"
end
end
puts <<-EOK
#ifndef LAYOUT_H
#define LAYOUT_H
/* #{config['name']}
* generated by Timur Ismagilov's waki_gen.rb
* on #{Time.now}
*
* https://github.com/bouncepaw/wakizashi
*/
Modif modif;
void exec_chord(chord currc) {
currc = ~currc % (1 << 11);
Serial.print("Execute chord ");
debug_print(currc);
modif.start_ctrl_maybe(Layer::curr, currc);
switch (Layer::curr) {
EOK
config['layers'].each do |layer, groups|
puts ind ind "case Layer::#{layer}: {"
puts ind ind ind "switch (currc) {"
if groups['prepend'] != nil
puts groups['prepend']
groups.delete 'prepend'
end
appendbuf = ""
if groups['append'] != nil
appendbuf = groups['append']
groups.delete 'append'
end
groups.each do |group, mods|
mods.each do |mod, chords|
puts eval "_#{group}(_#{mod}(#{chords}))"
end
end
puts ind ind ind "}"
puts ind ind ind appendbuf
puts ind ind ind "break;"
puts ind ind "}"
end
puts <<-EOK
}
modif.stop_ctrl_maybe(Layer::curr);
}
#endif
EOK