140 lines
3.7 KiB
Lua
140 lines
3.7 KiB
Lua
-- <treesitter> or { <treesitter>, <lsp>, <linter>, <formatter>, filetype=<ft> }
|
|
-- filetype defaults to <treesitter>. If different, specify it.
|
|
-- any positional argument can be skipped with nil
|
|
local languages = {
|
|
-- Docs / Config
|
|
'vim',
|
|
'vimdoc',
|
|
{ 'markdown', nil, nil, 'prettier' },
|
|
'markdown_inline',
|
|
'yaml',
|
|
'toml',
|
|
|
|
-- Data
|
|
'gitcommit',
|
|
'gitignore',
|
|
'dockerfile',
|
|
'diff',
|
|
{ 'json', 'jsonls', nil, 'prettier' },
|
|
{ 'jsonc', 'jsonls', nil, 'prettier' },
|
|
|
|
-- Shell / Scripting
|
|
{ 'bash', 'bashls', 'shellcheck', 'shfmt' },
|
|
{ 'lua', 'luals', 'luacheck', 'stylua' },
|
|
{ 'sql', 'sqlls', nil, 'sqlfluff' },
|
|
|
|
-- Programming
|
|
{ 'c', 'clangd', nil, 'clang-format' },
|
|
{ 'cpp', 'clangd', nil, 'clang-format' },
|
|
{ 'go', 'gopls', 'golangci-lint', 'gofmt' },
|
|
{ 'rust', 'rust_analyzer', 'clippy', 'rustfmt' },
|
|
{ 'python', 'pyright', 'ruff', 'black' },
|
|
|
|
-- Web stack
|
|
{ 'html', 'html', nil, 'prettier' },
|
|
{ 'css', 'cssls', 'stylelint', 'prettier' },
|
|
{ 'javascript', 'tsls', 'eslint', 'prettier' },
|
|
{ 'typescript', 'tsls', 'eslint', 'prettier' },
|
|
{ nil, 'tsls', 'eslint', 'prettier', filetype = 'javascriptreact' },
|
|
{ 'tsx', 'tsls', 'eslint', 'prettier', filetype = 'typescriptreact' },
|
|
}
|
|
|
|
local function normalize(lang)
|
|
if type(lang) == 'string' then
|
|
lang = { lang }
|
|
end
|
|
local t = {
|
|
treesitter = lang[1],
|
|
lsp = lang[2],
|
|
linter = lang[3],
|
|
formatter = lang[4],
|
|
filetype = lang.filetype or lang[1],
|
|
}
|
|
return t
|
|
end
|
|
|
|
local normalized = vim.tbl_map(normalize, languages)
|
|
local general = {
|
|
ts_parsers = {},
|
|
lsps = {},
|
|
linters_by_ft = {},
|
|
formatters_by_ft = {},
|
|
}
|
|
for _, opts in ipairs(normalized) do
|
|
if opts.treesitter then
|
|
table.insert(general.ts_parsers, opts.treesitter)
|
|
end
|
|
|
|
if opts.lsp then
|
|
table.insert(general.lsps, opts.lsp)
|
|
end
|
|
|
|
if opts.linter then
|
|
general.linters_by_ft[opts.filetype] = { opts.linter }
|
|
end
|
|
|
|
if opts.formatter then
|
|
general.formatters_by_ft[opts.filetype] = { opts.formatter }
|
|
end
|
|
end
|
|
|
|
return {
|
|
{ 'windwp/nvim-ts-autotag', config = true },
|
|
{ 'windwp/nvim-autopairs', event = 'InsertEnter', config = true },
|
|
{ 'mason-org/mason.nvim', config = true },
|
|
-- { 'saghen/blink.cmp', version = '1.*' },
|
|
{
|
|
'nvim-treesitter/nvim-treesitter',
|
|
build = ':TSUpdate',
|
|
main = 'nvim-treesitter.configs',
|
|
opts = {
|
|
highlight = { enable = true },
|
|
incremental_selection = { enable = true },
|
|
textobjects = { enable = true },
|
|
ensure_installed = general.ts_parsers,
|
|
},
|
|
},
|
|
{
|
|
'mfussenegger/nvim-lint',
|
|
event = { 'BufReadPre', 'BufNewFile' },
|
|
opts = { linters_by_ft = general.linters_by_ft },
|
|
config = function(_, opts)
|
|
local lint = require('lint')
|
|
lint.linters_by_ft = opts.linters_by_ft
|
|
vim.api.nvim_create_autocmd({ 'BufEnter', 'BufWritePost', 'InsertLeave' }, {
|
|
group = vim.api.nvim_create_augroup('lint_autocmd', { clear = true }),
|
|
callback = function()
|
|
lint.try_lint()
|
|
end,
|
|
})
|
|
end,
|
|
},
|
|
{
|
|
'stevearc/conform.nvim',
|
|
event = { 'BufWritePre' },
|
|
opts = {
|
|
-- Automatically format on save
|
|
format_on_save = {
|
|
timeout_ms = 500,
|
|
lsp_format = 'fallback', -- Use LSP when no formatter is configured
|
|
},
|
|
|
|
-- Formatters per filetype
|
|
default_format_opts = { stop_after_first = true },
|
|
formatters_by_ft = general.formatters_by_ft,
|
|
},
|
|
|
|
config = function(_, opts)
|
|
require('conform').setup(opts)
|
|
|
|
-- Create a command to format manually
|
|
vim.api.nvim_create_user_command('Format', function()
|
|
require('conform').format({
|
|
async = true,
|
|
lsp_format = 'fallback',
|
|
})
|
|
end, { desc = 'Format current buffer' })
|
|
end,
|
|
},
|
|
}
|