Optimize for typing characters into long C++ raw strings.

* lisp/progmodes/cc-fonts.el (c-font-lock-complex-decl-prepare)
(c-font-lock-objc-methods) (c-font-lock-declarations, c-font-lock-enum-tail)
(c-font-lock-cut-off-declarators, c-font-lock-enclosing-decls): If the chunk
been fontified consists entirely of comments and strings, don't attempt to
perform the function's action.

* lisp/progmodes/cc-mode.el (c-before-change-check-unbalanced-strings): Don't
expand (c-new-BEG c-new-END) unnecessarily to the entire raw string being
fontified.
(c-fl-decl-start, c-fl-decl-end): When in a (raw or otherwise) string, don't
return a position outside of the string (which used to cause unneeded
fontification).
This commit is contained in:
Alan Mackenzie 2019-04-23 09:16:05 +00:00
parent 085929ca93
commit 0d5caa9a0c
2 changed files with 469 additions and 455 deletions

View file

@ -880,48 +880,51 @@ casts and declarations are fontified. Used on level 2 and higher."
(when (bobp)
(c-clear-found-types))
;; Clear the c-type char properties which mark the region, to recalculate
;; them properly. The most interesting properties are those put on the
;; closest token before the region.
(save-excursion
(let ((pos (point)))
(c-backward-syntactic-ws)
(c-clear-char-properties
(if (and (not (bobp))
(memq (c-get-char-property (1- (point)) 'c-type)
'(c-decl-arg-start
c-decl-end
c-decl-id-start
c-decl-type-start)))
(1- (point))
pos)
limit 'c-type)))
(c-skip-comments-and-strings limit)
(when (< (point) limit)
;; Update `c-state-cache' to the beginning of the region. This will
;; make `c-beginning-of-syntax' go faster when it's used later on,
;; and it's near the point most of the time.
(c-parse-state)
;; Clear the c-type char properties which mark the region, to recalculate
;; them properly. The most interesting properties are those put on the
;; closest token before the region.
(save-excursion
(let ((pos (point)))
(c-backward-syntactic-ws)
(c-clear-char-properties
(if (and (not (bobp))
(memq (c-get-char-property (1- (point)) 'c-type)
'(c-decl-arg-start
c-decl-end
c-decl-id-start
c-decl-type-start)))
(1- (point))
pos)
limit 'c-type)))
;; Check if the fontified region starts inside a declarator list so
;; that `c-font-lock-declarators' should be called at the start.
;; The declared identifiers are font-locked correctly as types, if
;; that is what they are.
(let ((prop (save-excursion
(c-backward-syntactic-ws)
(unless (bobp)
(c-get-char-property (1- (point)) 'c-type)))))
(when (memq prop '(c-decl-id-start c-decl-type-start))
(c-forward-syntactic-ws limit)
(c-font-lock-declarators limit t (eq prop 'c-decl-type-start)
(not (c-bs-at-toplevel-p (point))))))
;; Update `c-state-cache' to the beginning of the region. This will
;; make `c-beginning-of-syntax' go faster when it's used later on,
;; and it's near the point most of the time.
(c-parse-state)
(setq c-font-lock-context ;; (c-guess-font-lock-context)
(save-excursion
(if (and c-cpp-expr-intro-re
(c-beginning-of-macro)
(looking-at c-cpp-expr-intro-re))
'in-cpp-expr)))
nil)
;; Check if the fontified region starts inside a declarator list so
;; that `c-font-lock-declarators' should be called at the start.
;; The declared identifiers are font-locked correctly as types, if
;; that is what they are.
(let ((prop (save-excursion
(c-backward-syntactic-ws)
(unless (bobp)
(c-get-char-property (1- (point)) 'c-type)))))
(when (memq prop '(c-decl-id-start c-decl-type-start))
(c-forward-syntactic-ws limit)
(c-font-lock-declarators limit t (eq prop 'c-decl-type-start)
(not (c-bs-at-toplevel-p (point))))))
(setq c-font-lock-context ;; (c-guess-font-lock-context)
(save-excursion
(if (and c-cpp-expr-intro-re
(c-beginning-of-macro)
(looking-at c-cpp-expr-intro-re))
'in-cpp-expr)))
nil))
(defun c-font-lock-<>-arglists (limit)
;; This function will be called from font-lock for a region bounded by POINT
@ -936,73 +939,76 @@ casts and declarations are fontified. Used on level 2 and higher."
;;
;; This function might do hidden buffer changes.
(let (;; The font-lock package in Emacs is known to clobber
;; `parse-sexp-lookup-properties' (when it exists).
(parse-sexp-lookup-properties
(cc-eval-when-compile
(boundp 'parse-sexp-lookup-properties)))
(c-parse-and-markup-<>-arglists t)
c-restricted-<>-arglists
id-start id-end id-face pos kwd-sym)
(c-skip-comments-and-strings limit)
(when (< (point) limit)
(while (and (< (point) limit)
(re-search-forward c-opt-<>-arglist-start limit t))
(let (;; The font-lock package in Emacs is known to clobber
;; `parse-sexp-lookup-properties' (when it exists).
(parse-sexp-lookup-properties
(cc-eval-when-compile
(boundp 'parse-sexp-lookup-properties)))
(c-parse-and-markup-<>-arglists t)
c-restricted-<>-arglists
id-start id-end id-face pos kwd-sym)
(setq id-start (match-beginning 1)
id-end (match-end 1)
pos (point))
(while (and (< (point) limit)
(re-search-forward c-opt-<>-arglist-start limit t))
(goto-char id-start)
(unless (c-skip-comments-and-strings limit)
(setq kwd-sym nil
c-restricted-<>-arglists nil
id-face (get-text-property id-start 'face))
(setq id-start (match-beginning 1)
id-end (match-end 1)
pos (point))
(if (cond
((eq id-face 'font-lock-type-face)
;; The identifier got the type face so it has already been
;; handled in `c-font-lock-declarations'.
nil)
(goto-char id-start)
(unless (c-skip-comments-and-strings limit)
(setq kwd-sym nil
c-restricted-<>-arglists nil
id-face (get-text-property id-start 'face))
((eq id-face 'font-lock-keyword-face)
(when (looking-at c-opt-<>-sexp-key)
;; There's a special keyword before the "<" that tells
;; that it's an angle bracket arglist.
(setq kwd-sym (c-keyword-sym (match-string 1)))))
(if (cond
((eq id-face 'font-lock-type-face)
;; The identifier got the type face so it has already been
;; handled in `c-font-lock-declarations'.
nil)
(t
;; There's a normal identifier before the "<". If we're not in
;; a declaration context then we set `c-restricted-<>-arglists'
;; to avoid recognizing templates in function calls like "foo (a
;; < b, c > d)".
(c-backward-syntactic-ws)
(when (and (memq (char-before) '(?\( ?,))
(not (eq (get-text-property (1- (point)) 'c-type)
'c-decl-arg-start)))
(setq c-restricted-<>-arglists t))
t))
((eq id-face 'font-lock-keyword-face)
(when (looking-at c-opt-<>-sexp-key)
;; There's a special keyword before the "<" that tells
;; that it's an angle bracket arglist.
(setq kwd-sym (c-keyword-sym (match-string 1)))))
(progn
(goto-char (1- pos))
;; Check for comment/string both at the identifier and
;; at the "<".
(unless (c-skip-comments-and-strings limit)
(t
;; There's a normal identifier before the "<". If we're not in
;; a declaration context then we set `c-restricted-<>-arglists'
;; to avoid recognizing templates in function calls like "foo (a
;; < b, c > d)".
(c-backward-syntactic-ws)
(when (and (memq (char-before) '(?\( ?,))
(not (eq (get-text-property (1- (point)) 'c-type)
'c-decl-arg-start)))
(setq c-restricted-<>-arglists t))
t))
(c-fontify-types-and-refs ()
(when (c-forward-<>-arglist (c-keyword-member
kwd-sym 'c-<>-type-kwds))
(when (and c-opt-identifier-concat-key
(not (get-text-property id-start 'face)))
(c-forward-syntactic-ws)
(cond ((looking-at c-opt-identifier-concat-key)
(c-put-font-lock-face id-start id-end
c-reference-face-name))
((eq (char-after) ?\())
(t (c-put-font-lock-face id-start id-end
'font-lock-type-face))))))
(progn
(goto-char (1- pos))
;; Check for comment/string both at the identifier and
;; at the "<".
(unless (c-skip-comments-and-strings limit)
(goto-char pos)))
(goto-char pos)))))
(c-fontify-types-and-refs ()
(when (c-forward-<>-arglist (c-keyword-member
kwd-sym 'c-<>-type-kwds))
(when (and c-opt-identifier-concat-key
(not (get-text-property id-start 'face)))
(c-forward-syntactic-ws)
(cond ((looking-at c-opt-identifier-concat-key)
(c-put-font-lock-face id-start id-end
c-reference-face-name))
((eq (char-after) ?\())
(t (c-put-font-lock-face id-start id-end
'font-lock-type-face))))))
(goto-char pos)))
(goto-char pos))))))
nil)
(defun c-font-lock-declarators (limit list types not-top
@ -1311,227 +1317,229 @@ casts and declarations are fontified. Used on level 2 and higher."
;; This function might do hidden buffer changes.
;;(message "c-font-lock-declarations search from %s to %s" (point) limit)
(c-skip-comments-and-strings limit)
(when (< (point) limit)
(save-restriction
(let (;; The position where `c-find-decl-spots' last stopped.
start-pos
;; o - 'decl if we're in an arglist containing declarations
;; (but if `c-recognize-paren-inits' is set it might also be
;; an initializer arglist);
;; o - '<> if the arglist is of angle bracket type;
;; o - 'arglist if it's some other arglist;
;; o - nil, if not in an arglist at all. This includes the
;; parenthesized condition which follows "if", "while", etc.
context
;; A list of starting positions of possible type declarations, or of
;; the typedef preceding one, if any.
last-cast-end
;; The result from `c-forward-decl-or-cast-1'.
decl-or-cast
;; The maximum of the end positions of all the checked type
;; decl expressions in the successfully identified
;; declarations. The position might be either before or
;; after the syntactic whitespace following the last token
;; in the type decl expression.
(max-type-decl-end 0)
;; Same as `max-type-decl-*', but used when we're before
;; `token-pos'.
(max-type-decl-end-before-token 0)
;; End of <..> construct which has had c-<>-arg-sep c-type
;; properties set within it.
(max-<>-end 0)
;; Set according to the context to direct the heuristics for
;; recognizing C++ templates.
c-restricted-<>-arglists
;; Turn on recording of identifier ranges in
;; `c-forward-decl-or-cast-1' and `c-forward-label' for
;; later fontification.
(c-record-type-identifiers t)
label-type
c-record-ref-identifiers
;; Make `c-forward-type' calls mark up template arglists if
;; it finds any. That's necessary so that we later will
;; stop inside them to fontify types there.
(c-parse-and-markup-<>-arglists t)
;; The font-lock package in Emacs is known to clobber
;; `parse-sexp-lookup-properties' (when it exists).
(parse-sexp-lookup-properties
(cc-eval-when-compile
(boundp 'parse-sexp-lookup-properties))
))
(save-restriction
(let (;; The position where `c-find-decl-spots' last stopped.
start-pos
;; o - 'decl if we're in an arglist containing declarations
;; (but if `c-recognize-paren-inits' is set it might also be
;; an initializer arglist);
;; o - '<> if the arglist is of angle bracket type;
;; o - 'arglist if it's some other arglist;
;; o - nil, if not in an arglist at all. This includes the
;; parenthesized condition which follows "if", "while", etc.
context
;; A list of starting positions of possible type declarations, or of
;; the typedef preceding one, if any.
last-cast-end
;; The result from `c-forward-decl-or-cast-1'.
decl-or-cast
;; The maximum of the end positions of all the checked type
;; decl expressions in the successfully identified
;; declarations. The position might be either before or
;; after the syntactic whitespace following the last token
;; in the type decl expression.
(max-type-decl-end 0)
;; Same as `max-type-decl-*', but used when we're before
;; `token-pos'.
(max-type-decl-end-before-token 0)
;; End of <..> construct which has had c-<>-arg-sep c-type
;; properties set within it.
(max-<>-end 0)
;; Set according to the context to direct the heuristics for
;; recognizing C++ templates.
c-restricted-<>-arglists
;; Turn on recording of identifier ranges in
;; `c-forward-decl-or-cast-1' and `c-forward-label' for
;; later fontification.
(c-record-type-identifiers t)
label-type
c-record-ref-identifiers
;; Make `c-forward-type' calls mark up template arglists if
;; it finds any. That's necessary so that we later will
;; stop inside them to fontify types there.
(c-parse-and-markup-<>-arglists t)
;; The font-lock package in Emacs is known to clobber
;; `parse-sexp-lookup-properties' (when it exists).
(parse-sexp-lookup-properties
(cc-eval-when-compile
(boundp 'parse-sexp-lookup-properties))
))
;; Below we fontify a whole declaration even when it crosses the limit,
;; to avoid gaps when jit/lazy-lock fontifies the file a block at a
;; time. That is however annoying during editing, e.g. the following is
;; a common situation while the first line is being written:
;;
;; my_variable
;; some_other_variable = 0;
;;
;; font-lock will put the limit at the beginning of the second line
;; here, and if we go past it we'll fontify "my_variable" as a type and
;; "some_other_variable" as an identifier, and the latter will not
;; correct itself until the second line is changed. To avoid that we
;; narrow to the limit if the region to fontify is a single line.
(if (<= limit (c-point 'bonl))
(narrow-to-region
(point-min)
(save-excursion
;; Narrow after any operator chars following the limit though,
;; since those characters can be useful in recognizing a
;; declaration (in particular the '{' that opens a function body
;; after the header).
(goto-char limit)
(skip-chars-forward c-nonsymbol-chars)
(point))))
;; Below we fontify a whole declaration even when it crosses the limit,
;; to avoid gaps when jit/lazy-lock fontifies the file a block at a
;; time. That is however annoying during editing, e.g. the following is
;; a common situation while the first line is being written:
;;
;; my_variable
;; some_other_variable = 0;
;;
;; font-lock will put the limit at the beginning of the second line
;; here, and if we go past it we'll fontify "my_variable" as a type and
;; "some_other_variable" as an identifier, and the latter will not
;; correct itself until the second line is changed. To avoid that we
;; narrow to the limit if the region to fontify is a single line.
(if (<= limit (c-point 'bonl))
(narrow-to-region
(point-min)
(save-excursion
;; Narrow after any operator chars following the limit though,
;; since those characters can be useful in recognizing a
;; declaration (in particular the '{' that opens a function body
;; after the header).
(goto-char limit)
(skip-chars-forward c-nonsymbol-chars)
(point))))
(c-find-decl-spots
limit
c-decl-start-re
(eval c-maybe-decl-faces)
(c-find-decl-spots
limit
c-decl-start-re
(eval c-maybe-decl-faces)
(lambda (match-pos inside-macro &optional toplev)
;; Note to maintainers: don't use `limit' inside this lambda form;
;; c-find-decl-spots sometimes narrows to less than `limit'.
(setq start-pos (point))
(when
;; The result of the form below is true when we don't recognize a
;; declaration or cast, and we don't recognize a "non-decl",
;; typically a brace list.
(if (or (and (eq (get-text-property (point) 'face)
'font-lock-keyword-face)
(looking-at c-not-decl-init-keywords))
(and c-macro-with-semi-re
(looking-at c-macro-with-semi-re))) ; 2008-11-04
;; Don't do anything more if we're looking at a keyword that
;; can't start a declaration.
t
(lambda (match-pos inside-macro &optional toplev)
;; Note to maintainers: don't use `limit' inside this lambda form;
;; c-find-decl-spots sometimes narrows to less than `limit'.
(setq start-pos (point))
(when
;; The result of the form below is true when we don't recognize a
;; declaration or cast, and we don't recognize a "non-decl",
;; typically a brace list.
(if (or (and (eq (get-text-property (point) 'face)
'font-lock-keyword-face)
(looking-at c-not-decl-init-keywords))
(and c-macro-with-semi-re
(looking-at c-macro-with-semi-re))) ; 2008-11-04
;; Don't do anything more if we're looking at a keyword that
;; can't start a declaration.
t
;; Set `context' and `c-restricted-<>-arglists'. Look for
;; "<" for the sake of C++-style template arglists.
;; Ignore "(" when it's part of a control flow construct
;; (e.g. "for (").
(let ((got-context
(c-get-fontification-context
match-pos
(< match-pos (if inside-macro
max-type-decl-end-before-token
max-type-decl-end))
toplev)))
(setq context (car got-context)
c-restricted-<>-arglists (cdr got-context)))
;; Set `context' and `c-restricted-<>-arglists'. Look for
;; "<" for the sake of C++-style template arglists.
;; Ignore "(" when it's part of a control flow construct
;; (e.g. "for (").
(let ((got-context
(c-get-fontification-context
match-pos
(< match-pos (if inside-macro
max-type-decl-end-before-token
max-type-decl-end))
toplev)))
(setq context (car got-context)
c-restricted-<>-arglists (cdr got-context)))
;; Check we haven't missed a preceding "typedef".
(when (not (looking-at c-typedef-key))
(c-backward-syntactic-ws)
(c-backward-token-2)
(or (looking-at c-typedef-key)
(goto-char start-pos)))
;; Check we haven't missed a preceding "typedef".
(when (not (looking-at c-typedef-key))
(c-backward-syntactic-ws)
(c-backward-token-2)
(or (looking-at c-typedef-key)
(goto-char start-pos)))
;; In QT, "more" is an irritating keyword that expands to nothing.
;; We skip over it to prevent recognition of "more slots: <symbol>"
;; as a bitfield declaration.
(when (and (c-major-mode-is 'c++-mode)
(looking-at
(concat "\\(more\\)\\([^" c-symbol-chars "]\\|$\\)")))
(goto-char (match-end 1))
(c-forward-syntactic-ws))
;; In QT, "more" is an irritating keyword that expands to nothing.
;; We skip over it to prevent recognition of "more slots: <symbol>"
;; as a bitfield declaration.
(when (and (c-major-mode-is 'c++-mode)
(looking-at
(concat "\\(more\\)\\([^" c-symbol-chars "]\\|$\\)")))
(goto-char (match-end 1))
(c-forward-syntactic-ws))
;; Now analyze the construct.
(if (eq context 'not-decl)
(progn
(setq decl-or-cast nil)
(if (c-syntactic-re-search-forward
"," (min limit (point-max)) 'at-limit t)
(c-put-char-property (1- (point)) 'c-type 'c-not-decl))
nil)
(setq decl-or-cast
(c-forward-decl-or-cast-1
match-pos context last-cast-end))
;; Now analyze the construct.
(if (eq context 'not-decl)
(progn
(setq decl-or-cast nil)
(if (c-syntactic-re-search-forward
"," (min limit (point-max)) 'at-limit t)
(c-put-char-property (1- (point)) 'c-type 'c-not-decl))
nil)
(setq decl-or-cast
(c-forward-decl-or-cast-1
match-pos context last-cast-end))
;; Ensure that c-<>-arg-sep c-type properties are in place on the
;; commas separating the arguments inside template/generic <..>s.
(when (and (eq (char-before match-pos) ?<)
(> match-pos max-<>-end))
(save-excursion
(goto-char match-pos)
(c-backward-token-2)
(if (and
(eq (char-after) ?<)
(let ((c-restricted-<>-arglists
(save-excursion
(c-backward-token-2)
(and
(not (looking-at c-opt-<>-sexp-key))
(progn (c-backward-syntactic-ws)
(memq (char-before) '(?\( ?,)))
(not (eq (c-get-char-property (1- (point))
'c-type)
'c-decl-arg-start))))))
(c-forward-<>-arglist nil)))
(setq max-<>-end (point)))))
;; Ensure that c-<>-arg-sep c-type properties are in place on the
;; commas separating the arguments inside template/generic <..>s.
(when (and (eq (char-before match-pos) ?<)
(> match-pos max-<>-end))
(save-excursion
(goto-char match-pos)
(c-backward-token-2)
(if (and
(eq (char-after) ?<)
(let ((c-restricted-<>-arglists
(save-excursion
(c-backward-token-2)
(and
(not (looking-at c-opt-<>-sexp-key))
(progn (c-backward-syntactic-ws)
(memq (char-before) '(?\( ?,)))
(not (eq (c-get-char-property (1- (point))
'c-type)
'c-decl-arg-start))))))
(c-forward-<>-arglist nil)))
(setq max-<>-end (point)))))
(cond
((eq decl-or-cast 'cast)
;; Save the position after the previous cast so we can feed
;; it to `c-forward-decl-or-cast-1' in the next round. That
;; helps it discover cast chains like "(a) (b) c".
(setq last-cast-end (point))
(c-fontify-recorded-types-and-refs)
nil)
(cond
((eq decl-or-cast 'cast)
;; Save the position after the previous cast so we can feed
;; it to `c-forward-decl-or-cast-1' in the next round. That
;; helps it discover cast chains like "(a) (b) c".
(setq last-cast-end (point))
(c-fontify-recorded-types-and-refs)
nil)
(decl-or-cast
;; We've found a declaration.
(decl-or-cast
;; We've found a declaration.
;; Set `max-type-decl-end' or `max-type-decl-end-before-token'
;; under the assumption that we're after the first type decl
;; expression in the declaration now. That's not really true;
;; we could also be after a parenthesized initializer
;; expression in C++, but this is only used as a last resort
;; to slant ambiguous expression/declarations, and overall
;; it's worth the risk to occasionally fontify an expression
;; as a declaration in an initializer expression compared to
;; getting ambiguous things in normal function prototypes
;; fontified as expressions.
(if inside-macro
(when (> (point) max-type-decl-end-before-token)
(setq max-type-decl-end-before-token (point)))
(when (> (point) max-type-decl-end)
(setq max-type-decl-end (point))))
(goto-char start-pos)
(c-font-lock-single-decl limit decl-or-cast match-pos
context
(or toplev (nth 4 decl-or-cast))))
;; Set `max-type-decl-end' or `max-type-decl-end-before-token'
;; under the assumption that we're after the first type decl
;; expression in the declaration now. That's not really true;
;; we could also be after a parenthesized initializer
;; expression in C++, but this is only used as a last resort
;; to slant ambiguous expression/declarations, and overall
;; it's worth the risk to occasionally fontify an expression
;; as a declaration in an initializer expression compared to
;; getting ambiguous things in normal function prototypes
;; fontified as expressions.
(if inside-macro
(when (> (point) max-type-decl-end-before-token)
(setq max-type-decl-end-before-token (point)))
(when (> (point) max-type-decl-end)
(setq max-type-decl-end (point))))
(goto-char start-pos)
(c-font-lock-single-decl limit decl-or-cast match-pos
context
(or toplev (nth 4 decl-or-cast))))
(t t))))
(t t))))
;; It was a false alarm. Check if we're in a label (or other
;; construct with `:' except bitfield) instead.
(goto-char start-pos)
(when (setq label-type (c-forward-label t match-pos nil))
;; Can't use `c-fontify-types-and-refs' here since we
;; use the label face at times.
(cond ((eq label-type 'goto-target)
(c-put-font-lock-face (caar c-record-ref-identifiers)
(cdar c-record-ref-identifiers)
c-label-face-name))
((eq label-type 'qt-1kwd-colon)
(c-put-font-lock-face (caar c-record-ref-identifiers)
(cdar c-record-ref-identifiers)
'font-lock-keyword-face))
((eq label-type 'qt-2kwds-colon)
(mapc
(lambda (kwd)
(c-put-font-lock-face (car kwd) (cdr kwd)
;; It was a false alarm. Check if we're in a label (or other
;; construct with `:' except bitfield) instead.
(goto-char start-pos)
(when (setq label-type (c-forward-label t match-pos nil))
;; Can't use `c-fontify-types-and-refs' here since we
;; use the label face at times.
(cond ((eq label-type 'goto-target)
(c-put-font-lock-face (caar c-record-ref-identifiers)
(cdar c-record-ref-identifiers)
c-label-face-name))
((eq label-type 'qt-1kwd-colon)
(c-put-font-lock-face (caar c-record-ref-identifiers)
(cdar c-record-ref-identifiers)
'font-lock-keyword-face))
c-record-ref-identifiers)))
(setq c-record-ref-identifiers nil)
;; `c-forward-label' has probably added a `c-decl-end'
;; marker, so return t to `c-find-decl-spots' to signal
;; that.
t))))
((eq label-type 'qt-2kwds-colon)
(mapc
(lambda (kwd)
(c-put-font-lock-face (car kwd) (cdr kwd)
'font-lock-keyword-face))
c-record-ref-identifiers)))
(setq c-record-ref-identifiers nil)
;; `c-forward-label' has probably added a `c-decl-end'
;; marker, so return t to `c-find-decl-spots' to signal
;; that.
t))))
nil)))
nil))))
(defun c-font-lock-enum-body (limit)
;; Fontify the identifiers of each enum we find by searching forward.
@ -1561,19 +1569,21 @@ casts and declarations are fontified. Used on level 2 and higher."
;;
;; Note that this function won't attempt to fontify beyond the end of the
;; current enum block, if any.
(let* ((paren-state (c-parse-state))
(encl-pos (c-most-enclosing-brace paren-state)))
(when (and
encl-pos
(eq (char-after encl-pos) ?\{)
(save-excursion
(goto-char encl-pos)
(c-backward-over-enum-header)))
(c-syntactic-skip-backward "^{," nil t)
(c-put-char-property (1- (point)) 'c-type 'c-decl-id-start)
(c-skip-comments-and-strings limit)
(when (< (point) limit)
(let* ((paren-state (c-parse-state))
(encl-pos (c-most-enclosing-brace paren-state)))
(when (and
encl-pos
(eq (char-after encl-pos) ?\{)
(save-excursion
(goto-char encl-pos)
(c-backward-over-enum-header)))
(c-syntactic-skip-backward "^{," nil t)
(c-put-char-property (1- (point)) 'c-type 'c-decl-id-start)
(c-forward-syntactic-ws)
(c-font-lock-declarators limit t nil t)))
(c-forward-syntactic-ws)
(c-font-lock-declarators limit t nil t))))
nil)
(defun c-font-lock-cut-off-declarators (limit)
@ -1585,46 +1595,48 @@ casts and declarations are fontified. Used on level 2 and higher."
;; font-lock-keyword-face. It always returns NIL to inhibit this and
;; prevent a repeat invocation. See elisp/lispref page "Search-based
;; fontification".
(let ((here (point))
(decl-search-lim (c-determine-limit 1000))
paren-state encl-pos token-end context decl-or-cast
start-pos top-level c-restricted-<>-arglists
c-recognize-knr-p) ; Strictly speaking, bogus, but it
(c-skip-comments-and-strings limit)
(when (< (point) limit)
(let ((here (point))
(decl-search-lim (c-determine-limit 1000))
paren-state encl-pos token-end context decl-or-cast
start-pos top-level c-restricted-<>-arglists
c-recognize-knr-p) ; Strictly speaking, bogus, but it
; speeds up lisp.h tremendously.
(save-excursion
(when (not (c-back-over-member-initializers))
(unless (or (eobp)
(looking-at "\\s(\\|\\s)"))
(forward-char))
(c-syntactic-skip-backward "^;{}" decl-search-lim t)
(when (eq (char-before) ?})
(c-go-list-backward) ; brace block of struct, etc.?
(c-syntactic-skip-backward "^;{}" decl-search-lim t))
(when (or (bobp)
(memq (char-before) '(?\; ?{ ?})))
(setq token-end (point))
(c-forward-syntactic-ws here)
(when (< (point) here)
;; We're now putatively at the declaration.
(setq start-pos (point))
(setq paren-state (c-parse-state))
;; At top level or inside a "{"?
(if (or (not (setq encl-pos
(c-most-enclosing-brace paren-state)))
(eq (char-after encl-pos) ?\{))
(progn
(setq top-level (c-at-toplevel-p))
(let ((got-context (c-get-fontification-context
token-end nil top-level)))
(setq context (car got-context)
c-restricted-<>-arglists (cdr got-context)))
(setq decl-or-cast
(c-forward-decl-or-cast-1 token-end context nil))
(when (consp decl-or-cast)
(goto-char start-pos)
(c-font-lock-single-decl limit decl-or-cast token-end
context top-level))))))))
nil))
(save-excursion
(when (not (c-back-over-member-initializers))
(unless (or (eobp)
(looking-at "\\s(\\|\\s)"))
(forward-char))
(c-syntactic-skip-backward "^;{}" decl-search-lim t)
(when (eq (char-before) ?})
(c-go-list-backward) ; brace block of struct, etc.?
(c-syntactic-skip-backward "^;{}" decl-search-lim t))
(when (or (bobp)
(memq (char-before) '(?\; ?{ ?})))
(setq token-end (point))
(c-forward-syntactic-ws here)
(when (< (point) here)
;; We're now putatively at the declaration.
(setq start-pos (point))
(setq paren-state (c-parse-state))
;; At top level or inside a "{"?
(if (or (not (setq encl-pos
(c-most-enclosing-brace paren-state)))
(eq (char-after encl-pos) ?\{))
(progn
(setq top-level (c-at-toplevel-p))
(let ((got-context (c-get-fontification-context
token-end nil top-level)))
(setq context (car got-context)
c-restricted-<>-arglists (cdr got-context)))
(setq decl-or-cast
(c-forward-decl-or-cast-1 token-end context nil))
(when (consp decl-or-cast)
(goto-char start-pos)
(c-font-lock-single-decl limit decl-or-cast token-end
context top-level))))))))
nil)))
(defun c-font-lock-enclosing-decls (limit)
;; Fontify the declarators of (nested) declarations we're in the middle of.
@ -1636,27 +1648,29 @@ casts and declarations are fontified. Used on level 2 and higher."
;; font-lock-keyword-face. It always returns NIL to inhibit this and
;; prevent a repeat invocation. See elisp/lispref page "Search-based
;; Fontification".
(let* ((paren-state (c-parse-state))
(decl-search-lim (c-determine-limit 1000))
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 (and (atom ps-elt)
(eq (char-after ps-elt) ?\{))
(goto-char ps-elt)
(c-syntactic-skip-backward "^;{}" decl-search-lim)
(c-forward-syntactic-ws)
(setq in-typedef (looking-at c-typedef-key))
(if in-typedef (c-forward-over-token-and-ws))
(when (and c-opt-block-decls-with-vars-key
(looking-at c-opt-block-decls-with-vars-key))
(c-skip-comments-and-strings limit)
(when (< (point) limit)
(let* ((paren-state (c-parse-state))
(decl-search-lim (c-determine-limit 1000))
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 (and (atom ps-elt)
(eq (char-after ps-elt) ?\{))
(goto-char ps-elt)
(when (c-safe (c-forward-sexp))
(c-forward-syntactic-ws)
(c-font-lock-declarators limit t in-typedef
(not (c-bs-at-toplevel-p (point))))))))))
(c-syntactic-skip-backward "^;{}" decl-search-lim)
(c-forward-syntactic-ws)
(setq in-typedef (looking-at c-typedef-key))
(if in-typedef (c-forward-over-token-and-ws))
(when (and c-opt-block-decls-with-vars-key
(looking-at c-opt-block-decls-with-vars-key))
(goto-char ps-elt)
(when (c-safe (c-forward-sexp))
(c-forward-syntactic-ws)
(c-font-lock-declarators limit t in-typedef
(not (c-bs-at-toplevel-p (point)))))))))))
(defun c-font-lock-raw-strings (limit)
;; Fontify C++ raw strings.

View file

@ -1192,8 +1192,6 @@ Note that the style variables are always made local to the buffer."
(beg-literal-type (and beg-limits
(c-literal-type beg-limits))))
(when (eq end-literal-type 'string)
(setq c-new-END (max c-new-END (cdr end-limits))))
;; It is possible the buffer change will include inserting a string quote.
;; This could have the effect of flipping the meaning of any following
;; quotes up until the next unescaped EOL. Also guard against the change
@ -1282,7 +1280,6 @@ Note that the style variables are always made local to the buffer."
(when (and (eq beg-literal-type 'string)
(memq (char-after (car beg-limits)) c-string-delims))
(setq c-new-BEG (min c-new-BEG (car beg-limits)))
(c-clear-char-property (car beg-limits) 'syntax-table)
(c-truncate-semi-nonlit-pos-cache (car beg-limits))))))
@ -1832,6 +1829,9 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
;; declaration is one which does not start outside of struct braces (and
;; similar) enclosing POS. Brace list braces here are not "similar".
;;
;; POS being in a literal does not count as being in a declaration (on
;; pragmatic grounds).
;;
;; This function is called indirectly from font locking stuff - either from
;; c-after-change (to prepare for after-change font-locking) or from font
;; lock context (etc.) fontification.
@ -1842,92 +1842,92 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
capture-opener
bod-lim bo-decl)
(goto-char (c-point 'bol new-pos))
(when lit-start ; Comment or string.
(goto-char lit-start))
(setq bod-lim (c-determine-limit 500))
(unless lit-start
(setq bod-lim (c-determine-limit 500))
;; In C++ Mode, first check if we are within a (possibly nested) lambda
;; form capture list.
(when (c-major-mode-is 'c++-mode)
(let ((paren-state (c-parse-state))
opener)
(save-excursion
(while (setq opener (c-pull-open-brace paren-state))
(goto-char opener)
(if (c-looking-at-c++-lambda-capture-list)
(setq capture-opener (point)))))))
;; In C++ Mode, first check if we are within a (possibly nested) lambda
;; form capture list.
(when (c-major-mode-is 'c++-mode)
(let ((paren-state (c-parse-state))
opener)
(save-excursion
(while (setq opener (c-pull-open-brace paren-state))
(goto-char opener)
(if (c-looking-at-c++-lambda-capture-list)
(setq capture-opener (point)))))))
(while
;; Go to a less nested declaration each time round this loop.
(and
(setq old-pos (point))
(let (pseudo)
(while
(progn
(c-syntactic-skip-backward "^;{}" bod-lim t)
(and (eq (char-before) ?})
(save-excursion
(backward-char)
(setq pseudo (c-cheap-inside-bracelist-p (c-parse-state))))))
(goto-char pseudo))
t)
(> (point) bod-lim)
(progn (c-forward-syntactic-ws)
;; Have we got stuck in a comment at EOB?
(not (and (eobp)
(c-literal-start))))
(< (point) old-pos)
(progn (setq bo-decl (point))
(or (not (looking-at c-protection-key))
(c-forward-keyword-clause 1)))
(progn
;; 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 new-pos (min new-pos bo-decl))
(goto-char bo-decl))
t)
;; Try and go out a level to search again.
(progn
(c-backward-syntactic-ws bod-lim)
(and (> (point) bod-lim)
(or (memq (char-before) '(?\( ?\[))
(and (eq (char-before) ?\<)
(eq (c-get-char-property
(1- (point)) 'syntax-table)
c-<-as-paren-syntax))
(and (eq (char-before) ?{)
(save-excursion
(backward-char)
(consp (c-looking-at-or-maybe-in-bracelist))))
)))
(not (bobp)))
(backward-char)) ; back over (, [, <.
(when (and capture-opener (< capture-opener new-pos))
(setq new-pos capture-opener))
(and (/= new-pos pos) new-pos)))
(while
;; Go to a less nested declaration each time round this loop.
(and
(setq old-pos (point))
(let (pseudo)
(while
(progn
(c-syntactic-skip-backward "^;{}" bod-lim t)
(and (eq (char-before) ?})
(save-excursion
(backward-char)
(setq pseudo (c-cheap-inside-bracelist-p (c-parse-state))))))
(goto-char pseudo))
t)
(> (point) bod-lim)
(progn (c-forward-syntactic-ws)
;; Have we got stuck in a comment at EOB?
(not (and (eobp)
(c-literal-start))))
(< (point) old-pos)
(progn (setq bo-decl (point))
(or (not (looking-at c-protection-key))
(c-forward-keyword-clause 1)))
(progn
;; 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 new-pos (min new-pos bo-decl))
(goto-char bo-decl))
t)
;; Try and go out a level to search again.
(progn
(c-backward-syntactic-ws bod-lim)
(and (> (point) bod-lim)
(or (memq (char-before) '(?\( ?\[))
(and (eq (char-before) ?\<)
(eq (c-get-char-property
(1- (point)) 'syntax-table)
c-<-as-paren-syntax))
(and (eq (char-before) ?{)
(save-excursion
(backward-char)
(consp (c-looking-at-or-maybe-in-bracelist))))
)))
(not (bobp)))
(backward-char)) ; back over (, [, <.
(when (and capture-opener (< capture-opener new-pos))
(setq new-pos capture-opener))
(and (/= new-pos pos) new-pos))))
(defun c-fl-decl-end (pos)
;; If POS is inside a declarator, return the end of the token that follows
;; the declarator, otherwise return nil.
;; the declarator, otherwise return nil. POS being in a literal does not
;; count as being in a declarator (on pragmatic grounds).
(goto-char pos)
(let ((lit-start (c-literal-start))
pos1)
(if lit-start (goto-char lit-start))
(c-backward-syntactic-ws)
(when (setq pos1 (c-on-identifier))
(goto-char pos1)
(let ((lim (save-excursion
(and (c-beginning-of-macro)
(progn (c-end-of-macro) (point))))))
(when (and (c-forward-declarator lim)
(or (not (eq (char-after) ?\())
(c-go-list-forward nil lim))
(eq (c-forward-token-2 1 nil lim) 0))
(c-backward-syntactic-ws)
(point))))))
(unless lit-start
(c-backward-syntactic-ws)
(when (setq pos1 (c-on-identifier))
(goto-char pos1)
(let ((lim (save-excursion
(and (c-beginning-of-macro)
(progn (c-end-of-macro) (point))))))
(when (and (c-forward-declarator lim)
(or (not (eq (char-after) ?\())
(c-go-list-forward nil lim))
(eq (c-forward-token-2 1 nil lim) 0))
(c-backward-syntactic-ws)
(point)))))))
(defun c-change-expand-fl-region (_beg _end _old-len)
;; Expand the region (c-new-BEG c-new-END) to an after-change font-lock