let fancy_symbols_enabled = 1

set termguicolors
set encoding=utf-8
let using_neovim = has('nvim')
let using_vim = !using_neovim

" ============================================================================
" Vim-plug initialization
" Avoid modifying this section, unless you are very sure of what you are doing

let vim_plug_just_installed = 0
if using_neovim
    let vim_plug_path = expand('~/.config/nvim/autoload/plug.vim')
else
    let vim_plug_path = expand('~/.vim/autoload/plug.vim')
endif
if !filereadable(vim_plug_path)
    echo "Installing Vim-plug..."
    echo ""
    if using_neovim
        silent !mkdir -p ~/.config/nvim/autoload
        silent !curl -fLo ~/.config/nvim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
    else
        silent !mkdir -p ~/.vim/autoload
        silent !curl -fLo ~/.vim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
    endif
    let vim_plug_just_installed = 1
endif

" manually load vim-plug the first time
if vim_plug_just_installed
    :execute 'source '.fnameescape(vim_plug_path)
endif

" Obscure hacks done, you can now modify the rest of the config down below 
" as you wish :)
" IMPORTANT: some things in the config are vim or neovim specific. It's easy 
" to spot, they are inside `if using_vim` or `if using_neovim` blocks.

" ============================================================================
" Active plugins
" You can disable or add new ones here:

" this needs to be here, so vim-plug knows we are declaring the plugins we
" want to use
if using_neovim
    call plug#begin("~/.config/nvim/plugged")
else
    call plug#begin("~/.vim/plugged")
endif

" Plug 'preservim/nerdtree'
" Plug 'Xuyuanp/nerdtree-git-plugin'
Plug 'preservim/nerdtree' |
            \ Plug 'Xuyuanp/nerdtree-git-plugin'


Plug 'airblade/vim-gitgutter'
" install the markdown plugin 
Plug 'iamcco/mathjax-support-for-mkdp'
Plug 'iamcco/markdown-preview.vim'

" Install the vim-go

Plug 'https://github.com/fatih/vim-go.git'
" Now the actual plugins:

" Override configs by directory
" Code commenter
Plug 'scrooloose/nerdcommenter'
Plug 'xuhdev/vim-latex-live-preview', { 'for': 'tex' }
Plug 'lervag/vimtex'
" Better file browser
" Plug 'scrooloose/nerdtree'
" Class/module browser
Plug 'majutsushi/tagbar'
" Search results counter
Plug 'vim-scripts/IndexedSearch'
" Airline
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
" Code and files fuzzy finder
Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' }
Plug 'junegunn/fzf.vim'
" Pending tasks list
Plug 'fisadev/FixedTaskList.vim'
" Surround
Plug 'tpope/vim-surround'
" Indent text object
" Plug 'michaeljsmith/vim-indent-object'
" Indentation based movements
Plug 'jeetsukumaran/vim-indentwise'
" Better language packs
" Plug 'sheerun/vim-polyglot'
" Ack code search (requires ack installed in the system)
Plug 'mileszs/ack.vim'
" Paint css colors with the real color
Plug 'lilydjwg/colorizer'
" Window chooser
Plug 't9md/vim-choosewin'
" Automatically sort python imports
" Highlight matching html tags
Plug 'valloric/MatchTagAlways'
" Generate html in a simple way
Plug 'mattn/emmet-vim'
" Git integration
Plug 'tpope/vim-fugitive'
Plug 'ryanoasis/vim-devicons'
Plug 'morhetz/gruvbox'
" for better highlighting
Plug 'nvim-treesitter/nvim-treesitter', {'do': ':TSUpdate'}

"install the tabnine ai autocompleter
Plug 'jiangmiao/auto-pairs'
"Don't open the preview window when ycm working
if using_vim
    " Consoles as buffers (neovim has its own consoles as buffers)
    Plug 'rosenfeld/conque-term'
    " XML/HTML tags navigation (neovim has its own)
    Plug 'vim-scripts/matchit.zip'
endif

" coc autocompletion
Plug 'neoclide/coc.nvim', {'branch': 'release'}
" EasyMOtion plugin
if using_vim
    Plug 'https://github.com/easymotion/vim-easymotion.git'
else
    Plug 'phaazon/hop.nvim'
    " Plug 'justinmk/vim-sneak'
    " map F <Plug>Sneak_S
endif
" best commenter 
Plug 'tpope/vim-commentary'
Plug 'tpope/vim-rails'
Plug 'honza/vim-snippets'
Plug 'alvan/vim-closetag'
Plug 'tomasiser/vim-code-dark'

" Tell vim-plug we finished declaring plugins, so it can load them
call plug#end()

" ============================================================================
" Install plugins the first time vim runs

if vim_plug_just_installed
    echo "Installing Bundles, please ignore key map error messages"
    :PlugInstall
endif

" ============================================================================
" Vim settings and mappings
" You can edit them as you wish
if using_neovim
    " A bunch of things that are set by default in neovim, but not in vim

    " no vi-compatible
    set nocompatible

    " allow plugins by file type (required for plugins!)
    filetype plugin on
    filetype indent on

    " always show status bar
    set ls=2

    " incremental search
    set incsearch
    " highlighted search results



    set hlsearch

    " syntax highlight on
    syntax on

    " better backup, swap and undos storage for vim (nvim has nice ones by
    " default)
    " set directory=~/.vim/dirs/tmp     " directory to place swap files in
    " set backup                        " make backup files
    " set backupdir=~/.vim/dirs/backups " where to put backup files
    set undofile                      " persistent undos - undo after you re-open the file
    " set undodir=~/.vim/dirs/undos
    " set viminfo+=n~/.vim/dirs/viminfo
    " create needed directories if they don't exist
    " if !isdirectory(&backupdir)
    "     call mkdir(&backupdir, "p")
    " endif
    " if !isdirectory(&directory)
    "     call mkdir(&directory, "p")
    " endif
    " if !isdirectory(&undodir)
    "     call mkdir(&undodir, "p")
    " endif
end
 
if using_vim
    " A bunch of things that are set by default in neovim, but not in vim

    " no vi-compatible
    set nocompatible

    " allow plugins by file type (required for plugins!)
    filetype plugin on
    filetype indent on

    " always show status bar
    set ls=2

    " incremental search
    set incsearch
    " highlighted search results



    set hlsearch

    " syntax highlight on
    syntax on

    " better backup, swap and undos storage for vim (nvim has nice ones by
    " default)
    set directory=~/.vim/dirs/tmp     " directory to place swap files in
    set backup                        " make backup files
    set backupdir=~/.vim/dirs/backups " where to put backup files
    set undofile                      " persistent undos - undo after you re-open the file
    set undodir=~/.vim/dirs/undos
    set viminfo+=n~/.vim/dirs/viminfo
    " create needed directories if they don't exist
    if !isdirectory(&backupdir)
        call mkdir(&backupdir, "p")
    endif
    if !isdirectory(&directory)
        call mkdir(&directory, "p")
    endif
    if !isdirectory(&undodir)
        call mkdir(&undodir, "p")
    endif
end

" tabs and spaces handling
set expandtab
set tabstop=4
set softtabstop=4
set shiftwidth=4

" show line numbers
set nu
set rnu
set cursorline
set ignorecase
" remove ugly vertical lines on window division
set fillchars+=vert:\ 

" use 256 colors when possible
if has('gui_running') || using_neovim || (&term =~? 'mlterm\|xterm\|xterm-256\|screen-256')
    if !has('gui_running')
        let &t_Co = 256
    endif
else
endif

" set colorscheme(themes)
" colorscheme gruvbox
" set background=dark    
set t_Co=256
set t_ut=
colorscheme codedark

" Set backgroud to transparent
function! s:set_tranparent()
    autocmd vimenter * hi Normal guibg=NONE ctermbg=NONE " transparent bg
endfunction
" enable the line below if you want to set the backgroud to transparent
" call <SID>set_tranparent()

" This few mappings make sure you can paste mutiple times
nnoremap r d
vnoremap r d

nnoremap <silent> p "+p
vnoremap <silent> p "+p
vnoremap <silent> d "+d
nnoremap <silent> d "+d
vnoremap <silent> y "+y
nnoremap <silent> y "+y
vnoremap <silent> c "+c
nnoremap <silent> c "+c
vnoremap <silent> s "+s
nnoremap <silent> s "+s


nnoremap <silent> P "+P
vnoremap <silent> P "+P
vnoremap <silent> D "+D
nnoremap <silent> D "+D
vnoremap <silent> Y "+Y
nnoremap <silent> Y "+Y
vnoremap <silent> C "+C
nnoremap <silent> C "+C
vnoremap <silent> S "+S
nnoremap <silent> S "+S

" This two line make sure you can ctrl-o to the previous line even you use 10j
" 20k to move
nnoremap <silent> j :<C-u>exe "normal! m'".v:count1."j"<cr>
nnoremap <silent> k :<C-u>exe "normal! m'".v:count1."k"<cr>

"This is a mapping for jump back, for c-o
nnoremap <c-g> <c-i>

" This line makes sure the shape of the cursor looks great
imap <c-c> <esc>
nmap <c-c> <esc>
if has("autocmd")
  au VimEnter,InsertLeave * silent execute '!echo -ne "\e[2 q"' | redraw!
  au InsertEnter,InsertChange *
    \ if v:insertmode == 'i' |
    \   silent execute '!echo -ne "\e[6 q"' | redraw! |
    \ elseif v:insertmode == 'r' |
    \   silent execute '!echo -ne "\e[4 q"' | redraw! |
    \ endif
  au VimLeave * silent execute '!echo -ne "\e[ q"' | redraw!
endif

" general mappings
nmap <c-a> ggVG
map tt :tabnew 
map <c-l> :tabn<CR>
imap <c-l> <ESC>:tabn<CR>
map <c-h> :tabp<CR>
imap <c-h> <ESC>:tabp<CR>
imap <c-s> <ESC>:w<CR>
nnoremap <c-s> :w<CR>
nnoremap <c-c> :q<CR>
nnoremap <C-Left> :bprevious<CR>
nnoremap <C-Right> :bnext<CR>
" commenter mapping
map <C-_> :Commentary<CR>
imap <C-_> <esc>:Commentary<CR>a

" when scrolling, keep cursor 5 lines away from screen border
set scrolloff=5
" Set mouse on
set mouse=a
" clear search results
nnoremap <silent> // :noh<CR>
let g:go_metalinter_command = 'golangci-lint'
" clear empty spaces at the end of lines on save of python files
"autocmd BufWritePre *.py :%s/\s\+$//e

" fix problems with uncommon shells (fish, xonsh) and plugins running commands
" (neomake, ...)
set shell=/bin/zsh


" toggle tagbar display
map <F4> :TagbarToggle<CR>
" autofocus on tagbar open
let g:tagbar_autofocus = 1

" coc config

" Use tab for trigger completion with characters ahead and navigate.
" NOTE: Use command ':verbose imap <tab>' to make sure tab is not mapped by
" other plugin before putting this into your config.

" This two lines make sure you can use underline for errors
let &t_Cs = "\e[4:3m"
let &t_Ce = "\e[4:0m"
hi CocUnderline gui=undercurl term=undercurl
hi CocErrorHighlight ctermfg=red  guifg=#c4384b gui=undercurl term=undercurl
hi CocWarningHighlight ctermfg=yellow guifg=#c4ab39 gui=undercurl term=undercurl


inoremap <silent><expr> <TAB>
      \ pumvisible() ? "\<C-n>" :
      \ <SID>check_back_space() ? "\<TAB>" :
      \ coc#refresh()
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"

function! s:check_back_space() abort
  let col = col('.') - 1
  return !col || getline('.')[col - 1]  =~# '\s'
endfunction

" Use <c-space> to trigger completion.
if has('nvim')
  inoremap <silent><expr> <c-space> coc#refresh()
else
  inoremap <silent><expr> <c-@> coc#refresh()
endif

" Make <CR> auto-select the first completion item and notify coc.nvim to
" format on enter, <cr> could be remapped by other vim plugin
inoremap <silent><expr> <cr> pumvisible() ? coc#_select_confirm()
                              \: "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"

" Use `[g` and `]g` to navigate diagnostics
" Use `:CocDiagnostics` to get all diagnostics of current buffer in location list.
nmap <silent> [g <Plug>(coc-diagnostic-prev)
nmap <silent> ]g <Plug>(coc-diagnostic-next)

" GoTo code navigation.
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)
" this line is to show documentation in preview float window
" let g:go_doc_popup_window = 1
let g:go_doc_keywordprg_enabled = 0
let g:coc_disable_transparent_cursor = 1

" Use K to show documentation in preview window.
nnoremap <silent> K :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

autocmd CursorHold * silent call CocActionAsync('highlight')

xmap <leader>f  <Plug>(coc-format-selected)
nmap <leader>f  <Plug>(coc-format-selected)
nmap <leader>af  <c-a><Plug>(coc-format-selected)<c-o><c-o>

" easymotion plugin setting

" ====================================
" <Leader>f{char} to move to {char}
" map  <Leader>f <Plug>(easymotion-bd-f)

" this two lines prevent easymotion to interrupt the coc-diagnostic
if using_vim
    nmap <Leader>f <Plug>(easymotion-overwin-f)

    " s{char}{char} to move to {char}{char}
    nmap s <Plug>(easymotion-overwin-f2)

    " Move to line
    " map <Leader>L <Plug>(easymotion-bd-jk)
    nmap <Leader>L <Plug>(easymotion-overwin-line)

    " Move to word
    map  <Leader>w <Plug>(easymotion-bd-w)
    " nmap <Leader>w <Plug>(easymotion-overwin-w)

    autocmd User EasyMotionPromptBegin silent! CocDisable
    autocmd User EasyMotionPromptEnd silent! CocEnable
    let g:easymotion#is_active = 0
    function! EasyMotionCoc() abort
      if EasyMotion#is_active()
        let g:easymotion#is_active = 1
        CocDisable
      else
        if g:easymotion#is_active == 1
          let g:easymotion#is_active = 0
          CocEnable
        endif
      endif
    endfunction
    autocmd TextChanged,CursorMoved * call EasyMotionCoc()
else
    nmap <Leader>w :HopWord<CR>
    nmap f :HopChar2<CR>
endif
nmap <c-e> :CocDiagnostics<CR>
" nmap ln <Plug>(coc-openlink)

" Rezie the window
map <c-k> :vertical resize  +5<CR>
imap <c-k> <ESC>:vertical resize  +5<CR>i
map <c-j> :vertical resize  -5<CR>
imap <c-j> <ESC>:vertical resize  -5<CR>i

" NERDTree -----------------------------

" toggle nerdtree display
let g:NERDTreeWinSize=20
map <F3> :NERDTreeToggle<CR>
" open nerdtree with the current file selected
nmap ,t :NERDTreeFind<CR>
" don;t show these file types
let NERDTreeIgnore = ['\.pyc$', '\.pyo$']

" Enable folder icons
let g:WebDevIconsUnicodeDecorateFolderNodes = 1
let g:DevIconsEnableFoldersOpenClose = 1

" Fix directory colors
highlight! link NERDTreeFlags NERDTreeDir

" Remove expandable arrow
let g:WebDevIconsNerdTreeBeforeGlyphPadding = ""
let g:WebDevIconsUnicodeDecorateFolderNodes = v:true
let NERDTreeDirArrowExpandable = "\u00a0"
let NERDTreeDirArrowCollapsible = "\u00a0"
let NERDTreeNodeDelimiter = "\x07"

" Autorefresh on tree focus
function! NERDTreeRefresh()
    if &filetype == "nerdtree"
        silent exe substitute(mapcheck("R"), "<CR>", "", "")
    endif
endfunction

autocmd BufEnter * call NERDTreeRefresh()

" Tasklist ------------------------------

" show pending tasks list
map <F2> :TaskList<CR>

" closetag config
let g:closetag_filenames = '*.html,*.xhtml,*.phtml,*.erb'

" set completeopt-=preview
" Fzf ------------------------------

" file finder mapping
nmap <c-p> :Files<CR>
" tags (symbols) in current file finder mapping
nmap ,g :BTag<CR>
" the same, but with the word under the cursor pre filled
nmap ,wg :execute ":BTag " . expand('<cword>')<CR>
" tags (symbols) in all files finder mapping
nmap ,G :Tags<CR>
" the same, but with the word under the cursor pre filled
nmap ,wG :execute ":Tags " . expand('<cword>')<CR>
" general code finder in current file mapping
nmap ,f :BLines<CR>
" the same, but with the word under the cursor pre filled
nmap ,wf :execute ":BLines " . expand('<cword>')<CR>
" general code finder in all files mapping
nmap ,F :Lines<CR>
" the same, but with the word under the cursor pre filled
nmap ,wF :execute ":Lines " . expand('<cword>')<CR>
" commands finder mapping
nmap ,c :Commands<CR>

" Ack.vim ------------------------------

" mappings
nmap <c-f> :Ack -i
nmap ,wr :execute ":Ack " . expand('<cword>')<CR>

" Window Chooser ------------------------------

" mapping
nmap  -  <Plug>(choosewin)
" show big letters
let g:choosewin_overlay_enable = 1

" " Signify ------------------------------

" " this first setting decides in which order try to guess your current vcs
" " UPDATE it to reflect your preferences, it will speed up opening files
" let g:signify_vcs_list = ['git', 'hg']
" " mappings to jump to changed blocks
" nmap <leader>sn <plug>(signify-next-hunk)
" nmap <leader>sp <plug>(signify-prev-hunk)
" " nicer colors
" highlight DiffAdd           cterm=bold ctermbg=none ctermfg=119
" highlight DiffDelete        cterm=bold ctermbg=none ctermfg=167
" highlight DiffChange        cterm=bold ctermbg=none ctermfg=227
" highlight SignifySignAdd    cterm=bold ctermbg=237  ctermfg=119
" highlight SignifySignDelete cterm=bold ctermbg=237  ctermfg=167
" highlight SignifySignChange cterm=bold ctermbg=237  ctermfg=227

" Autoclose ------------------------------

" Fix to let ESC work as espected with Autoclose plugin
" (without this, when showing an autocompletion window, ESC won't leave insert
"  mode)
"let g:AutoClosePumvisible = {"ENTER": "\<C-Y>", "ESC": "\<ESC>"}


" Airline ------------------------------

let g:airline_powerline_fonts = 1
" let g:airline_theme = 'bubblegum'
" This is for vscode-style 
let g:airline_theme = 'codedark'
let g:airline#extensions#whitespace#enabled = 0
let g:airline#extensions#tabline#enabled = 1

" Fancy Symbols!!

if fancy_symbols_enabled
    let g:webdevicons_enable = 1

    " custom airline symbols
    if !exists('g:airline_symbols')
       let g:airline_symbols = {}
    endif
   " let g:airline_left_sep = ''
   " let g:airline_left_alt_sep = ''
   " let g:airline_right_sep = ''
   " let g:airline_right_alt_sep = ''
   " let g:airline_symbols.branch = '⭠'
   " let g:airline_symbols.readonly = '⭤'
   " let g:airline_symbols.linenr = '⭡'
else
    let g:webdevicons_enable = 0
endif

" this line make sure gdiffsplit show eveything vertically
set diffopt+=vertical
" Custom configurations ----------------

" Include user's custom nvim configurations
if using_neovim
    let custom_configs_path = "~/.config/nvim/custom.vim"
else
    let custom_configs_path = "~/.vim/custom.vim"
endif
if filereadable(expand(custom_configs_path))
  execute "source " . custom_configs_path
endif
