clang-format配置与使用
clang-format配置与使用
参考教程.
1. 安装
下载clang-format
,设置环境变量。我使用的是vscode扩展中的clang-format
。
位于: extensions/ms-vscode.cpptools-1.7.0-insiders/bin/
。
将程序放置到系统边境变量的路径中,或者将软件路径添加到系统环境变量。
2. 配置
--style=
指定配置文件。不指定将使用默认配置。默认情况下会先从当前目录寻找 .clang-format
配置文件。这个配置有点弱智,难道就不能指定路径吗?
因此,自己定义的配置只能通过将.clang-format
放置到需要格式化文件的路径下。因此,通过脚本或者程序的方式来复制配置文件到工作目录中。并在格式化完成后将其移除,这样可以不在工作目录下引入新的文件。
使用 Go
来完成这个任务。(成功掌握可变参数和信道的使用-.-)
package main
import (
"fmt"
log "fmt"
"io"
"os"
"os/exec"
"path/filepath"
"runtime"
)
func main() {
clang_format_process(os.Args...)
}
func clang_format_process(args ...string) {
conf_dir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
work_dir, _ := os.Getwd()
if conf_dir == work_dir {
if os := runtime.GOOS; os == "linux" {
conf_dir = filepath.Clean("/usr/local/sbin/clang_format_config.d")
} else if os == "windows" {
conf_dir = filepath.Clean("D:\\Program Files\\app")
}
}
work_dir_config := filepath.Join(work_dir, ".clang-format")
var config string = "config/.clang-format"
conf_dir_config := filepath.Join(conf_dir, filepath.Clean(config)) /* 使用clean生成与平台无关的路径 */
/* 根据不同的平台选择不同的格式化工具 */
var tool_dir string
switch os := runtime.GOOS; os {
case "windows":
tool_dir = filepath.Join(conf_dir, "bin/clang-format.exe")
case "linux":
tool_dir = filepath.Join(conf_dir, "bin/clang-format")
}
if _, err := os.Stat(tool_dir); err != nil {
log.Println("Error: no such file: ", tool_dir)
return
}
// is_custom := flag.Bool("nc", false, "custom argurement lists")
// flag.Parse()
if len(os.Args) <= 1 {
log.Println("Usage: \nclang_format_custom file.c file1.c\nor clang_format_custom -nc (= clang-format[.exe] )")
return
}
// 使用-cu参数,请删除true和修改os.Args[2:]
if os.Args[1] != "-nc" {
arg_pos := 1
print_args(os.Args[1:]...)
if _, err := os.Stat(work_dir_config); err == nil {
log.Println(work_dir_config)
log.Println(".clang-format has existed.")
return
}
/* 复制配置文件当工作目录中 */
if _, err := copy(conf_dir_config, work_dir_config); err != nil {
log.Println(err)
}
ch := make(chan int)
for _, arg := range os.Args[arg_pos:] {
go clang_format_exec(ch, tool_dir, work_dir, arg)
}
// 阻塞在此,等待所有goroutine完成
for i := arg_pos; i < len(os.Args); i++ {
<-ch
}
os.Remove(work_dir_config)
return
} else {
cmd := exec.Command(tool_dir, os.Args[2:]...) /* 不使用自定义参数时,直接调用clang-format */
output, err := cmd.CombinedOutput()
if err != nil {
log.Println(err)
}
fmt.Print(string(output))
return
}
}
func print_args(args ...string) {
log.Println("----------args list--------------")
for _, arg := range args {
log.Println(arg)
}
log.Println("-------------end-----------------")
}
func clang_format_exec(ch chan int, tool_dir, work_dir, file string) {
log.Println("format ", file)
cmd := exec.Command(tool_dir, "-i", file)
err := cmd.Run()
if err != nil {
log.Println(err)
}
ch <- 1
}
func copy(src, dst string) (int64, error) {
sourceFileStat, err := os.Stat(src)
if err != nil {
return 0, err
}
if !sourceFileStat.Mode().IsRegular() {
return 0, fmt.Errorf("%s is not a regular file", src)
}
source, err := os.Open(src)
if err != nil {
return 0, err
}
defer source.Close()
destination, err := os.Create(dst)
if err != nil {
return 0, err
}
defer destination.Close()
nBytes, err := io.Copy(destination, source)
return nBytes, err
}
程序目录结构:
.
├── bin
│ ├── clang-format
│ └── clang-format.exe
├── clang_format_custom
├── clang_format_custom.exe
├── config
├── .clang-format
└── .clang-format_backup
执行结果:
好了,宏定义对齐终于酸爽了。根据自己的喜好配置.clang-format
配置文件。我的配置如下:
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: true
AlignConsecutiveAssignments: true
AlignConsecutiveBitFields: true
AlignConsecutiveDeclarations: true
AlignEscapedNewlines: Right
AlignOperands: Align
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortEnumsOnASingleLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: false
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Allman
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: 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
SortPriority: 0
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
- Regex: '.*'
Priority: 1
SortPriority: 0
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentCaseLabels: false
IndentCaseBlocks: false
IndentGotoLabels: true
IndentPPDirectives: None
IndentExternBlock: AfterExternBlock
IndentWidth: 4
IndentWrappedFunctionNames: false
InsertTrailingCommas: None
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
Standard: Latest
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 4
UseCRLF: false
UseTab: Never
WhitespaceSensitiveMacros:
- STRINGIZE
- PP_STRINGIZE
- BOOST_PP_STRINGIZE
...