vim.diagnostic.config({ -- only show virtual text for WARN and higher virtual_text = { severity = { min = vim.diagnostic.severity.WARN } }, }) local capabilities = require('cmp_nvim_lsp').default_capabilities() local nvim_lsp = require('lspconfig') nvim_lsp.bashls.setup({ capabilities = capabilities, on_attach = on_attach, }); if vim.fn.executable("node_modules/.bin/eslint") == 1 then local options = {} -- some projects have local rules, this isn't exactly generic but is good -- enough if vim.fn.isdirectory("lint-rules") == 1 then options.rulePaths = { "./lint-rules" } end nvim_lsp.eslint.setup({ settings = { options = options, }, on_attach = function(client, bufnr) -- add formatting capability, the language server registers this -- dynamically but neovim does not support that yet -- https://github.com/microsoft/vscode-eslint/pull/1307 client.server_capabilities.documentFormattingProvider = true client.server_capabilities.documentRangeFormattingProvider = true -- mappings should have been attached by typescript and re-attaching can -- overwrite the typescript specific overrides end, }) end if vim.fn.executable("dprint") == 1 then local version = vim.version.parse(vim.fn.system("dprint --version")) if vim.version.cmp(version, {0,45,0}) >= 0 then nvim_lsp.dprint.setup({}) end end if vim.fn.executable("deno") == 1 then nvim_lsp.denols.setup({ capabilities = capabilities, on_attach = on_attach, }); else require('typescript').setup({ server = { init_options = { completionDisableFilterText = true, preferences = { importModuleSpecifierPreference = 'non-relative', }, }, capabilities = capabilities, handlers = { ['$/typescriptVersion'] = function(err, result, ctx, config) vim.notify(string.format('Typescript %s', result.version)) end }, flags = { debounce_text_changes = 150, }, on_attach = function(client, bufnr) -- mark tsserver as not having formatting available as we rely on -- eslint for that client.server_capabilities.documentFormattingProvider = false client.server_capabilities.documentRangeFormattingProvider = false on_attach(client, bufnr) -- override mappings for typescript local opts = { silent = true, buffer = bufnr } -- exclude import statements from reference search (may have false positives) vim.keymap.set('n', 'gr', 'Telescope lsp_references default_text=!import\\ ', opts) vim.keymap.set('n', 'gD', 'Telescope lsp_definitions', opts) vim.keymap.set('n', 'gd', 'TypescriptGoToSourceDefinition', opts) end } }) end if vim.fn.executable("gopls") == 1 then nvim_lsp.gopls.setup({ capabilities = capabilities, on_attach = on_attach, }); end if vim.fn.executable("solargraph") == 1 then nvim_lsp.solargraph.setup({ capabilities = capabilities, on_attach = on_attach, init_options = { formatting = false, } }) end if vim.fn.executable("nil") == 1 then nvim_lsp.nil_ls.setup({ on_attach = on_attach, }); end -- format on save local group = vim.api.nvim_create_augroup('LspFormatting', { clear = false }) vim.api.nvim_create_autocmd('LspAttach', { callback = function(args) local bufnr = args.buf local client = vim.lsp.get_client_by_id(args.data.client_id) if client.server_capabilities.documentFormattingProvider then for key, cmd in pairs(vim.api.nvim_get_autocmds({ group = group, buffer = bufnr })) do vim.api.nvim_del_autocmd(cmd.id) end vim.api.nvim_create_autocmd('BufWritePre', { group = group, buffer = bufnr, callback = function() vim.lsp.buf.format() end, }) end end, }) -- custom LSP servers local configs = require('lspconfig.configs') if not configs.elvish then configs.elvish = { default_config = { cmd = {'elvish', '--lsp'}, filetypes = {'elvish'}, root_dir = nvim_lsp.util.root_pattern('*.elv'), settings = {}, }, } end nvim_lsp.elvish.setup({ capabilities = capabilities, on_attach = on_attach, })