feat(neovim): switch to null-ls

- switch from diagnostic-languageserver to null-ls.nvim
- add shellcheck & shfmt
- replace nix-linter with statix
- replace prettier with prettier_d_slim
- add stylelint, eslint_d & prettier_d_slim binaries
This commit is contained in:
Felix Schröter 2022-08-29 13:14:18 +02:00
parent 2122000c73
commit ccaf72b459
Signed by: felschr
GPG key ID: 671E39E6744C807D
4 changed files with 75 additions and 171 deletions

View file

@ -12,24 +12,24 @@
nodePackages.yaml-language-server nodePackages.yaml-language-server
nodePackages.vscode-langservers-extracted nodePackages.vscode-langservers-extracted
nodePackages.typescript-language-server nodePackages.typescript-language-server
# not working like variant from node_modules
# nodePackages.graphql-language-service-cli
nodePackages.dockerfile-language-server-nodejs nodePackages.dockerfile-language-server-nodejs
nodePackages.diagnostic-languageserver
haskellPackages.haskell-language-server haskellPackages.haskell-language-server
rust-analyzer rust-analyzer
sumneko-lua-language-server sumneko-lua-language-server
glsl-language-server glsl-language-server
# linters & formatters # linters & formatters
shellcheck
shfmt
nodePackages.eslint nodePackages.eslint
# TODO uses custom script until json support is fixed nodePackages.eslint_d
(pkgs.writeScriptBin "nix-linter" '' statix
echo '['
${nix-linter}/bin/nix-linter --json-stream "$1" | sed '$!s/$/,/'
echo ']'
'')
nixfmt nixfmt
# nodePackages.stylelint nodePackages.stylelint
nodePackages.prettier nodePackages.prettier
nodePackages.prettier_d_slim
]; ];
# enableAnalyzersSupport loads very slowly # enableAnalyzersSupport loads very slowly

View file

@ -55,6 +55,7 @@ in {
# lsp # lsp
nvim-lspconfig nvim-lspconfig
null-ls-nvim
nvim-lightbulb nvim-lightbulb
# dap # dap

View file

@ -6,25 +6,26 @@ require("nvim-lightbulb").setup({
} }
}) })
local format_augroup = vim.api.nvim_create_augroup("LspFormatting", {})
local on_attach = function(client, bufnr) local on_attach = function(client, bufnr)
-- codelens -- codelens
if client.resolved_capabilities.code_lens then if client.resolved_capabilities.code_lens then
vim.api.nvim_create_autocmd({"CursorHold", "CursorHoldI", "InsertLeave"}, { vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI", "InsertLeave" }, {
callback = vim.lsp.codelens.refresh, callback = vim.lsp.codelens.refresh,
buffer = bufnr, buffer = bufnr,
}) })
end end
end if client.supports_method("textDocument/formatting") then
vim.api.nvim_clear_autocmds({ group = format_augroup, buffer = bufnr })
-- format on save vim.api.nvim_create_autocmd("BufWritePre", {
local diagnosticls_on_attach = function(client, bufnr) group = format_augroup,
on_attach(client, bufnr) buffer = bufnr,
vim.api.nvim_create_autocmd("BufWritePre", { callback = function()
callback = function() -- TODO switch to `vim.lsp.buf.format` after updating to nvim 0.8
vim.lsp.buf.formatting_seq_sync(nil, nil, { "tsserver", "diagnosticls" }) vim.lsp.buf.formatting_seq_sync(nil, nil, { "tsserver", "null-ls" })
end, end,
buffer = bufnr, })
}) end
end end
local config = require("lspconfig") local config = require("lspconfig")
@ -67,7 +68,7 @@ for _, lsp in ipairs(servers) do
} }
end end
config.rust_analyzer.setup{ config.rust_analyzer.setup {
on_attach = on_attach, on_attach = on_attach,
capabilities = capabilities, capabilities = capabilities,
root_dir = config.util.root_pattern("Cargo.toml", "rust-project.json", ".git"), root_dir = config.util.root_pattern("Cargo.toml", "rust-project.json", ".git"),
@ -78,10 +79,10 @@ config.rust_analyzer.setup{
}, },
} }
config.omnisharp.setup{ config.omnisharp.setup {
on_attach = on_attach, on_attach = on_attach,
capabilities = capabilities, capabilities = capabilities,
cmd = {"OmniSharp", "--languageserver", "--hostPID", tostring(pid)}, cmd = { "OmniSharp", "--languageserver", "--hostPID", tostring(pid) },
} }
local runtime_path = vim.split(package.path, ';') local runtime_path = vim.split(package.path, ';')
@ -98,7 +99,7 @@ config.sumneko_lua.setup {
path = runtime_path, path = runtime_path,
}, },
diagnostics = { diagnostics = {
globals = {"vim"}, globals = { "vim" },
}, },
workspace = { workspace = {
library = vim.api.nvim_get_runtime_file("", true), library = vim.api.nvim_get_runtime_file("", true),
@ -110,158 +111,59 @@ config.sumneko_lua.setup {
}, },
} }
config.diagnosticls.setup { local null_ls = require("null-ls")
on_attach = diagnosticls_on_attach, local null_ls_custom = {
capabilities = capabilities, diagnostics = {},
filetypes = { formatting = {
"javascript", -- TODO this doesn't use the correct formatter for some reason
"javascript.jsx", -- likely some kind of directory or direnv issue
"javascriptreact", nix_fmt = {
"typescript", name = "nix fmt",
"typescript.jsx", meta = {
"typescriptreact", url = "https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-fmt.html",
"json", description = "reformat your code in the standard style",
"yaml",
"markdown",
"nix",
"html",
"css"
},
init_options = {
linters = {
eslint = {
command = "eslint_d",
args = {
"--cache",
"--stdin",
"--stdin-filename",
"%filepath",
"--format",
"json"
},
rootPatterns = {".eslintrc.js", ".eslintrc.json", ".git"},
debounce = 50,
sourceName = "eslint",
parseJson = {
errorsRoot = "[0].messages",
line = "line",
column = "column",
endLine = "endLine",
endColumn = "endColumn",
message = "${message} [${ruleId}]",
security = "severity"
},
securities = {
["2"] = "error",
["1"] = "warning"
},
}, },
stylelint = { method = null_ls.methods.FORMATTING,
command = "stylelint", filetypes = { "nix" },
args = { generator = require("null-ls.helpers").formatter_factory({
"--stdin",
"--formatter",
"json",
"--file",
"%filepath"
},
rootPatterns = {".git"},
debounce = 50,
sourceName = "stylelint",
parseJson = {
errorsRoot = "[0].warnings",
line = "line",
column = "column",
message = "${text}",
security = "severity",
},
securities = {
error = "error",
warning = "warning",
},
},
["nix-linter"] = {
-- TODO uses custom script until json support is fixed
command = "nix-linter",
sourceName = "nix-linter",
debounce = 50,
parseJson = {
line = "pos.spanBegin.sourceLine",
column = "pos.spanBegin.sourceColumn",
endLine = "pos.spanEnd.sourceLine",
endColumn = "pos.spanEnd.sourceColumn",
message = "${description}",
},
},
},
filetypes = {
javascript = {"eslint"},
["javascript.jsx"] = {"eslint"},
javascriptreact = {"eslint"},
typescript = {"eslint"},
["typescript.jsx"] = {"eslint"},
typescriptreact = {"eslint"},
css = {"stylelint"},
nix = {"nix-linter"},
},
formatters = {
eslint = {
command = "eslint_d",
args = {
"--cache",
"--fix-to-stdout",
"--stdin",
"--stdin-filename",
"%filepath"
},
debounce = 50,
rootPatterns = {".eslintrc.js", ".eslintrc.json", ".git"},
},
stylelint = {
command = "stylelint",
args = {
"--stdin",
"--fix",
"--file",
"%filepath"
},
rootPatterns = {".stylelintrc.json", ".git"},
},
prettier = {
command = "prettier",
args = {
"--stdin",
"--stdin-filepath",
"%filepath"
},
rootPatterns = {".prettierrc.json", ".git"},
},
nixfmt = {
command = "nix", command = "nix",
args = {"fmt"} args = { "fmt" },
}, -- to_stdin = true,
rustfmt = { }),
command = "rustfmt",
},
},
formatFiletypes = {
javascript = {"eslint"},
["javascript.jsx"] = {"eslint"},
javascriptreact = {"eslint"},
typescript = {"eslint"},
["typescript.jsx"] = {"eslint"},
typescriptreact = {"eslint"},
json = {"prettier"},
yaml = {"prettier"},
markdown = {"prettier"},
nix = {"nixfmt"},
rust = {"rustfmt"},
html = {"prettier"},
css = {"stylelint"},
}, },
}, },
} }
null_ls.setup({
sources = {
null_ls.builtins.diagnostics.shellcheck,
null_ls.builtins.diagnostics.statix, -- nix linter
null_ls.builtins.diagnostics.eslint_d,
null_ls.builtins.diagnostics.stylelint,
null_ls.builtins.formatting.shfmt,
null_ls.builtins.formatting.prettier_d_slim.with {
filetypes = {
"css",
"scss",
"less",
"html",
"json",
"jsonc",
"yaml",
"markdown",
"graphql",
"handlebars",
},
},
-- TODO not properly working yet
-- null_ls_custom.formatting.nix_fmt,
null_ls.builtins.formatting.nixfmt,
null_ls.builtins.formatting.rustfmt,
null_ls.builtins.formatting.terraform_fmt,
},
on_attach = on_attach,
})
require("nvim-autopairs").setup({ require("nvim-autopairs").setup({
check_ts = true, check_ts = true,
}) })

View file

@ -23,7 +23,8 @@ wk.register({
}, },
f = { f = {
function() function()
vim.lsp.buf.formatting_seq_sync(nil, nil, { "tsserver", "diagnosticls" }) -- TODO switch to `vim.lsp.buf.format` after updating to nvim 0.8
vim.lsp.buf.formatting_seq_sync(nil, nil, { "tsserver", "null-ls" })
end, end,
"Format file", "Format file",
}, },