I often get asked what my vim settings are so I decided to call it a day and document it already.
I will be breaking up the pieces so that one can pick and choose on what is useful for them.
First some generic settings
set nocompatible set cinoptions=t0,+4,(4,u4,w1 set shiftwidth=8 set softtabstop=8 set ruler set tabstop=8 set autoindent set showmode set showmatch set tags=./tags,tags,/usr/src/sys/arch/amd64/tags,/var/db/libc.tags set hlsearch set incsearch set backspace=indent,eol,start set showcmd " display incomplete commands set ttyfast " needed to make laggy connections work fast enough "set mouse=a " enable if you want the mouse to work in xterm syntax on
Show us the whitespace that violates KNF
" show KNF violations highlight OverLength ctermbg=red ctermfg=white guibg=#592929 match OverLength /\%81v.*/ let c_space_errors=1
" line set cinoptions=:0,t0,+4,(4
Make funny terminals accept some keystrokes
" backspace imap ^? ^H " ctrl up and ctrl down in tmux if &term == "screen" set t_kN=^[[6;*~ set t_kP=^[[5;*~ endif
Detect if we want to enable spelling check
" text & mutt files au BufNewFile,BufRead /tmp/mutt*,/tmp/cvs*,*.txt set tw=72 noai noshowmatch au BufNewFile,BufRead /tmp/mutt*,/tmp/cvs*,*.txt setlocal spell spelllang=en_us au BufNewFile,BufRead /tmp/mutt*,/tmp/cvs*,*.txt syntax off " git commits au BufNewFile,BufRead *.git/COMMIT_EDITMSG set tw=72 noai noshowmatch au BufNewFile,BufRead *.git/COMMIT_EDITMSG setlocal spell spelllang=en_us " f7 toggles spelling on/off nn <F7> :setlocal spell! spell?<CR>
When editing binary files or to ensure there are no funny hidden characters I use the hex converter.
" Convert to hex and back; does not save changes nn <F5> :%!xxd -g 1<CR> nn <F6> :%!xxd -g 1 -r<CR>
I sometimes like to be able to see man pages while hacking. With this little plugin i can type :Man strlcpy and the man pages shows up.
This is were it gets juicy. The following lines are for integration between vim and the build environment. These settings make compiling and fixing bugs a breeze. First we define our leader (like a meta key) to be , (comma) to prefix every command we type. The only prerequisite is that one must have a Makefile of sorts in the current directory for this to work because it literally runs make.
The process is as follows:
- save file and compile with ,m
- if everything is fine nothing happens however, if there are errors or warnings the so called quickfix window is opened at the bottom
- to go to the next compiler error press ,n
- to go to the previous compiler error press ,p
- to hide the quickfix window press ,h and ,s to show it
- to view all error lines press ,l
" compiler stuff let g:compiler_gcc_ignore_unmatched_lines=1 let mapleader=',' " quickfix :make nmap <silent> <Leader>m :wa<CR>:silent! make \| redraw! \| cw<CR><CR> vmap <silent> <Leader>m :wa<CR>:silent! make \| redraw! \| cw<CR><CR> " handy shortcuts map <Leader>h :ccl<CR> map <Leader>s :cw<CR> map <Leader>l :cl<CR> " jump between messages map <Leader>n :cn<CR> map <Leader>p :cp<CR>
Add a couple of macros
- @u uncoment line
- @c comment line
- @p add a printf with the function name for quick debugging
" @c comment, @u uncomment, @p print function name let @u='0xx$xx^[' let @c='I/*^[A*/^[' let @p='ofprintf(stderr, "%s\n", __func__);^['
The following function adds a mechanism to run a shell command and open a window on top of the screen with the results. For example :Shell ls -la
function! s:ExecuteInShell(command, bang) let _ = a:bang != '' ? s:_ : a:command == '' ? '' : join(map(split(a:command), 'expand(v:val)')) if (_ != '') let s:_ = _ let bufnr = bufnr('%') let winnr = bufwinnr('^' . _ . '$') silent! execute winnr < 0 ? 'new ' . fnameescape(_) : winnr . 'wincmd w' setlocal buftype=nowrite bufhidden=wipe nobuflisted noswapfile nowrap silent! :%d let message = 'Execute ' . _ . '...' call append(0, message) echo message silent! 2d | resize 1 | redraw silent! execute 'silent! %!'. _ silent! execute 'resize ' . line('$') silent! execute 'autocmd BufUnload <buffer> execute bufwinnr(' . bufnr . ') . ''wincmd w''' silent! execute 'autocmd BufEnter <buffer> execute ''resize '' . line(''$'')' silent! execute 'nnoremap <silent> <buffer> <LocalLeader>r :call <SID>ExecuteInShell(''' . _ . ''', '''')<CR>' silent! execute 'nnoremap <silent> <buffer> <LocalLeader>g :execute bufwinnr(' . bufnr . ') . ''wincmd w''<CR>' endif endfunction command! -complete=shellcmd -nargs=* -bang Shell call s:ExecuteInShell(<q-args>, '<bang>') cabbrev shell Shell
This is a recent addition of the [clang_complete plugin]. The [clang] completion plugin allows one to autocomplete things such as structure elements while maintaing context. Meaning, only show the possible structure elements and nothing else. This thing is hard to setup which is it's only real downfall. These are the rough steps:
- Install python
- One must use a vim that was compiled with python support
- Download the plugin and extract it in the proper vim directory (on my system it was: /usr/local/share/vim/vim73/plugin/). I couldn't get the installer to work.
- The hard part is setting all the correct paths, clang and python must be in the path.
- Find libclang.so (mine was at: /usr/contrib/lib/libclang.so) and set g:clang_library_path to point to the directory that contains that library.
- Now comes the real hard part, in order for completion to work it needs a .clang_complete file in it's root. This file contains all -D -I and -f lines the project normally needs to compile. One on each line. Behind the scenes the plugin is actually compiling the code in order to determine the scope, hence it nreeds those flags to compile the file. To make that a bit easier the plugin ships with a script called cc_args.py however that script is limited to only generating that file in the current dir. For OpenBSD developers this is bad because we tend to build in a obj directory. I modified the script to add a -f parameter to it which delineates where the file ends up. I rigged the cc_args.py script inside a makefile and create it at the same time as the dependencies. For example (simplified):
The contents of the example .clang_complete file is as follows:
-I. -I/home/marco/git/xxxterm -I/usr/local/include/webkit-1.0 -I/usr/local/include/gtk-2.0 -I/usr/local/lib/gtk-2.0/include -I/usr/local/include/pango-1.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/X11R6/include -I/usr/local/include/cairo -I/usr/local/include/atk-1.0 -I/usr/X11R6/include/pixman-1 -I/usr/include/dev/pci/drm -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/libpng -I/usr/X11R6/include/freetype2 -I/usr/local/include/libsoup-2.4 -I/usr/local/include/libxml2 -I/usr/local/include -I/usr/local/include/p11-kit-1 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -DXXXTERM_BUILDSTR="XXXTERM_1_10_0-50-gc4cf7e8"
- While trying this to work it helps to know that ,q is mapped to the quickfix window and shows errors suchs as xxxterm.h not found (meaning the -I stuff isn't working right)
The following settings are the ones I like but one must play with the toy before getting an idea what works. I left the commented stuff in here in order to make is a bit easier to tune.
" autcomplete for clang set completeopt="menu,menuone,longest" "let g:clang_auto_select=1 "let g:clang_complete_auto=1 let g:clang_complete_copen=1 "let g:clang_hl_errors=1 "let g:clang_periodic_quickfix=1 "let g:clang_snippets=1 "let g:clang_snippets_engine="clang_complete" "let g:clang_conceal_snippets=1 "let g:clang_exec="clang" "let g:clang_user_options='2>/dev/null || exit 0' let g:clang_auto_user_options="path, .clang_complete, obj/.clang_complete" let g:clang_use_library=1 let g:clang_library_path="/usr/contrib/lib/" "let g:clang_sort_algo="priority" "let g:clang_complete_macros=1 let g:clang_complete_patterns=1 nnoremap <Leader>q :call g:ClangUpdateQuickFix()<CR>