1use std::collections::HashMap;
7use std::sync::LazyLock;
8
9pub static LANGUAGE_ALIASES: LazyLock<HashMap<&'static str, &'static str>> = LazyLock::new(|| {
13 let mut m = HashMap::new();
14
15 m.insert("python", "Python");
17 m.insert("py", "Python");
18 m.insert("python3", "Python");
19 m.insert("py3", "Python");
20
21 m.insert("javascript", "JavaScript");
23 m.insert("js", "JavaScript");
24 m.insert("node", "JavaScript");
25 m.insert("nodejs", "JavaScript");
26
27 m.insert("typescript", "TypeScript");
29 m.insert("ts", "TypeScript");
30
31 m.insert("rust", "Rust");
33 m.insert("rs", "Rust");
34
35 m.insert("bash", "Bourne Again Shell (bash)");
37 m.insert("sh", "Bourne Again Shell (bash)");
38 m.insert("shell", "Bourne Again Shell (bash)");
39 m.insert("zsh", "Bourne Again Shell (bash)");
40 m.insert("fish", "Bourne Again Shell (bash)");
41
42 m.insert("c", "C");
44 m.insert("h", "C");
45
46 m.insert("cpp", "C++");
48 m.insert("c++", "C++");
49 m.insert("cxx", "C++");
50 m.insert("hpp", "C++");
51 m.insert("hxx", "C++");
52
53 m.insert("csharp", "C#");
55 m.insert("cs", "C#");
56
57 m.insert("go", "Go");
59 m.insert("golang", "Go");
60
61 m.insert("java", "Java");
63
64 m.insert("kotlin", "Kotlin");
66 m.insert("kt", "Kotlin");
67
68 m.insert("swift", "Swift");
70
71 m.insert("ruby", "Ruby");
73 m.insert("rb", "Ruby");
74
75 m.insert("php", "PHP");
77
78 m.insert("perl", "Perl");
80 m.insert("pl", "Perl");
81
82 m.insert("lua", "Lua");
84
85 m.insert("r", "R");
87
88 m.insert("scala", "Scala");
90
91 m.insert("haskell", "Haskell");
93 m.insert("hs", "Haskell");
94
95 m.insert("ocaml", "OCaml");
97 m.insert("ml", "OCaml");
98
99 m.insert("fsharp", "F#");
101 m.insert("fs", "F#");
102
103 m.insert("elixir", "Elixir");
105 m.insert("ex", "Elixir");
106 m.insert("exs", "Elixir");
107
108 m.insert("erlang", "Erlang");
110 m.insert("erl", "Erlang");
111
112 m.insert("clojure", "Clojure");
114 m.insert("clj", "Clojure");
115
116 m.insert("sql", "SQL");
118 m.insert("mysql", "SQL");
119 m.insert("postgresql", "SQL");
120 m.insert("postgres", "SQL");
121 m.insert("sqlite", "SQL");
122
123 m.insert("html", "HTML");
125 m.insert("htm", "HTML");
126 m.insert("xhtml", "HTML");
127
128 m.insert("css", "CSS");
130 m.insert("scss", "SCSS");
131 m.insert("sass", "Sass");
132 m.insert("less", "Less");
133
134 m.insert("json", "JSON");
136 m.insert("jsonc", "JSON");
137
138 m.insert("yaml", "YAML");
140 m.insert("yml", "YAML");
141
142 m.insert("toml", "TOML");
144
145 m.insert("xml", "XML");
147 m.insert("xsl", "XML");
148 m.insert("xslt", "XML");
149 m.insert("svg", "XML");
150
151 m.insert("markdown", "Markdown");
153 m.insert("md", "Markdown");
154 m.insert("mdown", "Markdown");
155
156 m.insert("latex", "LaTeX");
158 m.insert("tex", "TeX");
159
160 m.insert("makefile", "Makefile");
162 m.insert("make", "Makefile");
163 m.insert("mk", "Makefile");
164
165 m.insert("dockerfile", "Dockerfile");
167 m.insert("docker", "Dockerfile");
168
169 m.insert("nginx", "nginx");
171
172 m.insert("ini", "INI");
174 m.insert("conf", "INI");
175 m.insert("cfg", "INI");
176
177 m.insert("diff", "Diff");
179 m.insert("patch", "Diff");
180
181 m.insert("git", "Git Commit");
183 m.insert("gitcommit", "Git Commit");
184 m.insert("gitignore", "Git Ignore");
185
186 m.insert("lisp", "Lisp");
188 m.insert("elisp", "Lisp");
189 m.insert("emacs-lisp", "Lisp");
190 m.insert("commonlisp", "Lisp");
191 m.insert("cl", "Lisp");
192
193 m.insert("scheme", "Scheme");
195 m.insert("racket", "Scheme");
196
197 m.insert("dart", "Dart");
199
200 m.insert("vue", "Vue Component");
202
203 m.insert("graphql", "GraphQL");
205 m.insert("gql", "GraphQL");
206
207 m.insert("protobuf", "Protocol Buffers");
209 m.insert("proto", "Protocol Buffers");
210
211 m.insert("terraform", "Terraform");
213 m.insert("tf", "Terraform");
214 m.insert("hcl", "Terraform");
215
216 m.insert("asm", "Assembly (x86_64)");
218 m.insert("assembly", "Assembly (x86_64)");
219 m.insert("nasm", "Assembly (x86_64)");
220
221 m.insert("text", "Plain Text");
223 m.insert("txt", "Plain Text");
224 m.insert("plain", "Plain Text");
225
226 m.insert("objc", "Objective-C");
228 m.insert("objective-c", "Objective-C");
229 m.insert("objectivec", "Objective-C");
230
231 m.insert("objcpp", "Objective-C++");
233 m.insert("objective-c++", "Objective-C++");
234
235 m.insert("pascal", "Pascal");
237 m.insert("delphi", "Pascal");
238
239 m.insert("groovy", "Groovy");
241
242 m.insert("powershell", "PowerShell");
244 m.insert("ps1", "PowerShell");
245 m.insert("pwsh", "PowerShell");
246
247 m.insert("batch", "Batch File");
249 m.insert("bat", "Batch File");
250 m.insert("cmd", "Batch File");
251
252 m.insert("regex", "Regular Expression");
254 m.insert("regexp", "Regular Expression");
255
256 m.insert("applescript", "AppleScript");
258
259 m.insert("jsx", "JavaScript (Babel)");
261 m.insert("tsx", "TypeScript");
262
263 m.insert("coffeescript", "CoffeeScript");
265 m.insert("coffee", "CoffeeScript");
266
267 m.insert("d", "D");
269 m.insert("dlang", "D");
270
271 m.insert("nim", "Nim");
273 m.insert("nimrod", "Nim");
274
275 m.insert("zig", "Zig");
277
278 m.insert("crystal", "Crystal");
280 m.insert("cr", "Crystal");
281
282 m.insert("julia", "Julia");
284 m.insert("jl", "Julia");
285
286 m.insert("solidity", "Solidity");
288 m.insert("sol", "Solidity");
289
290 m.insert("vyper", "Vyper");
292 m.insert("vy", "Vyper");
293
294 m.insert("fortran", "Fortran (Modern)");
296 m.insert("f90", "Fortran (Modern)");
297 m.insert("f95", "Fortran (Modern)");
298 m.insert("f03", "Fortran (Modern)");
299
300 m.insert("cobol", "COBOL");
302 m.insert("cob", "COBOL");
303
304 m.insert("actionscript", "ActionScript");
306 m.insert("as", "ActionScript");
307
308 m.insert("handlebars", "Handlebars");
310 m.insert("hbs", "Handlebars");
311 m.insert("mustache", "Handlebars");
312
313 m.insert("jinja", "Jinja");
315 m.insert("jinja2", "Jinja");
316
317 m.insert("puppet", "Puppet");
319 m.insert("pp", "Puppet");
320
321 m.insert("rst", "reStructuredText");
323 m.insert("restructuredtext", "reStructuredText");
324 m.insert("rest", "reStructuredText");
325
326 m.insert("asciidoc", "AsciiDoc");
328 m.insert("adoc", "AsciiDoc");
329
330 m.insert("org", "orgmode");
332 m.insert("orgmode", "orgmode");
333
334 m
335});
336
337pub fn language_alias(name: &str) -> &str {
351 let lower = name.to_lowercase();
352 LANGUAGE_ALIASES
353 .get(lower.as_str())
354 .copied()
355 .unwrap_or(name)
356}
357
358pub fn all_aliases() -> impl Iterator<Item = (&'static str, &'static str)> {
362 LANGUAGE_ALIASES.iter().map(|(k, v)| (*k, *v))
363}
364
365pub fn aliases_for(syntax_name: &str) -> Vec<&'static str> {
376 LANGUAGE_ALIASES
377 .iter()
378 .filter_map(|(alias, name)| {
379 if *name == syntax_name {
380 Some(*alias)
381 } else {
382 None
383 }
384 })
385 .collect()
386}
387
388#[cfg(test)]
389mod tests {
390 use super::*;
391
392 #[test]
393 fn test_python_aliases() {
394 assert_eq!(language_alias("python"), "Python");
395 assert_eq!(language_alias("py"), "Python");
396 assert_eq!(language_alias("Python"), "Python"); assert_eq!(language_alias("PY"), "Python");
398 }
399
400 #[test]
401 fn test_javascript_aliases() {
402 assert_eq!(language_alias("javascript"), "JavaScript");
403 assert_eq!(language_alias("js"), "JavaScript");
404 assert_eq!(language_alias("node"), "JavaScript");
405 }
406
407 #[test]
408 fn test_rust_aliases() {
409 assert_eq!(language_alias("rust"), "Rust");
410 assert_eq!(language_alias("rs"), "Rust");
411 }
412
413 #[test]
414 fn test_shell_aliases() {
415 let expected = "Bourne Again Shell (bash)";
416 assert_eq!(language_alias("bash"), expected);
417 assert_eq!(language_alias("sh"), expected);
418 assert_eq!(language_alias("shell"), expected);
419 assert_eq!(language_alias("zsh"), expected);
420 }
421
422 #[test]
423 fn test_unknown_returns_original() {
424 assert_eq!(language_alias("unknown-lang"), "unknown-lang");
425 assert_eq!(language_alias("foo"), "foo");
426 }
427
428 #[test]
429 fn test_aliases_for() {
430 let python_aliases = aliases_for("Python");
431 assert!(python_aliases.contains(&"py"));
432 assert!(python_aliases.contains(&"python"));
433 assert!(python_aliases.contains(&"python3"));
434 }
435
436 #[test]
437 fn test_case_insensitivity() {
438 assert_eq!(language_alias("PYTHON"), "Python");
439 assert_eq!(language_alias("JavaScript"), "JavaScript");
440 assert_eq!(language_alias("RUST"), "Rust");
441 }
442
443 #[test]
444 fn test_all_aliases_not_empty() {
445 let count = all_aliases().count();
446 assert!(count > 100); }
448}