From 2f93d9277b4267b15ae70fe02a626034cbf864c7 Mon Sep 17 00:00:00 2001 From: fleaz Date: Fri, 4 Aug 2023 00:04:48 +0200 Subject: [PATCH] modules/nvim: Drop coc and finally get lsp to work propperly --- home-manager/modules/neovim.nix | 202 ++++++++++++++++++-------------- 1 file changed, 115 insertions(+), 87 deletions(-) diff --git a/home-manager/modules/neovim.nix b/home-manager/modules/neovim.nix index df2b835..dd131ee 100644 --- a/home-manager/modules/neovim.nix +++ b/home-manager/modules/neovim.nix @@ -1,30 +1,13 @@ { pkgs, ... }: { - home.file.".config/nvim/coc-settings.json".text = '' - { - "diagnostic.virtualText": true, - "diagnostic.checkCurrentLine": false, - "diagnostic.virtualTextCurrentLineOnly": false, - "diagnostic.messageTarget": "", - - "suggest.noselect": true, - - "languageserver": { - "nix": { - "command": "nil", - "filetypes": ["nix"], - "rootPatterns": ["flake.nix"] - } - } - } - ''; - programs.neovim = { enable = true; withPython3 = true; extraPackages = with pkgs; [ nil nixpkgs-fmt + gopls + pyright (python3.withPackages (ps: with ps; [ black flake8 @@ -62,16 +45,16 @@ # Go plugin from fatih vim-go - # Coc language server support - coc-nvim - coc-pyright - # markdown vim-markdown tabular - vim-terraform - vim-nix + # lsp and completion + nvim-lspconfig + nvim-cmp + cmp-nvim-lsp + cmp-buffer + ]; extraConfig = '' set nocompatible @@ -124,68 +107,6 @@ set undoreload=1000 endif - " COC - - " Having longer updatetime (default is 4000 ms = 4s) leads to noticeable - " delays and poor user experience - set updatetime=300 - - " Use tab for trigger completion with characters ahead and navigate - " NOTE: There's always complete item selected by default, you may want to enable - " no select by `"suggest.noselect": true` in your configuration file - " NOTE: Use command ':verbose imap ' to make sure tab is not mapped by - " other plugin before putting this into your config - inoremap - \ coc#pum#visible() ? coc#pum#next(1) : - \ CheckBackspace() ? "\" : - \ coc#refresh() - inoremap coc#pum#visible() ? coc#pum#prev(1) : "\" - - " Make to accept selected completion item or notify coc.nvim to format - " u breaks current undo, please make your own choice - inoremap coc#pum#visible() ? coc#pum#confirm() - \: "\u\\=coc#on_enter()\" - - function! CheckBackspace() abort - let col = col('.') - 1 - return !col || getline('.')[col - 1] =~# '\s' - endfunction - - " Use to trigger completion - if has('nvim') - inoremap coc#refresh() - else - inoremap coc#refresh() - endif - - " Use `[g` and `]g` to navigate diagnostics - " Use `:CocDiagnostics` to get all diagnostics of current buffer in location list - nmap [g (coc-diagnostic-prev) - nmap ]g (coc-diagnostic-next) - - " GoTo code navigation - nmap gd (coc-definition) - nmap gy (coc-type-definition) - nmap gi (coc-implementation) - nmap gr (coc-references) - - " Use K to show documentation in preview window - nnoremap K :call ShowDocumentation() - - function! ShowDocumentation() - if CocAction('hasProvider', 'hover') - call CocActionAsync('doHover') - else - call feedkeys('K', 'in') - endif - endfunction - - " Highlight the symbol and its references when holding the cursor - autocmd CursorHold * silent call CocActionAsync('highlight') - - " Symbol renaming - nmap rn (coc-rename) - " Always show the signcolumn, otherwise it would shift the text each time " diagnostics appear/become resolved set signcolumn=yes @@ -209,12 +130,119 @@ let g:go_highlight_types = 1 let g:go_highlight_operators = 1 let g:go_highlight_build_constraints = 1 + " Don't use gopls from vim-go + let g:go_gopls_enabled = 0 " neoformat let g:neoformat_python_black = { 'args': ['-l 120'] } + lua << EOF require("bufferline").setup{} + + require('lspconfig').gopls.setup{} + require('lspconfig').pyright.setup{} + + vim.api.nvim_create_autocmd('LspAttach', { + desc = 'LSP actions', + callback = function() + local bufmap = function(mode, lhs, rhs) + local opts = {buffer = true} + vim.keymap.set(mode, lhs, rhs, opts) + end + + -- Displays hover information about the symbol under the cursor + bufmap('n', 'K', 'lua vim.lsp.buf.hover()') + + -- Jump to the definition + bufmap('n', 'gd', 'lua vim.lsp.buf.definition()') + + -- Jump to declaration + bufmap('n', 'gD', 'lua vim.lsp.buf.declaration()') + + -- Lists all the implementations for the symbol under the cursor + bufmap('n', 'gi', 'lua vim.lsp.buf.implementation()') + + -- Jumps to the definition of the type symbol + bufmap('n', 'go', 'lua vim.lsp.buf.type_definition()') + + -- Lists all the references + bufmap('n', 'gr', 'lua vim.lsp.buf.references()') + + -- Displays a function's signature information + bufmap('n', 'gs', 'lua vim.lsp.buf.signature_help()') + + -- Renames all references to the symbol under the cursor + bufmap('n', '', 'lua vim.lsp.buf.rename()') + + -- Selects a code action available at the current cursor position + bufmap('n', '', 'lua vim.lsp.buf.code_action()') + bufmap('x', '', 'lua vim.lsp.buf.range_code_action()') + + -- Show diagnostics in a floating window + bufmap('n', 'gl', 'lua vim.diagnostic.open_float()') + + -- Move to the previous diagnostic + bufmap('n', '[d', 'lua vim.diagnostic.goto_prev()') + + -- Move to the next diagnostic + bufmap('n', ']d', 'lua vim.diagnostic.goto_next()') + end + }) + + vim.opt.completeopt = {'menu', 'menuone', 'noselect'} + local cmp = require('cmp') + local select_opts = {behavior = cmp.SelectBehavior.Select} + cmp.setup({ + sources = { + {name = 'path'}, + {name = 'nvim_lsp', keyword_length = 1}, + {name = 'buffer', keyword_length = 3}, + {name = 'luasnip', keyword_length = 2}, + }, + window = { + documentation = cmp.config.window.bordered() + }, + formatting = { + fields = {'menu', 'abbr', 'kind'} + }, + mapping = { + [''] = cmp.mapping.confirm({select = false}), + [''] = cmp.mapping.select_prev_item(select_opts), + [''] = cmp.mapping.select_next_item(select_opts), + + [''] = cmp.mapping.select_prev_item(select_opts), + [''] = cmp.mapping.select_next_item(select_opts), + + [''] = cmp.mapping.scroll_docs(-4), + [''] = cmp.mapping.scroll_docs(4), + + [''] = cmp.mapping.abort(), + [''] = cmp.mapping.confirm({select = true}), + [''] = cmp.mapping.confirm({select = false}), + [''] = cmp.mapping(function(fallback) + local col = vim.fn.col('.') - 1 + + if cmp.visible() then + cmp.select_next_item(select_opts) + elseif col == 0 or vim.fn.getline('.'):sub(col, col):match('%s') then + fallback() + else + cmp.complete() + end + end, {'i', 's'}), + [''] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item(select_opts) + else + fallback() + end + end, {'i', 's'}), + + + } + }) + EOF ''; };