1use std::sync::{Arc, LazyLock};
2
3use crate::{Lang, LangInner};
4
5macro_rules! define_langs {
6 (
7 $(
8 $fn_name:ident => {
9 feature: $feature:literal,
10 name: $name:literal,
11 ts_lang: $ts_lang:expr,
12 node_types_key: $node_types_key:literal,
13 names: [$($alias:literal),* $(,)?],
14 extensions: [$($ext:literal),* $(,)?] $(,)?
15 }
16 ),* $(,)?
17 ) => {
18 $(
20 #[cfg(feature = $feature)]
21 plotnik_macros::generate_node_types!($node_types_key);
22 )*
23
24 $(
26 #[cfg(feature = $feature)]
27 pub fn $fn_name() -> Lang {
28 paste::paste! {
29 static LANG: LazyLock<Lang> = LazyLock::new(|| {
30 Arc::new(LangInner::new_static(
31 $name,
32 $ts_lang.into(),
33 &[<$node_types_key:upper _NODE_TYPES>],
34 ))
35 });
36 }
37 Arc::clone(&LANG)
38 }
39 )*
40
41 pub fn from_name(s: &str) -> Option<Lang> {
42 match s.to_ascii_lowercase().as_str() {
43 $(
44 #[cfg(feature = $feature)]
45 $($alias)|* => Some($fn_name()),
46 )*
47 _ => None,
48 }
49 }
50
51 pub fn from_ext(ext: &str) -> Option<Lang> {
52 match ext.to_ascii_lowercase().as_str() {
53 $(
54 #[cfg(feature = $feature)]
55 $($ext)|* => Some($fn_name()),
56 )*
57 _ => None,
58 }
59 }
60
61 pub fn all() -> Vec<Lang> {
62 vec![
63 $(
64 #[cfg(feature = $feature)]
65 $fn_name(),
66 )*
67 ]
68 }
69 };
70}
71
72define_langs! {
73 bash => {
74 feature: "bash",
75 name: "bash",
76 ts_lang: tree_sitter_bash::LANGUAGE,
77 node_types_key: "bash",
78 names: ["bash", "sh", "shell"],
79 extensions: ["sh", "bash", "zsh"],
80 },
81 c => {
82 feature: "c",
83 name: "c",
84 ts_lang: tree_sitter_c::LANGUAGE,
85 node_types_key: "c",
86 names: ["c"],
87 extensions: ["c", "h"],
88 },
89 cpp => {
90 feature: "cpp",
91 name: "cpp",
92 ts_lang: tree_sitter_cpp::LANGUAGE,
93 node_types_key: "cpp",
94 names: ["cpp", "c++", "cxx", "cc"],
95 extensions: ["cpp", "cc", "cxx", "hpp", "hh", "hxx", "h++", "c++"],
96 },
97 csharp => {
98 feature: "csharp",
99 name: "c_sharp",
100 ts_lang: tree_sitter_c_sharp::LANGUAGE,
101 node_types_key: "csharp",
102 names: ["csharp", "c#", "cs", "c_sharp"],
103 extensions: ["cs"],
104 },
105 css => {
106 feature: "css",
107 name: "css",
108 ts_lang: tree_sitter_css::LANGUAGE,
109 node_types_key: "css",
110 names: ["css"],
111 extensions: ["css"],
112 },
113 elixir => {
114 feature: "elixir",
115 name: "elixir",
116 ts_lang: tree_sitter_elixir::LANGUAGE,
117 node_types_key: "elixir",
118 names: ["elixir", "ex"],
119 extensions: ["ex", "exs"],
120 },
121 go => {
122 feature: "go",
123 name: "go",
124 ts_lang: tree_sitter_go::LANGUAGE,
125 node_types_key: "go",
126 names: ["go", "golang"],
127 extensions: ["go"],
128 },
129 haskell => {
130 feature: "haskell",
131 name: "haskell",
132 ts_lang: tree_sitter_haskell::LANGUAGE,
133 node_types_key: "haskell",
134 names: ["haskell", "hs"],
135 extensions: ["hs", "lhs"],
136 },
137 hcl => {
138 feature: "hcl",
139 name: "hcl",
140 ts_lang: tree_sitter_hcl::LANGUAGE,
141 node_types_key: "hcl",
142 names: ["hcl", "terraform", "tf"],
143 extensions: ["hcl", "tf", "tfvars"],
144 },
145 html => {
146 feature: "html",
147 name: "html",
148 ts_lang: tree_sitter_html::LANGUAGE,
149 node_types_key: "html",
150 names: ["html", "htm"],
151 extensions: ["html", "htm"],
152 },
153 java => {
154 feature: "java",
155 name: "java",
156 ts_lang: tree_sitter_java::LANGUAGE,
157 node_types_key: "java",
158 names: ["java"],
159 extensions: ["java"],
160 },
161 javascript => {
162 feature: "javascript",
163 name: "javascript",
164 ts_lang: tree_sitter_javascript::LANGUAGE,
165 node_types_key: "javascript",
166 names: ["javascript", "js", "jsx", "ecmascript", "es"],
167 extensions: ["js", "mjs", "cjs", "jsx"],
168 },
169 json => {
170 feature: "json",
171 name: "json",
172 ts_lang: tree_sitter_json::LANGUAGE,
173 node_types_key: "json",
174 names: ["json"],
175 extensions: ["json"],
176 },
177 kotlin => {
178 feature: "kotlin",
179 name: "kotlin",
180 ts_lang: tree_sitter_kotlin::LANGUAGE,
181 node_types_key: "kotlin",
182 names: ["kotlin", "kt"],
183 extensions: ["kt", "kts"],
184 },
185 lua => {
186 feature: "lua",
187 name: "lua",
188 ts_lang: tree_sitter_lua::LANGUAGE,
189 node_types_key: "lua",
190 names: ["lua"],
191 extensions: ["lua"],
192 },
193 nix => {
194 feature: "nix",
195 name: "nix",
196 ts_lang: tree_sitter_nix::LANGUAGE,
197 node_types_key: "nix",
198 names: ["nix"],
199 extensions: ["nix"],
200 },
201 php => {
202 feature: "php",
203 name: "php",
204 ts_lang: tree_sitter_php::LANGUAGE_PHP,
205 node_types_key: "php",
206 names: ["php"],
207 extensions: ["php"],
208 },
209 python => {
210 feature: "python",
211 name: "python",
212 ts_lang: tree_sitter_python::LANGUAGE,
213 node_types_key: "python",
214 names: ["python", "py"],
215 extensions: ["py", "pyi", "pyw"],
216 },
217 ruby => {
218 feature: "ruby",
219 name: "ruby",
220 ts_lang: tree_sitter_ruby::LANGUAGE,
221 node_types_key: "ruby",
222 names: ["ruby", "rb"],
223 extensions: ["rb", "rake", "gemspec"],
224 },
225 rust => {
226 feature: "rust",
227 name: "rust",
228 ts_lang: tree_sitter_rust::LANGUAGE,
229 node_types_key: "rust",
230 names: ["rust", "rs"],
231 extensions: ["rs"],
232 },
233 scala => {
234 feature: "scala",
235 name: "scala",
236 ts_lang: tree_sitter_scala::LANGUAGE,
237 node_types_key: "scala",
238 names: ["scala"],
239 extensions: ["scala", "sc"],
240 },
241 solidity => {
242 feature: "solidity",
243 name: "solidity",
244 ts_lang: tree_sitter_solidity::LANGUAGE,
245 node_types_key: "solidity",
246 names: ["solidity", "sol"],
247 extensions: ["sol"],
248 },
249 swift => {
250 feature: "swift",
251 name: "swift",
252 ts_lang: tree_sitter_swift::LANGUAGE,
253 node_types_key: "swift",
254 names: ["swift"],
255 extensions: ["swift"],
256 },
257 typescript => {
258 feature: "typescript",
259 name: "typescript",
260 ts_lang: tree_sitter_typescript::LANGUAGE_TYPESCRIPT,
261 node_types_key: "typescript",
262 names: ["typescript", "ts"],
263 extensions: ["ts", "mts", "cts"],
264 },
265 tsx => {
266 feature: "typescript",
267 name: "tsx",
268 ts_lang: tree_sitter_typescript::LANGUAGE_TSX,
269 node_types_key: "typescript_tsx",
270 names: ["tsx"],
271 extensions: ["tsx"],
272 },
273 yaml => {
274 feature: "yaml",
275 name: "yaml",
276 ts_lang: tree_sitter_yaml::LANGUAGE,
277 node_types_key: "yaml",
278 names: ["yaml", "yml"],
279 extensions: ["yaml", "yml"],
280 },
281}