Skip to content

Commit

Permalink
filetype: support filetype detection via hashbang
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Nomarian authored and deepcube committed Jun 15, 2022
1 parent 901f52e commit 2e8c73b
Showing 1 changed file with 60 additions and 3 deletions.
63 changes: 60 additions & 3 deletions lua/plugins/filetype.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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" },
},
Expand Down Expand Up @@ -133,6 +136,7 @@ vis.ftdetect.filetypes = {
ext = { "%.fnl$" },
},
fish = {
utility = { "^fish$" },
ext = { "%.fish$" },
},
forth = {
Expand Down Expand Up @@ -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 = {
Expand Down Expand Up @@ -329,13 +333,15 @@ vis.ftdetect.filetypes = {
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 = {
Expand Down Expand Up @@ -409,6 +415,7 @@ vis.ftdetect.filetypes = {
ext = { "%.taskpaper$" },
},
tcl = {
utility = {"^tclsh$", "^jimsh$" },
ext = { "%.tcl$", "%.tk$" },
},
texinfo = {
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 2e8c73b

Please sign in to comment.