" VIM CORE
set encoding=utf-8
let &titleold="term"
set nocompatible                    " enable advanced features
set autochdir                       " current dir is vim workdir
set title                           " set xterm title
set path+=.,**                      " expand to dirs under workdir
set mouse=v                         " don't interract with the mouse
set laststatus=2                    " always show the status line
set keywordprg=":help"              " show vim help when hitting "K"
set backspace=indent,eol,start      " bkspc behave like expected
set ttimeout                        " activate timeout for key combos
set ttimeoutlen=50                  " set timeout for key combinations
set number                          " enable line numbers
set numberwidth=6                   " space for more numbers
set cursorline                      " highlight line number+cursor line
if has("bsd")
    set cursorlineopt=number
endif
"set cursorcolumn                    " highlight current cursor column
execute "set colorcolumn=" . join(range(73,80), ',')
set modeline                        " read vim mode line in files
set modelines=5                     " top/bottom line no. to search
set lazyredraw                      " no scr. update during macros
set spelllang=de,en                 " spell check languages
syntax enable                       " enable syntax plugin (builtin)
filetype plugin indent on           " load plugins based on filetype
set re=1                            " use old regexp engine (faster)
let mapleader = ","

" INDENTATION
set autoindent                      " indent new lines on same level
set smartindent                     " smart indent for programming
set cindent                         " smart indent for C programming

"set formatprg=fmt\ -mnst\ 4\ -w\ 72 " gq wrap rule
set formatprg=par\ -w72qie           " gq wrap rule

" SEARCH
"set incsearch                       " search while typing
set hlsearch                        " highlight all search matches
"set wrapscan                       " search continues on top
set ignorecase                      " search case insensitive
set smartcase                       " capital letter => case sensitive

" SPACES (TABS)
set tabstop=8                       " tabs are displayed as X spaces
set shiftwidth=4                    " number of spaces used to indent
let &softtabstop=&shiftwidth        " tab key enters X spaces
set expandtab                       " use spaces when hitting tab
set smarttab                        " backspace will delete shiftwidth
set textwidth=0                     " automatically break lines here

set list                            " display control characers
set listchars=tab:>-                " which characters to display

let g:currentmode={
       \ 'n'  : 'NORMAL',
       \ 'v'  : 'VISUAL',
       \ 's'  : 'SELECT',
       \ 'V'  : 'V·Line',
       \ '' : 'V·Block',
       \ 'i'  : 'INSERT',
       \ 'R'  : 'R',
       \ 'Rv' : 'V·Replace',
       \ 'c'  : 'Command',
       \}

" STATUSLINE, AIRLINE/POWERLINE IS FOR NOOBS
set statusline=%#VisualNOS#
set statusline+=\ [%#Visual#%{toupper(g:currentmode[mode()])}%#VisualNOS#]
set statusline+=\ [%#Visual#%f%#VisualNOS#]
set statusline+=%m%r%h%w%q
set statusline+=%=
set statusline+=\ [BUF:%#Visual#%n%#VisualNOS#]
set statusline+=\ [%#Visual#%{&fileencoding?&fileencoding:&encoding}%#VisualNOS#]
set statusline+=\ [%#Visual#%{&fileformat}%#VisualNOS#]
set statusline+=\ [HEX:%#Visual#%B%#VisualNOS#\ INT:%#Visual#%b%#VisualNOS#]
set statusline+=\ [ROW:%#Visual#%l%#VisualNOS#\ COL:%#Visual#%c%#VisualNOS#]
set statusline+=\ [%#Visual#%p%#VisualNOS#%%]
set statusline+=\ 

" C specific highlighting
let c_space_errors=1                " trailing space and before tab
let c_gnu=1                         " GNU gcc specific items
let c_comment_strings=1             " strings and numbers in comment
let c_curly_error=1                 " highlight missing } (may be slow)

" TEMPORARY FILES
set undofile                        " save undo history to disk
set undodir=~/.vim/undo//           " save undo history here
set backup                          " create backups
set backupcopy=yes                  " copy file and edit original
set backupdir=~/.vim/backup//       " save backup files here
set backupskip=mutt-*               " do not create backups of emails
set nowritebackup                   " no extra backup before writing
set writeany                        " write to any file (:w!)
set directory=~/.vim/swapfiles//    " move swapfiles out of the way

" CREATE DIRECTORIES
silent execute '!mkdir -p ~/.vim/undo ~/.vim/backup ~/.vim/swapfiles'

" LOOK N FEEL
set t_Co=256                        " for terminal with 256 colors
set background=dark                 " I prefer dark backgrounds

colorscheme wombat256               " :colorscheme <tab> for more
let g:is_posix = 1                  " $( ) is fine

" THEME TWEAKS
highlight CursorLine   ctermbg=238
highlight ColorColumn  ctermbg=none   ctermfg=9
highlight CursorLineNr ctermbg=none   ctermfg=208 cterm=none
highlight LineNr       ctermbg=0
highlight SpecialKey   ctermbg=232    ctermfg=245
highlight Normal       ctermbg=232
highlight NonText      ctermbg=232    ctermfg=234
highlight ErrorMsg     ctermbg=0      ctermfg=160 cterm=none
highlight VisualNOS    ctermbg=0      ctermfg=238
highlight Visual       ctermbg=232    ctermfg=208
highlight Search       ctermbg=220    ctermfg=0
highlight VertSplit    ctermbg=none

" HIGHLIGHT SPECIAL WORDS
match ErrorMsg '\(TODO:\|FIXME\|XXX\|workaround\|WTF\|\s\+$\| \+\ze\t\)'

" SPELLING FIX (for cursorline)
highlight SpellBad cterm=NONE ctermfg=darkred ctermbg=NONE

" VIMDIFF COLOR FIX
highlight DiffAdd    ctermfg=1 ctermbg=0
highlight DiffDelete ctermfg=2 ctermbg=0
highlight DiffChange ctermfg=3 ctermbg=0
highlight DiffText   ctermfg=4 ctermbg=0
highlight VertSplit  ctermfg=1 ctermbg=0

" CURSOR SHAPE
" let &t_SI = "\e[6 q"                " insert mode: ibeam cursor
" let &t_EI = "\e[2 q"                " normal mode: block cursor

" TAB NAVIGATION
set tabpagemax=25                   " allowed max tabs (10)
inoremap [5^ <Esc>:tabn<CR>       " Strg+PgUp: Next tab
nnoremap [5^ :tabn<CR>
inoremap [6^ <Esc>:tabp<CR>       " Strg+PgDown: Previous tab
nnoremap [6^ :tabp<CR>
inoremap  <Esc>:tabnew<CR>        " Strg+T: New tab
nnoremap  :tabnew<CR>

" TMUX FIXES
map   <PageDown>
imap  <PageDown>
nmap  <PageDown>

map   <PageUp>
imap  <PageUp>
nmap  <PageUp>

map   <PageDown>
imap  <PageDown>
nmap  <PageDown>

map   <PageUp>
imap  <PageUp>
nmap  <PageUp>

" NAVIGATE ON VISUAL LINES (SOFT WRAP)
imap <silent> <Down> <C-o> gj
imap <silent> <Up> <C-o> gk
nmap <silent> <Down> gj
nmap <silent> <Up> gk

" USE ARROW / VIM KEYS INSIDE OMNIBOX
inoremap <expr> j pumvisible() ? '<C-n>' : 'j'
inoremap <expr> k pumvisible() ? '<C-p>' : 'k'
inoremap <expr> <Down> pumvisible() ? '<C-n>' : '<Down>'
inoremap <expr> <Up> pumvisible() ? '<C-p>' : '<Up>'

" NETRW
let g:netrw_banner       = 1        " disable annoying banner
let g:netrw_browse_split = 4        " open in prior window
let g:netrw_altv         = 1        " open splits to the right
let g:netrw_liststyle    = 0        " tree view
let g:netrw_ctags        = "ectags" " ctags executable to use

" TAGS FILE
set tags=.git/tags;                  " Search tagfile backward recursive
nnoremap gt <c-]>                   " Jump to tag (go tag)
nnoremap gb <c-o>                   " Jump to last position (go back)
nnoremap gh :FSHere<CR>             " Jump to header file (go header)

" CSCOPE
if has("cscope")
    set csprg=cscope
    set cst
    set cspc=3
    if filereadable("cscope.out")
        cs add cscope.out
    elseif filereadable(".git/cscope.out")
        cs add .git/cscope.out
    elseif filereadable($CSCOPEDB)
        cs add $CSCOPEDB
    elseif filereadable("../.git/cscope.out")
        cs add ../.git/cscope.out
    elseif filereadable("../../.git/cscope.out")
        cs add ../../.git/cscope.out
    elseif filereadable("../../../.git/cscope.out")
        cs add ../../../.git/cscope.out
    elseif filereadable("../../../../.git/cscope.out")
        cs add ../../../../.git/cscope.out
    endif
    "   'ts'   symbol: find all references to the token under cursor
    "   'tg'   global: find global definition(s) of the token under cursor
    "   'tc'   calls:  find all calls to the function name under cursor
    "   'tt'   text:   find all instances of the text under cursor
    "   'te'   egrep:  egrep search for the word under cursor
    "   'tf'   file:   open the filename under cursor
    "   'ti'   includes: find files that include the filename under cursor
    "   'td'   called: find functions that function under cursor calls
    nmap ts :scs find s <C-R>=expand("<cword>")<CR><CR>
    nmap tg :scs find g <C-R>=expand("<cword>")<CR><CR>
    nmap tc :scs find c <C-R>=expand("<cword>")<CR><CR>
    nmap tt :scs find t <C-R>=expand("<cword>")<CR><CR>
    nmap te :scs find e <C-R>=expand("<cword>")<CR><CR>
    nmap tf :scs find f <C-R>=expand("<cfile>")<CR><CR>
    nmap ti :scs find i ^<C-R>=expand("<cfile>")<CR>$<CR>
    nmap td :scs find d <C-R>=expand("<cword>")<CR><CR>
    function! UpdateCSCOPE()
        :! cscope -RL -f .git/cscope.out
        :! ectags -Rf .git/tags
    endfunction
endif

nmap  :cnext<CR>
nmap  :cprevious<CR>
nmap  :execute "grep " . expand("<cword>")<CR><CR>

nmap mm :make<CR><CR><CR>
nmap mt :make test<CR><CR><CR>
nmap md :make debug<CR><CR><CR>
nmap em :!vim Makefile<CR><CR>

if executable('ugrep')
    set grepprg=ugrep\ -RInk\ -j\ -u\ --tabs=1\ --ignore-files
    set grepformat=%f:%l:%c:%m,%f+%l+%c+%m,%-G%f\\\|%l\\\|%c\\\|%m
endif

" CUSTOM: # highlights, n searches.
nmap # :let @/ = expand('<cword>')\|set hlsearch<C-M>

" PLUGIN: TAGBAR
nmap <F12> :TagbarToggle<CR>
let g:tagbar_ctags_bin = "ectags"

" PLUGIN: TERMDEBUGGER
let g:termdebugger = "egdb"

" PLUGIN: EASY ALIGN
xmap ga <Plug>(EasyAlign)
nmap ga <Plug>(EasyAlign)

" CUSTOM: AUTO BRACKET
inoremap {<CR> {<CR>  <CR>}<up><right>

" CUSTOM: TREAT C FILES AS C, NOT C++
augroup project
    autocmd!
    autocmd BufRead,BufNewFile *.h,*.c set filetype=c.doxygen
augroup END

" CUSTOM: AUTORELOAD ON VIMRC CHANGE
augroup myvimrc
     au!
     au BufWritePost vimrc so $MYVIMRC
augroup END

augroup myquickfix
        autocmd!
        autocmd QuickFixCmdPost [^l]* cwindow
        autocmd QuickFixCmdPost l*    lwindow
augroup END

augroup cursorpos
autocmd BufReadPost *
     \ if line("'\"") > 0 && line("'\"") <= line("$") |
     \   exe "normal! g`\"" |
     \ endif
augroup END