2015-11-11 4 views
32

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

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

+0

Для вашего конкретного примера установите 'AllowShortFunctionsOnASingleLine: None'. – dejvuth

+0

Ну, это останавливает его от разворачивания 'main', но меня больше беспокоит инициализация вектора в целом. Если вектор был инициализирован таким образом в другой (более длинной) функции, он все равно будет разворачиваться. – zmb

+0

Мне интересно, поможет ли настройка различных вариантов «штрафа», но все они кажутся штрафами, связанными с разрывом линий, а не «их развязыванием». – zmb

ответ

22

Так что, возился в коде формата лязг и сделал несколько исправлений, вот мои два цента:

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

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

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

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

    • устанавливающего ограничение столбца
    • с помощью «Параметры пакета БИН» варианты
    • установление штрафов для различных видов перерывов - - перерыв после типа возврата функции, разрыв перед первым параметром вызова, разрыв строкового литерала, нарушение комментария ...
    • размещение комментариев в конце строки (формат clang не может удалить комментарий и поэтому должен разбить строку)
    • использовать лязг-формат/выключают директив

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

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

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

Или, если у вас есть 4 х 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 }; 

Если вы позволяете лязг формат пробегает такие вещи, как это он просто будет искажать их, и AFAIK нет простого способа сделайте так, чтобы они отформатировали их, поэтому вам просто нужно прибегнуть либо к «большому количеству тривиальных комментариев», либо использовать clang-format, когда у вас есть что-то вроде этого. Это просто неотъемлемые ограничения инструмента. Если вам не нравится когда-либо делать что-то подобное, то это, вероятно, не инструмент для вас.

+0

Отличный ответ. Ваше предложение кажется немного лучше, чем '// clang-format off', и объяснение того, почему он ведет себя таким образом, имеет большой смысл. – zmb

+0

ColumnLimit 0 все еще сохраняет разрывы строк. Как объяснить это? – KindDragon

6

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

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

Он также хочет установить 'ColumnLimit' в 120? – Danh

+1

Справа. Это сохраняет мою упаковку, но не делает ничего, чтобы исправить слишком длинные строки (что является основным преимуществом инструмента, IMO). – zmb

+0

Это компромисс, но без проблем. Я рад, что программисты обернутся на 100 вручную, если clang-format не изменяет новые строки в определениях моего массива, в моих более сложных выражениях 'std :: cout', моих списках параметров enum, ... – Gauthier

9

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

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

+0

Я не говорю, что это плохой ответ, но какое абсолютно ужасное решение проблемы. Запутайте свой код комментариями, чтобы сделать автоматическое форматирование. – Martin

+0

Возможно, но на практике я редко использовал это, когда хотел нарушить правила форматирования. Я обычно ценю, что так выхожу, и не понимаю, что его злоупотребляют «загромождением вашего кода». Использование инструмента плохо часто у пользователя – MattG

Смежные вопросы