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个字符就决定合并行。

- 有这种选择吗?-文件里没有我感兴趣的东西。

27840 次浏览

我没有看到任何目前在 文件允许你这样做。

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

我不确定 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

因此,在对 clang 格式代码进行了修改并做了一些补丁之后,我的建议是:

  • Clang 格式是基于,

    • 使用 libclang解析 AST,这基本上消除了所有空格
    • 将标记序列分解为“未包装的行”,类似于“逻辑”代码行
    • 应用规则/配置信息有时将“未包装的行”分割成更小的单元
    • 使用新的空格/缩进重新显示所有内容

    要让它尊重原始的白空间并不容易,因为当您第一次解析代码时,白空间会被丢弃。

  • 您可以控制它放置换行符的位置,最简单的方法是

    • 设置列限制
    • 使用“ bin pack 参数”选项
    • 为各种类型的中断设置惩罚——函数返回类型之后的中断、第一次调用参数之前的中断、字符串文字中断、注释中断... ..。
    • 将注释放在一行的末尾(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 超过这个值时,它通常不会对齐正确的列,它会在逗号后面放置固定数量的空格,而且对于这个问题你也无能为力。

或者,如果你有一个4x4的矩阵可以与 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 在这样的东西上运行,它只会破坏它们,而且 afak 没有简单的方法使它们格式化得很好,所以你只能求助于“很多琐碎的注释”黑客技术,或者在你有这样的东西时使用 clang-format off。这些只是该工具固有的局限性。如果你不喜欢做这样的事情,那么它可能不是你的工具。

在最后一个字符串后面加一个逗号。这告诉 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(); }

使用. clang-format 格式的这些规则

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

但是,如果您想将 ColumnLimit设置为非零值,那么它将无法工作:

  ValidateVisitor(clang::CompilerInstance *Compiler) :
Compiler(Compiler), Context(&Compiler->getASTContext()),
SM(&Context->getSourceManager()) {
}