unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
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).



      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).