Подтвердить что ты не робот

Разрыв строки в стиле Кланг

Я ищу настройку 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 символов.

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

4b9b3361

Ответ 1

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

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

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

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

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

    • установка предела столбца
    • с использованием опций "параметры пакета bin"
    • установление штрафов за различные виды разрывов - перерыв после типа возврата функции, разрыв перед первым параметром вызова, разрыв строкового литерала, нарушение комментария...
    • размещение комментариев в конце строки (формат clang не может удалить комментарий и поэтому должен разбить строку)
    • используйте директивы off/on для clang-format

Вот одна вещь, которую вы могли бы попробовать:

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 off, когда у вас есть что-то вроде этого. Это просто неотъемлемые ограничения инструмента. Если вам не нравится когда-либо делать что-то подобное, то это, вероятно, не инструмент для вас.

Ответ 2

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

Ответ 3

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

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