diff options
| author | khwerz <khwerz@gmail.com> | 2022-01-25 02:17:10 -0400 |
|---|---|---|
| committer | Evan Gates <evan.gates@gmail.com> | 2022-06-15 11:59:21 -0600 |
| commit | 2e8c73b4882b4187f86c09ea7fcb2f5ca4ec792e (patch) | |
| tree | 77e5afce59012a92d86630c37b0d3781f5173d7a /lua/plugins/filetype.lua | |
| parent | 901f52e46d4e444ddc1f41a306287a9a2657b489 (diff) | |
| download | vis-2e8c73b4882b4187f86c09ea7fcb2f5ca4ec792e.tar.gz vis-2e8c73b4882b4187f86c09ea7fcb2f5ca4ec792e.tar.xz | |
filetype: support filetype detection via hashbang
add 2 tables, hashbang and utility for vis.ftdetect.filetypes.<lang>
fetch utility from /usr/bin/env args (mostly)
Support -S for /usr/bin/env args, discard variables=value args
Diffstat (limited to 'lua/plugins/filetype.lua')
| -rw-r--r-- | lua/plugins/filetype.lua | 63 |
1 files changed, 60 insertions, 3 deletions
diff --git a/lua/plugins/filetype.lua b/lua/plugins/filetype.lua index 18767ec..cc1fd05 100644 --- a/lua/plugins/filetype.lua +++ b/lua/plugins/filetype.lua @@ -37,9 +37,12 @@ vis.ftdetect.filetypes = { 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$"}, mime = { "text/x-shellscript", "application/x-shellscript" }, }, @@ -133,6 +136,7 @@ vis.ftdetect.filetypes = { ext = { "%.fnl$" }, }, fish = { + utility = { "^fish$" }, ext = { "%.fish$" }, }, forth = { @@ -241,15 +245,15 @@ vis.ftdetect.filetypes = { 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" }, - detect = function(_, data) - return data:match("^#!/usr/bin/make") - end }, man = { ext = { @@ -329,6 +333,7 @@ vis.ftdetect.filetypes = { ext = { "%.pure$" }, }, python = { + utility = { "^python%d?" }, ext = { "%.sc$", "%.py$", "%.pyw$" }, mime = { "text/x-python", "text/x-script.python" }, }, @@ -336,6 +341,7 @@ vis.ftdetect.filetypes = { ext = { "%.re$" }, }, rc = { + utility = {"^rc$"}, ext = { "%.rc$", "%.es$" }, }, rebol = { @@ -409,6 +415,7 @@ vis.ftdetect.filetypes = { ext = { "%.taskpaper$" }, }, tcl = { + utility = {"^tclsh$", "^jimsh$" }, ext = { "%.tcl$", "%.tk$" }, }, texinfo = { @@ -536,6 +543,56 @@ vis.events.subscribe(vis.events.WIN_OPEN, function(win) 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 |
