4

I want my C code indented as follows:

switch (x)
{
    case 1:
        break;
    case 2:
    {
        break;
    }
}

Instead of this:

switch (x)
{
    case 1:
        break;
    case 2:
        {
            break;
        }
}

I looked through cinoptions, but didn't find what I need. I'm looking for some options I missed or other indentation script.

Thanks in advance

  • I guess brackets ate optional for case blocks so you can avoid them. – SibiCoder Jul 11 '16 at 3:37
  • 3
    @SibiCoder: I don't think it's the point of the question. – nobe4 Jul 11 '16 at 7:57
2

I don't think it's possible as is, you can work around that though.


For your current example you can set

:set  cino={-s

This will reindent each {/} pair found to reduce the shift width setting. This will work on the example you gave:

switch (x)
{
  case 1:
    break;
  case 2:
  {
      break;
  }
}

But not on an example with more complex syntax:

switch (x)
{
  case 1:
    break;
  case 2:
  {
      break;
      if( 1 )
    {
        //stuff
    }
  }
}

Apparently, by looking at :h cindent, Vim prefers the curly brace on the same line as the statement.

So I would recommand using the following formatting instead:

switch (x) {

  case 1:
    break;

  case 2: {
    break;
  }

}

With this, you can set cino=l1 and indent will be:

switch (x) {

  case 1:
    break;

  case 2: {
    break;
  }

}

Again, it might not suit your coding style but AFAIK, it the best way to properly indent the case statement.

0

I finally came up with a solution with custom indent script:

setlocal comments=s1:/*,mb:*,ex:*/

setlocal cindent
setlocal cinoptions=Ls,t0,(0

setlocal indentexpr=GetCaseBlockCorrectedIndent()
setlocal indentkeys=!^F,0{,0},0),0#,o,O,e,:

function! s:PrevNonBlankOrComment(startlnum)
    let lnum = a:startlnum
    while lnum > 0
        let lnum = prevnonblank(lnum)
        if (getline(lnum) =~ '^\s*\(/\|\*\)')
            let lnum -= 1
        else
            break
        endif
    endwhile
    return lnum
endfunction

function! GetCaseBlockCorrectedIndent()
    let lnum = v:lnum
    let prevlnum = s:PrevNonBlankOrComment(lnum - 1)
    let idnt = cindent(v:lnum)
    let adj = 0
    if getline(prevlnum) =~ '^\s*case\>' && getline(lnum) =~ '^\s*{'
       let adj = -&shiftwidth
    endif
    return idnt + adj
endfunction
  • I desire the same indenting, but this solution doesn't work for multiple scoped cases. Does that work for you? (I tried vim with just vim-sensible and this code, but no luck.) – idbrii Sep 5 '18 at 18:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.