"==============================================================================
"                               vim-plug
"==============================================================================

" plugins list
 call plug#begin('~/.vim/plugged')
    Plug 'sheerun/vim-polyglot'                                              " A ton of language syntax
    Plug 'iamcco/markdown-preview.nvim', { 'do': 'cd app && yarn install'  } " Markdown Preview
    Plug 'pearofducks/ansible-vim'                                           " Ansible support
	Plug 'morhetz/gruvbox'                                                   " Gruvbox theme
    Plug 'chriskempson/base16-vim'                                           " Base 16 Themes - https://github.com/chriskempson/base16-vim
    Plug 'sickill/vim-monokai'                                               " Monokai Theme
    Plug 'arcticicestudio/nord-vim'                                          " Nord theme
    Plug 'itchyny/lightline.vim'                                             " vim status bar
    Plug 'danilamihailov/beacon.nvim'                                        " see cursor jumps easier
    Plug 'shinchu/lightline-gruvbox.vim'                                     " Gruvbox theme for status line
    Plug 'lewis6991/gitsigns.nvim'                                           " Git gutter and sings
    Plug 'zivyangll/git-blame.vim'                                           " Git blame
    Plug 'lilydjwg/colorizer'                                                " Displays the colors in file
    Plug 'jiangmiao/auto-pairs'                                              " Auto create bracket/parens/quote pairs
    Plug 'vim-syntastic/syntastic'                                           " coding-errors checker
    Plug 'puremourning/vimspector'                                           " Multi lang Debugger
    Plug 'neoclide/coc.nvim', {'branch': 'release'}                          " Lanuage server integrations
    Plug 'tpope/vim-fugitive'                                                " git wrapper
    Plug 'fatih/vim-go', { 'do': ':GoUpdateBinaries' }                       " golang plugin for vim
    Plug 'Yggdroot/indentLine'                                               " Indentation LInes
    Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }                      " Install fzf
    Plug 'junegunn/fzf.vim'                                                  " Fuzzy search
    Plug 'francoiscabrol/ranger.vim'                                         " Ranger <leader>f
    Plug 'kyazdani42/nvim-web-devicons'                                      " for file icons
    Plug 'kyazdani42/nvim-tree.lua'                                          " File tree/browser
 call plug#end()

" Eliminate delay for esc insert->normal
set timeoutlen=1000 ttimeoutlen=0
" Set encoding to utf8
set encoding=UTF-8
" Set no compatible
set nocompatible
" File type plugin on
filetype plugin on
" Turn on syntax
syntax on
" install plugins automatically
autocmd VimEnter *
  \  if len(filter(values(g:plugs), '!isdirectory(v:val.dir)'))
  \|   PlugInstall --sync | q
  \| endif

" remove unused plugins automatically
autocmd VimEnter *
  \  if len(filter(split(globpath(g:plug_home, '*'), "\n"), 'isdirectory(v:val)'))
  \ > len(filter(values(g:plugs), 'stridx(v:val.dir, g:plug_home) == 0'))
  \|   PlugClean | q
  \| endif
" Initiate lua
lua require('gitsigns').setup()
" Init NvimTree
lua require'nvim-tree'.setup {}
" Toggle NerdTree with Ctrl+n
nnoremap <C-n> :NvimTreeToggle<CR>
nnoremap <leader>r :NvimTreeRefresh<CR>
nnoremap <leader>n :NvimTreeFindFile<CR>
" Open fzf Files search Ctrl+p
map <C-p> :Files<CR>
" Open file search Ctrl+f
map <C-f> :BLines<CR>
" Open Global search Ctrl+s
map <C-s> :Ag<CR>
" Indent Guides auto start
let g:indent_guides_enable_on_vim_startup = 1

" Toggle git blame <leader>s in normal mode
nnoremap <Leader>s :<C-u>call gitblame#echo()<CR>

" Tab navigation and creation
map <C-t> :tabnew<CR>
noremap <Tab><Tab> :tabn<CR>

" Insert mode navigation Alt+hjkl
imap <M-h> <Left>
imap <M-l> <Right>
imap <M-j> <Down>
imap <M-k> <Up>

" Set line heighlight on by default
set cursorline
" Copy to clipboard
vnoremap  <leader>y  "+y
nnoremap  <leader>Y  "+yg_
nnoremap  <leader>y  "+y
nnoremap  <leader>yy  "+yy

" Paste from clipboard
nnoremap <leader>p "+p
nnoremap <leader>P "+P
vnoremap <leader>p "+p
vnoremap <leader>P "+P
" Enable mouse use in all modes
set mouse=a
" Auto highlight similar words when staying on a word after .5 sec
set updatetime=500
augroup highlight_current_word
  au!
  au CursorHold *
    \ if ( expand("%") != 'NvimTree_1' )
       \ | :silent! :exec 'match Search /\V\<' . expand('<cword>') . '\>/'
    \ | endif
augroup END


"==============================================================================
"                          Beacon settings
"==============================================================================
let g:beacon_minimal_jump = 1
"==============================================================================
"                          Sync NERDTree with file
"==============================================================================
" Check if NERDTree is open or active
function! IsNERDTreeOpen()
  return exists("t:NERDTreeBufName") && (bufwinnr(t:NERDTreeBufName) != -1)
endfunction

" Call NERDTreeFind iff NERDTree is active, current window contains a modifiable
" file, and we're not in vimdiff
function! SyncTree()
  if &modifiable && IsNERDTreeOpen() && strlen(expand('%')) > 0 && !&diff
    NERDTreeFind
    wincmd p
  endif
endfunction

" Highlight currently open buffer in NERDTree
autocmd BufRead * call SyncTree()

" Nerdtree show hidden files
let NERDTreeShowHidden=1
" Dont show .git folder
let NERDTreeIgnore=['\.git$']

"==============================================================================
"                          Theme settings
"==============================================================================

let &t_8f = "\<Esc>[38;2;%lu;%lu;%lum"
let &t_8b = "\<Esc>[48;2;%lu;%lu;%lum"
set termguicolors
" Theme
colorscheme gruvbox
" Setting dark mode
" set background=dark

"==============================================================================
"                               line number
"==============================================================================

" turn hybrid line numbers on
:set number relativenumber
:set nu rnu

:augroup numbertoggle
:  autocmd!
:  autocmd BufEnter,FocusGained,InsertLeave,WinEnter * if &nu && mode() != "i" | set rnu   | endif
:  autocmd BufLeave,FocusLost,InsertEnter,WinLeave   * if &nu                  | set nornu | endif
:augroup END

" Set current line number more visible
" hi clear CursorLine
augroup CLClear
    autocmd! ColorScheme * hi clear CursorLine
augroup END 


" open files at the last remember line
if has("autocmd")
      au BufReadPost *
            \ if line("'\"") > 0 && line("'\"") <= line("$")
            \|    exe "normal! g`\""
            \| endif
endif

"==============================================================================
"                              TAB settings
"==============================================================================

"filetype plugin indent on

" show existing tab with 4 spaces width
set tabstop=4

" when indenting with '>', use 4 spaces width
set shiftwidth=4

" On pressing tab, insert 4 spaces
set expandtab


"==============================================================================
"                               set column
"==============================================================================

" set coding style limit at 80 chars
set colorcolumn=80

"==============================================================================
"                            mouse settings
"==============================================================================

" enable mouse
set mouse=a

"==============================================================================
"                              file title
"==============================================================================

" always show current file title
set title


"==============================================================================
"                           normal mode mapping
"==============================================================================

" mapping capsLock to ctrl
map CapsLock Ctrl


" this package is extending % to <> and other sifferent closures
packadd! matchit
:let b:match_words = '<:>,<tag>:</tag>'

" enable ci( of all sorts to work from outside the parenthese
nnoremap ci( %ci(
nnoremap ci[ %ci[
nnoremap ci{ %ci{
" NOTE: use 'normal' for <> because % is not a regular vim command (package)
nnoremap ci< :normal %<CR>ci<

" enable di( of all sorts to work from outside the parenthese
nnoremap di( %di(
nnoremap di[ %di[
nnoremap di{ %di{
" NOTE: use 'normal' for <> because % is not a regular vim command (package)
nnoremap di< :normal %<CR>di<

" easy navigation on split screen
nnoremap <C-J> <C-W><C-J>
nnoremap <C-K> <C-W><C-K>
nnoremap <C-L> <C-W><C-L>
nnoremap <C-H> <C-W><C-H>

" easy access to buffers
" \l       : list buffers
" \b \f \g : go back/forward/last-used
" \d       : delete buffer
nnoremap <Leader>l :ls<CR>
nnoremap <Leader>b :bp<CR>
nnoremap <Leader>f :bn<CR>
nnoremap <Leader>g :e#<CR>
nnoremap <Leader>c :bd<CR>

" make 'Y' act like 'D' and 'C' instead of working like 'yy'
nnoremap Y y$

"==============================================================================
"                            search settings
"==============================================================================

" ignore CASE in search
set ignorecase

" higlight search matches
set hlsearch

"==============================================================================
"                                vim && tmux 
"==============================================================================

" makes split-navigation act differently when in vim\tmux
" in both cases navigation will be done with ctr + hjkl (without tmux prefix)
if exists('$TMUX')
    function! TmuxOrSplitSwitch(wincmd, tmuxdir)
        let previous_winnr = winnr()
        silent! execute "wincmd " . a:wincmd
        if previous_winnr == winnr()
            call system("tmux select-pane -" . a:tmuxdir)
            redraw!
        endif
    endfunction
                                            
    let previous_title = substitute(system("tmux display-message -p '#{pane_title}'"), '\n', '', '')
    let &t_ti = "\<Esc>]2;vim\<Esc>\\" . &t_ti
    let &t_te = "\<Esc>]2;". previous_title . "\<Esc>\\" . &t_te
                                                  
    nnoremap <silent> <C-h> :call TmuxOrSplitSwitch('h', 'L')<cr>
    nnoremap <silent> <C-j> :call TmuxOrSplitSwitch('j', 'D')<cr>
    nnoremap <silent> <C-k> :call TmuxOrSplitSwitch('k', 'U')<cr>
    nnoremap <silent> <C-l> :call TmuxOrSplitSwitch('l', 'R')<cr>
else
    map <C-h> <C-w>h
    map <C-j> <C-w>j
    map <C-k> <C-w>k
    map <C-l> <C-w>l
endif



"==============================================================================
"                             split settings
"==============================================================================
"
" more intuitive default splits
 set splitbelow
 set splitright

"==============================================================================
"                    Lightline.vim plugin & status line
"==============================================================================

" make status line always visible
set laststatus=2

" NOTE: 'FugitiveHead' is 'vim-fugitive' plugin's function and depend on it
" configure lightline.vim status line
let g:lightline = {
      \ 'active': {
      \   'left': [ [ 'mode', 'paste' ],
      \             [ 'gitbranch', 'readonly', 'filename', 'modified' ] ]
      \ },
      \ 'component_function': {
      \   'gitbranch': 'FugitiveHead',
      \   'filename': 'LightlineFilename',
      \ },
      \ }
" lightline colorscheme
" let g:lightline.colorscheme = 'gruvbox'
" function to get the filename from vim to lightline.vim
function! LightlineFilename()
      return &filetype ==# 'vimfiler' ? vimfiler#get_status_string() :
              \ &filetype ==# 'unite' ? unite#get_status_string() :
              \ &filetype ==# 'vimshell' ? vimshell#get_status_string() :
              \ expand('%') !=# '' ? expand('%') : '[No Name]'
endfunction

let g:unite_force_overwrite_statusline = 0
let g:vimfiler_force_overwrite_statusline = 0
let g:vimshell_force_overwrite_statusline = 0

" actually this have no effect when lightline.vim plugin is installed
set statusline+=%f      "relative path (use %F for absolute path)
set statusline+=%m      "modified flag
set statusline+=%=      "left/right separator
set statusline+=%l/%L   "cursor line/total lines
set statusline+=\ %P    "percent through file

"==============================================================================
"                            Spelling settings
"==============================================================================

" make spell checker underline errors with vim 'set spell' command
" Note: must appear after the last line that is altering colorscheme
hi clear SpellBad
hi SpellBad cterm=underline
set spell

"==============================================================================
"                              Delete settings
"==============================================================================

" make backspace always erase in insert mode and not only new inputs
set backspace=indent,eol,start

"==============================================================================
"                              Fold settings
"==============================================================================

set foldmethod=marker


"==============================================================================
"                                 swp files
"==============================================================================

" Don't use swapfile
set noswapfile



"==============================================================================
"                                 Coc Key mapping
"==============================================================================
"" Use <c-space> to trigger completion.
if has('nvim')
  inoremap <silent><expr> <c-space> coc#refresh()
else
  inoremap <silent><expr> <c-@> coc#refresh()
endif
" Symbol renaming.
nmap <F2> <Plug>(coc-rename)
" Hit tab go see documentation
nmap <Tab> :silent call <SID>show_documentation()<CR>
function! s:show_documentation()
  if (index(['vim','help'], &filetype) >= 0)
    execute 'h '.expand('<cword>')
  elseif (coc#rpc#ready())
    call CocActionAsync('doHover')
  else
    execute '!' . &keywordprg . " " . expand('<cword>')
  endif
endfunction
