clang-format

Clang 13 documentation


自定义


注意的问题

在clang-format version 7.0.1-8+deb10u2版本下,ColumnLimit不能随意设值。12.0版本下已经没有这个问题。

安装最新版本

Debian安装说明

$ 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;
}