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