Vim和C++11 Lambda:自动缩进

20

在C++11的lambda函数中使用vim实际上效果很差。缩进不起作用,许多括号被标记为错误。

我知道C和C++的缩进和语法高亮是通过内部编程而不是通过c[...].vim文件实现的。有没有可能为C++11设置vim,特别是对于带有lambda函数的源代码?也许有人可以提示如何在内部vim语法检查中添加lambda解析。

编辑:(根据评论要求的示例代码)

代码应该类似于以下示例,但格式为单列。

  MyLoop( [](int a, int b){
        {       
            ::i++;
            for (;;)
            {   
                SomeFunc();
            }   
            cout << "Result: " << a*b<<endl;
        }       
    });    

更新vim 7.4版本: 现在,vim不再将lambda表达式视为错误,但它仍然没有对lambda表达式进行任何缩进处理,所以仍然不能用于c++ :-(

顺便问一句:有没有好的自动格式化工具可以添加到vim环境中,这样按下一个键就能进行外部格式化呢?


1
https://dev59.com/kXA85IYBdhLWcg3wBO3h - u0b34a0f6ae
你能否添加一个示例,说明它是如何缩进的以及你希望它如何缩进? - Alex
6个回答

23

Vim 7.4现在有一个jN的cinoption选项,用于“正确缩进Java匿名类”。 (:help java-cinoptions) 这将改善C++11lambda表达式的缩进行为。

使用以下选项(放在您的~/.vim/after/ftplugin/cpp.vim中):

setlocal cindent cino=j1,(0,ws,Ws

如果我将您的for循环的左花括号放在同一行(否则就太疯狂了),那么vim会像这样缩进您的代码:

MyLoop( [](int a, int b){
    {       
        ::i++;
        for (;;) {   
            SomeFunc();
        }   
        cout << "Result: " << a*b<<endl;
    }       
});   

它也不能提供你想要的悬挂缩进。如果将初始打开大括号移到自己的一行中,那么就可以得到所需的悬挂缩进。

有关所有选项,请参见:help cinoptions-values


如果您想要一个更智能的缩进程序,这个用户推荐使用set equalprg=clang-format来使用ClangFormat,以便=ip会缩进当前段落。这不会使vim在输入时正确缩进(您需要设置indentexpr,并且那很复杂)。

还有一个vim插件,似乎与设置equalprg相同,但代码更多。不确定它是否更好。它被认为是clang-format.py(来自Cyprian Guerra的答案)的替代品。


2
不错。如果您不想创建~/.vim/after/ftplugin/cpp.vim文件,也可以在.vimrc中添加以下行: autocmd BufEnter *.cpp :setlocal cindent cino=j1,(0,ws,Ws - jmmk
我已将 setlocal cindent cino=j1,(0,ws,Ws 添加到了我的 ~/.vimrc 中,它有效了,谢谢! - schneiderfelipe
1
@FelipeS.S.Schneider:因为你在没有ftplugin或autocmd的情况下使用了setlocal,这只适用于您编辑的第一个文件。使用set将其设置为所有文件的默认值(仍可能被ftplugin覆盖- 在此处查看有关此的帮助)。 - idbrii

1

使用

:let c_no_curly_error = 1

你可以将它放入你的vimrc文件中。

至于你的假设,是错误的。在vim运行时中有一个语法文件。你可以在:help c.vim中看到参考和在你的vim运行时路径中查找实现(:echo &rtp)。


这个解决方案可以去除放错位置的括号,但这不是我想要的。缩进仍然是错误的。 - Klaus
1
虽然有一个C语法文件,但缩进是在内部完成的,这似乎是OP帖子中重要的问题。 - dash-tom-bang

1

这里有一个由Michael Small创建的this项目。我还没有尝试过,但也许这正是你正在寻找的。


1
安装了这些新的语法文件后,我不再有错误的大括号了,但是对于lambda函数来说,缩进仍然是错误的。 - Klaus

0
你似乎在寻找的是来自LLVM团队的clang-format.py或者来自Linda_pp a.k.a. rhysd(感谢idbrii提供后者)的vim-clang-format - 两者都使用clang,因此都支持所有C++11的新结构,并且可以按照以下方式运行:
:pyf ~/src/llvm.git/tools/clang/tools/clang-format/clang-format.py

或者:ClangFormat

后者似乎更好,因为它(除了其他功能之外)允许遵循“每个环境使用相同行为的一个配置文件”规则,特别是当您使用VIM附加管理器(例如VAM)时。


1
vim-clang-format声称是clang-format.py的一个更好的替代品。不确定哪个比equalprg更好。 - idbrii
clang-format 修改了大量与缩进无关的格式,这并不总是可取的。 - pavon

0

设置智能缩进和自动缩进。

在vim中输入上述代码后,您将获得正确的缩进。

但是,如果您使用gg=G或包含“=”的命令重新缩进上述代码,则缩进仍然不正确。


gg=G是该功能的重要部分 :-) 而且红色标记的大括号也不太美观。好吧,如上所述,我可以抑制所有有关错误大括号的警告,但这也没有什么帮助。我真的很想知道为什么没有人为vim实现正确的缩进文件。我实际上只运行外部格式化程序,这真的很愚蠢!是vim过时了还是c++11不经常使用?现在已经两年没有解决这个问题了...顺便说一句:初始化列表在vim中也有问题 :-( - Klaus

0

我刚刚为此苦苦挣扎了几天,看起来在启用 cindent 的情况下切换 smartindent 帮助了我解决 C++11 中的 lambda 缩进问题。

在你的 ~/.vimrc 文件中:

set cindent
set smartindent

希望这能帮助大家。


我没有看到任何改变。lambda表达式内部的所有缩进仍然是错误的。所有的大括号都移到了同一列。你能展示一下你设置的缩进是什么样子吗? - Klaus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接