ClangFormat(クラン・フォーマット)とは、C/C++をターゲットとした強力なコード整形ツールです。eclipseやVisual Studio Codeなどで使用することができます。このようなツールを使用することで、人や環境が変わっても同じスタイルでコードを記述することができます。
本ページでは、Visual Studio Codeでの使用例を紹介します。
必要なもの
- Visual Studio Code
-
何はともあれ、本体がないことには始まりません。
Download Visual Studio Code – Mac, Linux, Windows Visual Studio Code is free and available on your favorite platform – Linux, macOS, and Windows. Download Visual Studio Code to experience a redefined code edito… - C/C++
-
Visual Studio Codeの拡張機能です。
C/C++ – Visual Studio Marketplace Extension for Visual Studio Code – C/C++ IntelliSense, debugging, and code browsing.
Visual Studio Codeの設定
Visual Studio Codeでの使用例
src
├ main.c
├ main.h
├ ...
└ ...
src
├ main.c
├ main.h
├ ...
└ .clang-format
ClangFormatファイルの記述例
「.clang-format」ファイルは、下記の様に記述します。先頭行の「—」は必要なものなので削除してはいけません。
---
# アクセス修飾子のインデント
AccessModifierOffset: -2
# 引数は左揃え
AlignAfterOpenBracket: Align
# 初期化子リストを左揃え
AlignArrayOfStructures: Left
# 連続する行の位置を揃える
AlignConsecutiveAssignments: true # "="
AlignConsecutiveDeclarations: true # 宣言
AlignConsecutiveMacros: true # マクロ
AlignTrailingComments: true # コメント
# enum定数を項目毎に改行する
AllowShortEnumsOnASingleLine: false
# 短い関数を単一行にしない
AllowShortFunctionsOnASingleLine: None
# "{ }"を独立行に配置する
# "BreakBeforeBraces: Custom" の場合に有効
BraceWrapping:
AfterClass: true # classの後
AfterControlStatement: false # 制御文の後
AfterEnum: true # enumの後
AfterFunction: true # 関数の後
AfterStruct: true # structの後
AfterUnion: true # unionの後
AfterExternBlock: false # externの後
BeforeCatch: false # catchの前
BeforeElse: false # elseの前
# "{ }"の位置をカスタム設定する
BreakBeforeBraces: Custom
# 1行の文字数を制限する (0で無制限)
ColumnLimit: 120
# includeを名前順にソートする
IncludeBlocks: Preserve
# swicth分のcaseにインデントを設定する
IndentCaseLabels: false
# インデント
IndentWidth: 2
# ポインターの"*"、"&"は変数宣言の左に記述する
PointerAlignment: Right
# コメントは改行しない
ReflowComments: false
# キャストの後ろにスペースを入れない
SpaceAfterCStyleCast: false
# 制御文の"("の前にスペースを入れる
SpaceBeforeParens: ControlStatements
# コメントの前にスペース入れる
SpacesBeforeTrailingComments: 2
ClangFormatのスタイルオプション
ClangFormatには多数のスタイルオプションがあります。しかしそのすべてが使用している環境で動作するとは限りません。ここではVisual Studio Codeで動作確認できた範囲のものだけを抜き出しています。最新のClangFormatとは合わないところもあるかもしれませんが、参考にどうぞ。
なおClangFormatの最新バージョンの情報は下記を参照ください。
AccessModifierOffset
アクセス修飾子public、protected、privateのインデントを設定します。IndentWidthを設定している場合は、その値が基準となります。
// AccessModifierOffset: -2
// IndentWidth: 2
class Sample {
private:
int func1(void);
public:
int func2(void);
}
AlignAfterOpenBracket
引数の整列方法を設定します。
// AlignAfterOpenBracket: Align
someLongFunction(argument1,
argument2);
// AlignAfterOpenBracket: DontAlign
someLongFunction(argument1,
argument2);
// AlignAfterOpenBracket: AlwaysBreak
someLongFunction(
argument1, argument2);
// AlignAfterOpenBracket: BlockIndent
someLongFunction(
argument1, argument2
);
AlignArrayOfStructures
構造体の初期化子リストを整列します。
// AlignArrayOfStructures: None
// 整列しない
// AlignArrayOfStructures: Left
struct test demo[] =
{
{56, 23, "hello"},
{7, 5, "abc" }
};
// AlignArrayOfStructures: Right
struct test demo[] =
{
{56, 23, "hello"},
{ 7, 5, "abc"}
};
AlignConsecutiveAssignments
連続する行の「=」の位置を揃えます。
// AlignConsecutiveAssignments: true
aaa = 0;
bb = 1;
cccc = 2;
AlignConsecutiveDeclarations
連続する行の宣言を揃えます。
// AlignConsecutiveDeclarations: true
char sc;
int si;
double d;
AlignConsecutiveMacros
連続する行のマクロを揃えます。
// AlignConsecutiveMacros: true
#define SHORT_NAME 42
#define EVEN_LONGER_NAME (2)
#define foo(x) (x * x)
AlignEscapedNewlines
エスケープされた改行の、円マークの位置を揃えます。
// AlignEscapedNewlines: true (左寄せで揃える)
#define TEST \
"long long test" \
"string"
// AlignEscapedNewlines: false (ColumnLimit位置で揃える)
#define TEST \
"long long test" \
"string"
AlignOperands
水平方向に二項演算子と三項演算子を揃えます。
// AlignOperands: true
int aaa = bbbbbbbbbbbbbbb +
ccccccccccccccc;
AlignTrailingComments
連続する行のコメントを揃えます。
// AlignTrailingComments: true
int a; // comment a
int b = 2; // comment b
AllowShortEnumsOnASingleLine
enum定数を項目毎に改行します。なおfalseに設定すると、波括弧も独立した行に表示されます。この仕様はBraceWrappingの個別設定でも回避できません。
// AllowShortEnumsOnASingleLine: true
enum { A, B } myEnum;
// AllowShortEnumsOnASingleLine: false
enum
{
A,
B
} myEnum;
AllowShortFunctionsOnASingleLine
短い関数を単一行にします。
// AllowShortFunctionsOnASingleLine: None
// (単一行にしない)
// AllowShortFunctionsOnASingleLine: InlineOnly
// (class内で定義された関数だけ単一行にする)
class Foo {
void f() { foo(); }
};
void f() {
foo();
}
void f() {
}
// AllowShortFunctionsOnASingleLine: Inline
// (class内で定義された関数と空の関数だけ単一行にする)
class Foo {
void f() { foo(); }
};
void f() {
foo();
}
void f() {}
// AllowShortFunctionsOnASingleLine: Empty
// (空の関数だけ単一行にする)
void f() {}
void f2() {
bar2();
}
// AllowShortFunctionsOnASingleLine: All
// (すべて単一行にする)
class Foo {
void f() { foo(); }
};
void f() { bar(); }
BraceWrapping
{ }の位置を個々に設定します。trueに設定すると、{ }を独立した行に記述します。なお個々に設定するためには、BreakBeforeBracesをCustomに設定する必要があります。
// インデントはスペースで入れること
BraceWrapping:
AfterClass: true // classの後
AfterControlStatement: true // 制御文の後
AfterEnum: true // enumの後
AfterFunction: true // 関数の後
AfterNamespace: true // namespaceの後
AfterStruct: true // structの後
AfterUnion: true // unionの後
AfterExternBlock: true // externの後
BeforeCatch: true // catchの前
BeforeElse: true // elseの前
BreakBeforeBraces
{ }の位置を設定します。なお下記以外にもLinux、Mozilla、Stroustrup、GNU、Webkitがありますが省略します。
// BreakBeforeBraces: Attach (常にコンテキストに付ける)
void function(int val) {
if (val > MAX) {
...
}
...
}
// BreakBeforeBraces: Allman (常に独立した行に付ける)
void function(int val)
{
if (val > MAX)
{
...
}
...
}
// BreakBeforeBraces: Custom (BraceWrappingで個々に設定する)
ColumnLimit
1行の文字数を設定します。
ColumnLimit: 120
IncludeBlocks
includeを整列(ソート)します。
// IncludeBlocks: Preserve (連続する行を整列する)
#include <stdio.h>
#include <stdint.h>
#include "b.h"
#include "a.h"
↓
#include <stdint.h>
#include <stdio.h>
#include "a.h"
#include "b.h"
// IncludeBlocks: Merge (離れた行も引っ付けて整列する)
#include <stdio.h>
#include <stdint.h>
#include "b.h"
#include "a.h"
↓
#include "a.h"
#include "b.h"
#include <stdint.h>
#include <stdio.h>
// IncludeBlocks: Regroup (IncludeCategoriesの順に整列する)
IncludeCategories
「IncludeBlocks: Regroup」の整列順を設定します。
IncludeCategories:
- Regex: '^<.*\.h>'
Priority: 1
- Regex: '^<.*'
Priority: 2
- Regex: '.*'
Priority: 3
IndentCaseLabels
caseにインデントを設定します。
// IndentCaseLabels: true
switch (val) {
case 1:
...
break;
case 2:
...
break;
default:
...
}
// IndentCaseLabels: false
switch (val) {
case 1:
...
break;
case 2:
...
break;
default:
...
}
IndentWidth
インデント数を設定します。
IndentWidth: 2
PointerAlignment
ポインターの「*」や「&」の位置を揃えます。
// PointerAlignment: Left
int* p;
// PointerAlignment: Middle
int * p;
// PointerAlignment: Right
int *p;
ReflowComments
ColumnLimitを超えるコメントの、途中での改行を試みます。
// ReflowComments: true (試みる)
// ReflowComments: false (試みない)
SpaceAfterCStyleCast
キャストの後にスペースを入れるかを設定します。
// SpaceAfterCStyleCast: true
(int) i;
// SpaceAfterCStyleCast: false
(int)i;
SpaceBeforeAssignmentOperators
演算子の前にスペースを入れるかを設定します。
// SpaceBeforeAssignmentOperators: true
i = i + 1;
// SpaceBeforeAssignmentOperators: false
i= i + 1;
SpaceBeforeParens
開始括弧「(」の前にスペースを入れるかを設定します。
// SpaceBeforeParens: Never (スペースを入れない)
void function(int val) {
if(val > MAX) {
...
}
}
// SpaceBeforeParens: ControlStatements (制御文の前にはスペースを入れる)
void function(int val) {
if (val > MAX) {
...
}
}
// SpaceBeforeParens: Always (すべてにスペースを入れる)
void function (int val) {
if (val > MAX) {
...
}
}
SpaceInEmptyParentheses
空の括弧( )内にスペースを入れるかを設定します。
// SpaceInEmptyParentheses: true
func( );
// SpaceInEmptyParentheses: false
func();
SpacesBeforeTrailingComments
コメントの前に入れるスペースの数を設定します。
// SpacesBeforeTrailingComments: 2
int name; // 2スペース
SpacesInAngles
<>内にスペースを入れるかを設定します。
// SpacesInAngles: true
static_cast< int >(arg);
// SpacesInAngles: false
static_cast<int>(arg);
SpacesInCStyleCastParentheses
キャストの( )内にスペースを入れるかを設定します。
// SpacesInCStyleCastParentheses: true
( int )i;
// SpacesInCStyleCastParentheses: false
(int)i;
SpacesInParentheses
( )内にスペースを入れるかを設定します。
// SpacesInParentheses: true
void function( int val ) {
if ( val > MAX ) {
...
}
...
}
// SpacesInParentheses: false
void function(int val) {
if (val > MAX) {
...
}
...
}
SpacesInSquareBrackets
[ ]内にスペースを入れるかを設定します。
// SpacesInSquareBrackets: true
int a[ 5 ];
// SpacesInSquareBrackets: false
int a[5];
部分的に整形の対象外にする
初期化子リストなど、視認性をあげるため意図的に位置揃えしたいこともあります。この様な場合は「clang-format off」と「clang-format on」で囲むことで部分的に整形の対象外にすることができます。
// clang-format off
...
// clang-format on