From ConformalOpenSource
Jump to: navigation, search

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

Auto KNF

" 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;*~

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.

source /usr/local/share/vim/vim73/ftplugin/man.vim

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>'

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 (mine was at: /usr/contrib/lib/ 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 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 script inside a makefile and create it at the same time as the dependencies. For example (simplified):
javascript.h: ${JSFILES}
	python /home/marco/ -f ${.CURDIR}/ ${CC} -c ${CPPFLAGS} ${CFLAGS} ${.CURDIR}/xxxterm.c

The contents of the example .clang_complete file is as follows:

  • 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>