Clang格式换行符

时间:2015-11-11 17:56:48

标签: c++ clang code-formatting clang-format

我正在寻找clang-format设置,以防止该工具删除换行符。

例如,我将ColumnLimit设置为120,这是我重新格式化一些示例代码时会发生的情况。

在:

#include <vector>
#include <string>

std::vector<std::string> get_vec()
{
   return std::vector<std::string> {
      "this is a test",
      "some of the lines are longer",
      "than other, but I would like",
      "to keep them on separate lines"
   };
}

int main()
{
   auto vec = get_vec();
}

后:

#include <vector>
#include <string>

std::vector<std::string> get_vec()
{
   return std::vector<std::string>{"this is a test", "some of the lines are longer", "than other, but I would like",
         "to keep them on separate lines"};
}

int main()
{
   auto vec = get_vec();
}

我想要的是该工具会破坏超过120个字符的行,但不会因为它们少于120个字符而决定合并行。

有这样的选择吗?文档中没有任何内容对我有用。

5 个答案:

答案 0 :(得分:34)

所以,在clang格式代码中弄乱并制作了一些补丁,这是我的两分钱:

  • Clang格式基于

    • 使用libclang解析AST,基本上消除了所有空格
    • 将令牌序列分解为&#34;未展开的行&#34;这就像&#34;逻辑&#34;代码行
    • 应用规则/配置信息有时会拆分&#34;展开的行&#34;成小单位
    • 用新的空格/缩进再次将它全部吐出来

    让它尊重原始的whitepsace并不容易,当你第一次解析代码时会被抛出。

  • 您可以通过

    来控制换行符的位置,最容易
    • 设置列限制
    • 使用&#34; bin pack参数&#34;选项
    • 设置各种中断的惩罚 - 在返回函数类型后中断,在第一个调用参数之前中断,中断字符串文字,中断注释...
    • 在一行的末尾放置注释(clang格式无法删除注释,因此必须拆分该行)
    • 使用clang-format off / on指令

这是你可以尝试的一件事:

std::vector<std::string> get_vec()
{
   return std::vector<std::string> {   //
      "this is a test",                //
      "some of the lines are longer",  //
      "than other, but I would like",  //
      "to keep them on separate lines" //
   };
}

优于// clang-format off的优点是,如果您稍后更改标签宽度或其他选项,那些代码行仍会获得这些格式更改,因此您无需手动进入// clang-format off区域来修复它。然而,它仍然是一个黑客,YMMV。

最终,clang-format非常关注在整个代码库中强制使用统一格式,确保所有字符串文字在程序的各个位置都以相同的样式格式化。如果您希望对换行决策进行微观级别控制,那么这并不是真正符合工具的精神,而且您必须执行禁用它的操作。

这有时令人沮丧。当你想用数组做事并使列对齐或某事时 - 例如,这里有一些来自lua C api的自然代码:

static luaL_Reg const methods[] = {
    {"matches",               &dispatch::intf_match_unit},
    {"to_recall",             &dispatch::intf_put_recall_unit},
    {"to_map",                &dispatch::intf_put_unit},
    {"erase",                 &dispatch::intf_erase_unit},
    {"clone",                 intf_copy_unit},
    {"extract",               &dispatch::intf_extract_unit},
    {"advance",               intf_advance_unit},
};

当clang-format运行时,它通常不会对齐右列,它会在逗号后面放置一定数量的空格,你可以做的不多它afaik。

或者,如果你有4 x 4矩阵用于OpenGL:

      constexpr float shadow_skew_hardcoded[16] =
        { 1.0f, 0.0f, 0.0f, 0.0f,
          0.5f, 0.5f, 0.0f, 0.0f,
          0.0f, 0.0f, 1.0f, 0.0f,
          0.0f, 0.0f, 0.0f, 1.0f };

如果你让clang-format运行这样的东西,它只会破坏它们,并且afaik那里没有简单的方法让它很好地格式化,所以你只需要求助于&#34;许多琐碎的评论&#34; hack,或者当你有这样的东西时使用clang-format。这些只是该工具的内在局限性。如果你不高兴做这样的事情,那么它可能不适合你。

答案 1 :(得分:14)

我不确定你是否格式化你想做什么,但是可以告诉clang-format单独保留代码段。我将此用于您正在谈论的那种场景,代码块,其中非常特殊的格式使其更易于阅读。

std::vector<std::string> get_vec()
{
   // clang-format off
   return std::vector<std::string> {
      "this is a test",
      "some of the lines are longer",
      "than other, but I would like",
      "to keep them on separate lines"
   };
   // clang-format on
}

请参阅: http://clang.llvm.org/docs/ClangFormatStyleOptions.html#disabling-formatting-on-a-piece-of-code

答案 2 :(得分:7)

我没有看到documentation中允许你这样做的任何内容。

将ColumnLimit设置为0仍将保留文本换行。

clang-format-mp-3.4 test.c -style="{ ColumnLimit: 0 }"

#include <vector>
#include <memory>
#include <string>

int main() {
  std::vector<std::string> vec = {
    "this is a test",
    "with some strings",
    "that I want on separate lines"
  };
}

答案 3 :(得分:0)

在最后一个字符串之后添加一个逗号。这告诉clang-format垂直格式化它。例如: https://godbolt.org/z/bZxr__右键单击>设置文本格式

#include <string>
#include <vector>

std::vector<std::string> get_vec() {
  return std::vector<std::string>{
      "this is a test",
      "some of the lines are longer",
      "than other, but I would like",
      "to keep them on separate lines", // comma here after last element
  };
}

int main() { auto vec = get_vec(); }

答案 4 :(得分:0)

使用 .clang 格式的这些规则

BasedOnStyle: LLVM
AlignAfterOpenBracket: AlwaysBreak
AllowShortBlocksOnASingleLine: Empty
BreakConstructorInitializers: AfterColon
BinPackArguments: false  // Important for this case
BinPackParameters: false  // Important for this case
AlignEscapedNewlines: DontAlign
SpacesBeforeTrailingComments: 2
AllowShortBlocksOnASingleLine: Never
AllowShortFunctionsOnASingleLine: None
ContinuationIndentWidth: 2
IndentWidth: 2
Standard: c++17
UseTab: Never

我得到的格式接近预期的结果

#include <string>
#include <vector>

std::vector<std::string> get_vec() {
  return std::vector<std::string>{
    "this is a test",
    "some of the lines are longer",
    "than other, but I would like",
    "to keep them on separate lines"};
}

int main() {
  auto vec = get_vec();
}