" ------- PLUGINS -------

" First init : installation des plugins
if empty(glob('~/.vim/autoload/plug.vim'))
  silent !curl -fLo ~/.vim/autoload/plug.vim --create-dirs
    \ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
  autocmd VimEnter * PlugInstall --sync | source $MYVIMRC
endif

" Debut de chargement des plugins
call plug#begin('~/.vim/plugged')

" Verif de la syntaxe du code
Plug 'scrooloose/syntastic'
" Navigateur de fichiers
Plug 'preservim/nerdtree'
" Gestion des sessions
Plug 'mhinz/vim-startify'

" Git plugin with commands 'G<command>'
Plug 'tpope/vim-fugitive'
" Modal git editing with <leader>g
Plug 'jreybert/vimagit'
" Affiche les symboles de modifs git dans la marge
Plug 'airblade/vim-gitgutter'

" Theme
Plug 'drewtempelmeyer/palenight.vim'
" Theme de barre de statut en bas
Plug 'itchyny/lightline.vim'

" Add syntax highlighting for a large range of filetypes
"Plug 'sheerun/vim-polyglot'

call plug#end()




" ------- TRUE COLORS -------

if (has("nvim"))
  let $NVIM_TUI_ENABLE_TRUE_COLOR=1
endif
if (has("termguicolors"))
  set termguicolors
endif




" ------- CONF -------

" Use Vim settings, rather than Vi
set nocompatible

" Encodage
set encoding=UTF-8

" Affiche la barre d'info en bas
set laststatus=2
" Largeur maxi : 0 = desactive
set textwidth=0
" Nombre de cmd dans l'historique
set history=50
" Options du fichier ~/.viminfo
set viminfo='20,\"50
" Active la touche Backspace
set backspace=2
" Garde toujours X ligne(s) visible(s) à l'écran au dessus du curseur
set scrolloff=5
" Affiche les commandes dans la barre de status
set showcmd
" Affiche la paire de parenthèses
set showmatch
" Essaye de garder le curseur dans la même colonne quand on change de ligne
set nostartofline

"find the next match as we type the search
set incsearch
"highlight searches by default
set hlsearch

"set search to be case insensitive
set ignorecase
"unless you typed uppercase letters in your query
set smartcase

"add line numbers
set number

"turn on syntax highlighting
syntax on
filetype plugin on

" Desactive le visualbell
set visualbell t_vb=

" Active la souris
set mouse=a

" Touche <leader>
let mapleader = " "

" Passer d'une ligne a l'autre avec les fleches
set whichwrap=<,>,[,]

" Performances
set hidden
set lazyredraw
set ttyfast




" ------- THEME & PLUGIN: Lightline -------

set background=dark
colorscheme palenight
let g:palenight_terminal_italics=1

" Surligne la ligne en cours
set cursorline
" N'affiche pas le mode en cours en bas, vu qu'il est sur la lightline
set noshowmode

function! LightlineSession()
  if v:this_session != ""
    return '[Session: ' . fnamemodify(v:this_session, ':t') . ']'
  endif
  return '[Session: -]'
endfunction

function! LightlineSpellLanguage()
  if(&spell)
    return "Spell: " . &spelllang
  else
    return "(nospell)"
  endif
endfunction

let g:lightline = {
 \ 'colorscheme': 'wombat',
 \ 'active': {
 \   'left': [ [ 'mode', 'paste' ],
 \             [ 'gitbranch', 'readonly', 'relativepath', 'modified' ],
 \             [ 'vimsession' ] ],
 \ 'right': [ [ 'lineinfo' ],
 \            [ 'percent' ],
 \            [ 'spelllang', 'fileformat', 'fileencoding', 'filetype' ] ] 
 \ },
 \ 'component_function': {
 \   'gitbranch': 'FugitiveHead',
 \   'vimsession': 'LightlineSession',
 \   'spelllang' : 'LightlineSpellLanguage'
 \ },
 \ }

let g:lightline.tabline = {
 \ 'left': [ ['tabs'] ],
 \ 'right': [ ['close'] ]
 \ }

autocmd WinEnter,BufWinEnter,FileType,ColorScheme,SessionLoadPost,BufEnter,TabEnter,InsertEnter * call lightline#update()

set showtabline=2




" ------- INDENTATION -------

set shiftwidth=2
set tabstop=2
set softtabstop=2
set expandtab
filetype indent plugin on

" Desactive l'autoindent le temps d'un copier-coller
set pastetoggle=<F12>

" Change l'indentation
nnoremap <leader><Right> >>
vnoremap <leader><Right> >gv
nnoremap <leader><Left> <<
vnoremap <leader><Left> <gv
vnoremap < <gv
vnoremap > >gv




" ------- FOLDS SETTINGS -------

set foldcolumn=3
set foldmethod=manual
set foldlevelstart=99
autocmd BufWinLeave *.php,*.htm,*.html,*.css,*.c,*.cc,*.h,*.cpp,*.py,*.rb,*.js mkview
autocmd BufWinEnter *.php,*.htm,*.html,*.css,*.c,*.cc,*.h,*.cpp,*.py,*.rb,*.js silent loadview

" Cree un fold du prochain/precedent {, jusqu'au } de fermeture
nmap <C-f> ?{<CR>zf%za:noh<CR>
nmap <leader><Down> /{<CR>zf%za:noh<CR>
nnoremap <leader><Up> ?{<CR>zf%za:noh<CR>
" Toggle le fold en cours
nmap <F8> za
" Ouvre tous les folds
nnoremap <leader><PageDown> zR
" Ferme tous les folds
nnoremap <leader><PageUp> zM




" ------- AUTOCOMPLETION -------

set wildmode=list:full
set wildignore+=*.o,*.obj,*.exe,*.so,*.dll,*.pyc,*.swp,*.jpg,*.png,*.gif,*.pdf,*.bak,.svn,.hg,.bzr,.git,

set omnifunc=syntaxcomplete#Complete
set completeopt=menuone

" Autocompletion avec la touche <TAB>
function! Smart_TabComplete()
  " Current line
  let line = getline('.')
  " Caractere juste avant le curseur
  let charBefore = strpart(line, col('.') -2, 1)


  " PAS DE COMPLETION SI RIEN AVANT
  if(charBefore == " ")
    return "\<tab>"
  endif


  " COMPLETION ET CORRECTION : MODE ORTHOGRAPHE
  if(&spell)
    if( match(charBefore, "[a-zA-Z]") < 0 )
      return "\<tab>"
    else
      " Caractere sous le curseur
      let charCursor = strpart(line, col('.') - 1, 1)
      if charCursor == "" | return "\<C-N>" | endif
      if charCursor == " " | return "\<C-N>" | endif
      return "\<c-o>z="
    endif
  endif


  " COMPLETION : MODE CODE : HTML FERMETURE DE BALISE

  if(charBefore == ">")
    let substr = strpart(line, -1, col('.'))
    let substr = matchstr(substr, "<[^<]*$")
    if(substr == "") | return "\<tab>" | endif
    let substrPos = match(substr, "[ >]")
    let substr = strpart(substr, 1, substrPos - 1)
    if(strpart(line, col('.') - 1, 1) == "") | let substrPos = substrPos - 1 | endif
    return "</" . substr . ">\<c-o>" . (substrPos + 2) . "h"
  endif


  " COMPLETION : MODE CODE : COMPLETION

  " from the start of the current line to one character right of the cursor
  let substr = strpart(line, -1, col('.'))
  " word till cursor:
  let substr = matchstr(substr, "[^ \t]*$")
  " nothing to match on empty string
  if (strlen(substr) == 0)
    return "\<tab>"
  endif

  " position of slash, if any
  let has_slash = match(substr, '\/') != -1
  if (has_slash)
    " file matching
    return "\<C-X>\<C-F>"
  else
    " plugin matching
"TODO:        return "\<C-X>\<C-O>"
    return "\<C-N>"
  endif

endfunction

inoremap <tab> <c-r>=Smart_TabComplete()<CR>




" ------- SPELL -------

" Use word completion when spelling is enabled
set complete+=kspell

"switch spellcheck languages
let g:myLangList=["nospell","fr","en_us"]

function! MySpellLang()
  if !exists("b:myLang")
    if &spell
      let b:myLang=index(g:myLangList, &spelllang)
      if b:myLang < 0 | b:myLang = 0 | endif
    else
      let b:myLang=0
    endif
  endif

  "loop through languages
  let b:myLang = b:myLang + 1
  if b:myLang >= len(g:myLangList) | let b:myLang = 0 | endif
  if b:myLang == 0
    set nospell
  else
    execute "setlocal spell spelllang=".get(g:myLangList, b:myLang)
  endif
endf

map <silent> <F11> :call MySpellLang()<CR>
imap <silent> <F11> <C-o>:call MySpellLang()<CR>



" ------- PLUGIN: NerdTree -------

let NERDTreeQuitOnOpen=1
let NERDTreeShowHidden=1

" Affiche/Cache l'explorateur NerdTree
noremap <leader>e :NERDTreeToggle<CR>




" ------- PLUGIN: Syntastic -------

let g:syntastic_always_populate_loc_list = 1
let g:syntastic_check_on_open = 1
let g:syntastic_check_on_wq = 0

" Infos de syntaxe
nmap <F7> :Errors<CR>




" ------- PLUGIN: GitGutter -------

let g:gitgutter_terminal_reports_focus = 0
let g:gitgutter_async = 0
autocmd BufWritePost * GitGutter




" ------- PLUGIN: Magit -------

map <F6> :Magit<CR>
imap <F6> <Esc>:Magit<CR>




" ------- PLUGIN: Startify (sessions) -------

let g:startify_session_persistence = 1
let g:startify_enable_special = 0
let g:startify_files_number = 10
let g:startify_relative_path = 0
let g:startify_change_to_dir = 1
let g:startify_update_oldfiles = 1
let g:startify_session_autoload = 1
let g:startify_custom_header = 'startify#pad(["         VIM - STARTIFY"] + [""] + ["[e] Empty file"] + ["[q] Quit"] + ["[t] Tag file(s) to be opened in tabs"])'
let g:startify_lists = [
  \ { 'type': 'sessions',  'header': ['   Sessions']       },
  \ { 'type': 'files',     'header': ['   MRU']            },
  \ { 'type': 'dir',       'header': ['   MRU '. getcwd()] },
  \ { 'type': 'bookmarks', 'header': ['   Bookmarks']      },
  \ { 'type': 'commands',  'header': ['   Commands']       },
  \ ]
let g:startify_session_before_save = [
  \ 'echo "Cleaning up before saving.."',
  \ 'silent! NERDTreeTabsClose'
  \ ]

let g:startify_session_dir = $HOME . '/.vim/session'

function! EnsureDirExists (dir)
  if !isdirectory(a:dir)
    call mkdir(a:dir,'p')
  endif
endfunction

function! SessionCreate()
  if empty(v:this_session)
    if tabpagenr("$") > 1
      call EnsureDirExists(g:startify_session_dir)
      SSave!
    endif
  endif
endfunction

" Quitte quand plusieurs onglets sont ouverts, et cree une session si elle n'existe pas
noremap <leader>q :call SessionCreate()<CR>:qa<CR>
" Supprime la session en cours
noremap <leader>d :SDelete!<CR>




" ------- CLAVIER -------

map ; A;<ESC>

" Enregistre tous les onglets en meme temps
noremap <leader>w :wa<CR>

" Commente la ligne courante
autocmd VimEnter *.php,*.js,*.c,*.cc,*.h,*.cpp noremap <leader><leader> 0i//<ESC>
autocmd VimEnter *.sh noremap <leader><leader> 0i#<ESC>

" Clear search highlighting
nnoremap <Esc><Esc> :noh<CR>

" Marqeur
nmap <F9> ma
imap <F9> <C-O>ma
nmap <F10> 'a
nmap <F10> <C-O>'a



" ------- TABS -------

" Ouvre les fichiers sur plusieurs onglets au lieu de plusieurs buffers
"if !&diff | silent tab all | tabfirst | endif

" Creer un nouveau tab et ouvre l'explorateur NerdTree
noremap <leader>t :$tabe<CR>:NERDTreeToggle<CR>
noremap <F3> :$tabe<CR>:NERDTreeToggle<CR>
inoremap <F3> <ESC>:$tabe<CR>:NERDTreeToggle<CR>
" Passer au precedent/suivant tab
noremap <F2> gT
inoremap <F2> <Esc>gT
noremap <F4> gt
inoremap <F4> <Esc>gt
" Deplacer le tab courant vers la gauche/droite
noremap <leader><F2> :tabm -1<CR>
noremap <leader><F4> :tabm +1<CR>