]> git.eshelyaron.com Git - emacs.git/commitdiff
Optimise c-font-lock-<>-arglists, particularly for buffers with few <..> pairs
authorAlan Mackenzie <acm@muc.de>
Mon, 14 Dec 2020 20:44:33 +0000 (20:44 +0000)
committerAlan Mackenzie <acm@muc.de>
Mon, 14 Dec 2020 20:44:33 +0000 (20:44 +0000)
* lisp/progmodes/cc-fonts.el (c-font-lock-<>-arglists): In place of a regexp
search for a complicated and slow regexp, search simply for "<" ouside of
literals together with add hoc testing of other requirements for a <...>
match.

* lisp/progmodes/cc-langs.el (c-nonsymbol-key): New c-lang-defvar from the
c-lang-const.

lisp/progmodes/cc-fonts.el
lisp/progmodes/cc-langs.el

index bb7e5bea6e6bba1dec987c8df8a52bc950a95234..38166c27ec85260b056455902370145c8d82d3c9 100644 (file)
@@ -1008,66 +1008,75 @@ casts and declarations are fontified.  Used on level 2 and higher."
             (boundp 'parse-sexp-lookup-properties)))
          (c-parse-and-markup-<>-arglists t)
          c-restricted-<>-arglists
-         id-start id-end id-face pos kwd-sym)
+         id-start id-end id-face pos kwd-sym
+         old-pos)
 
       (while (and (< (point) limit)
-                 (re-search-forward c-opt-<>-arglist-start limit t))
-
-       (setq id-start (match-beginning 1)
-             id-end (match-end 1)
-             pos (point))
-
-       (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))
-
-         (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)
-
-              ((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)))))
-
-              (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))
+                 (setq old-pos (point))
+                 (c-syntactic-re-search-forward "<" limit t nil t))
+       (setq pos (point))
+       (save-excursion
+         (backward-char)
+         (c-backward-syntactic-ws old-pos)
+         (if (re-search-backward
+              (concat "\\(\\`\\|" c-nonsymbol-key "\\)\\(" c-symbol-key"\\)\\=")
+              old-pos t)
+             (setq id-start (match-beginning 2)
+                   id-end (match-end 2))
+           (setq id-start nil id-end nil)))
+
+       (when id-start
+         (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))
+
+           (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)
 
-             (progn
-               (goto-char (1- pos))
-               ;; Check for comment/string both at the identifier and
-               ;; at the "<".
-               (unless (c-skip-comments-and-strings limit)
-
-                 (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))))))
+                ((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 2)))))
+
+                (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))
+
+               (progn
+                 (goto-char (1- pos))
+                 ;; Check for comment/string both at the identifier and
+                 ;; at the "<".
+                 (unless (c-skip-comments-and-strings limit)
+
+                   (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
index d6089ea2950ac08094e2d66e1a4e48f706a07f97..4d1aeaa5cb92f841e816cb7bb00815d9ebb5063f 100644 (file)
@@ -699,6 +699,7 @@ It's assumed to not contain any submatchers."
   ;; The same thing regarding Unicode identifiers applies here as to
   ;; `c-symbol-key'.
   t (concat "[" (c-lang-const c-nonsymbol-chars) "]"))
+(c-lang-defvar c-nonsymbol-key (c-lang-const c-nonsymbol-key))
 
 (c-lang-defconst c-identifier-ops
   "The operators that make up fully qualified identifiers.  nil in