Does anyone have or know about vim plugin/macro/function that indents nicely c++ templates?
When I highlight template definition in vim .hpp/.h file and indent it with '=' I get something like this:
> template <
> class TFilter,
> class TParser,
> class TConsumer,
> class TDataProcessor,
> class TDataFeed,
> class TSymbolMap
> >
> struct DataFeedTraits
> {
> typedef TFilter Filter;
> typedef TParser<TSymbolMap> Parser;
> typedef TConsumer<Parser> Consumer;
> typedef TDataProcessor<Filter,Consumer> DataProcessor;
> typedef TDataFeed<Filter,DataProcessor,Parser,Ccnsumer> DataFeed;
> };
I think the cindent aligns the struct/class declaration with the closing bracket '>'. I would like to end up with something like this, or similar, exact formatting does not matter, as far as it is formatted:
template <
class TFilter,
class TParser,
class TConsumer,
class TDataProcessor,
class TDataFeed,
class TSymbolMap
>
struct DataFeedTraits
{
typedef TFilter Filter;
typedef TParser<TSymbolMap> Parser;
typedef TConsumer<Parser> Consumer;
typedef TDataProcessor<Filter,Consumer> DataProcessor;
typedef TDataFeed<Filter,DataProcessor,Parser,Ccnsumer> DataFeed;
};
My solution:
" Don't indent namespace and template
function! CppNoNamespaceAndTemplateIndent()
let l:cline_num = line('.')
let l:cline = getline(l:cline_num)
let l:pline_num = prevnonblank(l:cline_num - 1)
let l:pline = getline(l:pline_num)
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
let l:retv = cindent('.')
let l:pindent = indent(l:pline_num)
if l:pline =~# '^\s*template\s*\s*$'
let l:retv = l:pindent
elseif l:pline =~# '\s*typename\s*.*,\s*$'
let l:retv = l:pindent
elseif l:cline =~# '^\s*>\s*$'
let l:retv = l:pindent - &shiftwidth
elseif l:pline =~# '\s*typename\s*.*>\s*$'
let l:retv = l:pindent - &shiftwidth
elseif l:pline =~# '^\s*namespace.*'
let l:retv = 0
endif
return l:retv
endfunction
if has("autocmd")
autocmd BufEnter *.{cc,cxx,cpp,h,hh,hpp,hxx} setlocal indentexpr=CppNoNamespaceAndTemplateIndent()
endif
You can use the identexpr option to specify indent by evaluating an expression (i.e. writing a vim script function). This function should accept a string -- the line -- and return the number of spaces to indent. This gives you the flexibility to return an indent level for this template condition, or fall-back to autoindent, smartindent or cindent in normal, C-like situations.
Here is an example that was created to handle the signals and slots extension of Qt. It demonstrates fall-back to the cindent function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With