" vim: ft=vim
"if has("nvim")
"	autocmd! BufWritePost,BufEnter * Neomake
"endif

function! SourceIfExists(file)
  if filereadable(expand(a:file))
    exe 'source' a:file
  endif
endfunction
if has("nvim")
  let EDITOR="nvim"
  call SourceIfExists("~/.vim/vim.nvim")
else
  let EDITOR="vim"
  call SourceIfExists("~/.vim/vim.vim")
end

hi Comment ctermfg=black ctermbg=NONE cterm=bold
"hi Comment ctermfg=darkgray cterm=bold
hi Conceal ctermfg=black ctermbg=NONE cterm=bold
hi CursorLine cterm=none guibg=NONE
hi CursorLineNr ctermfg=white cterm=NONE
hi FoldColumn ctermfg=black ctermbg=none cterm=bold
hi Folded ctermfg=black ctermbg=NONE cterm=bold
hi LineNr ctermfg=black ctermbg=none cterm=bold
hi Pmenu ctermbg=magenta ctermfg=black
hi PmenuSel ctermbg=darkmagenta ctermfg=black
hi PmenuSbar ctermfg=gray ctermbg=black
hi PmenuThumb ctermfg=white
hi Search ctermfg=black ctermbg=yellow
hi SignColumn ctermbg=black
hi SpecialKey ctermfg=black cterm=bold
hi StatusLine term=bold,reverse ctermfg=white ctermbg=blue cterm=none
hi StatusLineNC term=reverse ctermfg=blue ctermbg=none cterm=underline
hi Visual ctermfg=black ctermbg=yellow cterm=none
hi WarningMsg ctermbg=darkyellow ctermfg=white
au FileType xml hi xmlAttrib ctermfg=green
au FileType xslt hi xmlNamespace ctermfg=red
au FileType xslt hi xmlAttrib ctermfg=green
au FileType * hi Special ctermfg=red
"au FileType haskell hi Comment ctermfg=DarkGreen
au FileType haskell hi Identifier ctermfg=LightGray

" Search term under cursor
nmap <silent> * :set hls<CR>:let @/="\\<<C-r><C-w>\\>"<CR>/<BS>
nmap <silent> <C-n> :set hls<CR>:call Vimgrepbuffers('\<' . expand('<cword>') . '\>')<CR>
" Search subterm under cursor
nmap <silent> µ :set hls<CR>:let @/="<C-r><C-w>"<CR>/<BS>
nmap <silent> <C-m> :set hls<CR>:call Vimgrepbuffers(expand('<cword>'))<CR>

fun! Vimgrepbuffers(pattern)
  exe 'vimgrep /' . a:pattern . '/g ' . getbufinfo({'buflisted': 1})->map({_,b -> fnameescape(b.name)})->join(' ')
  let @/ = a:pattern
  let l:winnr = winnr()
  cwindow 3
  " If focus changed, restore it (jump to the last window).
  if l:winnr isnot# winnr()
    wincmd p
  endif
endfun
command! -nargs=1 G set hls | call Vimgrepbuffers(<f-args>)

" Navigation
nmap i gk
nmap k gj
nmap j <Left>
nmap l <Right>
xmap i gk
xmap k gj
xmap j <Left>
xmap l <Right>

nmap K :join<CR>
nmap J <Home>
nmap L <End>
nmap m :buffer 

" Maintain Visual Mode after shifting > and <
vmap < <gv
vmap > >gv

" Move visual block
vmap I :m '<-2<CR>gv=gv
vmap K :m '>+1<CR>gv=gv

if &term =~ '^screen'
  " Fix <Home>, <End>, <C-Left>, etc. when vim is in tmux;
  " tmux will send xterm-style keys when xterm-keys is on
  execute "set <xHome>=\e[7~"
  execute "set <xEnd>=\e[8~"
  execute "set <xRight>=\e[1;*C"
  execute "set <xLeft>=\e[1;*D"
  execute "set <xUp>=\e[1;*A"
  execute "set <xDown>=\e[1;*B"
endif

set autoindent
set background=dark
set breakindent
set cmdheight=1
if !has("nvim")
set completeopt=menu,menuone,popup,longest
endif
set conceallevel=0
set cpoptions+=M " ignore backslashes in % matching
set cursorline
execute "silent !mkdir -p ~/.cache/" . EDITOR . "/swap"
execute "set directory=$HOME/.cache/" . EDITOR . "/swap"
if !has("nvim")
set diffopt=internal,filler,closeoff,algorithm:histogram,indent-heuristic
endif
set encoding=utf-8
set expandtab
set foldcolumn=0
set foldenable
function! GetFoldExprFromIndent()
 " Calcule l'indentation en fonction des tabulations
 " et espaces au début des lignes
	let line   = getline(v:lnum)
	let tabs   = matchend(line,"^\t*")
	let spaces = matchend(line,"^[ \t]*") - tabs
	return tabs + ((spaces + 3) / 4)
endfunction
set foldexpr=GetFoldExprFromIndent()
set foldignore=
set foldlevelstart=99
set foldmethod=indent
set foldminlines=0
set hidden
set history=1042
set hlsearch
set incsearch
set laststatus=2
set lazyredraw
set linebreak
set list
set path=.,/usr/include,/usr/local/include,,
set scroll=0
set scrolloff=10
set sidescroll=0
set sidescrolloff=0
set signcolumn=yes
set shortmess+=A
set swapfile
let mapleader = ","
set matchpairs+=<:>
set maxmempattern=2000
set noautochdir
set nocompatible
set noerrorbells
set noignorecase
"set noloadplugins
set nosmartindent
set nowrapscan
set number
set ruler
"set runtimepath=$HOME/.$EDITOR,$VIMRUNTIME,$VIM
set sessionoptions=curdir,folds
set shiftwidth=2
set showcmd
set statusline=%f
"set statusline+=\ %l:%c
"set statusline=\ %{get(b:,'coc_current_function','')}
set statusline+=%=
"set statusline+=%#ErrorMsg#%{CocStatusDiagnosticError()}%*
"set statusline+=\ %{CocStatus()}
set statusline+=%{LinterStatus()}
set statusline+=\ %m%R\ %Y
set tabstop=2
set ttyfast
set undolevels=542
set updatetime=300
set verbose=0
execute "silent !mkdir -p ~/.cache/" . EDITOR . "/view"
execute "set viewdir=$HOME/.cache/" . EDITOR . "/view"
execute "set viminfo+=n$HOME/.cache/" . EDITOR . "/info"
set visualbell
set visualbell t_vb=
set whichwrap+=<,>,[,]
set wildignore=*.a,*.d,*.o,*.so,*~,*.cmo,*.cmi,*.cmx,*.cmxs,*.cma,*.cmxa,*.byte,*.native,*.hi
set wildmenu
set wildmode=list:longest,full
set wrap
syntax on
" When editing a file, always jump to the last known cursor position.
" Don't do it when the position is invalid or when inside an event handler
" (happens when dropping a file on gvim).
autocmd BufReadPost *
	\ if line("'\"") > 0 && line("'\"") <= line("$") |
	\   exe "normal g`\"" |
	\  endif
" Set screen title
if (&term == "screen" || &term == "screen.linux")
	"set t_ts=k
	"set t_fs=\
 endif
if has("gui_running")
	set title
	set titlelen=0
	set titlestring=VIM:\ %F\ %a%r%m
else
	" Italic
	set t_ZH=
	set t_ZR=
	" Underline
	set t_us=
	set t_ue=
	" Set window title
	set t_ts=]0;
	set t_fs=
	"set titlestring=%t%(\ %M%)%(\ (%{expand(\"%:p:h\")})%)%(\ %a%)\ -\ %{v:servername}
	auto BufEnter * :set title | let &titlestring = 'VIM: ' . expand('%:p')
	"auto VimLeave * :set t_ts=k\
 endif
let space = &shiftwidth == 0 ? &tabstop : &shiftwidth
if (&term == "linux" || &term == "screen.linux")
  "set foldtext=substitute(getline(v\:foldstart),'^\\(\\s*\\)',{m->substitute(m[1],'\\('.repeat('\ ',&shiftwidth).'\\\|\\t\\)','\|'.repeat('.',&shiftwidth-1),'g')},'').'\ \ ('.(v\:foldend-v\:foldstart+1).')\ '
  "set fillchars=fold:_
  set list listchars=nbsp:+,tab:\|.,trail:_,extends:>,precedes:<
	set foldtext=getline(v\:foldstart).'\ \ ('.(v\:foldend-v\:foldstart+1).')\ '
 else
  "set foldtext=substitute(getline(v\:foldstart),'^\\(\\s*\\)',{m->substitute(m[1],'\\('.repeat('\ ',&shiftwidth).'\\\|\\t\\)','⎢'.repeat('·',&shiftwidth-1),'g')},'').'\ \ ('.(v\:foldend-v\:foldstart+1).')\ '
  "set fillchars=fold:·
	set foldtext=getline(v\:foldstart).'\ \ ('.(v\:foldend-v\:foldstart+1).')\ '
	set list listchars=nbsp:¬,tab:⎢·,trail:·,extends:>,precedes:<
 endif

"let g:indentLine_char_list = ['⎢']
"" Concealed text is not highlighted by the visual mode, this is annoying.
""let g:indentLine_concealcursor = 'incv'
"let g:indentLine_faster = 1
"let g:indentLine_first_char = '⎢'
"let g:indentLine_leadingSpaceChar = '·'
"let g:indentLine_leadingSpaceEnabled = 1
"let g:indentLine_showFirstIndentLevel = 1
"let g:indentLine_bgcolor_term = 'NONE'
"let g:indentLine_defaultGroup = 'Folded'

if (v:version >= 700)
	hi TabLine term=bold,reverse ctermfg=white ctermbg=blue cterm=none
	hi TabLineFill term=bold,reverse ctermfg=none ctermbg=blue cterm=none
	hi TabLineSel term=reverse ctermfg=white ctermbg=none cterm=bold
	imap <C-S-tab> <Esc>:tabprevious<CR>i
	imap <C-t> <Esc>:tabnew<CR>
	imap <C-tab> <Esc>:tabnext<CR>i
	nmap <C-S-tab> :tabprevious<CR>
	nmap <Esc><tab> :bnext<CR>
	nmap <C-t> :tabnew<CR>
	"nmap <C-tab> :tabprevious<CR>
	"nmap <tab> :tabnext<CR>
	nmap <C-tab> :bprevious!<CR>
	nmap <tab> :bnext!<CR>
	nmap td :tabclose<CR>
	nmap ti :tabfirst<CR>
	nmap tj :tabprev<CR>
	nmap tk :tablast<CR>
	nmap tl :tabnext<CR>
	nmap tm :tabm<Space>
	nmap tn :tabnew<Space>
	nmap tt :tabedit<Space>
	nmap <C-i> :bprevious!<CR>
	nmap <C-k> :bnext!<CR>
	nmap <C-j> :lprevious<CR>
	nmap <C-l> :lnext<CR>
	nmap <C-u> :cprevious<CR>
	nmap <C-o> :cnext<CR>
	nmap <C-w>k :wincmd j<CR>
	nmap <C-w>i :wincmd k<CR>
	nmap <C-w>j :wincmd h<CR>
	nmap <C-w>l :wincmd l<CR>
	set tabpagemax=1000
	set sessionoptions+=tabpages
 endif
if (v:version >= 704)
	execute "silent !mkdir -p ~/.cache/" . EDITOR . "/undo"
	execute "set undodir=$HOME/.cache/" . EDITOR . "/undo"
	set undofile
	autocmd BufWritePre /tmp/*  setlocal noundofile
	autocmd BufWritePre */sec/* setlocal noundofile
 endif
fun! TrimWhitespace()
  let l:save = winsaveview()
  keeppatterns %s/\s\+$//e
  call winrestview(l:save)
endfun
autocmd BufRead .envrc setfiletype sh
"autocmd BufRead *.hamlet setfiletype html
"autocmd BufRead *.julius setfiletype javascript
"autocmd BufRead *.lucius setfiletype css
autocmd BufRead *.ledger setfiletype ledger
autocmd BufRead *.lhs setfiletype haskell
autocmd BufRead HLint.hs setfiletype txt
autocmd BufRead *.purs
 \ setfiletype purescript |
 \ set syntax=haskell
"autocmd BufRead *.nix set syntax=zsh | set expandtab
autocmd BufNewFile,BufRead *.nix
 \ hi nixAntiquotation ctermfg=cyan |
 \ set expandtab |
 \ set isk+=- |
 \ set foldmethod=indent
autocmd BufWritePre *.nix :call TrimWhitespace()
autocmd BufNewFile,BufRead *.py
 \ set noexpandtab |
 \ set tabstop=2 |
 \ set softtabstop=0
autocmd BufNewFile,BufRead *.hs set expandtab
autocmd BufNewFile,BufRead *.tct set filetype=tct | set expandtab
autocmd BufWritePost * if &diff == 1 | diffupdate | endif
augroup quickfix
	autocmd!
	autocmd FileType qf setlocal wrap
augroup END

" If doing a diff. Upon writing changes to file, automatically update the differences
"""
""" plugins
"""
" matchit
	let b:match_words = '«:»,“:”'
" easy_align
	nmap <Leader>a <Plug>(EasyAlign)
	vmap <Enter> <Plug>(EasyAlign)
	let g:easy_align_ignore_groups = ['Comment', 'String', 'ledgerTransaction', 'ledgerTag', 'jccComment', 'jccTransaction']
" netrw
	let g:netrw_liststyle = 3
	"let g:netrw_cursorline = 0
	let s:netrw_usercul = 0
" NERD_tree
" buffergator
	let g:buffergator_display_regime = "bufname"
	let g:buffergator_show_full_directory_path = 0
	let g:buffergator_viewport_split_policy = 'R'
	let g:buffergator_autoupdate = 1
	let g:buffergator_autodismiss_on_select = 0
	let g:buffergator_suppress_keymaps = 1
	nmap <leader>bq :bp <BAR> bd #<CR>
	"let g:buffergator_mru_cycle_loop = 1
	nmap <leader>i :BuffergatorMruCyclePrev<cr>
	nmap <leader>k :BuffergatorMruCycleNext<cr>
	nmap <leader>bl :BuffergatorOpen<cr>
	nmap <leader>T :enew<cr>
	set cpoptions+=M " ignore backslashes in % matching
" TOHtml
	let g:html_expand_tabs = 0
	let g:html_ignore_conceal = 0
	let g:html_ignore_folding = 1
	let g:html_number_lines = 0
	let g:html_use_xhtml = 0
" CtrlP
	"map <C-p> :CtrlPBuffer<CR>
	"let g:ctrlp_working_path_mode = 'c'
	"let g:ctrlp_map = '<Leader>t'
	"let g:ctrlp_match_window_bottom = 0
	"let g:ctrlp_match_window_reversed = 0
	"let g:ctrlp_custom_ignore = '\v\~$|\.(o|swp|pyc|wav|mp3|ogg|blend)$|(^|[/\\])\.(hg|git|bzr)($|[/\\])|__init__\.py'
	"let g:ctrlp_working_path_mode = 0
	"let g:ctrlp_dotfiles = 0
	"let g:ctrlp_switch_buffer = 0
" vimproc
" ghc-mod
	"map <silent> tu :call GHC_BrowseAll()<CR>
	"map <silent> tw :call GhcModType<CR>
	map <silent> hc :GhcModTypeClear<CR>
	map <silent> he :GhcModExpand<CR>
	map <silent> hi :GhcModTypeInsert<CR>
	map <silent> hs :GhcModSigCodegen<CR>
	map <silent> hs :GhcModSplitFunCase<CR>
	map <silent> ht :GhcModType<CR>
" vimBall
" AnsiEsc
" Hoogle
	nmap <F5> :Hoogle <C-R><C-W><CR>
" TimeKeeper
	"let g:TimeKeeperUpdateFileTimeSec = 5
	""let g:TimeKeeperStartOnLoad = 1
	"let g:TimeKeeperUseFlatFile = 0
	"nmap <silent> <F8> :call TimeKeeper_ToggleTaskWindow()<cr>
	"call TimeKeeper_StartTracking()
" Recover
	let g:RecoverPlugin_Delete_Unmodified_Swapfile = 1
" calendar-vim
	let g:calendar_number_of_months = 1
  let g:calendar_wruler = 'di lu ma me je ve sa'
	let g:calendar_monday = 1
	function MyCalAction(day,month,year,week,dir)
	 " day   : day you actioned
	 " month : month you actioned
	 " year  : year you actioned
	 " week  : day of week (Mo=1 ... Su=7)
	 " dir   : direction of calendar
	endfunction
	"let calendar_action = 'MyCalAction'
	"hi link ALEError Error
	"hi Warning term=underline cterm=underline ctermfg=Yellow gui=undercurl guisp=Gold
	"hi link ALEWarning Warning
	"hi link ALEInfo SpellCap
" echodoc
  "let g:echodoc#enable_at_startup = 1
  "let g:echodoc#type = 'signature'
" vim-gitgutter
	"let g:gitgutter_grep = 'rg'
	let g:gitgutter_grep = 'grep'
  let g:gitgutter_diff_args = '--diff-algorithm=histogram'
	let g:gitgutter_map_keys = 0
	let g:gitgutter_sign_added = '+'
	let g:gitgutter_sign_modified = '±'
	let g:gitgutter_sign_modified_removed = '-'
	let g:gitgutter_sign_removed = '_'
	let g:gitgutter_sign_removed_first_line = '▔'
  let g:gitgutter_sign_priority = 9
  hi GitGutterAdd ctermfg=green
  hi GitGutterDelete ctermfg=red
  hi GitGutterChange ctermfg=yellow
  hi GitGutterChangeDelete ctermfg=red
	nmap [c <Plug>(GitGutterPrevHunk)
	nmap ]c <Plug>(GitGutterNextHunk)
	nmap <Leader>p <Plug>(GitGutterPreviewHunk)
	nmap <Leader>+ <Plug>(GitGutterStageHunk)
	nmap <Leader>- <Plug>(GitGutterUndoHunk)
" deoplete
  "let g:deoplete#enable_at_startup = 1
  "call deoplete#custom#option('sources', {
  "\ '_': ['ale', 'buffer', 'around'],
  "\})