unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: "D Chiesa" <dpchiesa@hotmail.com>
To: <emacs-devel@gnu.org>
Subject: cc-mode help - c-basic-matchers-after
Date: Sat, 24 Apr 2010 09:37:57 -0400	[thread overview]
Message-ID: <COL124-DS139313F69BD5E7EB46D795CE060@phx.gbl> (raw)

Hi,

I'm working on improving the fontification of c# in csharp-mode, which 
depends on cc-mode.

In most cases in cc-mode, reference to the c-lang-const symbols are done 
through a variable of the same name, rather than directly through the 
(c-lang-const ...) fn.   The pattern for defining the variable looks like 
this:

    (c-lang-defconst c-brace-list-key
      ;; Regexp matching the start of declarations where the following
      ;; block is a brace list.
      t (c-make-keywords-re t (c-lang-const c-brace-list-decl-kwds)))
    (c-lang-defvar c-brace-list-key (c-lang-const c-brace-list-key))

And then the code in cc-mode references the value either via the variable, 
or (c-lang-const ...).  This is nice because it offers the chance for a 
cc-mode language to set its own regex into that symbol, and that regex may 
or may not be the result of a simple call to c-make-keywords-re.

But, in some cases this approach is not used faithfully.  One case in 
particular causes problems for fontification of C#.

In c-basic-matchers-after (defined in cc-fonts.el), the first case in that 
fn deals with identifiers inside enum lists, and "hard-codes" the regex used 
to recognize brace-lists .  See below, the call to concat, and specifically 
the comment that begins with "Disallow".

     (c-lang-defconst c-basic-matchers-after
       "Font lock matchers for various things that should be fontified after
     generic casts and declarations are fontified.  Used on level 2 and
     higher."

       t `(;; Fontify the identifiers inside enum lists.  (The enum type
           ;; name is handled by `c-simple-decl-matchers' or
           ;; `c-complex-decl-matchers' below.
           ,@(when (c-lang-const c-brace-id-list-kwds)
               `((,(c-make-font-lock-search-function
                    (concat
                     "\\<\\("
                     (c-make-keywords-re nil (c-lang-const 
c-brace-id-list-kwds))
                     "\\)\\>"
                     ;; Disallow various common punctuation chars that can't 
come
                     ;; before the '{' of the enum list, to avoid searching 
too far.
                     "[^\]\[{}();,/#=]*"
                     "{")
                    '((c-font-lock-declarators limit t nil)
                      (save-match-data
                        (goto-char (match-end 0))
                        (c-put-char-property (1- (point)) 'c-type
                                             'c-decl-id-start)
                        (c-forward-syntactic-ws))
                      (goto-char (match-end 0)))))))

This works in many languages, but it does not work in C#, specifically for 
the case of object initializers, which take this form:

     var x = new MyType(arg1, arg2, ...) {
         Field1 = "foo",
         Field2 = "bar",
     };

This syntax creates a new instance using the given constructor, and then 
sets public fields or properties on that instance to the given values.
When I say "it does not work" what I mean is that regex in the matcher 
doesn't match, and as a result the char property c-decl-id-start is not 
applied to the open curly.  As a result of that, the assignment statements 
inside the curlies are not fontified properly.

C# 3.0 also allows this simpler syntax:

     var x = new MyType {
         Field1 = "foo",
         Field2 = "bar",
     };

...which invokes the default constructor, and then performs the assignments. 
This syntax is fontified correctly.   The difference is the absence of the 
(), which is "disallowed" by the hard-coded regex.

The difference is shown here:
http://i40.tinypic.com/29qo0go.jpg

What I'd like to see is that regex in c-basic-matchers-after to be a pure 
c-lang-const.  Rather than augmenting that regex deep inside the matcher to 
stipulate that () must be disallowed in that context, if that regex could 
refer to an unadorned c-lang-const, then any mode dependent upon cc-mode 
would be able to set the appropriate regex for the matcher, in an 
appropriate c-lang-defconst .

In other words, change the code for c-basic-matchers-after to

       t `(;; Fontify the identifiers inside enum lists.  (The enum type
           ;; name is handled by `c-simple-decl-matchers' or
           ;; `c-complex-decl-matchers' below.
           ,@(when (c-lang-const c-brace-id-list-kwds)
               `((,(c-make-font-lock-search-function
                    (c-lang-const c-brace-id-list-beginning-re)
                    '((c-font-lock-declarators limit t nil)


and introduce c-brace-id-list-beginning-re , as

    (c-lang-defconst c-brace-id-list-beginning-re
      ;; Regexp matching the start of a brace list, including the opening
      ;; brace.
      t (concat
         "\\<\\("
         (c-make-keywords-re nil (c-lang-const c-brace-id-list-kwds))
         "\\)\\>"
         ;; Disallow various common punctuation chars that can't come
         ;; before the '{' of the enum list, to avoid searching too far.
         "[^\]\[{}();,/#=]*"
         "{")
      )

Have I understood this properly?  Does this request make sense?


-Dino Chiesa

 





             reply	other threads:[~2010-04-24 13:37 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-04-24 13:37 D Chiesa [this message]
  -- strict thread matches above, loose matches on Subject: below --
2010-04-24 14:35 cc-mode help - c-basic-matchers-after D Chiesa

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=COL124-DS139313F69BD5E7EB46D795CE060@phx.gbl \
    --to=dpchiesa@hotmail.com \
    --cc=emacs-devel@gnu.org \
    /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).