使用VIM可以格式化C++代码吗?

36

我对VIM还比较新手。我得到了一些源代码,但是一团糟。乍一看,我至少想清楚并组织好代码,所以我希望正确格式化它,我的意思是根据函数的深度进行缩进。

我想知道是否可以使用VIM完成,否则您可以推荐哪些其他命令行工具。

谢谢

9个回答

66

虽然vim是一个很好用的多功能工具,但在某些任务上我仍然更喜欢使用外部工具。这种方法有时比使用内置的功能更直观易记。

例如在缩进方面,我会通过astyle过滤整个文件缓冲区。相比于vim中的等效命令,astyle参数更容易掌握,特别是如果你不是vim专家的话。此外,astyle提供了更多细化输出的灵活性。

首先安装astyle:
# apt-get install astyle

然后在vim中执行以下操作:
:%!astyle (简单情况 - astyle默认模式为C/C++)

:%!astyle --mode=c --style=ansi -s2 (ansi C++风格,每个缩进级别使用两个空格)

:1,40!astyle --mode=c --style=ansi (ansi C++风格,仅过滤1-40行)


能否将此映射到像ctrl+shift+F这样的键组合? - danihodovic
5
你可以通过将equalprg设置为Astyle来覆盖Vim的缩进操作符(=),例如:set equalprg=~/astyle\ --style=google。这样做可以让Astyle替代Vim原本的缩进操作符。 - Parsa

37

你可以按照以下方式操作:

gg=G

1
澄清一下,=[motion]缩进了运动所包含的区域。gg移动到文件的开头,而G移动到文件的结尾。 - Sarah
3
或者以 V 开始进入可视行模式,然后使用 j 向下选择要格式化的所有行,最后按下 = - hasen
1
我不喜欢 gg=G。为什么?因为当你用逗号(参数列表、长布尔值)分隔长列表时,它会破坏手动对齐。 - Benoit

19

我强烈推荐现在使用clang-format。一旦你已经安装了clang-format,它允许将其简单地集成到Vim中:

http://clang.llvm.org/docs/ClangFormat.html#vim-integration

它是唯一真正理解你的C++代码的代码美化工具,它比机器更像人类智能地美化代码。例如:

void TestFunction(int argument1, int argument2,
                  int argument3);
void TestFunctionVeryLongName(int argument1,
                              int argument2,
                              int argument3);
void TestFunctionWithRidiculouslyLongName(
    int argument1, int argument2, int argument3);

2
在 clang-format 手册建议的按键绑定之外,另一种选择是在 vim 中使用 equalprg 绑定。这样可以使用 G=gg 或其他 = 缩进选项来调用 clang-format。只需将以下内容放入您的 .vimrc 文件中:`autocmd FileType c,cpp setlocal equalprg=clang-format` - Daniel

5

Vim一定可以做到这一点,尽管结果可能不完美:

  1. 首先,在可视模式下选择整个文件:ggVG
  2. 然后按=重新缩进所有内容。

您可以使用以下命令了解有关等号命令的更多信息::help =


5

有一个vim插件可以让你在vim内对代码进行格式化。它叫做vim-autoformat,你可以在这里下载:

https://github.com/vim-autoformat/vim-autoformat

它可以将外部的代码格式化程序集成到vim中。例如,如果你想格式化C、C++、C#或Java代码,你需要安装一个叫做astyle的程序,vim会自动将其设置为格式化程序。


4

2
我不写C++代码,但我会写一些Java代码。
相反,Vim支持格式化一些常见的语言。我已经设置了一个快捷键来格式化整个缓冲区的代码。它将返回到我刚编辑的那一行 :)
" format the file
map <leader>fm gg=G'. 

1
一个类似于m000的想法的通用解决方案是使用UniversalIndentGUI作为外部工具。

谢谢提供信息,但我更喜欢使用VIM,因为我需要在远程机器上调试代码。 - Open the way

0

我刚刚解决了这个问题,所以我想贡献一下,为了节省其他人的时间。

你可以使用gg=G来缩进你的代码。但是当你想调整自动缩进发生的方式时,事情变得难以理解。因此,如果你只关心消除错误的空格而不真正关心格式化样式,那么gg=G是最快的方法,因为它是内置的。

如果你确实想控制样式(例如,你正在尝试使你的代码符合样式指南),那么你需要一个外部工具来处理你的文件。你可以在vim中使用以下命令调用该工具::%!<toolname> <options>。这将通过该工具管道传输文件并重新加载处理后的结果。(你显然也可以用它来做任何你想对你的文件做的事情)

那么下一个问题是,你应该选择什么外部工具?无论如何,方法都是相同的:

  1. 安装所选工具
  2. 确保它在您的路径中
  3. 在您的vimrc文件中添加一行,创建一个快捷键以节省时间
  4. 使用它。

现在,您使用哪个工具取决于您要复制的样式。如果您想复制广泛使用的样式,那么astyle可能就是您需要的全部。

如果您想复制自定义样式,则需要两个东西:

  1. UniversalIndentGui - 一个前端,让您尝试各种选项并实时预览其对源文件的影响
  2. 一组已安装并在您的路径中的源代码格式化工具

uncrustifygreatcode之间,您应该能够完全复制您想要的样式。

实际上,我说谎了。还有一种方法,叫做clang-format。但是,你需要阅读关于它的文档,并且它仍处于早期阶段,因此某些选项不太好用。它是一个很棒的工具(绝对是最聪明的工具,因为它构建了您代码的AST),而且甚至适用于Windows。

如果你愿意花时间去阅读手册,你也可以看看GNU Indent

当然,还有最后一种方法,那就是实际上花时间学习vim的缩进规则,并为你的样式编写一个缩进规则。这需要时间,但是可以通过gg=G实现。

有关astyle vs uncrustify vs greatcode的一些注释:

  1. Astyle适用于一般格式化,但无法很好地对齐变量声明和重新格式化注释。
  2. Uncrustify可以做许多Astyle无法做到的事情,但要准备花费一个小时来尝试找到所需选项的正确组合。(或者如果你想浪费很多时间,使用遗传算法来找出最佳选项组合,以便你的风格,并在你分享代码时给我一个链接,这样我也可以使用它 :))

请注意,您不必选择一个工具。使用vim,您可以将一个按键映射为连续执行多个命令,因此理论上您可以使用这些工具的组合来获得您想要的精确效果。

最后,这是我的.vimrc文件的摘录,我已经将F12映射为使用某些选项调用astyle:

"A2 = attached brackets
"-s8 indent 8 spaces
"-xc attached braces to class declarations
"-xj remove braces for single statement ifs and elses
"-c convert tabs to spaces in the non-indentation part of the line
map <F12> :%!astyle -A2 -s8 -xc -xj -c<CR>

不要以样式来评判我。只需使用工具来复制您想要的内容。

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