clang-format 使用介绍

9,479 阅读1分钟

clang-format

介绍

该程序能够自动化格式 C/C++/Obj-C 代码,支持多种代码风格:Google, Chromium, LLVM, Mozilla, WebKit,也支持自定义 style(通过编写 .clang-format 文件)。

安装

  • linux

    sudo apt install clang-format
    
  • mac

    brew install clang-format
    

安装完后,将该 bin 档目录添加到 user PATH 中。输入如下命令,查下版本信息:

  • linux/mac

     clang-format --version
    

结果可能如下:

image-20200505000416583

  • windows

    clang-format.exe --version
    

结果可能如下:

image-20200519143752621

不同版本程序对应不同版本文档,当前程序版本为9.0,故需要查看9.0文档

使用

  1. 直接使用内置 style,比如 LLVM,Google 等,命令为如下形式:

    clang-format -style=llvm -i xxx.c
    
  2. 使用自定义 style 文件 .clang-format,程序会先查询当前目录是否有 .clang-format 文件,若没找到,则会递归往父目录查找,一般是放在 project 根目录(闲懒可以直接放在 $HOME 目录),命令为如下形式:

    clang-format -style=file -i xxx.c
    

集成

许多编辑器通过插件的方式可以集成 clang-format,比如 vim,vs code,source insight 等。

vim

  1. 通过 vim-plug 或者 vundle 插件管理器安装 vim-autoformat

  2. 配置一下 vim-autoformat,如下:

    let g:formatdef_my_clang = '"clang-format"'
    let g:formatters_cpp = ['my_clang']
    let g:formatters_c = ['my_clang']
    noremap <F9> :Autoformat<cr>
    

    按下 F9,即可对用 vim 打开的当前文件使用自定义 style 文件 .clang-format 格式化代码(当前目录或者更上级目录要存在 .clang-format)。

vs code

  1. 安装如下 extension(这个应该是必装插件了)

    image-20200519162152152

  2. 打开 File->Preferences->Settings,搜索 format,作下图设置:

    image-20200519163021991

    image-20200519163219396

    这样只要保存(ctrl+s)就会调用 clang-format.exe 去格式化代码了(当前目录或者更上级目录要存在 .clang-format)。

source insight

  1. 在工具栏的 Options 或者 Tools 找到 Custom Commands

    image-20200519145248180

  2. 点击 Add,填入 clang-format 命令名,点击 OK

    image-20200519150505258

  3. Run 编辑框输入 "D:\LLVM\bin\clang-format.exe" -style=file -fallback-style=none -i %f,勾选 Save Files FirstWait Until Done

    image-20200519145738184

  4. 为该命令分配快捷键,点击 Custom Commands 页面右下角 Keys...,选择刚才创建好的 Custom Cmd: clang-format,点击 Assign New Key,此时你可以敲自己喜欢的快捷键,比如 Ctrl+Alt+F,最后点击 OK 就大功告成

    image-20200519150948608

  5. 敲第4步定义的快捷键,就可以对当前的文件格式化了(当前目录或者更上级目录要存在 .clang-format)。

自定义配置文件.clang-format

先导出一份llvm的模板:

clang-format -style=llvm -dump-config > .clang-format

在此基础上修改如下:

Language:        Cpp
# BasedOnStyle:  LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Left
AlignOperands:   true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BreakBeforeBraces: custom
BraceWrapping:
  AfterClass:      true
  AfterControlStatement: true
  AfterEnum:       true
  AfterFunction:   true
  AfterNamespace:  true
  AfterObjCDeclaration: true
  AfterStruct:     true
  AfterUnion:      true
  AfterExternBlock: true
  BeforeCatch:     true
  BeforeElse:      true
  IndentBraces:    true
  SplitEmptyFunction: true
  SplitEmptyRecord: true
  SplitEmptyNamespace: true
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Allman
BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: false
ColumnLimit:     128
CommentPragmas:  '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat:   false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
  - foreach
  - Q_FOREACH
  - BOOST_FOREACH
IncludeBlocks:   Preserve
IncludeCategories:
  - Regex:           '^"(llvm|llvm-c|clang|clang-c)/'
    Priority:        2
  - Regex:           '^(<|"(gtest|gmock|isl|json)/)'
    Priority:        3
  - Regex:           '.*'
    Priority:        1
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: true
IndentPPDirectives: None
IndentWidth:     4
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd:   ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments:  true
SortIncludes:    false
SortUsingDeclarations: false
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles:  false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard:        Cpp11
TabWidth:        4
UseTab:          Never
...