diff --git a/nvim-config/coc-settings.json b/nvim-config/coc-settings.json deleted file mode 100644 index 2ebdeae..0000000 --- a/nvim-config/coc-settings.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "languageserver": { - "haskell": { - "command": "haskell-language-server-wrapper", - "args": ["--lsp"], - "rootPatterns": ["*.cabal", "stack.yaml", "cabal.project", "package.yaml", "hie.yaml"], - "filetypes": ["haskell", "lhaskell"] - } - }, - "coc.source.iced.enable": true, - "coc.preferences.formatOnSaveFiletypes": ["css","markdown"], - "diagnostic-languageserver.filetypes": { - "vim": "vint", - "email": "languagetool", - "markdown": [ "write-good", "markdownlint" ], - "sh": "shellcheck", - "bash": "shellcheck", - "elixir": ["mix_credo", "mix_credo_compile"], - "eelixir": ["mix_credo", "mix_credo_compile"], - "php": ["phpstan", "psalm"], - "yaml": [ "yamllint" ], - "cmake": [ "cmake-lint", "cmakelint" ], - "systemd": "systemd-analyze" - }, - "diagnostic-languageserver.formatFiletypes": { - "dart": "dartfmt", - "elixir": "mix_format", - "eelixir": "mix_format", - "python": ["black", "isort"], - "lua": "lua-format", - "sh": "shfmt", - "bash": "shfmt", - "blade": "blade-formatter", - "cmake": "cmake-format" - } -} diff --git a/nvim-config/init.vim b/nvim-config/init.vim index 1ec7f6c..4f0cbbf 100644 --- a/nvim-config/init.vim +++ b/nvim-config/init.vim @@ -60,13 +60,6 @@ Plug 'mhinz/vim-sayonara' " Session-Management Plug 'xolox/vim-session' | Plug 'xolox/vim-misc' -" CoC -Plug 'neoclide/coc.nvim', {'branch': 'release'} - -" Clojure -Plug 'guns/vim-sexp', {'for': 'clojure'} -Plug 'liquidz/vim-iced', {'for': 'clojure'} -Plug 'liquidz/vim-iced-coc-source', {'for': 'clojure'} " todo.txt Plug 'freitass/todo.txt-vim' @@ -74,14 +67,21 @@ Plug 'freitass/todo.txt-vim' " LSP Plug 'williamboman/mason.nvim' Plug 'williamboman/mason-lspconfig.nvim' -Plug 'neovim/nvim-lspconfig', {'branch': 'v0.1.6'} +Plug 'neovim/nvim-lspconfig' +Plug 'hrsh7th/cmp-nvim-lsp' +Plug 'hrsh7th/cmp-buffer' +Plug 'hrsh7th/cmp-path' +Plug 'hrsh7th/cmp-cmdline' +Plug 'hrsh7th/nvim-cmp' +Plug 'onsails/lspkind.nvim' + +" For vsnip users. +Plug 'hrsh7th/cmp-vsnip' +Plug 'hrsh7th/vim-vsnip' -" Go -Plug 'fatih/vim-go', {'do':':GoUpdateBinaries'} call plug#end() - -" SETTINGS +" GENERAL VIM SETUP " set leader to space let mapleader= "\" @@ -119,7 +119,7 @@ set smartcase " ... unless the query has capital letters. set incsearch " Incremental search. set gdefault " Use 'g' flag by default with :s/foo/bar/. set magic " Use 'magic' patterns (extended regular expressions). -"set inccommand=nosplit " Use live-preview of search/replace etc. +set inccommand=nosplit " Use live-preview of search/replace etc. set conceallevel=2 " Allow things to be visually opressed (i.e. *foo* be italic) set mouse=a " enable mouse set foldenable " enable folding @@ -133,46 +133,13 @@ set hidden let g:loaded_perl_provider = 0 -" LSP Config - -lua << EOF -require("mason").setup() -require("mason-lspconfig").setup() -EOF - -" Use to clear the highlighting of :set hlsearch. -if maparg('', 'n') ==# '' - nnoremap :nohlsearch -endif - " Remember cursor position between vim sessions - autocmd BufReadPost * - \ if line("'\"") > 0 && line ("'\"") <= line("$") | - \ exe "normal! g'\"" | - \ endif - " center buffer around cursor when opening files - autocmd BufRead * normal zz - - -"" KEY-BINDINGS - -" use to fold/unfold - -nnoremap za - -" : completion -function! CheckBackSpace() abort - let col = col('.') - 1 - return !col || getline('.')[col - 1] =~ '\s' -endfunction -inoremap - \ pumvisible() ? "\" : - \ CheckBackSpace() ? "\" : - \ coc#refresh() -" : completion back -inoremap pumvisible() ? "\" : "\" -" : confirm completion, or insert -inoremap pumvisible() ? "\" : "\" +autocmd BufReadPost * + \ if line("'\"") > 0 && line ("'\"") <= line("$") | + \ exe "normal! g'\"" | + \ endif + " center buffer around cursor when opening files +autocmd BufRead * normal zz " use to Jump to definition instead of (default) nmap @@ -184,129 +151,204 @@ inoremap ddi tnoremap -""""""""""""""""""""""""""""""""""""""""""""" Coc Keys -" 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) +" FANCY NEOVIM-MAGIC -" GoTo code navigation -nmap gd (coc-definition) -nmap gy (coc-type-definition) -nmap gi (coc-implementation) -nmap gr (coc-references) +" setup mason, language-server & nvim-cmp for completion +lua < K :call ShowDocumentation() + require("mason").setup() + require("mason-lspconfig").setup() -function! ShowDocumentation() - if CocAction('hasProvider', 'hover') - call CocActionAsync('doHover') - else - call feedkeys('K', 'in') - endif -endfunction + local has_words_before = function() + unpack = unpack or table.unpack + local line, col = unpack(vim.api.nvim_win_get_cursor(0)) + return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil + end -" Highlight the symbol and its references when holding the cursor -autocmd CursorHold * silent call CocActionAsync('highlight') + local feedkey = function(key, mode) + vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true) + end -" Symbol renaming -nmap rn (coc-rename) + -- Set up nvim-cmp. + local cmp = require'cmp' + local lspkind = require'lspkind' -" Formatting selected code -xmap f (coc-format-selected) -nmap f (coc-format-selected) + cmp.setup({ + snippet = { + -- REQUIRED - you must specify a snippet engine + expand = function(args) + vim.fn["vsnip#anonymous"](args.body) -- For `vsnip` users. + -- require('luasnip').lsp_expand(args.body) -- For `luasnip` users. + -- require('snippy').expand_snippet(args.body) -- For `snippy` users. + -- vim.fn["UltiSnips#Anon"](args.body) -- For `ultisnips` users. + end, + formatting = { + format = lspkind.cmp_format(), + }, + }, + window = { + -- completion = cmp.config.window.bordered(), + -- documentation = cmp.config.window.bordered(), + }, + mapping = cmp.mapping.preset.insert({ + [''] = cmp.mapping.scroll_docs(-4), + [''] = cmp.mapping.scroll_docs(4), + [''] = cmp.mapping.complete(), + [''] = cmp.mapping.abort(), + [''] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items. + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + if #cmp.get_entries() == 1 then + cmp.confirm({ select = true }) + else + cmp.select_next_item() + end + elseif vim.fn["vsnip#available"](1) == 1 then + feedkey("(vsnip-expand-or-jump)", "") + elseif has_words_before() then + cmp.complete() + if #cmp.get_entries() == 1 then + cmp.confirm({ select = true }) + end + else + fallback() -- The fallback function sends a already mapped key. In this case, it's probably ``. + end + end, { "i", "s" }), -augroup mygroup - autocmd! - " Setup formatexpr specified filetype(s) - autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected') - " Update signature help on jump placeholder - autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp') -augroup end + [""] = cmp.mapping(function() + if cmp.visible() then + cmp.select_prev_item() + elseif vim.fn["vsnip#jumpable"](-1) == 1 then + feedkey("(vsnip-jump-prev)", "") + end + end, { "i", "s" }), -" Applying code actions to the selected code block -" Example: `aap` for current paragraph -xmap a (coc-codeaction-selected) -nmap a (coc-codeaction-selected) + }), + sources = cmp.config.sources({ + { name = 'nvim_lsp' }, + { name = 'vsnip' }, -- For vsnip users. + -- { name = 'luasnip' }, -- For luasnip users. + -- { name = 'ultisnips' }, -- For ultisnips users. + -- { name = 'snippy' }, -- For snippy users. + }, { + { name = 'buffer' }, + }) + }) -" Remap keys for applying code actions at the cursor position -nmap ac (coc-codeaction-cursor) -" Remap keys for apply code actions affect whole buffer -nmap as (coc-codeaction-source) -" Apply the most preferred quickfix action to fix diagnostic on the current line -nmap qf (coc-fix-current) + -- Set configuration for specific filetype. + cmp.setup.filetype('gitcommit', { + sources = cmp.config.sources({ + { name = 'git' }, -- You can specify the `git` source if [you were installed it](https://github.com/petertriho/cmp-git). + }, { + { name = 'buffer' }, + }) + }) -" Remap keys for applying refactor code actions -nmap re (coc-codeaction-refactor) -xmap r (coc-codeaction-refactor-selected) -nmap r (coc-codeaction-refactor-selected) + -- Use buffer source for `/` and `?` (if you enabled `native_menu`, this won't work anymore). + cmp.setup.cmdline({ '/', '?' }, { + mapping = cmp.mapping.preset.cmdline(), + sources = { + { name = 'buffer' } + } + }) -" Run the Code Lens action on the current line -nmap cl (coc-codelens-action) + -- Use cmdline & path source for ':' (if you enabled `native_menu`, this won't work anymore). + cmp.setup.cmdline(':', { + mapping = cmp.mapping.preset.cmdline(), + sources = cmp.config.sources({ + { name = 'path' } + }, { + { name = 'cmdline' } + }) + }) -" Map function and class text objects -" NOTE: Requires 'textDocument.documentSymbol' support from the language server -xmap if (coc-funcobj-i) -omap if (coc-funcobj-i) -xmap af (coc-funcobj-a) -omap af (coc-funcobj-a) -xmap ic (coc-classobj-i) -omap ic (coc-classobj-i) -xmap ac (coc-classobj-a) -omap ac (coc-classobj-a) + -- Set up lspconfig. + local capabilities = require('cmp_nvim_lsp').default_capabilities() -" Remap and to scroll float windows/popups -if has('nvim-0.4.0') || has('patch-8.2.0750') - nnoremap coc#float#has_scroll() ? coc#float#scroll(1) : "\" - nnoremap coc#float#has_scroll() ? coc#float#scroll(0) : "\" - inoremap coc#float#has_scroll() ? "\=coc#float#scroll(1)\" : "\" - inoremap coc#float#has_scroll() ? "\=coc#float#scroll(0)\" : "\" - vnoremap coc#float#has_scroll() ? coc#float#scroll(1) : "\" - vnoremap coc#float#has_scroll() ? coc#float#scroll(0) : "\" -endif + local on_attach = function(client, bufnr) + local function buf_set_keymap(...) vim.api.nvim_buf_set_keymap(bufnr, ...) end + local function buf_set_option(...) vim.api.nvim_buf_set_option(bufnr, ...) end -" Use CTRL-S for selections ranges -" Requires 'textDocument/selectionRange' support of language server -nmap (coc-range-select) -xmap (coc-range-select) + buf_set_option('omnifunc', 'v:lua.vim.lsp.omnifunc') + end -" Add `:Format` command to format current buffer -command! -nargs=0 Format :call CocActionAsync('format') + require("lspconfig").gopls.setup { + cmd = {'gopls'}, + -- on_attach = on_attach, + capabilities = capabilities, + settings = { + gopls = { + experimentalPostfixCompletions = true, + analyses = { + unusedparams = true, + shadow = true, + }, + staticcheck = true, + }, + }, + init_options = { + usePlaceholders = true, + } + } + require("lspconfig").eslint.setup {} + require("lspconfig").jsonls.setup {} + require("lspconfig").tsserver.setup {} + require("lspconfig").ast_grep.setup {} + require("lspconfig").golangci_lint_ls.setup {} -" Add `:Fold` command to fold current buffer -command! -nargs=? Fold :call CocAction('fold', ) + function swallow_output(callback, ...) + local old_print = print + print = function(...) end -" Add `:OR` command for organize imports of the current buffer -command! -nargs=0 OR :call CocActionAsync('runCommand', 'editor.action.organizeImport') + pcall(callback, arg) -" Add (Neo)Vim's native statusline support -" NOTE: Please see `:h coc-status` for integrations with external plugins that -" provide custom statusline: lightline.vim, vim-airline -set statusline^=%{coc#status()}%{get(b:,'coc_current_function','')} + print = old_print + end -" Mappings for CoCList -" Show all diagnostics -nnoremap a :CocList diagnostics -" Manage extensions -nnoremap e :CocList extensions -" Show commands -nnoremap c :CocList commands -" Find symbol of current document -nnoremap o :CocList outline -" Search workspace symbols -nnoremap s :CocList -I symbols -" Do default action for next item -nnoremap j :CocNext -" Do default action for previous item -nnoremap k :CocPrev -" Resume latest coc list -nnoremap p :CocListResume + -- See `:help vim.diagnostic.*` for documentation on any of the below functions + vim.keymap.set('n', 'e', vim.diagnostic.open_float) + vim.keymap.set('n', '[d', vim.diagnostic.goto_prev) + vim.keymap.set('n', ']d', vim.diagnostic.goto_next) + vim.keymap.set('n', 'q', vim.diagnostic.setloclist) + + -- Use LspAttach autocommand to only map the following keys + -- after the language server attaches to the current buffer + vim.api.nvim_create_autocmd('LspAttach', { + group = vim.api.nvim_create_augroup('UserLspConfig', {}), + callback = function(ev) + + -- Buffer local mappings. + -- See `:help vim.lsp.*` for documentation on any of the below functions + local opts = { buffer = ev.buf } + vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, opts) + vim.keymap.set('n', 'gd', vim.lsp.buf.definition, opts) + vim.keymap.set('n', 'K', vim.lsp.buf.hover, opts) + vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, opts) + vim.keymap.set('n', '', vim.lsp.buf.signature_help, opts) + vim.keymap.set('n', 'wa', vim.lsp.buf.add_workspace_folder, opts) + vim.keymap.set('n', 'wr', vim.lsp.buf.remove_workspace_folder, opts) + vim.keymap.set('n', 'wl', function() + print(vim.inspect(vim.lsp.buf.list_workspace_folders())) + end, opts) + vim.keymap.set('n', 'D', vim.lsp.buf.type_definition, opts) + vim.keymap.set('n', 'rn', vim.lsp.buf.rename, opts) + vim.keymap.set({ 'n', 'v' }, 'ca', vim.lsp.buf.code_action, opts) + vim.keymap.set('n', 'gr', vim.lsp.buf.references, opts) + vim.keymap.set('v', 'f', function() + vim.lsp.buf.format { async = true } + end, opts) + vim.api.nvim_create_autocmd('BufWrite', { + callback = function(ev) + vim.lsp.buf.format { async = false } + end + }) + end, + }) +EOF + +"" KEY-BINDINGS -"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" -" autoformat code if possible (read docs on vim-autoformat!) -"noremap f :Autoformat noremap TM :TableModeToggle " multi-cursor