views:

369

answers:

3

How to set vim to not indent namespace content in C++?

namespace < identifier >
{
    < statement_list > // Unwanted indentation
}

Surprisingly, 'cinoptions' doesn't provide a way to edit namespace content indentation.

+1  A: 

I use cpp.vim which is inspired by the Google C++ Style Guide. Among other things, that script does what you're asking.

Whisty
+7  A: 

cpp.vim will solve your problem, but if you don't want the full-blown Google coding style then just take a peek at the plugin source and see how it handles namespaces. It's super simple:

function! IndentNamespace()
  let l:cline_num = line('.')
  let l:pline_num = prevnonblank(l:cline_num - 1)
  let l:pline = getline(l:pline_num)
  let l:retv = cindent('.')
  while l:pline =~# '\(^\s*{\s*\|^\s*//\|^\s*/\*\|\*/\s*$\)'
    let l:pline_num = prevnonblank(l:pline_num - 1)
    let l:pline = getline(l:pline_num)
  endwhile
  if l:pline =~# '^\s*namespace.*'
    let l:retv = 0
  endif
  return l:retv
endfunction

setlocal indentexpr=IndentNamespace()

In essence all you do is match the last non-blank line against /^\s*namespace/, and if it matches return 0 (as the indent position for indentexpr); otherwise return Vim's builtin cindent mechanism's value.

I essentially stole the code from the plugin, stripped anything that isn't namespace-related and renamed the indent function to IndentNamespace(). Save this as ~/.vim/indent/cpp.vim.

wilhelmtell
Since I place the opening curly bracket at the line below the namespace declaration this code doesn't work. It finds { at the previous non-blank line. Still, it is a great solution.
freitass
Ah, you're right. I think I trimmed too much form the plugin. :s Try again now. The fix will ignore any comments or scope braces after the namespace line.
wilhelmtell
I'm sorry taking so long to answer. Just tried your new solution but it still didn't work. The "full-blown" Google coding style script you suggested also didn't work. I don't know why yet.
freitass
A: 

I've configured vim to not indent for the namespace. These are the relevant lines in my vimrc:

autocmd Filetype cpp set shiftwidth=2
set cino=>2(0^-2g0h2

Frankly, I don't remember how to interpet the cino statement, but :help cinoptions should help in deciphering it. One caveat: I think it's configured to not indent when using a format like so:

namespace foo 
{ // <- curly bracket on next line
...

versus

namespace foo { // <- same line

Since I put the curly bracket on the next line exclusively for namespaces, it does what I want, but it might not work if you use that style for other function declarations, for, etc.

dimatura
Like I said, 'cinoptions' (long for 'cino'), inherently, won't make it. From the lines you have pasted, '^-2' combined with 'shiftwidth=2' removes the indentation of namespace contents, but it also removes the indentation of every block with an opening curly brace at column 0.
freitass
Yes, that's the case. The cpp.vim solution looks better and I'm incorporating in my vim config just now :)
dimatura