filetype: Set "groovy" for Jenkinsfile
[vis.git] / lua / plugins / filetype.lua
blob3cd234e0a8fb78ae32eb40832bab384ee702b62c
1 vis.ftdetect = {}
3 vis.ftdetect.ignoresuffixes = {
4 "~$", "%.orig$", "%.bak$", "%.old$", "%.new$"
7 vis.ftdetect.filetypes = {
8 actionscript = {
9 ext = { "%.as$", "%.asc$" },
11 ada = {
12 ext = { "%.adb$", "%.ads$" },
14 ansi_c = {
15 ext = { "%.c$", "%.C$", "%.h$" },
16 mime = { "text/x-c" },
18 antlr = {
19 ext = { "%.g$", "%.g4$" },
21 apdl = {
22 ext = { "%.ans$", "%.inp$", "%.mac$" },
24 apl = {
25 ext = { "%.apl$" }
27 applescript = {
28 ext = { "%.applescript$" },
30 asm = {
31 ext = { "%.asm$", "%.ASM$", "%.s$", "%.S$" },
33 asp = {
34 ext = { "%.asa$", "%.asp$", "%.hta$" },
36 autoit = {
37 ext = { "%.au3$", "%.a3x$" },
39 awk = {
40 ext = { "%.awk$" },
42 bash = {
43 ext = { "%.bash$", "%.csh$", "%.sh$", "%.zsh$" ,"^APKBUILD$", "%.ebuild$"},
44 mime = { "text/x-shellscript", "application/x-shellscript" },
46 batch = {
47 ext = { "%.bat$", "%.cmd$" },
49 bibtex = {
50 ext = { "%.bib$" },
52 boo = {
53 ext = { "%.boo$" },
55 caml = {
56 ext = { "%.caml$", "%.ml$", "%.mli$", "%.mll$", "%.mly$" },
58 chuck = {
59 ext = { "%.ck$" },
61 clojure = {
62 ext = { "%.clj$", "%.cljc$", "%.cljs$", "%.edn$" }
64 cmake = {
65 ext = { "%.cmake$", "%.cmake.in$", "%.ctest$", "%.ctest.in$" },
67 coffeescript = {
68 ext = { "%.coffee$" },
69 mime = { "text/x-coffee" },
71 cpp = {
72 ext = { "%.cpp$", "%.cxx$", "%.c++$", "%.cc$", "%.hh$", "%.hpp$", "%.hxx$", "%.h++$" },
73 mime = { "text/x-c++" },
75 crontab = {
76 ext = { "^crontab.*$" },
77 cmd = { "set savemethod inplace" },
79 crystal = {
80 ext = { "%.cr$" },
82 csharp = {
83 ext = { "%.cs$" },
85 css = {
86 ext = { "%.css$" },
87 mime = { "text/x-css" },
89 cuda = {
90 ext = { "%.cu$", "%.cuh$" },
92 dart = {
93 ext = { "%.dart$" },
95 desktop = {
96 ext = { "%.desktop$" },
98 diff = {
99 ext = { "%.diff$", "%.patch$", "%.rej$" },
101 dmd = {
102 ext = { "%.d$", "%.di$" },
104 dockerfile = {
105 ext = { "^Dockerfile$", "%.Dockerfile$" },
107 dot = {
108 ext = { "%.dot$" },
110 dsv = {
111 ext = { "^group$", "^gshadow$", "^passwd$", "^shadow$" },
113 eiffel = {
114 ext = { "%.e$", "%.eif$" },
116 elixir = {
117 ext = { "%.ex$", "%.exs$" },
119 elm = {
120 ext = { "%.elm$" },
122 erlang = {
123 ext = { "%.erl$", "%.hrl$" },
125 fantom = {
126 ext = { "%.fan$" },
128 faust = {
129 ext = { "%.dsp$" },
131 fennel = {
132 ext = { "%.fnl$" },
134 fish = {
135 ext = { "%.fish$" },
137 forth = {
138 ext = { "%.forth$", "%.frt$", "%.fs$", "%.fth$" },
140 fortran = {
141 ext = { "%.f$", "%.for$", "%.ftn$", "%.fpp$", "%.f77$", "%.f90$", "%.f95$", "%.f03$", "%.f08$" },
143 fsharp = {
144 ext = { "%.fs$" },
146 fstab = {
147 ext = { "fstab" },
149 gap = {
150 ext = { "%.g$", "%.gd$", "%.gi$", "%.gap$" },
152 gemini = {
153 ext = { "%.gmi" },
154 mime = { "text/gemini" },
156 gettext = {
157 ext = { "%.po$", "%.pot$" },
159 gherkin = {
160 ext = { "%.feature$" },
162 ['git-commit'] = {
163 ext = { "^COMMIT_EDITMSG$" },
164 cmd = { "set colorcolumn 72" },
166 ['git-rebase'] = {
167 ext = { "git%-rebase%-todo" },
169 glsl = {
170 ext = { "%.glslf$", "%.glslv$" },
172 gnuplot = {
173 ext = { "%.dem$", "%.plt$" },
175 go = {
176 ext = { "%.go$" },
178 groovy = {
179 ext = { "%.groovy$", "%.gvy$", "^Jenkinsfile$" },
181 gtkrc = {
182 ext = { "%.gtkrc$" },
184 haskell = {
185 ext = { "%.hs$" },
186 mime = { "text/x-haskell" },
188 html = {
189 ext = { "%.htm$", "%.html$", "%.shtm$", "%.shtml$", "%.xhtml$" },
190 mime = { "text/x-html" },
192 icon = {
193 ext = { "%.icn$" },
195 idl = {
196 ext = { "%.idl$", "%.odl$" },
198 inform = {
199 ext = { "%.inf$", "%.ni$" },
201 ini = {
202 ext = { "%.cfg$", "%.cnf$", "%.conf$", "%.inf$", "%.ini$", "%.reg$" },
204 io_lang = {
205 ext = { "%.io$" },
207 java = {
208 ext = { "%.bsh$", "%.java$" },
210 javascript = {
211 ext = { "%.cjs$", "%.js$", "%.jsfl$", "%.mjs$", "%.ts$" },
213 json = {
214 ext = { "%.json$" },
215 mime = { "text/x-json" },
217 jsp = {
218 ext = { "%.jsp$" },
220 julia = {
221 ext = { "%.jl$" },
223 latex = {
224 ext = { "%.bbl$", "%.cls$", "%.dtx$", "%.ins$", "%.ltx$", "%.tex$", "%.sty$" },
225 mime = { "text/x-tex" },
227 ledger = {
228 ext = { "%.ledger$", "%.journal$" },
230 less = {
231 ext = { "%.less$" },
233 lilypond = {
234 ext = { "%.ily$", "%.ly$" },
236 lisp = {
237 ext = { "%.cl$", "%.el$", "%.lisp$", "%.lsp$" },
238 mime = { "text/x-lisp" },
240 litcoffee = {
241 ext = { "%.litcoffee$" },
243 logtalk = {
244 ext = { "%.lgt$" },
246 lua = {
247 ext = { "%.lua$" },
248 mime = { "text/x-lua" },
250 makefile = {
251 ext = { "%.iface$", "%.mak$", "%.mk$", "GNUmakefile", "makefile", "Makefile" },
252 mime = { "text/x-makefile" },
253 detect = function(_, data)
254 return data:match("^#!/usr/bin/make")
257 man = {
258 ext = {
259 "%.1$", "%.2$", "%.3$", "%.4$", "%.5$", "%.6$", "%.7$",
260 "%.8$", "%.9$", "%.1x$", "%.2x$", "%.3x$", "%.4x$",
261 "%.5x$", "%.6x$", "%.7x$", "%.8x$", "%.9x$"
264 markdown = {
265 ext = { "%.md$", "%.markdown$" },
266 mime = { "text/x-markdown" },
268 meson = {
269 ext = { "^meson%.build$" },
271 moonscript = {
272 ext = { "%.moon$" },
273 mime = { "text/x-moon" },
275 myrddin = {
276 ext = { "%.myr$" },
278 nemerle = {
279 ext = { "%.n$" },
281 networkd = {
282 ext = { "%.link$", "%.network$", "%.netdev$" },
284 nim = {
285 ext = { "%.nim$" },
287 nsis = {
288 ext = { "%.nsh$", "%.nsi$", "%.nsis$" },
290 objective_c = {
291 ext = { "%.m$", "%.mm$", "%.objc$" },
292 mime = { "text/x-objc" },
294 pascal = {
295 ext = { "%.dpk$", "%.dpr$", "%.p$", "%.pas$" },
297 perl = {
298 ext = { "%.al$", "%.perl$", "%.pl$", "%.pm$", "%.pod$" },
299 mime = { "text/x-perl" },
301 php = {
302 ext = { "%.inc$", "%.php$", "%.php3$", "%.php4$", "%.phtml$" },
304 pico8 = {
305 ext = { "%.p8$" },
307 pike = {
308 ext = { "%.pike$", "%.pmod$" },
310 pkgbuild = {
311 ext = { "^PKGBUILD$" },
313 pony = {
314 ext = { "%.pony$" },
316 powershell = {
317 ext = { "%.ps1$" },
319 prolog = {
320 ext = { "%.pl$", "%.pro$", "%.prolog$" },
322 props = {
323 ext = { "%.props$", "%.properties$" },
325 protobuf = {
326 ext = { "%.proto$" },
328 ps = {
329 ext = { "%.eps$", "%.ps$" },
331 pure = {
332 ext = { "%.pure$" },
334 python = {
335 ext = { "%.sc$", "%.py$", "%.pyw$" },
336 mime = { "text/x-python" },
338 reason = {
339 ext = { "%.re$" },
341 rc = {
342 ext = { "%.rc$", "%.es$" },
344 rebol = {
345 ext = { "%.r$", "%.reb$" },
347 rest = {
348 ext = { "%.rst$" },
350 rexx = {
351 ext = { "%.orx$", "%.rex$" },
353 rhtml = {
354 ext = { "%.erb$", "%.rhtml$" },
356 routeros = {
357 ext = { "%.rsc" },
358 detect = function(_, data)
359 return data:match("^#.* by RouterOS")
362 rstats = {
363 ext = { "%.R$", "%.Rout$", "%.Rhistory$", "%.Rt$", "Rout.save", "Rout.fail" },
365 ruby = {
366 ext = { "%.Rakefile$", "%.rake$", "%.rb$", "%.rbw$", "^Vagrantfile$" },
367 mime = { "text/x-ruby" },
369 rust = {
370 ext = { "%.rs$" },
371 mime = { "text/x-rust" },
373 sass = {
374 ext = { "%.sass$", "%.scss$" },
375 mime = { "text/x-sass", "text/x-scss" },
377 scala = {
378 ext = { "%.scala$" },
379 mime = { "text/x-scala" },
381 scheme = {
382 ext = { "%.rkt$", "%.sch$", "%.scm$", "%.sld$", "%.sls$", "%.ss$" },
384 smalltalk = {
385 ext = { "%.changes$", "%.st$", "%.sources$" },
387 sml = {
388 ext = { "%.sml$", "%.fun$", "%.sig$" },
390 snobol4 = {
391 ext = { "%.sno$", "%.SNO$" },
393 spin = {
394 ext = { "%.spin$" }
396 sql= {
397 ext = { "%.ddl$", "%.sql$" },
399 strace = {
400 detect = function(_, data)
401 return data:match("^execve%(")
404 systemd = {
405 ext = {
406 "%.automount$", "%.device$", "%.mount$", "%.path$",
407 "%.scope$", "%.service$", "%.slice$", "%.socket$",
408 "%.swap$", "%.target$", "%.timer$"
411 taskpaper = {
412 ext = { "%.taskpaper$" },
414 tcl = {
415 ext = { "%.tcl$", "%.tk$" },
417 texinfo = {
418 ext = { "%.texi$" },
420 text = {
421 ext = { "%.txt$" },
422 -- Do *not* list mime "text/plain" here, it is covered below,
423 -- see 'try text lexer as a last resort'
425 toml = {
426 ext = { "%.toml$" },
428 vala = {
429 ext = { "%.vala$" }
431 vb = {
432 ext = {
433 "%.asa$", "%.bas$", "%.ctl$", "%.dob$",
434 "%.dsm$", "%.dsr$", "%.frm$", "%.pag$", "%.vb$",
435 "%.vba$", "%.vbs$"
438 vcard = {
439 ext = { "%.vcf$", "%.vcard$" },
441 verilog = {
442 ext = { "%.v$", "%.ver$", "%.sv$" },
444 vhdl = {
445 ext = { "%.vh$", "%.vhd$", "%.vhdl$" },
447 wsf = {
448 ext = { "%.wsf$" },
450 xs = {
451 ext = { "%.xs$", "^%.xsin$", "^%.xsrc$" },
453 xml = {
454 ext = { "%.dtd$", "%.plist$", "%.svg$", "%.xml$", "%.xsd$", "%.xsl$", "%.xslt$", "%.xul$" },
456 xtend = {
457 ext = {"%.xtend$" },
459 yaml = {
460 ext = { "%.yaml$", "%.yml$" },
461 mime = { "text/x-yaml" },
463 zig = {
464 ext = { "%.zig$" },
468 vis.events.subscribe(vis.events.WIN_OPEN, function(win)
470 local set_filetype = function(syntax, filetype)
471 for _, cmd in pairs(filetype.cmd or {}) do
472 vis:command(cmd)
474 win:set_syntax(syntax)
477 local name = win.file.name
478 -- remove ignored suffixes from filename
479 local sanitizedfn = name
480 if sanitizedfn ~= nil then
481 sanitizedfn = sanitizedfn:gsub('^.*/', '')
482 repeat
483 local changed = false
484 for _, pattern in pairs(vis.ftdetect.ignoresuffixes) do
485 local start = sanitizedfn:find(pattern)
486 if start then
487 sanitizedfn = sanitizedfn:sub(1, start-1)
488 changed = true
491 until not changed
494 -- detect filetype by filename ending with a configured extension
495 if sanitizedfn ~= nil then
496 for lang, ft in pairs(vis.ftdetect.filetypes) do
497 for _, pattern in pairs(ft.ext or {}) do
498 if sanitizedfn:match(pattern) then
499 set_filetype(lang, ft)
500 return
506 -- run file(1) to determine mime type
507 local mime
508 if name ~= nil then
509 local file = io.popen(string.format("file -bL --mime-type -- '%s'", name:gsub("'", "'\\''")))
510 if file then
511 mime = file:read('*all')
512 file:close()
513 if mime then
514 mime = mime:gsub('%s*$', '')
516 if mime and #mime > 0 then
517 for lang, ft in pairs(vis.ftdetect.filetypes) do
518 for _, ft_mime in pairs(ft.mime or {}) do
519 if mime == ft_mime then
520 set_filetype(lang, ft)
521 return
529 -- pass first few bytes of file to custom file type detector functions
530 local file = win.file
531 local data = file:content(0, 256)
532 if data and #data > 0 then
533 for lang, ft in pairs(vis.ftdetect.filetypes) do
534 if type(ft.detect) == 'function' and ft.detect(file, data) then
535 set_filetype(lang, ft)
536 return
541 -- try text lexer as a last resort
542 if (mime or 'text/plain'):match('^text/.+$') then
543 set_filetype('text', vis.ftdetect.filetypes.text)
544 return
547 win:set_syntax(nil)
548 end)