set encoding=utf-8


set nocompatible              " be iMproved, required


"vim-plug installation (auto installs on new machines)

if empty(glob('~/.vim/autoload/plug.vim'))
  silent !curl -fLo ~/.vim/autoload/plug.vim --create-dirs
    \ https://git.burschel.com/sebastian/kabelkiste/raw/branch/master/dotfiles/.vim/autoload/plug.vim
  autocmd VimEnter * PlugInstall --sync | source $MYVIMRC
endif


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


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

" Java autocomplete
" Plug 'artur-shaik/vim-javacomplete2'

" Generates a list of todo comments
Plug 'chauncey-garrett/vim-tasklist'

" Autocompletion for everything
Plug 'neoclide/coc.nvim', {'branch': 'release'}

" Fuzzy file finder
Plug 'ctrlpvim/ctrlp.vim'

" Zooms into windows (fullscreen toggle)
Plug 'szw/vim-maximizer'

" Linter and analyse tool
Plug 'dense-analysis/ale'

" Forces <Tab> to do what I want (autocomplete etc.)
Plug 'ervandew/supertab'

" Adds the closing equivalent of everything that opens: ""[]()....
Plug 'jiangmiao/auto-pairs'

" Git commit browser
Plug 'junegunn/gv.vim'

" When pressing " or @, it shows a popup with the register content.
Plug 'junegunn/vim-peekaboo'

" The package manager itself.
Plug 'junegunn/vim-plug'

" Shows the color in css files
Plug 'ap/vim-css-color'

" Add swift support
Plug 'keith/swift.vim'

" Latex, I guess? Have to check if I actually need this.
Plug 'LaTeX-Box-Team/LaTeX-Box'

" I use it as my snippet manager, but it is actually for HTML.
Plug 'mattn/emmet-vim'

" Necessary to use my emmet json snippet file
Plug 'mattn/webapi-vim'

" vue support
Plug 'posva/vim-vue'

" Makes (un)commenting stuff much easier.
Plug 'preservim/nerdcommenter'

" My dark theme
Plug 'SeBaBu/darcula'

" My light theme.
Plug 'NLKNguyen/papercolor-theme'

" File browser
Plug 'scrooloose/nerdtree'

" Language pack for most languages I use.
Plug 'sheerun/vim-polyglot'

" Git support for vim
Plug 'tpope/vim-fugitive'

" Change surrounding stuff fast and reliable
Plug 'tpope/vim-surround'

" Status line for the bottom of the screen (and a themes pack)
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'

" Shows vertical lines to make indents more visible
Plug 'Yggdroot/indentLine'

" Better Javascript indent and syntax support
Plug 'pangloss/vim-javascript'

call plug#end()


" Leader
let mapleader = ","

set backspace=2   " Backspace deletes like most programs in insert mode
set nobackup
set nowritebackup
set noswapfile    " http://robots.thoughtbot.com/post/18739402579/global-gitignore#comment-458413287
set history=200
set ruler         " show the cursor position all the time
set showcmd       " display incomplete commands
set incsearch     " do incremental searching
set laststatus=2  " Always display the status line
set autowrite     " Automatically :write before running commands
set modelines=0   " Disable modelines as a security precaution
set nomodeline
set cursorline    " Highlight the full line the cursor is in


" Switch syntax highlighting on, when the terminal has colors
" Also switch on highlighting the last used search pattern.
if (&t_Co > 2 || has("gui_running")) && !exists("syntax_on")
  syntax on
endif

" Higher redrawtime or syntax highlighting can fail.
set redrawtime=10000

if filereadable(expand("~/.vimrc.bundles"))
  source ~/.vimrc.bundles
endif

" Load matchit.vim, but only if the user hasn't installed a newer version.
if !exists('g:loaded_matchit') && findfile('plugin/matchit.vim', &rtp) ==# ''
  runtime! macros/matchit.vim
endif


augroup vimrcEx
  autocmd!

"  " When editing a file, always jump to the last known cursor position.
"  " Don't do it for commit messages, when the position is invalid, or when
"  " inside an event handler (happens when dropping a file on gvim).
  autocmd BufReadPost *
    \ if &ft != 'gitcommit' && line("'\"") > 0 && line("'\"") <= line("$") |
    \   exe "normal g`\"" |
    \ endif

  " Set syntax highlighting for specific file types
  autocmd BufRead,BufNewFile *.md set filetype=markdown
  autocmd BufRead,BufNewFile .{jscs,jshint,eslint}rc set filetype=json
  autocmd BufRead,BufNewFile aliases.local,zshrc.local,*/zsh/configs/* set filetype=sh
  autocmd BufRead,BufNewFile gitconfig.local set filetype=gitconfig
  autocmd BufRead,BufNewFile tmux.conf.local set filetype=tmux
  autocmd BufRead,BufNewFile vimrc.local set filetype=vim
augroup END


" When the type of shell script is /bin/sh, assume a POSIX-compatible
" shell for syntax highlighting purposes.
"let g:is_posix = 1

" Softtabs, 4 spaces
set tabstop=4
set shiftwidth=4
set shiftround          " Tabs are rounded to multiples of shiftwidth
set expandtab           " Tabs are spaces

" Display extra whitespace
set list listchars=tab:»·,trail:·,nbsp:·

" Use one space, not two, after punctuation.
set nojoinspaces

" Make it obvious where 80 characters is (Python only)
autocmd FileType python setlocal colorcolumn=81

" Highlight "self." in different color in python files:
augroup python_syntax_extra
  autocmd!
  autocmd! Syntax python :syn keyword Keyword self
augroup END

" Line numbers with the width of 5 digits
set number
set numberwidth=5

" Relative line numbers, but real line number for current line
set number relativenumber
set nu rnu

" Autocomplete menu for command mode
set wildmenu
set wildmode=longest:full,full

" Open new split panes to right and bottom, which feels more natural
set splitbelow
set splitright

" Quicker window movement
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-h> <C-w>h
nnoremap <C-l> <C-w>l

" Autocomplete with dictionary words when spell check is on
set complete+=kspell

"Autocompletion syntax:
set omnifunc=syntaxcomplete#Complete

" Keep 8 rows above and below the kk
set scrolloff=8

" Jump to wrapped line instead of next real line.
nnoremap j gj
nnoremap k gk

" Use e and E to jump to start or end of a line.
nnoremap e ^
nnoremap E $

" Do not cut words when breaking lines.
set linebreak

" Searching with "/": Ignore case if search term is lower case.
set ignorecase
set smartcase
set hlsearch

" Stop highlighting search results.
nnoremap <leader><space> :nohlsearch<CR>

" Search replace bind:
nnoremap S :%s//g<Left><Left>

" Strip trailing whitespaces on each save
fun! <SID>StripTrailingWhitespaces()
    let l = line(".")
    let c = col(".")
    %s/\s\+$//e
    call cursor(l, c)
endfun
autocmd BufWritePre * :call <SID>StripTrailingWhitespaces()

" Indent and unindent with tab.
nnoremap <Tab> >>_
nnoremap <S-Tab> <<_
inoremap <S-Tab> <C-D>
vnoremap <Tab> >gv
vnoremap <S-Tab> <gv

" Remap buffer navigation:
map gn :bn<cr>
map gN :bp<cr>
map gp :bp<cr>


" Toggle through splits:
nnoremap <leader>w <C-w>w
nnoremap <leader>W <C-w>W

" Emmet
let g:user_emmet_leader_key=','
let g:user_emmet_settings = webapi#json#decode(join(readfile(expand('~/.vim/customizations/vim-emmet-mysnippets.json')), "\n"))

" jedi-vim:
"let g:jedi#popup_on_dot = 1

" Peekaboo window width
let g:peekaboo_window = 'vert bo 65new'

" javacomplete2
autocmd FileType java setlocal omnifunc=javacomplete#Complete

" tasklist settings
let g:tlTokenList = ["FIXME", "TODO", "todo"] " keywords for todos
let g:tlWindowPosition = 1 "Open window on bottom, 0 would be top
let g:tlRememberPosition = 1
map <leader>t <Plug>TaskList

" nerdtree settings
map <C-n> :NERDTreeToggle<CR>
let NERDTreeIgnore=["\.git$"]

" nerdcommenter settins
let g:NERDCompactSexyComs = 1
" Comment symbols are in a straight line and not mimicing the indents of the code
let g:NERDDefaultAlign = "left"
" Add a space between the comment symbol(s) and the code
let NERDSpaceDelims=1

" supertab settings
" On autocomplete, start cycling from top to bottom
let g:SuperTabDefaultCompletionType = "<c-n>"

" airline settings
let g:airline#extensions#tabline#enabled = 1 " Show buffers as tabs

" ale settings
let g:ale_linters = {'python': ['flake8', 'mypy', 'pylint', 'prospector']}
let g:ale_fixers = {'python': ['isort', 'black'],
                   \'json': ['fixjson'],
                   \'html': ['html-beautify', 'tidy'],
                   \'htmldjango': ['html-beautify'],
                   \'xml': ['xmllint'],
                   \'java': ['uncrustify'],
                   \'javascript': ['eslint', 'prettier', 'xo', 'standard'],
                   \'tex': ['latexindent']}



" Run ALEFix shortcut
nnoremap <leader>f :ALEFix<CR>

" Markdown spellchecking
" autocmd FileType markdown setlocal spell spelllang=de " not working yet


" colorscheme toggle dark/light:
function! s:SwitchColorscheme()
    if g:colors_name == 'darcula'
        set background=light
        colorscheme PaperColor
        AirlineTheme papercolor
    else
        colorscheme darcula
        set background=dark
        AirlineTheme dark
    endif
endfunction
map <silent> <F4> :call <SID>SwitchColorscheme()<CR>

colorscheme darcula

" Highlight whole todo comment, not just the keyword itself:
augroup myTodo
  autocmd!
  autocmd Syntax * syntax match myTodo /\v\_.<(TODO|FIXME|todo|fixme).*/hs=s+1 containedin=.*Comment
augroup END

highlight link myTodo Todo

" Bind ctrl+u to jump list jump (opposite of ctrl+o)
nnoremap <C-u> <C-i>

" Bind ctrl-s to quicksave!
noremap <silent> <C-S>          :update<CR>
vnoremap <silent> <C-S>         <C-C>:update<CR>
inoremap <silent> <C-S>         <C-O>:update<CR>

" Load changes to a file automatically from drive if the file has not been
" changed yet
set autoread

" Generate help tags to find the docs with :help
"if !empty((globpath(&rtp, '~/.vim/doc/**'))
"    helptags ~/.vim/doc
"endif

" Use persistent history. (so undo from older sessions can be used)
if !isdirectory("$HOME/.vim/.vim-undo-dir")
    silent !mkdir -p $HOME/.vim/.vim-undo-dir
endif
set undodir=$HOME/.vim/.vim-undo-dir
set undofile

" Set the character which is used as tab indent marker
let g:indentLine_char = '┊'

" CoC install the language extensions I want:
let g:coc_global_extensions = [
            \"coc-json",
            \"coc-git",
            \"coc-tsserver",
            \"coc-html",
            \"coc-css",
            \"coc-htmldjango",
            \"coc-jedi",
            \"coc-vetur"]

" Toggle zoom into windows with vim-maximizer
nnoremap <leader>z :MaximizerToggle<CR>


" In split views, delete a buffer but keep the window layout.
" Found it here: https://vim.fandom.com/wiki/Deleting_a_buffer_without_closing_the_window
"delete the buffer; keep windows; create a scratch buffer if no buffers left
function s:Kwbd(kwbdStage)
  if(a:kwbdStage == 1)
    if(&modified)
      let answer = confirm("This buffer has been modified.  Are you sure you want to delete it?", "&Yes\n&No", 2)
      if(answer != 1)
        return
      endif
    endif
    if(!buflisted(winbufnr(0)))
      bd!
      return
    endif
    let s:kwbdBufNum = bufnr("%")
    let s:kwbdWinNum = winnr()
    windo call s:Kwbd(2)
    execute s:kwbdWinNum . 'wincmd w'
    let s:buflistedLeft = 0
    let s:bufFinalJump = 0
    let l:nBufs = bufnr("$")
    let l:i = 1
    while(l:i <= l:nBufs)
      if(l:i != s:kwbdBufNum)
        if(buflisted(l:i))
          let s:buflistedLeft = s:buflistedLeft + 1
        else
          if(bufexists(l:i) && !strlen(bufname(l:i)) && !s:bufFinalJump)
            let s:bufFinalJump = l:i
          endif
        endif
      endif
      let l:i = l:i + 1
    endwhile
    if(!s:buflistedLeft)
      if(s:bufFinalJump)
        windo if(buflisted(winbufnr(0))) | execute "b! " . s:bufFinalJump | endif
      else
        enew
        let l:newBuf = bufnr("%")
        windo if(buflisted(winbufnr(0))) | execute "b! " . l:newBuf | endif
      endif
      execute s:kwbdWinNum . 'wincmd w'
    endif
    if(buflisted(s:kwbdBufNum) || s:kwbdBufNum == bufnr("%"))
      execute "bd! " . s:kwbdBufNum
    endif
    if(!s:buflistedLeft)
      set buflisted
      set bufhidden=delete
      set buftype=
      setlocal noswapfile
    endif
  else
    if(bufnr("%") == s:kwbdBufNum)
      let prevbufvar = bufnr("#")
      if(prevbufvar > 0 && buflisted(prevbufvar) && prevbufvar != s:kwbdBufNum)
        b #
      else
        bn
      endif
    endif
  endif
endfunction

command! Kwbd call s:Kwbd(1)
nnoremap <silent> <Plug>Kwbd :<C-u>Kwbd<CR>

" Create a mapping (e.g. in your .vimrc) like this:
"nmap <C-W>! <Plug>Kwbd
nmap <leader>bd <Plug>Kwbd



nmap <silent> ga <Plug>(coc-codeaction-line)

" Go to definition
nmap <silent> <leader>g <Plug>(coc-definition)
" nmap <silent> gy <Plug>(coc-type-definition)
" nmap <silent> gi <Plug>(coc-implementation)
" nmap <silent> gr <Plug>(coc-references)

" Load local config if there is one
if filereadable($HOME . "/.vimrc.local")
  source ~/.vimrc.local
endif


