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
|
use std::{env::args, fs::File, io::Read};
mod format_layer;
fn main() {
let mode = args().nth(1).expect("Exists");
let mut file_to_format = String::new();
{
File::open(args().skip(1).last().expect("Exists"))
.expect("Should work")
.read_to_string(&mut file_to_format)
.expect("Failed to read file to format");
let mut lines: Vec<_> = file_to_format.lines().collect();
if lines[0] == "// clang-format off" {
lines.remove(0);
}
if lines.last().expect("Exists") == &"// clang-format on" {
lines.remove(lines.len() - 1);
}
file_to_format = lines.join("\n");
}
let output = match mode.as_str() {
"keymap.h" => {
let mut c_column_max = [0; 14];
// The first run calculates the correct c_column_max values, and the second one
// actually formats.
let out = format_keymap_h(&mut c_column_max, file_to_format);
format_keymap_h(&mut c_column_max, out)
}
"ledmap.h" => {
let mut c_column_max = [0; 14];
// We also need two passes here.
let out = format_ledmap_h(&mut c_column_max, file_to_format);
format_ledmap_h(&mut c_column_max, out)
}
other => unreachable!("Invalid mode: '{other}'"),
};
print!("// clang-format off\n{}// clang-format on\n", output);
}
fn format_ledmap_h(c_column_max: &mut [usize; 14], ledmap_h: String) -> String {
let mut output: String = String::new();
let mut c_layer: Vec<String> = vec![];
ledmap_h
.lines()
.filter(|line| !line.trim().is_empty())
.for_each(|line| {
let line = line.trim();
let first_char = line.chars().next().unwrap();
let second_char = line.chars().nth(1).unwrap();
if line.is_empty() {
return;
}
match (first_char, second_char) {
('/', '/') => {
// Comment, don't touch.
output.push_str(line);
output.push('\n');
}
('c', 'o') | ('}', ';') => {
// Start or end of the ledmap def, leave it alone
output.push_str(line);
output.push('\n');
}
('[', '0'..='9') | ('/', '*') => {
// Start of a new layer
assert!(
c_layer.is_empty(),
"A new layer cannot start, when the current layer is not empty."
);
output.push_str(&format!(" {}", line));
output.push('\n');
}
('}', ',') => {
// End of a layer
output.push_str(&format_layer::format_layer(
c_layer.join("\n"),
c_column_max,
));
c_layer.clear();
output.push_str(&format!(" {}", line));
output.push('\n');
}
_ => {
// We are in a layer
c_layer.push(line.to_owned());
}
}
});
output
}
fn format_keymap_h(c_column_max: &mut [usize; 14], keymap_h: String) -> String {
let mut output: String = String::new();
let mut c_layer: Vec<String> = vec![];
keymap_h
.lines()
.filter(|line| !line.trim().is_empty())
.for_each(|line| {
let line = line.trim();
let first_char = line.chars().take(1).last().unwrap();
if line.is_empty() {
return;
}
match first_char {
'/' => {
// Comment, don't touch
output.push_str(line);
output.push('\n');
}
'c' | '}' => {
// Start or end of the kemap def, leave it alone
output.push_str(line);
output.push('\n');
}
'[' => {
// Start of a new layer
assert!(
c_layer.is_empty(),
"A new layer cannot start, when the current layer is not empty."
);
output.push_str(&format!(" {}", line));
output.push('\n');
}
')' => {
// End of a layer
output.push_str(&format_layer::format_layer(
c_layer.join("\n"),
c_column_max,
));
c_layer.clear();
output.push_str(&format!(" {}", line));
output.push('\n');
}
_ => {
// We are in a layer
c_layer.push(line.to_owned());
}
}
});
output
}
|