﻿"############################################################################################################
" MISCELLANEOUS
"############################################################################################################

" Define leader char (use µ instead of backslash)
" let mapleader="µ"

" Disable the gui menu because it interferes with my mappings (<A-p>...)
set guioptions-=m

" Allow buffers to be hidden even if there are changes not yet written (!!! beware then when using :q! or :qa!)
set hidden

" Automatically reload files modified by external programs (if not changed inside of Vim)
" This also copes with annoying pop up that also moves mouse pointer to top right corner
set autoread

" Adjust back textwidth (TODO: find out which script set it to 78!!!)
" keep comments within an 160 column limit, but not code:
set formatoptions=crq
set textwidth=160

" Enable BS over start of line
set bs=2

" Allow virtual edit only in block mode
set ve=block                " choice: block, insert, all, onemore

" Enable mouse double-click on hyperlink in help screen (g<Rclick> for back)
set mouse=a

" fix vim bug - original value does not expand the ~
set tags=~/.vimtags,./tags,./TAGS,tags,TAGS

" :HL - Determining the highlight group that the word under the cursor belongs to ([http://mysite.verizon.net/astronaut/vim/index.html#Tags])
command -bar -nargs=0 HL echo "hi<" . synIDattr(synID(line("."),col("."),1),"name") . '> trans<' . synIDattr(synID(line("."),col("."),0),"name") . "> lo<" . synIDattr(synIDtrans(synID(line("."),col("."),1)),"name") . ">"

"#### Fast Macro - use qq to register the fast macro, and @@ or é to replay the fast macro ######
noremap @@ @q

" Compensates for AZERTY keyboard
imap    ² `
imap    ³ ~
map     ² `
noremap ²² ``
noremap ³ ~
noremap g³ g~
noremap é @q
noremap § ^
noremap ç {
noremap à }

" Trim trailing spaces on save
if !exists("autocmd_BufWritePre_trimspace_tab")
    let autocmd_BufWritePre_trimspace_tab = 1
    autocmd FileType c,cpp,java,php,vim autocmd BufWritePre <buffer> :call setline(1,map(getline(1,"$"),'substitute(v:val,"\\s\\+$","","")'))
    " autocmd BufWritePre * :set expandtab<CR>:retab
endif

" Enable lazy redraw (to speed up cursor mvmt)
set lazyredraw

" Enable modeline (vim param settings embedded in documents)
set modeline

" Extend command-line history to 200 entries, and remap C-p/C-n to Up/Down to allow history filtering
set history=200
cnoremap <C-p> <Up>
cnoremap <C-n> <Down>

"############################################################################################################
" APPEARANCE / DISPLAY
"############################################################################################################

" Enable 256-colors
set t_Co=256

" Select my color scheme
colorscheme mipscheme

" Select light background scheme
set bg=light

" Enable syntax highlighting
syntax enable

" Show line numbers
set number

" Highlight the current line
" -- disabled because slow down display
set nocursorline

" Show special characters... (use CTRL-k << for «, CTRL-k .M for ·, see :help dig)
"(http://vim.wikia.com/wiki/Highlight_unwanted_spaces)
set list listchars=tab:\ \ ,trail:·,extends:>,precedes:<
"To also show tabs:
" set list listchars=tab:»·,trail:·,extends:>,precedes:<
" set list listchars=tab:\|-,trail:.,extends:>,precedes:<

" Don't WRAP anymore since we use listchars...
set nowrap

" Restore WRAP actually
" set wrap linebreak nolist


"############################################################################################################
" AVOID THE ESC KEY
"############################################################################################################

"--- C-C ----------
" C-C    : Same as ESC (prevent C-C to move one char on the left)
inoremap <C-C> <Esc>`^

"--- C-Space ------
" C-Space: NORMAL   --> ESC any prefix keys
" C-Space: VISUAL   --> ESC any selection (gV is required to prevent automatic reselection)
" C-Space: OPERATOR --> ESC any operator pending commands (like y)
" C-Space: INSERT   --> ESC insert mode and `^ restore cursor position (cursor does not move left)
"   (S-Space only works in GUI, see http://vim.wikia.com/wiki/Avoid_the_escape_key)
" nnoremap <nul> <Esc>     (disabled, conflicts with cscope shortcuts)
vnoremap <nul> <Esc>gV
onoremap <nul> <Esc>
inoremap <nul> <Esc>`^

"--- jj -----------
" jj     : ... same as ESC (let's try) ...
inoremap jj <Esc>`^

"############################################################################################################
" MOVEMENT / QUICK EDIT
"############################################################################################################

" Cursor movements wrap over end-of-line
set whichwrap+=<,>,h,l

" jklm: instead of hjkl (jklm are under fingers!)
" DISABLED! LET'S TRY WITHOUT THESE - Trick is to keep the fingers on jklm, and avoid using h (use F instead)
" "noremap j          h
" "noremap <C-W>j     <C-W>h
" "noremap <C-W>J     <C-W>H
" "noremap <C-W><C-J> <C-W>h
" "noremap k          j
" "noremap <C-W>k     <C-W>j
" "noremap <C-W>K     <C-W>J
" "noremap <C-W><C-K> <C-W>j
" "noremap l          k
" "noremap <C-W>l     <C-W>k
" "noremap <C-W>L     <C-W>K
" "noremap <C-W><C-L> <C-W>k
" "noremap m          l
" "noremap <C-W>m     <C-W>l
" "noremap <C-W>M     <C-W>L
" "noremap <C-W><C-M> <C-W>l
" "noremap h          m
" "noremap <C-W>h     <C-W>m
" "noremap <C-W>H     <C-W>M

" C-Q : INSERT, Home     (C-A is last inserted text)
inoremap <C-Q> <Home>

" C-E : INSERT, End
inoremap <C-E> <End>

" C-D : INSERT, Del
inoremap <C-D> <Del>

" [[ / ]] : Next/previous function + recenter
noremap [[    [[zz
noremap ]]    ]]zz

" Use <SPACE> to insert a single character (http://vim.wikia.com/wiki/Insert_a_single_character)
nnoremap <space> :exec "normal i".nr2char(getchar())."\e"<CR>

" Add empty lines in NORMAL mode (http://vim.wikia.com/wiki/Quickly_adding_and_deleting_empty_lines)
nnoremap <silent><A-o> :set paste<CR>m`o<Esc>``:set nopaste<CR>
nnoremap <silent><A-S-o> :set paste<CR>m`O<Esc>``:set nopaste<CR>

"############################################################################################################
" AUTO-COMPLETE
"############################################################################################################

" C-N: Auto-completion menu
" # DISABLED - Don't like the extra window opened, and strange completion.
" # To try: CTRL-N, or CTRL-X CTRL-N, CTRL-X CTRL-O, CTRL-X CTRL-P...
" inoremap <expr> <C-N> pumvisible() \|\| &omnifunc == '' ?
" \ "\<lt>C-n>" :
" \ "\<lt>C-x>\<lt>C-o><c-r>=pumvisible() ?" .
" \ "\"\\<lt>c-n>\\<lt>c-p>\\<lt>c-n>\" :" .
" \ "\" \\<lt>bs>\\<lt>C-n>\"\<CR>"


"############################################################################################################
" INDENTATION
"############################################################################################################

" Custom indentation settings
set tabstop=4 softtabstop=4 shiftwidth=4 expandtab copyindent preserveindent smarttab
set autoindent

" :notab - replace tab with spaces
ca notab  set expandtab<CR>:retab

" Tab / Shift-Tab: VISUAL - same as << >>, but stay in visual mode
vnoremap <S-Tab>    <gv
vnoremap <Tab>      >gv

"############################################################################################################
" CLIPBOARD
"############################################################################################################

" Windows-kinda mode (see mswin.vim)
" C-V: INSERT / COMMAND - Paste clipboard
inoremap <C-V>          <C-R>+
cnoremap <C-V>          <C-R>+
" C-B: Insert VERBATIM (old C-V)
inoremap <C-B>          <C-V>
cnoremap <C-B>          <C-V>
" S-Ins: NORMAL / INSERT / COMMAND - Paste X clipboard
nnoremap <S-Insert>     "*gP
inoremap <S-Insert>     <C-R>*
cnoremap <S-Insert>     <C-R>*

function! EnableClipboardMappings()
    "#### Remap delete (d) / change (c,C) / delete char (x,X) so that it doesn't change the unnamed register ############
    " c: same as before but text discarded             C: same as before but text discarded
    " d: same as before but text discarded             D: delete, text saved in unnamed buffer / DD: delete current line
    " x: same as before but text discarded             X: delete current line in normal mode (dd), text discarded
    " <BS>: backspae (X)

    " Circumvent silly Vim that complains 'no such mapping'
    nnoremap c "_c
    vnoremap c "_c
    nnoremap C "_C
    vnoremap C "_C
    nnoremap CC CC
    nunmap   CC
    nnoremap d "_d
    vnoremap d "_d
    nnoremap <silent> D :set opfunc=DeleteToUnnamed<CR>g@
    vnoremap <silent> D :<C-U>call DeleteToUnnamed(visualmode(), 1)<CR>
    nnoremap <silent> DD dd
    nnoremap x "_x
    vnoremap x "_xgv
    nnoremap X "_dd
    vnoremap X "_X
    nnoremap <BS> "_X
    nnoremap y y
    nunmap   y
    vnoremap y y
    vunmap   y
    nnoremap Y Y
    nunmap   Y
    vnoremap Y Y
    vunmap   Y
    nnoremap p p
    nunmap   p
    vnoremap p p
    vunmap   p
    nnoremap P P
    nunmap   P
    vnoremap P P
    vunmap   P

    if has('clipboard')
        nnoremap <silent> <F6> :call EnableClipboardMappingsX()<CR>:echo "Yank/Paste to clipboard mappings"<CR>
    endif
endfunction

function! EnableClipboardMappingsX()
    "#### Use Clipboard as default register for yank / paste - Use D / C to Cut / Change to clipboard ############
    " C: Change using clipboard register (do c$ for Change to eol)
    "   CC: change current line using clipboard register
    " D: Delete using clipboard register (do d$ for delete to eol)
    "   DD: delete current line using clipboard register
    " X: delete current line
    " x: (visual) keep the current selection
    " BS: same as original X

    " Circumvent silly Vim that complains 'no such mapping'
    nnoremap c c
    nunmap   c
    vnoremap c c
    vunmap   c
    nnoremap <silent> C :set opfunc=ChangeToClipboard<CR>g@
    vnoremap <silent> C :<C-U>call ChangeToClipboard(visualmode(), 1)<CR>
    nnoremap <silent> CC "+cc
    nnoremap d d
    nunmap   d
    vnoremap d d
    vunmap   d
    nnoremap <silent> D :set opfunc=DeleteToClipboard<CR>g@
    vnoremap <silent> D :<C-U>call DeleteToClipboard(visualmode(), 1)<CR>
    nnoremap <silent> DD "+dd
    nnoremap x x
    nunmap   x
    vnoremap x xgv
    nnoremap X dd
    vnoremap X X
    vunmap   X
    nnoremap <BS> X
    nnoremap y "+y
    vnoremap y "+y
    nnoremap Y "+Y
    vnoremap Y "+Y
    nnoremap p "+p
    vnoremap p "+p
    nnoremap P "+P
    vnoremap P "+P

    nnoremap <silent> <F6> :call EnableClipboardMappings()<CR>:echo "Standard yank/paste mappings"<CR>
endfunction

" Use clipboard as default register if available
if has('clipboard')
    call EnableClipboardMappingsX()
else
    call EnableClipboardMappings()
endif

function! DeleteToClipboard(type, ...)
  let sel_save = &selection
  let &selection = "inclusive"

  if a:0                                     " Invoked from Visual mode, use '< and '> marks.
    silent exe "normal! `<" . a:type . "`>\"+x"
  elseif a:type == 'line'
    silent exe "normal! '[V']\"+x"
  elseif a:type == 'block'
    silent exe "normal! `[\<C-V>`]\"+x"
  else
    silent exe "normal! `[v`]\"+x"
  endif

  let &selection = sel_save
endfunction

function! ChangeToClipboard(type, ...)
  let sel_save = &selection
  let sel_ve= &virtualedit
  let &selection = "inclusive"
  let &virtualedit = "onemore"

  if a:0                                     " Invoked from Visual mode, use '< and '> marks.
    exe "normal! `<" . a:type . "`>\"+x" | startinsert
  elseif a:type == 'line'
    exe "normal! '[V']\"+x" | startinsert
  elseif a:type == 'block'
    exe "normal! `[\<C-V>`]\"+x" | startinsert
  else
    exe "normal! `[v`]\"+x" | startinsert
  endif

  let &selection = sel_save
  let &virtualedit = sel_ve
endfunction

function! DeleteToUnnamed(type, ...)
  let sel_save = &selection
  let &selection = "inclusive"

  if a:0                                     " Invoked from Visual mode, use '< and '> marks.
    silent exe "normal! `<" . a:type . "`>x"
  elseif a:type == 'line'
    silent exe "normal! '[V']x"
  elseif a:type == 'block'
    silent exe "normal! `[\<C-V>`]x"
  else
    silent exe "normal! `[v`]x"
  endif

  let &selection = sel_save
endfunction

"############################################################################################################
" SEARCH / SUBSTITUTE
"############################################################################################################
" Links:
"  - [http://vim.wikia.com/wiki/Keystroke_Saving_Substituting_and_Searching]
"    [http://vim.wikia.com/wiki/Search_and_replace_the_word_under_the_cursor]

" Enable hlsearch so that search query is always highlighted
set hlsearch

" Enable incremental search
set incsearch

" Centre on next
nnoremap n nzz

" F4 : NORMAL - Replace current word
noremap  <F4>      "*yiw:%s/<C-R><C-W>//gc<Left><Left><Left>
" <Leader>s : NORMAL - Replace current word (match word)
nnoremap <Leader>s "*yiw:%s/\<<C-r><C-w>\>//gc<Left><Left><Left>
" /  : VISUAL - Search highlighted text in visual mode
vnoremap /         y:execute "/".escape(@",'[]/\.*')<CR>
" F4 : VISUAL - Replace selection
vnoremap <F4>      y:execute "%s/".escape(@",'[]/')."//gc"<Left><Left><Left><Left>
" (Use C-V/S-Ins to paste current word, or C-W to delete previous word)

" gl - Set clipboard to current word (was C-J, then C-L)
nnoremap gl      "+yiw
" F3  - Set clipboard to current word and edit
nnoremap <F3>       :let @+ = "<C-r><C-w>"<Left>
" C-P - Replace current word with clipboard
nnoremap <C-P>      ciw<C-R>+<Esc>
" C-F3 - Set search pattern to current word (but don't search yet)
nnoremap <C-F3>     :let @/ = "\\<".escape("<C-r><C-w>",'[]/\.*')."\\>"<CR>
" S-F3 - Replace current word with clipboard, and search next
nmap     <S-F3>     <C-F3><C-P>n
" (Use either as (F3, S-F3, S-F3...) OR (gl, hjkl, S-F3, S-F3...)

"############################################################################################################
" WINDOWS / TABS
"############################################################################################################

" A-J / A-M: next/previous tabs
noremap <M-j> gT
noremap <M-m> gt

" C-(NUM+,NUM-,NUM*,NUM/): Increase/decrease width/height of current window
nnoremap <C-kPlus> <C-W>+
nnoremap <C-kMinus> <C-W>-
nnoremap <C-kMultiply> <C-W>>
nnoremap <C-kDivide> <C-W><

" C-W t: Promote window to tab (http://vim.1045645.n5.nabble.com/Promote-window-to-tab-td1198017.html)
" ... Disabled. Does not work when 1 window on current tab
" noremap <C-W>t :tabedit <C-R>%<CR>gT<C-W>qgt

" Disabled (was F9) : Resize current to 15 high + winfixheight
" noremap <silent> <F9> 15<C-W>_:set winfixheight<CR>

" F9 : Duplicate previous window in current window
" (F7 conflicts with vim-latex)
nnoremap <silent> <F9> <C-W><C-P>mA<C-W><C-P>`A

"############################################################################################################
" LOCATION LIST
"############################################################################################################

" C-N / C-H : next/previous quickfix entry
nnoremap <silent><C-N> :cnext<CR>
nnoremap <silent><C-H> :cprevious<CR>

" F2 : toggle QuickFix window
function! Setf2cclose()
    silent exe "nnoremap <silent><F2> :cclose<CR>:call Setf2copen()<CR>"
endfunction

function! Setf2copen()
    silent exe "nnoremap <silent><F2> 2:copen<CR>:call Setf2cclose()<CR>"
endfunction
call Setf2copen()

" Tips1536 - Automatically fit QuickFix window height
au FileType qf call AdjustWindowHeight(2, 5)
function! AdjustWindowHeight(minheight, maxheight)
  nnoremap <buffer> <C-M> <C-M>
  exe max([min([line("$"), a:maxheight]), a:minheight]) . "wincmd _"
  call Setf2cclose()
endfunction


"############################################################################################################
" PLUGINS
"############################################################################################################

" snipMate (http://www.vim.org/scripts/script.php?script_id=2540)
" --------
filetype plugin on

" BufTabs
" -------
" Always show status line
set laststatus=2
" C-K for file on the left (next), C-J for file on the right (prev)
nnoremap <silent> <C-J> :call BufStatNext()<CR>
noremap <silent> <C-K> :call BufStatPrev()<CR>
" Let's format the line as for Lusty-Juggler
let g:bufstat_number_before_bufname = "0"
let g:bufstat_join_string = "|"
let g:bufstat_active_hl_group = "ActiveBuffer"
let g:bufstat_inactive_hl_group = "InactiveBuffer"
let g:bufstat_separator_hl_group = "BufferSep"
" use fancy buffer closing that doesn't close the split
cnoremap <expr>   bd    (getcmdtype() == ':' && getcmdline() == '' ? 'Bclose' : 'bd')
cnoremap <expr>   Q     (getcmdtype() == ':' && getcmdline() == '' ? 'Bclose' : 'Q')
nnoremap <silent> <F8>  :Bclose<CR>

" LustyExplorer
" -------------
nmap <Leader>f       <Leader>lf
nmap <Leader>r       <Leader>lr
nmap <Leader>b       <Leader>lb
nmap <Leader>g       <Leader>lg
let g:LustyExplorerSuppressRubyWarning = 1

" LustyJuggler
" -------------
nmap <Leader>j       <Leader>lj
let g:LustyJugglerSuppressRubyWarning = 1

" NERD-Tree
" ---------
" Open and close the NERD_tree.vim separately
nmap <F11>  :NERDTreeToggle<CR>

" Fuzzy-Finder
" ------------
"  In file mode, use **/pattern to search in a directory tree. This is default in CoverageFile mode
nmap <silent> <Leader>zf      :FufFile<CR>
nmap <silent> <Leader>zc      :FufCoverageFile<CR>
nmap <silent> <Leader>zT      :FufBufferTag<CR>
nmap <silent> <Leader>zt      :FufTag<CR>

" Possible other tag look-up: [i, [I, ... (see :help include-search)]]"

"############################################################################################################
" DEVELOPMENT
"############################################################################################################

" Mapping for Quick Make (:write all, :make, Show QuickFix window if errors)
nmap <F5> :wa<CR>:make<CR>:cw<CR>

"############################################################################################################
" VIM-LATEX
"############################################################################################################

" REQUIRED. This makes vim invoke Latex-Suite when you open a tex file.
filetype plugin on

" IMPORTANT: win32 users will need to have 'shellslash' set so that latex
" can be called correctly.
" set shellslash

" IMPORTANT: grep will sometimes skip displaying the file name if you
" search in a singe file. This will confuse Latex-Suite. Set your grep
" program to always generate a file-name.
set grepprg=grep\ -nH\ $*

" OPTIONAL: This enables automatic indentation as you type.
filetype indent on

" OPTIONAL: Starting with Vim 7, the filetype of empty .tex files defaults to
" 'plaintex' instead of 'tex', which results in vim-latex not being loaded.
" The following changes the default filetype back to 'tex':
let g:tex_flavor='latex'

" Use <C-l> for jump formward instead of <C-J>
imap <C-l> <Plug>IMAP_JumpForward
nmap <C-l> <Plug>IMAP_JumpForward
vmap <C-l> <Plug>IMAP_JumpForward
