" General Options {{{1
" ====================
set nocompatible      " ignored in NeoVim, tells Vim to break compatibility with vi

let mapleader=';'     " set <leader>

syntax enable

set mouse=a           " enable mouse selection
set splitright        " open new splits on the right
set splitbelow        " open new splits below
set scrolloff=4       " keep the cursor 4 lines away from the top/bottom
set ruler             " show the lines/% bottom right
set showcmd           " show the commands while typing
set laststatus=2      " always show the status line
set encoding=utf-8    " set default encoding
set autoread          " autoreload file on change

set inccommand=split

set conceallevel=0    " don't use conceals, seriously
let g:tex_conceal=''  " I said no conceals

set shell=/bin/zsh    " use zsh instead of bash

set number            " line numbers on the left side
set relativenumber    " number+relativenumber = relative numbers for all but current line
" toggle hybrid relative numbers when entering/leaving insert mode
":augroup numbertoggle
":  autocmd!
":  autocmd InsertLeave * set relativenumber
":  autocmd InsertEnter * set norelativenumber
":augroup END

" use the nice `par` program to wrap lines at 99 characters
" TODO pass the current textwidth to par?
"set formatprg=par\ -w99
set formatoptions=tcrqnlmj
set textwidth=99

set ignorecase smartcase   " don't match case if typing in all-lowercase

" Ctrl+Backspace deletes previous word like in most text editors
inoremap  <esc>dba<bs>

" Switching buffers {{{2
nnoremap <silent> <F14> :bprev<cr>    " s-F2
nnoremap <silent> <F15> :bnext<cr>    " s-F3
nnoremap <silent> <F16> :bwipeout<cr> " s-F4

" Indentation {{{2
set tabstop=2         " tab is 2 wide
set shiftwidth=2      " for use with > and <
set noexpandtab       " tab key puts tabs
"set list listchars=tab:‧\ ,trail:·  " display tabs with a leading \cdot. Alternatives: \mapsto ↦, U+16EB runic single punctuation ᛫
                                    " trailing whitespace looks like \cdot
set list listchars=tab:¦\ ,trail:·  " show indentation lines for tabs, trailing whitespace looks like \cdot

" Ignore motion for < >
nnoremap < <<
nnoremap > >>
" Make < > shifts keep selection
vnoremap < <gv
vnoremap > >gv

" Folds {{{2

set foldlevelstart=3  " Not too much folding

nnoremap <silent> <Space> @=(foldlevel('.')?'za':"\<Space>")<CR>
vnoremap <Space> zf

" Misc {{{2

" Change cursor shape according to mode
:let $NVIM_TUI_ENABLE_CURSOR_SHAPE=1

" Escape from NeoVim terminals
tnoremap <Esc> <C-\><C-n>
" Just hit the [à0] button on an AZERTY, no need to do shift+à to for 0
nnoremap à   0
inoremap jj <Esc>
" Clear highlighting after a search
nnoremap <silent> <leader>n :noh<CR>

" Open a file in the current directory
nmap <leader>e :e <C-R>=expand("%:p:h") . "/" <CR>

" sudo save
command W :execute ':silent w !sudo tee % > /dev/null' | :edit!

" Navigate to bookmark, AZERTY has no backtick key
noremap <leader>m `

" Consistent aliases to jump to first non-whitespace character and last character
noremap <a-h> ^
noremap <a-l> $
inoremap <a-h> <esc>^i
inoremap <a-l> <esc>$a
noremap <home> ^
inoremap <home> <esc>^i


" System clipboard {{{2
" Copy to clipboard            " Paste from clipboard
vnoremap  <leader>y  "+y    |  nnoremap <leader>p "+p
nnoremap  <leader>Y  "+yg_  |  nnoremap <leader>P "+P
nnoremap  <leader>y  "+y    |  vnoremap <leader>p "+p
nnoremap  <leader>yy "+yy   |  vnoremap <leader>P "+P

" Opening windows {{{2
nnoremap <C-j> <C-w>n
nmap     <C-k> <C-w>N
nnoremap <C-l> <C-w>v
nmap     <C-h> <C-w>V

imap <C-w> <esc><C-w>
vmap <C-w> <esc><C-w>

nnoremap <silent> <C-w>v :vnew<CR>
nnoremap <silent> <C-w>V :let spr=&spr<BAR>set nospr<BAR>vnew<BAR>let &spr=spr<CR>
nnoremap <silent> <C-w>N :let spr=&spr<BAR>set nospr<BAR>new<BAR>let &spr=spr<CR>

" Cool arrows {{{2
inoremap <leader>akl ↗ | inoremap <leader>alk ↗
inoremap <leader>ajl ↘ | inoremap <leader>alj ↘
inoremap <leader>ajh ↙ | inoremap <leader>ahj ↙
inoremap <leader>akh ↖ | inoremap <leader>ahk ↖
inoremap <leader>ajk ↕ | inoremap <leader>akj ↕
inoremap <leader>ahl ↔ | inoremap <leader>alh ↔

inoremap <leader>dah ⇠
inoremap <leader>daj ⇣
inoremap <leader>dak ⇡
inoremap <leader>dal ⇢

inoremap <leader>aahh ⇐
inoremap <leader>aajj ⇓
inoremap <leader>aakk ⇑
inoremap <leader>aall ⇒
inoremap <leader>aakl ⇗ | inoremap <leader>aalk ⇗
inoremap <leader>aajl ⇘ | inoremap <leader>aalj ⇘
inoremap <leader>aajh ⇙ | inoremap <leader>aahj ⇙
inoremap <leader>aakh ⇖ | inoremap <leader>aahk ⇖
inoremap <leader>aajk ⇕ | inoremap <leader>aakj ⇕
inoremap <leader>aahl ⇔ | inoremap <leader>aalh ⇔

" Default visual block {{{2
nnoremap v <C-v>
nnoremap <C-v> v

" Adding modeline {{{2
" Append modeline after last line in buffer.
" Use substitute() instead of printf() to handle '%%s' modeline in LaTeX
" files.
function! AppendModeline()
  let l:modeline = printf(" vim: set ts=%d sw=%d tw=%d %set :",
        \ &tabstop, &shiftwidth, &textwidth, &expandtab ? '' : 'no')
  let l:modeline = substitute(&commentstring, "%s", l:modeline, "")
  call append(line("$"), l:modeline)
endfunction
nnoremap <silent> <leader>ml :call AppendModeline()<CR>

" Spell check {{{2
" ================
set spelllang=en_uk,nl
set spellfile=$HOME/.local/share/nvim/spellfile.utf-8.add

augroup spellcheck_textfiles
  au! BufNewFile,BufRead *.md,*.txt,*.tex setlocal spell
augroup END

" Keep undo history {{{2
" ======================
set undodir=/tmp/vim-undodir
set undofile


" Plug-ins {{{1
" =============

" Plug {{{2
" ------------
call plug#begin('~/.config/nvim/plug')

" Colors
"Plug   'chriskempson/base16-vim'
 Plug           'rakr/vim-one'

" Language support
 Plug        'sheerun/vim-polyglot'                                             " color, indentation support for 100+ languages
 Plug       'chrisbra/csv.vim',              { 'for': 'csv' }                   " CSV files
"Plug  'neovimhaskell/haskell-vim',          { 'for': 'haskell' }               " included in vim-polyglot
"Plug 'LaTeX-Box-Team/LaTeX-Box',            { 'for': 'tex' }                   " included in vim-polyglot
"Plug      'rust-lang/rust.vim',             { 'for': 'rust' }                  " included in vim-polyglot
 Plug             'ap/vim-css-color'                                            " CSS color names

" C/C++
"Plug    'vim-scripts/c.vim',                { 'for': ['c', 'cpp', 'objc'] }    " various IDE-like C features
 Plug    'vim-scripts/DoxygenToolkit.vim',   { 'for': ['c', 'cpp', 'python'] }  " simplify Doxygen documentation in C, C++, Python
"Plug     'derekwyatt/vim-fswitch',          { 'for': ['c', 'cpp', 'objc'] }    " switch between companion source files (e.g. .h and .cpp)
 Plug     'derekwyatt/vim-fswitch',          { 'on': 'FSRight' }                " switch between companion source files (e.g. .h and .cpp)
"Plug     'derekwyatt/vim-protodef',         { 'for': ['c', 'cpp', 'objc'] }    " pull in C++ function prototypes into implementation files
 Plug    'vim-scripts/Conque-GDB',           { 'for': ['c', 'cpp', 'objc'] }    " GDB command line interface and terminal emulator
"Plug         'Shougo/vimproc.vim',          { 'do': 'make' }                   " dependency of vim-vebugger, asynchronous execution library
"Plug       'idanarye/vim-vebugger',         { 'for': ['c', 'cpp', 'objc', 'java', 'python', 'ruby'] }  " debugger frontend for GDB, LDB, PDB, RDebug e.a.

" Edit
"Plug      'jiangmiao/auto-pairs'                                               " insert or delete [], (), '' etc. in pairs
 Plug            'sjl/gundo.vim'                                                " visualise your undo tree
 Plug     'scrooloose/nerdcommenter'                                            " intensely orgasmic commenting
 Plug         'SirVer/ultisnips'                                                " ultimate snippet solution
 Plug         'fadein/vim-FIGlet',           { 'on': 'FIGlet' }                 " ASCII art
 Plug          'honza/vim-snippets'                                             " snippets for ultisnips
 Plug       'junegunn/vim-easy-align'                                           " easily align text in Alexander Approved™ ways
 Plug          'matze/vim-move'                                                 " move lines and selections up and down
"Plug           'kana/vim-operator-user'                                        " define your own operator easily
 Plug       'junegunn/vim-peekaboo'                                             " preview registers when pressing \" or @
 Plug           'gcmt/wildfire.vim'                                             " smart selection of the closest text object
 Plug       'Valloric/YouCompleteMe',        { 'do': 'git submodule update --init --recursive && ./install.py --system-libclang --all' }  " code-completion engine

" Navigation
 Plug       'ctrlpvim/ctrlp.vim'                                                " fuzzy file, buffer, mru, tag, etc. finder
 Plug           'dyng/ctrlsf.vim'                                               " search for code, edit it in-place, have multiple cursors
 Plug       'Yggdroot/indentLine'                                               " display the indention levels with thin vertical lines
 Plug     'scrooloose/nerdtree'                                                 " filesystem tree explorer
 Plug     'majutsushi/tagbar'                                                   " display tags in a window, ordered by scope
 Plug     'easymotion/vim-easymotion'                                           " quickly jump to any location on the screen
 Plug       'airblade/vim-gitgutter'                                            " show a Git diff in the gutter, stage/undo hunks
 Plug          'mhinz/vim-grepper',          { 'on': 'Grepper' }                " asynchronous git grep search
"Plug 'ludovicchabant/vim-gutentags'                                            " unobtrusively manage tag files
 Plug          'tpope/vim-obsession'                                            " continuously updated session files

" Powerline
 Plug    'vim-airline/vim-airline'                                              " statusline plugin in pure Vimscript
 Plug    'vim-airline/vim-airline-themes'                                       " themes for airline


" Analysis
 Plug           'w0rp/ale'                                                      " asynchronous linting engine
"Plug          'dbmrq/vim-ditto'                                                " highlight overused words

" Misc
 Plug   'editorconfig/editorconfig-vim'                                         " per-project modeline-like configuration
"Plug         'kassio/neoterm',              { 'on': 'T' }                      " wrapper of some neovim's :terminal functions
"Plug          'tpope/vim-fugitive'                                             " a Git wrapper
"Plug    'vim-scripts/TeTrIs.vim'                                               " Tetris clone

call plug#end()"

" One {{{2
" --------
set termguicolors
set cursorline
let g:one_allow_italics = 1
colorscheme one
set background=dark
hi Normal guibg=NONE ctermbg=NONE
hi SpellBad guibg=NONE ctermbg=NONE
hi Comment guifg=#888888
hi link Whitespace Conceal
hi CursorLine guibg=NONE ctermbg=NONE
hi CursorLineNr guibg=NONE ctermbg=NONE

" Haskell {{{2
" ------------
let g:haskell_enable_quantification=1
let g:haskell_enable_recursivedo=1
let g:haskell_enable_arrowsyntax=1
let g:haskell_enable_pattern_synonyms=1
let g:haskell_enable_typeroles=1
let g:haskell_enable_static_pointers=1

" Python {{{2
" -----------

" Fuck PEP 8, tabs are better
let g:python_recommended_style = 0

" Rust {{{2
" ---------

" As with Python, fuck spaces
let g:rust_recommended_style = 0
setlocal textwidth=99

" Markdown {{{2
" -------------
let g:vim_markdown_conceal = 0

" CSV.vim {{{2
" ------------

" CSS colors {{{2
" ---------------

" Doxygen {{{2
" ------------
nnoremap <leader>df :Dox<CR>
nnoremap <leader>dl :DoxLic<CR>
nnoremap <leader>da :DoxAuthor<CR>
let g:DoxygenToolkit_authorName="Midgard"

" FSwitch {{{2
" ------------
let b:fswitchdst = ''
au! BufEnter *.cpp let b:fswitchdst = 'hpp,h' | let b:fswitchlocs = '.'
au! BufEnter *.hpp let b:fswitchdst = 'cpp'   | let b:fswitchlocs = '.'
au! BufEnter *.c   let b:fswitchdst = 'h'     | let b:fswitchlocs = '.'
au! BufEnter *.h   let b:fswitchdst = 'c,cpp' | let b:fswitchlocs = '.'
nmap <silent> <F2> :FSRight<cr>

" Protodef {{{2
" -------------
nnoremap ;def :call protodef#ReturnSkeletonsFromPrototypesForCurrentBuffer({})<cr>

" ConqueGDB {{{2
" --------------
let g:ConqueGdb_Leader = ','
" Commented entries are the defaults
"let g:ConqueGdb_Run = g:ConqueGdb_Leader . 'r'
"let g:ConqueGdb_Continue = g:ConqueGdb_Leader . 'c'
let g:ConqueGdb_Next = g:ConqueGdb_Leader . 'o' " step over
let g:ConqueGdb_Step = g:ConqueGdb_Leader . 'i' " step in
"let g:ConqueGdb_Print = g:ConqueGdb_Leader . 'p'
"let g:ConqueGdb_ToggleBreak = g:ConqueGdb_Leader . 'b'
let g:ConqueGdb_Finish = g:ConqueGdb_Leader . 'O' " step out
"let g:ConqueGdb_Backtrace = g:ConqueGdb_Leader . 't'

nnoremap <F12> :ConqueGdb --args build/tests --debug

" Vebugger {{{2
" -------------
"let g:vebugger_leader='<leader>v'
"
"nnoremap <F5>  :VBGstepOver<cr>
"nnoremap <F6>  :VBGstepIn<cr>
"nnoremap <F7>  :VBGstepOut<cr>
"nnoremap <F8>  :VBGcontinue<cr>
"nnoremap <F12> :VBGstartGDB ./huffman

" Auto-pairs {{{2
" ---------------

" Gundo {{{2
" ----------
nnoremap <F3> :GundoToggle<CR>

" NERDCommenter {{{2
" ------------------
nmap & <leader>c<space>
vmap & <leader>c<space>

" UltiSnips {{{2
" ---------------
let g:UltiSnipsExpandTrigger='²'

" EasyAlign {{{2
" --------------
xmap <leader>a <Plug>(EasyAlign)
nmap <leader>a <Plug>(EasyAlign)

" Move (lines) {{{2
" -----------------

" Operator user {{{2
" ------------------

" Peekaboo {{{2
" -------------

" Wildfire {{{2
" -------------
nmap <leader>s <Plug>(wildfire-quick-select)
let g:wildfire_objects = ["iw", "i'", "i`", 'i"', "i)", "i]", "i}", "ip", "it"]

" YouCompleteMe {{{2
" ------------------
"noremap <leader>g :YcmCompleter GoToImprecise<CR>
noremap <leader>g <esc>:YcmCompleter GoTo<CR>
noremap <M-CR> <esc>:YcmCompleter FixIt<CR>

let g:ycm_enable_diagnostic_highlighting=0
let g:ycm_complete_in_comments=1

let g:ycm_seed_identifiers_with_syntax=1
let g:ycm_collect_identifiers_from_tags_files=1
let g:ycm_add_preview_to_completeopt=1
let g:ycm_autoclose_preview_window_after_insertion=1

let g:ycm_server_python_interpreter='/usr/bin/python3'
let g:ycm_global_ycm_extra_conf='~/.config/nvim/ycm_extra_conf.py'
let g:ycm_extra_conf_globlist = ['~/wlk/*', '~/doc/*','~/dev/*','~/uni/*'] "  ,'!~/*'
"let g:ycm_rust_src_path='/data/programming/rustc-1.7.0/src'
set completeopt=menu

" CtrlP {{{2
" ----------
let g:ctrlp_map='<C-Space>'
let g:ctrlp_user_command=['.git/', 'git --git-dir=%s/.git ls-files . -co --exclude-standard']
"nnoremap <leader>s :CtrlPTag<CR>"

" Ctrl-S-F {{{2
" -------------
nmap              <C-F>f     <Plug>CtrlSFPrompt
nmap              <C-F><C-F> <C-F>f
vmap              <C-F>f     <Plug>CtrlSFVwordExec
vmap              <C-F><C-F> <C-F>f
vmap              <C-F>F     <Plug>CtrlSFVwordPath
nmap              <C-F>w     <Plug>CtrlSFCwordPath
nmap              <C-F>W     <Plug>CtrlSFCCwordPath
nmap              <C-F><Up>  <Plug>CtrlSFPwordPath
nnoremap <silent> <C-F>o     :CtrlSFOpen<CR>
nnoremap <silent> <C-F>t     :CtrlSFToggle<CR>
inoremap <silent> <C-F>t     <Esc>:CtrlSFToggle<CR>
let g:ctrlsf_regex_pattern = 1

" IndentLine {{{2
" ---------------

" NERDTree {{{2
" -------------
nnoremap <silent> <leader>t :NERDTreeToggle<CR>
nnoremap <silent> ² :NERDTreeFind<CR>
let NERDTreeIgnore=[
  \ "^__pycache__$",
  \ ".*\\.class$",
  \ ".*\\.o$",
  \ ".*\\.hi$",
  \ ".*\\.pyc$",
  \ ".*\\.bak$",
  \ ".*\\~$"
  \ ]

" automatically open NERDTree when opening vi
"autocmd StdinReadPre * let s:std_in=1
"autocmd VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif

" Tagbar {{{2
" -----------
nnoremap <leader>o :Tagbar<CR>
let g:tagbar_autoclose=1
let g:tagbar_autofocus=1
let g:tagbar_sort=0
let g:tagbar_compact=1
let g:tagbar_iconchars=['▸', '▾']
let g:tagbar_type_make={
  \ 'kinds': ['m:macros', 't:targets']
  \ }
let g:tagbar_type_rust={
  \ 'ctagstype': 'rust',
  \ 'kinds': [
    \ 'n:modules',
    \ 's:structs',
    \ 'i:interfaces',
    \ 'c:implementations',
    \ 'f:functions',
    \ 'g:enums',
    \ 't:typedefs',
    \ 'v:variables',
    \ 'M:macros',
    \ 'm:fields',
    \ 'e:enumerators',
    \ 'F:methods',
    \ ]
  \ }

" EasyMotion {{{2
" ---------------
let g:EasyMotion_do_mapping=0
let g:EasyMotion_startofline=0
map      <leader>f <Plug>(easymotion-s)
map      <leader>j <Plug>(easymotion-j)
map      <leader>k <Plug>(easymotion-k)
map      <leader>w <Plug>(easymotion-bd-w)
nmap     <leader>w <Plug>(easymotion-overwin-w)

" GitGutter {{{2
" --------------

" Grepper {{{2
" ------------
nnoremap <leader>G :Grepper<CR>
let g:grepper={
  \ 'tools': ['rg', 'git', 'grep'],
  \ 'open': 1,
  \ 'jump': 0,
  \ }

" Gutentags {{{2
" --------------
let g:gutentags_cache_dir = '~/.cache/gutentag'

" Obsession {{{2
" --------------

" Airline {{{2
" ------------
let g:airline_powerline_fonts=1
let g:airline_theme='minimalist'
let g:airline#extensions#ycm#enabled=1
let g:airline#extensions#tabline#enabled=1
let g:airline#extensions#ale#enabled=1

" Ale {{{2
" --------
let g:ale_linters = {
\   'c':   [],
\   'cpp': [],
\}
let g:ale_lint_on_text_change='normal'
let g:ale_lint_on_insert_leave=1
let g:ale_completion_delay=''
let g:ale_lint_delay=500

" Ditto {{{2
" ----------

" EditorConfig {{{2
" -----------------
"
let g:EditorConfig_exclude_patterns = ['fugitive://.*', 'scp://.*']
let g:EditorConfig_max_line_indicator = 'exceeding'

let g:EditorConfig_exec_path = '/usr/bin/editorconfig'
let g:EditorConfig_core_mode = 'external_command'

" Neoterm {{{2
" ------------

" Fugitive {{{2
" -------------

" TeTrIs {{{2
" -----------

" vim: set foldmethod=marker foldlevel=1 et ts=2 sw=2 ft=vim nowrap :

