+2011-12-23 Alan Mackenzie <acm@muc.de>
+
+ Fix unstable fontification inside templates.
+
+ * progmodes/cc-langs.el (c-before-font-lock-functions): newly
+ created from the singular version. The (c c++ objc) entry now
+ additionally has c-set-fl-decl-start. The other languages (apart
+ from AWK) have that as a single entry.
+
+ * progmodes/cc-fonts.el (c-font-lock-enclosing-decls): The
+ functionality for "local" declarations has been extracted to
+ c-set-fl-decl-start.
+
+ * progmodes/cc-mode.el: (c-common-init, c-after-change): Changes
+ due to pluralisation of c-before-font-lock-functions.
+ (c-set-fl-decl-start): New function, extracted from
+ c-font-lock-enclosing-decls and enhanced.
+
2011-12-23 Juanma Barranquero <lekktu@gmail.com>
* desktop.el (desktop-internal-v2s): Fix typos in docstring (bug#10353).
;; prevent a repeat invocation. See elisp/lispref page "Search-based
;; Fontification".
(let* ((paren-state (c-parse-state))
- (start (point))
- (bod-lim (max (- (point) 500) (point-min)))
- decl-context bo-decl in-typedef type-type ps-elt)
-
- ;; First, are we actually in a "local" declaration?
- (setq decl-context (c-beginning-of-decl-1 bod-lim)
- bo-decl (point)
- in-typedef (looking-at c-typedef-key))
- (if in-typedef (c-forward-token-2))
- (when (and (eq (car decl-context) 'same)
- (< bo-decl start))
- ;; Are we genuinely at a type?
- (setq type-type (c-forward-type t))
- (if (and type-type
- (or (not (eq type-type 'maybe))
- (looking-at c-symbol-key)))
- (c-font-lock-declarators limit t in-typedef)))
-
- ;; Secondly, are we in any nested struct/union/class/etc. braces?
+ decl-context in-typedef ps-elt)
+ ;; Are we in any nested struct/union/class/etc. braces?
(while paren-state
(setq ps-elt (car paren-state)
paren-state (cdr paren-state))
When the mode is initialized, the functions are called with
parameters \(point-min) and \(point-max).")
-(c-lang-defconst c-before-font-lock-function
- "If non-nil, a function called just before font locking.
-Typically it will extend the region about to be fontified \(see
+(c-lang-defconst c-before-font-lock-functions
+ ;; For documentation see the following c-lang-defvar of the same name.
+ ;; The value here may be a list of functions or a single function.
+ t 'c-set-fl-decl-start
+ (c c++ objc) '(c-neutralize-syntax-in-and-mark-CPP c-set-fl-decl-start)
+ awk 'c-awk-extend-and-syntax-tablify-region)
+(c-lang-defvar c-before-font-lock-functions
+ (let ((fs (c-lang-const c-before-font-lock-functions)))
+ (if (listp fs)
+ fs
+ (list fs)))
+ "If non-nil, a list of functions called just before font locking.
+Typically they will extend the region about to be fontified \(see
below) and will set `syntax-table' text properties on the region.
-It takes 3 parameters, the BEG, END, and OLD-LEN supplied to
-every after-change function; point is undefined on both entry and
-exit; on entry, the buffer will have been widened and match-data
-will have been saved; the return value is ignored.
+These functions will be run in the order given. Each of them
+takes 3 parameters, the BEG, END, and OLD-LEN supplied to every
+after-change function; point is undefined on both entry and exit;
+on entry, the buffer will have been widened and match-data will
+have been saved; the return value is ignored.
-The function may extend the region to be fontified by setting the
+The functions may extend the region to be fontified by setting the
buffer local variables c-new-BEG and c-new-END.
-The function is called even when font locking is disabled.
+The functions are called even when font locking is disabled.
-When the mode is initialized, this function is called with
-parameters \(point-min), \(point-max) and <buffer size>."
- t nil
- (c c++ objc) 'c-neutralize-syntax-in-and-mark-CPP
- awk 'c-awk-extend-and-syntax-tablify-region)
-(c-lang-defvar c-before-font-lock-function
- (c-lang-const c-before-font-lock-function))
+When the mode is initialized, these functions are called with
+parameters \(point-min), \(point-max) and <buffer size>.")
\f
;;; Syntactic analysis ("virtual semicolons") for line-oriented languages (AWK).
(setq c-new-BEG (point-min))
(setq c-new-END (point-max))
(save-excursion
- (if c-get-state-before-change-functions
- (mapc (lambda (fn)
- (funcall fn (point-min) (point-max)))
- c-get-state-before-change-functions))
- (if c-before-font-lock-function
- (funcall c-before-font-lock-function (point-min) (point-max)
- (- (point-max) (point-min))))))
+ (mapc (lambda (fn)
+ (funcall fn (point-min) (point-max)))
+ c-get-state-before-change-functions)
+ (mapc (lambda (fn)
+ (funcall fn (point-min) (point-max)
+ (- (point-max) (point-min))))
+ c-before-font-lock-functions)))
(set (make-local-variable 'outline-regexp) "[^#\n\^M]")
(set (make-local-variable 'outline-level) 'c-outline-level)
;; Point is undefined both before and after this function call, the buffer
;; has been widened, and match-data saved. The return value is ignored.
;;
- ;; This function is the C/C++/ObjC value of `c-before-font-lock-function'.
+ ;; This function is in the C/C++/ObjC value of `c-before-font-lock-functions'.
;;
;; Note: SPEED _MATTERS_ IN THIS FUNCTION!!!
;;
;; these caches from inside them, and we must thus be sure that this
;; has already been executed.
;;
- ;; This calls the language variable c-before-font-lock-function, if non nil.
+ ;; This calls the language variable c-before-font-lock-functions, if non nil.
;; This typically sets `syntax-table' properties.
(c-save-buffer-state ()
;; larger than (beg end).
(setq c-new-BEG beg
c-new-END end)
- (if c-before-font-lock-function
- (save-excursion
- (funcall c-before-font-lock-function beg end old-len)))))))
+ (save-excursion
+ (mapc (lambda (fn)
+ (funcall fn beg end old-len))
+ c-before-font-lock-functions))))))
+
+(defun c-set-fl-decl-start (beg end old-len)
+ ;; If the beginning of line containing c-new-BEG is in the middle of a
+ ;; "local" declaration (i.e. one which does not start outside of braces
+ ;; enclosing this pos, such as a struct), set c-new-BEG to (at most) the
+ ;; beginning of that declaration. Note that declarations, in this sense,
+ ;; can be nested. c-new-BEG will be used later by c-font-lock-declarations.
+ ;;
+ ;; This function is an element of c-before-font-lock-functions, being called
+ ;; (indirectly) from an after-change function. The after-change-functions'
+ ;; parameters BEG, OLD and OLD-LEN are ignored here.
+ (when font-lock-mode
+ (goto-char (c-point 'bol c-new-BEG))
+ (let ((lit-limits (c-literal-limits))
+ bod-lim bo-decl)
+
+ (when lit-limits ; Comment or string.
+ (goto-char (car lit-limits)))
+ (setq bod-lim (max (- (point) 500) (point-min)))
+
+ (while
+ ;; Go to a less nested declaration each time round this loop.
+ (and
+ (eq (car (c-beginning-of-decl-1 bod-lim)) 'same)
+ (progn (setq bo-decl (point))
+ ;; Are we looking at a keyword such as "template" or
+ ;; "typedef" which can decorate a type, or the type itself?
+ (when (or (looking-at c-prefix-spec-kwds-re)
+ (c-forward-type t))
+ ;; We've found another candidate position.
+ (setq c-new-BEG (min c-new-BEG bo-decl))
+ (goto-char bo-decl))
+ t)
+ ;; Try and go out a level to search again.
+ (progn
+ (c-backward-syntactic-ws bod-lim)
+ (or (memq (char-before) '(?\( ?\[))
+ (and (eq (char-before) ?\<)
+ (eq (c-get-char-property
+ (1- (point)) 'syntax-table)
+ c-<-as-paren-syntax))))
+ (not (bobp)))
+ (backward-char))))) ; back over (, [, <.
(defun c-after-font-lock-init ()
;; Put on `font-lock-mode-hook'.