local M = {} function M.lsp_conf() local lspconf = require('lspconfig') local on_attach = function(client, bufnr) vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc') local function buf_set_keymap(...) vim.api.nvim_buf_set_keymap(bufnr, ...) end 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', 'K', 'lua vim.lsp.buf.hover()', opts) buf_set_keymap('n', 'gi', 'lua vim.lsp.buf.implementation()', opts) buf_set_keymap('n', 'lx', 'lua vim.lsp.buf.signature_help()', opts) buf_set_keymap('n', 'la', 'lua vim.lsp.buf.add_workspace_folder()', opts) buf_set_keymap('n', 'lr', 'lua vim.lsp.buf.remove_workspace_folder()', opts) buf_set_keymap('n', 'lw', 'lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))', opts) buf_set_keymap('n', 'ld', 'lua vim.lsp.buf.type_definition()', opts) buf_set_keymap('n', 'ln', 'lua vim.lsp.buf.rename()', opts) buf_set_keymap('n', 'gr', 'lua vim.lsp.buf.references()', opts) buf_set_keymap('n', 'le', '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) buf_set_keymap('n', 'll', 'lua vim.lsp.diagnostic.set_loclist()', opts) if client.resolved_capabilities.document_formatting then buf_set_keymap('n', 'lo', 'lua vim.lsp.buf.formatting()', opts) elseif client.resolved_capabilities.document_range_formatting then buf_set_keymap('n', 'lo', 'lua vim.lsp.buf.range_formatting({},{0,0},{vim.fn.line("$"),0})', opts) end -- Attach lsp_signature.nvim require('lsp_signature').on_attach({ bind = true, -- This is mandatory, otherwise border config doesn't work floating_window = true, fix_pos = true, hint_prefix = '🐬 ', transpancy = 5, handler_opts = {border = 'none'}, zindex = 50, -- set to 200 to make the float window on top of others toggle_key = '' }, bufnr) end local capabilities = vim.lsp.protocol.make_client_capabilities() -- Add additional capabilities supported by nvim-cmp local completionItem = capabilities.textDocument.completion.completionItem completionItem.documentationFormat = {'markdown', 'plaintext'} completionItem.snippetSupport = true completionItem.preselectSupport = true completionItem.insertReplaceSupport = true completionItem.labelDetailsSupport = true completionItem.deprecatedSupport = true completionItem.commitCharactersSupport = true completionItem.tagSupport = {valueSet = {1}} completionItem.resolveSupport = { properties = { 'documentation', 'detail', 'additionalTextEdits', } } --------------------------- -- Server configurations -- --------------------------- -- https://github.com/neovim/nvim-lspconfig/blob/master/CONFIG.md local servers_path = vim.fn.stdpath('data') .. '/lsp' -- C/C++ lspconf.clangd.setup { on_attach = on_attach, capabilities = capabilities, filetypes = {'c', 'cpp'}, init_options = { usePlaceholders = true, completeUnimported = true, clangdFileStatus = true }, cmd = { 'clangd', '-j=2', '--background-index', '--clang-tidy', '--completion-style=detailed', '--pch-storage=memory', '--header-insertion=iwyu', '--header-insertion=decorators' } } -- Lua local lua_lib_path = {} local lua_runtime_path = {} -- lua_lib_path[vim.fn.expand('~/.luarocks/share/lua/5.3')] = true -- lua_lib_path[vim.fn.expand('/usr/share/lua/5.3')] = true lua_lib_path[os.getenv('VIMRUNTIME') .. '/lua'] = true -- local function add(lib) -- for _, p in pairs(vim.fn.expand(lib .. '/lua', false, true)) do -- p = vim.loop.fs_realpath(p) -- if p then lua_lib_path[p] = true end -- end -- end -- for _, site in pairs(vim.split(vim.opt.packpath, ',')) do -- add(site .. '/pack/*/opt/*') -- add(site .. '/pack/*/start/*') -- end table.insert(lua_runtime_path, 'lua/?.lua') table.insert(lua_runtime_path, 'lua/?/init.lua') -- table.insert(lua_runtime_path, '?.lua') -- table.insert(lua_runtime_path, '?/?.lua') -- table.insert(lua_runtime_path, '?/init.lua') for lib, _ in pairs(lua_lib_path) do table.insert(lua_runtime_path, lib .. '/?.lua') table.insert(lua_runtime_path, lib .. '/?/init.lua') end lspconf.sumneko_lua.setup { on_attach = on_attach, capabilities = capabilities, cmd = { servers_path .. '/sumneko_lua/bin/Linux/lua-language-server', '-E', '-e', 'LANG=en', servers_path .. '/sumneko_lua/main.lua' }, settings = { Lua = { diagnostics = {globals = {'vim'}}, runtime = {version = 'LuaJIT', path = lua_runtime_path}, workspace = { library = lua_lib_path, maxPreload = 1000, preloadFileSize = 150 }, completion = {callSnippet = 'Replace'}, hint = {enable = true}, telemetry = {enable = false} } } } -- Go lspconf.gopls.setup { on_attach = on_attach, capabilities = capabilities, cmd = {servers_path .. '/gopls/gopls', '--remote=auto'}, init_options = { usePlaceholders = true, completeUnimported = true } } -- Yaml lspconf.yamlls.setup { on_attach = on_attach, capabilities = capabilities, cmd = {servers_path .. '/yamlls/node_modules/.bin/yaml-language-server', '--stdio'}, settings = { redhat = {telemetry = {enabled = false}}, yaml = { format = { bracketSpacing = true, printWidth = 80, -- proseWrap = 'always', -- default is 'preserve' -- singleQuote = true, -- editor.formatOnType = true } } } } -- Tailwind -- lspconf.tailwindcss.setup { -- on_attach = on_attach, -- capabilities = capabilities, -- cmd = {servers_path .. '/tailwindcss/node_modules/.bin/tailwindcss-language-server', '--stdio'}, -- settings = { -- tailwindCSS = { -- emmetCompletions = true -- } -- } -- } -- Emmet if not lspconf.emmet_ls then require('lspconfig/configs').emmet_ls = { default_config = { cmd = {servers_path .. '/emmet_ls/node_modules/.bin/emmet-ls', '--stdio'}, filetypes = {'html', 'css'}, root_dir = function(fname) return vim.loop.cwd() end, settings = {} } } end lspconf.emmet_ls.setup {capabilities = capabilities} -- HTML lspconf.html.setup { on_attach = on_attach, capabilities = capabilities, cmd = {servers_path .. '/vscode/node_modules/.bin/vscode-html-language-server', '--stdio'}, filetypes = {'html', 'markdown'} } -- JSON lspconf.jsonls.setup { on_attach = on_attach, capabilities = capabilities, cmd = {servers_path .. '/vscode/node_modules/.bin/vscode-json-language-server', '--stdio'}, settings = { json = { -- Schema catalog: https://www.schemastore.org/api/json/catalog.json schemas = { { fileMatch = {'package.json'}, url = 'https://json.schemastore.org/package.json' }, { fileMatch = {'tsconfig*.json'}, url = 'https://json.schemastore.org/tsconfig.json' }, { fileMatch = { '.prettierrc', '.prettierrc.json', 'prettier.config.json' }, url = 'https://json.schemastore.org/prettierrc.json' }, { fileMatch = {'.eslintrc', '.eslintrc.json'}, url = 'https://json.schemastore.org/eslintrc.json' }, { fileMatch = { '.babelrc', '.babelrc.json', 'babel.config.json' }, url = 'https://json.schemastore.org/babelrc.json' }, { fileMatch = {'lerna.json'}, url = 'https://json.schemastore.org/lerna.json' }, { fileMatch = {'now.json', 'vercel.json'}, url = 'https://json.schemastore.org/now.json' }, { fileMatch = { '.stylelintrc', '.stylelintrc.json', 'stylelint.config.json' }, url = 'http://json.schemastore.org/stylelintrc.json' } } } } } -- TODO: efm-langserver -- Others local servers = { rust_analyzer = {'rust-analyzer'}, sqls = {servers_path .. '/sqls/sqls'}, cmake = {servers_path .. '/cmake/venv/bin/cmake-language-server'}, bashls = {servers_path .. '/bashls/node_modules/.bin/bash-language-server', 'start'}, dockerls = {servers_path .. '/dockerls/node_modules/.bin/docker-langserver', '--stdio'}, cssls = {servers_path .. '/vscode/node_modules/.bin/vscode-css-language-server', '--stdio'}, pyright = {servers_path .. '/pyright/node_modules/.bin/pyright-langserver', '--stdio'}, -- vimls = {servers_path .. '/vimls/node_modules/.bin/vim-language-server', '--stdio'}, tsserver = {servers_path .. '/tsserver/node_modules/.bin/typescript-language-server', '--stdio'} } for server, _ in pairs(servers) do lspconf[server].setup { on_attach = on_attach, capabilities = capabilities, cmd = servers[server] } end -- Replace the default lsp diagnostic letters with prettier symbols vim.fn.sign_define('LspDiagnosticsSignError', {text = ''}) vim.fn.sign_define('LspDiagnosticsSignWarning', {text = ''}) vim.fn.sign_define('LspDiagnosticsSignInformation', {text = ''}) vim.fn.sign_define('LspDiagnosticsSignHint', {text = ''}) end function M.sqls_conf() require('sqls').setup { picker = 'telescope' } end function M.trouble_conf() require('trouble').setup { mode = 'lsp_workspace_diagnostics', fold_open = ' ', fold_closed = '', action_keys = { open_split = {''}, open_vsplit = {''}, open_tab = {''} }, signs = { error = '', warning = '', hint = '', information = '', other = '' } } end -- function M.comments_conf() -- require('todo-comments').setup { -- signs = false, -- -- sign_priority = 8, -- keywords = { -- FIX = { -- icon = ' ', -- icon used for the sign, and in search results -- color = 'error', -- can be a hex color, or a named color (see below) -- alt = {'FIXME', 'BUG', 'FIXIT', 'ISSUE'}, -- a set of other keywords that all map to this FIX keywords -- -- signs = false, -- configure signs for some keywords individually -- }, -- TODO = {icon = ' ', color = 'info'}, -- HACK = {icon = ' ', color = 'warning'}, -- WARN = {icon = ' ', color = 'warning', alt = {'WARNING', 'XXX'}}, -- PERF = {icon = ' ', alt = {'OPTIM', 'PERFORMANCE', 'OPTIMIZE'}}, -- NOTE = {icon = ' ', color = 'hint', alt = {'INFO'}}, -- }, -- merge_keywords = true, -- highlight = { -- before = '', -- 'fg' or 'bg' or empty -- keyword = 'fg', -- 'fg', 'bg', 'wide' or empty. (wide is the same as bg, but will also highlight surrounding characters) -- after = '', -- 'fg' or 'bg' or empty -- pattern = [[.*<(KEYWORDS)\s*:]], -- pattern or table of patterns, used for highlightng (vim regex) -- comments_only = true, -- uses treesitter to match keywords in comments only -- max_line_len = 400, -- ignore lines longer than this -- exclude = {'org'}, -- list of file types to exclude highlighting -- }, -- colors = { -- error = {'LspDiagnosticsDefaultError', 'Red'}, -- warning = {'LspDiagnosticsDefaultWarning', 'Yellow'}, -- info = {'LspDiagnosticsDefaultInformation', 'Blue'}, -- hint = {'LspDiagnosticsDefaultHint', 'Cyan'}, -- default = {'Normal', 'White'} -- }, -- search = { -- command = 'rg', -- args = { -- '--hidden', -- '--color=never', -- '--no-heading', -- '--with-filename', -- '--line-number', -- '--column', -- }, -- -- regex that will be used to match keywords. -- -- don't replace the (KEYWORDS) placeholder -- pattern = [[\b(KEYWORDS):]] -- ripgrep regex -- -- pattern = [[\b(KEYWORDS)\b]] -- match without the extra colon. You'll likely get false positives -- } -- } -- end function M.outline_conf() vim.g.symbols_outline = { highlight_hovered_item = false, show_guides = false } end function M.null_ls_conf() end function M.dap_conf() local dap = require('dap') vim.fn.sign_define('DapBreakpoint', {text='', texthl='Red'}) vim.fn.sign_define('DapLogPoint', {text='', texthl='Red'}) vim.fn.sign_define('DapStopped', {text='', texthl='Red'}) vim.fn.sign_define('DapBreakpointRejected', {text='ﱢ', texthl='Red'}) end function M.dapui_conf() end return M