From cb5e207c74eb289482bdab37d9c298ec88987062 Mon Sep 17 00:00:00 2001 From: Alan Mackenzie Date: Fri, 23 Dec 2011 11:48:54 +0000 Subject: [PATCH] Fix unstable fontification inside templates. --- lisp/ChangeLog | 18 ++++++++++++ lisp/progmodes/cc-fonts.el | 21 ++------------ lisp/progmodes/cc-langs.el | 38 +++++++++++++++----------- lisp/progmodes/cc-mode.el | 68 ++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 98 insertions(+), 47 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 834244dcc72..f1a3a452367 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,21 @@ +2011-12-23 Alan Mackenzie + + 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 * desktop.el (desktop-internal-v2s): Fix typos in docstring (bug#10353). diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el index c6c8bd107f6..97cfe808322 100644 --- a/lisp/progmodes/cc-fonts.el +++ b/lisp/progmodes/cc-fonts.el @@ -1538,25 +1538,8 @@ casts and declarations are fontified. Used on level 2 and higher." ;; 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)) diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index 96f0887eec0..2b6dc7a9df7 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -485,28 +485,34 @@ The functions are called even when font locking isn't enabled. 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 ." - 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 .") ;;; Syntactic analysis ("virtual semicolons") for line-oriented languages (AWK). diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index 36b95f4b3f5..01111d2b536 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el @@ -633,13 +633,13 @@ compatible with old code; callers should always specify it." (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) @@ -881,7 +881,7 @@ Note that the style variables are always made local to the buffer." ;; 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!!! ;; @@ -1026,7 +1026,7 @@ Note that the style variables are always made local to the buffer." ;; 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 () @@ -1066,9 +1066,53 @@ Note that the style variables are always made local to the buffer." ;; 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'. -- 2.11.4.GIT