From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Alan Mackenzie Newsgroups: gmane.emacs.devel Subject: Re: c-mode pragma and preproc Date: Sun, 19 Jan 2020 17:26:47 +0000 Message-ID: <20200119172647.GB9172@ACM> References: <20191219140738.q5zdmily5ubwnmg3.ref@Ergus> <20191219140738.q5zdmily5ubwnmg3@Ergus> <20200111114402.GA6005@ACM> <20200114140110.hrfqmrfkffwsknse@Ergus> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="41776"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Mutt/1.10.1 (2018-07-13) Cc: emacs-devel@gnu.org To: Ergus Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sun Jan 19 18:28:31 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 1itEND-000An6-AK for ged-emacs-devel@m.gmane-mx.org; Sun, 19 Jan 2020 18:28:31 +0100 Original-Received: from localhost ([::1]:52042 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1itENC-0002Go-5x for ged-emacs-devel@m.gmane-mx.org; Sun, 19 Jan 2020 12:28:30 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:54510) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1itELd-0000b5-Nb for emacs-devel@gnu.org; Sun, 19 Jan 2020 12:26:55 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1itELb-000706-Rt for emacs-devel@gnu.org; Sun, 19 Jan 2020 12:26:53 -0500 Original-Received: from colin.muc.de ([193.149.48.1]:41947 helo=mail.muc.de) by eggs.gnu.org with smtp (Exim 4.71) (envelope-from ) id 1itELa-0006zd-Vg for emacs-devel@gnu.org; Sun, 19 Jan 2020 12:26:51 -0500 Original-Received: (qmail 73263 invoked by uid 3782); 19 Jan 2020 17:26:49 -0000 Original-Received: from acm.muc.de (p4FE15C7F.dip0.t-ipconnect.de [79.225.92.127]) by colin.muc.de (tmda-ofmipd) with ESMTP; Sun, 19 Jan 2020 18:26:47 +0100 Original-Received: (qmail 12100 invoked by uid 1000); 19 Jan 2020 17:26:47 -0000 Content-Disposition: inline In-Reply-To: <20200114140110.hrfqmrfkffwsknse@Ergus> X-Delivery-Agent: TMDA/1.1.12 (Macallan) X-Primary-Address: acm@muc.de X-detected-operating-system: by eggs.gnu.org: FreeBSD 9.x [fuzzy] X-Received-From: 193.149.48.1 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:244382 Archived-At: Hello again, Ergus. On Tue, Jan 14, 2020 at 15:01:10 +0100, Ergus wrote: > On Sat, Jan 11, 2020 at 11:44:02AM +0000, Alan Mackenzie wrote: > Hi Alan: > >On Thu, Dec 19, 2019 at 15:07:38 +0100, Ergus wrote: > >> Hi Alan: > >> Recently I have been noticing that many "modern" programming models > >> (Open-MP, OmpSs, OpenACC, programming for Intel Xeon Phi) use > >> extensively the #pragma sentence. > >> But in general, while the pre-processor sentences are usually in column > >> zero ([0]), the #pragma, on the other hand, are preferred to be aligned > >> with text (0). They are more readable that way. OK, I have an experimental implementation of M-x c-toggle-cpp-indent-to-body (see patch below). This can be customised by changing c-cpp-indent-to-body-directives, the list of directives which should be indented as statements. It's default value is ("pragma"). (Yes, I know you said that it would only be needed for "pragma", but it seemed a bit restrictive so to restrict it.). The indentation takes place either on typing (or any other action which causes indentation) or on typing a space after "# pragma". [ .... ] > For example the most general example so far is: > #pragma omp parallel shared(salaries1, salaries2) > { > #pragma omp for reduction(+: salaries1) > for (int employee = 0; employee < 25000; employee++) > { > salaries1 += fetchTheSalary(employee, Co::Company1); > } > #pragma omp single > { > std::cout << "Salaries1: " << salaries1 << std::endl; > } > #pragma omp for reduction(+: salaries1) > for (int employee = 0; employee < 25000; employee++) > { > salaries2 += fetchTheSalary(employee, Co::Company2); > } > #pragma omp barrier > } Thanks. This example was helpful. Just one thing - I haven't yet amended the CC Mode manual. Would you please try the patch out, and let me know how well it satisfies your needs. The patch should apply cleanly to the master branch. Thanks! [ .... ] diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el index 1071191775..223266177a 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,78 @@ 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) + (save-excursion + (save-match-data + (back-to-indentation) + (when (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) > Best, > Ergus -- Alan Mackenzie (Nuremberg, Germany).