---@module 'lazy'
---@type LazySpec
return { {
	'mfussenegger/nvim-lint',
	event = { 'BufWritePost', 'BufReadPost', 'TextChanged' },
	---@module 'lint'
	opts = {
		---@type table<string, string[]>
		linters_by_ft = {
			c    = { 'clangtidy' },
			cpp  = { 'clangtidy' },
			sh   = { 'shellcheck' },
			glsl = { 'glslang' },
		},
		linters = {
			glslang = {
				cmd = 'glslangValidator',
				stdin = false,
				args = { '-C' },
				ignore_exitcode = true,
				parser = function(output)
					local diags = {}
					for _, line in ipairs(vim.split(output, '\n')) do
						local f, lnum, sev, msg = line:match(
						'^([^:]+):(%d+):%s+([^:]+):%s+(.+)$')            -- file:line: severity: message
						if not f then sev, f, lnum, msg = line:match(
							'^(%w+):%s+([^:]+):(%d+):%s+(.+)$') end  -- severity: file:line: message

						if lnum then
							local s = sev:lower() == 'error'
							    and vim.diagnostic.severity.ERROR
							    or vim.diagnostic.severity.WARN
							table.insert(diags, {
								lnum = tonumber(lnum) - 1,
								col = 0,
								message = msg,
								source = 'glslang',
								severity = s
							})
						end
					end
					return diags
				end
			}
		}
	},
	config = function(_, opts)
		local lint = require('lint')
		lint.linters_by_ft = opts.linters_by_ft

		for name, linter in pairs(opts.linters) do
			lint.linters[name] = linter
		end

		-- autocommand for linting
		Autocmd({ 'BufWritePost', 'BufWinEnter', 'TextChanged' },
			{ callback = function() lint.try_lint() end });
	end
} }
