Разрывы строк в формате 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 символов.

Есть ли такая опция? Ничто в документах не выделялось мне.

5 ответов

Решение

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

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

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

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

  • Вы можете легко контролировать разрывы строк,

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

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

Добавьте запятую после последней строки. Это говорит clang-форматировать его по вертикали. Пример: 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(); }

Я не уверен, что вы используете clang-формат, чтобы делать именно то, что вы хотите, но можно сказать, что clang-формат оставляет фрагменты кода в покое. Я использую это как раз для того сценария, о котором вы говорите, блоков кода, где очень специфическое форматирование облегчает чтение.

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

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

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

С этими правилами в формате .clang

      BasedOnStyle: LLVM
AlignAfterOpenBracket: AlwaysBreak
AllowShortBlocksOnASingleLine: Empty
BreakConstructorInitializers: AfterColon
BinPackArguments: false  // Important for this case
BinPackParameters: false  // Important for this case
AlignEscapedNewlines: DontAlign
SpacesBeforeTrailingComments: 2
AllowShortBlocksOnASingleLine: Never
AllowShortFunctionsOnASingleLine: None
ContinuationIndentWidth: 2
IndentWidth: 2
Standard: c++17
UseTab: Never

Получилось форматирование, близкое к ожидаемому результату

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

int main() {
  auto vec = get_vec();
}
Другие вопросы по тегам