local ok, lspconfig = pcall(require, "lspconfig") if not ok then return end local root_dir for dir in vim.fs.parents(vim.api.nvim_buf_get_name(0)) do if vim.fn.isdirectory(dir .. "/.git") == 1 then root_dir = dir break end end vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, { border = "single" }) local capabilities = {} local has_cmp, cmp_lsp = pcall(require, "cmp_nvim_lsp") if has_cmp then capabilities = cmp_lsp.default_capabilities() end local has_lsp_format, lsp_format = pcall(require, "lsp-format") if has_lsp_format then lsp_format.setup() end local on_attach = function(client, bufnr) require("my.keymaps").lsp_keymaps(client, bufnr) if client.server_capabilities.completionProvider then vim.api.nvim_buf_set_option(bufnr, "omnifunc", "v:lua.vim.lsp.omnifunc") end if client.server_capabilities.definitionProvider then vim.api.nvim_buf_set_option(bufnr, "tagfunc", "v:lua.vim.lsp.tagfunc") end -- Highlight on cursor hold if client.server_capabilities.documentHighlightProvider then vim.api.nvim_create_autocmd({ "CursorHold" }, { callback = vim.lsp.buf.document_highlight, buffer = bufnr, }) end if client.server_capabilities.signatureHelp then vim.api.nvim_create_autocmd({ "CursorHoldI" }, { callback = vim.lsp.buf.signature_help, buffer = bufnr, }) end vim.api.nvim_create_autocmd({ "CursorMoved" }, { callback = vim.lsp.buf.clear_references, buffer = bufnr, }) if has_lsp_format then lsp_format.on_attach(client) end end local function prettier_command() if not root_dir then return "prettier" end if vim.fs.basename(root_dir .. "node_modules/prettier") then return "npx prettier" else return "prettier" end end local prettier = { formatCommand = prettier_command() .. [[ --stdin-filepath ${INPUT} ${--tab-width:tab_width}]], formatStdin = true, } local eslint = { lintCommand = [[eslint_d -f visualstudio --stdin --stdin-filename ${INPUT}]], lintIgnoreExitCode = true, lintStdin = true, lintFormats = { "%f(%l,%c): %tarning %m", "%f(%l,%c): %rror %m", }, lintSource = "eslint", } local shellcheck = { lintCommand = "shellcheck -f gcc -x", lintSource = "shellcheck", lintFormats = { "%f:%l:%c: %trror: %m", "%f:%l:%c: %tarning: %m", "%f:%l:%c: %tote: %m", }, } local servers = { efm = { filetypes = { "typescript", "typescriptreact", "sh", "php" }, init_options = { documentFormatting = true }, settings = { rootMarkers = { ".git/" }, languages = { typescript = { prettier, eslint }, typescriptreact = { prettier, eslint }, sh = { shellcheck }, php = { prettier }, }, }, }, gopls = {}, nil_ls = { settings = { ['nil'] = { formatting = { command = { "nixpkgs-fmt" }, }, }, }, }, jedi_language_server = {}, -- python lsp ruff_lsp = {}, -- python linter rust_analyzer = { assist = { importGranularity = "module", importPrefix = "self", }, cargo = { buildScripts = { enable = true, }, }, procMacro = { enable = true, }, }, lua_ls = { settings = { Lua = { runtime = { version = "LuaJIT", }, diagnostics = { globals = { "vim" }, }, workspace = { checkThirdParty = false, library = vim.api.nvim_get_runtime_file("", true), }, telemetry = { enable = false, }, }, }, }, elixirls = { cmd = { "elixir-ls" }, settings = { elixirLS = { dialyzerEnabled = true, }, }, }, tsserver = { settings = { documentFormatting = false, }, }, psalm = { cmd = { "vendor/bin/psalm-language-server" }, }, } for lsp, settings in pairs(servers) do lspconfig[lsp].setup(vim.tbl_extend("force", { on_attach = on_attach, capabilities = capabilities, }, settings)) end