set undodir=~/.cache/vim/undo
set directory=~/.cache/vim/swap
set backupdir=~/.cache/vim/backup
set viewdir=~/.cache/vim/view
set runtimepath=~/.config/vim,$VIMRUNTIME,/usr/share/vim/vimfiles/,~/.config/vim/after

" {{{1 Plugin
call plug#begin('~/.config/vim/bundle')
" 1. Plugins
"   Vim-plug - Plugin manager
    Plug 'junegunn/vim-plug'

    Plug './archlinux-snippets'
    " Plug './rss-reader.vim'

"   Vim-Go - for go stuff
    Plug 'fatih/vim-go', {'for': 'go'}
    " Plug 'rust-lang/rust.vim', {'for': 'rust'}
    " Plug 'racer-rust/vim-racer', {'for': 'rust'}
    " let g:racer_cmd = "/usr/bin/racer"
    " let g:racer_experimental_completer = 1

"   Vim-Wiki - For notes and stuff
    Plug 'vimwiki/vimwiki', {'on' : ['VimwikiIndex', 'VimwikiUISelect'], 'for': 'wiki' }
    " Plug 'itchyny/calendar.vim', {'on' : 'Calendar', 'for': 'wiki' }
    " Plug 'tbabej/taskwiki', {'on': 'VimwikiIndex', 'for': 'wiki'}

" Comletion and linting
    Plug 'dense-analysis/ale'

    Plug 'prabirshrestha/vim-lsp'

"   GIT STUFF
"   Because its great
    Plug 'tpope/vim-fugitive'
    Plug 'tpope/vim-git'

" Misc
    Plug 'tpope/vim-unimpaired'
    Plug 'tpope/vim-obsession'
    Plug  'tpope/vim-sleuth'

"   Commenting
    Plug 'tpope/vim-commentary'
    Plug 'tpope/vim-surround'

"   Trying out snippets
    Plug 'sirver/ultisnips'
    Plug 'honza/vim-snippets'

    Plug 'junegunn/fzf.vim'

    Plug 'vim-test/vim-test'

    let g:vimspector_base_dir=expand('$XDG_CONFIG_HOME/vim/vimspector')
    Plug 'puremourning/vimspector'

" Style
    Plug 'vim-airline/vim-airline'
    Plug 'whatyouhide/vim-gotham'
    Plug 'airblade/vim-gitgutter'

" goyo for editing
    Plug 'junegunn/goyo.vim'


  Plug 'iamcco/markdown-preview.nvim', { 'do': { -> mkdp#util#install() }, 'for': ['markdown', 'vim-plug']}

call plug#end()
" }}}1
" {{{1 Description

" 2. Hotkeys
"   2.1 Leader Hotkeys (SPACE)
"       f: find
"       g: grep
"       t: tab things
"       d: Git diff 
"       [: Ale go to definition
"       r: Ale find references
"       h: Ale hover
"       e: toggle quickfix
"       l: toggle location list
"       j: prev buffer 
"       k: next buffer 
"       <Tab>: Cycle tabs
"       /: Open last text match innside a quickfix window 
"   2.1.1 LSP Stuff
"       gn: Next Reference
"       gp: Previous Reference
"       gI: Implementation
"       ga: Code Action
"       gd: Definition
"       gk: Peek Definition
"       gt: Type Definition
"       gm: Signature Help
"       go: Document Symbol
"       gr: Rename
"       gw: Workspace Symbol
"   2.1.2 Tests / Debugger
"       F5: continue
"       Shift+F5: quit
"       F6: Pause
"       F9: Toggle Breakpoint
"   2.2 Maps
"      2.1 - Normal
"           ^A: start of line
"           ^E: end of line
"           ^Q: Paranthesis match
"           ESC: Disable hlsearch
"           ^J: rebound }
"           ^K: rebound {
"           ^P: Location/Quickfix previous
"           ^N: Location/Quickfix next 
"      2.3 - Visual
"           *: Visual hlsearch 
"      2.4 - Command Line 
"           ^J: Down in history
"           ^K: Up in history
"           ^A: start of line
"           ^E: end of line
" }}}1
" {{{1 Base config

" =========
" Theme
" =========
set termguicolors
set t_Co=256
let &t_SI = "\<Esc>[6 q"
let &t_SR = "\<Esc>[4 q"
let &t_EI = "\<Esc>[2 q"
set t_ut=
syntax enable
filetype plugin indent on
colorscheme gotham256

" Sane defaults
set ff=unix
set nocompatible
set shell=/bin/zsh
set enc=utf-8
set fenc=utf-8
let $MYVIMRC="$XDG_CONFIG_HOME/vim/vimrc"

" =========
" Visual 
" =========
set number
set relativenumber  " start with relative numbers
set ruler
set cursorline
set noshowmode
set laststatus=2    " always show statusbar  
set ttimeoutlen=50
set shortmess=IatO    "We dont care for the intro message
set list
set listchars=tab:>-


" =========
" Behaviour
" =========
set nobackup            " lol
set backupskip=/tmp
set noswapfile          " Yolo
set magic               " Muh regex
set mouse=""              " We don't want the mouse
set clipboard=unnamed   " We want to access clipboard from X
set scrolloff=10 	    " 10 lines space between frame and cursor
set splitright          " Splitting right feels more natrual
" set splitbelow
set ttyfast
set diffopt=filler,vertical,foldcolumn:0,context:4,indent-heuristic,algorithm:patience,hiddenoff
set hidden              " So we can create new buffers and dont need to save them
set noesckeys           " Remap esc!

set wrap
set wrapmargin=80
set textwidth=120
"History and undo
set history=1000
set undofile

set undolevels=1000
set undoreload=10000
" Completion menu
set completeopt=menu,menuone,popup,noselect,noinsert
set omnifunc=ale#completion#OmniFunc

"Wildmenu
set path=.                  " Include relative directory to the file
set path+=,,                " Include current directory
set path+=**                " Include recurisve directories
set wildmenu            	" visual autocomplete for command menu
set wildignorecase      " Make wildmenu ignore our case
set wildmode=longest,full	" Show vim completion menu

" File ignores for wildmenu
set wildignore+=.git
set wildignore+=*.pyc
set wildignore+=node_modules
set wildignore+=.tags
set wildignore+=*.git*
set wildignore+=*cache*
set wildignore+=*logs*
set wildignore+=*node_modules/**
set wildignore+=*.gem
set wildignore+=log/**
set wildignore+=tmp/**
set wildignore+=*.png,*.jpg,*.gif

" =========
" Searching
" =========
set ignorecase
set smartcase
set incsearch

" ===========
" Indentation
" ===========
set expandtab " We want spaces!
set tabstop=4
set softtabstop=4
set shiftwidth=4
set autoindent 	" Indent automatically
set smartindent " Clever indentation

" =======
" Folding 
" =======
if &foldmethod ==# ''
  set foldmethod=syntax
endif
set foldlevel=0
set foldcolumn=0
set foldtext=TxtFoldText()

function! TxtFoldText()
  let level = repeat('-', min([v:foldlevel-1,3])) . '+'
  let title = substitute(getline(v:foldstart), '{\{3}\d\?\s*', '', '')
  let title = substitute(title, '^["#! ]\+', '', '')
  return printf('%-4s %-s', level, title)
endfunction

" }}}}2
" {{{1 Mapping
"{{{2 Remappings
inoremap # X<BS>#

" Dont move on *
nnoremap <silent> * *<c-o>

map ø :
map ; :

" More natural movement when lines wrap
noremap j gj
noremap k gk
nnoremap gj 5j
nnoremap gk 5k

" Emacs stuff i really like
noremap <C-A> ^
noremap <C-E> $
noremap <C-Q> %

"Faster up and down
noremap <silent> <C-J> :<C-u>execute "keepjumps norm! " . v:count1 . "}"<CR>
noremap <silent> <C-K> :<C-u>execute "keepjumps norm! " . v:count1 . "{"<CR>
vnoremap <silent> <C-J> :<C-u>execute "keepjumps norm! " . v:count1 . "}"<CR>
vnoremap <silent> <C-K> :<C-u>execute "keepjumps norm! " . v:count1 . "{"<CR>


" Folds
nnoremap          zf zMzvzz
nnoremap          zz za
nnoremap <silent> zj :silent! normal! zc<cr>zjzvzz
nnoremap <silent> zk :silent! normal! zc<cr>zkzvzz[z"
" Command line
cnoremap <C-K> <Up>
cnoremap <C-J> <Down>
cnoremap <C-A> <Home>
cnoremap <C-E> <End>
"}}}
"{{{2 Leader mapping
let mapleader=" "
let maplocalleader=","

" map <silent><leader>s :source ~/.vimrc<CR>
map <leader>g :Rg 
map <leader>[ :LspDefinition<CR>
map <leader>r :LspReferences<CR>
map <leader>s :LspSignatureHelp<CR>

map <leader>m :make<cr>

" Buffers
nnoremap <leader>j  :bprev<CR>
nnoremap <leader>k  :bnext<CR>
nnoremap <leader>c  :bw<CR>

" Fugitive
nnoremap gd :Gdiffsplit!<cr>
nnoremap gs :G<CR>

"}}}
""{{{2 New mappings
"" ========
"" New Maps
"" ========
" map <silent><ESC> :set hlsearch!<CR>
map <ScrollWheelUp> <nop>
map <S-ScrollWheelUp> <nop>
map <ScrollWheelDown> <nop>
map <S-ScrollWheelDown> <nop>

noremap <silent><C-S> :silent update<CR>
inoremap <silent> <C-S> <C-O>:update<CR>
nnoremap <leader><TAB> :tabnext<CR>

" This monster lets us use star with a visual selection
vnoremap <silent> * :<C-U>
  \let old_reg=getreg('"')<Bar>let old_regtype=getregtype('"')<CR>
  \gvy/<C-R><C-R>=substitute(
  \escape(@", '/\.*$^~['), '\_s\+', '\\_s\\+', 'g')<CR><CR>
  \gV:call setreg('"', old_reg, old_regtype)<CR>

" Ref: toggle.vim
nnoremap <silent> <leader>/ :execute 'vimgrep /'.@/.'/g %'<CR>:copen<CR>
nnoremap <silent><C-n> :execute windowNext<cr>zvzz
nnoremap <silent><C-p> :execute windowPrev<cr>zvzz
"}}}
"{{{2 Commands
cmap W!! w !sudo tee % >/dev/null
command! Source :source ~/.config/vim/vimrc
"}}}
" }}}2
"{{{1 Autocommand
"{{{2 Default aucommands
augroup filetypes
    autocmd!
    au BufNewFile,BufRead *.md,*.markdown setlocal filetype=ghmarkdown | setlocal tw=80
    au Filetype mail setlocal tw=80 
    au Filetype latex setlocal tw=80 
    au Filetype sh setlocal noexpandtab
    au Filetype gitcommit setlocal spell | setlocal tw=72
    au Filetype git setlocal foldlevel=20
augroup END

augroup vimrc_autocommands
  autocmd!
  autocmd WinEnter,FocusGained  * setlocal cursorline
  autocmd WinLeave,FocusLost    * setlocal nocursorline
  autocmd InsertEnter           * setlocal norelativenumber
  autocmd InsertLeave           * setlocal relativenumber

  autocmd BufReadPost *
        \ if line("'\"") > 0 && line("'\"") <= line('$') |
        \   execute 'normal! g`"' |
        \ endif
augroup END
"}}}
"{{{2 Goyo
" Because numbers can fuck off
function! s:goyo_enter()
    augroup goyo_enter
        autocmd BufEnter    *   setlocal tw=95
        autocmd InsertEnter *   setlocal nonumber
        autocmd InsertLeave *   setlocal norelativenumber
    augroup END
endfunction

function! s:goyo_leave()
  augroup goyo_enter
    autocmd!
  augroup END
  augroup! goyo_enter 
endfunction

let g:goyo_width = 95

autocmd User GoyoEnter nested call <SID>goyo_enter()
autocmd User GoyoLeave nested call <SID>goyo_leave()
"}}}
"}}}
"{{{1 Plugins
"{{{2 internal: matchit
packadd! matchit
"}}}
"{{{2 plugin: vimtex
let g:vimtex_complete_enabled = 1
let g:vimtex_complete_bib = {"recursive": 1, "simple": 1}
"}}}
"{{{2 plugin: airline
let g:airline_theme='gotham'
let g:airline_extensions = ['branch', 'tabline', 'ale']
"}}}
"{{{2 plugin: fzf 
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'] }
let g:fzf_tags_command = 'ctags -R --options=/home/fox/.config/ctags'
map <leader>f :FZF<CR>
map <leader>t :Tags<CR>
nmap <Space><Space> :Buffers<CR>
map <leader>v :BCommits<CR>
imap <silent><c-l> <C-O>:Snippet<CR>

imap <c-x><c-k> <plug>(fzf-complete-word)
imap <c-x><c-f> <plug>(fzf-complete-path)
imap <c-x><c-j> <plug>(fzf-complete-file-ag)
imap <c-x><c-l> <plug>(fzf-complete-line)
"}}}
"{{{2 plugin: ultisnips
" We dont really want expand trigger over tab.
" CBA to add a shitton of vimscript for tab completion
let g:UltiSnipsExpandTrigger="<c-j>"
let g:UltiSnipsJumpForwardTrigger="<c-j>"
let g:UltiSnipsJumpBackwardTrigger="<c-k>"
let g:UltiSnipsSnippetsDir="~/.config/vim/snippets/"
let g:UltiSnipsSnippetDirectories=["UltiSnips", "user_snippets"]
"}}}
"{{{2 plugin: vim-go
let g:go_info_mode = 'guru'
let g:go_gopls_enabled = 0
let g:go_doc_keywordprg_enabled = 0
let g:go_def_mapping_enabled = 0
"}}}
"}}}
set viminfo+=n~/.cache/vim/viminfo
" vim: fdm=marker
