Полное разделение длинных определений функций не только на запятые с помощью Uncrustify

Я использую Uncrustify v0.60 для форматирования моего исходного кода C++. Для настройки Uncrustify я использую UniversalIndentGUI v1.2.0 rev.1070.

в Line Splitting options раздел UniversalIndentGUI я установил Code Width до 120

Предположим, у меня есть следующий пример кода:

namespace MyNameSpace
{
    class MyClass
    {
    public:
        std::map< std::string, MyOtherClass* >* ConstructMyOtherClassMap( std::vector< std::string >* allNames, int arg0, double arg1, char arg2 );

    }
}

Объявление этого метода заканчивается в столбце> 120, поэтому Uncrustify возвращает следующий результат:

namespace MyNameSpace
{
    class MyClass
    {
    public:
        std::map< std::string, MyOtherClass* >* ConstructMyOtherClassMap( std::vector< std::string >* allNames,
            int arg0,
            double arg1,
            char arg2 );

    }
}

Как вы можете видеть, Uncrustify разделяет список параметров по запятым, и теперь объявление метода заканчивается в столбце < 120. Однако в этом случае я хочу, чтобы Uncrustify также поместил первый параметр в свою собственную строку, например так:

namespace MyNameSpace
{
    class MyClass
    {
    public:
        std::map< std::string, MyOtherClass* >* ConstructMyOtherClassMap( 
            std::vector< std::string >* allNames,
            int arg0,
            double arg1,
            char arg2 );

    }
}

Возможно ли это сделать с помощью Uncrustify v0.60?

Мне известны варианты в Newline adding and removing раздел, такой как Nl Func Decl Start или же Nl Func Def Start которые добавляют новую строку после открывающей скобки ( символ, но это также влияет на код длиной менее 120 символов. Я не хочу, чтобы следующий код распределялся по нескольким строкам:

int Sum( int a, int b, int c, int d );

2 ответа

Решение

К сожалению, это невозможно в текущем состоянии Uncrustify. Поэтому лучшее, что вы можете сделать, - это настроить параметры, которые вы упомянули, следующим образом:

nl_func_decl_start = ignore
nl_func_def_start  = ignore

nl_func_decl_start_single = ignore
nl_func_def_start_single  = ignore

ls_func_split_full = true

и вручную обернуть первый параметр в соответствующих случаях. Однако лично я не думаю, что это хорошая идея. Просто дайте ему выполнить автоматическую упаковку по запросу. Например, мне нравятся те же настройки, которые я перечислил выше, и в любом случае у меня все еще очень аккуратный код. Примеры следуют.

Без переноса - параметры конструктора и список инициализатора конструктора вписываются в максимальную длину строки:

PluginDialog::
PluginDialog(QString const& path, QStringList const& fileNames, QWidget* parent): QDialog(parent), label(new QLabel), treeWidget(new QTreeWidget), okButton(new QPushButton(tr("OK"))) {
  // ...
}

Теперь они не подходят, и по соглашению мы решили сначала обернуть список инициализаторов:

PluginDialog::
PluginDialog(QString const& path, QStringList const& fileNames, QWidget* parent): QDialog(parent), 
                                                                                  label(new QLabel), 
                                                                                  treeWidget(new QTreeWidget), 
                                                                                  okButton(new QPushButton(tr("OK"))) {
  // ...
}

противоположное соглашение также возможно:

PluginDialog::
PluginDialog(QString const&     path,
             QStringList const& fileNames,
             QWidget*           parent): QDialog(parent), label(new QLabel), treeWidget(new QTreeWidget), okButton(new QPushButton(tr("OK"))) {
  // ...
}

Теперь ни один из двух предыдущих случаев не подходит, и поэтому любой из них объединяется в следующую и единственно возможную конфигурацию:

PluginDialog::
PluginDialog(QString const&     path,
             QStringList const& fileNames,
             QWidget*           parent): QDialog(parent),
                                         label(new QLabel),
                                         treeWidget(new QTreeWidget),
                                         okButton(new QPushButton(tr("OK"))) {
  // ...
}

Теперь мы не подходим снова, и по соглашению мы решили переместить столбец списка инициализатора конструктора в столбец списка параметров конструктора:

PluginDialog::
PluginDialog(QString const&     path,
             QStringList const& fileNames,
             QWidget*           parent):
  QDialog(parent),
  label(new QLabel),
  treeWidget(new QTreeWidget),
  okButton(new QPushButton(tr("OK"))) {
  // ...
}

кстати, у нас снова разветвление, то есть это тоже возможно:

PluginDialog::
PluginDialog(
  QString const&     path,
  QStringList const& fileNames,
  QWidget*           parent): QDialog(parent),
                              label(new QLabel),
                              treeWidget(new QTreeWidget),
                              okButton(new QPushButton(tr("OK"))) {
  // ...
}

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

PluginDialog::
PluginDialog(
  QString const&     path,
  QStringList const& fileNames,
  QWidget*           parent):
  QDialog(parent),
  label(new QLabel),
  treeWidget(new QTreeWidget),
  okButton(new QPushButton(tr("OK"))) {
  // ...
}

Было бы замечательно, если бы Uncrustify предложила своего рода опцию "избежать путаницы", как это делает Jindent. В этом случае последний фрагмент, например, будет выглядеть следующим образом:

PluginDialog::
PluginDialog(
  QString const&     path,
  QStringList const& fileNames,
  QWidget*           parent):
    QDialog(parent),
    label(new QLabel),
    treeWidget(new QTreeWidget),
    okButton(new QPushButton(tr("OK"))) {
  // ...
}

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

Для меня (используя Uncrustify 0.63), чтобы достичь того, что вы хотели, работает эта комбинация:

Добавить или удалить символ новой строки после '(' в объявлении функции

nl_func_decl_start                       = add

Добавить или удалить символ новой строки после '(' в определении функции

nl_func_def_start                        = add

Переопределяет nl_func_decl_start, когда есть только один параметр.

nl_func_decl_start_single                = remove

Переопределяет nl_func_def_start, когда есть только один параметр.

nl_func_def_start_single                 = remove

Добавить или удалить символ новой строки после каждого ',' в объявлении функции

nl_func_decl_args                        = add

Добавить или удалить символ новой строки после каждого "," в определении функции

nl_func_def_args                         = add

Добавьте или удалите символ новой строки перед ')' в объявлении функции

nl_func_decl_end                         = add

Добавьте или удалите символ новой строки перед ')' в определении функции

nl_func_def_end                          = add

Переопределяет nl_func_decl_end, когда есть только один параметр.

nl_func_decl_end_single                  = remove

Переопределяет nl_func_def_end, когда есть только один параметр.

nl_func_def_end_single                   = remove

Компактная версия (без объяснения причин):

nl_func_decl_start                       = add
nl_func_def_start                        = add
nl_func_decl_start_single                = remove
nl_func_def_start_single                 = remove
nl_func_decl_args                        = add
nl_func_def_args                         = add
nl_func_decl_end                         = add
nl_func_def_end                          = add
nl_func_decl_end_single                  = remove
nl_func_def_end_single                   = remove
Другие вопросы по тегам