From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Alan Mackenzie Newsgroups: gmane.emacs.bugs Subject: bug#21409: 24.5; Wrong syntactic information for two line statement in an arglist Date: Sun, 13 Mar 2022 13:43:11 +0000 Message-ID: References: <87eek7taft.fsf@gnus.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="39208"; mail-complaints-to="usenet@ciao.gmane.io" Cc: acm@muc.de, Lars Ingebrigtsen , 21409@debbugs.gnu.org To: Gulshan Singh Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sun Mar 13 14:44:24 2022 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nTOWF-0009yb-Gt for geb-bug-gnu-emacs@m.gmane-mx.org; Sun, 13 Mar 2022 14:44:23 +0100 Original-Received: from localhost ([::1]:54336 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nTOWD-0007NR-Tm for geb-bug-gnu-emacs@m.gmane-mx.org; Sun, 13 Mar 2022 09:44:21 -0400 Original-Received: from eggs.gnu.org ([209.51.188.92]:55088) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nTOVu-0007NH-TA for bug-gnu-emacs@gnu.org; Sun, 13 Mar 2022 09:44:02 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:47939) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1nTOVu-0006UU-K8; Sun, 13 Mar 2022 09:44:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1nTOVu-0002ay-G5; Sun, 13 Mar 2022 09:44:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Alan Mackenzie Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org, bug-cc-mode@gnu.org Resent-Date: Sun, 13 Mar 2022 13:44:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 21409 X-GNU-PR-Package: emacs,cc-mode Original-Received: via spool by 21409-submit@debbugs.gnu.org id=B21409.16471790089920 (code B ref 21409); Sun, 13 Mar 2022 13:44:02 +0000 Original-Received: (at 21409) by debbugs.gnu.org; 13 Mar 2022 13:43:28 +0000 Original-Received: from localhost ([127.0.0.1]:41836 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1nTOVI-0002Zt-Mh for submit@debbugs.gnu.org; Sun, 13 Mar 2022 09:43:28 -0400 Original-Received: from colin.muc.de ([193.149.48.1]:19929 helo=mail.muc.de) by debbugs.gnu.org with smtp (Exim 4.84_2) (envelope-from ) id 1nTOVC-0002Zb-QV for 21409@debbugs.gnu.org; Sun, 13 Mar 2022 09:43:23 -0400 Original-Received: (qmail 45935 invoked by uid 3782); 13 Mar 2022 13:43:12 -0000 Original-Received: from acm.muc.de (p4fe157ef.dip0.t-ipconnect.de [79.225.87.239]) (using STARTTLS) by colin.muc.de (tmda-ofmipd) with ESMTP; Sun, 13 Mar 2022 14:43:11 +0100 Original-Received: (qmail 7532 invoked by uid 1000); 13 Mar 2022 13:43:11 -0000 Content-Disposition: inline In-Reply-To: X-Submission-Agent: TMDA/1.3.x (Ph3nix) X-Primary-Address: acm@muc.de X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:228294 Archived-At: Hello again, Gulshan. On Sat, Mar 12, 2022 at 11:32:50 +0000, Alan Mackenzie wrote: > Sorry I missed your bug report back in 2015. > On Fri, Mar 11, 2022 at 17:52:38 -0800, Gulshan Singh wrote: > > On Thu, Dec 3, 2020 at 3:07 AM Lars Ingebrigtsen wrote: > > > Gulshan Singh writes: > > > > In c-mode (and all derivatives), the following code has the wrong > > > > syntactic information (at least, in my opinion): > > > > foo(bar > > > > .baz() > > > > .qux()); [ .... ] > I think the best solution to the problem would be to write a new Line-Up > function for this particular scenario, and to make it available to users > to insert into the c-offsets-alist entry for arglist-cont-nonempty. The > page "Customizing Indentation" in the CC Mode manual is pertinent here. > But first, we need to firm up the specification. What, precisely, will > trigger this new Line-Up function? I've come up with an answer to that question. On _any_ argument continued onto the next line, we indent it c-basic-offset from the _first_ argument. This is easy to implement, since it's a minor variation on c-lineup-arglist. See the following patch for an example of what that does. [ .... ] > > It's definitely reasonable, but it's not what I'd prefer, which would be > > this: > > foo(bar > > .baz() > > .qux()); > > `.baz()` and `.qux()` are indented two spaces (my value for > > `c-basic-offset`) from the start of `bar`, as opposed to aligned with > > `bar`. This matches what happens if the call to `foo` isn't there: > > bar > > .baz() > > .qux(); I've hacked up the following patch, which introduces the new Line-Up function c-lineup-arglist-+. To use it (temporarily) do C-c C-o RET on the .baz() line, and change the setting for arglist-cont-nonempty from (c-lineup-gcc-asm-reg c-lineup-arglist) to (c-lineup-gcc-asm-reg c-lineup-arglist-+ c-lineup-arglist) .. Note that c-lineup-arglist-+ is a function which returns nil to mean "not appropriate here", so it must be in a list, not in the last position. This is all better explained in the CC Mode manual on page "c-offsets-alist". If this patch does what you want, you can then incorporate the new Line-Up function into your CC Mode style, or however else you set up your indentation. If you want any help with this, feel free to ask on this list, or on bug-cc-mode@gnu.org. Here's the patch. It should apply to either the latest version of stand-alone CC Mode, or the version in the Emacs master branch. Please apply the patch, byte compile the changed file (or all of CC Mode), and make the amendment to your indentation setup noted above. (If you want any help with any of this, feel free to send me private email). Then please let us know if this patch does the Right Thing. Thanks! diff -r 1a0681da2be1 cc-align.el --- a/cc-align.el Thu Feb 10 16:46:58 2022 +0000 +++ b/cc-align.el Sun Mar 13 13:35:56 2022 +0000 @@ -207,6 +207,58 @@ (vector (current-column))))))) ;; Contributed by Kevin Ryde . +(defun c-lineup-argcont-1 (elem) + ;; Move to the start of the current arg and return non-nil, otherwise + ;; return nil. + (beginning-of-line) + + (when (eq (car elem) 'arglist-cont-nonempty) + ;; Our argument list might not be the innermost one. If it + ;; isn't, go back to the last position in it. We do this by + ;; stepping back over open parens until we get to the open paren + ;; of our argument list. + (let ((open-paren (c-langelem-2nd-pos c-syntactic-element)) + (paren-state (c-parse-state))) + (while (not (eq (car paren-state) open-paren)) + (unless (consp (car paren-state)) ;; ignore matched braces + (goto-char (car paren-state))) + (setq paren-state (cdr paren-state))))) + + (let ((start (point)) c) + + (when (bolp) + ;; Previous line ending in a comma means we're the start of an + ;; argument. This should quickly catch most cases not for us. + ;; This case is only applicable if we're the innermost arglist. + (c-backward-syntactic-ws) + (setq c (char-before))) + + (unless (eq c ?,) + ;; In a gcc asm, ":" on the previous line means the start of an + ;; argument. And lines starting with ":" are not for us, don't + ;; want them to indent to the preceding operand. + (let ((gcc-asm (save-excursion + (goto-char start) + (c-in-gcc-asm-p)))) + (unless (and gcc-asm + (or (eq c ?:) + (save-excursion + (goto-char start) + (looking-at "[ \t]*:")))) + + (c-lineup-argcont-scan (if gcc-asm ?:)) + t))))) + +(defun c-lineup-argcont-scan (&optional other-match) + ;; Find the start of an argument, for `c-lineup-argcont'. + (when (zerop (c-backward-token-2 1 t)) + (let ((c (char-after))) + (if (or (eq c ?,) (eq c other-match)) + (progn + (forward-char) + (c-forward-syntactic-ws)) + (c-lineup-argcont-scan other-match))))) + (defun c-lineup-argcont (elem) "Line up a continued argument. @@ -221,56 +273,28 @@ for the operands. Works with: arglist-cont, arglist-cont-nonempty." - (save-excursion - (beginning-of-line) + (when (c-lineup-argcont-1 elem) + (vector (current-column))))) - (when (eq (car elem) 'arglist-cont-nonempty) - ;; Our argument list might not be the innermost one. If it - ;; isn't, go back to the last position in it. We do this by - ;; stepping back over open parens until we get to the open paren - ;; of our argument list. - (let ((open-paren (c-langelem-2nd-pos c-syntactic-element)) - (paren-state (c-parse-state))) - (while (not (eq (car paren-state) open-paren)) - (unless (consp (car paren-state)) ;; ignore matched braces - (goto-char (car paren-state))) - (setq paren-state (cdr paren-state))))) +(defun c-lineup-argcont-+ (langelem) + "Indent an argument continuation `c-basic-offset' in from the first argument. - (let ((start (point)) c) - - (when (bolp) - ;; Previous line ending in a comma means we're the start of an - ;; argument. This should quickly catch most cases not for us. - ;; This case is only applicable if we're the innermost arglist. - (c-backward-syntactic-ws) - (setq c (char-before))) +foo (xyz, uvw, aaa + bbb + ccc + + ddd + eee + fff); <- c-lineup-argcont-+ + <--> c-basic-offset - (unless (eq c ?,) - ;; In a gcc asm, ":" on the previous line means the start of an - ;; argument. And lines starting with ":" are not for us, don't - ;; want them to indent to the preceding operand. - (let ((gcc-asm (save-excursion - (goto-char start) - (c-in-gcc-asm-p)))) - (unless (and gcc-asm - (or (eq c ?:) - (save-excursion - (goto-char start) - (looking-at "[ \t]*:")))) +Only continuation lines like this are touhced, nil being returned +on lines which are the start of an argument. - (c-lineup-argcont-scan (if gcc-asm ?:)) - (vector (current-column)))))))) - -(defun c-lineup-argcont-scan (&optional other-match) - ;; Find the start of an argument, for `c-lineup-argcont'. - (when (zerop (c-backward-token-2 1 t)) - (let ((c (char-after))) - (if (or (eq c ?,) (eq c other-match)) - (progn - (forward-char) - (c-forward-syntactic-ws)) - (c-lineup-argcont-scan other-match))))) +Works with: arglist-cont, arglist-cont-nonempty." + (save-excursion + (when (c-lineup-argcont-1 langelem) ; Check we've got a continued argument... + ;; ... but ignore the position found. + (goto-char (c-langelem-2nd-pos c-syntactic-element)) + (forward-char) + (c-forward-syntactic-ws) + (vector (+ (current-column) c-basic-offset))))) (defun c-lineup-arglist-intro-after-paren (_langelem) "Line up a line to just after the open paren of the surrounding paren -- Alan Mackenzie (Nuremberg, Germany).