On Wed, 7 Oct 2009 04:51:36 -0700 (PDT), bradphelan wrote:
> 
> Hi,
> 
> I can't figure out how to customize cindent to achieve the following.
> Lists are arranged vertically so that the
> first and last bracket are aligned with each comma. Does anybody have
> an idea.
> 
> const int foo
>     ( int a
>     , int b
>     , std::string c
>     )
> {
>     // stuff
> }
> 
> 
> Regards
> 
> Brad Phelan

I asked this question some time ago on the list, and the general answer was 
that there is no way short of writing your own indent function. As a result I 
came up with the following function which solves this problem (as well as a few 
other indenting quirks I've grown used to).

I put it into a file called cpp.vim in my ~/.vim/after/indent directory (as I 
use it for C++ files - call it c.vim if you want it for C files, and remove the 
stuff about output operators :-) ):

-------8<-------------8<--------------------------
" Modified indent function for C++ files.
"
" This is designed to fix some faults in the built-in VIm cindent() function. In
" particular, it formats lists of parameters with one parameter per line, and
" with a leading ',' on the line, so that the commas all line up below the
" corresponding open parenthesis
"
" It also lines up multi-line i/o operations, so the leading '<<' or '>>' all
" appear lined up below each other.
"
"   What we do depends on the following:
"   If current line's first non-blank char is ','
"       If prior line's first non-blank char is not ','
"           use cindent-2
"       Endif
"   Else If first non-blank char is '<' or '>'
"       If next char matches first non-blank
"           Look for the first occurence of the same token on prior line
"           and use that as the indent.
"       Endif
"   Else
"       If prior line ends in '('
"           use cindent+1
"       Else If prior line ends in '='
"           use cindent+4
"       Else
"           use cindent
"       Endif
"   Endif
"
if (!exists("*CppIndentDepth"))
    function CppIndentDepth()
        let lnum=v:lnum
        let ind=cindent(lnum)
        let inum=match(getline("."), "\\S")
        let ichar=getline(".")[inum]
        let rind=ind
        if ichar == ','
            if getline(lnum-1)[ind] != ','
                let rind = (ind - 2)
            endif
        elseif ichar =~ '[<>]'
            if getline(".")[inum+1] == ichar
                let matchit = ichar . ichar
                let pos = match(getline(line(".")-1), matchit)
                if pos != -1
                    let rind = pos
                endif
            endif
        else
            let pline = getline(lnum-1)
            let lastnb = matchstr(pline, "\\S\\s*$")[0]
            if lastnb == '('
                let rind = ind + 1
            elseif lastnb == '='
                let rind = ind + 4
            endif
        endif
        return rind
    endfunction
endif

set indentexpr=CppIndentDepth()
-------8<-------------8<--------------------------

It's not perfect by any means (in particular, when you first enter the code it 
doesn't seem to line up properly, but is fine once it's reformatted), but it 
does the job for me.

Spencer

-- 
<<< Eagles may soar, but weasels don't get sucked into jet engines >>>
5:28pm up 40 days 23:24, 1 user, load average: 1.36, 1.46, 1.48
Registered Linux User #232457 | LFS ID 11703

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Reply via email to