""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" vim
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
set nocompatible
set mouse=a
set history=1000
set ruler
set number
set showcmd
set ttimeoutlen=100
set backspace=indent,eol,start
set tabstop=4
set expandtab
set shiftwidth=4
set softtabstop=4
set autoindent
set showmatch
set incsearch
set hlsearch
set wrapscan
set ignorecase
set smartcase
set hidden
set splitright
set splitbelow
" set backupdir=~/.config/nvim/backup,/tmp
" set backup
set noswapfile
set wildmode=longest,list
set nospell
set foldmethod=syntax
set foldopen-=block
set foldlevel=99
set lazyredraw
set listchars=eol:¬,tab:\ \ ,trail:·
set fillchars=vert:\|,fold:\ 
set list
set laststatus=2
set scrolloff=8
set background=light
" set colorcolumn=100
set wrap
set showbreak=..
set clipboard+=unnamedplus
" set formatoptions+=l
set noerrorbells
set visualbell
set t_vb=
set title
set autoread
syntax on
let g:tex_flavor="latex"
" set listchars=eol:¬,tab:▸\ ,trail:·
" set listchars=eol:¬,tab:>\ ,trail:·

if !has('nvim') | set encoding=utf-8 | endif

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" plugins
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
call plug#begin('~/.local/share/nvim/site/plugins')

Plug 'kien/ctrlp.vim' | Plug 'sgur/ctrlp-extensions.vim'
Plug 'scrooloose/nerdtree'
" Plug 'scrooloose/syntastic'
Plug 'vim-scripts/bufexplorer.zip'
Plug 'majutsushi/tagbar'

Plug 'Shougo/deoplete.nvim'
Plug 'SirVer/ultisnips'

Plug 'Raimondi/delimitMate'
Plug 'tpope/vim-surround'
Plug 'tpope/vim-commentary'
Plug 'junegunn/vim-easy-align'

Plug 'maxbrunsfeld/vim-yankstack'

Plug 'tpope/vim-repeat'
Plug 'wellle/targets.vim'

Plug 'benekastah/neomake'

Plug 'tpope/vim-fugitive'
Plug 'tpope/vim-dispatch'

Plug 'lervag/vimtex'
Plug 'vim-scripts/MatlabFilesEdition'
Plug 'vim-scripts/LanguageTool'

" Plug 'mhinz/neovim-remote'

Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' } | Plug 'junegunn/fzf.vim'
Plug 'rking/ag.vim'

Plug 'tpope/vim-obsession'
Plug 'mhinz/vim-startify'
Plug 'wesQ3/vim-windowswap'

Plug 'bling/vim-airline' | Plug 'vim-airline/vim-airline-themes' |Plug 'jonathanfilip/vim-lucius'
Plug 'altercation/vim-colors-solarized'

call plug#end()

filetype plugin indent on

set omnifunc=syntaxcomplete#Complete
set completeopt=menu

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" plugin specific
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

" NerdTree
let NERDTreeQuitOnOpen=1
let NERDTreeHijackNetrw=1

" syntastic
" set statusline+=%#warningmsg#
" set statusline+=%{SyntasticStatuslineFlag()}
" set statusline+=%*
" let g:syntastic_always_populate_loc_list = 1
" let g:syntastic_auto_loc_list = 1
" let g:syntastic_check_on_open = 1
" let g:syntastic_check_on_wq = 0

" CtrlP
set wildignore+=main,*.o,*.d,*.aux,*.bbl,*.lof,*.loa,*.blg,*.fdb_latexmk,*.fls,*.tdo,*.pdf,*.pyc
let g:ctrlp_switch_buffer = 'e'
let g:ctrlp_working_path_mode = 'ra'
let g:ctrlp_extensions = [ 'tag', 'buffertag', 'mixed' ]
let g:ctrlp_map = ''
" let g:ctrlp_prompt_mappings = {
"     \ 'PrtSelectMove("j")':   ['<c-n>', '<down>'],
"     \ 'PrtSelectMove("k")':   ['<c-p>', '<up>'],
" 		\}

" tagbar
let g:tagbar_left=1
let g:tagbar_autoclose=1
let g:tagbar_autofocus=1

" deoplete
let g:deoplete#enable_at_startup=1
" if !exists('g:deoplete#omni#input_patterns')
" 	let g:deoplete#omni#input_patterns = {}
" endif

" DelimitMate
let delimitMate_expand_space=1
let delimitMate_expand_cr=1

" UltiSnips
let g:UltiSnipsSnippetsDir='~/.config/nvim/UltiSnips'
let g:UltiSnipsSnippetsDirectories=["UltiSnips"]
let g:UltiSnipsExpandTrigger="<C-j>"
let g:UltiSnipsJumpForwardTrigger="<C-j>"
let g:UltiSnipsJumpBackwardTrigger="<C-k>"

" YankStack
let g:yankstack_map_keys=0
call yankstack#setup()

" vimtex
let g:vimtex_fold_enabled = 1
let g:vimtex_view_method = 'zathura'
let g:vimtex_quickfix_mode = 2
" let g:deoplete#omni#input_patterns.tex =
" 			\ '\v\\%('
" 			\ . '\a*cite\a*%(\s*\[[^]]*\]){0,2}\s*\{[^}]*'
" 			\ . '|\a*ref%(\s*\{[^}]*|range\s*\{[^,}]*%(}\{)?)'
" 			\ . '|hyperref\s*\[[^]]*'
" 			\ . '|includegraphics\*?%(\s*\[[^]]*\]){0,2}\s*\{[^}]*'
" 			\ . '|%(include%(only)?|input)\s*\{[^}]*'
" 			\ . '|\a*(gls|Gls|GLS)(pl)?\a*%(\s*\[[^]]*\]){0,2}\s*\{[^}]*'
" 			\ . '|includepdf%(\s*\[[^]]*\])?\s*\{[^}]*'
" 			\ . '|includestandalone%(\s*\[[^]]*\])?\s*\{[^}]*'
" 			\ . ')'

" Startify
let g:startify_session_dir = '~/.config/nvim/obsessions'
let g:startify_list_order = [['      Sessions'],'sessions',
													\ ['      Bookmarks'],'bookmarks',
													\ ['      Recent dirs'],'dir',]
let g:startify_bookmarks = [ {'v': '~/.config/nvim/init.vim'} ]
													" \ ['      Recent files'],'files',
let g:startify_custom_header = []

" windowswap
let g:windowswap_map_keys=0

" airline
let g:airline_theme='lucius'
if !exists('g:airline_symbols')
	let g:airline_symbols={}
endif
let g:airline_left_sep=''
let g:airline_right_sep=''
let g:airline_symbols.linenr = '␊'
let g:airline_symbols.linenr = '␤'
let g:airline_symbols.linenr = '¶'
let g:airline_symbols.branch = '⎇'
let g:airline_symbols.paste = 'ρ'
let g:airline_symbols.paste = 'Þ'
let g:airline_symbols.paste = '∥'
let g:airline_symbols.whitespace = 'Ξ'
let g:airline_section_y=''
let g:airline#extensions#tabline#enabled=1
let g:airline#extensions#tabline#tab_nr_type = 1
let g:airline#extensions#tabline#show_buffers=0
let g:airline#extensions#tabline#show_tab_nr=1
let g:airline#extensions#tabline#show_tab_type=0
let g:airline#extensions#tabline#fnamemod = ':~:.'

" Lucius
colorscheme lucius
LuciusWhite

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" misc
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

let mapleader = "\<Space>"

nnoremap <leader>w :w<CR>

nnoremap <silent> <leader>q :call ToggleList("Quickfix List", 'c')<CR>

nnoremap <silent> <leader>ev :tabnew ~/.config/nvim/init.vim<CR>

nnoremap Y y$

nnoremap j gj
nnoremap k gk
vnoremap j gj
vnoremap k gk

" file navigation
nnoremap <silent> <leader>f :Files ~<CR>
nnoremap <silent> <leader>F :e.<CR>
nnoremap <silent> <leader>o :CtrlPBuffer<CR>
nnoremap <silent> <leader>O :BufExplorer<CR>
nnoremap <silent> <leader>t :CtrlPBufTagAll<CR>
nnoremap <silent> <leader>T :TagbarToggle<CR>

nnoremap <leader>p :CtrlPYankring<CR>
nnoremap <C-p> <Plug>yankstack_substitute_newer_paste
nnoremap <C-n> <Plug>yankstack_substitute_older_paste

" command line mappings
cnoremap <C-p> <Up>
cnoremap <C-n> <Down>
cnoremap w!! w !sudo tee > /dev/null %

" quickfix mappings
nnoremap <silent> <leader>q :call ToggleList("Quickfix List", 'c')<CR>
nnoremap <silent> [q :cprevious<CR>
nnoremap <silent> ]q :cnext<CR>

" split movement
nnoremap <C-h> <C-w>h
nnoremap <BS> <C-w>h
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-l> <C-w>l
nnoremap <leader>s :call WindowSwap#EasyWindowSwap()<CR>

" terminal mappings
tnoremap <Esc> <C-\><C-n>
tnoremap <C-h> <C-\><C-n><C-w>h
tnoremap <C-j> <C-\><C-n><C-w>j
tnoremap <C-k> <C-\><C-n><C-w>k
tnoremap <C-l> <C-\><C-n><C-w>l

" alignment mappings
nnoremap <silent> <leader>= :normal vip<CR> :'<,'>EasyAlign =<CR>
vnoremap <silent> <leader>= :'<,'>EasyAlign =<CR>
vmap <Enter> <Plug>(EasyAlign)
nmap ga <Plug>(EasyAlign)

augroup Terminal
	autocmd!
	au BufWinEnter,WinEnter term://* startinsert
	au TermOpen * call SetMatlabMaps()
augroup END

" no folding on open bracket
augroup Folding
	autocmd!
	au InsertEnter * if !exists('w:last_fdm') | let w:last_fdm=&foldmethod | setlocal foldmethod=manual | endif
	au InsertLeave,WinLeave * if exists('w:last_fdm') | let &l:foldmethod=w:last_fdm | unlet w:last_fdm | endif
augroup END

" Source init.vim on write
augroup VimIntern
	autocmd!
	au BufWritePost ~/Documents/setup/nvim/init.vim source %
	" check for file change
	au FocusGained,BufEnter,CursorMoved,CursorMovedI,CursorHold,CursorHoldI * :silent! checktime
	" change working directory to current files directory
	au BufEnter * silent! lcd %:p:h
augroup END

" tmux window title
augroup TmuxTitle
	autocmd!
	au VimEnter * call SaveTmuxWindowName()
	au SessionLoadPost * call ChangeTmuxToSessionName()
	au VimLeave * call system("tmux rename-window '" . g:tmuxWindowName . "'")
augroup END

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" filetype specific
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" matlab
augroup Matlab
	autocmd!
	au FileType matlab let b:commentary_format='% %s'
	au FileType matlab setlocal listchars=eol:¬,tab:\|\ ,trail:·
	au FileType matlab nnoremap <leader>ml :call OpenMatlabInTerminal()<CR>
    " au FileType matlab inoremap <silent> = =<Esc>:call <SID>ealign()<CR>a
augroup END

" c/c++
augroup Cpp
	autocmd!
	au FileType c,cpp setlocal listchars=eol:¬,tab:\|\ ,trail:·
	au FileType c,cpp nnoremap <leader>ml :call OpenMatlabInTerminal()<CR>
    " au FileType c,cpp inoremap <silent> = =<Esc>:call <SID>ealign()<CR>a
augroup END

" tex
augroup Tex
	autocmd!
	au Filetype tex,latex setlocal foldmethod=expr
	au Filetype tex,latex setlocal foldlevel=0
	au Filetype tex,latex setlocal spell
	" au Filetype tex,latex setlocal textwidth=80
	au Filetype tex,latex inoremap $ $$<Left>
	au BufWritePost *.tex Neomake
augroup END

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" custom functions
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" open terminal with matlab in bottom right split
function! OpenMatlabInTerminal()
	execute "normal \<C-w>l"
	split
	terminal mlnd
	call SetMatlabMaps()
endfunction

function! SetMatlabMaps()
	if bufname('') =~? "mlnd"
		tnoremap <buffer> <leader><leader>mc close all<CR>
		tnoremap <buffer> <leader><leader>mw clear<CR>
		tnoremap <buffer> <leader><leader>mf clear functions<CR>
		nnoremap <buffer> <C-c> i<C-c>
	endif
endfunction

" change tmux window name to session
function! ChangeTmuxToSessionName()
	let sessionName = v:this_session
	if strlen(sessionName)
		let session = substitute(sessionName, ".*/", "", "g")
		call system("tmux rename-window '" . session . "'")
	else
		call system("tmux rename-window 'nvim'")
	endif
endfunction

function! SaveTmuxWindowName()
	let g:tmuxWindowName = system("tmux display-message -p '#W'")
	call system("tmux rename-window 'nvim'")
endfunction

" remove whitespaces
function! TrimWhiteSpace()
	%s/\s\+$//e
endfunction

" function! s:ealign()
"   let p = '^.*=\s.*$'
"   if exists(':Tabularize') && getline('.') =~# '^.*=' && (getline(line('.')-1) =~# p || getline(line('.')+1) =~# p)
"     let column = strlen(substitute(getline('.')[0:col('.')],'[^=]','','g'))
"     let position = strlen(matchstr(getline('.')[0:col('.')],'.*=\s*\zs.*'))
"     Tabularize/=/l1
"     normal! 0
"     call search(repeat('[^=]*=',column).'\s\{-\}'.repeat('.',position),'ce',line('.'))
"   endif
" endfunction

" toggle the quickfix or location list window.
function! GetBufferList()
	redir =>buflist
	silent! ls
	redir END
	return buflist
endfunction

function! ToggleList(bufname, pfx)
	let buflist = GetBufferList()
	for bufnum in map(filter(split(buflist, '\n'), 'v:val =~ "'.a:bufname.'"'), 'str2nr(matchstr(v:val, "\\d\\+"))')
		if bufwinnr(bufnum) != -1
			exec(a:pfx.'close')
			return
		endif
	endfor
	if a:pfx == 'l' && len(getloclist(0)) == 0
		echohl ErrorMsg
		echo "Location List is Empty."
		return
	endif
	let winnr = winnr()
	exec(a:pfx.'open')
	if winnr() != winnr
		wincmd p
	endif
endfunction

" let neomake_matlab_mlint_maker = {
" 		\ 'exe': 'mlint',
" 		\ 'errorformat':
" 				\ '%+PFile:\ %f,' .
" 				\ 'L\ %l\ (C\ %c):\ %m,' .
" 				\ 'L\ %l\ (C\ %c-%.):\ %m,',
" 		\ }

" neomake matlab maker
let neomake_matlab_mlint_maker = {
			\ 'exe': 'mlint',
			\ 'errorformat':
			\ '%+PFile:\ %f,' .
			\ 'L\ %l\ (C\ %c):\ %*[a-zA-Z0-9]:\ %m,'.
			\ 'L\ %l\ (C\ %c-%*[0-9]):\ %*[a-zA-Z0-9]:\ %m'
			\ }
