]> ruderich.org/simon Gitweb - config/dotfiles.git/blobdiff - vimrc
vimrc: Fix indentation in s:CustomSyntaxHighlights().
[config/dotfiles.git] / vimrc
diff --git a/vimrc b/vimrc
index bb0bfe6ce268e5722210a7f383fb0e51e559c5ec..2406b1c809b20f901207c636a33b93ee6c2b1225 100644 (file)
--- a/vimrc
+++ b/vimrc
@@ -1,5 +1,20 @@
 " Vim main configuration file.
 
+" Copyright (C) 2011-2012  Simon Ruderich
+"
+" This file is free software: you can redistribute it and/or modify
+" it under the terms of the GNU General Public License as published by
+" the Free Software Foundation, either version 3 of the License, or
+" (at your option) any later version.
+"
+" This file is distributed in the hope that it will be useful,
+" but WITHOUT ANY WARRANTY; without even the implied warranty of
+" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+" GNU General Public License for more details.
+"
+" You should have received a copy of the GNU General Public License
+" along with this file.  If not, see <http://www.gnu.org/licenses/>.
+
 
 " EDITOR SETTINGS
 
@@ -64,6 +79,14 @@ if exists('+cryptmethod')
     set cryptmethod=blowfish
 endif
 
+" Clear all vimrc-related autocmds. Has to be done here as the vimrc augroup
+" is used multiple times.
+if has('autocmd')
+    augroup vimrc
+        autocmd!
+    augroup END
+endif
+
 
 " EDIT SETTINGS
 
@@ -167,6 +190,10 @@ if exists('+cursorline')
     set cursorline
 endif
 
+" Highlight all matches on the screen when searching. Use <C-L> (see below) to
+" remove the highlighting until the next search.
+set hlsearch
+
 " Display tabs, trailing space, non breakable spaces and long lines (when
 " wrapping is disabled).
 set list
@@ -179,9 +206,34 @@ if has('statusline')
     " Always display the status line even if there is only one window.
     set laststatus=2
 
+    " If there's more than one buffer return "/<nr>" (e.g. "/05") where <nr>
+    " is the highest buffer number, otherwise return nothing. Used in
+    " 'statusline' to get an overview of available buffer numbers.
+    function! StatuslineBufferCount()
+        let l:bufnr = bufnr('$')
+        if l:bufnr > 1
+            let l:result = '/'
+            if exists('*printf')
+                let l:result .= printf('%02d', l:bufnr)
+            else
+                " Older Vims don't have printf() (and no .= either). Emulate
+                " "%02d".
+                if l:bufnr < 10
+                    let l:result = l:result . '0'
+                endif
+                let l:result = l:result . l:bufnr
+            endif
+            return l:result
+        else
+            return ''
+        endif
+    endfunction
+
     set statusline=
     " on the left
-    set statusline+=%02n: " buffer number
+    set statusline+=%02n  " buffer number
+    set statusline+=%{StatuslineBufferCount()} " highest buffer number
+    set statusline+=:
     set statusline+=%f\   " path to current file in buffer
     set statusline+=%h    " [help] if buffer is help file
     set statusline+=%w    " [Preview] if buffer is preview buffer
@@ -236,6 +288,33 @@ cmap <Left>  <Nop>
 cnoremap <C-P> <Up>
 cnoremap <C-N> <Down>
 
+if has('eval')
+" Don't move the cursor to the first column for certain scroll commands (<C-F,
+" <C-B>, <C-D>, <C-U>). Thanks to jamessan in #vim on Freenode (2011-08-31
+" 02:27 CEST) for the 'nostartofline' tip. But I can't use 'nostartofline'
+" directly because it also enables that feature for other commands which I
+" don't want.
+
+    " Set 'nostartofline' for a single movement.
+    function! s:TemporaryNostartofline(movement)
+        let l:startofline = &startofline
+        set nostartofline
+        execute 'normal! ' . a:movement
+        let &startofline = l:startofline
+    endfunction
+
+    " Thanks to fow in #vim on Freenode (2012-02-16 15:38 CET) for the idea to
+    " use "<Bslash><Lt>"; Vim documentation reference: :help <>.
+    nnoremap <silent> <C-F>
+        \ :call <SID>TemporaryNostartofline("<Bslash><Lt>C-F>")<CR>
+    nnoremap <silent> <C-B>
+        \ :call <SID>TemporaryNostartofline("<Bslash><Lt>C-B>")<CR>
+    nnoremap <silent> <C-D>
+        \ :call <SID>TemporaryNostartofline("<Bslash><Lt>C-D>")<CR>
+    nnoremap <silent> <C-U>
+        \ :call <SID>TemporaryNostartofline("<Bslash><Lt>C-U>")<CR>
+endif
+
 " Write before suspending, thanks to deryni in #vim on Freenode (2011-05-09
 " 20:02 CEST). To suspend without saving either unmap this or use :stop<CR>.
 nnoremap <silent> <C-Z> :update<CR>:stop<CR>
@@ -244,9 +323,10 @@ nnoremap <silent> <C-Z> :update<CR>:stop<CR>
 " in #vim on Freenode (2011-08-15 00:17 CEST).
 nnoremap <C-G> 2<C-G>
 
-" Use <Space> to move down a page and - to move up one like in mutt.
-nnoremap <Space> <C-F>
-nnoremap - <C-B>
+" Use <Space> to move down a page and - to move up one like in mutt. Don't use
+" nnoremap so the <C-F>/<C-B> 'nostartofline' fix (see above) works.
+nmap <Space> <C-F>
+nmap - <C-B>
 
 " Go to next and previous buffer. Thanks to elik in #vim on Freenode
 " (2010-05-16 18:38 CEST) for this idea.
@@ -271,9 +351,9 @@ nnoremap <C-W>O <C-W>p<C-W>o
 " Maps to change spell language between English and German and disable spell
 " checking.
 if exists('+spell')
-    noremap <silent> <Leader>sn :set nospell<CR>
-    noremap <silent> <Leader>se :set spell spelllang=en_us<CR>
-    noremap <silent> <Leader>sd :set spell spelllang=de_de<CR>
+    nnoremap <silent> <Leader>sn :set nospell<CR>
+    nnoremap <silent> <Leader>se :set spell spelllang=en_us<CR>
+    nnoremap <silent> <Leader>sd :set spell spelllang=de_de<CR>
 endif
 
 " Add semicolon to the end of the line. Thanks to
@@ -288,7 +368,9 @@ if has('eval')
     function! s:VSetSearch()
         let l:temp = @@
         normal! gvy
-        let @/ = '\V' . substitute(escape(@@, '\'), '\n', '\\n', 'g')
+        " Added \C to force 'noignorecase' while searching the current visual
+        " selection. I want to search for the exact string in this case.
+        let @/ = '\C' . '\V' . substitute(escape(@@, '\'), '\n', '\\n', 'g')
         let @@ = l:temp
     endfunction
     vnoremap * :<C-U>call <SID>VSetSearch()<CR>//<CR>
@@ -404,42 +486,80 @@ if has('syntax')
         set synmaxcol=500
     endif
 
+" Use (limited) syntax based omni completion if no other omni completion is
+" available. Taken from :help ft-syntax-omni.
+    if has('autocmd') && exists('+omnifunc')
+        augroup vimrc
+            autocmd FileType *
+                \ if &omnifunc == '' |
+                \     setlocal omnifunc=syntaxcomplete#Complete |
+                \ endif
+        augroup END
+    endif
+
+" Function to enable all custom highlights. Necessary as highlights are
+" window-local and thus must be set for each new window.
+    function! s:CustomSyntaxHighlights()
+        " Not the first time called, nothing to do.
+        if exists('w:vimrc_syntax_run')
+            return
+        endif
+        let w:vimrc_syntax_run = 1
+
 " Highlight lines longer than 78 characters. Thanks to Tony Mechelynck
 " <antoine.mechelynck@gmail.com> from the Vim mailing list. It can easily be
 " disabled when necessary with :2match (in Vim >= 700).
-    if exists(':2match')
-        2match Todo /\%>78v./
-    else
-        match Todo /\%>78v./
-    endif
+        if exists(':2match')
+            2match Todo /\%>78v./
+        else
+            match Todo /\%>78v./
+        endif
 
-    if exists('*matchadd')
+        if exists('*matchadd')
 " Highlight some important keywords in all documents.
-        for s:x in ['TODO', 'XXX', 'FIXME', 'CHANGED', 'REMOVED', 'DELETED']
-            call matchadd('Todo', s:x)
-        endfor
+            for s:x in ['TODO', 'XXX', 'FIXME',
+                      \ 'CHANGED', 'REMOVED', 'DELETED']
+                call matchadd('Todo', s:x)
+            endfor
 
 " Highlight unicode whitespace which is no normal whitespace (0x20).
-        for s:x in ['00a0', '1680', '180e', '2000', '2001', '2002', '2003',
-                \ '2004', '2005', '2006', '2007', '2008', '2009', '200a',
-                \ '200b', '200c', '200d', '202f', '205f', '2060', '3000',
-                \ 'feff']
-            call matchadd('Error', '\%u' . s:x)
-        endfor
+            for s:x in ['00a0', '1680', '180e', '2000', '2001', '2002',
+                      \ '2003', '2004', '2005', '2006', '2007', '2008',
+                      \ '2009', '200a', '200b', '200c', '200d', '202f',
+                      \ '205f', '2060', '3000', 'feff']
+                call matchadd('Error', '\%u' . s:x)
+            endfor
+        endif
+    endfunction
+" Enable highlights for the current and all new windows. Thanks to bairui in
+" #vim on Freenode (2012-04-01 00:22 CEST) for the WinEnter suggestion.
+    call <SID>CustomSyntaxHighlights()
+    if has('autocmd')
+        augroup vimrc
+            autocmd WinEnter * call <SID>CustomSyntaxHighlights()
+        augroup END
     endif
 
+
 " Settings for specific filetypes.
 
     " Haskell.
+    let g:hs_highlight_delimiters = 1
     let g:hs_highlight_boolean = 1
     let g:hs_highlight_types = 1
     let g:hs_highlight_more_types = 1
-
     " Perl.
     let g:perl_fold = 1
     let g:perl_fold_blocks = 1
     let g:perl_nofold_packages = 1
     let g:perl_include_pod = 1 " syntax coloring for PODs
+    " Python.
+    let g:python_highlight_all = 1
+    " Vim.
+    let g:vimsyn_embed = 0      " don't highlight embedded languages
+    let g:vimsyn_folding = 'af' " folding for autogroups (a) and functions (f)
+    " XML.
+    let g:xml_syntax_folding = 1
 endif
 
 
@@ -476,12 +596,10 @@ endif
 " twice.
 if has('autocmd')
     augroup vimrc
-" Remove all autocmds from the current group.
-        autocmd!
 
 " Go to last position of opened files. Taken from :help last-position-jump.
         autocmd BufReadPost *
-            \ if line("'\"") > 1 && line("'\"") <= line("$") |
+            \ if line("'\"") > 1 && line("'\"") <= line('$') |
             \     execute "normal! g'\"" |
             \ endif
 " But not for Git commits, go to beginning of the file.
@@ -500,13 +618,17 @@ if has('autocmd')
 
 " Automatically disable 'paste' mode when leaving insert mode. Thanks to
 " Raimondi in #vim on Freenode (2010-08-14 23:01 CEST). Very useful as I only
-" want to paste once and then 'paste' gets automatically unset.
+" want to paste once and then 'paste' gets automatically unset. InsertLeave
+" doesn't exist in older Vims.
         if exists('##InsertLeave')
             autocmd InsertLeave * set nopaste
         endif
 
-" Write file when running :mak[e] before 'makeprg' is called.
-        autocmd QuickFixCmdPre * write
+" Write file when running :mak[e] before 'makeprg' is called. QuickFixCmdPre
+" doesn't exist in older Vims.
+        if exists('##QuickFixCmdPre')
+            autocmd QuickFixCmdPre * write
+        endif
 
 " AFTER/FTPLUGIN AUTO COMMANDS
 
@@ -555,7 +677,7 @@ if has('eval')
 " file it was loaded from, thus the changes you made. Thanks to the
 " vimrc_example.vim file in Vim's source. Modified to use the same filetype
 " for the diffed file than the filetype for the original file.
-    if !exists(":DiffOrig")
+    if !exists(':DiffOrig')
         command DiffOrig
             \ let s:diff_orig_filetype = &filetype
             \ | vertical new