Uncrustifyのセッティング (8) コメント整形編

コメント求む
------------
はてさて、今回はコメント整形オプションに関する解説です。だいぶ来ました。。。

何だか勢い余って、Uncrustify徹底解説みたいになってきていますが、調べれば調べるほど、いろいろと分からなくなってきます。あとこれ、Uncrustifyのバグのようなものも見つかって面白いです。

例えば、次のようにメンバイニシャライザーの':'と同じ位置に','を置くためのオプションとして'pos_class_comma'というのがありますが、いくらいじっても'lead'になりませんw。

```cpp:member_initializers.cpp
class Foo
{
public:
    Foo(int foo, int bar)
        : m_foo(foo)
        , m_bar(bar)
    {
    }

private:
    int m_foo;
    int m_bar;
};
```

仕様なのかもしれませんが、コメント整形オプションにも、若干気になる整形が発生するケースがあります。

```cpp:single_line_comment_word_wrap.cppp
// こういう'/* */'スタイルのコメントを整形すると。。。
{
    /* this is a comment. this is a comment. this is a comment. */
}

// こんなふうに、折り返しされたコメントが先頭の'*'にくっついちゃいます。
{
    /* this is a comment. this is a comment. this
     *is a comment. */
}
```

コメント整形オプション一覧
--------------------------

| 項目                      | 説明                                                                                                                                                                                                  |
|:--------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| cmt_width                 | コメントを一定の幅で折り返す (桁数) { number }                                                                                                                                                        |
| cmt_reflow_mode           | コメントリフロー (テキストの流し込み、再配置) (0: 折り返しのみ (リフローしない) 1: リフローも折り返しもしない 2: フルリフロー) (0と2の差がわからない) { number }                                      |
| cmt_indent_multi          | 複数行コメントの変更 (cmd_width、キーワード置換、先行文字列など含む) を無効化する { false, true }                                                                                                     |
| cmt_c_group               | ブロックになっているCコメント ('/* ... */') をグループ化するかどうか { false, true }                                                                                                                  |
| cmt_c_nl_start            | 結合したCコメントの最初の行に、'/*'単体を付けるかどうか { false, true }                                                                                                                               |
| cmt_c_nl_end              | 結合したCコメントの最後の行に、'*/'単体を付けるかどうか { false, true }                                                                                                                               |
| cmt_cpp_to_c              | C++コメントをCコメントに変更するかどうか { false, true }                                                                                                                                              |
| cmt_cpp_group             | ブロックになっているC++コメント ('// ....') をグループ化するかどうか (cmt_cpp_to_cがtrueの場合のみ) { false, true }                                                                                   |
| cmt_cpp_nl_start          | 結合したC++コメント ('// ....') の最初の行に、'/*'単体を付けるかどうか (cmt_cpp_to_cがtrueの場合のみ) { false, true }                                                                                 |
| cmt_cpp_nl_end            | 結合したC++コメント ('// ....') の最後の行に、'*/'単体を付けるかどうか (cmt_cpp_to_cがtrueの場合のみ) { false, true }                                                                                 |
| cmt_star_cont             | コメント行にスター '*' を続けて付けるかどうか { false, true }                                                                                                                                         |
| cmt_sp_before_star_cont   | 連続するコメント行の開始位置と'*'の間に挿入する空白数 { number }                                                                                                                                      |
| cmt_sp_after_star_cont    | 連続するコメント行の'*'とコメントの間に挿入する空白数 { number }                                                                                                                                      |
| cmt_multi_check_last      | '*'で始める複数行コメントに対し、最初と最後のコメント行が同じ長さの場合に、先頭にある空白を削除するかどうか (デフォルト: true) { false, true }                                                        |
| cmt_insert_file_header    | C/C++コメントで始まらないファイルに、先頭にコメントを付加する定型フォーマットのファイル名 ($(filename)はカレントファイルの名前に置換) { string }                                                      |
| cmt_insert_file_footer    | C/C++コメントで終わらないファイルに、末尾にコメントを付加する定型フォーマットのファイル名 ($(filename)はカレントファイルの名前に置換) { string }                                                      |
| cmt_insert_func_header    | C/C++コメントで始まらない関数実装に、関数の直前に付加する定型フォーマットのファイル名 ($(function)は関数名に、$(javaparam)はjavadocスタイルの@paramと@returnに、$(fclass)はクラス名に置換) { string } |
| cmt_insert_class_header   | C/C++コメントで始まらないクラス定義の直前に付加する定型フォーマットのファイル名 ($(class)はクラス名に置換) { string }                                                                                 |
| cmt_insert_oc_msg_header  | C/C++コメントで始まらないObjective-Cのメッセージ仕様の直前に付加する定型フォーマットのファイル名。 ($(message)は関数名に、$(javaparam)はjavadocスタイルの@paramと@returnに置換) { string }            |
| cmt_insert_before_preproc | プリプロセッサの前にコメントを挿入すべきかどうか (cmt_insert_oc_msg_header、cmt_insert_func_header、cmt_insert_class_headerに影響を及ぼす) { false, true }                                            |

僕の設定
--------
```bash:comment.cfg
cmt_width                           = 96
cmt_reflow_mode                     = 0
cmt_indent_multi                    = true
cmt_c_group                         = true
cmt_c_nl_start                      = true
cmt_c_nl_end                        = true
cmt_cpp_to_c                        = false
cmt_cpp_group                       = false
cmt_cpp_nl_start                    = false
cmt_cpp_nl_end                      = false
cmt_star_cont                       = true
cmt_sp_before_star_cont             = 0
cmt_sp_after_star_cont              = 0
cmt_multi_check_last                = false
cmt_insert_file_header              = ""
cmt_insert_file_footer              = ""
cmt_insert_func_header              = ""
cmt_insert_class_header             = ""
cmt_insert_oc_msg_header            = ""
cmt_insert_before_preproc           = false
```

CMT_WIDTH
---------
```cpp:cmt_width.cpp
// cmt_width = 20
// 16桁でコメントを折り返す。
    /* this is a
       comment */
```

CMT_REFLOW_MODE
---------------
```cpp:cmt_reflow_mode.cpp
// cmt_reflow_mode = 1
// リフローも折り返しもしない。元のコメント記述のまま。
    /* this is my comment. */

// cmt_reflow_mode = 0
// テキストがcmt_widthで折り返される。
    /* this is my
      comment. */
```

CMT_INDENT_MULTI
----------------
```cpp:cmt_indent_multi.cpp
// cmt_indent_multi = false
// 2行以上のコメントは整形されない。
    /* this is my long comment.
       this is my long comment.
       this is my long comment. */

// cmt_indent_multi = true
// 複数行コメントが整形される。(あまり美しないし、下手に整形されそうだ)
    /* this is my long
      comment.
       this is my long
         comment.
       this is my long
         comment. */
```

CMT_C_GROUP
-----------
```cpp:cmt_c_group.cpp
// cmt_c_group = false
// 以下のように複数行続くCスタイル ('/* ... */') のコメントはグループ化されない。
    /* this is a comment. */
    /* this is a comment. */
    /* this is a comment. */

// cmt_c_group = true
// ブロックの先頭の'/*'と末尾の'*/'を残して、取り除き、自動的にコメントをグループ化する。
    /* this is a comment.
       this is a comment.
       this is a comment. */
```

CMT_C_NL_START
--------------
```cpp:cmt_c_nl_start.cpp
// cmt_c_nl_start = true
// ブロックの先頭に'/*'のみのコメント行を挿入する。
    /*
       this is a comment.
       this is a comment.
       this is a comment. */
```

CMT_C_NL_END
------------
```cpp:cmt_c_nl_end.cpp
// cmt_c_nl_end = true
// ブロックの末尾に'*/'のみのコメント行を挿入する。
// cmt_c_nl_startと一緒にすると対照的できれいかな。
    /* this is a comment
       this is a comment.
       this is a comment.
     */
````

CMT_CPP_TO_C
------------
```cpp:cmt_cpp_to_c.cpp
// cmt_cpp_to_c = true
// '//'で始まるコメントブロックを'/* */'に変更してくれる。
// 整形前
    // this is a comment.
    // this is a comment.
    // this is a comment.

// 整形後
    /* this is a comment. */
    /* this is a comment. */
    /* this is a comment. */
```

CMT_CPP_GROUP
-------------
```cpp:cmt_cpp_group.cpp
// cmt_cpp_group = true (&& cmt_cpp_to_c = true)
// '//'で始まるコメントブロックが'/* */'スタイルに変更されていれば、グループ化する。
    /* this is originally a '//' style comment.
       this is originally a '//' style comment.
       this is originally a '//' style comment. */
```

CMT_CPP_NL_START
----------------
```cpp:cmt_cpp_nl_start.cpp
// cmt_cpp_nl_start = true (&& cmt_cpp_to_c = true)
// cmt_c_nl_startと同じ。ブロックの先頭に'/*'のみのコメント行を挿入する。
    /*
       this is originally a '//' style comment.
       this is originally a '//' style comment.
       this is originally a '//' style comment. */
```

CMT_CPP_NL_END
--------------
```cpp:cmt_cpp_nl_end.cpp
// cmt_cpp_nl_end = true (&& cmt_cpp_to_c = true)
// cmt_c_nl_startと同じ。ブロックの末尾に'*/'のみのコメント行を挿入する。
    /* this is originally a '//' style comment.
       this is originally a '//' style comment.
       this is originally a '//' style comment.
     */
```

CMT_STAR_CONT
-------------
```cpp:cmt_star_cont.cpp
// cmt_star_cont = true
// コメント行の先頭に'*'を付ける。
    /*
     * originally, this is a non-starred comment.
     * originally, this is a non-starred comment.
     * originally, this is a non-starred comment.
     */
```

CMT_SP_BEFORE_STAR_CONT
-----------------------
```cpp:cmt_sp_before_star_cont.cpp
// cmt_sp_before_star_cont = 1
// こんなふうに'*'の位置がずれる。
    /*
      * this is a comment.
      * this is a comment.
      * this is a comment.
      */
```

CMT_SP_AFTER_STAR_CONT
----------------------
```cpp:cmt_sp_after_star_cont.cpp
// cmt_sp_after_star_cont = 1 (&& cmt_sp_before_star_cont = 0)
// こんなふうに'*'の後のコメントテキストがずれる。
// (たぶん、半角空白の数は'after'-'before'で決まる)
    /*
     *  this is a comment.
     *  this is a comment.
     *  this is a comment.
     */
```