web-dev-qa-db-fra.com

Sauts de ligne au format Clang

Je recherche un clang-format paramètre pour empêcher l'outil de supprimer les sauts de ligne.

Par exemple, j'ai mon ColumnLimit réglé sur 120, et voici ce qui se passe lorsque je reformate un exemple de code.

Avant:

#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();
}

Après:

#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();
}

Ce que je voudrais, c'est que l'outil casse les lignes de plus de 120 caractères, mais ne décide pas de combiner les lignes simplement parce qu'elles sont inférieures à 120 caractères.

Existe-t-il une telle option? Rien dans les documents ne me paraissait remarquable.

45
zmb

Donc, après avoir gâché le code au format clang et fait quelques correctifs, voici mes deux cents:

  • Le format Clang est basé sur,

    • analyser le AST en utilisant libclang, ce qui élimine essentiellement tous les espaces
    • décomposer la séquence de jetons en "lignes déballées" qui sont comme des lignes de code "logiques"
    • Application de règles/informations de configuration pour parfois diviser des "lignes non enveloppées" en unités plus petites
    • Crachez le tout à nouveau avec de nouveaux espaces/indentations

    Ce n'est pas facile de le faire respecter l'espace blanc d'origine, ce genre de problème est lancé lorsque vous analysez le code pour la première fois.

  • Vous pouvez contrôler où il place les sauts de ligne, le plus facilement, en

    • définition de la limite de colonne
    • en utilisant les options "bin pack parameters"
    • fixer des pénalités pour différents types de coupures - coupure après type de retour d'une fonction, coupure avant le premier paramètre d'appel, coupure d'une chaîne littérale, coupure d'un commentaire ...
    • placer des commentaires à la fin d'une ligne (le format clang ne peut pas supprimer le commentaire et doit donc diviser la ligne)
    • utiliser les directives off/on au format clang

Voici une chose que vous pouvez essayer:

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" //
   };
}

L'avantage de ceci sur // clang-format off est que, si vous modifiez ultérieurement la largeur de tabulation ou une autre option, ces lignes de code obtiendront toujours ces modifications de mise en forme de sorte que vous n'avez pas besoin d'aller manuellement dans le // clang-format off régions pour y remédier. Cependant, c'est encore un peu un hack, YMMV.

En fin de compte, clang-format consiste à imposer un format uniforme sur une base de code entière, en s'assurant que tous les littéraux de chaîne sont formatés dans le même style partout dans votre programme. Si vous voulez avoir un contrôle au niveau micro sur les décisions de saut de ligne, ce n'est pas vraiment dans l'esprit de l'outil, et vous devrez faire des choses comme le désactiver.

Cela peut parfois être frustrant, surtout. quand vous voulez faire des choses avec des tableaux et avoir des colonnes alignées ou quelque chose - par exemple, voici du code naturel de 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},
};

Lorsque le format clang passe par-dessus, cela ne va généralement pas aligner la colonne de droite, cela va lui placer un nombre fixe d'espaces après les virgules et il n'y a pas grand-chose que vous puissiez faire à ce sujet afaik.

Ou, si vous avez une matrice 4 x 4 à utiliser avec OpenGL:

      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 };

Si vous laissez le format clang courir sur des choses comme celle-ci, cela va juste les modifier, et afaik il n'y a pas de moyen facile de les formater correctement, il vous suffit donc de recourir au hack "beaucoup de commentaires triviaux", ou d'utiliser désactivez le format lorsque vous avez quelque chose comme ça. Ce ne sont que des limites intrinsèques de l'outil. Si vous n'êtes jamais heureux de devoir faire des choses comme ça, ce n'est probablement pas l'outil qu'il vous faut.

35
Chris Beck

Je ne suis pas sûr que vous clang-format pour faire exactement ce que vous voulez, mais il est possible de dire à clang-format de laisser les sections de code seules. Je l'utilise pour exactement le genre de scénario dont vous parlez, des blocs de code où une mise en forme très particulière facilite la lecture.

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
}

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

14
MattG

Je n'ai rien vu actuellement dans le documentation qui vous permettrait de le faire.

La définition de ColumnLimit à 0 préservera toujours l'habillage du texte.

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

Ajoutez une virgule après la dernière chaîne. Cela indique à clang-format de le formater verticalement. Ex: https://godbolt.org/z/bZxr__ Clic droit> formater le texte

#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