Vim 缩进 c++ 模板?

发布于 2024-07-09 23:42:22 字数 1434 浏览 5 评论 0原文

有谁知道或知道 vim 插件/宏/函数可以很好地缩进 c++ 模板吗?

当我在 vim .hpp/.h 文件中突出显示模板定义并用“=”缩进时,我得到这样的结果:

>     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;
>                   };

我认为 cindent 将结构/类声明与右括号“>”对齐。 我想最终得到这样的结果,或者类似的结果,只要它被格式化,精确的格式并不重要:

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;
};

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;
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

长梦不多时 2024-07-16 23:42:22

我的解决方案:

" 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

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
红焚 2024-07-16 23:42:22

您可以使用 identexpr 选项通过评估 < a href="http://vimdoc.sourceforge.net/htmldoc/indent.html#indent-expression" rel="nofollow noreferrer">表达式(即编写vim脚本函数)。 这个函数应该接受一个字符串——行——并返回要缩进的空格数。 这使您可以灵活地返回此模板条件的缩进级别,或回退到 自动缩进smartindentcindent 在正常的、类似 C 的情况下。

这是一个为处理 Qt 的信号和槽扩展而创建的示例。 它演示了 cindent 函数的回退。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文