dotfiles

personal dotfiles
git clone anongit@rnpnr.xyz:dotfiles.git
Log | Files | Refs | Feed | Submodules

build.lua (4134B)


      1 local gf   = require('goto-ref')
      2 local util = require('util')
      3 
      4 vis.events.subscribe(vis.events.FILE_SAVE_PRE, function(file)
      5 	local M = require('plugins/vis-lint')
      6 	M.logger = function(str, level)
      7 		if level == M.log.ERROR then
      8 			vis:message(str)
      9 		end
     10 	end
     11 	M.fixers["bibtex"] = { "bibtidy" }
     12 	M.fixers["c"]      = { "clang-format -fallback-style=none" }
     13 	M.fixers["cpp"]    = { "clang-format -fallback-style=none" }
     14 	M.fixers["json"]   = { "jq --tab" }
     15 	return M.fix(file)
     16 end)
     17 
     18 local logger = function(clear, ostr, estr)
     19 	if ostr == nil and estr == nil then return end
     20 	if clear then util.message_clear(vis) end
     21 	if ostr  then vis:message(ostr)       end
     22 	if estr  then vis:message(estr)       end
     23 	vis:message(string.rep("=", vis.win.viewport.width / 2))
     24 end
     25 
     26 local file_exists = function(file)
     27 	local f = io.open(file, "r")
     28 	if f ~= nil then io.close(f) return true else return false end
     29 end
     30 
     31 local default_error_search = function(error_string)
     32 	gf.setup_iterators_from_text(error_string, function(str)
     33 		return str:find(" error:")    or
     34 		       str:find(": note:")    or
     35 		       str:find(": warning:")
     36 
     37 	end)
     38 end
     39 
     40 local function build_files(win)
     41 	local build_tex = function (f)
     42 		local cmd = "lualatex -halt-on-error -shell-escape "
     43 
     44 		-- build in draft mode to update references
     45 		local err, ostr = vis:pipe(cmd .. "-draftmode " .. f.name)
     46 		if err ~= 0 then logger(true, ostr) return false end
     47 
     48 		local fp = util.splitext(f.name)
     49 		-- update refrences
     50 		vis:command("!biber " .. fp .. " >/dev/null")
     51 		-- update glossary
     52 		-- vis:command("!makeglossaries " .. fp .. " >/dev/null")
     53 
     54 		-- build actual pdf
     55 		err = vis:pipe(cmd .. f.name)
     56 		if err ~= 0 then return false end
     57 
     58 		-- reload pdf (zathura does this automatically)
     59 		-- vis:command('!pkill -HUP mupdf')
     60 
     61 		return true
     62 	end
     63 
     64 	local run_python = function (f)
     65 		local _, ostr, estr = vis:pipe('python ' .. f.name)
     66 		logger(true, ostr, estr)
     67 		if estr then return false end
     68 		return true
     69 	end
     70 
     71 	local run_sh  = function (f)
     72 		local _, ostr, estr = vis:pipe("$PWD/" .. f.name)
     73 		logger(true, ostr, estr)
     74 		default_error_search(estr)
     75 		return true
     76 	end
     77 
     78 	local build_c = function (f)
     79 		local cmd
     80 		if cmd == nil and file_exists('./build')    then cmd = '$PWD/build --debug' end
     81 		if cmd == nil and file_exists('./build.sh') then cmd = '$PWD/build.sh'      end
     82 		if cmd == nil and file_exists('Makefile')   then cmd = 'make'               end
     83 		if not cmd then return false, 'failed to determine method to build' end
     84 
     85 		local _, _, estr = vis:pipe(cmd)
     86 		logger(true, nil, estr)
     87 		default_error_search(estr)
     88 		return true
     89 	end
     90 
     91 	local lang = {
     92 		bash   = run_sh,
     93 		c      = build_c,
     94 		cpp    = build_c,
     95 		latex  = build_tex,
     96 		python = run_python,
     97 		rc     = run_sh,
     98 	}
     99 
    100 	local builder = lang[win.syntax]
    101 	if builder == nil then
    102 		builder = function ()
    103 			vis:info(win.syntax .. ': filetype not supported')
    104 			return false
    105 		end
    106 	end
    107 
    108 	win:map(vis.modes.NORMAL, " c", function ()
    109 		vis:command('X/.*/w')
    110 		local s = "built: " .. win.file.name
    111 		local ret, info = builder(win.file)
    112 		if info then s = s .. " | info: " .. info end
    113 
    114 		-- check for FIXMEs/TODOs
    115 		local _, out = vis:pipe('ag --depth=0 --count "(FIXME|TODO)"')
    116 		if out then
    117 			local file_count_table = gf.generate_line_indices(out)
    118 			local count = 0
    119 			for i = 1, #file_count_table do
    120 				local file, occurences = table.unpack(file_count_table[i])
    121 				count = count + tonumber(occurences)
    122 			end
    123 			if count ~= 0 then s = s .. " | FIXME/TODOs: " .. tostring(count) end
    124 		end
    125 
    126 		if ret == true then vis:info(s) end
    127 		return ret
    128 	end, "build file in current window")
    129 end
    130 
    131 local cached_command
    132 vis:command_register("build", function(argv)
    133 	if #argv == 0 and cached_command == nil then vis:info("build cmd [arg ...]") return false end
    134 	if #argv ~= 0 then cached_command = table.concat(argv, " ") end
    135 
    136 	vis:command('X/.*/w')
    137 	vis:info("running: " .. cached_command)
    138 	vis:redraw()
    139 	local code, ostr, estr = vis:pipe(cached_command)
    140 	if code ~= 0 then
    141 		logger(true, ostr, estr)
    142 		default_error_search(estr)
    143 	end
    144 end, "run command and try to collect errors")
    145 
    146 vis.events.subscribe(vis.events.WIN_OPEN, build_files)