I've been searching hard, but not finding terribly useful results for
the following problem. The problem is this: most of my labmates use
emacs and specific java formatting rules (simple in emacs). I need to
duplicate said rules (and have succeeded for most), but I'm not sure
how to automatically indent argument lists and nested bracket
structures. Switch-case also screws up when brackets are involved.
e.g. say I write
------------------------------------------------------
double[][] gpsToMeters = {{1,2,3},
{1,2,3},
{1,2,3},
{1,2,3}};
------------------------------------------------------
or
------------------------------------------------------
functionCallWithManyArguments(abc,
def,
ghi);
------------------------------------------------------
(hopefully spaces indented sufficiently)
I want the inner brackets to be vertically aligned, as well as the
first character in the argument list. According to my labmate, the
relevant operator in emacs is 'arglist-cont-nonempty'. I have tried
searching with many queries suggesting the same idea, for vim, but I'm
coming up dry and could really use some advice. I could hand-indent,
if I remember, but that seems pretty unnecessary.
Below are images showing the formatting results. The order is {guide
1, vim 1, guide 2, vim 2}
http://i.imgur.com/cxmfq.png
http://i.imgur.com/nEiAK.png
http://i.imgur.com/rGiFw.png
http://i.imgur.com/uRJCc.png
I hope you can help! Thanks for your time.
-chardson
On Jan 6, 1:27 am, chardson <a.chard...@gmail.com> wrote:
> Greetings all,
>
> I've been searching hard, but not finding terribly useful results for
> the following problem. The problem is this: most of my labmates use
> emacs and specific java formatting rules (simple in emacs). I need to
> duplicate said rules (and have succeeded for most), but I'm not sure
> how to automatically indent argument lists and nested bracket
> structures. Switch-case also screws up when brackets are involved.
>
> e.g. say I write
>
> ------------------------------------------------------
>
> double[][] gpsToMeters = {{1,2,3},
> {1,2,3},
> {1,2,3},
> {1,2,3}};
>
> ------------------------------------------------------
>
> or
>
> ------------------------------------------------------
>
> functionCallWithManyArguments(abc,
> def,
> ghi);
>
> ------------------------------------------------------
> (hopefully spaces indented sufficiently)
>
> I want the inner brackets to be vertically aligned, as well as the
> first character in the argument list.
For Java, C, C++, etc., the relevant option on Vim is 'cinoptions'
which controls the behavior of 'cindent'. 'cindent' is designed for C
code, but also used in Java, C++, and other similar languages. :help
'cinoptions-values' and :help 'cinoptions' will allow you to find what
you need.
Thanks much
My cinoptions are now "l1,(0,u0,j1"
The result, then, is
http://i.imgur.com/AYmcS.png
http://i.imgur.com/nqWuk.png
I haven't managed to find a solution for the nested {} list (matrix
format), nor do I know why the third case statement indents more than
the rest.
Does anyone know what statement I've misinterpreted? I've now read
the cinoptions help a number of times (and done my share of google
searches)
On Jan 11, 10:54 am, chardson <a.chard...@gmail.com> wrote:
> I've spent a fair amount of time reading and playing with cinoptions,
> which has solved some of my problems
>
> My cinoptions are now "l1,(0,u0,j1"
>
> The result, then, is
> http://i.imgur.com/AYmcS.png
> http://i.imgur.com/nqWuk.png
>
> I haven't managed to find a solution for the nested {} list (matrix
> format), nor do I know why the third case statement indents more than
> the rest.
>
> Does anyone know what statement I've misinterpreted? I've now read
> the cinoptions help a number of times (and done my share of google
> searches)
>
Hmm, I admit I didn't look in detail at your problem to ensure that it
could be solved by 'cinoptions', that was just my first (and probably
the easiest) solution that came to mind.
Unfortunately after reviewing the various settings, I don't think this
is possible with just an option tweak.
It IS possible if you override the indent plugin of the java filetype.
I suggest defining your own function and placing it in ~/.vim/after/
indent/java.vim
Also in this file, set the indentexpr option (locally) to your
function.
This function will return the value of GetJavaIndent() under most
circumstances, but you can then override this value in the specific
cases you need.
See :help 'indentexpr' for help in creating this function. You will
need to find a way to match the specific cases you are looking for.
Sadly, this may not be easy to set up, but once it is, you don't need
to do it again.
This is what I have for C files, but I did it long enough ago that I
cannot for the life of me remember what it is for or how it works
without studying it for a while. It may be helpful as a starting
point, but no guarantees:
==============$HOME/vimfiles/after/indent/c.vim===================
" special indenting (indent to the unmatched paren or bracket)
" autoload only supported in version 7 and above
if v:version>=701
let s:comment_text = '^\s*\*.*\|//.*\|/\*\%(\%(\*/\)\@!.\)*'
let &l:indentexpr="max([".(&indentexpr ? &indentexpr : -1).",
indent#OpenBracketAlign('".s:comment_text."')])"
unlet s:comment_text
endif
" cindent will use these values to do parenthesis-alignment.
setlocal cinoptions+=(0
setlocal cinoptions+=W2s
==============$HOME/vimfiles/autoload/indent.vim==================
" align the indent just after the last unclosed paren in the line
above,
" unless that parenthesis is contained in a comment.
"
" pass in a pattern to match text to be treated as a comment
function! indent#OpenParenAlign(comment_text)
let aboveLineNum=line('.')-1
if aboveLineNum < 1
return -1
else
" remove parentheses from comment text (keeping line the same
length)
let aboveLine=getline(aboveLineNum)
let aboveLine=
\ substitute(aboveLine,
\ a:comment_text,
\ substitute(submatch(0), '[()]', 'x', 'g'),
\ 'g')
" remove all matched parentheses from the line (keeping same line
length)
let aboveLineOld=aboveLine
let aboveLine=substitute(aboveLineOld,'(\([^()]*\))','x\1x','g')
while aboveLine!=aboveLineOld
let aboveLineOld=aboveLine
let aboveLine=substitute(aboveLineOld,'(\([^()]*\))','x\1x','g')
endwhile
" find position of last opening paren in the line - indent will be
just
" after this if it exists
let parenPos=match(aboveLine,'([^(]*$')
if parenPos==-1
if &cindent
return cindent('.')
else
return -1
endif
else
return parenPos+1
endif
endif
endfunction
" align the indent just after the last unclosed square bracket in the
line above
" unless that parenthesis is contained in a comment.
"
" pass in a pattern to match text to be treated as a comment
function! indent#OpenBracketAlign(comment_text)
let aboveLineNum=line('.')-1
if aboveLineNum < 1
return -1
else
" remove brackets from comment text (keeping line the same length)
let aboveLine=getline(aboveLineNum)
let aboveLine=
\ substitute(aboveLine,
\ a:comment_text,
\ substitute(submatch(0), '[][])]', 'x', 'g'),
\ 'g')
" remove all matched brackets from the line (keeping same line
length)
let aboveLineOld=aboveLine
let aboveLine=substitute(aboveLineOld,'\[\([^[\]]*\)\]','x
\1x','g')
while aboveLine!=aboveLineOld
let aboveLineOld=aboveLine
let aboveLine=substitute(aboveLineOld,'\[\([^[\]]*\)\]','x
\1x','g')
endwhile
" find position of last opening bracket in the line - indent will
be just
" after this if it exists
let bracketPos=match(aboveLine,'\[[^[]*$')
if bracketPos==-1
if &cindent
return cindent('.')
else
return -1
endif
else
return bracketPos+1
endif
endif
endfunction
I should mention:
This will NOT be a drop-in solution for you, it is for a different
file type, and solves an entirely different problem (one that I don't
even remember having, it's been in my config for so long). I included
it as an example of the method that you may be able to expand on and
possibly borrow some technique. I vaguely remember crafting this when
I wanted similar indent for array indices like this:
if (NULL != biglongarrayname[4 * (somevar + othervar) /
anotherbigvarname]
[(CONST_VAL << varshift) &
BIG_LONG_MASK_NAME_TAKING_UP_SPACE])
dosomething();