return { { 'neovim/nvim-lspconfig', lazy = false, dependencies = { { 'j-hui/fidget.nvim', opts = {} }, 'stevearc/conform.nvim', }, config = function() local capabilities = nil if pcall(require, 'blink.cmp') then capabilities = require('blink.cmp').get_lsp_capabilities() elseif pcall(require, 'cmp_nvim_lsp') then capabilities = require('cmp_nvim_lsp').default_capabilities() end local lspconfig = require('lspconfig') local servers = { clangd = { cmd = { 'clangd', '--clang-tidy', '--header-insertion=iwyu', '--import-insertions', '--header-insertion-decorators', }, }, elixirls = { cmd = { 'elixir-ls' }, settings = { elixirLS = { dialyzerEnabled = false, }, }, }, gopls = { settings = { gopls = { hints = { assignVariableTypes = true, compositeLiteralFields = true, compositeLiteralTypes = true, constantValues = true, functionTypeParameters = true, parameterNames = true, rangeVariableTypes = true, }, analyses = { -- composites = false, nilness = true, shadow = false, unusedparams = true, unusedwrite = true, }, gofumpt = true, -- hoverKind = 'Structured', }, }, }, lua_ls = { cmd = { 'luals' }, -- custom firejail-wrapped -- cmd = { 'lua-language-server' }, settings = { Lua = { runtime = { version = 'LuaJIT', path = vim.split(package.path, ';'), }, diagnostics = { globals = { '_G', 'assert', 'error', 'os', 'package', 'pairs', 'ipairs', 'pcall', 'require', 'string', 'table', 'type', 'unpack', 'vim', 'xpcall', }, neededFileStatus = { ['code-style-check'] = 'Any', }, }, format = { enable = true, defaultConfig = { indent_style = 'space', indent_size = '2', }, }, workspace = { library = { [vim.env.VIMRUNTIME .. '/lua'] = true, [vim.env.VIMRUNTIME .. '/lua/vim/lsp'] = true, [vim.fn.stdpath('config') .. '/lua'] = true, }, }, telemetry = { enable = false, }, }, }, }, rust_analyzer = { settings = { ['rust-analyzer'] = { diagnostics = { enable = true, }, checkOnSave = { command = { 'cargo', 'clippy' }, }, }, }, }, ts_ls = { init_options = { tsserver = { path = '/usr/lib/node_modules/typescript/lib', }, }, }, pylsp = {}, zls = { cmd = { 'zls', '--log-level', 'warn', }, }, bashls = {}, cssls = {}, jsonls = {}, html = {}, superhtml = {}, kotlin_language_server = { -- cmd = vim.lsp.rpc.connect('127.0.0.1', 20100), cmd = { 'distrobox', 'enter', '-n', 'android-dev', '--', '/usr/local/kotlin-langserver/bin/kotlin-language-server', }, init_options = { formatting = { formatter = 'none', -- disable because we use ktlint via gradle }, }, }, } for name, opts in pairs(servers) do opts = vim.tbl_deep_extend('force', { capabilities = capabilities, }, opts) lspconfig[name].setup(opts) end vim.api.nvim_create_autocmd('LspAttach', { callback = function() -- local client = -- assert(vim.lsp.get_client_by_id(args.data.client_id), 'must have valid client') vim.opt_local.omnifunc = 'v:lua.vim.lsp.omnifunc' vim.keymap.set('n', 'gd', vim.lsp.buf.definition, { buffer = true }) vim.keymap.set('n', 'gR', vim.lsp.buf.references, { buffer = true }) vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, { buffer = true }) vim.keymap.set('n', 'gT', vim.lsp.buf.type_definition, { buffer = true }) vim.keymap.set('n', 'K', vim.lsp.buf.hover, { buffer = true }) vim.keymap.set('n', 'grr', vim.lsp.buf.rename, { buffer = true }) vim.keymap.set('n', 'ga', vim.lsp.buf.code_action, { buffer = true }) end, }) end, }, { 'folke/lazydev.nvim', ft = 'lua', -- could add a completion source to cmp? }, -- formatting { 'stevearc/conform.nvim', lazy = false, opts = { formatters_by_ft = { lua = { 'stylua' }, go = { 'goimports', 'gofmt' }, python = { 'ruff_format' }, }, }, config = function(_, opts) require('conform').setup(opts) vim.api.nvim_create_autocmd('BufWritePre', { callback = function(args) if vim.g.nofmt then return end require('conform').format({ bufnr = args.buf, lsp_fallback = true, quiet = true, }) end, }) end, }, -- linting { 'nvimtools/none-ls.nvim', dependencies = { 'nvim-lua/plenary.nvim' }, event = 'VeryLazy', config = function() local nls = require('null-ls') nls.setup({ sources = { -- https://github.com/nvimtools/none-ls.nvim/blob/main/doc/BUILTINS.md -- nls.builtins.code_actions.gitsigns, nls.builtins.code_actions.impl, -- nls.builtins.completion.spell, -- nls.builtins.diagnostics.checkmake, -- nls.builtins.diagnostics.cmake_lint, -- nls.builtins.diagnostics.cppcheck, -- nls.builtins.diagnostics.gccdiag, nls.builtins.diagnostics.golangci_lint, -- nls.builtins.diagnostics.hadolint, -- nls.builtins.diagnostics.pylint, -- nls.builtins.diagnostics.selene, -- nls.builtins.diagnostics.semgrep, nls.builtins.diagnostics.sqlfluff, -- nls.builtins.diagnostics.stylelint, -- nls.builtins.diagnostics.textidote, nls.builtins.diagnostics.vale, }, }) end, }, -- diagnostics { enabled = true, 'rachartier/tiny-inline-diagnostic.nvim', lazy = false, opts = { preset = 'nonerdfont', signs = { left = '', right = '', diag = '', arrow = '◂ ', up_arrow = '▴ ', }, options = { throttle = 0, show_source = { enabled = true, }, multilines = { enabled = false, always_show = false, }, -- break_line = { enabled = true }, show_all_diags_on_cursorline = true, }, }, config = function(_, opts) require('tiny-inline-diagnostic').setup(opts) if vim.o.background == 'light' then require('tiny-inline-diagnostic').change({}, { mixing_color = '#aaaaaa' }) end end, }, }