Clang-formatowanie przerw linii

Szukam Ustawienia clang-format, aby zapobiec usuwaniu przerw linii przez narzędzie.

Na przykład, mam mój ColumnLimit ustawiony na 120, A oto, co się dzieje, gdy sformatuję przykładowy kod.

Przed:

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

Po:

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

Chciałbym, aby narzędzie łamało linie, które mają więcej niż 120 znaków, ale nie decyduje się na łączenie linii tylko dlatego, że mają mniej niż 120 znaków.

Czy jest taka opcja? Nic w docs nie wyróżniało się ja.
Author: Chris Beck, 2015-11-11

3 answers

Więc, po zamieszaniu w kodzie formatu clang i zrobieniu kilku łatek, oto moje dwa grosze: {]}

  • Format Clang opiera się na,

    • parsowanie AST za pomocą libclang, co w zasadzie eliminuje wszystkie białe spacje
    • dzielenie sekwencji tokenów na" linie rozpakowane", które są jak" logiczne " linie kodu
    • stosowanie reguł / informacji o konfiguracji, aby czasami dzielić "nawinięte linie" na mniejsze jednostki
    • Spit it all back out again with new whitespace / indentation

    Nie jest łatwo sprawić, by respektowała oryginalną whitepsace, która zostaje odrzucona, gdy po raz pierwszy analizujesz kod.

  • Możesz kontrolować, gdzie umieszcza podziały linii, najłatwiej, poprzez

    • ustawianie limitu kolumn
    • korzystanie z opcji "parametry pakietu bin"
    • ustawianie kar dla różnego rodzaju przerwań -- break po zwracanym typie funkcji, break przed pierwszym wywołaniem parametru, break ciągu znaków, przerwij komentarz...
    • umieszczanie komentarzy na końcu wiersza (format clang nie może usunąć komentarza i dlatego musi podzielić wiersz)
    • użyj dyrektyw clang-format off / on

Oto jedna rzecz, którą możesz wypróbować:

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

Zaletą tego nad // clang-format off jest to, że jeśli później zmienisz szerokość karty lub inną opcję, te linie kodu nadal będą miały te zmiany formatowania, więc nie musisz ręcznie wchodzić do regionów // clang-format off, Aby to naprawić to. Jednak nadal jest to trochę hack, YMMV.

Ostatecznie, clang-format polega na nałożeniu jednolitego formatu na całą bazę kodu, upewniając się, że wszystkie literały łańcuchów są formatowane w tym samym stylu wszędzie w twoim programie. Jeśli chcesz mieć kontrolę na poziomie mikro nad decyzjami o przerwaniu linii, to nie jest to w duchu narzędzia i będziesz musiał zrobić takie rzeczy, jak wyłączenie go.

To może być czasem frustrujące esp. gdy chcesz robić rzeczy z tablicami i mieć kolumny wyrównane czy coś -- na przykład, oto jakiś naturalny kod z 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},
};

Kiedy clang-format biegnie nad tym, to generalnie nie będzie wyrównać prawą kolumnę, jego zamiar umieścić go stałą liczbę spacji po przecinkach i nie ma wiele można z tym zrobić afaik.

Lub, jeśli masz matrycę 4 x 4 do użycia z 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 };
Jeśli pozwolisz clang-formatować takie rzeczy, to po prostu je zmanipulujesz, a afaik nie ma łatwego sposobu na zrób to ładnie sformatować je, więc po prostu trzeba uciekać się do" Wiele banalnych komentarzy " hack, lub użyć clang-format off, Gdy masz coś takiego. Są to po prostu wewnętrzne ograniczenia narzędzia. Jeśli nie jesteś szczęśliwy, że kiedykolwiek musisz robić takie rzeczy, to prawdopodobnie nie jest to narzędzie dla Ciebie.
 25
Author: Chris Beck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-18 19:11:11

Nie jestem pewien, czy formatujesz clang, aby robić dokładnie to, co chcesz, ale jest możliwe, aby powiedzieć clang-format, aby zostawił sekcje kodu same. Używam tego do dokładnie takiego scenariusza, o którym mówisz, bloków kodu, w których bardzo konkretne formatowanie ułatwia czytanie.

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
}

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

 11
Author: MattG,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-18 10:12:52

Nie widziałem obecnie w dokumentacji niczego, co mogłoby ci na to pozwolić.

Ustawienie ColumnLimit na 0 nadal zachowa zawijanie tekstu.

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"
  };
}
 7
Author: Sam P,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-17 16:20:10