From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Ergus via "Emacs development discussions." Newsgroups: gmane.emacs.devel Subject: Re: c-mode pragma and preproc Date: Wed, 12 Feb 2020 11:19:56 +0100 Message-ID: <20200212101956.lfmdlwodcx2qca4q@Ergus> References: <20191219140738.q5zdmily5ubwnmg3.ref@Ergus> <20191219140738.q5zdmily5ubwnmg3@Ergus> <20200111114402.GA6005@ACM> <20200114140110.hrfqmrfkffwsknse@Ergus> <20200119172647.GB9172@ACM> <20200120021538.wxtxv3vbsorksqdg@Ergus> <20200120212702.GB4348@ACM> <20200211200018.GA5902@ACM> Reply-To: Ergus Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii; format=flowed Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="46503"; mail-complaints-to="usenet@ciao.gmane.io" Cc: emacs-devel@gnu.org To: Alan Mackenzie Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Wed Feb 12 11:21:04 2020 Return-path: Envelope-to: ged-emacs-devel@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 1j1p8h-000BxD-8z for ged-emacs-devel@m.gmane-mx.org; Wed, 12 Feb 2020 11:21:03 +0100 Original-Received: from localhost ([::1]:34822 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j1p8g-0003AA-9P for ged-emacs-devel@m.gmane-mx.org; Wed, 12 Feb 2020 05:21:02 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:56112) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j1p7l-0001lS-AV for emacs-devel@gnu.org; Wed, 12 Feb 2020 05:20:08 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j1p7j-0007mP-6W for emacs-devel@gnu.org; Wed, 12 Feb 2020 05:20:04 -0500 Original-Received: from sonic305-1.consmr.mail.bf2.yahoo.com ([74.6.133.40]:41855) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1j1p7j-0007lm-0c for emacs-devel@gnu.org; Wed, 12 Feb 2020 05:20:03 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aol.com; s=a2048; t=1581502802; bh=zGSQrVzAubhtHQFB9Lgkd/scKPhO5/GuRBNhTy5bsVE=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From:Subject; b=epmpSCN+KAPARcM+Z687jDY2jQbwH3CwPgshTky+ojqfI202voxPVBiGzmzb0EqnZLjcts5D+TShwAVLDqSE1qhFQOEQUTu+mQdzD+AqugKTWK0m0VxA/KMn8CQ950Y+oU9c/OFsQQBb4DvmvuSO0TL+2M3MU6MGqlXKY/PZsZuCP70j5+k45e/rUrMnfWL2Q+BHAnq3BFNpYq4p2RhoWYS7aSUs9km/c04fZH/YdyHv3UPG463+0GdvDuDd3o9DzdjIOn+05b4H00iSptSEdq8Qk0kiZjxlBg5wCvHd9+8i5nulRUtkoHdXSNrLprxvhhUXIXSTSjyVMo00rINKbw== X-YMail-OSG: c6aj6HoVM1kS7Pu8rw.cPvRzmvYUSIP8svEsICiK3iFcFZTzW7bFBkbIeCsIpzR XNsKnWm2hGWPQVuFMMaG_CFGTAe_SiSKYMOm4rsOFWKpHFg2h96zUzYEaMV89wSoulBdbzbSSfRa W35dGhI99qtHoBjXL_e.4LHpAwt9lLT41_PXtEhtAs1iq.U3EgJwGnfRJgJ5hSxZLwfPHJgUhv6K Hn1pIvlF5SkQZyqlLIgmOyq2pHD3d_PWNp7yRNAFIkHh0a_VN18clyGTiJrR7Uq44ZG0HKn3AOU8 7.glgITA6ES21Xl3sLauECcvFjiclb_L8iyF0ZAg0YoOVUr8bWlVC95P0l3L4nuA980EYS5neA8o F7qUb3NkG3ZuzrwnsAYLGtTaGIHDVHeDTm2ILeuhqlW47M4jpCTR_UChCsGcQ99ukoslyt8XhTms 1mij34sdJfEsQH5dhHkRlvainonQOzpVWt0Ls9QpyP2wBX0NWgCLasaC2Apkfa1zw20gzDdnuMU0 FD5maLVjhEbctdklVNIgz5zbLx42pcrv0yBBwLVlX3qNUo7EogRRLrnc.y1qjL9w7f3Y0WTnLiUJ sudIOhePfV8WWOHTpzF6MTf033.h02NG.G4DXRR6_5hFN.ZGvfzKzn1priA0rBxnf.8PN34OF48O gu.kYPfAQ1.WHEFoPEdgadWlXjzFaC7kFbn_Aih0M5rMO85qnia3_EOEsepUidrovF8zrDUKR3dD Ja.axc5egEP1GzW9R75DzUYVaqBQgY3B3iWCFWB3BM32O4leEe.th0NyPCAHYOao2wQZ8V38gaSi bZ6ibHs6MAREvqKo_7cxYxlrSTvYoHPwOFB1NWNv8o Original-Received: from sonic.gate.mail.ne1.yahoo.com by sonic305.consmr.mail.bf2.yahoo.com with HTTP; Wed, 12 Feb 2020 10:20:02 +0000 Original-Received: by smtp401.mail.ir2.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 4fc18ac36aaae50ee6f7583f73c77f4c; Wed, 12 Feb 2020 10:19:58 +0000 (UTC) Content-Disposition: inline In-Reply-To: <20200211200018.GA5902@ACM> X-Mailer: WebService/1.1.15199 hermes Apache-HttpAsyncClient/4.1.4 (Java/1.8.0_181) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 74.6.133.40 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:244914 Archived-At: Hi Alan: Sorry for not commenting before the feedback. Yes it works fine for me. Except for the details I mentioned before about C-c C-o. But I understand the limitations we have there. So in my opinion you can commit it. Very thanks for this, Ergus On Tue, Feb 11, 2020 at 08:00:18PM +0000, Alan Mackenzie wrote: >Hello again, Ergus. > >Just a quick ping! > >I've now written the requisite documentation for the CC Mode manual. >Are you otherwise happy (or, at least, happy enough) with the state of >the code for me to commit it? > >-- >Alan Mackenzie (Nuremberg, Germany). > > >On Mon, Jan 20, 2020 at 21:27:02 +0000, Alan Mackenzie wrote: >> On Mon, Jan 20, 2020 at 03:15:38 +0100, Ergus via Emacs development discussions. wrote: >> > Hi Alan: > >> > I just tried the patch and it seems to work as expected. > >> Thanks! > >> > I just have 3 observations/suggestions/questions: > >> > 1) When I stay in column 0 like >> > |#pragma bla bla > >> > and I press tab (to indent the line's) I get: >> > | #pragma bla bla > >> > instead of: >> > |#pragma bla bla > >> > as it happens with other lines (where | is the cursor position). Is this >> > intended? > >> Whoops! That sort of thing is why I normally ask bug reporters to check >> the patch before I commit it. It's difficult to see when one is fixing a >> bug, but stands out like a sore thumb to somebody trying it out. > >> What happened was I called c-indent-line from inside a save-excursion. >> c-indent-line placed point correctly, but emerging from the >> save-excursion put it back to column 0. To fix this, either substitute >> this new version of c-align-cpp-indent-to-body for the old one, or >> reapply the patch below from scratch (whichever you prefer): > >> (defun c-align-cpp-indent-to-body () >> "Align a \"#pragma\" line under the previous line. >> This function is intented for use as a member of `c-special-indent-hook'." >> (when (assq 'cpp-macro c-syntactic-context) >> (when >> (save-excursion >> (save-match-data >> (back-to-indentation) >> (looking-at "#[ \t]*pragma\\([^[:alnum:]_$]\\|$\\)"))) >> (c-indent-line (delete '(cpp-macro) c-syntactic-context))))) > >> . > >> > 2) This new implementation breaks the "normal" way to configure the >> > indentation in c-mode because C-c C-o still returns cpp-macro (as >> > expected) while the indentation is not behaving as specified for >> > cpp-macros. So it seems to be confusing for the user and somehow a bit >> > inconsistent with the rest of cc-mode indentation. > >> It does a bit, yes. This is an inevitable downside of using >> c-special-indent-hook which counterbalances to some extent the ability to >> add lightweight, yet effective, solutions to otherwise awkward >> indentation problems. The other standard c-special-indent-hook function >> is c-gnu-impose-minimum, which in gnu style ensures that source code >> within functions has a minimum indentation. That also suffers from the >> inability to use C-c C-o with it. > >> > Why not just add an extra syntactic symbol for pragmas? Isn't it more >> > consistent that way? > >> There's no "just" about a new syntactic symbol. It would be more work to >> back it, more likely to interact with other features, and more likely to >> increase the complexity of CC Mode more than needed. Consider that, in >> reality, #pragma _is_ a cpp-macro, not something new. > >> > Otherwise the user will get false information from C-c C-o and looses >> > somehow a bit of flexibility. > >> This is true. > >> > Maybe we just need a variable that when not specified indent pragmas as >> > macros else indent pragmas as it specifies...? > >> Are you thinking of c-cpp-indent-to-body-flag? ;-) > >> > 3) Why the new function is called c-toggle-cpp-indent*? pragmas are part >> > of C too. Actually in HPC we usually use more C (and Fortran) than C++. > >> cpp for "C PreProcessor". :-) I don't think there are any instances of >> cpp meaning C++ in CC Mode, but I agree it's an unfortunate collision of >> abbreviations. :-( > >> I still haven't amended the CC Mode manual, but I will. > >> > In any case the only real "issue" in my opinion is 1). But so far it >> > works pretty fine. > >> OK, here's the replacement patch: > > >> diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el >> index 1071191775..56e3421ba2 100644 >> --- a/lisp/progmodes/cc-cmds.el >> +++ b/lisp/progmodes/cc-cmds.el >> @@ -48,6 +48,7 @@ >> (cc-bytecomp-defvar filladapt-mode) ; c-fill-paragraph contains a kludge >> ; which looks at this. >> (cc-bytecomp-defun electric-pair-post-self-insert-function) >> +(cc-bytecomp-defvar c-indent-to-body-directives) > >> ;; Indentation / Display syntax functions >> (defvar c-fix-backslashes t) >> @@ -1441,6 +1442,79 @@ c-electric-continued-statement >> (indent-according-to-mode) >> (delete-char -2))))) > >> +(defun c-align-cpp-indent-to-body () >> + "Align a \"#pragma\" line under the previous line. >> +This function is intented for use as a member of `c-special-indent-hook'." >> + (when (assq 'cpp-macro c-syntactic-context) >> + (when >> + (save-excursion >> + (save-match-data >> + (back-to-indentation) >> + (looking-at "#[ \t]*pragma\\([^[:alnum:]_$]\\|$\\)"))) >> + (c-indent-line (delete '(cpp-macro) c-syntactic-context))))) >> + >> +(defvar c-cpp-indent-to-body-flag nil) >> +;; Non-nil when CPP directives such as "#pragma" should be indented to under >> +;; the preceding statement. >> +(make-variable-buffer-local 'c-cpp-indent-to-body-flag) >> + >> +(defun c-electric-pragma () >> + "Reindent the current line if appropriate. >> + >> +This function is used to reindent a preprocessor line when the >> +symbol for the directive, typically \"pragma\", triggers this >> +function as a hook function of an abbreviation. >> + >> +The \"#\" of the preprocessor construct is aligned under the >> +first anchor point of the line's syntactic context. >> + >> +The line is reindented if the construct is not in a string or >> +comment, there is exactly one \"#\" contained in optional >> +whitespace before it on the current line, and `c-electric-flag' >> +and `c-syntactic-indentation' are both non-nil." >> + (save-excursion >> + (save-match-data >> + (when >> + (and >> + c-cpp-indent-to-body-flag >> + c-electric-flag >> + c-syntactic-indentation >> + last-abbrev-location >> + c-opt-cpp-symbol ; "#" or nil. >> + (progn (back-to-indentation) >> + (looking-at (concat c-opt-cpp-symbol "[ \t]*"))) >> + (>= (match-end 0) last-abbrev-location) >> + (not (c-literal-limits))) >> + (c-indent-line (delete '(cpp-macro) (c-guess-basic-syntax))))))) >> + >> +(defun c-add-indent-to-body-to-abbrev-table (d) >> + ;; Create an abbreviation table entry for the directive D, and add it to the >> + ;; current abbreviation table. Existing abbreviation (e.g. for "else") do >> + ;; not get overwritten. >> + (when (and c-buffer-is-cc-mode >> + local-abbrev-table >> + (not (abbrev-symbol d local-abbrev-table))) >> + (define-abbrev local-abbrev-table d d 'c-electric-pragma))) >> + >> +(defun c-toggle-cpp-indent-to-body (&optional arg) >> + "Toggle the cpp indent-to-body feature. >> +When enabled, when CPP directives which are words in >> +`c-indent-to-body-directives', the are indented such that the >> +initial \"#\" appears below the previous statement. >> + >> +Optional numeric ARG, if supplied, turns on the feature when positive, >> +turns it off when negative, and just toggles it when zero or >> +left out." >> + (interactive "P") >> + (setq c-cpp-indent-to-body-flag >> + (c-calculate-state arg c-cpp-indent-to-body-flag)) >> + (if c-cpp-indent-to-body-flag >> + (progn >> + (mapc 'c-add-indent-to-body-to-abbrev-table >> + c-cpp-indent-to-body-directives) >> + (add-hook 'c-special-indent-hook 'c-align-cpp-indent-to-body nil t)) >> + (remove-hook 'c-special-indent-hook 'c-align-cpp-indent-to-body t))) >> + > > >> (declare-function subword-forward "subword" (&optional arg)) >> diff --git a/lisp/progmodes/cc-vars.el b/lisp/progmodes/cc-vars.el >> index 861872486c..0391cdccfd 100644 >> --- a/lisp/progmodes/cc-vars.el >> +++ b/lisp/progmodes/cc-vars.el >> @@ -1649,6 +1649,15 @@ c-asymmetry-fontification-flag >> :type 'boolean >> :group 'c) > >> +(defcustom c-cpp-indent-to-body-directives '("pragma") >> + "Preprocessor directives which will be indented as statements. >> + >> +A list of Preprocessor directives which when reindented, or newly >> +typed in, will cause the \"#\" introducing the directive to be >> +indented as a statement." >> + :type '(repeat string) >> + :group 'c) >> + >> ;; Initialize the next two to a regexp which never matches. >> (defvar c-noise-macro-with-parens-name-re regexp-unmatchable) >> (make-variable-buffer-local 'c-noise-macro-with-parens-name-re) > > >> > Very thanks, >> > Ergus. > >> -- >> Alan Mackenzie (Nuremberg, Germany).