Question

I'm using Uncrustify v0.60 to format my C++ source code. In order to configure Uncrustify I am using the UniversalIndentGUI v1.2.0 rev.1070.

In the Line Splitting options section of UniversalIndentGUI I have set Code Width to 120.

Assume I have the following piece of example code:

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

    }
}

That method declaration ends in a column > 120, so Uncrustify returns the following result:

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

    }
}

As you can see Uncrustify split the parameter list at the commas and now the method declaration ends in a column < 120. However, in this case I want Uncrustify to put the first parameter on it's own line as well, like this:

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

    }
}

Is it possible to do this with Uncrustify v0.60?

I am aware of options in the Newline adding and removing section such as Nl Func Decl Start or Nl Func Def Start that add a newline after the opening parenthesis ( character but this also affects code that is < 120 characters long. I don't want to have the following code spread across several lines:

int Sum( int a, int b, int c, int d );
Was it helpful?

Solution

Unfortunately, this is not possible with the current state of Uncrustify. So the best thing you could do is to configure the options that you've mentioned in the following way:

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

and to manually wrap the first parameter in appropriate cases. However, personally, I don't think it is a good idea. Just let it perform lazy/on demand wrapping automatically. For instance, I enjoy the same settings I've listed above, and still have very neat code in any possible case. Examples follow.

No wrapping - constructor parameters and constructor initializer list both fit into maximal line length:

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

Now they do not fit, and by convention we decide to wrap initializer list first:

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

the opposite convention could be possible as well:

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

Now either case from 2 previous ones does not fit, and therefore either of them merge into the next and the only possible configuration:

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

Now we do not fit again, and by convention we decide to move constructor initializer list column under the constructor parameter list column:

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

by the way we have branching case again, i.e. this could be possible as well:

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

Finally, either case from 2 previous ones does not fit, and therefore either of them merge into the final and the only possible configuration:

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

It would be great if Uncrustify offered sort of "avoid confusing indentations" option like Jindent does. In this case, the last snippet would for example look as follows:

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

which is clearly more readable and pleasing. I proposed this feature for Uncrustify. However, I doubt we can see it implemented any time soon because the author of this project seems to be either too busy with some other stuff or not really interested in developing this project actively any more.

OTHER TIPS

For me (using Uncrustify 0.63), to achieve what you wanted, it works this combination:

Add or remove newline after '(' in a function declaration

nl_func_decl_start                       = add

Add or remove newline after '(' in a function definition

nl_func_def_start                        = add

Overrides nl_func_decl_start when there is only one parameter.

nl_func_decl_start_single                = remove

Overrides nl_func_def_start when there is only one parameter.

nl_func_def_start_single                 = remove

Add or remove newline after each ',' in a function declaration

nl_func_decl_args                        = add

Add or remove newline after each ',' in a function definition

nl_func_def_args                         = add

Add or remove newline before the ')' in a function declaration

nl_func_decl_end                         = add

Add or remove newline before the ')' in a function definition

nl_func_def_end                          = add

Overrides nl_func_decl_end when there is only one parameter.

nl_func_decl_end_single                  = remove

Overrides nl_func_def_end when there is only one parameter.

nl_func_def_end_single                   = remove

The compact version (without explanation):

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top