From 5a9235d56227d2330f43f3b8a7740aefceabd444 Mon Sep 17 00:00:00 2001 From: FollieHiyuki Date: Mon, 12 Jul 2021 04:20:58 +0300 Subject: [PATCH] neovim: add lspconfig, move compe config --- home/.config/nvim/lua/mappings.lua | 101 ++++++-------- home/.config/nvim/lua/modules/completion.lua | 54 +++++++- home/.config/nvim/lua/modules/gitgutter.lua | 4 +- home/.config/nvim/lua/modules/lsp.lua | 124 ++++++++++++++++++ .../nvim/lua/modules/telescope-nvim.lua | 5 +- home/.config/nvim/lua/plugins.lua | 68 +++++++--- home/.config/nvim/scripts/sumneko_lua.sh | 23 ++++ setup/lua-language-server.sh | 22 ---- 8 files changed, 297 insertions(+), 104 deletions(-) create mode 100644 home/.config/nvim/lua/modules/lsp.lua create mode 100755 home/.config/nvim/scripts/sumneko_lua.sh delete mode 100755 setup/lua-language-server.sh diff --git a/home/.config/nvim/lua/mappings.lua b/home/.config/nvim/lua/mappings.lua index 4d6be27..6a631b0 100644 --- a/home/.config/nvim/lua/mappings.lua +++ b/home/.config/nvim/lua/mappings.lua @@ -67,9 +67,24 @@ wk.register({ }, -- Naming common keys - ['['] = {name = 'Block motions (previous)'}, - [']'] = {name = 'Block motions (next)'}, - g = {name = 'Goto motions'}, + ['['] = { + name = 'Block motions (previous)', + d = 'Previous diagnostics', + g = 'Previous git hunk' + }, + [']'] = { + name = 'Block motions (next)', + d = 'Next diagnostics', + g = 'Next git hunk' + }, + g = { + name = 'Goto motions', + d = 'Go to definition', + D = 'Go to declaration', + i = 'Go to implementation', + r = 'Go to references' + }, + K = {name = 'Hover'}, z = {name = 'Misc utils'}, -- Don't need to show bufferline numbers @@ -119,8 +134,9 @@ wk.register({ j = {':Telescope symbols', 'Pick emojis'}, k = {':Telescope keymaps', 'Normal keymaps'}, m = {':Telescope marks', 'Bookmarks'}, + n = {':Telescope man_pages', 'Man pages'}, o = {':Telescope oldfiles', 'Recent files'}, - p = {':Telescope man_pages', 'Man pages'}, + p = {':Telescope project display_type=full', 'Projects'}, r = {':Telescope reloader', 'Reload lua modules'}, s = {':Telescope treesitter', 'Treesitter'}, t = {':Telescope', 'Telescope'}, @@ -131,15 +147,35 @@ wk.register({ }, l = { - name = 'LSP' + name = 'LSP', + a = 'Add workspace folder', + d = 'Type definition', + e = 'Line diagnostics', + l = 'List workspace folders', + n = 'Rename in buffer', + o = 'Format buffer', + q = 'Set diagnostics loclist', + r = 'Remove workspace folder', + s = 'Signature help', + f = { + name = 'Telescope', + a = {':Telescope lsp_code_actions', 'Code actions'}, + A = {':Telescope lsp_range_code_actions', 'Range code actions'}, + d = {':Telescope lsp_document_diagnostics', 'Buffer diagnostics'}, + D = {':Telescope lsp_workspace_diagnostics', 'Workspace diagnostics'}, + e = {':Telescope lsp_dynamic_workspace_symbols', 'Dynamic workspace symbols'}, + i = {':Telescope lsp_implementations', 'Implementations'}, + n = {':Telescope lsp_definitions', 'Definitions'}, + r = {':Telescope lsp_references', 'References'}, + s = {':Telescope lsp_document_symbols', 'Buffer symbols'}, + S = {':Telescope lsp_workspace_symbols', 'Workspace symbols'} + } }, -- Git g = { name = 'Git', b = 'Blame current line', - j = 'Next hunk', - k = 'Previous hunk', p = 'Preview hunk', r = 'Reset hunk', R = 'Reset all hunks in buffer', @@ -176,54 +212,3 @@ wk.register({ s = 'Stage hunk' } }, {mode = 'v', prefix = ''}) - ----------------- --- nvim-compe -- ----------------- --- Use (S-)Tab in completion menu --- See https://github.com/L3MON4D3/Luasnip/issues/1#issuecomment-835241958 -local t = function(str) - return vim.api.nvim_replace_termcodes(str, true, true, true) -end - -local function prequire(...) - local status, lib = pcall(require, ...) - if (status) then return lib end - return nil -end - -local luasnip = prequire('luasnip') - -local check_back_space = function() - local col = vim.fn.col('.') - 1 - return col == 0 or vim.fn.getline('.'):sub(col, col):match('%s') ~= nil -end - -_G.tab_complete = function() - if vim.fn.pumvisible() == 1 then - return t '' - elseif luasnip and luasnip.expand_or_jumpable() then - return t 'luasnip-expand-or-jump' - elseif check_back_space() then - return t '' - else - return vim.fn['compe#complete']() - end -end -_G.s_tab_complete = function() - if vim.fn.pumvisible() == 1 then - return t '' - elseif luasnip and luasnip.jumpable(-1) then - return t 'luasnip-jump-prev' - else - return t '' - end -end - -vim.api.nvim_set_keymap('i', '', 'v:lua.tab_complete()', {expr = true, noremap = true, silent = true}) -vim.api.nvim_set_keymap('s', '', 'v:lua.tab_complete()', {expr = true, noremap = true, silent = true}) -vim.api.nvim_set_keymap('i', '', 'v:lua.s_tab_complete()', {expr = true, noremap = true, silent = true}) -vim.api.nvim_set_keymap('s', '', 'v:lua.s_tab_complete()', {expr = true, noremap = true, silent = true}) - -vim.api.nvim_set_keymap('i', '', 'compe#complete()', {expr = true, noremap = true, silent = true}) -vim.api.nvim_set_keymap('i', '', 'compe#close(\'\')', {expr = true, noremap = true, silent = true}) diff --git a/home/.config/nvim/lua/modules/completion.lua b/home/.config/nvim/lua/modules/completion.lua index 212da50..d5b1476 100644 --- a/home/.config/nvim/lua/modules/completion.lua +++ b/home/.config/nvim/lua/modules/completion.lua @@ -1,4 +1,4 @@ -return require('compe').setup { +require('compe').setup { enabled = true, autocomplete = true, debug = false, @@ -7,11 +7,57 @@ return require('compe').setup { source = { path = true, buffer = true, - -- calc = true, + calc = false, nvim_lsp = true, - nvim_lua = true, + nvim_lua = false, + vsnip = false, luasnip = true, - -- tags = true, + utilsnips = false, + tags = false, spell = true } } + +-- Use (S-)Tab in completion menu +-- See https://github.com/neovim/nvim-lspconfig/wiki/Snippets +local t = function(str) + return vim.api.nvim_replace_termcodes(str, true, true, true) +end + +local check_back_space = function() + local col = vim.fn.col('.') - 1 + if col == 0 or vim.fn.getline('.'):sub(col, col):match('%s') then + return true + else + return false + end +end + +_G.tab_complete = function() + if vim.fn.pumvisible() == 1 then + return t '' + elseif require('luasnip').expand_or_jumpable() then + return t 'luasnip-expand-or-jump' + elseif check_back_space() then + return t '' + else + return vim.fn['compe#complete']() + end +end +_G.s_tab_complete = function() + if vim.fn.pumvisible() == 1 then + return t '' + elseif require('luasnip').jumpable(-1) then + return t 'luasnip-jump-prev' + else + return t '' + end +end + +vim.api.nvim_set_keymap('i', '', 'v:lua.tab_complete()', {expr = true}) +vim.api.nvim_set_keymap('s', '', 'v:lua.tab_complete()', {expr = true}) +vim.api.nvim_set_keymap('i', '', 'v:lua.s_tab_complete()', {expr = true}) +vim.api.nvim_set_keymap('s', '', 'v:lua.s_tab_complete()', {expr = true}) + +vim.api.nvim_set_keymap('i', '', 'compe#complete()', {expr = true}) +vim.api.nvim_set_keymap('i', '', 'compe#close(\'\')', {expr = true}) diff --git a/home/.config/nvim/lua/modules/gitgutter.lua b/home/.config/nvim/lua/modules/gitgutter.lua index b250070..df6f26f 100644 --- a/home/.config/nvim/lua/modules/gitgutter.lua +++ b/home/.config/nvim/lua/modules/gitgutter.lua @@ -12,8 +12,8 @@ return require('gitsigns').setup { noremap = true, buffer = true, - ['n gj'] = {expr = true, '&diff ? \'gj\' : \'lua require"gitsigns.actions".next_hunk()\''}, - ['n gk'] = {expr = true, '&diff ? \'gk\' : \'lua require"gitsigns.actions".prev_hunk()\''}, + ['n ]g'] = {expr = true, '&diff ? \']g\' : \'lua require"gitsigns.actions".next_hunk()\''}, + ['n [g'] = {expr = true, '&diff ? \'[g\' : \'lua require"gitsigns.actions".prev_hunk()\''}, ['n gs'] = 'lua require"gitsigns".stage_hunk()', ['v gs'] = 'lua require"gitsigns".stage_hunk({vim.fn.line("."), vim.fn.line("v")})', diff --git a/home/.config/nvim/lua/modules/lsp.lua b/home/.config/nvim/lua/modules/lsp.lua new file mode 100644 index 0000000..5a61f60 --- /dev/null +++ b/home/.config/nvim/lua/modules/lsp.lua @@ -0,0 +1,124 @@ +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', 'ls', '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', 'll', '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', 'lq', '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()', opts) + end +end + +local capabilities = vim.lsp.protocol.make_client_capabilities() +capabilities.textDocument.completion.completionItem.snippetSupport = true + +--------------------------- +-- Server configurations -- +--------------------------- +-- https://github.com/neovim/nvim-lspconfig/blob/master/CONFIG.md + +-- C/C++ +lspconf.clangd.setup { + on_attach = on_attach, + capabilities = capabilities, + filetypes = {'c', 'cpp'}, + cmd = { + 'clangd', + '-j=2', + '--background-index', + '--clang-tidy', + '--completion-style=detailed', + '--pch-storage=memory', + '--header-insertion=iwyu', + '--header-insertion=decorators' + } +} + +-- Lua +local runtime_path = vim.split(package.path, ';') +table.insert(runtime_path, 'lua/?.lua') +table.insert(runtime_path, 'lua/?/init.lua') + +lspconf.sumneko_lua.setup { + on_attach = on_attach, + cmd = { + vim.fn.stdpath('data') .. '/lsp/lua-language-server/bin/Linux/lua-language-server', + '-E', + vim.fn.stdpath('data') .. '/lsp/lua-language-server/main.lua' + }, + settings = { + Lua = { + diagnostics = { + globals = {'vim'} + }, + runtime = { + version = 'LuaJIT', + path = runtime_path + }, + workspace = { + library = vim.api.nvim_get_runtime_file('', true), + maxPreload = 100000, + preloadFileSize = 100000 + }, + telemetry = { + enable = false + } + } + } +} + +-- Go +lspconf.gopls.setup { + on_attach = on_attach, + capabilities = capabilities, + cmd = {'gopls', '--remote=auto'}, + init_options = { + usePlaceholders = true, + completeUnimported = true + } +} + +-- Others +local servers = { + 'dockerls', + 'bashls', + 'pyright', + 'tsserver', + 'html', + 'cmake', + 'rust_analyzer' +} +for _, server in ipairs(servers) do + lspconf[server].setup { + on_attach = on_attach, + capabilities = capabilities + } +end + +-- Replace the default lsp diagnostic letters with prettier symbols +-- vim.fn.sign_define('LspDiagnosticsSignError', {text = '', numhl = 'LspDiagnosticsDefaultError'}) +-- vim.fn.sign_define('LspDiagnosticsSignWarning', {text = '', numhl = 'LspDiagnosticsDefaultWarning'}) +-- vim.fn.sign_define('LspDiagnosticsSignInformation', {text = '', numhl = 'LspDiagnosticsDefaultInformation'}) +-- vim.fn.sign_define('LspDiagnosticsSignHint', {text = '', numhl = 'LspDiagnosticsDefaultHint'}) diff --git a/home/.config/nvim/lua/modules/telescope-nvim.lua b/home/.config/nvim/lua/modules/telescope-nvim.lua index ceefac2..4d8b9b1 100644 --- a/home/.config/nvim/lua/modules/telescope-nvim.lua +++ b/home/.config/nvim/lua/modules/telescope-nvim.lua @@ -25,6 +25,9 @@ local function telescope_setup() } }, extensions = { + project = { + base_dirs = {{'~/Code', max_depth = 2}} + }, fzf = { fuzzy = true, override_generic_sorter = false, @@ -33,7 +36,7 @@ local function telescope_setup() } } } - + require('telescope').load_extension('project') require('telescope').load_extension('fzf') end diff --git a/home/.config/nvim/lua/plugins.lua b/home/.config/nvim/lua/plugins.lua index 17544f6..ad89f19 100644 --- a/home/.config/nvim/lua/plugins.lua +++ b/home/.config/nvim/lua/plugins.lua @@ -10,7 +10,7 @@ end vim.cmd [[packadd packer.nvim]] return require('packer').startup( - function() + function(use) use {'wbthomason/packer.nvim', opt = true} ----------------- @@ -66,7 +66,8 @@ return require('packer').startup( use { 'lewis6991/gitsigns.nvim', event = {'BufRead', 'BufNewFile'}, - requires = 'nvim-lua/plenary.nvim', + wants = 'plenary.nvim', + requires = {{'nvim-lua/plenary.nvim', opt = true}}, config = function() require('modules.gitgutter') end @@ -118,12 +119,12 @@ return require('packer').startup( --------- -- LSP -- --------- - use { -- TODO: config + colors + use { 'neovim/nvim-lspconfig', - event = 'BufReadPre' - } - use { -- TODO: lua, python, clang - 'kabouzeid/nvim-lspinstall' + event = 'BufReadPre', + config = function() + require('modules.lsp') + end } use { 'hrsh7th/nvim-compe', @@ -146,17 +147,25 @@ return require('packer').startup( use { 'nvim-telescope/telescope.nvim', cmd = 'Telescope', + wants = { + 'popup.nvim', + 'plenary.nvim', + 'telescope-symbols.nvim', + 'telescope-project.nvim', + 'telescope-fzf-native.nvim' + }, requires = { - 'nvim-lua/popup.nvim', - 'nvim-lua/plenary.nvim', - 'nvim-telescope/telescope-symbols.nvim', - {'nvim-telescope/telescope-fzf-native.nvim', run = 'make'} + {'nvim-lua/popup.nvim', opt = true}, + {'nvim-lua/plenary.nvim', opt = true}, + {'nvim-telescope/telescope-symbols.nvim', opt = true}, + {'nvim-telescope/telescope-project.nvim', opt = true}, + {'nvim-telescope/telescope-fzf-native.nvim', run = 'make', opt = true} }, config = function() require('modules.telescope-nvim') end } - use { -- TODO: colors + config + custom telescope menu + use { -- TODO: colors + config 'pwntester/octo.nvim', cmd = 'Octo', wants = 'telescope.nvim', @@ -167,9 +176,13 @@ return require('packer').startup( use { -- TODO: config + colors 'TimUntersberger/neogit', cmd = 'Neogit', + wants = { + 'diffview.nvim', + 'plenary.nvim' + }, requires = { - -- 'sindrets/diffview.nvim', - 'nvim-lua/plenary.nvim' + {'nvim-lua/plenary.nvim', opt = true}, + {'sindrets/diffview.nvim', opt = true} } } use { @@ -199,6 +212,14 @@ return require('packer').startup( }) end } + use { + 'machakann/vim-sandwich', + event = 'BufRead' + } + use { + 'junegunn/vim-easy-align', + keys = 'ga' + } use { 'terrortylor/nvim-comment', keys = 'gc', @@ -208,7 +229,17 @@ return require('packer').startup( } use { 'windwp/nvim-ts-autotag', - ft = {'html', 'xml', 'javascript', 'javascriptreact', 'typescript', 'typescriptreact', 'vue', 'svelte', 'php'}, + ft = { + 'html', + 'xml', + 'javascript', + 'javascriptreact', + 'typescript', + 'typescriptreact', + 'vue', + 'svelte', + 'php' + }, wants = 'nvim-treesitter', config = function() require('nvim-treesitter.configs').setup { @@ -218,6 +249,10 @@ return require('packer').startup( } end } + use { + 'ahmedkhalf/lsp-rooter.nvim', + after = 'nvim-lspconfig' + } use { 'iamcco/markdown-preview.nvim', run = 'cd app && yarn install', @@ -238,10 +273,9 @@ return require('packer').startup( require('modules.terminal') end } - -- Just for benchmarking use {'tweekmonster/startuptime.vim', cmd = 'StartupTime'} - -- TODO: trouble.nvim, lspsaga, orgmode.nvim, lspkind, TrueZen/zen-mode, nvim-lint, vim-spectre, nvim-dap, lsp-rooter, hop.nvim, dial.nvim + -- TODO: trouble.nvim, lspsaga, orgmode.nvim, lspkind, TrueZen/zen-mode, nvim-lint, vim-spectre, nvim-dap, hop.nvim, dial.nvim, asynctasks.nvim end ) diff --git a/home/.config/nvim/scripts/sumneko_lua.sh b/home/.config/nvim/scripts/sumneko_lua.sh new file mode 100755 index 0000000..186025c --- /dev/null +++ b/home/.config/nvim/scripts/sumneko_lua.sh @@ -0,0 +1,23 @@ +#!/bin/sh -e + +current_path="$PWD" +luals_path="$HOME/.local/share/nvim/lsp/lua-language-server" + +# Clone / Update +if [ -d "$luals_path" ]; then + cd $luals_path + git pull --rebase +else + git clone https://github.com/sumneko/lua-language-server.git $luals_path +fi + +cd $luals_path +git submodule update --init --recursive + +# Build +cd 3rd/luamake +./compile/install.sh +cd ../.. +./3rd/luamake/luamake rebuild + +cd $current_path diff --git a/setup/lua-language-server.sh b/setup/lua-language-server.sh deleted file mode 100755 index 5e6f854..0000000 --- a/setup/lua-language-server.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh -e - -# clone the repo -git clone https://github.com/sumneko/lua-language-server.git -cd lua-language-server -git submodule update --init --recursive - -# build -# You need `ninja` -cd 3rd/luamake -ninja -f ninja/linux.ninja -cd ../.. -./3rd/luamake/luamake rebuild - -cd ../ - -# For coc.nvim -mkdir -pv ~/.local/share/nvim/lsp -cp -rf lua-language-server ~/.local/share/nvim/lsp/ && echo "copied 'lua-language-server' -> ~/.local/share/nvim/lsp/lua-language-server" -# For Doom Emacs -mkdir -pv ~/.config/emacs-config/doom/.local/etc/lsp -mv -fv lua-language-server ~/.config/emacs/.local/etc/lsp/