" ----------------------------------------------------------------------------
" vundle essentials
" ----------------------------------------------------------------------------

set nocompatible
filetype off

" set the runtime path to include Vundle and initialize
set rtp+=~/.vim/bundle/Vundle.vim

call vundle#begin()

" let vundle manage vundle...
Plugin 'VundleVim/Vundle.vim'

" Basic plugins
Plugin 'jiangmiao/auto-pairs'
Plugin 'preservim/nerdtree'
Plugin 'jeetsukumaran/vim-buffergator'

" IDE like plugins
Plugin 'prabirshrestha/asyncomplete.vim'
Plugin 'prabirshrestha/vim-lsp'
Plugin 'prabirshrestha/asyncomplete-lsp.vim'
Plugin 'mattn/vim-lsp-settings'
Plugin 'yami-beta/asyncomplete-omni.vim'
Plugin 'prabirshrestha/asyncomplete-file.vim'

" Language autocomplete for English
Plugin 'htlsne/asyncomplete-look'

" an additional colorscheme I like
Plugin 'altercation/vim-colors-solarized'

call vundle#end()

filetype plugin indent on

" ----------------------------------------------------------------------------
" basic essentials
" ----------------------------------------------------------------------------

" don't make vim vi compatible (if not set you miss out on a lot of features!)
" you'll see this option set in most configuration files found online
set nocompatible

" enable filetype recognition plus indent and plugin (pretty much mandatory)
filetype plugin indent on    " required

" enable syntax highlighting
syntax on

" backspace can be a tricky thing and this setting make it work a lot better
set backspace=indent,eol,start

" when tab completing on the expert line you don't want to miss out on EDIT vs
" edit or nerdtree vs NERDTree and this setting ignores case completely
set ignorecase

" highlight your search patterns (very handy when building regexes)
set hlsearch

" highlight the search pattern as-you-go (tremendously helpful when
" constructing regexes)
set incsearch

" always show a status line at the bottom of your vim which shows some basic 
" information about the file, which line you're at etc
set laststatus=2

" show files in statusbar when opening via expert mode
set wildmenu

" also show all possible expert mode commands in the statusline
set wildmode=full

" reverse numbering (in the sideline) so you don't have to manually count how
" many lines you have to yank
set rnu

" it's also nice to still have your absolute line number in the sideline
set nu

" can do copy paste from the clipboard
set clipboard=unnamedplus

" automatically save buffers
set autowrite
set autowriteall 

" spaces not tabs for coding purposes
set sw=4
set ts=4
set sts=4

" mouse usage can be handy, especially when using LspPeekDefinition
set mouse=a

" enable code folding
set foldmethod=indent

" set SPACE to toggle a fold
nnoremap <SPACE> za

" set the leader key for shortcuts (uncomment if you don't want it to be the
" default \ key
"let mapleader=";"

" ----------------------------------------------------------------------------
" plugin configuration
" ----------------------------------------------------------------------------

" NERDTree
" --------

" map a keyboard shortcut to show and hide NERDTree
nnoremap <C-t> :NERDTreeToggle<CR>

" Exit Vim if NERDTree is the only window remaining in the only tab.
autocmd BufEnter * if tabpagenr('$') == 1 && winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree() | quit | endif

" vim-lsp
" -------

" general vim-lsp settings
" ------------------------

" maps quite q few keyboad shortcuts
" this is taken staight off the github page with one added shortcut to peak at
" the definition of a function or class
function! s:on_lsp_buffer_enabled() abort
	setlocal omnifunc=lsp#complete
    setlocal signcolumn=yes
    if exists('+tagfunc') | setlocal tagfunc=lsp#tagfunc | endif
    nmap <buffer> gd <plug>(lsp-definition)
    nmap <buffer> gpd <plug>(lsp-peek-definition)
    nmap <buffer> gs <plug>(lsp-document-symbol-search)
    nmap <buffer> gS <plug>(lsp-workspace-symbol-search)
    nmap <buffer> gr <plug>(lsp-references)
    nmap <buffer> gi <plug>(lsp-implementation)
    nmap <buffer> gt <plug>(lsp-type-definition)
    nmap <buffer> <leader>rn <plug>(lsp-rename)
    nmap <buffer> [g <plug>(lsp-previous-diagnostic)
    nmap <buffer> ]g <plug>(lsp-next-diagnostic)
    nmap <buffer> K <plug>(lsp-hover)
    inoremap <buffer> <expr><c-f> lsp#scroll(+4)
    inoremap <buffer> <expr><c-d> lsp#scroll(-4)

    let g:lsp_format_sync_timeout = 2000
    autocmd! BufWritePre *.rs,*.go call execute('LspDocumentFormatSync')
endfunction

augroup lsp_install
    au!
    " call s:on_lsp_buffer_enabled only for languages that has the server registered.
    autocmd User lsp_buffer_enabled call s:on_lsp_buffer_enabled()
augroup END

" asyncomplete
" ------------

" make tab complete work
inoremap <expr> <Tab>   pumvisible() ? "\<C-n>" : "\<Tab>"
inoremap <expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>"
inoremap <expr> <cr>    pumvisible() ? asyncomplete#close_popup() : "\<cr>"

" force refresh with CTRL-SPACE
imap <c-@> <Plug>(asyncomplete_force_refresh)

" asyncomplete-file
" -----------------

au User asyncomplete_setup call asyncomplete#register_source(asyncomplete#sources#file#get_source_options({
	\ 'name': 'file',
    \ 'allowlist': ['*'],
    \ 'priority': 10,
    \ 'completor': function('asyncomplete#sources#file#completor')
    \ }))

" asyncomplete-omni
" -----------------

autocmd User asyncomplete_setup call asyncomplete#register_source(asyncomplete#sources#omni#get_source_options({
	\ 'name': 'omni',
	\ 'allowlist': ['*'],
	\ 'blocklist': ['c', 'cpp', 'html'],
	\ 'completor': function('asyncomplete#sources#omni#completor'),
	\ 'config': {
	\   'show_source_kind': 1,
	\ },
	\ }))

" asyncomplete-look
" -----------------

au User asyncomplete_setup call asyncomplete#register_source({
	\ 'name': 'look',
    \ 'allowlist': ['text', 'markdown'],
    \ 'completor': function('asyncomplete#sources#look#completor'),
    \ })

" ----------------------------------------------------------------------------
" visual configuration
" ----------------------------------------------------------------------------

" set a colorscheme
colorscheme solarized
set background=dark

" do soft wrap of text but not in the middle of words
set wrap linebreak nolist

" don't do hard wraps in any files
set textwidth=0

" add a color column at the 80 char
set colorcolumn=80

" spelling highlight needs to be done after the colorscheme load                
highlight SpellBad term=underline cterm=underline 

" enable English spellchecking in markdown files
autocmd FileType markdown setlocal spell
autocmd FileType markdown setlocal spelllang=en
