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: Wed, 12 Feb 2020 11:19:56 +0100 [thread overview]
Message-ID: <20200212101956.lfmdlwodcx2qca4q@Ergus> (raw)
In-Reply-To: <20200211200018.GA5902@ACM>
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)
> \f
>> ;; 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)))
>> +
> \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)
>
>
>> > Very thanks,
>> > Ergus.
>
>> --
>> Alan Mackenzie (Nuremberg, Germany).
prev parent reply other threads:[~2020-02-12 10:19 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.
2020-01-20 21:27 ` Alan Mackenzie
2020-02-11 20:00 ` Alan Mackenzie
2020-02-12 10:19 ` Ergus via Emacs development discussions. [this message]
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=20200212101956.lfmdlwodcx2qca4q@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).