67

我正在寻找一种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 个字符而决定合并行。

有这样的选择吗?文档中的任何内容对我来说都没有什么突出的。

4

5 回答 5

54

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

  • Clang 格式基于,

    • 使用 解析AST libclang,这基本上消除了所有空格
    • 将令牌序列分解为“展开的行”,就像“逻辑”代码行
    • 应用规则/配置信息有时将“展开的行”拆分为更小的单元
    • 用新的空格/缩进再次吐出它

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

  • 您可以通过以下方式最轻松地控制换行符的位置

    • 设置列限制
    • 使用“bin 包参数”选项
    • 为各种中断设置惩罚——在函数的返回类型之后中断,在第一次调用参数之前中断,中断字符串文字,中断注释......
    • 将注释放在行尾(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区域来修复它。然而,它仍然是一个 hack,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超过它时,它通常不会对齐右列,它会在逗号之后放置固定数量的空格,并且你无能为力。

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

      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 没有简单的方法可以很好地格式化它们,所以你只需要求助于“很多琐碎的评论”黑客,或者使用当你有这样的东西时关闭clang-format。这些只是该工具的内在限制。如果您对不得不做这样的事情感到不高兴,那么它可能不适合您。

于 2015-12-18T19:11:11.280 回答
18

我不确定您的 clang-format 是否完全符合您的要求,但可以告诉 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

于 2015-12-18T10:12:52.400 回答
15

在最后一个字符串后添加逗号。这告诉 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(); }
于 2019-05-29T08:36:11.353 回答
10

我目前在文档中没有看到任何 允许您这样做的内容。

将 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"
  };
}
于 2015-12-17T16:20:10.707 回答
1

使用 .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();
}
于 2021-08-05T19:38:02.607 回答