web-dev-qa-db-ja.com

Clang形式の改行

ツールが改行を削除しないようにするclang-format設定を探しています。

たとえば、ColumnLimitを120に設定していますが、サンプルコードを再フォーマットすると次のようになります。

前:

#include <vector>
#include <string>

std::vector<std::string> get_vec()
{
   return std::vector<std::string> {
      "this is a test",
      "some of the lines are longer",
      "than other, but I would like",
      "to keep them on separate lines"
   };
}

int main()
{
   auto vec = get_vec();
}

後:

#include <vector>
#include <string>

std::vector<std::string> get_vec()
{
   return std::vector<std::string>{"this is a test", "some of the lines are longer", "than other, but I would like",
         "to keep them on separate lines"};
}

int main()
{
   auto vec = get_vec();
}

私が望んでいるのは、ツールが120文字を超える行を分割するが、行が120文字未満であるという理由だけで行を結合することを決定しないことです。

そのようなオプションはありますか?ドキュメントには何も目立ちませんでした。

45
zmb

だから、clang形式のコードをいじり、いくつかのパッチを作成したので、ここに私の2セントがあります:

  • Clang形式は、

    • libclangを使用してASTを解析します。これは基本的にすべての空白を削除します
    • トークンシーケンスを「論理的な」コード行のような「ラップされていない行」に分割する
    • ルール/構成情報を適用して、「ラップされていない行」を小さな単位に分割することがあります
    • 新しいホワイトスペース/インデントを使用して、すべてを元に戻します

    元のホワイトスペースを尊重するのは簡単ではありません。最初のコードを解析するときに、そのようなものが放り込まれます。

  • 最も簡単に、改行を配置する場所を制御できます。

    • 列制限の設定
    • 「ビンパックパラメーター」オプションの使用
    • さまざまな種類のブレークのペナルティを設定する-関数の戻り値の型の後にブレーク、最初の呼び出しパラメータの前にブレーク、文字列リテラルをブレーク、コメントをブレーク...
    • 行末にコメントを配置する(clang形式ではコメントを削除できないため、行を分割する必要がある)
    • clang-formatのoff/onディレクティブを使用します

ここにあなたが試すことができる一つの事柄があります:

std::vector<std::string> get_vec()
{
   return std::vector<std::string> {   //
      "this is a test",                //
      "some of the lines are longer",  //
      "than other, but I would like",  //
      "to keep them on separate lines" //
   };
}

// clang-format offに対するこの利点は、後でタブ幅または他のオプションを変更した場合でも、それらのコード行が引き続きこれらのフォーマットの変更を取得するため、手動で// clang-format offに移動する必要がないことです。それを修正する地域。しかし、それはまだ少しのハック、YMMVです。

最終的に、clang-formatは、コードベース全体に統一フォーマットを課すことを非常に重視しており、すべての文字列リテラルがプログラムのどこでも同じスタイルでフォーマットされるようにします。改行の決定をマイクロレベルで制御したい場合、それは実際にはツールの精神ではなく、無効にするなどのことをする必要があります。

これは時々イライラすることがあります。配列を使って何かをしたいとき、列を整列させたり、何かをしたいとき-たとえば、lua C apiの自然なコードを次に示します。

static luaL_Reg const methods[] = {
    {"matches",               &dispatch::intf_match_unit},
    {"to_recall",             &dispatch::intf_put_recall_unit},
    {"to_map",                &dispatch::intf_put_unit},
    {"erase",                 &dispatch::intf_erase_unit},
    {"clone",                 intf_copy_unit},
    {"extract",               &dispatch::intf_extract_unit},
    {"advance",               intf_advance_unit},
};

Clang-formatがそれを実行すると、通常は右の列を揃えず、コンマの後に固定数のスペースを配置しますが、それに対してできることはあまりありません。

または、OpenGLで使用する4 x 4マトリックスがある場合:

      constexpr float shadow_skew_hardcoded[16] =
        { 1.0f, 0.0f, 0.0f, 0.0f,
          0.5f, 0.5f, 0.0f, 0.0f,
          0.0f, 0.0f, 1.0f, 0.0f,
          0.0f, 0.0f, 0.0f, 1.0f };

Clang-formatをこのようなものの上で実行させると、それらを壊してしまい、うまくフォーマットする簡単な方法はないので、「たくさんの些細なコメント」ハックに頼るか、このようなものがある場合、clang-format off。これらはツールの本質的な制限です。そのようなことをしなければならないことに満足していないなら、それはおそらくあなたのためのツールではないでしょう。

35
Chris Beck

あなたが望んでいることを正確に行うためにclang-formatするかどうかはわかりませんが、clang-formatにコードのセクションをそのままにするように指示することは可能です。これは、あなたが話しているまさにそのようなシナリオ、非常に特定のフォーマットが読みやすくするコードのブロックに使用します。

std::vector<std::string> get_vec()
{
   // clang-format off
   return std::vector<std::string> {
      "this is a test",
      "some of the lines are longer",
      "than other, but I would like",
      "to keep them on separate lines"
   };
   // clang-format on
}

参照: http://clang.llvm.org/docs/ClangFormatStyleOptions.html#disabling-formatting-on-a-piece-of-code

14
MattG

documentation に現在何も表示されていませんでした。

ColumnLimitを0に設定しても、テキストの折り返しは維持されます。

clang-format-mp-3.4 test.c -style="{ ColumnLimit: 0 }"

#include <vector>
#include <memory>
#include <string>

int main() {
  std::vector<std::string> vec = {
    "this is a test",
    "with some strings",
    "that I want on separate lines"
  };
}
8
Sam P

最後の文字列の後にコンマを追加します。これは、clang-formatに垂直にフォーマットするように指示します。例: https://godbolt.org/z/bZxr__ 右クリック>テキストのフォーマット

#include <string>
#include <vector>

std::vector<std::string> get_vec() {
  return std::vector<std::string>{
      "this is a test",
      "some of the lines are longer",
      "than other, but I would like",
      "to keep them on separate lines", // comma here after last element
  };
}

int main() { auto vec = get_vec(); }
0
Mac