vis-lint

vis plugin for linting code
git clone anongit@rnpnr.xyz:vis-lint.git
Log | Files | Refs | Feed | README | LICENSE

init.lua (3155B)


      1 -- See LICENSE for copyright details
      2 local lint = {}
      3 
      4 lint.linters = {}
      5 lint.linters["bash"]   = {"shellcheck -"}
      6 lint.linters["json"]   = {"jq"}
      7 lint.linters["lua"]    = {"luacheck --no-color -"}
      8 lint.linters["man"]    = {"mandoc -T lint"}
      9 lint.linters["meson"]  = {"muon check -"}
     10 lint.linters["python"] = {"black --quiet --check -", "isort --check -"}
     11 lint.linters["rust"]   = {"rustfmt --check", "clippy-driver -"}
     12 
     13 lint.fixers = {}
     14 lint.fixers["c"]       = {"clang-format -fallback-style=none"}
     15 lint.fixers["cpp"]     = {"clang-format -fallback-style=none"}
     16 lint.fixers["json"]    = {"jq"}
     17 lint.fixers["meson"]   = {"muon fmt -"}
     18 lint.fixers["python"]  = {"black -", "isort -"}
     19 lint.fixers["rust"]    = {"rustfmt"}
     20 
     21 lint.log = {}
     22 lint.log.INFO   = 1
     23 lint.log.ERROR  = 2
     24 lint.log.OUTPUT = 3
     25 
     26 lint.logger = function(str, level)
     27 	if level == lint.log.INFO then
     28 		vis:info(str)
     29 	else
     30 		vis:message(str)
     31 	end
     32 end
     33 
     34 local run_on_file = function(cmd, file, range, modify)
     35 	if range == nil or range.finish - range.start <= 1 then
     36 		range = {start = 0, finish = file.size}
     37 	end
     38 	local ret, ostr, estr = vis:pipe(file, range, cmd)
     39 	if ostr ~= nil or estr ~= nil then
     40 		if (modify and ostr) then
     41 			local pos = vis.win.selection.pos
     42 			file:delete(range.start, range.finish)
     43 			file:insert(range.start, ostr)
     44 			vis.win.selection.pos = pos
     45 		else
     46 			if ostr then lint.logger(ostr, lint.log.OUTPUT) end
     47 		end
     48 		if estr then lint.logger(estr, lint.log.ERROR) end
     49 		vis:redraw()
     50 	end
     51 	return ret
     52 end
     53 
     54 local run_actions_on_file = function(actions, file, range, modify)
     55 	local cmds = actions[vis.win.syntax]
     56 	if cmds == nil or #cmds == 0 then
     57 		lint.logger("vis-lint: action not defined for vis.win.syntax = "
     58 			.. (vis.win.syntax or "undefined"), lint.log.INFO)
     59 		return
     60 	end
     61 	-- print this to separate different outputs in the message buffer
     62 	local prefix = "--- "
     63 	lint.logger(prefix .. "vis-lint: (" .. os.date() .. ")")
     64 	local all_succeeded = true
     65 	local failure_count = 0
     66 	for _, cmd in ipairs(cmds) do
     67 		lint.logger(prefix .. "piping "
     68 			.. (file.name or "buffer")
     69 			.. (range and "<" .. range.start ..  "," .. range.finish .. ">" or "")
     70 			.. " to `" .. cmd .. "`")
     71 		local ret = run_on_file(cmd, file, range, modify)
     72 		if ret ~= 0 then
     73 			all_succeeded = false
     74 			failure_count = failure_count + 1
     75 			-- exit early if modify was specified
     76 			if modify then
     77 				lint.logger("Command failed with exit code: " .. ret, lint.log.ERROR)
     78 				return false
     79 			end
     80 		end
     81 	end
     82 	lint.logger(prefix .. #cmds .. " commands done, " .. failure_count .. " reported a problem")
     83 	return all_succeeded
     84 end
     85 
     86 lint.lint = function(file, range)
     87 	return run_actions_on_file(lint.linters, file, range)
     88 end
     89 
     90 lint.fix = function(file, range)
     91 	return run_actions_on_file(lint.fixers, file, range, true)
     92 end
     93 
     94 vis:command_register("lint", function(argv, force, win, selection, range)
     95 	return lint.lint(win.file, range)
     96 end, "Lint the current file and display output in the message window")
     97 
     98 vis:command_register("fix", function(argv, force, win, selection, range)
     99 	return lint.fix(win.file, range)
    100 end, "Pipe the current file through defined fixers. Modifies the buffer.")
    101 
    102 return lint