Subject: bug#66911: CC Mode 5.35.2 (C++//l); Noise macro being taken as anchor to class-open

From: Arsen Arsenović <[email-masked]>
Date: Fri, 17 Nov 2023 20:16:31 +0100

Hi Alan,

Thanks (again!) for working on this.

Alan Mackenzie <[email-masked]> writes:

> Hello, Arsen.
>
> On Thu, Nov 16, 2023 at 21:29:29 +0100, Arsen Arsenović wrote:
>> Hi Alan,
>
>> Thanks for working on this.
>
>> Alan Mackenzie <[email-masked]> writes:
>
> [ .... ]
>
>> > That was a mistake - the second anchor point is needed on class-open
>> > lines, not topmost-intro-cont ones.
>
>> > I've coded up this patch, which I include below.  Actually, only the last
>> > two smallish hunks of the patch are new, the rest is what you've seen
>> > before, so it will be necessary to start from a clean copy of
>> > cc-engine.el again.
>
>> > The syntactical context of the HERE line (the opening brace of that
>> > class) is now something like:
>
>> >     ((class-open 76 107))
>
>> > , where 76 is the position of the template keyword and 107 that of the
>> > class keyword.  When there's no template, both of these anchor points are
>> > the same.  Actually, that's not quite accurate: the 107 is the point
>> > after the indentation of the line that class is on; it just seemed better
>> > that way.
>
>> This behavior seems reasonable to me at a glance and at a test.  I like
>> the idea :-)
>
> [ .... ]
>
>> > So, again, please let me know how you get on with this patch.  Is the
>> > extra anchor point sufficient to write an alignment function to get the
>> > indentation you want?
>
>> The following did work nicely (after I made c-langelem-2nd-col, by
>> copying and altering c-langelem-col as is obvious).  I'm not sure if it
>> is idiomatic or the cleanest solution, though (plus, my Elisp-fu is
>> poor).
>
>> --8<---------------cut here---------------start------------->8---
>> (defun glibcxx-style/line-up-struct (sym-form)
>>   "Lines up a class-open with its prior struct line"
>>   (if (not (eq 'class-open (c-langelem-sym sym-form)))
>>       nil
>>     (let ((col (c-langelem-2nd-col c-syntactic-element t)))
>>       (if col
>> 	  (vector col)
>> 	nil))))
>> --8<---------------cut here---------------end--------------->8---
>
>> ... however, I noticed that class-close still anchors on the template
>> that precedes it, and seems to not have a 2nd-pos to play with, so the
>> above line-up fn, when set on class-open, produces:
>
>> --8<---------------cut here---------------start------------->8---
>> template<typename foo>
>>   struct f
>>   {
>> };
>> --8<---------------cut here---------------end--------------->8---
>
> Yes.  I should have noticed this myself.  :-(
>
>> ... so, we're getting quite close!
>
> So, please try out the new patch (below) which supplies the second anchor
> point to class-close too.  The patch applies cleanly to the Emacs master
> branch.  Again, please start off with a clean cc-engine.el before
> applying the new patch, not the version with the previous patch applied.

Excellent!  The following did it:

--8<---------------cut here---------------start------------->8---
(defun glibcxx-style/line-up-struct (sym-form)
  "Lines up a class-open/close with its prior struct line"
  (if (not (seq-contains-p '(class-open class-close)
			   (c-langelem-sym sym-form)))
      nil
    (let ((col (c-langelem-2nd-col c-syntactic-element t)))
      (if col
	  (vector col)
	nil))))
--8<---------------cut here---------------end--------------->8---

Again, unsure if it is the most elegant solution, or even if it's a good
one.  But it did work!

I've copied c-langelem-2nd-col again to do the above.  Is that helper
intentionally omitted?  Is there perhaps a more idiomatic solution?

In any case, I'll be sure to use this as soon as it lands in the Emacs
VCS.

Thanks again, have a lovely night!
-- 
Arsen Arsenović