nvim: Create single source of truth for language features

All additional languages features (LSPs, treesitter parsers, linters and
formatters) are now defined in a single place in 'core/languages'.

This file simply sets up a big table which contains all the enabled
programs and parsers, divided by type. They adhere to the structure
given by the respective plugin.

HACK: We are still cheating a bit currently for treesitter parsers since
I have not had the heart to go through all of them to
activate/deactivate what I could need. Most of them are simply still
loaded, not connected to a specific language. Will have to be sorted out
at some point but it is good enough for now.
This commit is contained in:
Marty Oehme 2025-03-14 21:15:21 +01:00
parent 62b0188fcc
commit c98fa26e91
Signed by: Marty
GPG key ID: 4E535BC19C61886E
7 changed files with 433 additions and 103 deletions

View file

@ -1,5 +1,6 @@
for _, source in ipairs({
"core.settings",
"core.languages",
"core.lazy",
"core.commands",
"core.mappings",

View file

@ -0,0 +1,370 @@
-- A list of all languages for which I have support for any of:
-- an LSP
-- Treesitter
-- linting
-- formatting
--
-- with their respective names used by lspconfig, nvim-treesitter, nvim-lint and conform.
--
local languages = {
arduino = { lsp = { arduino_language_server = {} }, ts = { "arduino" } },
awk = { ts = { "awk" }, format = { awk = { "gawk" } } },
astro = {
lsp = { astro = {} },
ts = { "astro" },
lint = { astro = { "eslint_d" } },
format = { astro = {
"prettier",
} },
},
bash = {
lsp = { bashls = {} },
ts = { "bash" },
lint = { bash = { "shellcheck" } },
format = { bash = { "shellharden", "shfmt" } },
},
beancount = { lsp = { beancount = {} }, ts = { "beancount" }, format = { beancount = { "bean-format" } } },
bibtex = { ts = { "bibtex" }, format = { bib = { "bibtex-tidy" } } },
c = { lsp = { clangd = {} }, ts = { "c" } },
css = { lsp = { cssls = {} }, ts = { "css" }, format = { css = { "prettier", "rustywind" } } },
csv = { ts = { "csv" } },
d = { lsp = { serve_d = {} }, ts = { "d" } },
dart = { ts = { "dart" } },
dhall = { ts = { "dhall" } },
diff = { ts = { "diff" } },
djot = { ts = { "djot" } },
docker_compose = { lsp = { docker_compose_language_service = {} } },
docker = { lsp = { dockerls = {} }, ts = { "dockerfile" } },
dot = { ts = { "dot" } },
emmet = { lsp = { emmet_ls = {} } },
javascript = {
lsp = { eslint = {} },
ts = { "javascript" },
lint = { javascript = { "eslint_d" }, javascriptreact = { "eslint_d" } },
format = { javascript = { "prettier" }, javascriptreact = { "prettier" } },
},
git = { ts = { "git_config", "git_rebase", "gitattributes", "gitcommit", "gitignore" } },
go = { lsp = { gopls = {} }, ts = { "go" }, lint = { go = { "revive" } }, format = { go = { "gofumpt" } } },
graphql = { format = { graphql = { "prettier" } } },
html = { format = { html = { "prettier", "rustywind" } } },
julia = { lsp = { julials = {} }, ts = { "julia" } },
json = {
lsp = { jsonls = {} },
ts = { "hjson", "json", "json5", "jsonc", "jsonnet" },
format = { json = { "jq" } },
},
latex = {
-- TODO: May need to switch to ltex_plus at some point since ltex is unmaintained
lsp = { ltex = { autostart = false }, texlab = {} },
ts = { "latex" },
},
lua = {
lsp = {
lua_ls = {
settings = {
Lua = {
diagnostics = { globals = { "vim" } },
telemetry = { enable = false },
hint = { enable = true, setType = true },
},
},
},
},
ts = { "fennel", "luadoc", "luap", "luau" },
format = { lua = { "stylua" } },
},
markdown = {
lsp = { marksman = {} },
ts = { "markdown", "markdown_inline" },
lint = { markdown = { "markdownlint" } },
format = { markdown = { "prettier", "injected" } },
},
nim = { lsp = { nim_langserver = {} }, ts = { "nim", "nim_format_string" }, format = { nim = { "nimpretty" } } },
nushell = { ts = { "nu" } },
python = {
lsp = { basedpyright = {}, ruff = {} },
ts = { "python" },
format = { python = { "ruff_format", "ruff_organize_imports" } },
},
quarto = { lint = { quarto = { "markdownlint" } }, format = { quarto = { "prettier", "injected" } } },
sh = { lint = { sh = { "shellcheck" } }, format = { sh = { "shellharden", "shfmt" } } },
sql = { format = { sql = { "sleek" } } },
svelte = { lint = { svelte = { "eslint_d" } }, format = { svelte = { "prettier" } } },
toml = { lsp = { taplo = {} }, ts = { "toml" } },
typescript = {
lsp = { ts_ls = {} },
ts = { "typescript" },
lint = { typescript = { "eslint_d" }, typescriptreact = { "eslint_d" } },
format = { typescript = { "prettier" }, typescriptreact = { "prettier" } },
},
typst = { lsp = { tinymist = { settings = { formatterMode = "typstyle" } } }, ts = { "typst" } },
vue = { format = { vue = { "prettier", "rustywind" } } },
yaml = { lsp = { yamlls = {}, ansiblels = {} }, ts = { "yaml" }, format = { yaml = { "prettier" } } },
zsh = { format = { zsh = { "shfmt" } } },
-- TODO: For an easier migration from having 'all' in treesitter config
-- Should be migrated away from over time until it is completely removed
_additional_treesitters = {
ts = {
"cmake",
"comment",
"commonlisp",
"cooklang",
"corn",
"cpon",
"cpp",
"cuda",
"cue",
"cylc",
"desktop",
"devicetree",
"disassembly",
"doxygen",
"dtd",
"earthfile",
"ebnf",
"editorconfig",
"eds",
"eex",
"elixir",
"elm",
"elsa",
"elvish",
"embedded_template",
"enforce",
"erlang",
"facility",
"faust",
"fidl",
"firrtl",
"fish",
"foam",
"forth",
"fortran",
"fsh",
"fsharp",
"func",
"fusion",
"gap",
"gaptst",
"gdscript",
"gdshader",
"gleam",
"glimmer",
"glimmer_javascript",
"glimmer_typescript",
"glsl",
"gn",
"gnuplot",
"goctl",
"godot_resource",
"gomod",
"gosum",
"gotmpl",
"gowork",
"gpg",
"graphql",
"gren",
"groovy",
"gstlaunch",
"hack",
"hare",
"haskell",
"haskell_persistent",
"hcl",
"heex",
"helm",
"hlsl",
"hlsplaylist",
"hocon",
"hoon",
"html",
"htmldjango",
"http",
"hurl",
"hyprlang",
"idl",
"idris",
"ini",
"inko",
"ipkg",
"ispc",
"janet_simple",
"java",
"javascript",
"jinja",
"jinja_inline",
"jq",
"jsdoc",
"just",
"kcl",
"kconfig",
"kdl",
"kotlin",
"koto",
"kusto",
"lalrpop",
"ledger",
"leo",
"linkerscript",
"liquid",
"liquidsoap",
"llvm",
"luau",
"m68k",
"make",
"matlab",
"menhir",
"mermaid",
"meson",
"mlir",
"muttrc",
"nasm",
"nginx",
"nickel",
"ninja",
"nix",
"norg",
"nqc",
"nu",
"objc",
"objdump",
"ocaml",
"ocaml_interface",
"ocamllex",
"odin",
"pascal",
"passwd",
"pem",
"perl",
"php",
"php_only",
"phpdoc",
"pioasm",
"po",
"pod",
"poe_filter",
"pony",
"powershell",
"printf",
"prisma",
"problog",
"prolog",
"promql",
"properties",
"proto",
"prql",
"psv",
"pug",
"puppet",
"purescript",
"pymanifest",
"python",
"ql",
"qmldir",
"qmljs",
"query",
"r",
"racket",
"ralph",
"rasi",
"razor",
"rbs",
"re2c",
"readline",
"regex",
"rego",
"requirements",
"rescript",
"rnoweb",
"robot",
"robots",
"roc",
"ron",
"rst",
"ruby",
"runescript",
"rust",
"scala",
"scfg",
"scheme",
"scss",
"sflog",
"slang",
"slim",
"slint",
"smali",
"smithy",
"snakemake",
"solidity",
"soql",
"sosl",
"sourcepawn",
"sparql",
"sql",
"squirrel",
"ssh_config",
"starlark",
"strace",
"styled",
"supercollider",
"superhtml",
"surface",
"svelte",
"sway",
"swift",
"sxhkdrc",
"systemtap",
"t32",
"tablegen",
"tact",
"tcl",
"teal",
"templ",
"tera",
"terraform",
"textproto",
"thrift",
"tiger",
"tlaplus",
"tmux",
"todotxt",
"tsv",
"tsx",
"turtle",
"twig",
"typespec",
"typoscript",
"udev",
"ungrammar",
"unison",
"usd",
"uxntal",
"v",
"vala",
"vento",
"verilog",
"vhdl",
"vhs",
"vim",
"vimdoc",
"vrl",
"vue",
"wgsl",
"wgsl_bevy",
"wing",
"wit",
"xcompose",
"xml",
"xresources",
"yang",
"yuck",
"zathurarc",
"zig",
"ziggy",
"ziggy_schema",
},
},
}
Languages = languages

View file

@ -82,6 +82,24 @@ return {
},
},
-- generic tool installer; automatic external dependency mgmt for neovim
-- used in my config for LSPs, formatters and linters
{
"williamboman/mason.nvim",
cmd = {
"Mason",
"MasonInstall",
"MasonUninstall",
"MasonUninstallAll",
"MasonLog",
"MasonUpdate",
},
opts = {},
build = ":MasonUpdate",
keys = {
{ "<leader>vm", ":Mason<cr>", desc = "Mason" },
},
},
-- personal dict improvements for git sync
{ "micarmst/vim-spellsync", event = "VeryLazy" },
{

View file

@ -1,36 +1,20 @@
local formatters = {
angular = { "prettier" },
astro = { "prettier" },
bash = { "shfmt" },
bib = { "bibtex-tidy" },
css = { "prettier", "rustywind" },
go = { "gofumpt" },
graphql = { "prettier" },
html = { "prettier", "rustywind" },
javascript = { "prettier" },
javascriptreact = { "prettier" },
json = { "jq" },
liquid = { "prettier" },
lua = { "stylua" },
markdown = { "prettier", "injected" },
nim = { "nimpretty" },
python = { "ruff_format", "ruff_organize_imports" },
quarto = { "prettier", "injected" },
sh = { "shfmt" },
sql = { "sleek" },
svelte = { "prettier" },
typescript = { "prettier" },
typescriptreact = { "prettier" },
vue = { "prettier", "rustywind" },
yaml = { "prettier" },
zsh = { "shfmt" },
}
local formatters = {}
for _, lang in pairs(Languages) do
if not lang.format then
goto continue
end
for ft, val in pairs(lang.format) do
formatters[ft] = val
end
::continue::
end
return {
-- formatting setup
{
"zapling/mason-conform.nvim",
dependencies = {
{ "williamboman/mason.nvim" },
{
"stevearc/conform.nvim",
config = function()

View file

@ -1,23 +1,20 @@
local linters = {
astro = { "eslint_d" },
bash = { "shellcheck" },
javascript = { "eslint_d" },
javascriptreact = { "eslint_d" },
go = { "revive" },
markdown = { "markdownlint" },
quarto = { "markdownlint" },
sh = { "shellcheck" },
svelte = { "eslint_d" },
text = {},
typescript = { "eslint_d" },
typescriptreact = { "eslint_d" },
}
local linters = {}
for _, lang in pairs(Languages) do
if not lang.lint then
goto continue
end
for ft, val in pairs(lang.lint) do
linters[ft] = val
end
::continue::
end
return {
-- linting setup
{
"rshkarin/mason-nvim-lint",
dependencies = {
{ "williamboman/mason.nvim" },
{
"mfussenegger/nvim-lint",
config = function()

View file

@ -1,48 +1,13 @@
local servers = {
ansiblels = {},
arduino_language_server = {},
astro = {},
bashls = {},
beancount = {},
clangd = {},
cssls = {},
docker_compose_language_service = {},
dockerls = {},
emmet_ls = {},
eslint = {},
gopls = {},
julials = {},
jsonls = {},
ltex = { autostart = false },
lua_ls = {
settings = {
Lua = {
diagnostics = { globals = { "vim" } },
-- enable when working on neovim stuff. Takes *long* to load
-- workspace = { library = vim.api.nvim_get_runtime_file("", true) },
telemetry = { enable = false },
hint = {
enable = true,
setType = true,
},
},
},
},
marksman = {},
nim_langserver = {},
basedpyright = {},
ruff = {},
serve_d = {},
taplo = {},
texlab = {},
tinymist = {
settings = {
formatterMode = "typstyle",
},
},
ts_ls = {},
yamlls = {},
}
local servers = {}
for _, lang in pairs(Languages) do
if not lang.lsp then
goto continue
end
for name, conf in pairs(lang.lsp) do
servers[name] = conf
end
::continue::
end
local lsp = {
{ -- pretty lsp 'peek' menus
@ -56,22 +21,7 @@ local lsp = {
{
"williamboman/mason-lspconfig.nvim",
opts = { automatic_installation = true },
dependencies = {
"williamboman/mason.nvim",
cmd = {
"Mason",
"MasonInstall",
"MasonUninstall",
"MasonUninstallAll",
"MasonLog",
"MasonUpdate",
},
opts = {},
build = ":MasonUpdate",
keys = {
{ "<leader>vm", ":Mason<cr>", desc = "Mason" },
},
},
dependencies = { "williamboman/mason.nvim" },
cmd = { "LspInstall", "LspUninstall" },
},
{ "saghen/blink.cmp", optional = true },

View file

@ -23,10 +23,20 @@ return {
},
version = false, -- TODO: Can be set to versioned if new version after 2024-12-12 is released
config = function()
local enabled_parsers = {}
for _, lang in pairs(Languages) do
if not lang.ts then
goto continue
end
for _, name in pairs(lang.ts) do
table.insert(enabled_parsers,name)
end
::continue::
end
---@diagnostic disable-next-line: missing-fields (seems an issue in the diagnostic)
require("nvim-treesitter.configs").setup({
-- one of "all", "maintained" (parsers with maintainers), or a list of languages
ensure_installed = "all",
ensure_installed = enabled_parsers,
ignore_install = {},
sync_install = false,
auto_install = true,