From 2eed62260129db6ceef31c8ded154f122f9474d9 Mon Sep 17 00:00:00 2001
From: Alexander Gehrke <github@qwertyuiop.de>
Date: Wed, 11 Aug 2021 12:25:50 +0200
Subject: [PATCH] Large cleanup and switch to NVIM LSP

---
 after/ftplugin/scala.vim | 24 +----------
 after/plugin/c.vim       | 12 ++++++
 after/plugin/compe.vim   |  7 ++++
 after/plugin/fswitch.vim |  9 ----
 after/plugin/gina.vim    |  2 +
 init.vim                 | 68 ++++++++++--------------------
 lua/conf/compe.lua       | 33 +++++++++++++++
 lua/conf/trouble.lua     |  5 +++
 lua/lsputils.lua         |  8 ++++
 lua/my-lsp.lua           | 91 ++++++++++++++++++++++++++++++++++++++++
 packages.vim             | 22 +++++++++-
 plugin/codelines.vim     |  2 +-
 plugin/editft.vim        |  2 +-
 plugin/smartq.vim        | 19 +++++++++
 14 files changed, 221 insertions(+), 83 deletions(-)
 create mode 100644 after/plugin/c.vim
 create mode 100644 after/plugin/compe.vim
 delete mode 100644 after/plugin/fswitch.vim
 create mode 100644 after/plugin/gina.vim
 create mode 100644 lua/conf/compe.lua
 create mode 100644 lua/conf/trouble.lua
 create mode 100644 lua/lsputils.lua
 create mode 100644 lua/my-lsp.lua
 create mode 100644 plugin/smartq.vim

diff --git a/after/ftplugin/scala.vim b/after/ftplugin/scala.vim
index de9bb9a..60759ed 100644
--- a/after/ftplugin/scala.vim
+++ b/after/ftplugin/scala.vim
@@ -1,27 +1,5 @@
-noremap <Leader>f :Autoformat<CR>
-
 imap //< <Plug>(codelines-close)<CR>
 map <silent> <buffer> <leader>cl :call jobstart(['codelines', '.'])<cr>
 
-nnoremap <silent> K :call <SID>show_documentation()<CR>
-
-function! s:show_documentation()
-	if (index(['vim','help'], &filetype) >= 0)
-		execute 'h '.expand('<cword>')
-	else
-		call CocAction('doHover')
-	endif
-endfunction
-
-" Toggle panel with Tree Views
-nnoremap <silent> <space>t :<C-u>CocCommand metals.tvp<CR>
-" Toggle Tree View 'metalsPackages'
-nnoremap <silent> <space>tp :<C-u>CocCommand metals.tvp metalsPackages<CR>
-" Toggle Tree View 'metalsCompile'
-nnoremap <silent> <space>tc :<C-u>CocCommand metals.tvp metalsCompile<CR>
-" Toggle Tree View 'metalsBuild'
-nnoremap <silent> <space>tb :<C-u>CocCommand metals.tvp metalsBuild<CR>
-" Reveal current current class (trait or object) in Tree View 'metalsPackages'
-nnoremap <silent> <space>tf :<C-u>CocCommand metals.revealInTreeView metalsPackages<CR>
-
 set tw=120
+set foldlevel=99
diff --git a/after/plugin/c.vim b/after/plugin/c.vim
new file mode 100644
index 0000000..09e6281
--- /dev/null
+++ b/after/plugin/c.vim
@@ -0,0 +1,12 @@
+
+"{{{ c header gates
+function! s:insert_gates()
+	let gatename = substitute(toupper(expand("%:t")), "\\.", "_", "g")
+	execute "normal! i#ifndef " . gatename
+	execute "normal! o#define " . gatename
+	execute "normal! Go#endif /* " . gatename . " */"
+	normal! kk
+endfunction
+autocmd BufNewFile *.{h,hpp} call <SID>insert_gates()
+
+"}}}
diff --git a/after/plugin/compe.vim b/after/plugin/compe.vim
new file mode 100644
index 0000000..a4ea8a8
--- /dev/null
+++ b/after/plugin/compe.vim
@@ -0,0 +1,7 @@
+if exists('g:loaded_compe')
+	inoremap <silent><expr> <C-Space> compe#complete()
+	inoremap <silent><expr> <CR>      compe#confirm('<CR>')
+	inoremap <silent><expr> <C-e>     compe#close('<C-e>')
+	inoremap <silent><expr> <C-f>     compe#scroll({ 'delta': +4 })
+	inoremap <silent><expr> <C-d>     compe#scroll({ 'delta': -4 })
+endif
diff --git a/after/plugin/fswitch.vim b/after/plugin/fswitch.vim
deleted file mode 100644
index 2dba22f..0000000
--- a/after/plugin/fswitch.vim
+++ /dev/null
@@ -1,9 +0,0 @@
-nmap <silent> <Leader>of :FSHere<cr>
-nmap <silent> <Leader>ol :FSRight<cr>
-nmap <silent> <Leader>oL :FSSplitRight<cr>
-nmap <silent> <Leader>oh :FSLeft<cr>
-nmap <silent> <Leader>oH :FSSplitLeft<cr>
-nmap <silent> <Leader>ok :FSAbove<cr>
-nmap <silent> <Leader>oK :FSSplitAbove<cr>
-nmap <silent> <Leader>oj :FSBelow<cr>
-nmap <silent> <Leader>oJ :FSSplitBelow<cr>
diff --git a/after/plugin/gina.vim b/after/plugin/gina.vim
new file mode 100644
index 0000000..d22531a
--- /dev/null
+++ b/after/plugin/gina.vim
@@ -0,0 +1,2 @@
+map <C-g>s <cmd>Gina status<cr>
+map <C-g>a <cmd>Gina add --patch<cr>
diff --git a/init.vim b/init.vim
index 062d641..cc897d1 100644
--- a/init.vim
+++ b/init.vim
@@ -32,6 +32,7 @@ set ttimeout
 set ttimeoutlen=50
 
 set foldmethod=syntax
+set foldlevelstart=99
 
 " disables visualbell
 set vb t_vb=
@@ -51,8 +52,12 @@ set suffixes+=.pdf
 set wildmenu
 set hidden
 
-set completeopt=menu,noinsert,preview
-inoremap <expr> <CR> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>"
+" set completeopt=menu,noinsert,preview
+set completeopt=menuone,noinsert,noselect
+set shortmess+=c
+imap <tab> <Plug>(completion_smart_tab)
+imap <s-tab> <Plug>(completion_smart_s_tab)
+inoremap <expr> <CR>    pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>"
 
 set mouse=
 
@@ -67,6 +72,8 @@ set spelllang=de
 set termguicolors
 set pumblend=20
 
+set updatetime=300
+
 " custom commands
 command! RC edit $MYVIMRC
 command! SRC source $MYVIMRC
@@ -109,47 +116,13 @@ augroup END
 
 "}}}
 
-"{{{ c header gates
-function! s:insert_gates()
-	let gatename = substitute(toupper(expand("%:t")), "\\.", "_", "g")
-	execute "normal! i#ifndef " . gatename
-	execute "normal! o#define " . gatename
-	execute "normal! Go#endif /* " . gatename . " */"
-	normal! kk
-endfunction
-autocmd BufNewFile *.{h,hpp} call <SID>insert_gates()
-
-"}}}
-
 " common mappings {{{
 
 nnoremap <space> za
-vnoremap <silent> . :normal .<CR>
+vnoremap <silent> . <cmd>normal .<CR>
 
 tnoremap <C-q> <C-\><C-n>
 
-"nnoremap q: :q
-"nnoremap <leader>: q:
-nnoremap <silent> q :<C-u>call <SID>SmartQ()<CR>
-function! s:SmartQ()
-  if exists("g:recording_macro")
-    let r = g:recording_macro
-    unlet g:recording_macro
-    normal! q
-    execute 'let @'.r.' = @'.r.'[:-2]'
-  else
-    let c = nr2char(getchar())
-    if c == ':'
-      call feedkeys(":q")
-    else
-      if c =~ '\v[0-9a-zA-Z"]'
-        let g:recording_macro = c
-      endif
-      execute 'normal! q'.c
-    endif
-  endif
-endfunction
-
 map <Left>  <C-w>h
 map <Down>  <C-w>j
 map <Up>    <C-w>k
@@ -181,30 +154,31 @@ nnoremap Y y$
 
 inoremap <C-Space> <C-x><C-o>
 
-nmap <C-L>         :noh<cr>:redraw!<cr>
-
-nmap <F9>	   :make<CR>
-nmap <leader>m  :make<CR>
+nmap <C-L>         <cmd>noh<cr><cmd>redraw!<cr>
 
 nmap <C-Tab> <C-w><C-w>
 imap <C-Tab> <esc><C-w><C-w>
 
-vmap <silent> gs :'<,'>sort<cr>
+vmap <silent> gs <cmd>'<,'>sort<cr>
 
 "}}}
 
 
 "Git {{{
-nmap <Leader>gu         :GitPush<CR>
-nmap <Leader>gvc        :!git svn dcommit<CR>
-nmap <Leader>gvf        :!git svn fetch<CR>
+nmap <Leader>gu         <cmd>Gina push<CR>
+nmap <Leader>gvc        <cmd>!git svn dcommit<CR>
+nmap <Leader>gvf        <cmd>!git svn fetch<CR>
 " Git }}}
 
 let g:signify_vcs_list = [ 'git', 'hg' ]
-let g:signify_disable_by_default = 1
+"let g:signify_disable_by_default = 1
 
 
-let g:localvimrc_whitelist='/home/crater2150/code/.*'
+let g:localvimrc_whitelist='/home/crater2150/work/.*'
 let g:localvimrc_sandbox=0
 
+lua require("my-lsp")
+lua require("lsputils")
+"lua require("conf.compe")
+lua require("conf.trouble")
 " vi:foldmethod=marker sw=2
diff --git a/lua/conf/compe.lua b/lua/conf/compe.lua
new file mode 100644
index 0000000..5bbdc83
--- /dev/null
+++ b/lua/conf/compe.lua
@@ -0,0 +1,33 @@
+require'compe'.setup {
+  enabled = true;
+  autocomplete = true;
+  debug = false;
+  min_length = 1;
+  preselect = 'enable';
+  throttle_time = 80;
+  source_timeout = 200;
+  resolve_timeout = 800;
+  incomplete_delay = 400;
+  max_abbr_width = 100;
+  max_kind_width = 100;
+  max_menu_width = 100;
+  documentation = {
+    border = { '', '' ,'', ' ', '', '', '', ' ' }, -- the border option is the same as `|help nvim_open_win|`
+    winhighlight = "NormalFloat:CompeDocumentation,FloatBorder:CompeDocumentationBorder",
+    max_width = 120,
+    min_width = 60,
+    max_height = math.floor(vim.o.lines * 0.3),
+    min_height = 1,
+  };
+
+  source = {
+    path = true;
+    buffer = true;
+    calc = true;
+    nvim_lsp = true;
+    nvim_lua = true;
+    vsnip = true;
+    ultisnips = true;
+    luasnip = true;
+  };
+}
diff --git a/lua/conf/trouble.lua b/lua/conf/trouble.lua
new file mode 100644
index 0000000..a4f5bbb
--- /dev/null
+++ b/lua/conf/trouble.lua
@@ -0,0 +1,5 @@
+require("trouble").setup {
+  -- your configuration comes here
+  -- or leave it empty to use the default settings
+  -- refer to the configuration section below
+}
diff --git a/lua/lsputils.lua b/lua/lsputils.lua
new file mode 100644
index 0000000..fc1c315
--- /dev/null
+++ b/lua/lsputils.lua
@@ -0,0 +1,8 @@
+vim.lsp.handlers['textDocument/codeAction'] = require'lsputil.codeAction'.code_action_handler
+vim.lsp.handlers['textDocument/references'] = require'lsputil.locations'.references_handler
+vim.lsp.handlers['textDocument/definition'] = require'lsputil.locations'.definition_handler
+vim.lsp.handlers['textDocument/declaration'] = require'lsputil.locations'.declaration_handler
+vim.lsp.handlers['textDocument/typeDefinition'] = require'lsputil.locations'.typeDefinition_handler
+vim.lsp.handlers['textDocument/implementation'] = require'lsputil.locations'.implementation_handler
+vim.lsp.handlers['textDocument/documentSymbol'] = require'lsputil.symbols'.document_handler
+vim.lsp.handlers['workspace/symbol'] = require'lsputil.symbols'.workspace_handler
diff --git a/lua/my-lsp.lua b/lua/my-lsp.lua
new file mode 100644
index 0000000..ee80fa0
--- /dev/null
+++ b/lua/my-lsp.lua
@@ -0,0 +1,91 @@
+local nvim_lsp = require('lspconfig')
+
+-- enable snippet support
+local capabilities = vim.lsp.protocol.make_client_capabilities()
+capabilities.textDocument.completion.completionItem.snippetSupport = true
+capabilities.textDocument.completion.completionItem.resolveSupport = {
+  properties = {
+    'documentation',
+    'detail',
+    'additionalTextEdits',
+  }
+}
+
+-- Use an on_attach function to only map the following keys
+-- after the language server attaches to the current buffer
+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
+
+	--Enable completion triggered by <c-x><c-o>
+	buf_set_option('omnifunc', 'v:lua.vim.lsp.omnifunc')
+
+	-- Mappings.
+	local opts = { noremap=true, silent=true }
+
+	-- See `:help vim.lsp.*` for documentation on any of the below functions
+	buf_set_keymap('n', 'gD', '<Cmd>lua vim.lsp.buf.declaration()<CR>', opts)
+	buf_set_keymap('n', 'gd', '<Cmd>lua vim.lsp.buf.definition()<CR>', opts)
+	buf_set_keymap('n', 'K', '<Cmd>lua vim.lsp.buf.hover()<CR>', opts)
+	buf_set_keymap('v', 'K', '<Cmd>lua vim.lsp.buf.hover()<CR>', opts)
+	buf_set_keymap('n', 'gi', '<cmd>lua vim.lsp.buf.implementation()<CR>', opts)
+	buf_set_keymap('n', '<C-k>', '<cmd>lua vim.lsp.buf.signature_help()<CR>', opts)
+	buf_set_keymap('n', '<Leader>D', '<cmd>lua vim.lsp.buf.type_definition()<CR>', opts)
+	buf_set_keymap('n', '<Leader>rn', '<cmd>lua vim.lsp.buf.rename()<CR>', opts)
+	buf_set_keymap('n', '<M-a>', '<cmd>lua vim.lsp.buf.code_action()<CR>', opts)
+	buf_set_keymap('n', 'gr', '<cmd>lua vim.lsp.buf.references()<CR>', opts)
+	buf_set_keymap('n', '<M-e>', '<cmd>lua vim.lsp.diagnostic.show_line_diagnostics()<CR>', opts)
+	buf_set_keymap('n', '[d', '<cmd>lua vim.lsp.diagnostic.goto_prev()<CR>', opts)
+	buf_set_keymap('n', ']d', '<cmd>lua vim.lsp.diagnostic.goto_next()<CR>', opts)
+	buf_set_keymap('n', '<M-q>', '<cmd>lua vim.lsp.diagnostic.set_loclist()<CR>', opts)
+	buf_set_keymap("n", "<Leader>f", "<cmd>lua vim.lsp.buf.formatting()<CR>", opts)
+	require'completion'.on_attach(client, bufnr)
+end
+
+
+require'lspinstall'.setup() -- important
+
+local servers = require'lspinstall'.installed_servers()
+for _, server in pairs(servers) do
+  require'lspconfig'[server].setup{
+    on_attach = on_attach,
+    capabilities = capabilities,
+  }
+end
+
+
+metals_config = require("metals").bare_config
+metals_config.init_options.statusBarProvider = "on"
+metals_config.settings = { showImplicitArguments = true }
+metals_config.on_attach = on_attach
+
+vim.cmd [[augroup lsp]]
+vim.cmd [[au!]]
+vim.cmd [[au FileType scala,sbt lua require("metals").initialize_or_attach(metals_config)]]
+vim.cmd [[augroup end]]
+
+-- Use a loop to conveniently call 'setup' on multiple servers and
+-- map buffer local keybindings when the language server attaches
+local servers = { "lemminx" }
+for _, lsp in ipairs(servers) do
+	nvim_lsp[lsp].setup {
+		on_attach = on_attach,
+		capabilities = capabilities,
+		flags = {
+			debounce_text_changes = 150,
+		}
+	}
+end
+
+vim.lsp.handlers["textDocument/publishDiagnostics"] = vim.lsp.with(
+	vim.lsp.diagnostic.on_publish_diagnostics, {
+		virtual_text = false,
+		underline = true,
+		signs = true,
+	}
+)
+
+-- vim.cmd [[autocmd CursorMoved * lua vim.lsp.diagnostic.show_line_diagnostics()]]
+-- vim.cmd [[autocmd CursorMoved * lua vim.lsp.diagnostic.show_line_diagnostics()]]
+vim.cmd [[autocmd CursorHoldI * silent! lua vim.lsp.buf.signature_help()]]
+vim.cmd [[autocmd CursorHold * lua vim.lsp.diagnostic.show_line_diagnostics({max_width = 100, focusable = false})]]
diff --git a/packages.vim b/packages.vim
index 62fd735..84d3bf5 100644
--- a/packages.vim
+++ b/packages.vim
@@ -3,7 +3,6 @@ call plug#begin(expand('<sfile>:p:h') . '/plugged')
 " basic stuff
 Plug 'pbrisbin/vim-mkdir'
 Plug 'embear/vim-localvimrc'
-Plug 'Soares/smarttab.vim'
 
 "Plug 'crater2150/vim-theme-chroma'
 Plug '~/sources/chroma-colors/vim'
@@ -26,7 +25,26 @@ Plug 'vim-scripts/argtextobj.vim'
 
 Plug 'mhinz/vim-signify'
 
-Plug 'neoclide/coc.nvim', {'branch': 'release'}
+" LSP
+
+" Plug 'neoclide/coc.nvim', {'branch': 'release'}
+Plug 'neovim/nvim-lspconfig'
+Plug 'kabouzeid/nvim-lspinstall'
+Plug 'scalameta/nvim-metals'
+" Plug 'hrsh7th/nvim-compe'
+Plug 'nvim-lua/completion-nvim'
+Plug 'nvim-treesitter/nvim-treesitter', {'branch': '0.5-compat', 'do': ':TSUpdate'}
+Plug 'nvim-lua/lsp-status.nvim'
+Plug 'RishabhRD/popfix'
+Plug 'RishabhRD/nvim-lsputils'
+Plug 'kyazdani42/nvim-web-devicons'
+Plug 'folke/trouble.nvim'
+Plug 'folke/lsp-colors.nvim'
+Plug 'nvim-lua/popup.nvim'
+Plug 'nvim-lua/plenary.nvim'
+Plug 'nvim-telescope/telescope.nvim'
+Plug 'L3MON4D3/LuaSnip'
+
 
 Plug 'machakann/vim-highlightedyank'
 
diff --git a/plugin/codelines.vim b/plugin/codelines.vim
index 9c040fa..4774b4e 100644
--- a/plugin/codelines.vim
+++ b/plugin/codelines.vim
@@ -4,4 +4,4 @@ function! codelines#close()
 endfunction
 
 inoremap <silent> <Plug>(codelines-close) <c-r>=codelines#close()<cr>
-noremap <silent> <Plug>(codelines-go-to-def) :exec "vimgrep #//>" . strpart(expand('<cword>'), 3) . "# code/*"<cr>
+noremap <silent> <Plug>(codelines-go-to-def) <cmd>exec "vimgrep #//>" . strpart(expand('<cword>'), 3) . "# code/*"<cr>
diff --git a/plugin/editft.vim b/plugin/editft.vim
index 49726c2..9baa8be 100644
--- a/plugin/editft.vim
+++ b/plugin/editft.vim
@@ -4,5 +4,5 @@ function! s:editft()
   exec "autocmd QuitPre <buffer> source " . ftpl
 endfunction
 
-noremap <silent> <Plug>(EditFT) :call <SID>editft()<cr>
+noremap <silent> <Plug>(EditFT) <cmd>call <SID>editft()<cr>
 map <leader>ftp <Plug>(EditFT)
diff --git a/plugin/smartq.vim b/plugin/smartq.vim
new file mode 100644
index 0000000..780213c
--- /dev/null
+++ b/plugin/smartq.vim
@@ -0,0 +1,19 @@
+nnoremap <silent> q <cmd>call <SID>SmartQ()<CR>
+function! s:SmartQ()
+  if exists("g:recording_macro")
+    let r = g:recording_macro
+    unlet g:recording_macro
+    normal! q
+    execute 'let @'.r.' = @'.r.'[:-2]'
+  else
+    let c = nr2char(getchar())
+    if c == ':'
+      call feedkeys(":q")
+    else
+      if c =~ '\v[0-9a-zA-Z"]'
+        let g:recording_macro = c
+      endif
+      execute 'normal! q'.c
+    endif
+  endif
+endfunction