From: Ergus via "Emacs development discussions." <emacs-devel@gnu.org>
To: Alan Mackenzie <acm@muc.de>
Cc: emacs-devel@gnu.org
Subject: Re: c-mode pragma and preproc
Date: Mon, 20 Jan 2020 03:15:38 +0100 [thread overview]
Message-ID: <20200120021538.wxtxv3vbsorksqdg@Ergus> (raw)
In-Reply-To: <20200119172647.GB9172@ACM>
Hi Alan:
I just tried the patch and it seems to work as expected.
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?
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. Why not just add an
extra syntactic symbol for pragmas? Isn't it more consistent that way?
Otherwise the user will get false information from C-c C-o and looses
somehow a bit of flexibility.
Maybe we just need a variable that when not specified indent pragmas as
macros else indent pragmas as it specifies...?
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++.
In any case the only real "issue" in my opinion is 1). But so far it
works pretty fine.
Very thanks,
Ergus.
On Sun, Jan 19, 2020 at 05:26:47PM +0000, Alan Mackenzie wrote:
>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 <tab> (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)
> \f
> ;; 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)))
>+
> \f
>
> (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).
>
next prev parent reply other threads:[~2020-01-20 2:15 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20191219140738.q5zdmily5ubwnmg3.ref@Ergus>
2019-12-19 14:07 ` c-mode pragma and preproc Ergus
2020-01-11 11:44 ` Alan Mackenzie
2020-01-14 14:01 ` Ergus
2020-01-19 17:26 ` Alan Mackenzie
2020-01-20 2:15 ` Ergus via Emacs development discussions. [this message]
2020-01-20 21:27 ` Alan Mackenzie
2020-02-11 20:00 ` Alan Mackenzie
2020-02-12 10:19 ` Ergus via Emacs development discussions.
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200120021538.wxtxv3vbsorksqdg@Ergus \
--to=emacs-devel@gnu.org \
--cc=acm@muc.de \
--cc=spacibba@aol.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).