return { 'mfussenegger/nvim-lint', dependencies = { 'WhoIsSethDaniel/mason-tool-installer.nvim' }, event = { 'BufReadPre', 'BufNewFile' }, opts = { linters_by_ft = { python = { 'ruff', 'mypy' }, go = { 'golangcilint' }, yaml = { 'yamllint' }, markdown = { 'markdownlint' }, sh = { 'shellcheck' }, lua = { 'luacheck' }, sql = { 'sqlfluff' }, }, mason_to_lint = { golangcilint = { 'golangci-lint' }, }, }, config = function(_, opts) local lint = require('lint') lint.linters_by_ft = opts.linters_by_ft -- Flatten linters and map to Mason package names local all_linters = {} for _, ft_linters in pairs(opts.linters_by_ft) do for _, l in ipairs(ft_linters) do local tool = opts.mason_to_lint[l] or { l } -- Handle both table and string values if type(tool) == 'table' then for _, t in ipairs(tool) do if t ~= '' then table.insert(all_linters, t) end end elseif tool ~= '' then table.insert(all_linters, tool) end end end -- Deduplicate tools local tools_set = {} for _, t in ipairs(all_linters) do tools_set[t] = true end local tools = vim.tbl_keys(tools_set) print('Ensuring installation of linters: ' .. table.concat(tools, ', ')) -- Setup mason-tool-installer safely require('mason-tool-installer').setup({ ensure_installed = tools, auto_update = false, run_on_start = true, start_delay = 3000, }) -- Autocommand group for linting local augroup = vim.api.nvim_create_augroup('LintAutogroup', { clear = true }) vim.api.nvim_create_autocmd({ 'BufEnter', 'BufWritePost', 'InsertLeave' }, { group = augroup, callback = function() local ft = vim.bo.filetype local available = lint.linters_by_ft[ft] if available and #available > 0 then local ok, err = pcall(lint.try_lint) if not ok then vim.notify('[nvim-lint] Error running linter: ' .. err, vim.log.levels.ERROR) end end end, }) end, }