This repository has been archived on 2023-10-17. You can view files and clone it, but cannot push or open issues or pull requests.
dotfiles/.config/vis/plugins/filetype.lua

610 lines
12 KiB
Lua

vis.ftdetect = {}
vis.ftdetect.ignoresuffixes = {
"~$", "%.orig$", "%.bak$", "%.old$", "%.new$"
}
vis.ftdetect.filetypes = {
actionscript = {
ext = { "%.as$", "%.asc$" },
},
ada = {
ext = { "%.adb$", "%.ads$" },
},
ansi_c = {
ext = { "%.c$", "%.C$", "%.h$" },
mime = { "text/x-c" },
},
antlr = {
ext = { "%.g$", "%.g4$" },
},
apdl = {
ext = { "%.ans$", "%.inp$", "%.mac$" },
},
apl = {
ext = { "%.apl$" }
},
applescript = {
ext = { "%.applescript$" },
},
asm = {
ext = { "%.asm$", "%.ASM$", "%.s$", "%.S$" },
},
asp = {
ext = { "%.asa$", "%.asp$", "%.hta$" },
},
autoit = {
ext = { "%.au3$", "%.a3x$" },
},
awk = {
hashbang = { "^/usr/bin/[mng]awk%s+%-f" },
utility = { "^[mgn]?awk$", "^goawk$" },
ext = { "%.awk$" },
},
bash = {
utility = { "^[db]ash$", "^sh$","^t?csh$","^zsh$" },
ext = { "%.bash$", "%.csh$", "%.sh$", "%.zsh$" ,"^APKBUILD$", "%.ebuild$", "^.bashrc$", "^.bash_profile$" },
mime = { "text/x-shellscript", "application/x-shellscript" },
},
batch = {
ext = { "%.bat$", "%.cmd$" },
},
bibtex = {
ext = { "%.bib$" },
},
boo = {
ext = { "%.boo$" },
},
caml = {
ext = { "%.caml$", "%.ml$", "%.mli$", "%.mll$", "%.mly$" },
},
chuck = {
ext = { "%.ck$" },
},
clojure = {
ext = { "%.clj$", "%.cljc$", "%.cljs$", "%.edn$" }
},
cmake = {
ext = { "%.cmake$", "%.cmake.in$", "%.ctest$", "%.ctest.in$" },
},
coffeescript = {
ext = { "%.coffee$" },
mime = { "text/x-coffee" },
},
cpp = {
ext = { "%.cpp$", "%.cxx$", "%.c++$", "%.cc$", "%.hh$", "%.hpp$", "%.hxx$", "%.h++$" },
mime = { "text/x-c++" },
},
crontab = {
ext = { "^crontab.*$" },
cmd = { "set savemethod inplace" },
},
crystal = {
ext = { "%.cr$" },
},
csharp = {
ext = { "%.cs$" },
},
css = {
ext = { "%.css$" },
mime = { "text/x-css" },
},
cuda = {
ext = { "%.cu$", "%.cuh$" },
},
dart = {
ext = { "%.dart$" },
},
desktop = {
ext = { "%.desktop$" },
},
diff = {
ext = { "%.diff$", "%.patch$", "%.rej$", "^COMMIT_EDITMSG$" },
cmd = { "set colorcolumn 72" },
},
dmd = {
ext = { "%.d$", "%.di$" },
},
dockerfile = {
ext = { "^Dockerfile$", "%.Dockerfile$" },
},
dot = {
ext = { "%.dot$" },
},
dsv = {
ext = { "^group$", "^gshadow$", "^passwd$", "^shadow$" },
},
eiffel = {
ext = { "%.e$", "%.eif$" },
},
elixir = {
ext = { "%.ex$", "%.exs$" },
},
elm = {
ext = { "%.elm$" },
},
erlang = {
ext = { "%.erl$", "%.hrl$" },
},
fantom = {
ext = { "%.fan$" },
},
faust = {
ext = { "%.dsp$" },
},
fennel = {
ext = { "%.fnl$" },
},
fish = {
utility = { "^fish$" },
ext = { "%.fish$" },
},
forth = {
ext = { "%.forth$", "%.frt$", "%.fs$", "%.fth$" },
},
fortran = {
ext = { "%.f$", "%.for$", "%.ftn$", "%.fpp$", "%.f77$", "%.f90$", "%.f95$", "%.f03$", "%.f08$" },
},
fsharp = {
ext = { "%.fs$" },
},
fstab = {
ext = { "fstab" },
},
gap = {
ext = { "%.g$", "%.gd$", "%.gi$", "%.gap$" },
},
gemini = {
ext = { "%.gmi" },
mime = { "text/gemini" },
},
gettext = {
ext = { "%.po$", "%.pot$" },
},
gherkin = {
ext = { "%.feature$" },
},
['git-rebase'] = {
ext = { "git%-rebase%-todo" },
},
glsl = {
ext = { "%.glslf$", "%.glslv$" },
},
gnuplot = {
ext = { "%.dem$", "%.plt$" },
},
go = {
ext = { "%.go$" },
},
groovy = {
ext = { "%.groovy$", "%.gvy$", "^Jenkinsfile$" },
},
gtkrc = {
ext = { "%.gtkrc$" },
},
hare = {
ext = { "%.ha$" }
},
haskell = {
ext = { "%.hs$" },
mime = { "text/x-haskell" },
},
html = {
ext = { "%.htm$", "%.html$", "%.shtm$", "%.shtml$", "%.xhtml$" },
mime = { "text/x-html" },
},
icon = {
ext = { "%.icn$" },
},
idl = {
ext = { "%.idl$", "%.odl$" },
},
inform = {
ext = { "%.inf$", "%.ni$" },
},
ini = {
ext = { "%.cfg$", "%.cnf$", "%.conf$", "%.inf$", "%.ini$", "%.reg$" },
},
io_lang = {
ext = { "%.io$" },
},
java = {
ext = { "%.bsh$", "%.java$" },
},
javascript = {
ext = { "%.cjs$", "%.js$", "%.jsfl$", "%.mjs$", "%.ts$", "%.jsx$", "%.tsx$" },
},
json = {
ext = { "%.json$" },
mime = { "text/x-json" },
},
jsp = {
ext = { "%.jsp$" },
},
julia = {
ext = { "%.jl$" },
},
latex = {
ext = { "%.bbl$", "%.cls$", "%.dtx$", "%.ins$", "%.ltx$", "%.tex$", "%.sty$" },
mime = { "text/x-tex" },
},
ledger = {
ext = { "%.ledger$", "%.journal$" },
},
less = {
ext = { "%.less$" },
},
lilypond = {
ext = { "%.ily$", "%.ly$" },
},
lisp = {
ext = { "%.cl$", "%.el$", "%.lisp$", "%.lsp$" },
mime = { "text/x-lisp" },
},
litcoffee = {
ext = { "%.litcoffee$" },
},
logtalk = {
ext = { "%.lgt$" },
},
lua = {
utility = {"^lua%-?5?%d?$", "^lua%-?5%.%d$" },
ext = { "%.lua$" },
mime = { "text/x-lua" },
},
makefile = {
hashbang = {"^#!/usr/bin/make"},
utility = {"^make$"},
ext = { "%.iface$", "%.mak$", "%.mk$", "GNUmakefile", "makefile", "Makefile" },
mime = { "text/x-makefile" },
},
man = {
ext = {
"%.1$", "%.2$", "%.3$", "%.4$", "%.5$", "%.6$", "%.7$",
"%.8$", "%.9$", "%.1x$", "%.2x$", "%.3x$", "%.4x$",
"%.5x$", "%.6x$", "%.7x$", "%.8x$", "%.9x$"
},
},
markdown = {
ext = { "%.md$", "%.markdown$" },
mime = { "text/x-markdown" },
},
meson = {
ext = { "^meson%.build$" },
},
moonscript = {
ext = { "%.moon$" },
mime = { "text/x-moon" },
},
myrddin = {
ext = { "%.myr$" },
},
nemerle = {
ext = { "%.n$" },
},
networkd = {
ext = { "%.link$", "%.network$", "%.netdev$" },
},
nim = {
ext = { "%.nim$" },
},
nsis = {
ext = { "%.nsh$", "%.nsi$", "%.nsis$" },
},
objective_c = {
ext = { "%.m$", "%.mm$", "%.objc$" },
mime = { "text/x-objc" },
},
pascal = {
ext = { "%.dpk$", "%.dpr$", "%.p$", "%.pas$" },
},
perl = {
ext = { "%.al$", "%.perl$", "%.pl$", "%.pm$", "%.pod$" },
mime = { "text/x-perl" },
},
php = {
ext = { "%.inc$", "%.php$", "%.php3$", "%.php4$", "%.phtml$" },
},
pico8 = {
ext = { "%.p8$" },
},
pike = {
ext = { "%.pike$", "%.pmod$" },
},
pkgbuild = {
ext = { "^PKGBUILD$", "%.PKGBUILD$" },
},
pony = {
ext = { "%.pony$" },
},
powershell = {
ext = { "%.ps1$" },
},
prolog = {
ext = { "%.pl$", "%.pro$", "%.prolog$" },
},
props = {
ext = { "%.props$", "%.properties$" },
},
protobuf = {
ext = { "%.proto$" },
},
ps = {
ext = { "%.eps$", "%.ps$" },
},
pure = {
ext = { "%.pure$" },
},
python = {
utility = { "^python%d?" },
ext = { "%.sc$", "%.py$", "%.pyw$" },
mime = { "text/x-python", "text/x-script.python" },
},
reason = {
ext = { "%.re$" },
},
rc = {
utility = {"^rc$"},
ext = { "%.rc$", "%.es$" },
},
rebol = {
ext = { "%.r$", "%.reb$" },
},
rest = {
ext = { "%.rst$" },
},
rexx = {
ext = { "%.orx$", "%.rex$" },
},
rhtml = {
ext = { "%.erb$", "%.rhtml$" },
},
routeros = {
ext = { "%.rsc" },
detect = function(_, data)
return data:match("^#.* by RouterOS")
end
},
rstats = {
ext = { "%.R$", "%.Rout$", "%.Rhistory$", "%.Rt$", "Rout.save", "Rout.fail" },
},
ruby = {
ext = { "%.Rakefile$", "%.rake$", "%.rb$", "%.rbw$", "^Vagrantfile$" },
mime = { "text/x-ruby" },
},
rust = {
ext = { "%.rs$" },
mime = { "text/x-rust" },
},
sass = {
ext = { "%.sass$", "%.scss$" },
mime = { "text/x-sass", "text/x-scss" },
},
scala = {
ext = { "%.scala$" },
mime = { "text/x-scala" },
},
scheme = {
ext = { "%.rkt$", "%.sch$", "%.scm$", "%.sld$", "%.sls$", "%.ss$" },
},
smalltalk = {
ext = { "%.changes$", "%.st$", "%.sources$" },
},
sml = {
ext = { "%.sml$", "%.fun$", "%.sig$" },
},
snobol4 = {
ext = { "%.sno$", "%.SNO$" },
},
spin = {
ext = { "%.spin$" }
},
sql= {
ext = { "%.ddl$", "%.sql$" },
},
strace = {
detect = function(_, data)
return data:match("^execve%(")
end
},
systemd = {
ext = {
"%.automount$", "%.device$", "%.mount$", "%.path$",
"%.scope$", "%.service$", "%.slice$", "%.socket$",
"%.swap$", "%.target$", "%.timer$"
},
},
taskpaper = {
ext = { "%.taskpaper$" },
},
tcl = {
utility = {"^tclsh$", "^jimsh$" },
ext = { "%.tcl$", "%.tk$" },
},
texinfo = {
ext = { "%.texi$" },
},
text = {
ext = { "%.txt$" },
-- Do *not* list mime "text/plain" here, it is covered below,
-- see 'try text lexer as a last resort'
},
toml = {
ext = { "%.toml$" },
},
vala = {
ext = { "%.vala$" }
},
vb = {
ext = {
"%.asa$", "%.bas$", "%.ctl$", "%.dob$",
"%.dsm$", "%.dsr$", "%.frm$", "%.pag$", "%.vb$",
"%.vba$", "%.vbs$"
},
},
vcard = {
ext = { "%.vcf$", "%.vcard$" },
},
verilog = {
ext = { "%.v$", "%.ver$", "%.sv$" },
},
vhdl = {
ext = { "%.vh$", "%.vhd$", "%.vhdl$" },
},
wsf = {
ext = { "%.wsf$" },
},
xs = {
ext = { "%.xs$", "^%.xsin$", "^%.xsrc$" },
},
xml = {
ext = {
"%.dtd$", "%.glif$", "%.plist$", "%.svg$", "%.xml$",
"%.xsd$", "%.xsl$", "%.xslt$", "%.xul$"
},
},
xtend = {
ext = {"%.xtend$" },
},
yaml = {
ext = { "%.yaml$", "%.yml$" },
mime = { "text/x-yaml" },
},
zig = {
ext = { "%.zig$" },
},
}
vis.events.subscribe(vis.events.WIN_OPEN, function(win)
local set_filetype = function(syntax, filetype)
for _, cmd in pairs(filetype.cmd or {}) do
vis:command(cmd)
end
win:set_syntax(syntax)
end
local name = win.file.name
-- remove ignored suffixes from filename
local sanitizedfn = name
if sanitizedfn ~= nil then
sanitizedfn = sanitizedfn:gsub('^.*/', '')
repeat
local changed = false
for _, pattern in pairs(vis.ftdetect.ignoresuffixes) do
local start = sanitizedfn:find(pattern)
if start then
sanitizedfn = sanitizedfn:sub(1, start-1)
changed = true
end
end
until not changed
end
-- detect filetype by filename ending with a configured extension
if sanitizedfn ~= nil then
for lang, ft in pairs(vis.ftdetect.filetypes) do
for _, pattern in pairs(ft.ext or {}) do
if sanitizedfn:match(pattern) then
set_filetype(lang, ft)
return
end
end
end
end
-- run file(1) to determine mime type
local mime
if name ~= nil then
local file = io.popen(string.format("file -bL --mime-type -- '%s'", name:gsub("'", "'\\''")))
if file then
mime = file:read('*all')
file:close()
if mime then
mime = mime:gsub('%s*$', '')
end
if mime and #mime > 0 then
for lang, ft in pairs(vis.ftdetect.filetypes) do
for _, ft_mime in pairs(ft.mime or {}) do
if mime == ft_mime then
set_filetype(lang, ft)
return
end
end
end
end
end
end
-- pass first few bytes of file to custom file type detector functions
local file = win.file
local data = file:content(0, 256)
if data and #data > 0 then
for lang, ft in pairs(vis.ftdetect.filetypes) do
if type(ft.detect) == 'function' and ft.detect(file, data) then
set_filetype(lang, ft)
return
end
end
--[[ hashbang check
hashbangs only have command <SPACE> argument
if /env, find utility in args
discard first arg if /-[^S]*S/; and all subsequent /=/
NOTE: this means you can't have a command with /^-|=/
return first field, which should be the utility.
NOTE: long-options unsupported
--]]
local fullhb, utility = data:match"^#![ \t]*(/+[^/\n]+[^\n]*)"
if fullhb then
local i, field = 1, {}
for m in fullhb:gmatch"%g+" do field[i],i = m,i+1 end
-- NOTE: executables should not have a space (or =, see below)
if field[1]:match"/env$" then
table.remove(field,1)
-- it is assumed that the first argument are short options, with -S inside
if string.match(field[1] or "", "^%-[^S-]*S") then -- -S found
table.remove(field,1)
-- skip all name=value
while string.match(field[1] or "","=") do
table.remove(field,1)
end
-- (hopefully) whatever is left in field[1] should be the utility or nil
end
end
utility = string.match(field[1] or "", "[^/]+$") -- remove filepath
end
local function searcher(tbl, subject)
for i, pattern in ipairs(tbl or {}) do
if string.match(subject, pattern) then
return true
end
end
return false
end
if utility or fullhb then
for lang, ft in pairs(vis.ftdetect.filetypes) do
if
utility and searcher(ft.utility, utility)
or
fullhb and searcher(ft.hashbang, fullhb)
then
set_filetype(lang, ft)
return
end
end
end
end
-- try text lexer as a last resort
if (mime or 'text/plain'):match('^text/.+$') then
set_filetype('text', vis.ftdetect.filetypes.text)
return
end
win:set_syntax(nil)
end)