Uncrustifyのセッティング (6) 空行編

続いて
------
まだUncrustifyの設定の旅は続きます。延々と続きます。

皆さんもよく人のソースコードを見ると、あるソースブロックの複数行の空行があったりするのを見るかと思います。Uncrustifyでは、この空行を挿入する行数もルール化することができます。

なお、空行オプションといいながら、指定するのは空行数ではなく改行文字数なので注意が必要である。

空行オプション一覧
------------------

| 項目                         | 説明                                                                                                                                                                                          |
|:-----------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| nl_max                       | 連続してもよい改行数。 (0: 制限なし) { number }                                                                                                                                               |
| nl_after_func_proto          | 関数プロトタイプ宣言の後の改行数 (別のプロトタイプ宣言が続く場合) (0: 変更なし) { number }                                                                                                    |
| nl_after_func_proto_group    | 関数プロトタイプ宣言の後の改行数 (別のプロトタイプ宣言が続かない倍) { number }                                                                                                                |
| nl_after_func_body           | 複数行の関数ボディの'}'の後の改行数 { number }                                                                                                                                                |
| nl_after_func_body_class     | クラス宣言内の複数行の関数ボディの'}'の後の改行数 { number }                                                                                                                                  |
| nl_after_func_body_one_liner | 一行関数ボディの'}'の後の改行数 { number }                                                                                                                                                    |
| nl_before_block_comment      | 複数行コメントの前の最小改行数 ('{'もしくは別の複数行コメントの後の場合、適用されない。) { number }                                                                                           |
| nl_before_c_comment          | 1行Cコメント ('/* ... */') の前の最小改行数 '{'もしくは別の1行Cコメントの後の場合、適用されない。 { number }                                                                                  |
| nl_before_cpp_comment        | C++コメント ('// ...') の前の最小改行数 '{'もしくは別のC++コメントの後の場合、適用されない。 { number }                                                                                       |
| nl_after_multiline_comment   | 複数行コメントの後に改行を強制するかどうか { false, true }                                                                                                                                    |
| nl_after_struct              | struct/enum/unionの定義の'}'もしくは';'の後の改行数 { number }                                                                                                                                |
| nl_after_class               | class定義の'}'もしくは';'の後の改行数 { number }                                                                                                                                              |
| nl_before_access_spec        | 'private:'、'public:'、'protected:'、'signals:'、'slots:'ラベルの前の改行数 '{'の後の場合、改行数は変更されない。 (0: 変更無し) { number }                                                    |
| nl_after_access_spec         | 'private:'、'public:'、'protected:'、'signals:'、'slots:'ラベルの後の改行数 (0: 変更無し) { number }                                                                                          |
| nl_comment_func_def          | 関数定義と関数コメントの間の改行数 (0: 変更無し) { number }                                                                                                                                   |
| nl_after_try_catch_finally   | '}'が続かないtry-catch-finallyブロックの後の改行数 (0: 変更無し) { number }                                                                                                                   |
| nl_around_cs_property        | プロパティ、インデクサ、イベントの定義の前後の改行数 (0: 変更無し) { number }                                                                                                                 |
| nl_between_get_set           | get/set/add/removeハンドラの間の改行数 (C#言語) (0: 変更無し) { number }                                                                                                                      |
| nl_property_brace            | プロパティと'{'の間に改行を挿入/削除する (C#言語) { ignore, add, remove, force }                                                                                                              |
| eat_blanks_after_open_brace  | '{'の後の改行を削除するかどうか { false, true }                                                                                                                                               |
| eat_blanks_before_close_brace| '}'の前の改行を削除するかどうか { false, true }                                                                                                                                               |
| nl_remove_extra_newlines     | プリプロセッサ以外の改行をどのぐらい積極的に削除するか 0: 変更しない 1: 他の設定でハンドルされない改行を可能な限り削除する 2: 全ての改行を一度削除して、設定から完全に整形しなおす { number } |
| nl_before_return             | 'return'文の前に改行を挿入するかどうか ('{'直後の'return'以外) { false, true }                                                                                                                |
| nl_after_return              | 'return'文の後に改行を挿入するかどうか ('}'が直後にある'return'以外) { false, true }                                                                                                          |
| nl_after_annotation          | Java注釈文の後に改行を挿入するかどうか 改行後の注釈文にのみ適用される { ignore, add, remove, force }                                                                                          |
| nl_between_annotation        | 2つの注釈文の間に改行を挿入するかどうか { ignore, add, remove, force }                                                                                                                        |

僕の設定
--------

```bash:blankline.cfg
nl_max                              = 2
nl_after_func_proto                 = 1
nl_after_func_proto_group           = 2
nl_after_func_body                  = 2
nl_after_func_body_class            = 2
nl_after_func_body_one_liner        = 1
nl_before_block_comment             = 0
nl_before_c_comment                 = 0
nl_before_cpp_comment               = 0
nl_after_multiline_comment          = true
nl_after_struct                     = 2
nl_after_class                      = 2
nl_before_access_spec               = 2
nl_after_access_spec                = 1
nl_comment_func_def                 = 1
nl_after_try_catch_finally          = 2
nl_around_cs_property               = 0
nl_between_get_set                  = 0
nl_property_brace                   = ignore
eat_blanks_after_open_brace         = true
eat_blanks_before_close_brace       = true
nl_remove_extra_newlines            = 0
nl_before_return                    = false
nl_after_return                     = false
nl_after_annotation                 = ignore
nl_between_annotation               = ignore
```

NL_MAX
------
```cpp:nl_max.cpp
// 整形前
// foo()とbar()の間に空行が2行ある。
{
    foo();


    bar();
}

// nl_max = 1
// 空行を除き、foo()とbar()を連続させる。
// 'nl_max'は改行数であって、空行数ではない点に注意。行と行の間は改行1個なので、こうなる。
{
    foo();
    bar();
}

// nl_max = 2
// foo()とbar()の間の空行は1行にまで縮められる。
{
    foo();

    bar();
}
```

NL_AFTER_FUNC_PROTO
-------------------
```cpp:nl_after_func_proto.cpp
// nl_after_func_proto = 2
// 関数プロトタイプ宣言の後に空行を最低1行は入れる。
// 改行2個ということは、関数プロトタイプ宣言の後に空行を1個挿入するということ。
char   func1(char c);

short  func2(short s);


int    func3(int i); // このように空行2個空いていも整形はされない。
                     // こういう場合は'nl_max = 1'にする。
```

NL_AFTER_FUNC_PROTO_GROUP
-------------------------
```cpp:nl_after_func_proto_group.cpp
// nl_after_func_proto_group = 2
// 関数プロトタイプ宣言のブロックの後に空行を最低1行は入れる。
int    func3(int i);
float  func4(float f);
double func5(double d);

int    i_foo;
float  f_foo;
double d_foo;
```

NL_AFTER_FUNC_BODY
------------------
```cpp:nl_after_func_body.cpp
// nl_after_func_body = 1
// 関数ボディの後 ('}'の次の行) に空行は入らない。
int func1(int i)
{
}
float func2(float f)
{
}

// nl_after_func_body = 2
// 関数ボディの後 ('}'の次の行) に空行が1行挿入される。
int func1(int i)
{
}

float func2(float f)
{
}

```

NL_AFTER_FUNC_BODY_CLASS
------------------------
```cpp:nl_after_func_body_class.cpp
// nl_after_func_body_class = 1
// クラス宣言内のメンバ関数のボディの後 ('}'の次の行) に空行は入らない。
class Foo
{
    int func1(int param)
    {
    }
    float func2(float param)
    {
    }
};

// nl_after_func_body_class = 2
// クラス宣言内のメンバ関数のボディの後 ('}'の次の行) に空行が1行挿入される。
class Foo
{
    int func1(int param)
    {
    }

    float func2(float param)
    {
    }

};
```

NL_AFTER_FUNC_BODY_ONE_LINER
----------------------------
```cpp:nl_after_func_body_one_liner.cpp
// nl_after_func_body_one_liner = 2
// 一行関数のボディの後 ('}'の次の行) に空行を最低1行は入れる。
int    func1(int i)    { return i * i; }

float  func2(float f)  { return f * f; }


double func3(double d) { return d * d; }    // このように空行2個空いていも整形はされない。
                                            // こういう場合は'nl_max = 1'にする。
```

NL_BEFORE_BLOCK_COMMENT
-----------------------
```cpp:nl_before_block_comment.cpp
// nl_before_block_comment = 2
// ブロックコメントの前に空行を最低1行は入れる。
{
    int i;

    /*
     * this is a block comment
     */
    int j;
}
// nl_before
```

NL_BEFORE_C_COMMENT
-------------------
```cpp:nl_before_c_comment.cpp
// nl_before_c_comment = 2
// Cコメント ('/* ... */') の前に空行を最低1行は入れる。
{
    /* this is a comment */
    int i;

    /* this is a comment */
    int j;



    /* this is a comment */
    int k;
}
```

NL_BEFORE_CPP_COMMENT
---------------------
```cpp:nl_before_cpp_comment.cpp
// nl_before_cpp_comment = 2
// C++コメント ('// ...') の前に空行を最低1行は入れる。
{
    // this is a comment
    int i;

    // this is a comment
    int j;


    // this is a comment
    int k;
}
```

NL_AFTER_MULTILINE_COMMENT
--------------------------
```cpp:nl_after_multiline_comment.cpp
// nl_after_multiline_comment = false
// 複数行コメントの最終行に続けてコードがある。
// 複数行コメントの末尾は改行するのがあたり前な気がするが。
{
    /*
     * this is multiline comment
     */ int foo, bar;
}

// nl_after_multiline_comment = true
// 複数行コメントの最終行に改行が挿入される。
{
    /*
     * this is multiline comment
     */
    int foo, bar;
}
```

NL_AFTER_STRUCT
---------------
```cpp:nl_after_struct.cpp
// nl_after_struct = 2
// 構造体宣言の後に空行を最低1行は入れる。
struct FooBar
{
    int foo;
    int bar;
};

int foobar;
```

NL_AFTER_CLASS
---------------
```cpp:nl_after_class.cpp
// nl_after_class = 2
// クラス宣言の後に空行を最低1行は入れる。
class FooBar
{
    int foo;
    int bar;
};

int foobar;
```

NL_BEFORE_ACCESS_SPEC
---------------------
```cpp:nl_before_access_spec.cpp
// nl_before_access_spec = 2
// アクセス指定子の前に空行が1行挿入される。
class Foo
{
public:
    Foo();

private:
    int m_bar;
};
```

NL_AFTER_ACCESS_SPEC
--------------------
```cpp:nl_after_access_spec.cpp
// nl_after_access_spec = 2
// アクセス指定子の後に空行が1行挿入される。
class Foo
{
public:

    Foo();

private:

    int m_bar;
};
```

NL_COMMENT_FUNC_DEF
-------------------
```cpp:nl_comment_func_def
// nl_comment_func_def = 2
// 関数定義と直前のコメントとの間に空行が1行挿入される。
/*
 * this is a comment
 */

void func(void)
{
}
```

NL_AFTER_TRY_CATCH_FINALLY
--------------------------
```cpp:nl_after_try_catch_finally.cpp
// nl_after_try_catch_finally = 2
// try-catch (C#などはfinallyも) の後に空行が1行挿入される。
{
    try {
        /* try something */
    } catch {
        /* catch an exception */
    }

    return;
}
```

EAT_BLANKS_AFTER_OPEN_BRACE
---------------------------
```cpp:eat_blanks_after_open_brace.cpp
// eat_blanks_after_open_brace = true
// 以下のようなコードの'{'の下の空行をすべて削除する。
{


    func1();
    func2();
    func3();

// 整形後
{
    func1();
    func2();
    func3();
```

EAT_BLANKS_BEFORE_CLOSE_BRACE
-----------------------------
```cpp:eat_blanks_before_close_brace.cpp
// eat_blanks_before_close_brace = true
// 以下のようなコードの'}'の上の空行をすべて削除する。
    func1();
    func2();
    func3();


}

// 整形後
    func1();
    func2();
    func3();
}
```

NL_BEFORE_RETURN
----------------
```cpp:nl_before_return.cpp
// nl_before_return = true
// 以下のようなコードの場合、'return'の前に空行が挿入される。
    result = func();
    return result;
}

// 整形後
// ただし、nl_maxが優先されるので、nl_max=1の場合、空行が挿入されないようだ。
    result = func();

    return result;
}
```

NL_AFTER_RETURN
---------------
```cpp:nl_after_return.cpp
// nl_after_return = true
// 以下のようなコードの場合、'return'の後に空行が挿入される。
    return 0;
error:
    return -1;
}

// 整形後
// ただし、nl_maxが優先されるので、nl_max=1の場合、空行が挿入されないようだ。
    return 0;

error:
    return -1;
}
```