Editor Vim
There exist only two real editors in the programmer's world ;-) One is Vim, and the other is the eier-legende-woll-milch-sau (sorry for that German phrase being a modified translation of allrounder - all-in-one device suitable for every purpose, couldn't resist ;-) (X)Emacs. So here we go for Vim.
Contents
General Vim settings
In .vimrc have the following settings. For the tabstops=4 setting it may
not be desired to have this globally effective, you may want to restrict it to
an OOo/SO environment by evaluating the $SOLARENV environment variable,
if $SOLARENV != ""
set ts=4 " tabstops are 4 (for all code) set sw=4 " shiftwidth is 4 set expandtab " expand tabs to spaces set showmatch " briefly jump to matching brackets set showmode " the mode we're in if version >= 600 filetype on " enable file type detection filetype plugin on " enable file type plugins filetype indent on " enable file type indents endif " previous and next compiler error (quickfix) map <C-P> :cp<CR> map <C-N> :cn<CR> " Only do this part when compiled with support for autocommands. if has("autocmd") " In text files, always limit the width of text to 78 characters, tabs are 8 autocmd BufRead *.txt,*.doc,*.dok setlocal tw=78 ts=8 sw=8 fo+=rn1 " Treat resource files and headers like C files autocmd BufRead *.hrc,*.src setlocal ft=c " Treat generated UNO header files like C++ files autocmd BufRead *.hdl setlocal ft=cpp " mail bodies have a textwidth of 72 characters, activate numbering " formatting, reset comments to default, no indenting autocmd FileType mail setlocal tw=72 fo+=rn1 comments& nocindent " AutoDoc comments in C/C++ files without '*' middle part autocmd FileType c,cpp setlocal comments^=s:/**,mb:\ ,e:*/ " AutoDoc comments in IDL files have a textwidth of 72 characters autocmd FileType idl setlocal comments^=s:/**,mb:\ ,e:*/ tw=72 " OOo .xcu configuration files and the like autocmd FileType xml setlocal sw=2 " HTML files autocmd FileType html,css setlocal sw=2 endif " setting up for :make set makeprg=$SOLARENV/bin/build.pl\ \-P4\ \-\-\ \-P4 " broken whitespace :au Syntax * syn match Error /\s\+$/ | syn match Error /^\s* \t\s*/
Vim and the GNU ID-utils
As mentioned in Little Helpers' GNU Id-utils, the eid command makes use of some environment variables when invoking the editor:
setenv VISUAL vim setenv EIDARG '+/%s/' setenv EIDLDEL '\<' setenv EIDRDEL '\>'
To be able to invoke the lid utility from within Vim we need a key mapping and function call, you may place this section into your .vimrc file:
" GNU id-utils, taken from :h ident-search " Generate the ID file in the current directory or in .. or ../.. or ../../.. " To use it, place the cursor on a word, type "_u" and vim will load the file " that contains the word. Search for the next occurrence of the word in the " same file with "n". Go to the next file with "_n". map _u :call ID_search()<Bar>execute "/\\<" . g:word . "\\>"<CR> map _n :n<Bar>execute "/\\<" . g:word . "\\>"<CR> function ID_search() let g:word = expand("<cword>") let x = system("lid --key=none ". g:word) let x = substitute(x, "\n", " ", "g") execute "next " . x endfun
lid.vim plugin
lid.vim is a plugin to integrate GNU id-utils with Vim, providing a lid -g output in the quickfix window that can be travelled using the :cnext and :cprev commands respectively their keyboard mappings.
Vim and Ctags
That's easy, as vim has builtin support for ctags, see :h tagsrch.txt, in .vimrc just tell it where to search for the tags files:
" Tags files are searched first relative to the current file, then relative to " the current working directory, and last in the $HOME directory. set tags=./tags,./../tags,./../../tags,./../../../tags,./../../../../tags,./../../../../../tags,tags,../tags,../../tags,../../../tags,../../../../tags,../../../../../tags,~/tags
For general Exuberant Ctags information and a script how to create the tags database see the Little Helpers' Exuberant Ctags section.
Vim and Cscope
For general Cscope information and a script how to create a cscope database for an OOo project see the Little Helpers' Cscope section.
Builtin Cscope support
Vim has builtin (well, if compiled in) support for cscope, see :h cscope. In .vimrc you may want to setup some things, but this is also a matter of work habits. Consider the following an example and consult the fine manual.
" Cscope settings if has("cscope") " quickfix window usage set cscopequickfix=s-,c-,d-,i-,t-,e- " :tag and the like use :cstag set cscopetag " first search cscope, than tags file set cscopetagorder=0 set nocsverb " add any database in current directory if filereadable("cscope.out") cs add cscope.out " else add database pointed to by environment elseif $CSCOPE_DB != "" cs add $CSCOPE_DB endif set csverb endif
More comfortable plugin script cecscope.vim
The command and menu driven cscope interface eases things a bit. It requires vim7.0aa snapshot #188 or later, the Vim7.1 release does fine.
Include file searches in Vim
Set the path variable in .vimrc:
" Where to look for files in gf and ^Wf and similar commands, " and for include files for i_^X^I and i_^X^D commands. " To use VIM_INC in OOo/SO environment define " alias solvim 'if ( ! $?UPDMINOREXT ) setenv UPDMINOREXT "" ; setenv VIM_INC ./${INPATH}/inc,../${INPATH}/inc,../../${INPATH}/inc,../../../${INPATH}/inc,`echo $SOLARINC|sed -e "s/^-I//" -e "s/ *-I/,/g"`,${SOLARVERSION}/${INPATH}/inc${UPDMINOREXT}/offuh' " Note the two space characters in the second substitute, and execute the alias after a setsolar. " Under 4NT you need some rubbish like (note this isn't updated since ages) " alias solvim=set _uq_%0=%@unique[%tmp%] && echos VIM_INC=>>_uq_%0 && echo %SOLARINC|sed -e "s/^-I//" -e "s/ \+-I/,/g">>_uq_%0 && set /r _uq_%0 && del /q _uq_%0 set path=.,./inc,./../inc,./../../inc,./../../../inc,./../../../../inc,$VIM_INC,,/usr/local/include,/usr/include
In case you missed it in the comments above: you need to invoke a shell alias after having sourced the environment:
tcsh alias solvim 'if ( ! $?UPDMINOREXT ) setenv UPDMINOREXT "" ; setenv VIM_INC ./${INPATH}/inc,../${INPATH}/inc,../../${INPATH}/inc,../../../${INPATH}/inc,`echo $SOLARINC|sed -e "s/^-I//" -e "s/ *-I/,/g"`,${SOLARVERSION}/${INPATH}/inc${UPDMINOREXT}/offuh' source LinuxX86Env.Set solvim
See also: in Vim :h include-search
Compiling a source from within Vim
Compiling the source from within the editor is of course desired, as warnings and errors generated by the compiler let you directly jump to the line in question. There are some quirks to be solved for the OOo/SO environment, but no real problem, just examine the working .vimrc sections below. Pressing Ctrl+K changes the current window's directory locally to the one of the file loaded, if there is a makfile.mk in that directory, sets the makeprg variable to the command needed to dmake just the current file, and executes it.
For the quickfix window to pull its content from the compiler output we need to have a valid error file setting, and as there's always the hassle with DOS based systems, we also need to take care of that:
" This uses the TMP environment variable, be sure to have it set! if $COMSPEC =~ "\\" " seems like we're having any DOS set makeef=$TMP\\vim##.err " :make errorfile else set makeef=$TMP/vim##.err " :make errorfile endif if $TMP =~ "\\" && ($COMSPEC =~ "4" || $SHELL =~ "4") " seems like we're having some DOS assumed to be 4DOS compatible set shellpipe=\|&\ tee endif
Now the makeprg setting:
" Call appropriate makeprg with Ctrl+K map <C-K> :call Make()<CR> if $SOLARENV == "" " Normal makeprg, not in OpenOffice.org/StarOffice environment function Make() make endfun else " Special dmake, only in OpenOffice.org/StarOffice environment set makeprg=dmake function SetMakeprg() " For a detached gvim we need to source the environment, assuming " the current working directory being source/core/tool/ or " similar, and having a copy of the setsolar -file environment " file as module/../ENV.$INPATH or in $SRC_ROOT set a " ln -s LinuxX86Env.Set ENV.$INPATH " For terminal vim re-sourcing the environment isn't necessary. if has("gui_running") if filereadable( "./prj/d.lst" ) set makeprg=source\ ../ENV.$INPATH\ \&\&\ dmake\ wall=t\ debug=t\ ./$INPATH/slo/%:t:r.obj elseif filereadable( "../prj/d.lst" ) set makeprg=source\ ../../ENV.$INPATH\ \&\&\ dmake\ wall=t\ debug=t\ ../$INPATH/slo/%:t:r.obj elseif filereadable( "../../prj/d.lst" ) set makeprg=source\ ../../../ENV.$INPATH\ \&\&\ dmake\ wall=t\ debug=t\ ../../$INPATH/slo/%:t:r.obj elseif filereadable( "../../../prj/d.lst" ) set makeprg=source\ ../../../../ENV.$INPATH\ \&\&\ dmake\ wall=t\ debug=t\ ../../../$INPATH/slo/%:t:r.obj elseif filereadable( "../../../../prj/d.lst" ) set makeprg=source\ ../../../../../ENV.$INPATH\ \&\&\ dmake\ wall=t\ debug=t\ ../../../../$INPATH/slo/%:t:r.obj else set makeprg=source\ ./ENV.$INPATH\ \&\&\ dmake\ wall=t\ debug=t endif else if filereadable( "./prj/d.lst" ) set makeprg=dmake\ wall=t\ debug=t\ ./$INPATH/slo/%:t:r.obj elseif filereadable( "../prj/d.lst" ) set makeprg=dmake\ wall=t\ debug=t\ ../$INPATH/slo/%:t:r.obj elseif filereadable( "../../prj/d.lst" ) set makeprg=dmake\ wall=t\ debug=t\ ../../$INPATH/slo/%:t:r.obj elseif filereadable( "../../../prj/d.lst" ) set makeprg=dmake\ wall=t\ debug=t\ ../../../$INPATH/slo/%:t:r.obj elseif filereadable( "../../../../prj/d.lst" ) set makeprg=dmake\ wall=t\ debug=t\ ../../../../$INPATH/slo/%:t:r.obj else set makeprg=dmake\ wall=t\ debug=t endif endif " Just some copy&paste versions: " Entire module, edit ENV.... and set BUILD_COMMAND to content of build alias "set makeprg=source\ ../../../ENV.$INPATH\ \&\&\ $BUILD_COMMAND "set makeprg=source\ ../../../ENV.$INPATH\ \&\&\ dmake\ ../../../$INPATH/slo/%:t:r.obj "set makeprg=dmake\ product=full " temporary override, no wall, no debug "if filereadable( "./prj/d.lst" ) " set makeprg=dmake\ ./$INPATH/slo/%:t:r.obj "elseif filereadable( "../prj/d.lst" ) " set makeprg=dmake\ ../$INPATH/slo/%:t:r.obj "elseif filereadable( "../../prj/d.lst" ) " set makeprg=dmake\ ../../$INPATH/slo/%:t:r.obj "elseif filereadable( "../../../prj/d.lst" ) " set makeprg=dmake\ ../../../$INPATH/slo/%:t:r.obj "elseif filereadable( "../../../../prj/d.lst" ) " set makeprg=dmake\ ../../../../$INPATH/slo/%:t:r.obj "else " set makeprg=dmake "endif endfun function Make() let my_local_path = expand("%:h") if (my_local_path == "") let my_local_path = "." endif if filereadable( my_local_path . "/makefile.mk" ) exec 'lcd ' . my_local_path call SetMakeprg() make else echo "No makefile.mk in " . my_local_path endif endfun endif
CVS/SVN/HG integration
CVS/SVN/HG commands
vcscommand.vim - CVS/SVN integration plugin
A nice plugin to handle CVS, SVN and HG actions from within Vim. Most useful being the VCSAnnotate and VCSVimDiff commands, IMHO.
Resolve CVS conflicts
CVSconflict - CVS conflict resolution using vimdiff
A plugin that converts a source file containing CVS merge conflicts into two VimDiff buffers that then can be easily edited.
This also should work with inline Mercurial merge conflicts (no separate files created).
Resolve HG conflicts
See Mercurial wiki merging with vim and using Vim as the filemerge program for gvim diff.
Other useful plugins and resources
- OmniCppComplete - C++ completion omnifunc with a ctags database
- undo_tags - small utility that lets you tag undo branches
- erAck's VIM and related bookmarks
A note for developers on WIN\DOS
Please don't complicate life for developers on other platforms by interspersing sources with CarriageReturn characters before linefeeds, which especially is extremely nasty in patches contributed. As you probably can't patch your kernel's IO to simply not automatically write CrLf instead of Lf in text files, when using Vim use this setting:
"set fileformats=dos,unix " Vim's default on DOS/WIN/OS2 set fileformats=unix,dos " Vim's default on UNX, also use it on DOS