Editor Vim

From Apache OpenOffice Wiki
Revision as of 17:44, 4 January 2011 by ErAck (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

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.


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


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
Personal tools