diff --git a/home/editors/lsp.nix b/home/editors/lsp.nix index c4f2abc..a803c0c 100644 --- a/home/editors/lsp.nix +++ b/home/editors/lsp.nix @@ -12,24 +12,24 @@ nodePackages.yaml-language-server nodePackages.vscode-langservers-extracted nodePackages.typescript-language-server + # not working like variant from node_modules + # nodePackages.graphql-language-service-cli nodePackages.dockerfile-language-server-nodejs - nodePackages.diagnostic-languageserver haskellPackages.haskell-language-server rust-analyzer sumneko-lua-language-server glsl-language-server # linters & formatters + shellcheck + shfmt nodePackages.eslint - # TODO uses custom script until json support is fixed - (pkgs.writeScriptBin "nix-linter" '' - echo '[' - ${nix-linter}/bin/nix-linter --json-stream "$1" | sed '$!s/$/,/' - echo ']' - '') + nodePackages.eslint_d + statix nixfmt - # nodePackages.stylelint + nodePackages.stylelint nodePackages.prettier + nodePackages.prettier_d_slim ]; # enableAnalyzersSupport loads very slowly diff --git a/home/editors/neovim/default.nix b/home/editors/neovim/default.nix index cb3cf57..6a6d39d 100644 --- a/home/editors/neovim/default.nix +++ b/home/editors/neovim/default.nix @@ -55,6 +55,7 @@ in { # lsp nvim-lspconfig + null-ls-nvim nvim-lightbulb # dap diff --git a/home/editors/neovim/lsp/lsp.lua b/home/editors/neovim/lsp/lsp.lua index 7477714..d314045 100644 --- a/home/editors/neovim/lsp/lsp.lua +++ b/home/editors/neovim/lsp/lsp.lua @@ -6,25 +6,26 @@ require("nvim-lightbulb").setup({ } }) +local format_augroup = vim.api.nvim_create_augroup("LspFormatting", {}) local on_attach = function(client, bufnr) -- codelens 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, buffer = bufnr, }) end -end - --- format on save -local diagnosticls_on_attach = function(client, bufnr) - on_attach(client, bufnr) - vim.api.nvim_create_autocmd("BufWritePre", { - callback = function() - vim.lsp.buf.formatting_seq_sync(nil, nil, { "tsserver", "diagnosticls" }) - end, - buffer = bufnr, - }) + if client.supports_method("textDocument/formatting") then + vim.api.nvim_clear_autocmds({ group = format_augroup, buffer = bufnr }) + vim.api.nvim_create_autocmd("BufWritePre", { + group = format_augroup, + buffer = bufnr, + callback = function() + -- 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 end local config = require("lspconfig") @@ -67,7 +68,7 @@ for _, lsp in ipairs(servers) do } end -config.rust_analyzer.setup{ +config.rust_analyzer.setup { on_attach = on_attach, capabilities = capabilities, 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, capabilities = capabilities, - cmd = {"OmniSharp", "--languageserver", "--hostPID", tostring(pid)}, + cmd = { "OmniSharp", "--languageserver", "--hostPID", tostring(pid) }, } local runtime_path = vim.split(package.path, ';') @@ -98,7 +99,7 @@ config.sumneko_lua.setup { path = runtime_path, }, diagnostics = { - globals = {"vim"}, + globals = { "vim" }, }, workspace = { library = vim.api.nvim_get_runtime_file("", true), @@ -110,158 +111,59 @@ config.sumneko_lua.setup { }, } -config.diagnosticls.setup { - on_attach = diagnosticls_on_attach, - capabilities = capabilities, - filetypes = { - "javascript", - "javascript.jsx", - "javascriptreact", - "typescript", - "typescript.jsx", - "typescriptreact", - "json", - "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" - }, +local null_ls = require("null-ls") +local null_ls_custom = { + diagnostics = {}, + formatting = { + -- TODO this doesn't use the correct formatter for some reason + -- likely some kind of directory or direnv issue + nix_fmt = { + name = "nix fmt", + meta = { + url = "https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-fmt.html", + description = "reformat your code in the standard style", }, - stylelint = { - command = "stylelint", - args = { - "--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 = { + method = null_ls.methods.FORMATTING, + filetypes = { "nix" }, + generator = require("null-ls.helpers").formatter_factory({ command = "nix", - args = {"fmt"} - }, - 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"}, + args = { "fmt" }, + -- to_stdin = true, + }), }, }, } +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({ check_ts = true, }) diff --git a/home/editors/neovim/lsp/mappings.lua b/home/editors/neovim/lsp/mappings.lua index cdceca4..db11adf 100644 --- a/home/editors/neovim/lsp/mappings.lua +++ b/home/editors/neovim/lsp/mappings.lua @@ -23,7 +23,8 @@ wk.register({ }, f = { 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, "Format file", },