set nocompatible              " be iMproved, required

" Reconfigure Vim to be clean!
set undodir=$XDG_CACHE_HOME/vim/undo//
set directory=$XDG_CACHE_HOME/vim/swap//
set backupdir=$XDG_CACHE_HOME/vim/backup//
set viminfo+='1000,n$XDG_CACHE_HOME/vim/viminfo
set runtimepath-=$HOME/.vim
set runtimepath^=$XDG_CONFIG_HOME/vim,$VIMRUNTIME,$XDG_CONFIG_HOME/vim/after
let g:netrw_home=$XDG_CACHE_HOME.'/vim'

silent !mkdir -p $XDG_CACHE_HOME/vim/swap $XDG_CACHE_HOME/vim/undo $XDG_CACHE_HOME/vim/backup

set tabstop=4
set shiftwidth=0   " Use tabstop
set softtabstop=-1 " Use tabstop
set expandtab
set smarttab
set smartindent
set number
set linebreak
set autoindent
set breakindent
set laststatus=2
set encoding=utf-8
set background=dark
set omnifunc=syntaxcomplete#Complete
set title
set clipboard=unnamed
set wildmenu
set report=0
set lazyredraw
set ttyfast
set autoread
set showmatch
set scrolloff=6
set nojoinspaces
set updatetime=500  " reduce delay from 4s default

let mapleader="\<space>"

" ALE config
let g:ale_completion_enabled = 1
let g:ale_open_list = 1
augroup CloseLoclistWindowGroup
    autocmd!
    autocmd QuitPre * if empty(&buftype) | lclose | endif
augroup END

" Autosave settings
function! SaveIfExist()
    if @% != "" && filereadable(@%) && !&readonly && &modified
        write
    endif
endfunction
set autowrite
autocmd CursorHold,CursorHoldI,InsertLeave,FocusGained,FocusLost * call SaveIfExist()

" Search options
set hlsearch
set ignorecase
set smartcase
set magic

" Auto-resize split on window resize
autocmd VimResized * wincmd =
" More natural splits
set splitbelow          " Horizontal split below current.
set splitright          " Vertical split to right of current.

" Whitespace highlight settings
set list
set listchars=space:·,tab:>-,trail:◦,extends:▶,precedes:◀
highlight SpecialKey ctermfg=8

set cc=+1
highlight ColorColumn ctermbg=8

" Highlight line and column of cursor
set cul cuc
highlight CursorLine   cterm=NONE ctermbg=8
highlight CursorColumn cterm=NONE ctermbg=8

if empty(glob('$XDG_CONFIG_HOME/vim/autoload/plug.vim'))
  silent !curl -fsSLo $XDG_CONFIG_HOME/vim/autoload/plug.vim --create-dirs
    \ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
  autocmd VimEnter * PlugInstall --sync | source $VIMRC
endif

call plug#begin('$XDG_CONFIG_HOME/vim/plug')

Plug 'scrooloose/nerdtree', { 'on':  'NERTreeToggle' }
Plug 'tpope/vim-sensible'
Plug 'tpope/vim-fugitive'
Plug 'tpope/vim-rhubarb'
Plug 'tpope/vim-abolish'
Plug 'tpope/vim-surround'
Plug 'tpope/vim-repeat'
Plug 'tpope/vim-commentary'
Plug 'majutsushi/tagbar'
Plug 'airblade/vim-gitgutter'
Plug 'ryanoasis/vim-devicons'
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
Plug 'lervag/vimtex'
Plug 'JamshedVesuna/vim-markdown-preview'
Plug 'junegunn/fzf.vim'

" Completion and linting
Plug 'dense-analysis/ale'
Plug 'Shougo/deoplete.nvim'
Plug 'roxma/nvim-yarp'
Plug 'roxma/vim-hug-neovim-rpc'

Plug 'fatih/vim-go', { 'do': ':GoUpdateBinaries' }

" Syntax Highlighting
Plug 'chr4/nginx.vim'
Plug 'PotatoesMaster/i3-vim-syntax'
Plug 'puppetlabs/puppet-syntax-vim'
Plug 'saltstack/salt-vim'
Plug 'arrufat/vala.vim'
Plug 'Glench/Vim-Jinja2-Syntax'
Plug 'pearofducks/ansible-vim'
Plug 'jvirtanen/vim-hcl'
Plug 'hashivim/vim-terraform'

call plug#end()

" Change to dvorak-mapped keys
let g:use_dvorak = 1

" Deoplete config
call deoplete#custom#option({
\ 'camel_case': v:true,
\ })
call deoplete#enable()

" Vim-Airline config
let g:Powerline_symbols = 'fancy'
let g:airline_powerline_fonts = 1
let g:airline_theme='solarized'
let g:airline#extensions#tabline#enabled = 1
" ALE integration
let g:airline#extensions#ale#enabled = 1

" vim-markdown plugin
let vim_markdown_preview_toggle=0
let vim_markdown_preview_browser='Chromium'
let vim_markdown_preview_use_xdg_open=1
let vim_markdown_preview_github=1

" LaTeX config
let g:tex_flavor='xelatex'
let g:vimtex_indent_enabled = 0     " auto-indentation is wrong and annoying
autocmd FileType tex silent VimtexCompile
autocmd FileType tex setlocal spell
augroup vimtex
    autocmd!
    autocmd BufWritePost tex call vimtex#toc#refresh()
    autocmd BufWritePost tex call vimtex#labels#refresh()
    autocmd BufWritePost tex silent VimtexCompile
augroup END

" Tagbar configuration
let g:tagbar_width = 50
let g:tagbar_compact = 1
let g:tagbar_show_linenumbers = 1
let g:tagbar_singleclick = 1
let g:tagbar_autopreview = 1

" NERDTree configuration
map  <leader><tab> :NERDTreeToggle<CR>

" FZF configurationn
map  <leader><space> :Files<CR>
map  <leader>b     :Buffers<CR>
map  <leader>l     :Lines<CR>

" Disable mouse
set mouse=nicr
nnoremap <LeftMouse> <nop>
nnoremap <RightMouse> <nop>

" Remap completion
inoremap <C-Space> <C-x><C-o>
inoremap <C-@> <C-Space>

" Unbind arrow keys
for prefix in ['n', 'v']
    for key in ['<Up>', '<Down>', '<Left>', '<Right>']
        exe prefix . "noremap " . key . " <Nop>"
    endfor
endfor

" Source: https://github.com/ChrisLane/dotfiles/blob/1f5efd44e1b78224568645eaec2e6e243959c0a9/.vimrc#L66
" Remove whitespace at end of lines with F5
:nnoremap <silent> <F5> :let _s=@/ <Bar> :%s/\s\+$//e <Bar> :let @/=_s <Bar> :nohl <Bar> :unlet _s <CR>

" Dvorak Hackery
" Source: https://github.com/sporkbox/vimrc/blob/master/vimrc
if (exists("g:use_dvorak") && g:use_dvorak == 1)
	" I use a Dvorak keyboard, so standard vim movement keys are a hassle.
	" Since mnemonics are helpful all around, I need a mapping that gives me
	" pain-free file navigation without screwing up mnemonics (too much).
	"
	" Thus:
	" (D)elete is now (K)ill: d2w == k2w "kill 2 words"
	" Un(T)il is now (J)ump-To: dt( == kj( "kill, jump-to paren"
	" (N)ext is now (L)eap: cn == cl "change up to leap point"

	" Standard movement, which is the true focus of this hack.
	" Mnemonics are awesome, so let's preserve as much as possible.
	noremap d h
	noremap h j
	noremap t k
	noremap n l

	noremap gh gj
	noremap gt gk

	" I work with tabs every now and then. No, I don't have a mnemonic, so
	" stfu.
	noremap gj gt
	noremap gJ gT

	" Window movement, equally important
	noremap <C-w>d <C-w>h
	noremap <C-w>h <C-w>j
	noremap <C-w>t <C-w>k
	noremap <C-w>n <C-w>l

	nnoremap <C-w><C-d> <C-w><C-h>
	nnoremap <C-w><C-h> <C-w><C-j>
	nnoremap <C-w><C-t> <C-w><C-k>
	nnoremap <C-w><C-n> <C-w><C-l>

	nnoremap <C-d> <C-w>h
	nnoremap <C-h> <C-w>j
	nnoremap <C-t> <C-w>k
	nnoremap <C-n> <C-w>l

	" Account for tag jumping
	nnoremap <C-j> <C-t>

	" Remappings for the D key
	noremap k d
	noremap K D

	" Remappings for the T key
	noremap j t
	"noremap J T

	" Remapping for the L key
	noremap l n
	noremap L N

	" General purpose help; the originals remain for convenience
	noremap - 0
	noremap _ $

	" Fold-related keybindings
	noremap zh zj
	noremap zt zk

    " Disable some default vimtex mappings that conflict with rebound keys
    let g:vimtex_mappings_disable = {
        \ 'n': ['tse', 'tsd', 'tsD', 'tsc', 'dse', 'dsc', 'ds$', 'dsd'],
        \ 'x': ['tsd', 'tsD'],
        \}

    " NERDTree configuration
    let NERDTreeMapOpenInTab='\t'   " prevent t opening file

    " Also remap keys in :Explore
    augroup netrw_dvorak_fix
        autocmd!
        autocmd filetype netrw call Fix_netrw_maps_for_dvorak()
    augroup END
    function! Fix_netrw_maps_for_dvorak()
        noremap <buffer> d h
        noremap <buffer> h j
        noremap <buffer> t k
        noremap <buffer> n l
    endfunction

endif

" Save aliases.
com! W w
com! Q q
com! Wq wq
com! WQ wq
com! Wqa wqa
com! WQa wqa
com! WQA wqa
" Write with sudo
cmap w!! w !sudo tee > /dev/null %

" Unmap ex-mode
map Q <nop>


autocmd FileType c setlocal noet
autocmd filetype c,h,cpp,hpp set colorcolumn=81
autocmd filetype c,h,cpp,hpp match ErrorMsg '\%>80v.\+'

autocmd FileType jinja setlocal sts=2 sw=2 et
autocmd FileType markdown setlocal sts=2 sw=2 et
autocmd FileType yaml setlocal sts=2 sw=2 et indentkeys-=<:>
autocmd FileType gitcommit setlocal tw=72 et sw=4