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#46301: 28.0.50; cc-mode: add support for c++ lambda expression Date: Thu, 25 Feb 2021 20:51:12 +0000 Message-ID: References: <87czxfx2b9.fsf@gmail.com> <87y2fe2jo3.fsf@gmail.com> 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="17901"; mail-complaints-to="usenet@ciao.gmane.io" Cc: 46301@debbugs.gnu.org To: Utkarsh Singh Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Thu Feb 25 21:52:11 2021 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 1lFNcI-0004Vh-GL for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 25 Feb 2021 21:52:10 +0100 Original-Received: from localhost ([::1]:58978 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lFNcH-00030T-Dp for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 25 Feb 2021 15:52:09 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:50664) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFNcA-0002wo-9C for bug-gnu-emacs@gnu.org; Thu, 25 Feb 2021 15:52:02 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]:56140) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lFNcA-0007ss-1H for bug-gnu-emacs@gnu.org; Thu, 25 Feb 2021 15:52:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1lFNc9-0006Rd-Uq for bug-gnu-emacs@gnu.org; Thu, 25 Feb 2021 15:52:01 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Alan Mackenzie Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 25 Feb 2021 20:52:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 46301 X-GNU-PR-Package: emacs Original-Received: via spool by 46301-submit@debbugs.gnu.org id=B46301.161428628424727 (code B ref 46301); Thu, 25 Feb 2021 20:52:01 +0000 Original-Received: (at 46301) by debbugs.gnu.org; 25 Feb 2021 20:51:24 +0000 Original-Received: from localhost ([127.0.0.1]:39453 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lFNbX-0006Ql-Tw for submit@debbugs.gnu.org; Thu, 25 Feb 2021 15:51:24 -0500 Original-Received: from colin.muc.de ([193.149.48.1]:35672 helo=mail.muc.de) by debbugs.gnu.org with smtp (Exim 4.84_2) (envelope-from ) id 1lFNbU-0006QV-Jw for 46301@debbugs.gnu.org; Thu, 25 Feb 2021 15:51:22 -0500 Original-Received: (qmail 48794 invoked by uid 3782); 25 Feb 2021 20:51:13 -0000 Original-Received: from acm.muc.de (p4fe15c19.dip0.t-ipconnect.de [79.225.92.25]) (using STARTTLS) by colin.muc.de (tmda-ofmipd) with ESMTP; Thu, 25 Feb 2021 21:51:13 +0100 Original-Received: (qmail 1166 invoked by uid 1000); 25 Feb 2021 20:51:13 -0000 Content-Disposition: inline In-Reply-To: <87y2fe2jo3.fsf@gmail.com> 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:200816 Archived-At: Hello, Utkarsh. On Wed, Feb 24, 2021 at 09:37:08 +0530, Utkarsh Singh wrote: > Alan Mackenzie writes: > > But from the end of that lambda, a further C-M-e takes point to the end > > of bubble_sort. > > Why do you think this is a bug? The lambda form is a function, it is at > > the top level (i.e. not within braces), so why shouldn't C-M-e stop at > > its end? That's a genuine question, by the way, not a rhetorical one. > I think there was some misunderstanding on my side as I was interpreting > c-end-of-defun as c-end-of-*named*-defun. This means I was not > considering lambda as an unnamed function but just as a default > argument. I've looked into a bit more, and come to the conclusion that this behaviour really is a bug. At least C-M-a/e don't recognize other C++ lambda functions as functions, so it shouldn't with this one in the parameter list, either. Besides, lambda functions in C++ are typically short, so the need for C-M-a/e to work on them seems less than the annoyance just moving 1 or 2 lines would cause. > > If anything, the rather unsystematic behaviour of C-M-a near this lambda > > function is of more concern. And there's the worry that this example > > will break other places where it's assumed that braces cannot occur in > > parameter lists. > > But of all the languages there are, trust C++ to be awkward. ;-) > Yes, C++ can get really ugly sometimes. Indeed. > The main moto behind my "feature request" was not solving the problem > logically but to be so called "contributor" of GNU Emacs. Apology for > that. No need to apologize! On the contrary, you've reported a bug, which has led to an improvement in the source code. Without bug reports, CC Mode would not be anywhere near what it is today. I've spent the last couple of days fixing the handling of C-M-a/e in cc-cmds.el. It took rather more than the four line patch you proposed. ;-) Could I ask you, please, to apply the following patch (which should apply cleanly to the Emacs master branch), byte compile cc-cmds.el, load it into Emacs, and test it for me on your real source code. Then please report back whether the bug is in fact fixed, and if not, what is still wrong. In the event you would like help with the patching or byte compiling, feel free to send me private email. Thanks! diff -r 00245e7ea2c5 cc-cmds.el --- a/cc-cmds.el Tue Feb 23 10:58:22 2021 +0000 +++ b/cc-cmds.el Thu Feb 25 20:15:09 2021 +0000 @@ -1621,7 +1621,7 @@ ;; ;; This function might do hidden buffer changes. (save-excursion - (let* (kluge-start + (let* (kluge-start knr-start knr-res decl-result brace-decl-p (start (point)) (paren-state (c-parse-state)) @@ -1652,63 +1652,39 @@ (not (looking-at c-defun-type-name-decl-key)))))) 'at-function-end) (t - ;; Find the start of the current declaration. NOTE: If we're in the - ;; variables after a "struct/eval" type block, we don't get to the - ;; real declaration here - we detect and correct for this later. - - ;;If we're in the parameters' parens, move back out of them. - (if least-enclosing (goto-char least-enclosing)) - ;; Kluge so that c-beginning-of-decl-1 won't go back if we're already - ;; at a declaration. - (if (or (and (eolp) (not (eobp))) ; EOL is matched by "\\s>" - (not (looking-at -"\\([;#]\\|\\'\\|\\s(\\|\\s)\\|\\s\"\\|\\s\\\\|\\s$\\|\\s<\\|\\s>\\|\\s!\\)"))) - (forward-char)) - (setq kluge-start (point)) - ;; First approximation as to whether the current "header" we're in is - ;; one followed by braces. - (setq brace-decl-p - (save-excursion - (and (c-syntactic-re-search-forward "[;{]" nil t t) - (or (eq (char-before) ?\{) - (and c-recognize-knr-p - ;; Might have stopped on the - ;; ';' in a K&R argdecl. In - ;; that case the declaration - ;; should contain a block. - (c-in-knr-argdecl)))))) - (setq decl-result - (car (c-beginning-of-decl-1 - ;; NOTE: If we're in a K&R region, this might be the start - ;; of a parameter declaration, not the actual function. - ;; It might also leave us at a label or "label" like - ;; "private:". - (and least-enclosing ; LIMIT for c-b-of-decl-1 - (c-safe-position least-enclosing paren-state))))) - - ;; Has the declaration we've gone back to got braces? - (if (or (eq decl-result 'label) - (looking-at c-protection-key)) - (setq brace-decl-p nil)) - - (cond - ((or (eq decl-result 'label) ; e.g. "private:" or invalid syntax. - (= (point) kluge-start)) ; might be BOB or unbalanced parens. - 'outwith-function) - ((eq decl-result 'same) - (if brace-decl-p - (if (eq (point) start) - 'at-header + (if (and least-enclosing + (eq (char-after least-enclosing) ?\()) + (c-go-list-forward least-enclosing)) + (c-forward-syntactic-ws) + (setq knr-start (point)) + (if (c-syntactic-re-search-forward "{" nil t t) + (progn + (backward-char) + (cond + ((or (progn + (c-backward-syntactic-ws) + (<= (point) start)) + (and c-recognize-knr-p + (and (setq knr-res (c-in-knr-argdecl)) + (<= knr-res knr-start)))) 'in-header) - 'outwith-function)) - ((eq decl-result 'previous) - (if (and (not brace-decl-p) - (c-in-function-trailer-p)) - 'at-function-end - 'outwith-function)) - (t (error - "c-where-wrt-brace-construct: c-beginning-of-decl-1 returned %s" - decl-result)))))))) + ((and knr-res + (goto-char knr-res) + (c-backward-syntactic-ws))) ; Always returns nil. + ((and (eq (char-before) ?\)) + (c-go-list-backward)) + (c-syntactic-skip-backward "^;" start t) + (if (eq (point) start) + (if (progn (c-backward-syntactic-ws) + (memq (char-before) '(?\; ?} nil))) + (if (progn (c-forward-syntactic-ws) + (eq (point) start)) + 'at-header + 'outwith-function) + 'in-header) + 'outwith-function)) + (t 'outwith-function))) + 'outwith-function)))))) (defun c-backward-to-nth-BOF-{ (n where) ;; Skip to the opening brace of the Nth function before point. If @@ -1730,9 +1707,11 @@ (goto-char (c-least-enclosing-brace (c-parse-state))) (setq n (1- n))) ((eq where 'in-header) - (c-syntactic-re-search-forward "{") - (backward-char) - (setq n (1- n))) + (let ((encl-paren (c-least-enclosing-brace (c-parse-state)))) + (if encl-paren (goto-char encl-paren)) + (c-syntactic-re-search-forward "{" nil t t) + (backward-char) + (setq n (1- n)))) ((memq where '(at-header outwith-function at-function-end in-trailer)) (c-syntactic-skip-backward "^}") (when (eq (char-before) ?\}) @@ -1941,21 +1920,24 @@ ;; The actual movement is done below. (setq n (1- n))) ((memq where '(at-function-end outwith-function at-header in-header)) - (when (c-syntactic-re-search-forward "{" nil 'eob) + (if (eq where 'in-header) + (let ((pos (c-least-enclosing-brace (c-parse-state)))) + (if pos (c-go-list-forward pos)))) + (when (c-syntactic-re-search-forward "{" nil 'eob t) (backward-char) (forward-sexp) (setq n (1- n)))) (t (error "c-forward-to-nth-EOF-\\;-or-}: `where' is %s" where))) - (when (c-in-function-trailer-p) - (c-syntactic-re-search-forward ";" nil 'eob t)) - ;; Each time round the loop, go forward to a "}" at the outermost level. (while (and (> n 0) (not (eobp))) (when (c-syntactic-re-search-forward "{" nil 'eob) (backward-char) (forward-sexp) (setq n (1- n)))) + + (when (c-in-function-trailer-p) + (c-syntactic-re-search-forward ";" nil 'eob t)) n) (defun c-end-of-defun (&optional arg) > -- > Utkarsh Singh -- Alan Mackenzie (Nuremberg, Germany).