Skip to main content

duat_filetype/
prefixes.rs

1//! Prefix autocompletion for various filetypes.
2//!
3//! This module provides the [`AutoPrefix`] trait, which lets [`Cursor`]s add prefixes (e.g. comments, list headings, etc).
4use std::{collections::HashMap, sync::LazyLock};
5
6use super::FileType;
7use duat_core::{mode::Cursor, text::RegexHaystack};
8
9/// Trait to add the comment prefix of the previous line.
10pub trait AutoPrefix {
11    /// Adds the comment prefix of the previous line
12    ///
13    /// This function will assume that the current cursor position is
14    /// where you want to add the prefix, with indentation already
15    /// taken into account.
16    ///
17    /// Returns `true` if the line was commented.
18    fn add_comment(&mut self) -> bool;
19}
20
21impl AutoPrefix for Cursor<'_> {
22    fn add_comment(&mut self) -> bool {
23        let Some(prev_lnum) = self.caret().line().checked_sub(1) else {
24            return false;
25        };
26
27        if let Some(filetype) = self.filetype()
28            && let Some(prefixes) = PREFIXES.get(filetype)
29        {
30            let line = self.text().line(prev_lnum);
31            for prefix in prefixes.iter() {
32                if let Some(range) = line.search(prefix.from).next()
33                    && prefix.blocker.is_none_or(|blocker| {
34                        line.search(blocker)
35                            .next()
36                            .is_none_or(|blocker_range| blocker_range.end <= range.start)
37                    })
38                {
39                    self.insert(prefix.set);
40                    self.move_hor(prefix.set.chars().count() as i32);
41
42                    return true;
43                }
44            }
45        }
46
47        false
48    }
49}
50
51struct Prefix {
52    from: &'static str,
53    set: &'static str,
54    blocker: Option<&'static str>,
55}
56
57const fn pf(from: &'static str, set: &'static str, blocker: Option<&'static str>) -> Prefix {
58    Prefix { from, set, blocker }
59}
60
61// List taken from https://gist.github.com/dk949/88b2652284234f723decaeb84db2576c
62static PREFIXES: LazyLock<HashMap<&str, &[Prefix]>> = LazyLock::new(|| {
63    const HASH: Prefix = pf(r"^\s*#", "#", None);
64    const DOUBLE_HASH: &[Prefix] = &[pf(r"^\s*##", "##", None)];
65
66    const SLASHES: Prefix = pf(r"^\s*//", "//", None);
67    const DOC_SLASHES: Prefix = pf(r"^\s*///", "///", None);
68    const INNER_DOC_SLASHES: Prefix = pf(r"^\s*//!", "//!", None);
69    const ASTERISK: Prefix = pf(r"^\s*\*", " *", Some(r#"\*/"#));
70    const SLASH_ASTERISK: Prefix = pf(r"^\s*/\*", " *", Some(r#"\*/"#));
71    const SLASH_ASTERISK_LINE: &[Prefix] = &[pf(r"^\s*/\*", "/*", None)];
72
73    const QUOTE: Prefix = pf(r"^\s*'", "'", None);
74    const DQUOTE: Prefix = pf(r#"^\s*""#, r#"""#, None);
75    const SEMICOLON: Prefix = pf(r"^\s;", ";", None);
76    const PERCENT: Prefix = pf(r"^\s*%", "%", None);
77    const EXCLAMATION: Prefix = pf(r"^\s*!", "!", None);
78    const DOLLAR_SIGN: Prefix = pf(r"^\s*$", "$", None);
79    const SLASH: Prefix = pf(r"^\s*/", "/", None);
80
81    const DASHES: Prefix = pf(r"^\s*--", "--", None);
82    const REM: Prefix = pf("^REM", "REM", None);
83    const DOT_ESCAPED_DQUOTE: &[Prefix] = &[pf(r#"^\s\.\\""#, r#".\""#, None)];
84    const DOUBLE_COLON: Prefix = pf(r"^\s*::", "::", None);
85    const ASTERISK_LINE: Prefix = pf(r"^\s*\*", "*", None);
86    const LISP: &[Prefix] = &[
87        const { pf(r"^\s*;;;;", ";;;;", None) },
88        const { pf(r"^\s*;;;", ";;;", None) },
89        const { pf(r"^\s*;;", ";;", None) },
90        SEMICOLON,
91    ];
92
93    HashMap::from_iter([
94        // Hash group
95        ("aap", &[HASH] as &[Prefix]),
96        ("ampl", &[HASH]),
97        ("ansible", &[HASH]),
98        ("apache", &[HASH]),
99        ("apachestyle", &[HASH]),
100        ("awk", &[HASH]),
101        ("bc", &[HASH]),
102        ("cairo", &[HASH]),
103        ("cfg", &[HASH]),
104        ("cl", &[HASH]),
105        ("cmake", &[HASH]),
106        ("coffeescript", &[HASH]),
107        ("conkyrc", &[HASH]),
108        ("crontab", &[HASH]),
109        ("cucumber", &[HASH]),
110        ("cython", &[HASH]),
111        ("dakota", &[HASH]),
112        ("debcontrol", &[HASH]),
113        ("debsources", &[HASH]),
114        ("desktop", &[HASH]),
115        ("dhcpd", &[HASH]),
116        ("diff", &[HASH]),
117        ("dockerfile", &[HASH]),
118        ("ebuild", &[HASH]),
119        ("ecd", &[HASH]),
120        ("eclass", &[HASH]),
121        ("elixir", &[HASH]),
122        ("elmfilt", &[HASH]),
123        ("ember-script", &[HASH]),
124        ("esmtprc", &[HASH]),
125        ("exim", &[HASH]),
126        ("expect", &[HASH]),
127        ("exports", &[HASH]),
128        ("fancy", &[HASH]),
129        ("fgl", &[HASH]),
130        ("fluent", &[HASH]),
131        ("fstab", &[HASH]),
132        ("fvwm", &[HASH]),
133        ("gdb", &[HASH]),
134        ("gdscript3", &[HASH]),
135        ("gentoo-conf-d", &[HASH]),
136        ("gentoo-env-d", &[HASH]),
137        ("gentoo-init-d", &[HASH]),
138        ("gentoo-make-conf", &[HASH]),
139        ("gentoo-package-keywords", &[HASH]),
140        ("gentoo-package-mask", &[HASH]),
141        ("gentoo-package-use", &[HASH]),
142        ("gitcommit", &[HASH]),
143        ("gitignore", &[HASH]),
144        ("gitrebase", &[HASH]),
145        ("gnuplot", &[HASH]),
146        ("gtkrc", &[HASH]),
147        ("hb", &[HASH]),
148        ("hog", &[HASH]),
149        ("hostsaccess", &[HASH]),
150        ("hxml", &[HASH]),
151        ("ia64", &[HASH]),
152        ("icon", &[HASH]),
153        ("inittab", &[HASH]),
154        ("jproperties", &[HASH]),
155        ("julia", &[HASH]),
156        ("kivy", &[HASH]),
157        ("ldif", &[HASH]),
158        ("lilo", &[HASH]),
159        ("lout", &[HASH]),
160        ("lss", &[HASH]),
161        ("lynx", &[HASH]),
162        ("mako", DOUBLE_HASH),
163        ("maple", &[HASH]),
164        ("meson", &[HASH]),
165        ("mips", &[HASH]),
166        ("mirah", &[HASH]),
167        ("mush", &[HASH]),
168        ("nginx", &[HASH]),
169        ("nimrod", &[HASH]),
170        ("nix", &[HASH]),
171        ("nsis", &[HASH]),
172        ("ntp", &[HASH]),
173        ("ora", &[HASH]),
174        ("paludis-use-conf", &[HASH]),
175        ("pcap", &[HASH]),
176        ("perl", &[HASH]),
177        ("pine", &[HASH]),
178        ("po", &[HASH]),
179        ("praat", &[HASH]),
180        ("privoxy", &[HASH]),
181        ("ps1", &[HASH]),
182        ("psf", &[HASH]),
183        ("ptcap", &[HASH]),
184        ("puppet", &[HASH]),
185        ("pyrex", &[HASH]),
186        ("python", &[HASH]),
187        ("radiance", &[HASH]),
188        ("ratpoison", &[HASH]),
189        ("rego", &[HASH]),
190        ("remind", &[HASH]),
191        ("resolv", &[HASH]),
192        ("rib", &[HASH]),
193        ("robot", &[HASH]),
194        ("robots", &[HASH]),
195        ("rspec", &[HASH]),
196        ("ruby", &[HASH]),
197        ("scons", &[HASH]),
198        ("sdc", &[HASH]),
199        ("sed", &[HASH]),
200        ("sh", &[HASH]),
201        ("shader_test", &[HASH]),
202        ("sls", &[HASH]),
203        ("sm", &[HASH]),
204        ("snakemake", &[HASH]),
205        ("snippets", &[HASH]),
206        ("snnsnet", &[HASH]),
207        ("snnspat", &[HASH]),
208        ("snnsres", &[HASH]),
209        ("spec", &[HASH]),
210        ("squid", &[HASH]),
211        ("sshconfig", &[HASH]),
212        ("sshdconfig", &[HASH]),
213        ("tcl", &[HASH]),
214        ("tf", &[HASH]),
215        ("tidy", &[HASH]),
216        ("tli", &[HASH]),
217        ("tmux", &[HASH]),
218        ("toml", &[HASH]),
219        ("tsscl", &[HASH]),
220        ("ttl", &[HASH]),
221        ("tup", &[HASH]),
222        ("upstart", &[HASH]),
223        ("vgrindefs", &[HASH]),
224        ("vrml", &[HASH]),
225        ("wget", &[HASH]),
226        ("wml", &[HASH]),
227        ("xmath", &[HASH]),
228        ("yaml", &[HASH]),
229        ("r", &[HASH]),
230        ("renpy", &[HASH]),
231        ("htmlcheetah", DOUBLE_HASH),
232        ("velocity", DOUBLE_HASH),
233        ("webmacro", DOUBLE_HASH),
234        // Slash group
235        ("groff", const { &[pf(r"^\s*\#", r"\#", None)] }),
236        ("acedb", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
237        ("actionscript", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
238        ("asy", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
239        ("bind-named", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
240        ("cg", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
241        ("ch", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
242        ("clean", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
243        ("clipper", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
244        ("cs", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
245        ("cuda", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
246        ("d", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
247        ("dot", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
248        ("dylan", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
249        ("fx", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
250        ("glsl", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
251        ("go", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
252        ("groovy", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
253        ("h", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
254        ("haxe", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
255        ("hercules", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
256        ("hyphy", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
257        ("idl", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
258        ("ishd", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
259        ("java", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
260        ("javacc", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
261        ("javascript", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
262        ("javascript.jquery", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
263        ("json5", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
264        ("jsonc", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
265        ("jsonnet", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
266        ("kscript", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
267        ("lpc", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
268        ("mel", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
269        ("named", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
270        ("objc", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
271        ("objcpp", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
272        ("objj", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
273        ("ooc", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
274        ("pccts", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
275        ("php", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
276        ("pike", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
277        ("pilrc", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
278        ("plm", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
279        ("pov", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
280        ("processing", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
281        ("proto", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
282        ("rc", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
283        ("scala", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
284        ("scss", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
285        ("slice", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
286        ("stan", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
287        ("stp", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
288        ("supercollider", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
289        ("swift", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
290        ("systemverilog", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
291        ("tads", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
292        ("teak", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
293        ("tsalt", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
294        ("typescript", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
295        ("uc", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
296        ("vala", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
297        ("vera", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
298        ("verilog", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
299        (
300            "verilog_systemverilog",
301            &[SLASH_ASTERISK, ASTERISK, SLASHES],
302        ),
303        ("sass", &[SLASH_ASTERISK, ASTERISK, SLASHES]),
304        ("asciidoc", &[SLASHES]),
305        ("ats", &[SLASHES]),
306        ("bib", &[SLASHES]),
307        ("calibre", &[SLASHES]),
308        ("cocci", &[SLASHES]),
309        ("cypher", &[SLASHES]),
310        ("faust", &[SLASHES]),
311        ("fsharp", &[SLASHES]),
312        ("openroad", &[SLASHES]),
313        ("ox", &[SLASHES]),
314        ("pfmain", &[SLASHES]),
315        ("scilab", &[SLASHES]),
316        ("specman", &[SLASHES]),
317        ("xkb", &[SLASHES]),
318        ("c", &[SLASH_ASTERISK, ASTERISK, DOC_SLASHES, SLASHES]),
319        ("cpp", &[SLASH_ASTERISK, ASTERISK, DOC_SLASHES, SLASHES]),
320        (
321            "rust",
322            &[
323                SLASH_ASTERISK,
324                ASTERISK,
325                DOC_SLASHES,
326                INNER_DOC_SLASHES,
327                SLASHES,
328            ],
329        ),
330        ("zig", &[DOC_SLASHES, INNER_DOC_SLASHES, SLASHES]),
331        ("spectre", &[SLASHES, const { pf(r"^\s*\*", "*", None) }]),
332        ("emblem", &[const { pf(r"^\s*/", "/", None) }]),
333        ("aml", SLASH_ASTERISK_LINE),
334        ("natural", SLASH_ASTERISK_LINE),
335        ("vsejcl", SLASH_ASTERISK_LINE),
336        ("less", &[SLASH_ASTERISK]),
337        // Tag group
338        ("aspvbs", &[QUOTE]),
339        // Dash group
340        ("ada", &[DASHES]),
341        ("ahdl", &[DASHES]),
342        ("applescript", &[DASHES]),
343        ("asn", &[DASHES]),
344        ("cabal", &[DASHES]),
345        ("csp", &[DASHES]),
346        ("eiffel", &[DASHES]),
347        ("elm", &[DASHES]),
348        ("gdmo", &[DASHES]),
349        ("haskell", &[DASHES]),
350        ("hive", &[DASHES]),
351        ("idris", &[DASHES]),
352        ("lace", &[DASHES]),
353        ("lean", &[DASHES]),
354        ("lua", &[DASHES]),
355        ("mib", &[DASHES]),
356        ("occam", &[DASHES]),
357        ("sa", &[DASHES]),
358        ("sather", &[DASHES]),
359        ("sqlforms", &[DASHES]),
360        ("sqlj", &[DASHES]),
361        ("vhdl", &[DASHES]),
362        ("lhaskell", const { &[pf(r"^\s*>--", ">--", None)] }),
363        // Semicolon group
364        ("amiga", &[SEMICOLON]),
365        ("armasm", &[SEMICOLON]),
366        ("asm68k", &[SEMICOLON]),
367        ("autohotkey", &[SEMICOLON]),
368        ("asterisk", &[SEMICOLON]),
369        ("autoit", &[SEMICOLON]),
370        ("bindzone", &[SEMICOLON]),
371        ("clojure", &[SEMICOLON]),
372        ("def", &[SEMICOLON]),
373        ("dns", &[SEMICOLON]),
374        ("dosini", &[SEMICOLON]),
375        ("dracula", &[SEMICOLON]),
376        ("dsl", &[SEMICOLON]),
377        ("fasm", &[SEMICOLON]),
378        ("gitconfig", &[SEMICOLON]),
379        ("idlang", &[SEMICOLON]),
380        ("iss", &[SEMICOLON]),
381        ("jess", &[SEMICOLON]),
382        ("kix", &[SEMICOLON]),
383        ("llvm", &[SEMICOLON]),
384        ("masm", &[SEMICOLON]),
385        ("monk", &[SEMICOLON]),
386        ("nagios", &[SEMICOLON]),
387        ("nasm", &[SEMICOLON]),
388        ("ncf", &[SEMICOLON]),
389        ("newlisp", &[SEMICOLON]),
390        ("omnimark", &[SEMICOLON]),
391        ("pic", &[SEMICOLON]),
392        ("povini", &[SEMICOLON]),
393        ("racket", &[SEMICOLON]),
394        ("rebol", &[SEMICOLON]),
395        ("registry", &[SEMICOLON]),
396        ("scsh", &[SEMICOLON]),
397        ("skill", &[SEMICOLON]),
398        ("smith", &[SEMICOLON]),
399        ("ss", &[SEMICOLON]),
400        ("tags", &[SEMICOLON]),
401        ("tasm", &[SEMICOLON]),
402        ("winbatch", &[SEMICOLON]),
403        ("wvdial", &[SEMICOLON]),
404        ("z8a", &[SEMICOLON]),
405        ("ppwiz", &[SEMICOLON]),
406        ("asm", &[SEMICOLON, HASH]),
407        ("samba", &[SEMICOLON, HASH]),
408        ("ledger", &[SEMICOLON, HASH]),
409        ("closure", LISP),
410        ("fennel", LISP),
411        ("lisp", LISP),
412        ("m17ndb", LISP),
413        ("scheme", LISP),
414        // Keyword group
415        ("basic", &[QUOTE, REM]),
416        ("simula", &[PERCENT]),
417        ("cvs", const { &[pf("^CVS:", "^CVS:", None)] }),
418        ("dosbatch", &[REM, DOUBLE_COLON]),
419        ("m4", const { &[pf(r"^\s*dnl", "dnl", None)] }),
420        ("opl", &[REM]),
421        (
422            "texinfo",
423            const {
424                &[
425                    pf(r"^\s*@comment", "@comment", None),
426                    pf(r"^\s*@c", "@c", None),
427                ]
428            },
429        ),
430        // Percent group
431        ("abc", &[PERCENT]),
432        ("asp", &[PERCENT]),
433        ("bbx", &[PERCENT]),
434        ("bst", &[PERCENT]),
435        ("ist", &[PERCENT]),
436        ("lilypond", &[PERCENT]),
437        ("lprolog", &[PERCENT]),
438        ("lytex", &[PERCENT]),
439        ("map", &[PERCENT]),
440        ("matlab", &[PERCENT]),
441        ("pdf", &[PERCENT]),
442        ("postscr", &[PERCENT]),
443        ("ppd", &[PERCENT]),
444        ("slang", &[PERCENT]),
445        ("slrnrc", &[PERCENT]),
446        ("tex", &[PERCENT]),
447        ("texmf", &[PERCENT]),
448        ("txt2tags", &[PERCENT]),
449        ("virata", &[PERCENT]),
450        ("sile", &[PERCENT]),
451        ("erlang", &[PERCENT]),
452        // Double quote group
453        ("ave", &[QUOTE]),
454        ("elf", &[QUOTE]),
455        ("lscript", &[QUOTE]),
456        ("spin", &[QUOTE]),
457        ("vb", &[QUOTE]),
458        ("man", const { &[pf(r#"^\s\.""#, r#".""#, None)] }),
459        ("mandoc", DOT_ESCAPED_DQUOTE),
460        ("troff", DOT_ESCAPED_DQUOTE),
461        ("nroff", &[DQUOTE]),
462        ("st", &[DQUOTE]),
463        ("vim", &[DQUOTE]),
464        // Exclamation mark group
465        ("apdl", &[EXCLAMATION]),
466        ("fortran", &[EXCLAMATION]),
467        ("incar", &[EXCLAMATION]),
468        ("inform", &[EXCLAMATION]),
469        ("molpro", &[EXCLAMATION]),
470        ("poscar", &[EXCLAMATION]),
471        ("rgb", &[EXCLAMATION]),
472        ("sqr", &[EXCLAMATION]),
473        ("uc4", &[EXCLAMATION]),
474        ("uil", &[EXCLAMATION]),
475        ("vasp", &[EXCLAMATION]),
476        ("xdefaults", &[EXCLAMATION]),
477        ("xpm2", &[EXCLAMATION]),
478        (
479            "factor",
480            &[EXCLAMATION, const { pf(r"^\s*!#", "!#", None) }],
481        ),
482        // Dollar sign group
483        ("master", &[DOLLAR_SIGN]),
484        ("nastran", &[DOLLAR_SIGN]),
485        ("patran", &[DOLLAR_SIGN]),
486        ("sinda", &[DOLLAR_SIGN]),
487        ("spice", &[DOLLAR_SIGN]),
488        ("tak", &[DOLLAR_SIGN]),
489        ("trasys", &[DOLLAR_SIGN]),
490        ("dcl", const { &[pf(r"^\s*$!", "$!", None)] }),
491        // Mixed group
492        ("hocon", &[SLASHES, HASH]),
493        ("octave", &[PERCENT, HASH]),
494        ("plsql", &[DASHES]),
495        ("sql", &[DASHES]),
496        ("prolog", &[PERCENT]),
497        ("minizinc", &[PERCENT]),
498        ("sentinel", &[HASH]),
499        ("terraform", &[HASH]),
500        // Other
501        ("btm", &[DOUBLE_COLON]),
502        ("caos", &[ASTERISK_LINE]),
503        ("cterm", &[ASTERISK_LINE]),
504        ("form", &[ASTERISK_LINE]),
505        ("foxpro", &[ASTERISK_LINE]),
506        ("gams", &[ASTERISK_LINE]),
507        ("sicad", &[ASTERISK_LINE]),
508        ("snobol4", &[ASTERISK_LINE]),
509        ("focexec", const { &[pf(r"^\s*-\*", "-*", None)] }),
510        ("haml", &[const { pf(r"^\s*-#", "-#", None) }, SLASH]),
511        ("haml", &[SLASH, const { pf(r"^\s*/!", "/!", None) }]),
512    ])
513});