UbuntuにClangFormatをインストール
ClangFormat
PlayGround
以下、または /tool/clang-format にて試すことが可能です。
パッケージリストを更新
インストール前の大切な作業です。
sudo apt update
clang-format をインストール
以下のコマンドでclang-format
をインストールします。
sudo apt install clang-format -y
使ってみる
main.c
という名前のファイルを作成し、ソースコードを記述します。
ここでは変化を確認しやすくするために、読みづらいコードを書いています。
1#include <stdio.h>2
3int main( void){4 int a = -1;5 for(int i=sizeof(a)* 8 - 1;i>=0;i--){printf("%d",(a>>i) &1);}6printf("\n");return 0;}
main.c
を以下のコマンドでフォーマットします。
clang-format main.c
1#include <stdio.h>2
3int 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
を確認します。
cat main.c
1#include <stdio.h>2
3int main( void){4 int a = -1;5 for(int i=sizeof(a)* 8 - 1;i>=0;i--){printf("%d",(a>>i) &1);}6printf("\n");return 0;}
main.c
自体は変更されていないことが確認できます。
なお、以下のように-i
オプションを付けると、フォーマット後の内容がmain.c
に上書きされます。
clang-format -i main.c
以下のコマンドでmain.c
を確認します。
cat main.c
1#include <stdio.h>2
3int 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
をフォーマットします。
clang-format --style="{BasedOnStyle: GNU, IndentWidth: 4}" main.c
1#include <stdio.h>2
3int4main (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
ファイルを作成します。
1BasedOnStyle: GNU2IndentWidth: 4
以下のコマンドでmain.c
をフォーマットします。
clang-format main.c
1#include <stdio.h>2
3int4main (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 --style=llvm -dump-config > .clang-format
以下のコマンドで.clang-format
ファイルの内容を表示します。
cat .clang-format
1---2Language: Cpp3# BasedOnStyle: LLVM4AccessModifierOffset: -25AlignAfterOpenBracket: Align186行の折りたたみ
6AlignArrayOfStructures: None7AlignConsecutiveMacros: None8AlignConsecutiveAssignments: None9AlignConsecutiveBitFields: None10AlignConsecutiveDeclarations: None11AlignEscapedNewlines: Right12AlignOperands: Align13AlignTrailingComments: true14AllowAllArgumentsOnNextLine: true15AllowAllParametersOfDeclarationOnNextLine: true16AllowShortEnumsOnASingleLine: true17AllowShortBlocksOnASingleLine: Never18AllowShortCaseLabelsOnASingleLine: false19AllowShortFunctionsOnASingleLine: All20AllowShortLambdasOnASingleLine: All21AllowShortIfStatementsOnASingleLine: Never22AllowShortLoopsOnASingleLine: false23AlwaysBreakAfterDefinitionReturnType: None24AlwaysBreakAfterReturnType: None25AlwaysBreakBeforeMultilineStrings: false26AlwaysBreakTemplateDeclarations: MultiLine27AttributeMacros:28 - __capability29BinPackArguments: true30BinPackParameters: true31BraceWrapping:32 AfterCaseLabel: false33 AfterClass: false34 AfterControlStatement: Never35 AfterEnum: false36 AfterFunction: false37 AfterNamespace: false38 AfterObjCDeclaration: false39 AfterStruct: false40 AfterUnion: false41 AfterExternBlock: false42 BeforeCatch: false43 BeforeElse: false44 BeforeLambdaBody: false45 BeforeWhile: false46 IndentBraces: false47 SplitEmptyFunction: true48 SplitEmptyRecord: true49 SplitEmptyNamespace: true50BreakBeforeBinaryOperators: None51BreakBeforeConceptDeclarations: true52BreakBeforeBraces: Attach53BreakBeforeInheritanceComma: false54BreakInheritanceList: BeforeColon55BreakBeforeTernaryOperators: true56BreakConstructorInitializersBeforeComma: false57BreakConstructorInitializers: BeforeColon58BreakAfterJavaFieldAnnotations: false59BreakStringLiterals: true60ColumnLimit: 8061CommentPragmas: '^ IWYU pragma:'62QualifierAlignment: Leave63CompactNamespaces: false64ConstructorInitializerIndentWidth: 465ContinuationIndentWidth: 466Cpp11BracedListStyle: true67DeriveLineEnding: true68DerivePointerAlignment: false69DisableFormat: false70EmptyLineAfterAccessModifier: Never71EmptyLineBeforeAccessModifier: LogicalBlock72ExperimentalAutoDetectBinPacking: false73PackConstructorInitializers: BinPack74BasedOnStyle: ''75ConstructorInitializerAllOnOneLineOrOnePerLine: false76AllowAllConstructorInitializersOnNextLine: true77FixNamespaceComments: true78ForEachMacros:79 - foreach80 - Q_FOREACH81 - BOOST_FOREACH82IfMacros:83 - KJ_IF_MAYBE84IncludeBlocks: Preserve85IncludeCategories:86 - Regex: '^"(llvm|llvm-c|clang|clang-c)/'87 Priority: 288 SortPriority: 089 CaseSensitive: false90 - Regex: '^(<|"(gtest|gmock|isl|json)/)'91 Priority: 392 SortPriority: 093 CaseSensitive: false94 - Regex: '.*'95 Priority: 196 SortPriority: 097 CaseSensitive: false98IncludeIsMainRegex: '(Test)?$'99IncludeIsMainSourceRegex: ''100IndentAccessModifiers: false101IndentCaseLabels: false102IndentCaseBlocks: false103IndentGotoLabels: true104IndentPPDirectives: None105IndentExternBlock: AfterExternBlock106IndentRequires: false107IndentWidth: 2108IndentWrappedFunctionNames: false109InsertTrailingCommas: None110JavaScriptQuotes: Leave111JavaScriptWrapImports: true112KeepEmptyLinesAtTheStartOfBlocks: true113LambdaBodyIndentation: Signature114MacroBlockBegin: ''115MacroBlockEnd: ''116MaxEmptyLinesToKeep: 1117NamespaceIndentation: None118ObjCBinPackProtocolList: Auto119ObjCBlockIndentWidth: 2120ObjCBreakBeforeNestedBlockParam: true121ObjCSpaceAfterProperty: false122ObjCSpaceBeforeProtocolList: true123PenaltyBreakAssignment: 2124PenaltyBreakBeforeFirstCallParameter: 19125PenaltyBreakComment: 300126PenaltyBreakFirstLessLess: 120127PenaltyBreakOpenParenthesis: 0128PenaltyBreakString: 1000129PenaltyBreakTemplateDeclaration: 10130PenaltyExcessCharacter: 1000000131PenaltyReturnTypeOnItsOwnLine: 60132PenaltyIndentedWhitespace: 0133PointerAlignment: Right134PPIndentWidth: -1135ReferenceAlignment: Pointer136ReflowComments: true137RemoveBracesLLVM: false138SeparateDefinitionBlocks: Leave139ShortNamespaceLines: 1140SortIncludes: CaseSensitive141SortJavaStaticImport: Before142SortUsingDeclarations: true143SpaceAfterCStyleCast: false144SpaceAfterLogicalNot: false145SpaceAfterTemplateKeyword: true146SpaceBeforeAssignmentOperators: true147SpaceBeforeCaseColon: false148SpaceBeforeCpp11BracedList: false149SpaceBeforeCtorInitializerColon: true150SpaceBeforeInheritanceColon: true151SpaceBeforeParens: ControlStatements152SpaceBeforeParensOptions:153 AfterControlStatements: true154 AfterForeachMacros: true155 AfterFunctionDefinitionName: false156 AfterFunctionDeclarationName: false157 AfterIfMacros: true158 AfterOverloadedOperator: false159 BeforeNonEmptyParentheses: false160SpaceAroundPointerQualifiers: Default161SpaceBeforeRangeBasedForLoopColon: true162SpaceInEmptyBlock: false163SpaceInEmptyParentheses: false164SpacesBeforeTrailingComments: 1165SpacesInAngles: Never166SpacesInConditionalStatement: false167SpacesInContainerLiterals: true168SpacesInCStyleCastParentheses: false169SpacesInLineCommentPrefix:170 Minimum: 1171 Maximum: -1172SpacesInParentheses: false173SpacesInSquareBrackets: false174SpaceBeforeSquareBrackets: false175BitFieldColonSpacing: Both176Standard: Latest177StatementAttributeLikeMacros:178 - Q_EMIT179StatementMacros:180 - Q_UNUSED181 - QT_REQUIRE_VERSION182TabWidth: 8183UseCRLF: false184UseTab: Never185WhitespaceSensitiveMacros:186 - STRINGIZE187 - PP_STRINGIZE188 - BOOST_PP_STRINGIZE189 - NS_SWIFT_NAME190 - CF_SWIFT_NAME191...
TheAlgorithms のスタイル
https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/.clang-format
個人的に好きなスタイルです。
1---2Language: Cpp3AccessModifierOffset: -34AlignAfterOpenBracket: Align5AlignConsecutiveMacros: true161行の折りたたみ
6AlignConsecutiveAssignments: false7AlignConsecutiveDeclarations: false8AlignEscapedNewlines: Left9AlignOperands: true10AlignTrailingComments: true11AllowAllArgumentsOnNextLine: true12AllowAllConstructorInitializersOnNextLine: true13AllowAllParametersOfDeclarationOnNextLine: true14AllowShortBlocksOnASingleLine: Never15AllowShortCaseLabelsOnASingleLine: false16AllowShortFunctionsOnASingleLine: All17AllowShortLambdasOnASingleLine: All18AllowShortIfStatementsOnASingleLine: Never19AllowShortLoopsOnASingleLine: true20AlwaysBreakAfterDefinitionReturnType: None21AlwaysBreakAfterReturnType: None22AlwaysBreakBeforeMultilineStrings: true23AlwaysBreakTemplateDeclarations: Yes24BinPackArguments: true25BinPackParameters: true26BraceWrapping:27 AfterCaseLabel: false28 AfterClass: false29 AfterControlStatement: false30 AfterEnum: false31 AfterFunction: false32 AfterNamespace: false33 AfterObjCDeclaration: false34 AfterStruct: false35 AfterUnion: false36 AfterExternBlock: false37 BeforeCatch: false38 BeforeElse: false39 IndentBraces: false40 SplitEmptyFunction: true41 SplitEmptyRecord: true42 SplitEmptyNamespace: true43BreakBeforeBinaryOperators: None44BreakBeforeBraces: Attach45BreakBeforeInheritanceComma: false46BreakInheritanceList: BeforeColon47BreakBeforeTernaryOperators: true48BreakConstructorInitializersBeforeComma: false49BreakConstructorInitializers: BeforeColon50BreakAfterJavaFieldAnnotations: false51BreakStringLiterals: true52ColumnLimit: 8053CommentPragmas: '^ IWYU pragma:'54CompactNamespaces: false55ConstructorInitializerAllOnOneLineOrOnePerLine: true56ConstructorInitializerIndentWidth: 457ContinuationIndentWidth: 458Cpp11BracedListStyle: true59DeriveLineEnding: true60DerivePointerAlignment: true61DisableFormat: false62ExperimentalAutoDetectBinPacking: false63FixNamespaceComments: true64ForEachMacros:65 - foreach66 - Q_FOREACH67 - BOOST_FOREACH68IncludeBlocks: Regroup69IncludeCategories:70 - Regex: '^<ext/.*\.h>'71 Priority: 272 SortPriority: 073 - Regex: '^<.*\.h>'74 Priority: 175 SortPriority: 076 - Regex: '^<.*'77 Priority: 278 SortPriority: 079 - Regex: '.*'80 Priority: 381 SortPriority: 082IncludeIsMainRegex: '([-_](test|unittest))?$'83IncludeIsMainSourceRegex: ''84IndentCaseLabels: true85IndentGotoLabels: true86IndentPPDirectives: None87IndentWidth: 488IndentWrappedFunctionNames: false89JavaScriptQuotes: Leave90JavaScriptWrapImports: true91KeepEmptyLinesAtTheStartOfBlocks: false92MacroBlockBegin: ''93MacroBlockEnd: ''94MaxEmptyLinesToKeep: 195NamespaceIndentation: None96ObjCBinPackProtocolList: Never97ObjCBlockIndentWidth: 298ObjCSpaceAfterProperty: false99ObjCSpaceBeforeProtocolList: true100PenaltyBreakAssignment: 2101PenaltyBreakBeforeFirstCallParameter: 1102PenaltyBreakComment: 300103PenaltyBreakFirstLessLess: 120104PenaltyBreakString: 1000105PenaltyBreakTemplateDeclaration: 10106PenaltyExcessCharacter: 1000000107PenaltyReturnTypeOnItsOwnLine: 200108PointerAlignment: Left109RawStringFormats:110 - Language: Cpp111 Delimiters:112 - cc113 - CC114 - cpp115 - Cpp116 - CPP117 - 'c++'118 - 'C++'119 CanonicalDelimiter: ''120 BasedOnStyle: google121 - Language: TextProto122 Delimiters:123 - pb124 - PB125 - proto126 - PROTO127 EnclosingFunctions:128 - EqualsProto129 - EquivToProto130 - PARSE_PARTIAL_TEXT_PROTO131 - PARSE_TEST_PROTO132 - PARSE_TEXT_PROTO133 - ParseTextOrDie134 - ParseTextProtoOrDie135 CanonicalDelimiter: ''136 BasedOnStyle: google137ReflowComments: true138SortIncludes: true139SortUsingDeclarations: true140SpaceAfterCStyleCast: false141SpaceAfterLogicalNot: false142SpaceAfterTemplateKeyword: true143SpaceBeforeAssignmentOperators: true144SpaceBeforeCpp11BracedList: false145SpaceBeforeCtorInitializerColon: true146SpaceBeforeInheritanceColon: true147SpaceBeforeParens: ControlStatements148SpaceBeforeRangeBasedForLoopColon: true149SpaceInEmptyBlock: false150SpaceInEmptyParentheses: false151SpacesBeforeTrailingComments: 2152SpacesInAngles: false153SpacesInConditionalStatement: false154SpacesInContainerLiterals: true155SpacesInCStyleCastParentheses: false156SpacesInParentheses: false157SpacesInSquareBrackets: false158SpaceBeforeSquareBrackets: false159Standard: Auto160StatementMacros:161 - Q_UNUSED162 - QT_REQUIRE_VERSION163TabWidth: 4164UseCRLF: false165UseTab: Never166...
以下のコマンドでダウンロードできます。
curl -OL https://raw.githubusercontent.com/TheAlgorithms/C-Plus-Plus/master/.clang-format
wget https://raw.githubusercontent.com/TheAlgorithms/C-Plus-Plus/master/.clang-format
優先順位
-
コマンドのオプションでスタイルを指定した場合: そのスタイルが優先されます。
-
コマンドのオプションでスタイルを指定しなかった場合:
.clang-format
ファイルの内容が優先されます。- 入力ファイルの最も近い親ディレクトリにある
.clang-format
ファイルを探そうとします。
- 入力ファイルの最も近い親ディレクトリにある
例えば、以下のようなディレクトリ構造があるとします。
ディレクトリ/home/ubuntu
- .clang-format
- main.c
ディレクトリcpp
- _clang-format
- main.cpp
ディレクトリtest
- test.cpp
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
の設定を適用するには、以下のようにします。
clang-format --style=file:/home/ubuntu/.clang-format /home/ubuntu/cpp/test/test.cpp
vim で使う
~/.vimrc
に以下の設定を追加すると、vim
でファイルを保存するたびにclang-format
が実行されます。
1let g:clang_format_cmd = 'clang-format'2
3function! FormatOnSave()4 execute '%!'.g:clang_format_cmd5endfunction6
7autocmd BufWritePre *.c *.c++ *.cc *.cpp *.cu *.cuh *.cxx *.h *.h++ *.hh *.hpp *.hxx call FormatOnSave()