コンテンツにスキップ

UbuntuにClangFormatをインストール

ClangFormat

PlayGround

以下、または /tool/clang-format にて試すことが可能です。

パッケージリストを更新

インストール前の大切な作業です。

Terminal window
sudo apt update

clang-format をインストール

以下のコマンドでclang-formatをインストールします。

Terminal window
sudo apt install clang-format -y

使ってみる

main.cという名前のファイルを作成し、ソースコードを記述します。 ここでは変化を確認しやすくするために、読みづらいコードを書いています。

main.c
1
#include <stdio.h>
2
3
int main( void){
4
int a = -1;
5
for(int i=sizeof(a)* 8 - 1;i>=0;i--){printf("%d",(a>>i) &1);}
6
printf("\n");return 0;}

main.cを以下のコマンドでフォーマットします。

Terminal window
clang-format main.c
実行結果
1
#include <stdio.h>
2
3
int main(void) {
4
int a = -1;
5
for (int i = sizeof(a) * 8 - 1; i >= 0; i--) {
6
printf("%d", (a >> i) & 1);
7
}
8
printf("\n");
9
return 0;
10
}

以下のコマンドでmain.cを確認します。

Terminal window
cat main.c
実行結果
1
#include <stdio.h>
2
3
int main( void){
4
int a = -1;
5
for(int i=sizeof(a)* 8 - 1;i>=0;i--){printf("%d",(a>>i) &1);}
6
printf("\n");return 0;}

main.c自体は変更されていないことが確認できます。

なお、以下のように-iオプションを付けると、フォーマット後の内容がmain.cに上書きされます。

Terminal window
clang-format -i main.c

以下のコマンドでmain.cを確認します。

Terminal window
cat main.c
実行結果
1
#include <stdio.h>
2
3
int main(void) {
4
int a = -1;
5
for (int i = sizeof(a) * 8 - 1; i >= 0; i--) {
6
printf("%d", (a >> i) & 1);
7
}
8
printf("\n");
9
return 0;
10
}

スタイルをカスタマイズ

clang-formatはスタイルをカスタマイズすることができます。

参考: https://clang.llvm.org/docs/ClangFormatStyleOptions.html

--style="{key: value, ...}"のようにコマンドのオプションでスタイルを指定する方法と、.clang-formatまたは_clang-formatという名前で保存したファイルでスタイルを指定する方法があります。

コマンドのオプションでスタイルを指定

以下のコマンドでスタイルを指定してmain.cをフォーマットします。

Terminal window
clang-format --style="{BasedOnStyle: GNU, IndentWidth: 4}" main.c
実行結果
1
#include <stdio.h>
2
3
int
4
main (void)
5
{
6
int a = -1;
7
for (int i = sizeof (a) * 8 - 1; i >= 0; i--)
8
{
9
printf ("%d", (a >> i) & 1);
10
}
11
printf ("\n");
12
return 0;
13
}

.clang-format でスタイルを指定

以下のような.clang-formatファイルを作成します。

.clang-format
1
BasedOnStyle: GNU
2
IndentWidth: 4

以下のコマンドでmain.cをフォーマットします。

Terminal window
clang-format main.c
実行結果
1
#include <stdio.h>
2
3
int
4
main (void)
5
{
6
int a = -1;
7
for (int i = sizeof (a) * 8 - 1; i >= 0; i--)
8
{
9
printf ("%d", (a >> i) & 1);
10
}
11
printf ("\n");
12
return 0;
13
}

.clang-format を作成するコマンド

以下のコマンドで.clang-formatファイルを作成することができます。

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

以下のコマンドで.clang-formatファイルの内容を表示します。

Terminal window
cat .clang-format
.clang-format
1
---
2
Language: Cpp
3
# BasedOnStyle: LLVM
4
AccessModifierOffset: -2
5
AlignAfterOpenBracket: Align
186行の折りたたみ
6
AlignArrayOfStructures: None
7
AlignConsecutiveMacros: None
8
AlignConsecutiveAssignments: None
9
AlignConsecutiveBitFields: None
10
AlignConsecutiveDeclarations: None
11
AlignEscapedNewlines: Right
12
AlignOperands: Align
13
AlignTrailingComments: true
14
AllowAllArgumentsOnNextLine: true
15
AllowAllParametersOfDeclarationOnNextLine: true
16
AllowShortEnumsOnASingleLine: true
17
AllowShortBlocksOnASingleLine: Never
18
AllowShortCaseLabelsOnASingleLine: false
19
AllowShortFunctionsOnASingleLine: All
20
AllowShortLambdasOnASingleLine: All
21
AllowShortIfStatementsOnASingleLine: Never
22
AllowShortLoopsOnASingleLine: false
23
AlwaysBreakAfterDefinitionReturnType: None
24
AlwaysBreakAfterReturnType: None
25
AlwaysBreakBeforeMultilineStrings: false
26
AlwaysBreakTemplateDeclarations: MultiLine
27
AttributeMacros:
28
- __capability
29
BinPackArguments: true
30
BinPackParameters: true
31
BraceWrapping:
32
AfterCaseLabel: false
33
AfterClass: false
34
AfterControlStatement: Never
35
AfterEnum: false
36
AfterFunction: false
37
AfterNamespace: false
38
AfterObjCDeclaration: false
39
AfterStruct: false
40
AfterUnion: false
41
AfterExternBlock: false
42
BeforeCatch: false
43
BeforeElse: false
44
BeforeLambdaBody: false
45
BeforeWhile: false
46
IndentBraces: false
47
SplitEmptyFunction: true
48
SplitEmptyRecord: true
49
SplitEmptyNamespace: true
50
BreakBeforeBinaryOperators: None
51
BreakBeforeConceptDeclarations: true
52
BreakBeforeBraces: Attach
53
BreakBeforeInheritanceComma: false
54
BreakInheritanceList: BeforeColon
55
BreakBeforeTernaryOperators: true
56
BreakConstructorInitializersBeforeComma: false
57
BreakConstructorInitializers: BeforeColon
58
BreakAfterJavaFieldAnnotations: false
59
BreakStringLiterals: true
60
ColumnLimit: 80
61
CommentPragmas: '^ IWYU pragma:'
62
QualifierAlignment: Leave
63
CompactNamespaces: false
64
ConstructorInitializerIndentWidth: 4
65
ContinuationIndentWidth: 4
66
Cpp11BracedListStyle: true
67
DeriveLineEnding: true
68
DerivePointerAlignment: false
69
DisableFormat: false
70
EmptyLineAfterAccessModifier: Never
71
EmptyLineBeforeAccessModifier: LogicalBlock
72
ExperimentalAutoDetectBinPacking: false
73
PackConstructorInitializers: BinPack
74
BasedOnStyle: ''
75
ConstructorInitializerAllOnOneLineOrOnePerLine: false
76
AllowAllConstructorInitializersOnNextLine: true
77
FixNamespaceComments: true
78
ForEachMacros:
79
- foreach
80
- Q_FOREACH
81
- BOOST_FOREACH
82
IfMacros:
83
- KJ_IF_MAYBE
84
IncludeBlocks: Preserve
85
IncludeCategories:
86
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
87
Priority: 2
88
SortPriority: 0
89
CaseSensitive: false
90
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
91
Priority: 3
92
SortPriority: 0
93
CaseSensitive: false
94
- Regex: '.*'
95
Priority: 1
96
SortPriority: 0
97
CaseSensitive: false
98
IncludeIsMainRegex: '(Test)?$'
99
IncludeIsMainSourceRegex: ''
100
IndentAccessModifiers: false
101
IndentCaseLabels: false
102
IndentCaseBlocks: false
103
IndentGotoLabels: true
104
IndentPPDirectives: None
105
IndentExternBlock: AfterExternBlock
106
IndentRequires: false
107
IndentWidth: 2
108
IndentWrappedFunctionNames: false
109
InsertTrailingCommas: None
110
JavaScriptQuotes: Leave
111
JavaScriptWrapImports: true
112
KeepEmptyLinesAtTheStartOfBlocks: true
113
LambdaBodyIndentation: Signature
114
MacroBlockBegin: ''
115
MacroBlockEnd: ''
116
MaxEmptyLinesToKeep: 1
117
NamespaceIndentation: None
118
ObjCBinPackProtocolList: Auto
119
ObjCBlockIndentWidth: 2
120
ObjCBreakBeforeNestedBlockParam: true
121
ObjCSpaceAfterProperty: false
122
ObjCSpaceBeforeProtocolList: true
123
PenaltyBreakAssignment: 2
124
PenaltyBreakBeforeFirstCallParameter: 19
125
PenaltyBreakComment: 300
126
PenaltyBreakFirstLessLess: 120
127
PenaltyBreakOpenParenthesis: 0
128
PenaltyBreakString: 1000
129
PenaltyBreakTemplateDeclaration: 10
130
PenaltyExcessCharacter: 1000000
131
PenaltyReturnTypeOnItsOwnLine: 60
132
PenaltyIndentedWhitespace: 0
133
PointerAlignment: Right
134
PPIndentWidth: -1
135
ReferenceAlignment: Pointer
136
ReflowComments: true
137
RemoveBracesLLVM: false
138
SeparateDefinitionBlocks: Leave
139
ShortNamespaceLines: 1
140
SortIncludes: CaseSensitive
141
SortJavaStaticImport: Before
142
SortUsingDeclarations: true
143
SpaceAfterCStyleCast: false
144
SpaceAfterLogicalNot: false
145
SpaceAfterTemplateKeyword: true
146
SpaceBeforeAssignmentOperators: true
147
SpaceBeforeCaseColon: false
148
SpaceBeforeCpp11BracedList: false
149
SpaceBeforeCtorInitializerColon: true
150
SpaceBeforeInheritanceColon: true
151
SpaceBeforeParens: ControlStatements
152
SpaceBeforeParensOptions:
153
AfterControlStatements: true
154
AfterForeachMacros: true
155
AfterFunctionDefinitionName: false
156
AfterFunctionDeclarationName: false
157
AfterIfMacros: true
158
AfterOverloadedOperator: false
159
BeforeNonEmptyParentheses: false
160
SpaceAroundPointerQualifiers: Default
161
SpaceBeforeRangeBasedForLoopColon: true
162
SpaceInEmptyBlock: false
163
SpaceInEmptyParentheses: false
164
SpacesBeforeTrailingComments: 1
165
SpacesInAngles: Never
166
SpacesInConditionalStatement: false
167
SpacesInContainerLiterals: true
168
SpacesInCStyleCastParentheses: false
169
SpacesInLineCommentPrefix:
170
Minimum: 1
171
Maximum: -1
172
SpacesInParentheses: false
173
SpacesInSquareBrackets: false
174
SpaceBeforeSquareBrackets: false
175
BitFieldColonSpacing: Both
176
Standard: Latest
177
StatementAttributeLikeMacros:
178
- Q_EMIT
179
StatementMacros:
180
- Q_UNUSED
181
- QT_REQUIRE_VERSION
182
TabWidth: 8
183
UseCRLF: false
184
UseTab: Never
185
WhitespaceSensitiveMacros:
186
- STRINGIZE
187
- PP_STRINGIZE
188
- BOOST_PP_STRINGIZE
189
- NS_SWIFT_NAME
190
- CF_SWIFT_NAME
191
...

TheAlgorithms のスタイル

https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/.clang-format

個人的に好きなスタイルです。

.clang-format
1
---
2
Language: Cpp
3
AccessModifierOffset: -3
4
AlignAfterOpenBracket: Align
5
AlignConsecutiveMacros: true
161行の折りたたみ
6
AlignConsecutiveAssignments: false
7
AlignConsecutiveDeclarations: false
8
AlignEscapedNewlines: Left
9
AlignOperands: true
10
AlignTrailingComments: true
11
AllowAllArgumentsOnNextLine: true
12
AllowAllConstructorInitializersOnNextLine: true
13
AllowAllParametersOfDeclarationOnNextLine: true
14
AllowShortBlocksOnASingleLine: Never
15
AllowShortCaseLabelsOnASingleLine: false
16
AllowShortFunctionsOnASingleLine: All
17
AllowShortLambdasOnASingleLine: All
18
AllowShortIfStatementsOnASingleLine: Never
19
AllowShortLoopsOnASingleLine: true
20
AlwaysBreakAfterDefinitionReturnType: None
21
AlwaysBreakAfterReturnType: None
22
AlwaysBreakBeforeMultilineStrings: true
23
AlwaysBreakTemplateDeclarations: Yes
24
BinPackArguments: true
25
BinPackParameters: true
26
BraceWrapping:
27
AfterCaseLabel: false
28
AfterClass: false
29
AfterControlStatement: false
30
AfterEnum: false
31
AfterFunction: false
32
AfterNamespace: false
33
AfterObjCDeclaration: false
34
AfterStruct: false
35
AfterUnion: false
36
AfterExternBlock: false
37
BeforeCatch: false
38
BeforeElse: false
39
IndentBraces: false
40
SplitEmptyFunction: true
41
SplitEmptyRecord: true
42
SplitEmptyNamespace: true
43
BreakBeforeBinaryOperators: None
44
BreakBeforeBraces: Attach
45
BreakBeforeInheritanceComma: false
46
BreakInheritanceList: BeforeColon
47
BreakBeforeTernaryOperators: true
48
BreakConstructorInitializersBeforeComma: false
49
BreakConstructorInitializers: BeforeColon
50
BreakAfterJavaFieldAnnotations: false
51
BreakStringLiterals: true
52
ColumnLimit: 80
53
CommentPragmas: '^ IWYU pragma:'
54
CompactNamespaces: false
55
ConstructorInitializerAllOnOneLineOrOnePerLine: true
56
ConstructorInitializerIndentWidth: 4
57
ContinuationIndentWidth: 4
58
Cpp11BracedListStyle: true
59
DeriveLineEnding: true
60
DerivePointerAlignment: true
61
DisableFormat: false
62
ExperimentalAutoDetectBinPacking: false
63
FixNamespaceComments: true
64
ForEachMacros:
65
- foreach
66
- Q_FOREACH
67
- BOOST_FOREACH
68
IncludeBlocks: Regroup
69
IncludeCategories:
70
- Regex: '^<ext/.*\.h>'
71
Priority: 2
72
SortPriority: 0
73
- Regex: '^<.*\.h>'
74
Priority: 1
75
SortPriority: 0
76
- Regex: '^<.*'
77
Priority: 2
78
SortPriority: 0
79
- Regex: '.*'
80
Priority: 3
81
SortPriority: 0
82
IncludeIsMainRegex: '([-_](test|unittest))?$'
83
IncludeIsMainSourceRegex: ''
84
IndentCaseLabels: true
85
IndentGotoLabels: true
86
IndentPPDirectives: None
87
IndentWidth: 4
88
IndentWrappedFunctionNames: false
89
JavaScriptQuotes: Leave
90
JavaScriptWrapImports: true
91
KeepEmptyLinesAtTheStartOfBlocks: false
92
MacroBlockBegin: ''
93
MacroBlockEnd: ''
94
MaxEmptyLinesToKeep: 1
95
NamespaceIndentation: None
96
ObjCBinPackProtocolList: Never
97
ObjCBlockIndentWidth: 2
98
ObjCSpaceAfterProperty: false
99
ObjCSpaceBeforeProtocolList: true
100
PenaltyBreakAssignment: 2
101
PenaltyBreakBeforeFirstCallParameter: 1
102
PenaltyBreakComment: 300
103
PenaltyBreakFirstLessLess: 120
104
PenaltyBreakString: 1000
105
PenaltyBreakTemplateDeclaration: 10
106
PenaltyExcessCharacter: 1000000
107
PenaltyReturnTypeOnItsOwnLine: 200
108
PointerAlignment: Left
109
RawStringFormats:
110
- Language: Cpp
111
Delimiters:
112
- cc
113
- CC
114
- cpp
115
- Cpp
116
- CPP
117
- 'c++'
118
- 'C++'
119
CanonicalDelimiter: ''
120
BasedOnStyle: google
121
- Language: TextProto
122
Delimiters:
123
- pb
124
- PB
125
- proto
126
- PROTO
127
EnclosingFunctions:
128
- EqualsProto
129
- EquivToProto
130
- PARSE_PARTIAL_TEXT_PROTO
131
- PARSE_TEST_PROTO
132
- PARSE_TEXT_PROTO
133
- ParseTextOrDie
134
- ParseTextProtoOrDie
135
CanonicalDelimiter: ''
136
BasedOnStyle: google
137
ReflowComments: true
138
SortIncludes: true
139
SortUsingDeclarations: true
140
SpaceAfterCStyleCast: false
141
SpaceAfterLogicalNot: false
142
SpaceAfterTemplateKeyword: true
143
SpaceBeforeAssignmentOperators: true
144
SpaceBeforeCpp11BracedList: false
145
SpaceBeforeCtorInitializerColon: true
146
SpaceBeforeInheritanceColon: true
147
SpaceBeforeParens: ControlStatements
148
SpaceBeforeRangeBasedForLoopColon: true
149
SpaceInEmptyBlock: false
150
SpaceInEmptyParentheses: false
151
SpacesBeforeTrailingComments: 2
152
SpacesInAngles: false
153
SpacesInConditionalStatement: false
154
SpacesInContainerLiterals: true
155
SpacesInCStyleCastParentheses: false
156
SpacesInParentheses: false
157
SpacesInSquareBrackets: false
158
SpaceBeforeSquareBrackets: false
159
Standard: Auto
160
StatementMacros:
161
- Q_UNUSED
162
- QT_REQUIRE_VERSION
163
TabWidth: 4
164
UseCRLF: false
165
UseTab: Never
166
...

以下のコマンドでダウンロードできます。

Terminal window
curl -OL https://raw.githubusercontent.com/TheAlgorithms/C-Plus-Plus/master/.clang-format

優先順位

  1. コマンドのオプションでスタイルを指定した場合: そのスタイルが優先されます。

  2. コマンドのオプションでスタイルを指定しなかった場合: .clang-formatファイルの内容が優先されます。

    • 入力ファイルの最も近い親ディレクトリにある.clang-formatファイルを探そうとします。

例えば、以下のようなディレクトリ構造があるとします。

Terminal window
/home/ubuntu
├── .clang-format
├── cpp
│   ├── _clang-format
│   ├── main.cpp
│   └── test
│   └── test.cpp
└── main.c

clang-format /home/ubuntu/main.cを実行した場合、/home/ubuntu/.clang-formatが優先されます。

clang-format /home/ubuntu/cpp/main.cppを実行した場合、/home/ubuntu/cpp/_clang-formatが優先されます。

clang-format /home/ubuntu/cpp/test/test.cppを実行した場合、/home/ubuntu/cpp/_clang-formatが優先されます。

なお、clang-format --style=file:設定ファイル プログラムとすることで、指定した設定ファイルを使ってプログラムをフォーマットすることができます。

/home/ubuntu/cpp/test/test.cpp/home/ubuntu/.clang-formatの設定を適用するには、以下のようにします。

Terminal window
clang-format --style=file:/home/ubuntu/.clang-format /home/ubuntu/cpp/test/test.cpp

vim で使う

~/.vimrcに以下の設定を追加すると、vimでファイルを保存するたびにclang-formatが実行されます。

~/.vimrc
1
let g:clang_format_cmd = 'clang-format'
2
3
function! FormatOnSave()
4
execute '%!'.g:clang_format_cmd
5
endfunction
6
7
autocmd BufWritePre *.c *.c++ *.cc *.cpp *.cu *.cuh *.cxx *.h *.h++ *.hh *.hpp *.hxx call FormatOnSave()