Author Topic: Question about continuation indent. Can this be configured?  (Read 1717 times)

ehoffman

  • Community Member
  • Posts: 18
  • Hero Points: 0
Hi

I was wondering, I have this piece of code

Code: [Select]
...
printf("%s  address family: %d%s\n",
       ifa->ifa_name, family,
       (family == AF_PACKET) ? " (AF_PACKET)" :
       (family == AF_INET) ?   " (AF_INET)" :
       (family == AF_INET6) ?  " (AF_INET6)" : "");
...

When I run the beautifier, it comes out like this:
Code: [Select]
...
printf("%s  address family: %d%s\n",
       ifa->ifa_name, family,
       (family == AF_PACKET) ? " (AF_PACKET)" :
                               (family == AF_INET) ?   " (AF_INET)" :
                                                     (family == AF_INET6) ?  " (AF_INET6)" : "");
...

That is, the continuation indentation align each line to the conditional operator question mark.

I found no way to modify this behavior, or to tell SlickEdit not to touch the indentation.  Have I missed an option?  I would expect to see an option for that under the C/C++ formatting dialog box, under Indent->Continuation Indent.  I have found no such option, or at least, everything I tried didn't cut it.

Best regards,
Eric

patrick

  • SlickEdit Team Member
  • Senior Community Member
  • *
  • Posts: 950
  • Hero Points: 69
Re: Question about continuation indent. Can this be configured?
« Reply #1 on: May 12, 2016, 02:36:27 pm »
You're right, there is no option to turn off the alignment for the "? :" operator.  That's what's overriding the continuation indent setting in this case. I can add an option to v21 that allows you to turn off the alignment rules for "? :" so the normal indent rules apply for whatever context the "? :" appears in.

ehoffman

  • Community Member
  • Posts: 18
  • Hero Points: 0
Re: Question about continuation indent. Can this be configured?
« Reply #2 on: May 12, 2016, 06:02:54 pm »
Thanks for your reply Patrick.

Well, I do think that the beautifier (and auto-format) should have every behavior configurable.  There are a few things like that which seem not to be configurable.

Here are a few examples (all in C/C++ context):

---------------

This is probably a bug, but in SE 20.x (was not like that in 19.x), if you have auto-surround enabled (that is, if you select some text, like an constant in an if statement, and type an opening parenthesis, it will surround the text with parenthesis), the behavior is different depending on if you selected the text manually, or through a search.

To demonstrate, suppose this code:
Code: [Select]
...
return (state & SM_ACTIVE ? true : false); /* Better put parenthesis so there's no confusion on precedence rules. */
...

Then, you wish to surround the evaluation with parenthesis.  You can select "state & SM_ACTIVE", press opening parenthesis, and it will surround the selection with parenthesis.  Moreover, SE, not knowing if your intention is to surround the selection, or overwrite it with something entirely different, keep the selection active.  So, if your intention is to replace the text with something different, as in following example:

Code: [Select]
...
if (link_state & LS_UP) {dome something...}
...

and you wish to replace LS_UP with (LS_ACTIVE | LS_DISABLED).  You can highlight LS_UP manually, and type (LS_ACTIVE | LS_DISABLED).  The opening parenthesis will auto-surround LS_UP (not what you want), then keeping LS_UP highlighted, as soon as you type LS_ACTIVE..., LS_UP is overwritten.  So you end up with the result you wanted (overwriting).

However, above I highlighted LS_UP manually (this is the distinction from the issue bellow).  If I do a search for LS_UP.  That is, <ctrl-f> LS_UP <enter>.  Then you end up with LS_UP highlighted, as above.  However, there is an issue if I start replacing the string.  As I type the opening parenthesis, LS_UP is auto-surrounded and LS_UP is still highlighted (as above), but here, the cursor is placed on the left of the opening parenthesis.  As soon as I continue typing LS_ACTIVE..., the LS_ACTIVE... is inserted on the left of the parenthesis, leaving intact the original string (which is now fully-surrounded).

Example, step by step (with color :P)
1st case, with LS_UP highlighted manually, type (LS_AC...:

if (link_state & |LS_UP) {do something...};
if (link_state & (|LS_UP)) {do something...};
if (link_state & (L|)) {do something...};
if (link_state & (LS|)) {do something...};
if (link_state & (LS_|)) {do something...};
if (link_state & (LS_A|)) {do something...};
if (link_state & (LS_AC|)) {do something...};
if (link_state & (LS_ACT|)) {do something...};
if (link_state & (LS_ACTI|)) {do something...};
...
if (link_state & (LS_ACTIVE | LS_DISABLED|)) {do something...};

2nd case, with LS_UP highlighted through the search function:

if (link_state & |LS_UP) {do something...};
if (link_state & |(LS_UP)) {do something...};
if (link_state & L|(LS_UP)) {do something...};
if (link_state & LS|(LS_UP)) {do something...};
if (link_state & LS_|(LS_UP)) {do something...};
if (link_state & LS_A|(LS_UP)) {do something...};
if (link_state & LS_AC|(LS_UP)) {do something...};
if (link_state & LS_ACT|(LS_UP)) {do something...};
if (link_state & LS_ACTI|(LS_UP)) {do something...};
...
if (link_state & LS_ACTIVE | LS_DISABLED|(LS_UP)) {do something...};

---------------

Another case, if you enable the formatting option Spacing-->Statements-->General Statement-->Space after semicolumn, and set it to ON, this will make sure that spaces are inserted after the semicolumn.  For example:

Disabled:
a = 1;b = 2;c = 3;
Enabled:
a = 1; b = 2; c = 3;

If you beautify the code, it will add spaces after every semi-column, even at end of line.   If the semi-column is the last character at end of line (or end of file), then the beautifier should probably not insert a space after this last semi-column.  I have checked and the behavior is correct if the character following the semi-column is a space or a tab.

---------------

It would be nice to have an option to left-align local pointer variables declaration with the asterisk sticking out on the left, or to not separate the assignment from the variable name.  For example, there is an option Spacing-->Declarations-->Local Var Declarations-->Name Justification, that let you align the names:

Without:
Code: [Select]
void func(void)
{
    int  a;
    bool b = true;
    char *pointer;
    char **str_array;
    short some_very_long_variable_name;
    ...
}

With:
Code: [Select]
void func(void)
{
    int   a;
    bool  b                            = true;
    char  *pointer;
    char  **str_array;
    short some_very_long_variable_name;
    ...
}

It would be nice to left-align with the pointer asterisk sticking out and/or with preserving spacing between variable name and assignment.  For ex:

Code: [Select]
void func(void)
{
    int     a;
    bool    b = true;
    char   *pointer;
    char  **str_array;
    short   some_very_long_variable_name;
    ...
}

---------------

Following the last feature, it would be nice to have this for function parameters too.  Maybe in 2 different option groups (newlines and spacing).  To have a way to always put each function parameters on different lines, and to have the above spacing rules apply to the parameters.  So to force to always have something like:

Code: [Select]
int func(int         a,
         const char *msg,
         char       *ret_str,
         int         flags = FLAGS_NONE);


I know this is a lot!  But those would be nice-to-have features  ;)

Thanks,
Eric
« Last Edit: May 12, 2016, 06:04:56 pm by ehoffman »

hs2

  • Senior Community Member
  • Posts: 2733
  • Hero Points: 285
Re: Question about continuation indent. Can this be configured?
« Reply #3 on: May 12, 2016, 08:56:44 pm »
Just my 2ct:
I've moved to this notation for pointers (and references):

Code: [Select]
char*              pointer_to_char;
char const*        pointer_to_const_char;
char const* const  const_pointer_to_const_char;

I found it's more intuitive since 'pointer' (resp. reference) belongs to the data type and const-ness is easy to get right and is more readable.
(found on the web: world simplest 'const' rule: just put 'const' to the immediate right of the const_thing)
Minor side effect is that alignments are more easy, too  ;D
HS2

ehoffman

  • Community Member
  • Posts: 18
  • Hero Points: 0
Re: Question about continuation indent. Can this be configured?
« Reply #4 on: May 13, 2016, 02:01:56 am »
Hello hs2

Yes, this is a long debate, even where I work we had this discussion about placement of the asterisk ;D  The thing is that it's pretty much a question of preference.  I personally am used to the older way of using char *ptr.  Although sometime even I have moments where I prefer the other way, mostly when writing something like void* data.  There are pros and cons to both notations.  One may argue that it's easier to know that a variable is a pointer.  When seeing char *msg, you know that msg is a pointer.  The other way is less intuitive unless you have a good established rule of naming the variables using prefix or suffix, for example: char* pMsg; char* PMsg; char* msg_ptr; char* p_msg;.  One of the things though that the "char *msg" form has over "char* msg" is in the following scenario: char* ptr_a, ptr_b, ptr_c;  Only ptr_a is actually a pointer.  In that case, the following look kind of awkward: char* ptr_a,* ptr_b,* ptr_c; :P

I have no intention to start a war here!   :D  That is not the point.  The real point is that the beautifier is mostly (95%) of the time used when taking code from somewhere else and bringing it to our application, or when refactoring the formatting of existing source code.  In this case, it's really irrelevant how you choose to define your declarations, as the code is already coded!  You can always beautify the pointer declarations, but unless the variable themselves are properly named, it's probably better to leave them as it is.

As a final word, I always joke that we'll remove all spaces, as in char*func(int*refer) which is valid!

hs2

  • Senior Community Member
  • Posts: 2733
  • Hero Points: 285
Re: Question about continuation indent. Can this be configured?
« Reply #5 on: May 13, 2016, 08:18:16 am »
Sure - I also didn't want to start an asterisk war ;) Just some thoughts what turned out to be pretty useful for ME.
And yes, naming is very important. BTW I found encoding parts of/the data type into the identifier is less helpful as it might seem, but context/scope prefixes ('m_' for members etc.) are. That's another long story ...
There are more or less strong opinions regarding coding style and I usually insist only on some very basic common criterias like indent, brace style, no TABs and such.
Let's see what the great SlickTeam can do more for us :)
HS2
« Last Edit: May 13, 2016, 08:20:21 am by hs2 »

patrick

  • SlickEdit Team Member
  • Senior Community Member
  • *
  • Posts: 950
  • Hero Points: 69
Re: Question about continuation indent. Can this be configured?
« Reply #6 on: May 16, 2016, 02:10:00 pm »
For the auto-surround, I can reproduce that behavior.  We'll take a look at what's causing that.

For the space after semicolon - yep, there's a fix we've planned going into v21 for this.  The short version is there is some code that decides whether to keep non-significant whitespace like that depending on where the cursor or hotspots are.  So if an alias had "something();%\c", we would put/leave the space after the semicolon if the setting said it should be there.  But there's a bug in the logic that decides, so it's leaving trailing spaces a lot of the time when it shouldn't.

The pointer spacing wouldn't be a bad option to have.  Same for the function parameter alignment - that one I know what the scope of the change would be, since we do something similar for SystemVerilog module parameters.   I can't promise either for v21, but if I have the time, I'll get them in.

patrick

  • SlickEdit Team Member
  • Senior Community Member
  • *
  • Posts: 950
  • Hero Points: 69
Re: Question about continuation indent. Can this be configured?
« Reply #7 on: August 02, 2016, 09:14:54 pm »
In the upcoming v21 beta3, there's now an option under Indent -> Indent Rule Exceptions that allows you to turn off the automatic alignment of the ternary ? operator.   

Beta 3 should also fix the problems with trailing spaces that you brought up.