aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkhwerz <khwerz@gmail.com>2022-01-25 02:17:10 -0400
committerEvan Gates <evan.gates@gmail.com>2022-06-15 11:59:21 -0600
commit2e8c73b4882b4187f86c09ea7fcb2f5ca4ec792e (patch)
tree77e5afce59012a92d86630c37b0d3781f5173d7a
parent901f52e46d4e444ddc1f41a306287a9a2657b489 (diff)
downloadvis-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
-rw-r--r--lua/plugins/filetype.lua63
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