
" vim-plug {{{
    " Automatic installation
"    if empty(glob('~/.vim/autoload/plug.vim'))
"        silent !curl -fLo ~/.vim/autoload/plug.vim --create-dirs
"        \ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
"        autocmd VimEnter * PlugInstall --sync | source $MYVIMRC
"    endif

    call plug#begin('~/.vim/plugins')

    Plug 'junegunn/vim-easy-align'
    Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --bin --all' }
    Plug 'tpope/vim-surround'
    Plug 'tpope/vim-commentary'
    Plug 'w0rp/ale'
    Plug 'airblade/vim-gitgutter'
    Plug 'itchyny/lightline.vim'
    Plug 'tpope/vim-repeat'
    Plug 'haya14busa/incsearch.vim'
    Plug 'gorodinskiy/vim-coloresque'
    Plug 'sheerun/vim-polyglot'
    Plug 'nvie/vim-flake8'
    Plug 'KKPMW/sacredforest-vim'
    Plug 'wolf-dog/lightline-sceaduhelm.vim'
    " Plug 'unblevable/quick-scope'
    Plug 'tpope/vim-fugitive'
    " Plug 'l04m33/vlime', {'rtp': 'vim/'}
    " Plug 'kovisoft/paredit'
    Plug 'sainnhe/vim-color-forest-night'
    Plug 'justinmk/vim-sneak'
    Plug 'axvr/zepl.vim'
    " Plug 'kovisoft/slimv'
    Plug 'tpope/vim-vinegar'
    " Plug 'preservim/nerdtree'
    Plug 'vimwiki/vimwiki'
    Plug 'simnalamburt/vim-mundo'
    Plug 'tpope/vim-dadbod'
    Plug 'junegunn/gv.vim'
    Plug 'rbong/vim-flog'
    Plug 'tpope/vim-unimpaired'
    Plug 'junegunn/goyo.vim'
    " Clojure
    Plug 'guns/vim-clojure-static' " syntax
    Plug 'tpope/vim-fireplace'
    Plug 'guns/vim-sexp'
    Plug 'tpope/vim-sexp-mappings-for-regular-people'
    Plug 'dylanaraps/wal.vim'
    Plug 'alvan/vim-closetag'
    Plug 'mattn/emmet-vim'
    " Plug 'tpope/vim-salve'
    Plug 'chrisbra/colorizer'
    " Plug 'ycm-core/YouCompleteMe'
    Plug 'vim-pandoc/vim-pandoc'
    Plug 'vim-pandoc/vim-pandoc-syntax'
    " cljfold

    " Todo:
    call plug#end()

"}}}

" appearance {{{
    colorscheme zenburn
    syntax on                 " Enable syntax
    filetype plugin on
    set encoding=utf-8        " Keep utf-8 encoding
    set scrolloff=2           " Keep at least 3 lines above and below cursor
    set showmode              " Something something buffers
    set showcmd               " Show command in bottom bar
    set wildmenu              " Visual autocomplete for command menu
    set wildmode=list:longest " Show all completions on tab
    set laststatus=2        " Last window will always have statusline
    set showmatch             " Highlight matching [{()}]
    set cursorline            " Highlight current line

    " remove underline on current line number
    hi CursorLineNr cterm=bold 

    " Lightline
    let g:lightline = { 'colorscheme': 'sceaduhelm' }
    set fillchars+=vert:│

    command! LightlineReload call LightlineReload()

    function! LightlineReload()
    call lightline#init()
    call lightline#colorscheme()
    call lightline#update()
    endfunction
"    }}}

" Movement {{{
    " TODO: map alt-j and k to move text lines vertically, maintaining indent
" }}}

" Folding {{{
    set foldenable        " Enable folding
    set foldmethod=marker " Fold sections by marker
    set foldlevel=0       " Fold by default
    set modelines=1       " Check final line of file for modeline

" }}}

" behavior {{{
    set nocompatible               " Turn off vi compatability nonsense
    set hidden                     " Hide buffer when opening new file
    set visualbell                 " Use visual bell instead of beeping
    set ttyfast                    " Improves smoothness and drawing
    set backspace=indent,eol,start " Always allow backspacing
    set undofile                   " Make .un file for persistent undo
    set relativenumber             " Make numbers relative to current line
    set lazyredraw                 " Redraw only when necessary
    set updatetime=100             " Make updates happen faster (gitgutter)
    set splitright                 " Make split to right by default
    set splitbelow
    set winheight=30               " Soft minimum window height (active)
    "set winminheight=10            " Hard minimum window height (inactive)
    set winwidth=85                " Window width for current window
    set winminwidth=30             " Hard minimum for window width
    set t_vb=                      " No visual bell ever
    let g:sneak#use_ic_scs=1
    set virtualedit=block
    let g:netrw_keepdir=0          " cwd follows netrw location
"}}} 

" searching {{{
    set gdefault   " Remove default g flag on search
    set ignorecase " Ignore case for searches
    set smartcase  " Case-specific only when uppercase
    set hlsearch   " Don't continue to highlight searched phrases.
    set incsearch  " But do search as characters are entered
    " Remap tab to jump by brackets
    " Nnoremap <tab> %
    " Vnoremap <tab> %
    " Remap tab to jump by window

"}}}

" tab settings {{{
    set tabstop=4 " Number of visual spaces per tab
    set softtabstop=4 " Should always = tabstop
    set shiftwidth=4 " Indent/outdent by 4 columns
    set expandtab       " Tabs are spaces
    set shiftround      " Always indent/outdent to the nearest tabstop
    " Make search terms more visible
    highlight Visual ctermbg=DarkGreen ctermfg=Black
    set autoindent      " Auto indentation

"}}}

" ruler settings {{{
    set rulerformat=%l,%-2v\|%4L\ Lines " Display line, column, and total lines
    set ruler                           " Turn on ruler

"}}}

" long line handling {{{
    " set textwidth=79
    " set fo=t
"   set colorcolumn=85

"}}}

" leaders {{{
    :let mapleader = ","

    " Clear search highlighting with leader-space
    nnoremap <leader><space> :noh<cr>
   
    " Underline with line of the same length
    nnoremap <leader>- yypv$r-

    " Insert date on current line
    nnoremap <leader>d k :r !date <cr>

    nnoremap <leader>k :vert new ~/.vim/bindings.md <cr>
    tnoremap <leader><esc> <C-\><C-n>

"}}}

" invisible characters {{{
    set list
    set listchars=tab:▸\ ,eol:¬

"}}}

" hjkl {{{
    " Disable arrow keys in normal and visual mode
    nnoremap <up> <nop>
    nnoremap <down> <nop>
    nnoremap <left> <nop>
    nnoremap <right> <nop>
    inoremap <up> <nop>
    inoremap <down> <nop>
    inoremap <left> <nop>
    inoremap <right> <nop>
    " Disable h and l
    " nnoremap h <nop>
    " nnoremap l <nop>
    " Make j and k move by screen line, not file line
    nnoremap j gj
    nnoremap k gk

"}}}

" slimv{{{
    " let g:slimv_repl_split=2
    " let g:slimv_repl_split_size=10

"}}}

" {{{ web dev
    autocmd FileType html set softtabstop=2     
    autocmd FileType html set ts=2     
    autocmd FileType html set shiftwidth=2     
    autocmd FileType css set softtabstop=2     
    autocmd FileType css set ts=2     
    autocmd FileType html set shiftwidth=2     

    " Emmet tab size
    let g:user_emmet_settings = {
    \    'indentation' : ' '
    \}
" }}}

" clojure {{{
    " TODO: make only work in clojure files
    nnoremap <leader>e :Eval<CR>      " eval form
    nnoremap <leader>E :%Eval<CR>     " eval file
" }}}

" split pane navigation {{{
    " Map vertical split to \ w, switch to it, open explorer, prompt for filename
    " TODO: make new window prompt use fzf
    " nnoremap <leader>w <C-w>v<C-w>l:e <C-S-d><BS><BS>open 
    " Switch panes wit ctrl + h/j/k/l
    nnoremap <C-h> <C-w>h
    nnoremap <C-j> <C-w>j
    nnoremap <C-k> <C-w>k
    nnoremap <C-l> <C-w>l
    nnoremap <C-c> :close <cr>
    " TODO remap to something else
    nnoremap <C-n> :bn <cr>
    " Term  mode
    tnoremap <C-h> <C-w>h
    tnoremap <C-j> <C-w>j
    tnoremap <C-k> <C-w>k
    tnoremap <C-l> <C-w>l
    tnoremap <C-c> :close <cr>
    tnoremap <C-n> :bn <cr>
    tnoremap <Esc> <C-\><C-n>

    " TODO: remap pane resize to something else (leader?)
    " quick-scope
    " Trigger a highlight in the appropriate direction when pressing these keys:
    let g:qs_highlight_on_keys = ['f', 'F', 't', 'T']

    augroup qs_colors
        autocmd!
        autocmd ColorScheme * highlight QuickScopePrimary guifg='#afff5f' gui=underline ctermfg=155 cterm=underline
        autocmd ColorScheme * highlight QuickScopeSecondary guifg='#5fffff' gui=underline ctermfg=81 cterm=underline
    augroup END

    nnoremap <c-s> gt

"}}}

" file specific {{{
    " In markdown files, when writing add two spaces to each line to fix spacing 
    " In compiled version
    " au BufWritePost *.md silent! %s/[^ ]\zs$/\1  /
    " TODO: find a better solution
    " Bold something in a markdown file
    " :au FileType markdown nmap <leader>b i**<esc>ea**<esc>b
    " Python
    " au BufNewFile,BufRead *.py
    "\ set tabstop=4
    "\ set softtabstop=4
    "\ set shiftwidth=4
    "\ set textwidth=79
    "\ set expandtab
    "\ set autoindent
    "\ set fileformat=unix
    "" Webdev
    " au BufNewFile,BufRead *.js, *.html, *.css
    "\ set tabstop=2
    "\ set softtabstop=2
    "\ set shiftwidth=2

"}}}

" plugin modification {{{
    " FZF
       map <C-p> :FZF<cr>
     " This is the default extra key bindings
        let g:fzf_action = {
        \ 'ctrl-t': 'tab split',
        \ 'ctrl-x': 'split',
        \ 'ctrl-v': 'vsplit' }

        " Default fzf layout
        " - down / up / left / right
        let g:fzf_layout = { 'down': '~30%' }

        " Customize fzf colors to match your color scheme
        let g:fzf_colors =
        \ { 'fg':    [ 'fg', 'Normal'],
        \ 'bg':      [ 'bg', 'Normal'],
        \ 'hl':      [ 'fg', 'Comment'],
        \ 'fg+':     [ 'fg', 'CursorLine', 'CursorColumn', 'Normal'],
        \ 'bg+':     [ 'bg', 'CursorLine', 'CursorColumn'],
        \ 'hl+':     [ 'fg', 'Statement'],
        \ 'info':    [ 'fg', 'PreProc'],
        \ 'border':  [ 'fg', 'Ignore'],
        \ 'prompt':  [ 'fg', 'Conditional'],
        \ 'pointer': [ 'fg', 'Exception'],
        \ 'marker':  [ 'fg', 'Keyword'],
        \ 'spinner': [ 'fg', 'Label'],
        \ 'header':  [ 'fg', 'Comment'] }

     " EasyAlign
     "" Start interactive EasyAlign in visual mode (e.g. vipga)
     xmap ga <Plug>(EasyAlign)
     " Start interactive EasyAlign for a motion/text object (e.g. gaip)
     nmap ga <Plug>(EasyAlign)

"}}}

" git commands {{{
    " Gitgutter hunk view
    nmap ghv <Plug>(GitGutterPreviewHunk)
    nmap ghn <Plug>(GitGutterNextHunk)
    nmap ghp <Plug>(GitGutterPrevHunk)
    nmap ghf <Plug>(GitGutterFold)
    nmap ghs <Plug>(GitGutterStageHunk)
    " Controls fugitive diff split direction
    set diffopt=vertical
    command! Gundo !git reset --soft HEAD~1
"}}}

" fold search {{{

" command to fold everything except what you searched for
    command! -nargs=* Fs
        \ if <q-args> != '' |
        \   exe "normal /".<q-args>."\<CR>" |
        \ endif |
        \ if @/ != '' |
        \   setlocal
        \     foldexpr=FoldRegex(v:lnum,@/,2)
        \     foldmethod=expr
        \     foldlevel=0 |
        \ endif
    
    function! FoldRegex(lnum,pat,context)
    " get start/end positions for context lines
    let startline=a:lnum-a:context
    while startline < 1
        let startline+=1
    endwhile
    let endline=a:lnum+a:context
    while endline > line('$')
        let endline-=1
    endwhile
    
    let returnval = 2
    
    let pos=getpos('.')
    
    " search from current line to get matches ON the line
    call cursor(a:lnum, 1)
    let matchline=search(a:pat,'cW',endline)
    if matchline==a:lnum
        let returnval = 0
    elseif matchline > 0
        " if current line didn't match, there could have been a match within
        " trailing context lines
        let returnval = 1
    else
        " if no match at current line, search leading context lines for a match
        call cursor(startline, 1)
        let matchline=search(a:pat,'cW',a:lnum)
        if matchline > 0
        let returnval = 1
        endif
    endif
    
    call setpos('.',pos)
    
    return returnval
    endfun

" }}}

" copy matches {{{

function! CopyMatches(reg)
  let hits = []
  %s//\=len(add(hits, submatch(0))) ? submatch(0) : ''/gne
  let reg = empty(a:reg) ? '+' : a:reg
  execute 'let @'.reg.' = join(hits, "\n") . "\n"'
endfunction
command! -register CopyMatches call CopyMatches(<q-reg>)

" }}}

" gvim {{{
    set guioptions=Ace
    set guifont=Consolas:h11
    " set guifont=Bitstream\ Vera\ Sans\ Mono
    set guioptions-=e
    set pythondll=python27.dll
"}}}

" zepl {{{
    augroup zepl
        autocmd!
        autocmd FileType python     let b:repl_config = { 'cmd': 'python3' }
        autocmd FileType javascript let b:repl_config = { 'cmd': 'python3' }
        autocmd FileType clojure    let b:repl_config = { 'cmd': 'clj' }
        autocmd FileType scheme     let b:repl_config = { 'cmd': 'rlwrap csi' }
        autocmd FileType lisp       let b:repl_config = { 'cmd': 'sbcl' }
        autocmd FileType julia      let b:repl_config = { 'cmd': 'julia' }
        " autocmd FileType cs         let b:repl_config = { 'cmd': '"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\VsDevCmd.bat"' }
        autocmd FileType cs         let b:repl_config = { 'cmd': 'cmd' }
    augroup END
"}}}

" TODO: rebind c-n
" TODO: change ,k to ,n and add notes to version control

" folding options, this must be last in file
" vim:foldmethod=marker:foldlevel=0


