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 символов.

есть такой вариант? Ничто в документах не бросалось мне в глаза.

3 ответов


Итак, покопавшись в коде формата clang и сделав несколько патчей, вот мои два цента:

  • формат Clang основан на,

    • разбор AST с помощью libclang, что в основном устраняет все пробелы
    • разбиение последовательности токенов на "развернутые строки", которые похожи на" логические " строки кода
    • применение правил / информация о конфигурации, чтобы иногда разделить "развернутые строки" на меньшие единицы
    • выплюнуть все это снова с новыми пробелами / отступами

    нелегко заставить его уважать исходный whitepsace, такой вид бросается, когда вы впервые анализируете код.

  • вы можете контролировать, где он помещает разрывы линии, наиболее легко, по

    • установка ограничения столбца
    • использование параметров" bin pack"
    • установка штрафов за различные виды перерывов -- break после возвращаемого типа функции, break перед первым параметром вызова, break строковый литерал, break комментарий...
    • размещение комментариев в конце строки (формат 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 очень много о навязывании единого формата по всей базе кода, убедившись, что все строковые литералы отформатированы в одном стиле везде в вашей программе. Если вы хотите иметь микроуровневый контроль над решениями о разрыве линии, это не совсем в духе инструмент, и вам придется делать такие вещи, как отключить его.

иногда это может расстраивать esp. когда вы хотите делать что-то с массивами и выровнять столбцы или что-то еще-например, вот некоторый естественный код из 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 работает над этим, он, как правило, не собирается выравнивать правый столбец, он собирается разместить его фиксированное количество пробелов после запятых, и вы не можете много сделать с этим afaik.

или, если у вас есть Матрица 4 x 4 для использования с 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 };

если вы позволите Clang-format работать над такими вещами, как это, он просто будет калечить их, и afaik нет простого способа сделать его форматировать их красиво, поэтому вам просто нужно прибегнуть либо к "множеству тривиальных комментариев", либо использовать clang-format, когда у вас есть что-то вроде этого. Это просто внутренние ограничения инструмента. Если вы не счастливы когда-либо делать такие вещи, то это, вероятно, не инструмент для вы.


Я не уверен, что вы 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


Я ничего не видел в настоящее время в документация это позволит вам сделать это.

установка 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"
  };
}