emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: address@hidden: C++-mode: Syntax highlighting: wrong color for funct


From: Alan Mackenzie
Subject: Re: address@hidden: C++-mode: Syntax highlighting: wrong color for function identifier depending on the kind of whitespace that follows]
Date: Thu, 10 Mar 2005 22:42:53 +0000 (GMT)


On Thu, 10 Mar 2005, Stefan Monnier wrote:

>>> You may be right, but I'd like to see your code first, to see how easy and
>>> robust it is to use your hook.
>> I re-posted my tentative 2002 patch here last night.

>Read again: I said "use" not "define".
>I.e. I don't want to see the font-lock side of the code, but the awk-mode or
>c++-mode side of it.  Most importantly, I'd like to see some code that would
>solve the problem at hand (see subject) using your new hook.

Sorry, I didn't quite understand what you were asking for.  I hope the
following will do.  I can't produce any working c-mode code for this in a
hurry.  But here is the stuff from cc-awk.el.  It has the functionality
to fit the hook I'd proposed, but not the same interface.

What it does is to expand the region in an AWK buffer to be
after-change-font-locked from a physical line to the containing
@dfn{logical line}, the maximal sequence of physical lines joined by
escaped newlines.  It does the Right Thing when a backslash at an EOL
gets inserted or deleted.

(defun c-awk-beginning-of-logical-line (&optional pos)
;; Go back to the start of the (apparent) current line (or the start of the
;; line containing POS), returning the buffer position of that point.  I.e.,
;; go back to the last line which doesn't have an escaped EOL before it.
;;
;; This is guaranteed to be "safe" for syntactic analysis, i.e. outwith any
;; comment, string or regexp.  IT MAY WELL BE that this function should not be
;; executed on a narrowed buffer.
;;
;; This function might do hidden buffer changes.
  (if pos (goto-char pos))
  (forward-line 0)
  (while (and (> (point) (point-min))
              (eq (char-before (1- (point))) ?\\))
    (forward-line -1))
  (point))

(defun c-awk-end-of-logical-line (&optional pos)
;; Go forward to the end of the (apparent) current logical line (or the end of
;; the line containing POS), returning the buffer position of that point.  I.e.,
;; go to the end of the next line which doesn't have an escaped EOL.
;;
;; This is guaranteed to be "safe" for syntactic analysis, i.e. outwith any
;; comment, string or regexp.  IT MAY WELL BE that this function should not be
;; executed on a narrowed buffer.
;;
;; This function might do hidden buffer changes.
  (if pos (goto-char pos))
  (end-of-line)
  (while (and (< (point) (point-max))
              (eq (char-before) ?\\))
    (end-of-line 2))
  (point))

(defvar c-awk-old-EOLL 0)
(make-variable-buffer-local 'c-awk-old-EOLL)
;; End of logical line following the region which is about to be changed.  Set
;; in c-awk-before-change and used in c-awk-after-change.

(defun c-awk-before-change (beg end)
;; This function is called exclusively from the before-change-functions hook.
;; It does two things: Finds the end of the (logical) line on which END lies,
;; and clears c-awk-NL-prop text properties from this point onwards.
;;
;; This function might do hidden buffer changes.
  (save-restriction
    (save-excursion
      (setq c-awk-old-EOLL (c-awk-end-of-logical-line end))
      (c-save-buffer-state nil
       (c-awk-clear-NL-props end (point-max))))))

(defun c-awk-end-of-change-region (beg end old-len)
  ;; Find the end of the region which needs to be font-locked after a change.
  ;; This is the end of the logical line on which the change happened, either
  ;; as it was before the change, or as it is now, which ever is later.
  ;; N.B. point is left undefined.
  ;;
  ;; This function might do hidden buffer changes.
  (max (+ (- c-awk-old-EOLL old-len) (- end beg))
       (c-awk-end-of-logical-line end)))

;; ACM 2002/5/25.  When font-locking is invoked by a buffer change, the region
;; specified by the font-lock after-change function must be expanded to
;; include ALL of any string or regexp within the region.  The simplest way to
;; do this in practice is to use the beginning/end-of-logical-line functions.
;; Don't overlook the possibility of the buffer change being the "recapturing"
;; of a previously escaped newline.
(defmacro c-awk-advise-fl-for-awk-region (function)
  `(defadvice ,function (before get-awk-region activate)
;; When font-locking an AWK Mode buffer, make sure that any string/regexp is
;; completely font-locked.
  (when (eq major-mode 'awk-mode)
    (save-excursion
      (ad-set-arg 1 (c-awk-end-of-change-region
                     (ad-get-arg 0)     ; beg
                     (ad-get-arg 1)     ; end
                     (ad-get-arg 2)))   ; old-len
      (ad-set-arg 0 (c-awk-beginning-of-logical-line (ad-get-arg 0)))))))

(c-awk-advise-fl-for-awk-region font-lock-after-change-function)
(c-awk-advise-fl-for-awk-region jit-lock-after-change)
(c-awk-advise-fl-for-awk-region lazy-lock-defer-rest-after-change)
(c-awk-advise-fl-for-awk-region lazy-lock-defer-line-after-change)



>> I think this putting of warning-face on unmatched quotes would be a good
>> idea generally.

>It would help if you actually explained what you're talking about.
>Not everyone uses awk-mode.

I'll try; I'm not doing very well at explaining at the moment.  Open a
new AWK mode buffer with font locking enabled:  Start by entering a
string:

"string

At this point, the opening quote has font-lock-warning-face, giving the
user a constant niggling reminder to close the string at some point; the
remainder of the text has font-lock-string-face.  Use escaped NLs to
continue the string thus:

"string\
on several\
lines.

The entire string still has string-face, and the opening quote still has
warning-face.  Finally, type the closing quote:

"string\
on several\
lines."

This last action now causes the opening quote to be refonted with
string-face.

>        Stefan

-- 
Alan Mackenzie (Munich, Germany)






reply via email to

[Prev in Thread] Current Thread [Next in Thread]