clang-format
clang-format
自定义
注意的问题
在clang-format version 7.0.1-8+deb10u2版本下,ColumnLimit不能随意设值。12.0版本下已经没有这个问题。
安装最新版本
$ sudo vi /etc/apt/sources.list.d/llvm.conf
deb http://apt.llvm.org/buster/ llvm-toolchain-buster-12 main
deb-src http://apt.llvm.org/buster/ llvm-toolchain-buster-12 main
$ wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
$ sudo apt update
$ sudo apt-cache search clang-format
arcanist-clang-format-linter - clang-format linter for Arcanist
clang-format - Tool to format C/C++/Obj-C code
clang-format-6.0 - Tool to format C/C++/Obj-C code
clang-format-7 - Tool to format C/C++/Obj-C code
clang-format-11 - Tool to format C/C++/Obj-C code
clang-format-8 - Tool to format C/C++/Obj-C code
clang-format-12 - Tool to format C/C++/Obj-C code
clang-format-12-dbgsym - debug symbols for clang-format-12
禁用clang-format的方法
当引入第三方开源代码时,往往不希望对其格式化,以免以后代码比较起来麻烦。
_clang-format / .clang-format
DisableFormat: true
如何实现全局配置
clang-format如何配置系统全局的样式文件(.clang-format),以下是clang-format获取style部分的代码。
clang-format会依据代码文件的路径以及迭代父目录以查找.clang-format和_clang-format文件名提取自定义style。
所以只要把.clang-format配置文件放到系统根目录(/.clang-format)下就可以实现全局引用。
FormatStyle getStyle(StringRef StyleName, StringRef FileName,
StringRef FallbackStyle) {
FormatStyle Style = getLLVMStyle();
Style.Language = getLanguageByFileName(FileName);
if (!getPredefinedStyle(FallbackStyle, Style.Language, &Style)) {
llvm::errs() << "Invalid fallback style \"" << FallbackStyle
<< "\" using LLVM style\n";
return Style;
}
if (StyleName.startswith("{")) {
// Parse YAML/JSON style from the command line.
if (std::error_code ec = parseConfiguration(StyleName, &Style)) {
llvm::errs() << "Error parsing -style: " << ec.message() << ", using "
<< FallbackStyle << " style\n";
}
return Style;
}
if (!StyleName.equals_lower("file")) {
if (!getPredefinedStyle(StyleName, Style.Language, &Style))
llvm::errs() << "Invalid value for -style, using " << FallbackStyle
<< " style\n";
return Style;
}
// Look for .clang-format/_clang-format file in the file's parent directories.
SmallString<128> UnsuitableConfigFiles;
SmallString<128> Path(FileName);
llvm::sys::fs::make_absolute(Path);
for (StringRef Directory = Path; !Directory.empty();
Directory = llvm::sys::path::parent_path(Directory)) {
if (!llvm::sys::fs::is_directory(Directory))
continue;
SmallString<128> ConfigFile(Directory);
llvm::sys::path::append(ConfigFile, ".clang-format");
DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
bool IsFile = false;
// Ignore errors from is_regular_file: we only need to know if we can read
// the file or not.
llvm::sys::fs::is_regular_file(Twine(ConfigFile), IsFile);
if (!IsFile) {
// Try _clang-format too, since dotfiles are not commonly used on Windows.
ConfigFile = Directory;
llvm::sys::path::append(ConfigFile, "_clang-format");
DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
llvm::sys::fs::is_regular_file(Twine(ConfigFile), IsFile);
}
if (IsFile) {
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
llvm::MemoryBuffer::getFile(ConfigFile.c_str());
if (std::error_code EC = Text.getError()) {
llvm::errs() << EC.message() << "\n";
break;
}
if (std::error_code ec =
parseConfiguration(Text.get()->getBuffer(), &Style)) {
if (ec == ParseError::Unsuitable) {
if (!UnsuitableConfigFiles.empty())
UnsuitableConfigFiles.append(", ");
UnsuitableConfigFiles.append(ConfigFile);
continue;
}
llvm::errs() << "Error reading " << ConfigFile << ": " << ec.message()
<< "\n";
break;
}
DEBUG(llvm::dbgs() << "Using configuration file " << ConfigFile << "\n");
return Style;
}
}
llvm::errs() << "Can't find usable .clang-format, using " << FallbackStyle
<< " style\n";
if (!UnsuitableConfigFiles.empty()) {
llvm::errs() << "Configuration file(s) do(es) not support "
<< getLanguageName(Style.Language) << ": "
<< UnsuitableConfigFiles << "\n";
}
return Style;
}