local nvim_lsp = require "lspconfig" local lsp_status = require("lsp-status") -- function to attach completion when setting up lsp local function on_attach(client) local function buf_set_keymap(...) vim.api.nvim_buf_set_keymap(bufnr, ...) end local function buf_set_option(...) vim.api.nvim_buf_set_option(bufnr, ...) end buf_set_option("omnifunc", "v:lua.vim.lsp.omnifunc") -- Mappings. local opts = {noremap = true, silent = true} buf_set_keymap("n", "gD", "lua vim.lsp.buf.declaration()", opts) buf_set_keymap("n", "gd", "lua vim.lsp.buf.definition()", opts) buf_set_keymap("n", "gr", "lua vim.lsp.buf.references()", opts) buf_set_keymap("n", "gi", "lua vim.lsp.buf.implementation()", opts) buf_set_keymap("n", "K", "lua vim.lsp.buf.hover()", opts) buf_set_keymap("n", "rn", "lua vim.lsp.buf.rename()", opts) buf_set_keymap("n", "e", "lua vim.lsp.diagnostic.show_line_diagnostics()", opts) buf_set_keymap("n", "[d", "lua vim.lsp.diagnostic.goto_prev()", opts) buf_set_keymap("n", "]d", "lua vim.lsp.diagnostic.goto_next()", opts) -- Set some keybinds conditional on server capabilities if client.resolved_capabilities.document_formatting then buf_set_keymap("n", "f", "lua vim.lsp.buf.formatting()", opts) elseif client.resolved_capabilities.document_range_formatting then buf_set_keymap("n", "f", "lua vim.lsp.buf.range_formatting()", opts) end -- Set autocommands conditional on server_capabilities if client.resolved_capabilities.document_highlight then vim.api.nvim_exec( [[ augroup lsp_document_highlight autocmd! * autocmd CursorHold lua vim.lsp.buf.document_highlight() autocmd CursorMoved lua vim.lsp.buf.clear_references() " autocmd CursorHold *.* :lua vim.lsp.diagnostic.show_line_diagnostics() autocmd BufWritePre * lua vim.lsp.buf.formatting_sync(nil, 300) augroup END ]], false ) end end -- Lua Language Server if vim.fn.has("mac") == 1 then system_name = "macOS" elseif vim.fn.has("unix") == 1 then system_name = "Linux" elseif vim.fn.has("win32") == 1 then system_name = "Windows" else print("Unsupported system for sumneko") end local sumneko_root_path = "/home/jim/.local/share/lua-language-server" local sumneko_binary = sumneko_root_path .. "/bin/" .. system_name .. "/lua-language-server" local runtime_path = vim.split(package.path, ";") table.insert(runtime_path, "lua/?.lua") table.insert(runtime_path, "lua/?/init.lua") nvim_lsp.sumneko_lua.setup { on_attach = on_attach, capabilities = lsp_status.capabilities, cmd = {sumneko_binary, "-E", sumneko_root_path .. "/main.lua"}, settings = { Lua = { runtime = { -- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim) version = "LuaJIT", -- Setup your lua path path = runtime_path }, diagnostics = { -- Get the language server to recognize the `vim` global globals = {"vim"} }, workspace = { -- Make the server aware of Neovim runtime files library = vim.api.nvim_get_runtime_file("", true) }, -- Do not send telemetry data containing a randomized but unique identifier telemetry = { enable = false } } } } -- Go Language Server nvim_lsp.gopls.setup { on_attach = on_attach, capabilities = lsp_status.capabilities } -- Svelte Language Server nvim_lsp.svelte.setup { on_attach = on_attach, capabilities = lsp_status.capabilities } -- Typescript Language Server local function organize_imports() local params = { command = "_typescript.organizeImports", arguments = {vim.api.nvim_buf_get_name(0)}, title = "" } vim.lsp.buf.execute_command(params) end nvim_lsp.tsserver.setup { on_attach = on_attach, capabilities = lsp_status.capabilities, commands = { OrganizeImports = { organize_imports, description = "Organize Imports" } } } -- Setup diagnostics formaters and linters for non LSP provided files nvim_lsp.diagnosticls.setup { on_attach = on_attach, capabilities = lsp_status.capabilities, cmd = {"diagnostic-languageserver", "--stdio"}, filetypes = { "lua", "sh", "markdown", "json", "yaml", "toml" }, init_options = { linters = { shellcheck = { command = "shellcheck", debounce = 100, args = {"--format", "json", "-"}, sourceName = "shellcheck", parseJson = { line = "line", column = "column", endLine = "endLine", endColumn = "endColumn", message = "${message} [${code}]", security = "level" }, securities = { error = "error", warning = "warning", info = "info", style = "hint" } }, markdownlint = { command = "markdownlint", isStderr = true, debounce = 100, args = {"--stdin"}, offsetLine = 0, offsetColumn = 0, sourceName = "markdownlint", formatLines = 1, formatPattern = { "^.*?:\\s?(\\d+)(:(\\d+)?)?\\s(MD\\d{3}\\/[A-Za-z0-9-/]+)\\s(.*)$", { line = 1, column = 3, message = {4} } } } }, filetypes = { sh = "shellcheck", markdown = "markdownlint" }, formatters = { shfmt = { command = "shfmt", args = {"-i", "2", "-bn", "-ci", "-sr"} }, prettier = { command = "prettier", args = {"--stdin-filepath", "%filepath"} } }, formatFiletypes = { sh = "shfmt", json = "prettier", yaml = "prettier", toml = "prettier", markdown = "prettier", lua = "prettier" } } } -- Enable diagnostics vim.lsp.handlers["textDocument/publishDiagnostics"] = vim.lsp.with( vim.lsp.diagnostic.on_publish_diagnostics, { underline = true, virtual_text = false, signs = true, update_in_insert = true } )