From 7459b2c0f777c56ff5c0fd64331cff0c7f50c1d8 Mon Sep 17 00:00:00 2001 From: Rokas Puzonas Date: Sun, 31 Oct 2021 16:46:27 +0200 Subject: [PATCH] feat: setup nvim-cmp for autocompletion and lspconfig --- README.md | 1 + lua/bindings.lua | 10 ---- lua/config/cmp.lua | 71 ++++++++++++++++++++++ lua/config/lspconfig.lua | 126 +++++++++++++++++++++++++++++++++++++++ lua/config/tabnine.lua | 10 ++++ lua/options.lua | 3 + lua/plugins.lua | 29 ++++++++- 7 files changed, 239 insertions(+), 11 deletions(-) create mode 100644 lua/config/cmp.lua create mode 100644 lua/config/lspconfig.lua create mode 100644 lua/config/tabnine.lua diff --git a/README.md b/README.md index 1e93006..8c43f64 100644 --- a/README.md +++ b/README.md @@ -4,5 +4,6 @@ ## Requirements * ripgrep - for telescope * [A patched font](https://www.nerdfonts.com/) - for dev icons +* [Sumenko language server](https://github.com/sumneko/lua-language-server/wiki/Build-and-Run-(Standalone)) diff --git a/lua/bindings.lua b/lua/bindings.lua index d67bb19..9964952 100644 --- a/lua/bindings.lua +++ b/lua/bindings.lua @@ -1,18 +1,8 @@ local map = require 'utils.map' -local silent = {silent = true} - -- Window movement map('n', '', 'h') map('n', '', 'j') map('n', '', 'k') map('n', '', 'l') - --- Toggle whitespace characters -map('n', 'tw', ':setlocal list!') - - --- Toggle numbers and sign column -map('n', 'tn', ':setlocal relativenumber!:setlocal number!') - diff --git a/lua/config/cmp.lua b/lua/config/cmp.lua new file mode 100644 index 0000000..94442fe --- /dev/null +++ b/lua/config/cmp.lua @@ -0,0 +1,71 @@ +-- Setup nvim-cmp. +local lspkind = require('lspkind') +lspkind.init() + +local cmp = require('cmp') + +cmp.setup{ + completion = { completeopt = 'menu,menuone,noinsert' }, + snippet = { + expand = function(args) + require("luasnip").lsp_expand(args.body) + end, + }, + mapping = { + -- [''] = cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Insert }), + -- [''] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Insert }), + [''] = cmp.mapping.scroll_docs(-4), + [''] = cmp.mapping.scroll_docs(4), + [''] = cmp.mapping.complete(), + [''] = cmp.mapping.close(), + [''] = cmp.mapping.confirm({ + behavior = cmp.ConfirmBehavior.Replace, + select = true, + }) + }, + sources = { + { name = 'nvim_lua' }, + + { name = 'nvim_lsp', max_item_count = 20 }, + { name = 'cmp_tabnine' }, + { name = 'path' }, + { name = 'luasnip' }, + { name = 'buffer', max_item_count = 10, keyword_length = 5 }, + }, + formatting = { + format = lspkind.cmp_format{ + with_text = true, + menu = { + buffer = "[buf]", + cmp_tabnine = "[tab9]", + nvim_lsp = "[lsp]", + nvim_lua = "[api]", + path = "[path]", + luasnip = "[snip]", + } + } + }, + experimental = { + native_menu = false, + ghost_text = true, + } +} + + +-- Use buffer source for `/`. +cmp.setup.cmdline('/', { + sources = { + { name = 'buffer' } + } +}) + +-- Use cmdline & path source for ':'. +-- cmp.setup.cmdline(':', { +-- sources = cmp.config.sources({ +-- { name = 'path' } +-- }, { +-- { name = 'cmdline' } +-- }) +-- }) + + diff --git a/lua/config/lspconfig.lua b/lua/config/lspconfig.lua new file mode 100644 index 0000000..7f114b7 --- /dev/null +++ b/lua/config/lspconfig.lua @@ -0,0 +1,126 @@ +local lspconfig = require('lspconfig') +local M = {} + +-- debounce_text_changes = delay, between changing something and lsp updating +M.flags = { debounce_text_changes = 150 } + +M.default_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 = vim.split(package.path, ';') + }, + diagnostics = { + -- Get the language server to recognize the `vim` global + globals = {'vim', 'packer_plugins'} + }, + workspace = { + -- Make the server aware of Neovim runtime files + library = vim.api.nvim_get_runtime_file("", true) + }, + telemetry = { enable = false } + } +} + +-- Use an on_attach function to only map the following keys +-- after the language server attaches to the current buffer +---@diagnostic disable-next-line: unused-local +local function on_attach(client, bufnr) + -- Mappings. + local opts = { noremap = true, silent = true } + + local function buf_set_keymap(mode, lhs, rhs) vim.api.nvim_buf_set_keymap(bufnr, mode, lhs, rhs, opts) end + local function buf_set_option(...) vim.api.nvim_buf_set_option(bufnr, ...) end + + -- Enable completion triggered by + buf_set_option('omnifunc', 'v:lua.vim.lsp.omnifunc') + + -- See `:help vim.lsp.*` for documentation on any of the below functions + buf_set_keymap('n', 'gd', 'lua vim.lsp.buf.definition()') + buf_set_keymap('n', 'gD', 'lua vim.lsp.buf.declaration()') + buf_set_keymap('n', 'gr', 'lua vim.lsp.buf.references()') + buf_set_keymap('n', 'gi', 'lua vim.lsp.buf.implementation()') + buf_set_keymap('n', 'K', 'lua vim.lsp.buf.hover()') + buf_set_keymap('n', '', 'lua vim.lsp.buf.signature_help()') + -- buf_set_keymap('n', 'wa', 'lua vim.lsp.buf.add_workspace_folder()') + -- buf_set_keymap('n', 'wr', 'lua vim.lsp.buf.remove_workspace_folder()') + -- buf_set_keymap('n', 'wl', 'lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))') + -- buf_set_keymap('n', 'D', 'lua vim.lsp.buf.type_definition()') + buf_set_keymap('n', 'rn', 'lua vim.lsp.buf.rename()') + buf_set_keymap('n', 'ca', 'lua vim.lsp.buf.code_action()') + buf_set_keymap('n', 'd', 'lua vim.lsp.diagnostic.show_line_diagnostics()') + -- buf_set_keymap('n', '[d', 'lua vim.lsp.diagnostic.goto_prev()') + -- buf_set_keymap('n', ']d', 'lua vim.lsp.diagnostic.goto_next()') + -- buf_set_keymap('n', 'q', 'lua vim.lsp.diagnostic.set_loclist()') + buf_set_keymap('n', 'f', 'lua vim.lsp.buf.formatting()') + + -- " auto-format + -- autocmd BufWritePre *.js lua vim.lsp.buf.formatting_sync(nil, 100) + -- autocmd BufWritePre *.jsx lua vim.lsp.buf.formatting_sync(nil, 100) + -- autocmd BufWritePre *.py lua vim.lsp.buf.formatting_sync(nil, 100) +end + + +local capabilities = vim.lsp.protocol.make_client_capabilities() +if packer_plugins['cmp-nvim-lsp'] and packer_plugins['cmp-nvim-lsp'].loaded then + capabilities = require('cmp_nvim_lsp').update_capabilities(capabilities) +end + +local function on_init(initialize_params, config) + -- print(vim.inspect(capabilities)) + -- print(vim.inspect(config)) +end + +-- https://github.com/sumneko/lua-language-server/wiki/Build-and-Run-(Standalone) +local function getSumnekoPaths() + USER = vim.fn.expand('$USER') + + if vim.fn.has("mac") == 1 then + local sumneko_root_path = "/Users/" .. USER .. "/.config/nvim/lua-language-server" + local sumneko_binary = "/Users/" .. USER .. "/.config/nvim/lua-language-server/bin/macOS/lua-language-server" + return sumneko_root_path, sumneko_binary + elseif vim.fn.has("unix") == 1 then + local sumneko_root_path = "/home/" .. USER .. "/.config/nvim/lua-language-server" + local sumneko_binary = "/home/" .. USER .. "/.config/nvim/lua-language-server/bin/Linux/lua-language-server" + return sumneko_root_path, sumneko_binary + end +end + +local function setupLuaServer() + local sumneko_root_path, sumneko_binary = getSumnekoPaths() + + if not sumneko_root_path then + print("Unsupported system for sumneko") + return + end + + lspconfig.sumneko_lua.setup { + cmd = {sumneko_binary, "-E", sumneko_root_path .. "/main.lua"}, + on_attach = on_attach, + filetypes = {"lua"}, + capabilities = capabilities, + on_init = on_init, + flags = M.flags, + settings = M.default_settings + } +end + +setupLuaServer() + +-- Use a loop to conveniently call 'setup' on multiple servers and +-- map buffer local keybindings when the language server attaches +local servers = { 'tsserver' } +for _, name in ipairs(servers) do + lspconfig[name].setup { + on_attach = on_attach, + capabilities = capabilities, + on_init = on_init, + flags = M.flags, + settings = M.default_settings + } +end + +return M + diff --git a/lua/config/tabnine.lua b/lua/config/tabnine.lua new file mode 100644 index 0000000..53b6123 --- /dev/null +++ b/lua/config/tabnine.lua @@ -0,0 +1,10 @@ +local tabnine = require('cmp_tabnine.config') + +tabnine:setup{ + max_lines = 1000, + max_num_results = 20, + sort = true, + run_on_every_keystroke = true, + snippet_placeholder = '..' +} + diff --git a/lua/options.lua b/lua/options.lua index 4fa4f82..85d2741 100644 --- a/lua/options.lua +++ b/lua/options.lua @@ -9,6 +9,9 @@ cmd [[filetype plugin on]] local buffer = { o, bo } local window = { o, wo } +-- List of possible completion options +opt('completeopt', 'menu,menuone,noselect') + -- Pseudo transparent popup window opt('pumblend', 15) cmd [[highlight PmenuSel blend=0]] diff --git a/lua/plugins.lua b/lua/plugins.lua index bfd3bd2..38ead0d 100644 --- a/lua/plugins.lua +++ b/lua/plugins.lua @@ -10,7 +10,7 @@ local function usePlugins(use) -- Reload lua configs use { 'famiu/nvim-reload', - requires = { 'nvim-lua/plenary.nvim' }, + requires = 'nvim-lua/plenary.nvim', config = [[require 'config.reload']] } @@ -69,9 +69,36 @@ local function usePlugins(use) -- UNIX commands use 'tpope/vim-eunuch' + -- Snippets + use 'L3MON4D3/LuaSnip' + -- Movement utilities use 'tpope/vim-unimpaired' + -- LSP config + use { + 'neovim/nvim-lspconfig', + config = [[require 'config.lspconfig']], + } + + -- Completion + use { 'onsails/lspkind-nvim' } + use { + 'hrsh7th/nvim-cmp', + -- requires = 'onsails/lspkind-nvim', -- For some reason breaks with this line + requires = {'saadparwaiz1/cmp_luasnip'}, + after = 'lspkind-nvim', + config = [[require 'config.cmp']], + event = 'InsertEnter *' + } + use {'tzachar/cmp-tabnine', after = 'nvim-cmp', run='./install.sh', requires = 'hrsh7th/nvim-cmp', config = [[require 'config.tabnine']]} + use {'hrsh7th/cmp-nvim-lsp', requires = {'hrsh7th/nvim-cmp', 'nvim-lspconfig'}} + use {'hrsh7th/cmp-nvim-lua', after = 'nvim-cmp', requires = 'hrsh7th/nvim-cmp'} + use {'hrsh7th/cmp-buffer', after = 'nvim-cmp', requires = 'hrsh7th/nvim-cmp'} + use {'hrsh7th/cmp-path', after = 'nvim-cmp', requires = 'hrsh7th/nvim-cmp'} + use {'hrsh7th/cmp-cmdline', after = 'nvim-cmp', requires = 'hrsh7th/nvim-cmp'} + use {'saadparwaiz1/cmp_luasnip', after = 'nvim-cmp', requires = {'L3MON4D3/LuaSnip', 'nvim-cmp'}} + -- Color themes use 'morhetz/gruvbox' use 'tomasr/molokai'