let mapleader = "\<Space>"
call plug#begin()

Plug 'easymotion/vim-easymotion'
Plug 'vim-airline/vim-airline'
Plug 'vim-syntastic/syntastic'
Plug 'vim-airline/vim-airline-themes'
Plug 'rust-lang/rust.vim'
Plug 'Valloric/YouCompleteMe', { 'for': ['c', 'cpp', 'rust'] }
Plug 'liuchengxu/space-vim-dark'
Plug 'scrooloose/nerdcommenter'
Plug 'scrooloose/nerdtree'
Plug 'junegunn/vim-easy-align'
Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --bin' }
Plug 'junegunn/fzf.vim'
Plug 'junegunn/vim-emoji'
Plug 'mhinz/vim-startify'
Plug 'tmux-plugins/vim-tmux'

call plug#end()

" Options
set backspace=2
set wildmenu
set wildmode=longest:full
set number
set encoding=utf-8
set timeoutlen=500
set list
set listchars=eol:$,tab:>-,trail:.,extends:>,precedes:<
set autoread
set ttimeoutlen=50
set nowrap
set cursorline

"  Indenting
set tabstop=4
set softtabstop=4
set shiftwidth=4
set expandtab
set shiftround
set smarttab
set autoindent
set smartindent
set showcmd

"  Tabs/windows/movement
set mouse=i
set splitbelow
set splitright
set scrolloff=2

"  Theming
if has('termguicolors')
    set termguicolors
    let &t_8f = "\<Esc>[38;2;%lu;%lu;%lum"
    let &t_8b = "\<Esc>[48;2;%lu;%lu;%lum"
endif

colo space-vim-dark
highlight LineNr guifg='#20af81' guibg='#212121'
highlight NonText guifg='#837b8d'

"  Because tmux
if &term =~ '^screen'
    " tmux will send xterm-style keys when its xterm-keys option is on
    execute "set <xUp>=\e[1;*A"
    execute "set <xDown>=\e[1;*B"
    execute "set <xRight>=\e[1;*C"
    execute "set <xLeft>=\e[1;*D"
endif

"  Airline
set laststatus=2
let g:airline_extensions = ['tabline']
let g:airline_powerline_fonts = 1
let g:airline_theme = 'violet'
let g:airline_left_sep = ''
let g:airline_right_sep = ''
let g:airline#extensions#tabline#left_sep = ''
let g:airline#extensions#tabline#left_alt_sep = ''
let g:airline#extensions#tabline#enabled = 1
let g:airline#extensions#default#section_truncate_width = {
    \ 'x': 40,
    \ 'y': 10,
    \ 'z': 60
    \ }
let g:airline_section_y = '%{winnr()}'

"  Easy Motion
map / <Plug>(easymotion-sn)
omap / <Plug>(easymotion-tn)

map n <Plug>(easymotion-next)
map N <Plug>(easymotion-prev)
map <leader><leader><leader> <Plug>(easymotion-bd-w)
map <leader><leader>l <Plug>(easymotion-bd-jk)

"  YouCompleteMe
let g:ycm_min_num_chars_for_completion = 5
let g:ycm_filetype_whitelist = { 'cpp': 1, 'rust': 1 }
let g:ycm_global_ycm_extra_conf = '~/.ycm_extra_conf.py'
let g:ycm_rust_src_path = '/Users/adrianbudau/.multirust/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/src'

"General Mappings
nnoremap <enter> :w<CR>
nnoremap <leader>q :q<CR>
nnoremap <leader>fo :e 

nnoremap <leader>fc :w !pbcopy<CR>
set pastetoggle=<F4>

nnoremap <leader>fR :source $MYVIMRC<CR>

"  NERDCommenter
let g:NERDSpaceDelims=1
nmap <leader>;; <Plug>NERDCommenterToggle
omap <leader>;; <Plug>NERDCommenterToggle
vmap <leader>;; <Plug>NERDCommenterToggle

"  NERDTree
noremap <leader>\ :NERDTree<CR>

"  Easy Align
nmap <Leader>ai :EasyAlign<CR>
vmap <Leader>ai :EasyAlign<CR>

"  Buffers
nnoremap <leader>bp :bp<CR>
nnoremap <leader>bn :bn<CR>
nnoremap <leader>bd :bd<CR>
nnoremap <leader>bk :bd<CR>

nnoremap <Tab> :bn<CR>
nnoremap <S-Tab> :bp<CR>

for s:i in range(1, 9)
    execute 'nnoremap <Leader>b' . s:i . ' :b' . s:i .'<CR>'
endfor

"  Tabs/Windows
nnoremap <leader>tc :tabnew<CR>
nnoremap <leader>tp :tabprev<CR>
nnoremap <leader>tn :tabnext<CR>

nnoremap <s-left> :tabprev<CR>
nnoremap <s-right> :tabnext<CR>
inoremap <s-left> <ESC>:tabprev<CR>
inoremap <s-right> <ESC>:tabnext<CR>

nnoremap <leader>ws :split 
nnoremap <leader>wv :vsplit 

for s:i in range(1, 9)
    execute 'nnoremap <Leader>' . s:i . ' :' . s:i . 'wincmd w<CR>'
endfor

"  Fuzzy Finder
nmap <leader>? <plug>(fzf-maps-n)
xmap <leader>? <plug>(fzf-maps-x)
omap <leader>? <plug>(fzf-maps-o)

nnoremap <Leader>ag :Ag<CR>
nnoremap <Leader>bb :Buffers<CR>

nnoremap <Leader>b? :Buffers<CR>
nnoremap <Leader>w? :Windows<CR>
nnoremap <Leader>f? :Files<CR>

nnoremap <Leader>ff :Files ~<CR>

"  Emoji!!!!!!
autocmd FileType markdown setlocal completefunc=emoji#complete

"  Compile
nnoremap <leader>pc :Compile<CR>
command! Compile :call CompileFunc()
function! CompileFunc()
    if exists("b:compile")
        execute "!" . b:compile
    endif
endfunction

"  Run
nnoremap <leader>pr :Run<CR>
command! Run :call RunFunc()
function! RunFunc()
    if exists("b:run")
        execute "!time " . b:run
    endif
endfunction

"    Compile + Run
nnoremap <leader>pcr :CompileRun<CR>
nnoremap <leader>prc :CompileRun<CR>

command! CompileRun :call CompileRunFunc()
function! CompileRunFunc()
    if exists("b:compile")
        execute "!" . b:compile
        if v:shell_error == 0
            call RunFunc()
        endif
    else
        call RunFunc()
    endif
endfunction

"    Debug
nnoremap <leader>pd :Debug<CR>
command! Debug :call Debug()
function! Debug()
    if exists("b:debug")
        execute "!" .b:debug
    endif
endfunction

"Language specific
"  C/C++
autocmd FileType c let b:compile = 'clang -g -O2 -Wall -Wextra % -o %< -lm'
autocmd FileType cpp let b:compile = 'g++ -O2 -std=c++1y -Wall -Wextra % -o %< -lm -Wl,-stack_size,0xd0000000'
autocmd FileType c,cpp let b:run = './%<'
autocmd FileType cpp let b:debug = 'make -C "%:p:h" -f ~/.vim/makefiles/Makefile "%:t:r-debug" && lldb "%<-debug"'

"  Python
autocmd FileType python let b:run = 'python3 %'

"  Java
autocmd FileType java let b:compile = 'javac %'
autocmd FileType java let b:run = 'java %'

"  Matlab
autocmd FileType matlab setlocal textwidth=79
autocmd FileType matlab let w:lengtherror = matchadd('ErrorMsg', '\%>79v.\+', -1)

"  Haskel
autocmd FileType hs setlocal textwidth=79
autocmd FileType hs let w:lengtherror = matchadd('ErrorMsg', '\%>79v.\+', -1)
autocmd FileType hs let b:run = 'runhaskell %'

"  PHP
autocmd Filetype php let w:lengtherror = matchadd('ErrorMsg', '\%>119v.\+', -1)

"  Go
autocmd FileType go setlocal noexpandtab
autocmd FileType go let b:run = 'go run %'

"  JS/CofeeScript
autocmd FileType javascript,coffee setlocal tabstop=2 shiftwidth=2
autocmd FileType javascript let b:run = 'node %'

"  Yaml
autocmd FileType yaml setlocal tabstop=2 shiftwidth=2

"  Nim
autocmd FileType nim setlocal tabstop=2 shiftwidth=2
autocmd FileType nim let b:compile = 'nimc -o %< %'
autocmd FileType nim let b:run = './%<'
autocmd FileType nim let b:debug = 'lldb ./%<'

"  Bash
autocmd FileType bash setlocal noexpandtab
autocmd FileType bash let b:run = 'bash %'

"  Ruby
autocmd FileType ruby let b:run = 'ruby %'

"  Rust
let g:rustfmt_command = "cargo fmt -- "
autocmd FileType rust let b:compile = 'cargo build --release'
autocmd FileType rust let b:run = 'cargo run --release'
autocmd FileType rust nnoremap <leader>fmt :RustFmt<CR>
autocmd FileType rust nnoremap <leader>clp :!cargo +nightly clippy<CR>
