LCOV - code coverage report
Current view: top level - lisp - font-lock.el (source / functions) Hit Total Coverage
Test: tramp-tests-after.info Lines: 132 606 21.8 %
Date: 2017-08-30 10:12:24 Functions: 12 44 27.3 %

          Line data    Source code
       1             : ;;; font-lock.el --- Electric font lock mode
       2             : 
       3             : ;; Copyright (C) 1992-2017 Free Software Foundation, Inc.
       4             : 
       5             : ;; Author: Jamie Zawinski
       6             : ;;      Richard Stallman
       7             : ;;      Stefan Monnier
       8             : ;; Maintainer: emacs-devel@gnu.org
       9             : ;; Keywords: languages, faces
      10             : ;; Package: emacs
      11             : 
      12             : ;; This file is part of GNU Emacs.
      13             : 
      14             : ;; GNU Emacs is free software: you can redistribute it and/or modify
      15             : ;; it under the terms of the GNU General Public License as published by
      16             : ;; the Free Software Foundation, either version 3 of the License, or
      17             : ;; (at your option) any later version.
      18             : 
      19             : ;; GNU Emacs is distributed in the hope that it will be useful,
      20             : ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
      21             : ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      22             : ;; GNU General Public License for more details.
      23             : 
      24             : ;; You should have received a copy of the GNU General Public License
      25             : ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
      26             : 
      27             : ;;; Commentary:
      28             : 
      29             : ;; Font Lock mode is a minor mode that causes your comments to be displayed in
      30             : ;; one face, strings in another, reserved words in another, and so on.
      31             : ;;
      32             : ;; Comments will be displayed in `font-lock-comment-face'.
      33             : ;; Strings will be displayed in `font-lock-string-face'.
      34             : ;; Regexps are used to display selected patterns in other faces.
      35             : ;;
      36             : ;; To make the text you type be fontified, use M-x font-lock-mode RET.
      37             : ;; When this minor mode is on, the faces of the current line are updated with
      38             : ;; every insertion or deletion.
      39             : ;;
      40             : ;; To turn Font Lock mode on automatically, add this to your init file:
      41             : ;;
      42             : ;;  (add-hook 'emacs-lisp-mode-hook #'turn-on-font-lock)
      43             : ;;
      44             : ;; Or if you want to turn Font Lock mode on in many modes:
      45             : ;;
      46             : ;;  (global-font-lock-mode t)
      47             : ;;
      48             : ;; Fontification for a particular mode may be available in a number of levels
      49             : ;; of decoration.  The higher the level, the more decoration, but the more time
      50             : ;; it takes to fontify.  See the variable `font-lock-maximum-decoration', and
      51             : ;; also the variable `font-lock-maximum-size'.  Support modes for Font Lock
      52             : ;; mode can be used to speed up Font Lock mode.  See `font-lock-support-mode'.
      53             : 
      54             : ;;; How Font Lock mode fontifies:
      55             : 
      56             : ;; When Font Lock mode is turned on in a buffer, it (a) fontifies the entire
      57             : ;; buffer and (b) installs one of its fontification functions on one of the
      58             : ;; hook variables that are run by Emacs after every buffer change (i.e., an
      59             : ;; insertion or deletion).  Fontification means the replacement of `face' text
      60             : ;; properties in a given region; Emacs displays text with these `face' text
      61             : ;; properties appropriately.
      62             : ;;
      63             : ;; Fontification normally involves syntactic (i.e., strings and comments) and
      64             : ;; regexp (i.e., keywords and everything else) passes.  There are actually
      65             : ;; three passes; (a) the syntactic keyword pass, (b) the syntactic pass and (c)
      66             : ;; the keyword pass.  Confused?
      67             : ;;
      68             : ;; The syntactic keyword pass places `syntax-table' text properties in the
      69             : ;; buffer according to the variable `font-lock-syntactic-keywords'.  It is
      70             : ;; necessary because Emacs's syntax table is not powerful enough to describe all
      71             : ;; the different syntactic constructs required by the sort of people who decide
      72             : ;; that a single quote can be syntactic or not depending on the time of day.
      73             : ;; (What sort of person could decide to overload the meaning of a quote?)
      74             : ;; Obviously the syntactic keyword pass must occur before the syntactic pass.
      75             : ;;
      76             : ;; The syntactic pass places `face' text properties in the buffer according to
      77             : ;; syntactic context, i.e., according to the buffer's syntax table and buffer
      78             : ;; text's `syntax-table' text properties.  It involves using a syntax parsing
      79             : ;; function to determine the context of different parts of a region of text.  A
      80             : ;; syntax parsing function is necessary because generally strings and/or
      81             : ;; comments can span lines, and so the context of a given region is not
      82             : ;; necessarily apparent from the content of that region.  Because the keyword
      83             : ;; pass only works within a given region, it is not generally appropriate for
      84             : ;; syntactic fontification.  This is the first fontification pass that makes
      85             : ;; changes visible to the user; it fontifies strings and comments.
      86             : ;;
      87             : ;; The keyword pass places `face' text properties in the buffer according to
      88             : ;; the variable `font-lock-keywords'.  It involves searching for given regexps
      89             : ;; (or calling given search functions) within the given region.  This is the
      90             : ;; second fontification pass that makes changes visible to the user; it
      91             : ;; fontifies language reserved words, etc.
      92             : ;;
      93             : ;; Oh, and the answer is, "Yes, obviously just about everything should be done
      94             : ;; in a single syntactic pass, but the only syntactic parser available
      95             : ;; understands only strings and comments."  Perhaps one day someone will write
      96             : ;; some syntactic parsers for common languages and a son-of-font-lock.el could
      97             : ;; use them rather then relying so heavily on the keyword (regexp) pass.
      98             : 
      99             : ;;; How Font Lock mode supports modes or is supported by modes:
     100             : 
     101             : ;; Modes that support Font Lock mode do so by defining one or more variables
     102             : ;; whose values specify the fontification.  Font Lock mode knows of these
     103             : ;; variable names from the buffer local variable `font-lock-defaults'.
     104             : ;; (Font Lock mode is set up via (a) where a mode's patterns are
     105             : ;; distributed with the mode's package library, and (b) where a mode's
     106             : ;; patterns are distributed with font-lock.el itself.  An example of (a)
     107             : ;; is Pascal mode, an example of (b) is Lisp mode.  Normally, the mechanism is
     108             : ;; (a); (b) is used where it is not clear which package library should contain
     109             : ;; the pattern definitions.)  Font Lock mode chooses which variable to use for
     110             : ;; fontification based on `font-lock-maximum-decoration'.
     111             : ;;
     112             : ;; Font Lock mode fontification behavior can be modified in a number of ways.
     113             : ;; See the below comments and the comments distributed throughout this file.
     114             : 
     115             : ;;; Constructing patterns:
     116             : 
     117             : ;; See the documentation for the variable `font-lock-keywords'.
     118             : ;;
     119             : ;; Efficient regexps for use as MATCHERs for `font-lock-keywords' and
     120             : ;; `font-lock-syntactic-keywords' can be generated via the function
     121             : ;; `regexp-opt'.
     122             : 
     123             : ;;; Adding patterns for modes that already support Font Lock:
     124             : 
     125             : ;; Though Font Lock highlighting patterns already exist for many modes, it's
     126             : ;; likely there's something that you want fontified that currently isn't, even
     127             : ;; at the maximum fontification level.  You can add highlighting patterns via
     128             : ;; `font-lock-add-keywords'.  For example, say in some C
     129             : ;; header file you #define the token `and' to expand to `&&', etc., to make
     130             : ;; your C code almost readable.  In your ~/.emacs there could be:
     131             : ;;
     132             : ;;  (font-lock-add-keywords 'c-mode '("\\<\\(and\\|or\\|not\\)\\>"))
     133             : ;;
     134             : ;; Some modes provide specific ways to modify patterns based on the values of
     135             : ;; other variables.  For example, additional C types can be specified via the
     136             : ;; variable `c-font-lock-extra-types'.
     137             : 
     138             : ;;; Adding patterns for modes that do not support Font Lock:
     139             : 
     140             : ;; Not all modes support Font Lock mode.  If you (as a user of the mode) add
     141             : ;; patterns for a new mode, you must define in your ~/.emacs a variable or
     142             : ;; variables that specify regexp fontification.  Then, you should indicate to
     143             : ;; Font Lock mode, via the mode hook setting `font-lock-defaults', exactly what
     144             : ;; support is required.  For example, say Foo mode should have the following
     145             : ;; regexps fontified case-sensitively, and comments and strings should not be
     146             : ;; fontified automagically.  In your ~/.emacs there could be:
     147             : ;;
     148             : ;;  (defvar foo-font-lock-keywords
     149             : ;;    '(("\\<\\(one\\|two\\|three\\)\\>" . 'font-lock-keyword-face)
     150             : ;;      ("\\<\\(four\\|five\\|six\\)\\>" . 'font-lock-type-face))
     151             : ;;    "Default expressions to highlight in Foo mode.")
     152             : ;;
     153             : ;;  (add-hook 'foo-mode-hook
     154             : ;;   (lambda ()
     155             : ;;     (set (make-local-variable 'font-lock-defaults)
     156             : ;;          '(foo-font-lock-keywords t))))
     157             : 
     158             : ;;; Adding Font Lock support for modes:
     159             : 
     160             : ;; Of course, it would be better that the mode already supports Font Lock mode.
     161             : ;; The package author would do something similar to above.  The mode must
     162             : ;; define at the top-level a variable or variables that specify regexp
     163             : ;; fontification.  Then, the mode command should indicate to Font Lock mode,
     164             : ;; via `font-lock-defaults', exactly what support is required.  For example,
     165             : ;; say Bar mode should have the following regexps fontified case-insensitively,
     166             : ;; and comments and strings should be fontified automagically.  In bar.el there
     167             : ;; could be:
     168             : ;;
     169             : ;;  (defvar bar-font-lock-keywords
     170             : ;;    '(("\\<\\(uno\\|due\\|tre\\)\\>" . 'font-lock-keyword-face)
     171             : ;;      ("\\<\\(quattro\\|cinque\\|sei\\)\\>" . 'font-lock-type-face))
     172             : ;;    "Default expressions to highlight in Bar mode.")
     173             : ;;
     174             : ;; and within `bar-mode' there could be:
     175             : ;;
     176             : ;;  (set (make-local-variable 'font-lock-defaults)
     177             : ;;       '(bar-font-lock-keywords nil t))
     178             : 
     179             : ;; What is fontification for?  You might say, "It's to make my code look nice."
     180             : ;; I think it should be for adding information in the form of cues.  These cues
     181             : ;; should provide you with enough information to both (a) distinguish between
     182             : ;; different items, and (b) identify the item meanings, without having to read
     183             : ;; the items and think about it.  Therefore, fontification allows you to think
     184             : ;; less about, say, the structure of code, and more about, say, why the code
     185             : ;; doesn't work.  Or maybe it allows you to think less and drift off to sleep.
     186             : ;;
     187             : ;; So, here are my opinions/advice/guidelines:
     188             : ;;
     189             : ;; - Highlight conceptual objects, such as function and variable names, and
     190             : ;;   different objects types differently, i.e., (a) and (b) above, highlight
     191             : ;;   function names differently to variable names.
     192             : ;; - Keep the faces distinct from each other as far as possible.
     193             : ;;   i.e., (a) above.
     194             : ;; - Use the same face for the same conceptual object, across all modes.
     195             : ;;   i.e., (b) above, all modes that have items that can be thought of as, say,
     196             : ;;   keywords, should be highlighted with the same face, etc.
     197             : ;; - Make the face attributes fit the concept as far as possible.
     198             : ;;   i.e., function names might be a bold color such as blue, comments might
     199             : ;;   be a bright color such as red, character strings might be brown, because,
     200             : ;;   err, strings are brown (that was not the reason, please believe me).
     201             : ;; - Don't use a non-nil OVERRIDE unless you have a good reason.
     202             : ;;   Only use OVERRIDE for special things that are easy to define, such as the
     203             : ;;   way `...' quotes are treated in strings and comments in Emacs Lisp mode.
     204             : ;;   Don't use it to, say, highlight keywords in commented out code or strings.
     205             : ;; - Err, that's it.
     206             : 
     207             : ;;; Code:
     208             : 
     209             : (require 'syntax)
     210             : (eval-when-compile (require 'cl-lib))
     211             : 
     212             : ;; Define core `font-lock' group.
     213             : (defgroup font-lock '((jit-lock custom-group))
     214             :   "Font Lock mode text highlighting package."
     215             :   :link '(custom-manual :tag "Emacs Manual" "(emacs)Font Lock")
     216             :   :link '(custom-manual :tag "Elisp Manual" "(elisp)Font Lock Mode")
     217             :   :group 'faces)
     218             : 
     219             : (defgroup font-lock-faces nil
     220             :   "Faces for highlighting text."
     221             :   :prefix "font-lock-"
     222             :   :group 'font-lock)
     223             : 
     224             : (defgroup font-lock-extra-types nil
     225             :   "Extra mode-specific type names for highlighting declarations."
     226             :   :group 'font-lock)
     227             : 
     228             : ;; User variables.
     229             : 
     230             : (defcustom font-lock-maximum-size 256000
     231             :   "Maximum buffer size for unsupported buffer fontification.
     232             : When `font-lock-support-mode' is nil, only buffers smaller than
     233             : this are fontified.  This variable has no effect if a Font Lock
     234             : support mode (usually `jit-lock-mode') is enabled.
     235             : 
     236             : If nil, means size is irrelevant.
     237             : If a list, each element should be a cons pair of the form (MAJOR-MODE . SIZE),
     238             : where MAJOR-MODE is a symbol or t (meaning the default).  For example:
     239             :  ((c-mode . 256000) (c++-mode . 256000) (rmail-mode . 1048576))
     240             : means that the maximum size is 250K for buffers in C or C++ modes, one megabyte
     241             : for buffers in Rmail mode, and size is irrelevant otherwise."
     242             :   :type '(choice (const :tag "none" nil)
     243             :                  (integer :tag "size")
     244             :                  (repeat :menu-tag "mode specific" :tag "mode specific"
     245             :                          :value ((t . nil))
     246             :                          (cons :tag "Instance"
     247             :                                (radio :tag "Mode"
     248             :                                       (const :tag "all" t)
     249             :                                       (symbol :tag "name"))
     250             :                                (radio :tag "Size"
     251             :                                       (const :tag "none" nil)
     252             :                                       (integer :tag "size")))))
     253             :   :group 'font-lock)
     254             : (make-obsolete-variable 'font-lock-maximum-size nil "24.1")
     255             : 
     256             : (defcustom font-lock-maximum-decoration t
     257             :   "Maximum decoration level for fontification.
     258             : If nil, use the default decoration (typically the minimum available).
     259             : If t, use the maximum decoration available.
     260             : If a number, use that level of decoration (or if not available the maximum).
     261             : The higher the number, the more decoration is done.
     262             : If a list, each element should be a cons pair of the form (MAJOR-MODE . LEVEL),
     263             : where MAJOR-MODE is a symbol or t (meaning the default).  For example:
     264             :  ((c-mode . t) (c++-mode . 2) (t . 1))
     265             : means use the maximum decoration available for buffers in C mode, level 2
     266             : decoration for buffers in C++ mode, and level 1 decoration otherwise."
     267             :   :type '(choice (const :tag "default" nil)
     268             :                  (const :tag "maximum" t)
     269             :                  (integer :tag "level" 1)
     270             :                  (repeat :menu-tag "mode specific" :tag "mode specific"
     271             :                          :value ((t . t))
     272             :                          (cons :tag "Instance"
     273             :                                (radio :tag "Mode"
     274             :                                       (const :tag "all" t)
     275             :                                       (symbol :tag "name"))
     276             :                                (radio :tag "Decoration"
     277             :                                       (const :tag "default" nil)
     278             :                                       (const :tag "maximum" t)
     279             :                                       (integer :tag "level" 1)))))
     280             :   :group 'font-lock)
     281             : 
     282             : (defcustom font-lock-verbose nil
     283             :   "If non-nil, means show status messages for buffer fontification.
     284             : If a number, only buffers greater than this size have fontification messages."
     285             :   :type '(choice (const :tag "never" nil)
     286             :                  (other :tag "always" t)
     287             :                  (integer :tag "size"))
     288             :   :group 'font-lock
     289             :   :version "24.1")
     290             : 
     291             : 
     292             : ;; Originally these variable values were face names such as `bold' etc.
     293             : ;; Now we create our own faces, but we keep these variables for compatibility
     294             : ;; and they give users another mechanism for changing face appearance.
     295             : ;; We now allow a FACENAME in `font-lock-keywords' to be any expression that
     296             : ;; returns a face.  So the easiest thing is to continue using these variables,
     297             : ;; rather than sometimes evalling FACENAME and sometimes not.  sm.
     298             : 
     299             : ;; Note that in new code, in the vast majority of cases there is no
     300             : ;; need to create variables that specify face names.  Simply using
     301             : ;; faces directly is enough.  Font-lock is not a template to be
     302             : ;; followed in this area.
     303             : (defvar font-lock-comment-face          'font-lock-comment-face
     304             :   "Face name to use for comments.")
     305             : 
     306             : (defvar font-lock-comment-delimiter-face 'font-lock-comment-delimiter-face
     307             :   "Face name to use for comment delimiters.")
     308             : 
     309             : (defvar font-lock-string-face           'font-lock-string-face
     310             :   "Face name to use for strings.")
     311             : 
     312             : (defvar font-lock-doc-face              'font-lock-doc-face
     313             :   "Face name to use for documentation.")
     314             : 
     315             : (defvar font-lock-keyword-face          'font-lock-keyword-face
     316             :   "Face name to use for keywords.")
     317             : 
     318             : (defvar font-lock-builtin-face          'font-lock-builtin-face
     319             :   "Face name to use for builtins.")
     320             : 
     321             : (defvar font-lock-function-name-face    'font-lock-function-name-face
     322             :   "Face name to use for function names.")
     323             : 
     324             : (defvar font-lock-variable-name-face    'font-lock-variable-name-face
     325             :   "Face name to use for variable names.")
     326             : 
     327             : (defvar font-lock-type-face             'font-lock-type-face
     328             :   "Face name to use for type and class names.")
     329             : 
     330             : (defvar font-lock-constant-face         'font-lock-constant-face
     331             :   "Face name to use for constant and label names.")
     332             : 
     333             : (defvar font-lock-warning-face          'font-lock-warning-face
     334             :   "Face name to use for things that should stand out.")
     335             : 
     336             : (defvar font-lock-negation-char-face    'font-lock-negation-char-face
     337             :   "Face name to use for easy to overlook negation.
     338             : This can be an \"!\" or the \"n\" in \"ifndef\".")
     339             : 
     340             : (defvar font-lock-preprocessor-face     'font-lock-preprocessor-face
     341             :   "Face name to use for preprocessor directives.")
     342             : 
     343             : (define-obsolete-variable-alias
     344             :   'font-lock-reference-face 'font-lock-constant-face "20.3")
     345             : 
     346             : ;; Fontification variables:
     347             : 
     348             : (defvar font-lock-keywords nil
     349             :   "A list of the keywords to highlight.
     350             : There are two kinds of values: user-level, and compiled.
     351             : 
     352             : A user-level keywords list is what a major mode or the user would
     353             : set up.  Normally the list would come from `font-lock-defaults'.
     354             : through selection of a fontification level and evaluation of any
     355             : contained expressions.  You can also alter it by calling
     356             : `font-lock-add-keywords' or `font-lock-remove-keywords' with MODE = nil.
     357             : 
     358             : Each element in a user-level keywords list should have one of these forms:
     359             : 
     360             :  MATCHER
     361             :  (MATCHER . SUBEXP)
     362             :  (MATCHER . FACENAME)
     363             :  (MATCHER . HIGHLIGHT)
     364             :  (MATCHER HIGHLIGHT ...)
     365             :  (eval . FORM)
     366             : 
     367             : where MATCHER can be either the regexp to search for, or the
     368             : function name to call to make the search (called with one
     369             : argument, the limit of the search; it should return non-nil, move
     370             : point, and set `match-data' appropriately if it succeeds; like
     371             : `re-search-forward' would).  MATCHER regexps can be generated via
     372             : the function `regexp-opt'.
     373             : 
     374             : FORM is an expression, whose value should be a keyword element,
     375             : evaluated when the keyword is (first) used in a buffer.  This
     376             : feature can be used to provide a keyword that can only be
     377             : generated when Font Lock mode is actually turned on.
     378             : 
     379             : HIGHLIGHT should be either MATCH-HIGHLIGHT or MATCH-ANCHORED.
     380             : 
     381             : For highlighting single items, for example each instance of the
     382             : word \"foo\", typically only MATCH-HIGHLIGHT is required.
     383             : However, if an item or (typically) items are to be highlighted
     384             : following the instance of another item (the anchor), for example
     385             : each instance of the word \"bar\" following the word \"anchor\"
     386             : then MATCH-ANCHORED may be required.
     387             : 
     388             : MATCH-HIGHLIGHT should be of the form:
     389             : 
     390             :  (SUBEXP FACENAME [OVERRIDE [LAXMATCH]])
     391             : 
     392             : SUBEXP is the number of the subexpression of MATCHER to be
     393             : highlighted.
     394             : 
     395             : FACENAME is an expression whose value is the face name to use.
     396             : Instead of a face, FACENAME can evaluate to a property list of
     397             : the form (face FACE PROP1 VAL1 PROP2 VAL2 ...)  in which case all
     398             : the listed text-properties will be set rather than just FACE.  In
     399             : such a case, you will most likely want to put those properties in
     400             : `font-lock-extra-managed-props' or to override
     401             : `font-lock-unfontify-region-function'.
     402             : 
     403             : OVERRIDE and LAXMATCH are flags.  If OVERRIDE is t, existing
     404             : fontification can be overwritten.  If `keep', only parts not
     405             : already fontified are highlighted.  If `prepend' or `append',
     406             : existing fontification is merged with the new, in which the new
     407             : or existing fontification, respectively, takes precedence.  If
     408             : LAXMATCH is non-nil, that means don't signal an error if there is
     409             : no match for SUBEXP in MATCHER.
     410             : 
     411             : For example, an element of the form highlights (if not already
     412             : highlighted):
     413             : 
     414             :  \"\\\\\\=<foo\\\\\\=>\"
     415             :   Discrete occurrences of \"foo\" in the value of the variable
     416             :   `font-lock-keyword-face'.
     417             : 
     418             :  (\"fu\\\\(bar\\\\)\" . 1)
     419             :   Substring \"bar\" within all occurrences of \"fubar\" in the
     420             :   value of `font-lock-keyword-face'.
     421             : 
     422             :  (\"fubar\" . fubar-face)
     423             :   Occurrences of \"fubar\" in the value of `fubar-face'.
     424             : 
     425             :  (\"foo\\\\|bar\" 0 foo-bar-face t)
     426             :   Occurrences of either \"foo\" or \"bar\" in the value of
     427             :   `foo-bar-face', even if already highlighted.
     428             : 
     429             :  (fubar-match 1 fubar-face)
     430             :   The first subexpression within all occurrences of whatever the
     431             :   function `fubar-match' finds and matches in the value of
     432             :   `fubar-face'.
     433             : 
     434             : MATCH-ANCHORED should be of the form:
     435             : 
     436             :  (MATCHER PRE-MATCH-FORM POST-MATCH-FORM MATCH-HIGHLIGHT ...)
     437             : 
     438             : where MATCHER is a regexp to search for or the function name to
     439             : call to make the search, as for MATCH-HIGHLIGHT above, but with
     440             : one exception; see below.  PRE-MATCH-FORM and POST-MATCH-FORM are
     441             : evaluated before the first, and after the last, instance
     442             : MATCH-ANCHORED's MATCHER is used.  Therefore they can be used to
     443             : initialize before, and cleanup after, MATCHER is used.
     444             : Typically, PRE-MATCH-FORM is used to move to some position
     445             : relative to the original MATCHER, before starting with
     446             : MATCH-ANCHORED's MATCHER.  POST-MATCH-FORM might be used to move
     447             : back, before resuming with MATCH-ANCHORED's parent's MATCHER.
     448             : 
     449             : For example, an element of the form highlights (if not already
     450             : highlighted):
     451             : 
     452             :  (\"\\\\\\=<anchor\\\\\\=>\" (0 anchor-face)
     453             :   (\"\\\\\\=<item\\\\\\=>\" nil nil (0 item-face)))
     454             : 
     455             :   Discrete occurrences of \"anchor\" in the value of
     456             :   `anchor-face', and subsequent discrete occurrences of
     457             :   \"item\" (on the same line) in the value of `item-face'.
     458             :   (Here PRE-MATCH-FORM and POST-MATCH-FORM are nil.  Therefore
     459             :   \"item\" is initially searched for starting from the end of the
     460             :   match of \"anchor\", and searching for subsequent instances of
     461             :   \"anchor\" resumes from where searching for \"item\" concluded.)
     462             : 
     463             : The above-mentioned exception is as follows.  The limit of the
     464             : MATCHER search defaults to the end of the line after
     465             : PRE-MATCH-FORM is evaluated.  However, if PRE-MATCH-FORM returns
     466             : a position greater than the position after PRE-MATCH-FORM is
     467             : evaluated, that position is used as the limit of the search.  It
     468             : is generally a bad idea to return a position greater than the end
     469             : of the line, i.e., cause the MATCHER search to span lines.
     470             : 
     471             : These regular expressions can match text which spans lines,
     472             : although it is better to avoid it if possible since updating them
     473             : while editing text is slower, and it is not guaranteed to be
     474             : always correct when using support modes like jit-lock or
     475             : lazy-lock.
     476             : 
     477             : This variable is set by major modes via the variable
     478             : `font-lock-defaults'.  Be careful when composing regexps for this
     479             : list; a poorly written pattern can dramatically slow things down!
     480             : 
     481             : A compiled keywords list starts with t.  It is produced
     482             : internally by `font-lock-compile-keywords' from a user-level
     483             : keywords list.  Its second element is the user-level keywords
     484             : list that was compiled.  The remaining elements have the same
     485             : form as user-level keywords, but normally their values have been
     486             : optimized.")
     487             : 
     488             : (defvar font-lock-keywords-alist nil
     489             :   "Alist of additional `font-lock-keywords' elements for major modes.
     490             : 
     491             : Each element has the form (MODE KEYWORDS . HOW).
     492             : Function `font-lock-set-defaults' adds the elements in the list KEYWORDS to
     493             : `font-lock-keywords' when Font Lock is turned on in major mode MODE.
     494             : 
     495             : If HOW is nil, KEYWORDS are added at the beginning of
     496             : `font-lock-keywords'.  If it is `set', they are used to replace the
     497             : value of `font-lock-keywords'.  If HOW is any other non-nil value,
     498             : they are added at the end.
     499             : 
     500             : This is normally set via `font-lock-add-keywords' and
     501             : `font-lock-remove-keywords'.")
     502             : (put 'font-lock-keywords-alist 'risky-local-variable t)
     503             : 
     504             : (defvar font-lock-removed-keywords-alist nil
     505             :   "Alist of `font-lock-keywords' elements to be removed for major modes.
     506             : 
     507             : Each element has the form (MODE . KEYWORDS).  Function `font-lock-set-defaults'
     508             : removes the elements in the list KEYWORDS from `font-lock-keywords'
     509             : when Font Lock is turned on in major mode MODE.
     510             : 
     511             : This is normally set via `font-lock-add-keywords' and
     512             : `font-lock-remove-keywords'.")
     513             : 
     514             : (defvar font-lock-keywords-only nil
     515             :   "Non-nil means Font Lock should not fontify comments or strings.
     516             : This is normally set via `font-lock-defaults'.")
     517             : 
     518             : (defvar font-lock-keywords-case-fold-search nil
     519             :   "Non-nil means the patterns in `font-lock-keywords' are case-insensitive.
     520             : This is set via the function `font-lock-set-defaults', based on
     521             : the CASE-FOLD argument of `font-lock-defaults'.")
     522             : (make-variable-buffer-local 'font-lock-keywords-case-fold-search)
     523             : 
     524             : (defvar font-lock-syntactically-fontified 0
     525             :   "Point up to which `font-lock-syntactic-keywords' has been applied.
     526             : If nil, this is ignored, in which case the syntactic fontification may
     527             : sometimes be slightly incorrect.")
     528             : (make-variable-buffer-local 'font-lock-syntactically-fontified)
     529             : 
     530             : (defvar font-lock-syntactic-face-function
     531             :   (lambda (state)
     532             :     (if (nth 3 state) font-lock-string-face font-lock-comment-face))
     533             :   "Function to determine which face to use when fontifying syntactically.
     534             : The function is called with a single parameter (the state as returned by
     535             : `parse-partial-sexp' at the beginning of the region to highlight) and
     536             : should return a face.  This is normally set via `font-lock-defaults'.")
     537             : 
     538             : (defvar font-lock-syntactic-keywords nil
     539             :   "A list of the syntactic keywords to put syntax properties on.
     540             : The value can be the list itself, or the name of a function or variable
     541             : whose value is the list.
     542             : 
     543             : See `font-lock-keywords' for a description of the form of this list;
     544             : only the differences are stated here.  MATCH-HIGHLIGHT should be of the form:
     545             : 
     546             :  (SUBEXP SYNTAX OVERRIDE LAXMATCH)
     547             : 
     548             : where SYNTAX can be a string (as taken by `modify-syntax-entry'), a syntax
     549             : table, a cons cell (as returned by `string-to-syntax') or an expression whose
     550             : value is such a form.  OVERRIDE cannot be `prepend' or `append'.
     551             : 
     552             : Here are two examples of elements of `font-lock-syntactic-keywords'
     553             : and what they do:
     554             : 
     555             :  (\"\\\\$\\\\(#\\\\)\" 1 \".\")
     556             : 
     557             :  gives a hash character punctuation syntax (\".\") when following a
     558             :  dollar-sign character.  Hash characters in other contexts will still
     559             :  follow whatever the syntax table says about the hash character.
     560             : 
     561             :  (\"\\\\(\\='\\\\).\\\\(\\='\\\\)\"
     562             :   (1 \"\\\"\")
     563             :   (2 \"\\\"\"))
     564             : 
     565             :  gives a pair of apostrophes, which surround a single character, a
     566             :  SYNTAX of \"\\\"\" (meaning string quote syntax).  Apostrophes in other
     567             : 
     568             :  contexts will not be affected.
     569             : 
     570             : This is normally set via `font-lock-defaults'.")
     571             : (make-obsolete-variable 'font-lock-syntactic-keywords
     572             :                         'syntax-propertize-function "24.1")
     573             : 
     574             : (defvar font-lock-syntax-table nil
     575             :   "Non-nil means use this syntax table for fontifying.
     576             : If this is nil, the major mode's syntax table is used.
     577             : This is normally set via `font-lock-defaults'.")
     578             : 
     579             : (defvar font-lock-mark-block-function nil
     580             :   "Non-nil means use this function to mark a block of text.
     581             : When called with no args it should leave point at the beginning of any
     582             : enclosing textual block and mark at the end.
     583             : This is normally set via `font-lock-defaults'.")
     584             : 
     585             : (defvar font-lock-fontify-buffer-function #'font-lock-default-fontify-buffer
     586             :   "Function to use for fontifying the buffer.
     587             : This is normally set via `font-lock-defaults'.")
     588             : 
     589             : (defvar font-lock-unfontify-buffer-function #'font-lock-default-unfontify-buffer
     590             :   "Function to use for unfontifying the buffer.
     591             : This is used when turning off Font Lock mode.
     592             : This is normally set via `font-lock-defaults'.")
     593             : 
     594             : (defvar font-lock-fontify-region-function #'font-lock-default-fontify-region
     595             :   "Function to use for fontifying a region.
     596             : It should take two args, the beginning and end of the region, and an optional
     597             : third arg VERBOSE.  If VERBOSE is non-nil, the function should print status
     598             : messages.  This is normally set via `font-lock-defaults'.
     599             : If it fontifies a larger region, it should ideally return a list of the form
     600             : \(jit-lock-bounds BEG . END) indicating the bounds of the region actually
     601             : fontified.")
     602             : 
     603             : (defvar font-lock-unfontify-region-function #'font-lock-default-unfontify-region
     604             :   "Function to use for unfontifying a region.
     605             : It should take two args, the beginning and end of the region.
     606             : This is normally set via `font-lock-defaults'.")
     607             : 
     608             : (defvar font-lock-inhibit-thing-lock nil
     609             :   "List of Font Lock mode related modes that should not be turned on.
     610             : Currently, valid mode names are `fast-lock-mode', `jit-lock-mode' and
     611             : `lazy-lock-mode'.  This is normally set via `font-lock-defaults'.")
     612             : (make-obsolete-variable 'font-lock-inhibit-thing-lock nil "25.1")
     613             : 
     614             : (defvar-local font-lock-multiline nil
     615             :   "Whether font-lock should cater to multiline keywords.
     616             : If nil, don't try to handle multiline patterns.
     617             : If t, always handle multiline patterns.
     618             : If `undecided', don't try to handle multiline patterns until you see one.
     619             : Major/minor modes can set this variable if they know which option applies.")
     620             : 
     621             : (defvar-local font-lock-fontified nil)  ; Whether we have fontified the buffer.
     622             : 
     623             : ;; Font Lock mode.
     624             : 
     625             : (eval-when-compile
     626             :   ;;
     627             :   ;; Borrowed from lazy-lock.el.
     628             :   ;; We use this to preserve or protect things when modifying text properties.
     629             :   (defmacro save-buffer-state (&rest body)
     630             :     "Bind variables according to VARLIST and eval BODY restoring buffer state."
     631             :     (declare (indent 0) (debug t))
     632             :     `(let ((inhibit-point-motion-hooks t))
     633             :        (with-silent-modifications
     634             :          ,@body)))
     635             :   ;;
     636             :   ;; Shut up the byte compiler.
     637             :   (defvar font-lock-face-attributes))   ; Obsolete but respected if set.
     638             : 
     639             : (defvar-local font-lock-set-defaults nil) ; Whether we have set up defaults.
     640             : 
     641             : (defun font-lock-specified-p (mode)
     642             :   "Return non-nil if the current buffer is ready for fontification.
     643             : The MODE argument, if non-nil, means Font Lock mode is about to
     644             : be enabled."
     645           0 :   (or font-lock-defaults
     646           0 :       (and (boundp 'font-lock-keywords)
     647           0 :            font-lock-keywords)
     648           0 :       (and mode
     649           0 :            font-lock-set-defaults
     650           0 :            font-lock-major-mode
     651           0 :            (not (eq font-lock-major-mode major-mode)))))
     652             : 
     653             : (defun font-lock-initial-fontify ()
     654             :   ;; The first fontification after turning the mode on.  This must
     655             :   ;;  only be called after the mode hooks have been run.
     656           0 :   (when (and font-lock-mode
     657           0 :              (font-lock-specified-p t))
     658           0 :     (let ((max-size (font-lock-value-in-major-mode font-lock-maximum-size)))
     659           0 :       (cond (font-lock-fontified
     660             :              nil)
     661           0 :             ((or (null max-size) (> max-size (buffer-size)))
     662           0 :              (font-lock-fontify-buffer))
     663           0 :             (font-lock-verbose
     664           0 :              (message "Fontifying %s...buffer size greater than font-lock-maximum-size"
     665           0 :                       (buffer-name)))))))
     666             : 
     667             : (defun font-lock-mode-internal (arg)
     668             :   ;; Turn on Font Lock mode.
     669           0 :   (when arg
     670           0 :     (add-hook 'after-change-functions #'font-lock-after-change-function t t)
     671           0 :     (font-lock-set-defaults)
     672           0 :     (font-lock-turn-on-thing-lock))
     673             :   ;; Turn off Font Lock mode.
     674           0 :   (unless font-lock-mode
     675           0 :     (remove-hook 'after-change-functions #'font-lock-after-change-function t)
     676           0 :     (font-lock-unfontify-buffer)
     677           0 :     (font-lock-turn-off-thing-lock)))
     678             : 
     679             : (defun font-lock-add-keywords (mode keywords &optional how)
     680             :   "Add highlighting KEYWORDS for MODE.
     681             : 
     682             : MODE should be a symbol, the major mode command name, such as `c-mode'
     683             : or nil.  If nil, highlighting keywords are added for the current buffer.
     684             : KEYWORDS should be a list; see the variable `font-lock-keywords'.
     685             : By default they are added at the beginning of the current highlighting list.
     686             : If optional argument HOW is `set', they are used to replace the current
     687             : highlighting list.  If HOW is any other non-nil value, they are added at the
     688             : end of the current highlighting list.
     689             : 
     690             : For example:
     691             : 
     692             :  (font-lock-add-keywords \\='c-mode
     693             :   \\='((\"\\\\\\=<\\\\(FIXME\\\\):\" 1 \\='font-lock-warning-face prepend)
     694             :     (\"\\\\\\=<\\\\(and\\\\|or\\\\|not\\\\)\\\\\\=>\" . \\='font-lock-keyword-face)))
     695             : 
     696             : adds two fontification patterns for C mode, to fontify `FIXME:' words, even in
     697             : comments, and to fontify `and', `or' and `not' words as keywords.
     698             : 
     699             : The above procedure will only add the keywords for C mode, not
     700             : for modes derived from C mode.  To add them for derived modes too,
     701             : pass nil for MODE and add the call to c-mode-hook.
     702             : 
     703             : For example:
     704             : 
     705             :  (add-hook \\='c-mode-hook
     706             :   (lambda ()
     707             :    (font-lock-add-keywords nil
     708             :     \\='((\"\\\\\\=<\\\\(FIXME\\\\):\" 1 \\='font-lock-warning-face prepend)
     709             :       (\"\\\\\\=<\\\\(and\\\\|or\\\\|not\\\\)\\\\\\=>\" .
     710             :        \\='font-lock-keyword-face)))))
     711             : 
     712             : The above procedure may fail to add keywords to derived modes if
     713             : some involved major mode does not follow the standard conventions.
     714             : File a bug report if this happens, so the major mode can be corrected.
     715             : 
     716             : Note that some modes have specialized support for additional patterns, e.g.,
     717             : see the variables `c-font-lock-extra-types', `c++-font-lock-extra-types',
     718             : `objc-font-lock-extra-types' and `java-font-lock-extra-types'."
     719         236 :   (cond (mode
     720             :          ;; If MODE is non-nil, add the KEYWORDS and HOW spec to
     721             :          ;; `font-lock-keywords-alist' so `font-lock-set-defaults' uses them.
     722          12 :          (let ((spec (cons keywords how)) cell)
     723          12 :            (if (setq cell (assq mode font-lock-keywords-alist))
     724          11 :                (if (eq how 'set)
     725           0 :                    (setcdr cell (list spec))
     726          11 :                  (setcdr cell (append (cdr cell) (list spec))))
     727          12 :              (push (list mode spec) font-lock-keywords-alist)))
     728             :          ;; Make sure that `font-lock-removed-keywords-alist' does not
     729             :          ;; contain the new keywords.
     730          12 :          (font-lock-update-removed-keyword-alist mode keywords how))
     731             :         (t
     732         224 :          (when (and font-lock-mode
     733         224 :                     (not (or font-lock-keywords font-lock-defaults)))
     734             :            ;; The major mode has not set any keywords, so when we enabled
     735             :            ;; font-lock-mode it only enabled the font-core.el part, not the
     736             :            ;; font-lock-mode-internal.  Try again.
     737           0 :            (font-lock-mode -1)
     738           0 :            (set (make-local-variable 'font-lock-defaults) '(nil t))
     739         224 :            (font-lock-mode 1))
     740             :          ;; Otherwise set or add the keywords now.
     741             :          ;; This is a no-op if it has been done already in this buffer
     742             :          ;; for the correct major mode.
     743         224 :          (font-lock-set-defaults)
     744         224 :          (let ((was-compiled (eq (car font-lock-keywords) t)))
     745             :            ;; Bring back the user-level (uncompiled) keywords.
     746         224 :            (if was-compiled
     747         224 :                (setq font-lock-keywords (cadr font-lock-keywords)))
     748             :            ;; Now modify or replace them.
     749         224 :            (if (eq how 'set)
     750           0 :                (setq font-lock-keywords keywords)
     751         224 :              (font-lock-remove-keywords nil keywords) ;to avoid duplicates
     752         224 :              (let ((old (if (eq (car-safe font-lock-keywords) t)
     753           0 :                             (cdr font-lock-keywords)
     754         224 :                           font-lock-keywords)))
     755         224 :                (setq font-lock-keywords (if how
     756           0 :                                             (append old keywords)
     757         224 :                                           (append keywords old)))))
     758             :            ;; If the keywords were compiled before, compile them again.
     759         224 :            (if was-compiled
     760          36 :                (setq font-lock-keywords
     761         236 :                      (font-lock-compile-keywords font-lock-keywords)))))))
     762             : 
     763             : (defun font-lock-update-removed-keyword-alist (mode keywords how)
     764             :   "Update `font-lock-removed-keywords-alist' when adding new KEYWORDS to MODE."
     765             :   ;; When font-lock is enabled first all keywords in the list
     766             :   ;; `font-lock-keywords-alist' are added, then all keywords in the
     767             :   ;; list `font-lock-removed-keywords-alist' are removed.  If a
     768             :   ;; keyword was once added, removed, and then added again it must be
     769             :   ;; removed from the removed-keywords list.  Otherwise the second add
     770             :   ;; will not take effect.
     771          12 :   (let ((cell (assq mode font-lock-removed-keywords-alist)))
     772          12 :     (if cell
     773           0 :         (if (eq how 'set)
     774             :             ;; A new set of keywords is defined.  Forget all about
     775             :             ;; our old keywords that should be removed.
     776           0 :             (setq font-lock-removed-keywords-alist
     777           0 :                   (delq cell font-lock-removed-keywords-alist))
     778             :           ;; Delete all previously removed keywords.
     779           0 :           (dolist (kword keywords)
     780           0 :             (setcdr cell (delete kword (cdr cell))))
     781             :           ;; Delete the mode cell if empty.
     782           0 :           (if (null (cdr cell))
     783           0 :               (setq font-lock-removed-keywords-alist
     784          12 :                     (delq cell font-lock-removed-keywords-alist)))))))
     785             : 
     786             : ;; Written by Anders Lindgren
     787             : ;;
     788             : ;; Case study:
     789             : ;; (I)  The keywords are removed from a major mode.
     790             : ;;      In this case the keyword could be local (i.e. added earlier by
     791             : ;;      `font-lock-add-keywords'), global, or both.
     792             : ;;
     793             : ;;      (a) In the local case we remove the keywords from the variable
     794             : ;;          `font-lock-keywords-alist'.
     795             : ;;
     796             : ;;      (b) The actual global keywords are not known at this time.
     797             : ;;          All keywords are added to `font-lock-removed-keywords-alist',
     798             : ;;          when font-lock is enabled those keywords are removed.
     799             : ;;
     800             : ;;      Note that added keywords are taken out of the list of removed
     801             : ;;      keywords.  This ensure correct operation when the same keyword
     802             : ;;      is added and removed several times.
     803             : ;;
     804             : ;; (II) The keywords are removed from the current buffer.
     805             : (defun font-lock-remove-keywords (mode keywords)
     806             :   "Remove highlighting KEYWORDS for MODE.
     807             : 
     808             : MODE should be a symbol, the major mode command name, such as
     809             : `c-mode' or nil.  If nil, highlighting keywords are removed for
     810             : the current buffer.
     811             : 
     812             : For a description of KEYWORDS, see `font-lock-add-keywords'.
     813             : 
     814             : To make the removal apply to modes derived from MODE as well,
     815             : pass nil for MODE and add the call to MODE-hook.  This may fail
     816             : for some derived modes if some involved major mode does not
     817             : follow the standard conventions.  File a bug report if this
     818             : happens, so the major mode can be corrected."
     819         224 :   (cond (mode
     820             :          ;; Remove one keyword at the time.
     821           0 :          (dolist (keyword keywords)
     822           0 :            (let ((top-cell (assq mode font-lock-keywords-alist)))
     823             :              ;; If MODE is non-nil, remove the KEYWORD from
     824             :              ;; `font-lock-keywords-alist'.
     825           0 :              (when top-cell
     826           0 :                (dolist (keyword-list-how-pair (cdr top-cell))
     827             :                  ;; `keywords-list-how-pair' is a cons with a list of
     828             :                  ;; keywords in the car top-cell and the original how
     829             :                  ;; argument in the cdr top-cell.
     830           0 :                  (setcar keyword-list-how-pair
     831           0 :                          (delete keyword (car keyword-list-how-pair))))
     832             :                ;; Remove keyword list/how pair when the keyword list
     833             :                ;; is empty and how doesn't specify `set'.  (If it
     834             :                ;; should be deleted then previously deleted keywords
     835             :                ;; would appear again.)
     836           0 :                (let ((cell top-cell))
     837           0 :                  (while (cdr cell)
     838           0 :                    (if (and (null (car (car (cdr cell))))
     839           0 :                             (not (eq (cdr (car (cdr cell))) 'set)))
     840           0 :                        (setcdr cell (cdr (cdr cell)))
     841           0 :                      (setq cell (cdr cell)))))
     842             :                ;; Final cleanup, remove major mode cell if last keyword
     843             :                ;; was deleted.
     844           0 :                (if (null (cdr top-cell))
     845           0 :                    (setq font-lock-keywords-alist
     846           0 :                          (delq top-cell font-lock-keywords-alist))))
     847             :              ;; Remember the keyword in case it is not local.
     848           0 :              (let ((cell (assq mode font-lock-removed-keywords-alist)))
     849           0 :                (if cell
     850           0 :                    (unless (member keyword (cdr cell))
     851           0 :                      (nconc cell (list keyword)))
     852           0 :                  (push (cons mode (list keyword))
     853           0 :                        font-lock-removed-keywords-alist))))))
     854             :         (t
     855             :          ;; Otherwise remove it immediately.
     856         224 :          (font-lock-set-defaults)
     857         224 :          (let ((was-compiled (eq (car font-lock-keywords) t)))
     858             :            ;; Bring back the user-level (uncompiled) keywords.
     859         224 :            (if was-compiled
     860         224 :                (setq font-lock-keywords (cadr font-lock-keywords)))
     861             : 
     862             :            ;; Edit them.
     863         224 :            (setq font-lock-keywords (copy-sequence font-lock-keywords))
     864         224 :            (dolist (keyword keywords)
     865         224 :              (setq font-lock-keywords
     866         224 :                    (delete keyword font-lock-keywords)))
     867             : 
     868             :            ;; If the keywords were compiled before, compile them again.
     869         224 :            (if was-compiled
     870           0 :                (setq font-lock-keywords
     871         224 :                      (font-lock-compile-keywords font-lock-keywords)))))))
     872             : 
     873             : ;;; Font Lock Support mode.
     874             : 
     875             : ;; This is the code used to interface font-lock.el with any of its add-on
     876             : ;; packages, and provide the user interface.  Packages that have their own
     877             : ;; local buffer fontification functions (see below) may have to call
     878             : ;; `font-lock-after-fontify-buffer' and/or `font-lock-after-unfontify-buffer'
     879             : ;; themselves.
     880             : 
     881             : (defcustom font-lock-support-mode 'jit-lock-mode
     882             :   "Support mode for Font Lock mode.
     883             : Support modes speed up Font Lock mode by being choosy about when fontification
     884             : occurs.  The default support mode, Just-in-time Lock mode (symbol
     885             : `jit-lock-mode'), is recommended.
     886             : 
     887             : Other, older support modes are Fast Lock mode (symbol `fast-lock-mode') and
     888             : Lazy Lock mode (symbol `lazy-lock-mode').  See those modes for more info.
     889             : However, they are no longer recommended, as Just-in-time Lock mode is better.
     890             : 
     891             : If nil, means support for Font Lock mode is never performed.
     892             : If a symbol, use that support mode.
     893             : If a list, each element should be of the form (MAJOR-MODE . SUPPORT-MODE),
     894             : where MAJOR-MODE is a symbol or t (meaning the default).  For example:
     895             :  ((c-mode . fast-lock-mode) (c++-mode . fast-lock-mode) (t . lazy-lock-mode))
     896             : means that Fast Lock mode is used to support Font Lock mode for buffers in C or
     897             : C++ modes, and Lazy Lock mode is used to support Font Lock mode otherwise.
     898             : 
     899             : The value of this variable is used when Font Lock mode is turned on."
     900             :   :type '(choice (const :tag "none" nil)
     901             :                  (const :tag "fast lock" fast-lock-mode)
     902             :                  (const :tag "lazy lock" lazy-lock-mode)
     903             :                  (const :tag "jit lock" jit-lock-mode)
     904             :                  (repeat :menu-tag "mode specific" :tag "mode specific"
     905             :                          :value ((t . jit-lock-mode))
     906             :                          (cons :tag "Instance"
     907             :                                (radio :tag "Mode"
     908             :                                       (const :tag "all" t)
     909             :                                       (symbol :tag "name"))
     910             :                                (radio :tag "Support"
     911             :                                       (const :tag "none" nil)
     912             :                                       (const :tag "fast lock" fast-lock-mode)
     913             :                                       (const :tag "lazy lock" lazy-lock-mode)
     914             :                                       (const :tag "JIT lock" jit-lock-mode)))
     915             :                          ))
     916             :   :version "21.1"
     917             :   :group 'font-lock)
     918             : 
     919             : (defvar fast-lock-mode)
     920             : (defvar lazy-lock-mode)
     921             : (defvar jit-lock-mode)
     922             : 
     923             : (declare-function fast-lock-after-fontify-buffer "fast-lock")
     924             : (declare-function fast-lock-after-unfontify-buffer "fast-lock")
     925             : (declare-function fast-lock-mode "fast-lock")
     926             : (declare-function lazy-lock-after-fontify-buffer "lazy-lock")
     927             : (declare-function lazy-lock-after-unfontify-buffer "lazy-lock")
     928             : (declare-function lazy-lock-mode "lazy-lock")
     929             : 
     930             : (defun font-lock-turn-on-thing-lock ()
     931           0 :   (pcase (font-lock-value-in-major-mode font-lock-support-mode)
     932           0 :     (`fast-lock-mode (fast-lock-mode t))
     933           0 :     (`lazy-lock-mode (lazy-lock-mode t))
     934             :     (`jit-lock-mode
     935             :      ;; Prepare for jit-lock
     936           0 :      (remove-hook 'after-change-functions
     937           0 :                   #'font-lock-after-change-function t)
     938           0 :      (set (make-local-variable 'font-lock-flush-function)
     939           0 :           #'jit-lock-refontify)
     940           0 :      (set (make-local-variable 'font-lock-ensure-function)
     941           0 :           #'jit-lock-fontify-now)
     942             :      ;; Prevent font-lock-fontify-buffer from fontifying eagerly the whole
     943             :      ;; buffer.  This is important for things like CWarn mode which
     944             :      ;; adds/removes a few keywords and does a refontify (which takes ages on
     945             :      ;; large files).
     946           0 :      (set (make-local-variable 'font-lock-fontify-buffer-function)
     947           0 :           #'jit-lock-refontify)
     948             :      ;; Don't fontify eagerly (and don't abort if the buffer is large).
     949           0 :      (set (make-local-variable 'font-lock-fontified) t)
     950             :      ;; Use jit-lock.
     951           0 :      (jit-lock-register #'font-lock-fontify-region
     952           0 :                         (not font-lock-keywords-only))
     953             :      ;; Tell jit-lock how we extend the region to refontify.
     954           0 :      (add-hook 'jit-lock-after-change-extend-region-functions
     955           0 :                #'font-lock-extend-jit-lock-region-after-change
     956           0 :                nil t))))
     957             : 
     958             : (defun font-lock-turn-off-thing-lock ()
     959           0 :   (cond ((bound-and-true-p fast-lock-mode)
     960           0 :          (fast-lock-mode -1))
     961           0 :         ((bound-and-true-p jit-lock-mode)
     962           0 :          (jit-lock-unregister 'font-lock-fontify-region)
     963             :          ;; Reset local vars to the non-jit-lock case.
     964           0 :          (kill-local-variable 'font-lock-fontify-buffer-function))
     965           0 :         ((bound-and-true-p lazy-lock-mode)
     966           0 :          (lazy-lock-mode -1))))
     967             : 
     968             : (defun font-lock-after-fontify-buffer ()
     969           0 :   (cond ((bound-and-true-p fast-lock-mode)
     970           0 :          (fast-lock-after-fontify-buffer))
     971             :         ;; Useless now that jit-lock intercepts font-lock-fontify-buffer.  -sm
     972             :         ;; (jit-lock-mode
     973             :         ;;  (jit-lock-after-fontify-buffer))
     974           0 :         ((bound-and-true-p lazy-lock-mode)
     975           0 :          (lazy-lock-after-fontify-buffer))))
     976             : 
     977             : (defun font-lock-after-unfontify-buffer ()
     978           0 :   (cond ((bound-and-true-p fast-lock-mode)
     979           0 :          (fast-lock-after-unfontify-buffer))
     980             :         ;; Useless as well.  It's only called when:
     981             :         ;; - turning off font-lock: it does not matter if we leave spurious
     982             :         ;;   `fontified' text props around since jit-lock-mode is also off.
     983             :         ;; - font-lock-default-fontify-buffer fails: this is not run
     984             :         ;;   any more anyway.   -sm
     985             :         ;;
     986             :         ;; (jit-lock-mode
     987             :         ;;  (jit-lock-after-unfontify-buffer))
     988           0 :         ((bound-and-true-p lazy-lock-mode)
     989           0 :          (lazy-lock-after-unfontify-buffer))))
     990             : 
     991             : ;;; End of Font Lock Support mode.
     992             : 
     993             : ;;; Fontification functions.
     994             : 
     995             : ;; Rather than the function, e.g., `font-lock-fontify-region' containing the
     996             : ;; code to fontify a region, the function runs the function whose name is the
     997             : ;; value of the variable, e.g., `font-lock-fontify-region-function'.  Normally,
     998             : ;; the value of this variable is, e.g., `font-lock-default-fontify-region'
     999             : ;; which does contain the code to fontify a region.  However, the value of the
    1000             : ;; variable could be anything and thus, e.g., `font-lock-fontify-region' could
    1001             : ;; do anything.  The indirection of the fontification functions gives major
    1002             : ;; modes the capability of modifying the way font-lock.el fontifies.  Major
    1003             : ;; modes can modify the values of, e.g., `font-lock-fontify-region-function',
    1004             : ;; via the variable `font-lock-defaults'.
    1005             : ;;
    1006             : ;; For example, Rmail mode sets the variable `font-lock-defaults' so that
    1007             : ;; font-lock.el uses its own function for buffer fontification.  This function
    1008             : ;; makes fontification be on a message-by-message basis and so visiting an
    1009             : ;; RMAIL file is much faster.  A clever implementation of the function might
    1010             : ;; fontify the headers differently than the message body.  (It should, and
    1011             : ;; correspondingly for Mail mode, but I can't be bothered to do the work.  Can
    1012             : ;; you?)  This hints at a more interesting use...
    1013             : ;;
    1014             : ;; Languages that contain text normally contained in different major modes
    1015             : ;; could define their own fontification functions that treat text differently
    1016             : ;; depending on its context.  For example, Perl mode could arrange that here
    1017             : ;; docs are fontified differently than Perl code.  Or Yacc mode could fontify
    1018             : ;; rules one way and C code another.  Neat!
    1019             : ;;
    1020             : ;; A further reason to use the fontification indirection feature is when the
    1021             : ;; default syntactic fontification, or the default fontification in general,
    1022             : ;; is not flexible enough for a particular major mode.  For example, perhaps
    1023             : ;; comments are just too hairy for `font-lock-fontify-syntactically-region' to
    1024             : ;; cope with.  You need to write your own version of that function, e.g.,
    1025             : ;; `hairy-fontify-syntactically-region', and make your own version of
    1026             : ;; `hairy-fontify-region' call that function before calling
    1027             : ;; `font-lock-fontify-keywords-region' for the normal regexp fontification
    1028             : ;; pass.  And Hairy mode would set `font-lock-defaults' so that font-lock.el
    1029             : ;; would call your region fontification function instead of its own.  For
    1030             : ;; example, TeX modes could fontify {\foo ...} and \bar{...}  etc. multi-line
    1031             : ;; directives correctly and cleanly.  (It is the same problem as fontifying
    1032             : ;; multi-line strings and comments; regexps are not appropriate for the job.)
    1033             : 
    1034             : (defvar font-lock-extend-after-change-region-function nil
    1035             :   "A function that determines the region to refontify after a change.
    1036             : 
    1037             : This variable is either nil, or is a function that determines the
    1038             : region to refontify after a change.
    1039             : It is usually set by the major mode via `font-lock-defaults'.
    1040             : Font-lock calls this function after each buffer change.
    1041             : 
    1042             : The function is given three parameters, the standard BEG, END, and OLD-LEN
    1043             : from `after-change-functions'.  It should return either a cons of the beginning
    1044             : and end buffer positions \(in that order) of the region to refontify, or nil
    1045             : \(which directs the caller to fontify a default region).
    1046             : This function should preserve the match-data.
    1047             : The region it returns may start or end in the middle of a line.")
    1048             : (make-variable-buffer-local 'font-lock-extend-after-change-region-function)
    1049             : 
    1050             : (defun font-lock-fontify-buffer (&optional interactively)
    1051             :   "Fontify the current buffer the way the function `font-lock-mode' would."
    1052             :   (declare
    1053             :    ;; When called from Lisp, this function is a big mess.  The caller usually
    1054             :    ;; expects one of the following behaviors:
    1055             :    ;; - refresh the highlighting (because the font-lock-keywords have been
    1056             :    ;;   changed).
    1057             :    ;; - apply font-lock highlighting even if font-lock-mode is not enabled.
    1058             :    ;; - reset the highlighting rules because font-lock-defaults
    1059             :    ;;   has been changed (and then rehighlight everything).
    1060             :    ;; Of course, this function doesn't do all of the above in all situations
    1061             :    ;; (e.g. depending on whether jit-lock is in use) and it can't guess what
    1062             :    ;; the caller wants.
    1063             :    (interactive-only "use `font-lock-ensure' or `font-lock-flush' instead."))
    1064             :   (interactive "p")
    1065           0 :   (font-lock-set-defaults)
    1066           0 :   (let ((font-lock-verbose (or font-lock-verbose interactively)))
    1067           0 :     (funcall font-lock-fontify-buffer-function)))
    1068             : 
    1069             : (defun font-lock-unfontify-buffer ()
    1070           0 :   (funcall font-lock-unfontify-buffer-function))
    1071             : 
    1072             : (defun font-lock-fontify-region (beg end &optional loudly)
    1073             :   "Fontify the text between BEG and END.
    1074             : If LOUDLY is non-nil, print status messages while fontifying.
    1075             : This works by calling `font-lock-fontify-region-function'."
    1076           0 :   (font-lock-set-defaults)
    1077           0 :   (funcall font-lock-fontify-region-function beg end loudly))
    1078             : 
    1079             : (defun font-lock-unfontify-region (beg end)
    1080             :   "Unfontify the text between BEG and END.
    1081             : This works by calling `font-lock-unfontify-region-function'."
    1082           0 :   (save-buffer-state
    1083           0 :     (funcall font-lock-unfontify-region-function beg end)))
    1084             : 
    1085             : (defvar font-lock-flush-function #'font-lock-after-change-function
    1086             :   "Function to use to mark a region for refontification.
    1087             : Called with two arguments BEG and END.")
    1088             : 
    1089             : (defun font-lock-flush (&optional beg end)
    1090             :   "Declare the region BEG...END's fontification as out-of-date.
    1091             : If the region is not specified, it defaults to the entire
    1092             : accessible portion of the current buffer."
    1093        8068 :   (and font-lock-mode
    1094           0 :        font-lock-fontified
    1095           0 :        (funcall font-lock-flush-function
    1096        8068 :                 (or beg (point-min)) (or end (point-max)))))
    1097             : 
    1098             : (defvar font-lock-ensure-function
    1099             :   (lambda (_beg _end)
    1100             :     (unless font-lock-fontified
    1101             :       (font-lock-default-fontify-buffer)
    1102             :       (unless font-lock-mode
    1103             :         ;; If font-lock is not enabled, we don't have the hooks in place to
    1104             :         ;; track modifications, so a subsequent call to font-lock-ensure can't
    1105             :         ;; assume that the fontification is still valid.
    1106             :         (setq font-lock-fontified nil))))
    1107             :   "Function to make sure a region has been fontified.
    1108             : Called with two arguments BEG and END.")
    1109             : 
    1110             : (defun font-lock-ensure (&optional beg end)
    1111             :   "Make sure the region BEG...END has been fontified.
    1112             : If the region is not specified, it defaults to the entire accessible
    1113             : portion of the buffer."
    1114           0 :   (font-lock-set-defaults)
    1115           0 :   (funcall font-lock-ensure-function
    1116           0 :            (or beg (point-min)) (or end (point-max))))
    1117             : 
    1118             : (defun font-lock-default-fontify-buffer ()
    1119             :   "Fontify the whole buffer using `font-lock-fontify-region-function'."
    1120           0 :   (let ((verbose (if (numberp font-lock-verbose)
    1121           0 :                      (> (buffer-size) font-lock-verbose)
    1122           0 :                    font-lock-verbose)))
    1123           0 :     (with-temp-message
    1124           0 :         (when verbose
    1125           0 :           (format "Fontifying %s..." (buffer-name)))
    1126             :       ;; Make sure we fontify etc. in the whole buffer.
    1127           0 :       (save-restriction
    1128           0 :         (unless font-lock-dont-widen (widen))
    1129           0 :         (condition-case nil
    1130           0 :             (save-excursion
    1131           0 :               (save-match-data
    1132           0 :                 (font-lock-fontify-region (point-min) (point-max) verbose)
    1133           0 :                 (font-lock-after-fontify-buffer)
    1134           0 :                 (setq font-lock-fontified t)))
    1135             :           ;; We don't restore the old fontification, so it's best to unfontify.
    1136           0 :           (quit (font-lock-unfontify-buffer)))))))
    1137             : 
    1138             : (defun font-lock-default-unfontify-buffer ()
    1139             :   "Unfontify the whole buffer using `font-lock-unfontify-region-function'."
    1140             :   ;; Make sure we unfontify etc. in the whole buffer.
    1141           0 :   (save-restriction
    1142           0 :     (widen)
    1143           0 :     (font-lock-unfontify-region (point-min) (point-max))
    1144           0 :     (font-lock-after-unfontify-buffer)
    1145           0 :     (setq font-lock-fontified nil)))
    1146             : 
    1147             : (defvar font-lock-dont-widen nil
    1148             :   "If non-nil, font-lock will work on the non-widened buffer.
    1149             : Useful for things like RMAIL and Info where the whole buffer is not
    1150             : a very meaningful entity to highlight.")
    1151             : 
    1152             : 
    1153             : (defvar font-lock-beg) (defvar font-lock-end)
    1154             : (defvar font-lock-extend-region-functions
    1155             :   '(font-lock-extend-region-wholelines
    1156             :     ;; This use of font-lock-multiline property is unreliable but is just
    1157             :     ;; a handy heuristic: in case you don't have a function that does
    1158             :     ;; /identification/ of multiline elements, you may still occasionally
    1159             :     ;; discover them by accident (or you may /identify/ them but not in all
    1160             :     ;; cases), in which case the font-lock-multiline property can help make
    1161             :     ;; sure you will properly *re*identify them during refontification.
    1162             :     font-lock-extend-region-multiline)
    1163             :   "Special hook run just before proceeding to fontify a region.
    1164             : This is used to allow major modes to help font-lock find safe buffer positions
    1165             : as beginning and end of the fontified region.  Its most common use is to solve
    1166             : the problem of /identification/ of multiline elements by providing a function
    1167             : that tries to find such elements and move the boundaries such that they do
    1168             : not fall in the middle of one.
    1169             : Each function is called with no argument; it is expected to adjust the
    1170             : dynamically bound variables `font-lock-beg' and `font-lock-end'; and return
    1171             : non-nil if it did make such an adjustment.
    1172             : These functions are run in turn repeatedly until they all return nil.
    1173             : Put first the functions more likely to cause a change and cheaper to compute.")
    1174             : ;; Mark it as a special hook which doesn't use any global setting
    1175             : ;; (i.e. doesn't obey the element t in the buffer-local value).
    1176             : (make-variable-buffer-local 'font-lock-extend-region-functions)
    1177             : 
    1178             : (defun font-lock-extend-region-multiline ()
    1179             :   "Move fontification boundaries away from any `font-lock-multiline' property."
    1180           0 :   (let ((changed nil))
    1181           0 :     (when (and (> font-lock-beg (point-min))
    1182           0 :                (get-text-property (1- font-lock-beg) 'font-lock-multiline))
    1183           0 :       (setq changed t)
    1184           0 :       (setq font-lock-beg (or (previous-single-property-change
    1185           0 :                                font-lock-beg 'font-lock-multiline)
    1186           0 :                               (point-min))))
    1187             :     ;;
    1188           0 :     (when (get-text-property font-lock-end 'font-lock-multiline)
    1189           0 :       (setq changed t)
    1190           0 :       (setq font-lock-end (or (text-property-any font-lock-end (point-max)
    1191           0 :                                                  'font-lock-multiline nil)
    1192           0 :                               (point-max))))
    1193           0 :     changed))
    1194             : 
    1195             : (defun font-lock-extend-region-wholelines ()
    1196             :   "Move fontification boundaries to beginning of lines."
    1197           0 :   (let ((changed nil))
    1198           0 :     (goto-char font-lock-beg)
    1199           0 :     (unless (bolp)
    1200           0 :       (setq changed t font-lock-beg
    1201           0 :             (let ((inhibit-field-text-motion t))
    1202           0 :               (line-beginning-position))))
    1203           0 :     (goto-char font-lock-end)
    1204           0 :     (unless (bolp)
    1205           0 :       (unless (eq font-lock-end
    1206           0 :                   (setq font-lock-end (line-beginning-position 2)))
    1207           0 :         (setq changed t)))
    1208           0 :     changed))
    1209             : 
    1210             : (defun font-lock-default-fontify-region (beg end loudly)
    1211             :   "Fontify the text between BEG and END.
    1212             : If LOUDLY is non-nil, print status messages while fontifying.
    1213             : This function is the default `font-lock-fontify-region-function'."
    1214           0 :   (save-buffer-state
    1215             :     ;; Use the fontification syntax table, if any.
    1216           0 :     (with-syntax-table (or font-lock-syntax-table (syntax-table))
    1217           0 :       (save-restriction
    1218           0 :         (unless font-lock-dont-widen (widen))
    1219             :         ;; Extend the region to fontify so that it starts and ends at
    1220             :         ;; safe places.
    1221           0 :         (let ((funs font-lock-extend-region-functions)
    1222           0 :               (font-lock-beg beg)
    1223           0 :               (font-lock-end end))
    1224           0 :           (while funs
    1225           0 :             (setq funs (if (or (not (funcall (car funs)))
    1226           0 :                                (eq funs font-lock-extend-region-functions))
    1227           0 :                            (cdr funs)
    1228             :                          ;; If there's been a change, we should go through
    1229             :                          ;; the list again since this new position may
    1230             :                          ;; warrant a different answer from one of the fun
    1231             :                          ;; we've already seen.
    1232           0 :                          font-lock-extend-region-functions)))
    1233           0 :           (setq beg font-lock-beg end font-lock-end))
    1234             :         ;; Now do the fontification.
    1235           0 :         (font-lock-unfontify-region beg end)
    1236           0 :         (when (and font-lock-syntactic-keywords
    1237           0 :                    (null syntax-propertize-function))
    1238             :           ;; Ensure the beginning of the file is properly syntactic-fontified.
    1239           0 :           (let ((start beg))
    1240           0 :             (when (< font-lock-syntactically-fontified start)
    1241           0 :               (setq start (max font-lock-syntactically-fontified (point-min)))
    1242           0 :               (setq font-lock-syntactically-fontified end))
    1243           0 :             (font-lock-fontify-syntactic-keywords-region start end)))
    1244           0 :         (unless font-lock-keywords-only
    1245           0 :           (font-lock-fontify-syntactically-region beg end loudly))
    1246           0 :         (font-lock-fontify-keywords-region beg end loudly)
    1247           0 :         `(jit-lock-bounds ,beg . ,end)))))
    1248             : 
    1249             : ;; The following must be rethought, since keywords can override fontification.
    1250             : ;;    ;; Now scan for keywords, but not if we are inside a comment now.
    1251             : ;;    (or (and (not font-lock-keywords-only)
    1252             : ;;             (let ((state (parse-partial-sexp beg end nil nil
    1253             : ;;                                              font-lock-cache-state)))
    1254             : ;;               (or (nth 4 state) (nth 7 state))))
    1255             : ;;        (font-lock-fontify-keywords-region beg end))
    1256             : 
    1257             : (defvar font-lock-extra-managed-props nil
    1258             :   "Additional text properties managed by font-lock.
    1259             : This is used by `font-lock-default-unfontify-region' to decide
    1260             : what properties to clear before refontifying a region.")
    1261             : 
    1262             : (defun font-lock-default-unfontify-region (beg end)
    1263             :   "Unfontify the text between BEG and END.
    1264             : This function is the default `font-lock-unfontify-region-function'."
    1265           0 :   (remove-list-of-text-properties
    1266           0 :    beg end (append
    1267           0 :             font-lock-extra-managed-props
    1268           0 :             (if font-lock-syntactic-keywords
    1269             :                 '(syntax-table face font-lock-multiline)
    1270           0 :               '(face font-lock-multiline)))))
    1271             : 
    1272             : ;; Called when any modification is made to buffer text.
    1273             : (defun font-lock-after-change-function (beg end &optional old-len)
    1274           0 :   (save-excursion
    1275           0 :     (let ((inhibit-point-motion-hooks t)
    1276             :           (inhibit-quit t)
    1277           0 :           (region (if font-lock-extend-after-change-region-function
    1278           0 :                       (funcall font-lock-extend-after-change-region-function
    1279           0 :                                beg end old-len))))
    1280           0 :       (save-match-data
    1281           0 :         (if region
    1282             :             ;; Fontify the region the major mode has specified.
    1283           0 :             (setq beg (car region) end (cdr region))
    1284             :           ;; Fontify the whole lines which enclose the region.
    1285             :           ;; Actually, this is not needed because
    1286             :           ;; font-lock-default-fontify-region already rounds up to a whole
    1287             :           ;; number of lines.
    1288             :           ;; (setq beg (progn (goto-char beg) (line-beginning-position))
    1289             :           ;;       end (progn (goto-char end) (line-beginning-position 2)))
    1290           0 :           (unless (eq end (point-max))
    1291             :             ;; Rounding up to a whole number of lines should include the
    1292             :             ;; line right after `end'.  Typical case: the first char of
    1293             :             ;; the line was deleted.  Or a \n was inserted in the middle
    1294             :             ;; of a line.
    1295           0 :             (setq end (1+ end))))
    1296           0 :         (font-lock-fontify-region beg end)))))
    1297             : 
    1298             : (defvar jit-lock-start) (defvar jit-lock-end)
    1299             : (defun font-lock-extend-jit-lock-region-after-change (beg end old-len)
    1300             :   "Function meant for `jit-lock-after-change-extend-region-functions'.
    1301             : This function does 2 things:
    1302             : - extend the region so that it not only includes the part that was modified
    1303             :   but also the surrounding text whose highlighting may change as a consequence.
    1304             : - anticipate (part of) the region extension that will happen later in
    1305             :   `font-lock-default-fontify-region', in order to avoid the need for
    1306             :   double-redisplay in `jit-lock-fontify-now'."
    1307           0 :   (save-excursion
    1308             :     ;; First extend the region as font-lock-after-change-function would.
    1309           0 :     (let ((region (if font-lock-extend-after-change-region-function
    1310           0 :                       (funcall font-lock-extend-after-change-region-function
    1311           0 :                                beg end old-len))))
    1312           0 :       (if region
    1313           0 :           (setq beg (min jit-lock-start (car region))
    1314           0 :                 end (max jit-lock-end (cdr region))))
    1315             :       ;; Then extend the region obeying font-lock-multiline properties,
    1316             :       ;; indicating which part of the buffer needs to be refontified.
    1317             :       ;; !!! This is the *main* user of font-lock-multiline property !!!
    1318             :       ;; font-lock-after-change-function could/should also do that, but it
    1319             :       ;; doesn't need to because font-lock-default-fontify-region does
    1320             :       ;; it anyway.  Here OTOH we have no guarantee that
    1321             :       ;; font-lock-default-fontify-region will be executed on this region
    1322             :       ;; any time soon.
    1323             :       ;; Note: contrary to font-lock-default-fontify-region, we do not do
    1324             :       ;; any loop here because we are not looking for a safe spot: we just
    1325             :       ;; mark the text whose appearance may need to change as a result of
    1326             :       ;; the buffer modification.
    1327           0 :       (when (and (> beg (point-min))
    1328           0 :                  (get-text-property (1- beg) 'font-lock-multiline))
    1329           0 :         (setq beg (or (previous-single-property-change
    1330           0 :                        beg 'font-lock-multiline)
    1331           0 :                       (point-min))))
    1332           0 :       (when (< end (point-max))
    1333           0 :         (setq end
    1334           0 :               (cond
    1335           0 :                ((get-text-property end 'font-lock-multiline)
    1336           0 :                 (or (text-property-any end (point-max)
    1337           0 :                                        'font-lock-multiline nil)
    1338           0 :                     (point-max)))
    1339             :                ;; If `end' has been set by the function above, don't corrupt it.
    1340           0 :                (font-lock-extend-after-change-region-function end)
    1341             :                 ;; Rounding up to a whole number of lines should include the
    1342             :                 ;; line right after `end'.  Typical case: the first char of
    1343             :                 ;; the line was deleted.  Or a \n was inserted in the middle
    1344             :                 ;; of a line.
    1345           0 :                (t (1+ end)))))
    1346             :       ;; Finally, pre-enlarge the region to a whole number of lines, to try
    1347             :       ;; and anticipate what font-lock-default-fontify-region will do, so as to
    1348             :       ;; avoid double-redisplay.
    1349             :       ;; We could just run `font-lock-extend-region-functions', but since
    1350             :       ;; the only purpose is to avoid the double-redisplay, we prefer to
    1351             :       ;; do here only the part that is cheap and most likely to be useful.
    1352           0 :       (when (memq 'font-lock-extend-region-wholelines
    1353           0 :                   font-lock-extend-region-functions)
    1354           0 :         (goto-char beg)
    1355           0 :         (setq beg (min jit-lock-start (line-beginning-position)))
    1356           0 :         (goto-char end)
    1357           0 :         (setq end
    1358           0 :               (max jit-lock-end
    1359           0 :                    (if (bolp) (point) (line-beginning-position 2)))))
    1360           0 :       (setq jit-lock-start beg
    1361           0 :             jit-lock-end end))))
    1362             : 
    1363             : (defun font-lock-fontify-block (&optional arg)
    1364             :   "Fontify some lines the way `font-lock-fontify-buffer' would.
    1365             : The lines could be a function or paragraph, or a specified number of lines.
    1366             : If ARG is given, fontify that many lines before and after point, or 16 lines if
    1367             : no ARG is given and `font-lock-mark-block-function' is nil.
    1368             : If `font-lock-mark-block-function' non-nil and no ARG is given, it is used to
    1369             : delimit the region to fontify."
    1370             :   (interactive "P")
    1371           0 :   (let ((inhibit-point-motion-hooks t)
    1372             :         deactivate-mark)
    1373             :     ;; Make sure we have the right `font-lock-keywords' etc.
    1374           0 :     (if (not font-lock-mode) (font-lock-set-defaults))
    1375           0 :     (save-mark-and-excursion
    1376           0 :       (save-match-data
    1377           0 :         (condition-case error-data
    1378           0 :             (if (or arg (not font-lock-mark-block-function))
    1379           0 :                 (let ((lines (if arg (prefix-numeric-value arg) 16)))
    1380           0 :                   (font-lock-fontify-region
    1381           0 :                    (save-excursion (forward-line (- lines)) (point))
    1382           0 :                    (save-excursion (forward-line lines) (point))))
    1383           0 :               (funcall font-lock-mark-block-function)
    1384           0 :               (font-lock-fontify-region (point) (mark)))
    1385           0 :           ((error quit) (message "Fontifying block...%s" error-data)))))))
    1386             : 
    1387             : ;;; End of Fontification functions.
    1388             : 
    1389             : ;;; Additional text property functions.
    1390             : 
    1391             : ;; The following text property functions should be builtins.  This means they
    1392             : ;; should be written in C and put with all the other text property functions.
    1393             : ;; In the meantime, those that are used by font-lock.el are defined in Lisp
    1394             : ;; below and given a `font-lock-' prefix.  Those that are not used are defined
    1395             : ;; in Lisp below and commented out.  sm.
    1396             : 
    1397             : (defun font-lock-prepend-text-property (start end prop value &optional object)
    1398             :   "Prepend to one property of the text from START to END.
    1399             : Arguments PROP and VALUE specify the property and value to prepend to the value
    1400             : already in place.  The resulting property values are always lists.
    1401             : Optional argument OBJECT is the string or buffer containing the text."
    1402          26 :   (let ((val (if (listp value) value (list value))) next prev)
    1403          44 :     (while (/= start end)
    1404          18 :       (setq next (next-single-property-change start prop object end)
    1405          18 :             prev (get-text-property start prop object))
    1406             :       ;; Canonicalize old forms of face property.
    1407          18 :       (and (memq prop '(face font-lock-face))
    1408          18 :            (listp prev)
    1409          18 :            (or (keywordp (car prev))
    1410          18 :                (memq (car prev) '(foreground-color background-color)))
    1411          18 :            (setq prev (list prev)))
    1412          18 :       (put-text-property start next prop
    1413          18 :                          (append val (if (listp prev) prev (list prev)))
    1414          18 :                          object)
    1415          26 :       (setq start next))))
    1416             : 
    1417             : (defun font-lock-append-text-property (start end prop value &optional object)
    1418             :   "Append to one property of the text from START to END.
    1419             : Arguments PROP and VALUE specify the property and value to append to the value
    1420             : already in place.  The resulting property values are always lists.
    1421             : Optional argument OBJECT is the string or buffer containing the text."
    1422           0 :   (let ((val (if (listp value) value (list value))) next prev)
    1423           0 :     (while (/= start end)
    1424           0 :       (setq next (next-single-property-change start prop object end)
    1425           0 :             prev (get-text-property start prop object))
    1426             :       ;; Canonicalize old forms of face property.
    1427           0 :       (and (memq prop '(face font-lock-face))
    1428           0 :            (listp prev)
    1429           0 :            (or (keywordp (car prev))
    1430           0 :                (memq (car prev) '(foreground-color background-color)))
    1431           0 :            (setq prev (list prev)))
    1432           0 :       (put-text-property start next prop
    1433           0 :                          (append (if (listp prev) prev (list prev)) val)
    1434           0 :                          object)
    1435           0 :       (setq start next))))
    1436             : 
    1437             : (defun font-lock-fillin-text-property (start end prop value &optional object)
    1438             :   "Fill in one property of the text from START to END.
    1439             : Arguments PROP and VALUE specify the property and value to put where none are
    1440             : already in place.  Therefore existing property values are not overwritten.
    1441             : Optional argument OBJECT is the string or buffer containing the text."
    1442           0 :   (let ((start (text-property-any start end prop nil object)) next)
    1443           0 :     (while start
    1444           0 :       (setq next (next-single-property-change start prop object end))
    1445           0 :       (put-text-property start next prop value object)
    1446           0 :       (setq start (text-property-any next end prop nil object)))))
    1447             : 
    1448             : (defun font-lock--remove-face-from-text-property (start
    1449             :                                                   end
    1450             :                                                   prop value &optional object)
    1451             :   "Remove a specific property value from text from START to END.
    1452             : Arguments PROP and VALUE specify the property and value to remove.  The
    1453             : resulting property values are not `eq' to VALUE nor lists containing VALUE.
    1454             : Optional argument OBJECT is the string or buffer containing the text."
    1455          16 :   (let ((start (text-property-not-all start end prop nil object)) next prev)
    1456          32 :     (while start
    1457          16 :       (setq next (next-single-property-change start prop object end)
    1458          16 :             prev (get-text-property start prop object))
    1459          16 :       (cond ((or (atom prev)
    1460          16 :                  (keywordp (car prev))
    1461          16 :                  (eq (car prev) 'foreground-color)
    1462          16 :                  (eq (car prev) 'background-color))
    1463           0 :              (when (eq value prev)
    1464           0 :                (remove-list-of-text-properties start next (list prop) object)))
    1465          16 :             ((memq value prev)          ;Assume prev is not dotted.
    1466          16 :              (let ((new (remq value prev)))
    1467          16 :                (cond ((null new)
    1468          16 :                       (remove-list-of-text-properties start next (list prop)
    1469          16 :                                                       object))
    1470           0 :                      ((= (length new) 1)
    1471           0 :                       (put-text-property start next prop (car new) object))
    1472             :                      (t
    1473          16 :                       (put-text-property start next prop new object))))))
    1474          16 :       (setq start (text-property-not-all next end prop nil object)))))
    1475             : 
    1476             : ;;; End of Additional text property functions.
    1477             : 
    1478             : ;;; Syntactic regexp fontification functions.
    1479             : 
    1480             : ;; These syntactic keyword pass functions are identical to those keyword pass
    1481             : ;; functions below, with the following exceptions; (a) they operate on
    1482             : ;; `font-lock-syntactic-keywords' of course, (b) they are all `defun' as speed
    1483             : ;; is less of an issue, (c) eval of property value does not occur JIT as speed
    1484             : ;; is less of an issue, (d) OVERRIDE cannot be `prepend' or `append' as it
    1485             : ;; makes no sense for `syntax-table' property values, (e) they do not do it
    1486             : ;; LOUDLY as it is not likely to be intensive.
    1487             : 
    1488             : (defun font-lock-apply-syntactic-highlight (highlight)
    1489             :   "Apply HIGHLIGHT following a match.
    1490             : HIGHLIGHT should be of the form MATCH-HIGHLIGHT,
    1491             : see `font-lock-syntactic-keywords'."
    1492           0 :   (let* ((match (nth 0 highlight))
    1493           0 :          (start (match-beginning match)) (end (match-end match))
    1494           0 :          (value (nth 1 highlight))
    1495           0 :          (override (nth 2 highlight)))
    1496           0 :     (if (not start)
    1497             :         ;; No match but we might not signal an error.
    1498           0 :         (or (nth 3 highlight)
    1499           0 :             (error "No match %d in highlight %S" match highlight))
    1500           0 :       (when (and (consp value) (not (numberp (car value))))
    1501           0 :         (setq value (eval value)))
    1502           0 :       (when (stringp value) (setq value (string-to-syntax value)))
    1503             :       ;; Flush the syntax-cache.  I believe this is not necessary for
    1504             :       ;; font-lock's use of syntax-ppss, but I'm not 100% sure and it can
    1505             :       ;; still be necessary for other users of syntax-ppss anyway.
    1506           0 :       (syntax-ppss-after-change-function start)
    1507           0 :       (cond
    1508           0 :        ((not override)
    1509             :         ;; Cannot override existing fontification.
    1510           0 :         (or (text-property-not-all start end 'syntax-table nil)
    1511           0 :             (put-text-property start end 'syntax-table value)))
    1512           0 :        ((eq override t)
    1513             :         ;; Override existing fontification.
    1514           0 :         (put-text-property start end 'syntax-table value))
    1515           0 :        ((eq override 'keep)
    1516             :         ;; Keep existing fontification.
    1517           0 :         (font-lock-fillin-text-property start end 'syntax-table value))))))
    1518             : 
    1519             : (defun font-lock-fontify-syntactic-anchored-keywords (keywords limit)
    1520             :   "Fontify according to KEYWORDS until LIMIT.
    1521             : KEYWORDS should be of the form MATCH-ANCHORED, see `font-lock-keywords',
    1522             : LIMIT can be modified by the value of its PRE-MATCH-FORM."
    1523           0 :   (let ((matcher (nth 0 keywords)) (lowdarks (nthcdr 3 keywords)) highlights
    1524             :         ;; Evaluate PRE-MATCH-FORM.
    1525           0 :         (pre-match-value (eval (nth 1 keywords))))
    1526             :     ;; Set LIMIT to value of PRE-MATCH-FORM or the end of line.
    1527           0 :     (if (and (numberp pre-match-value) (> pre-match-value (point)))
    1528           0 :         (setq limit pre-match-value)
    1529           0 :       (setq limit (line-end-position)))
    1530           0 :     (save-match-data
    1531             :       ;; Find an occurrence of `matcher' before `limit'.
    1532           0 :       (while (if (stringp matcher)
    1533           0 :                  (re-search-forward matcher limit t)
    1534           0 :                (funcall matcher limit))
    1535             :         ;; Apply each highlight to this instance of `matcher'.
    1536           0 :         (setq highlights lowdarks)
    1537           0 :         (while highlights
    1538           0 :           (font-lock-apply-syntactic-highlight (car highlights))
    1539           0 :           (setq highlights (cdr highlights)))))
    1540             :     ;; Evaluate POST-MATCH-FORM.
    1541           0 :     (eval (nth 2 keywords))))
    1542             : 
    1543             : (defun font-lock-fontify-syntactic-keywords-region (start end)
    1544             :   "Fontify according to `font-lock-syntactic-keywords' between START and END.
    1545             : START should be at the beginning of a line."
    1546           0 :   (unless parse-sexp-lookup-properties
    1547             :     ;; We wouldn't go through so much trouble if we didn't intend to use those
    1548             :     ;; properties, would we?
    1549           0 :     (set (make-local-variable 'parse-sexp-lookup-properties) t))
    1550             :   ;; If `font-lock-syntactic-keywords' is a symbol, get the real keywords.
    1551           0 :   (when (symbolp font-lock-syntactic-keywords)
    1552           0 :     (setq font-lock-syntactic-keywords (font-lock-eval-keywords
    1553           0 :                                         font-lock-syntactic-keywords)))
    1554             :   ;; If `font-lock-syntactic-keywords' is not compiled, compile it.
    1555           0 :   (unless (eq (car font-lock-syntactic-keywords) t)
    1556           0 :     (setq font-lock-syntactic-keywords (font-lock-compile-keywords
    1557           0 :                                         font-lock-syntactic-keywords
    1558           0 :                                         t)))
    1559             :   ;; Get down to business.
    1560           0 :   (let ((case-fold-search font-lock-keywords-case-fold-search)
    1561           0 :         (keywords (cddr font-lock-syntactic-keywords))
    1562             :         keyword matcher highlights)
    1563           0 :     (while keywords
    1564             :       ;; Find an occurrence of `matcher' from `start' to `end'.
    1565           0 :       (setq keyword (car keywords) matcher (car keyword))
    1566           0 :       (goto-char start)
    1567           0 :       (while (and (< (point) end)
    1568           0 :                   (if (stringp matcher)
    1569           0 :                       (re-search-forward matcher end t)
    1570           0 :                     (funcall matcher end)))
    1571             :         ;; Apply each highlight to this instance of `matcher', which may be
    1572             :         ;; specific highlights or more keywords anchored to `matcher'.
    1573           0 :         (setq highlights (cdr keyword))
    1574           0 :         (while highlights
    1575           0 :           (if (numberp (car (car highlights)))
    1576           0 :               (font-lock-apply-syntactic-highlight (car highlights))
    1577           0 :             (font-lock-fontify-syntactic-anchored-keywords (car highlights)
    1578           0 :                                                            end))
    1579           0 :           (setq highlights (cdr highlights))))
    1580           0 :       (setq keywords (cdr keywords)))))
    1581             : 
    1582             : ;;; End of Syntactic regexp fontification functions.
    1583             : 
    1584             : ;;; Syntactic fontification functions.
    1585             : 
    1586             : (defvar font-lock-comment-start-skip nil
    1587             :   "If non-nil, Font Lock mode uses this instead of `comment-start-skip'.")
    1588             : 
    1589             : (defvar font-lock-comment-end-skip nil
    1590             :   "If non-nil, Font Lock mode uses this instead of `comment-end'.")
    1591             : 
    1592             : (defun font-lock-fontify-syntactically-region (start end &optional loudly)
    1593             :   "Put proper face on each string and comment between START and END.
    1594             : START should be at the beginning of a line."
    1595           0 :   (syntax-propertize end)  ; Apply any needed syntax-table properties.
    1596           0 :   (with-syntax-table (or syntax-ppss-table (syntax-table))
    1597           0 :   (let ((comment-end-regexp
    1598           0 :          (or font-lock-comment-end-skip
    1599           0 :              (regexp-quote
    1600           0 :               (replace-regexp-in-string "^ *" "" comment-end))))
    1601             :         ;; Find the `start' state.
    1602           0 :         (state (syntax-ppss start))
    1603             :         face beg)
    1604           0 :     (if loudly (message "Fontifying %s... (syntactically...)" (buffer-name)))
    1605             :     ;;
    1606             :     ;; Find each interesting place between here and `end'.
    1607           0 :     (while
    1608           0 :         (progn
    1609           0 :           (when (or (nth 3 state) (nth 4 state))
    1610           0 :             (setq face (funcall font-lock-syntactic-face-function state))
    1611           0 :             (setq beg (max (nth 8 state) start))
    1612           0 :             (setq state (parse-partial-sexp (point) end nil nil state
    1613           0 :                                             'syntax-table))
    1614           0 :             (when face (put-text-property beg (point) 'face face))
    1615           0 :             (when (and (eq face 'font-lock-comment-face)
    1616           0 :                        (or font-lock-comment-start-skip
    1617           0 :                            comment-start-skip))
    1618             :               ;; Find the comment delimiters
    1619             :               ;; and use font-lock-comment-delimiter-face for them.
    1620           0 :               (save-excursion
    1621           0 :                 (goto-char beg)
    1622           0 :                 (if (looking-at (or font-lock-comment-start-skip
    1623           0 :                                     comment-start-skip))
    1624           0 :                     (put-text-property beg (match-end 0) 'face
    1625           0 :                                        font-lock-comment-delimiter-face)))
    1626           0 :               (if (looking-back comment-end-regexp (point-at-bol) t)
    1627           0 :                   (put-text-property (match-beginning 0) (point) 'face
    1628           0 :                                      font-lock-comment-delimiter-face))))
    1629           0 :           (< (point) end))
    1630           0 :       (setq state (parse-partial-sexp (point) end nil nil state
    1631           0 :                                       'syntax-table))))))
    1632             : 
    1633             : ;;; End of Syntactic fontification functions.
    1634             : 
    1635             : ;;; Keyword regexp fontification functions.
    1636             : 
    1637             : (defsubst font-lock-apply-highlight (highlight)
    1638             :   "Apply HIGHLIGHT following a match.
    1639             : HIGHLIGHT should be of the form MATCH-HIGHLIGHT, see `font-lock-keywords'."
    1640           0 :   (let* ((match (nth 0 highlight))
    1641           0 :          (start (match-beginning match)) (end (match-end match))
    1642           0 :          (override (nth 2 highlight)))
    1643           0 :     (if (not start)
    1644             :         ;; No match but we might not signal an error.
    1645           0 :         (or (nth 3 highlight)
    1646           0 :             (error "No match %d in highlight %S" match highlight))
    1647           0 :       (let ((val (eval (nth 1 highlight))))
    1648           0 :         (when (eq (car-safe val) 'face)
    1649           0 :           (add-text-properties start end (cddr val))
    1650           0 :           (setq val (cadr val)))
    1651           0 :         (cond
    1652           0 :          ((not (or val (eq override t)))
    1653             :           ;; If `val' is nil, don't do anything.  It is important to do it
    1654             :           ;; explicitly, because when adding nil via things like
    1655             :           ;; font-lock-append-text-property, the property is actually
    1656             :           ;; changed from <face> to (<face>) which is undesirable.  --Stef
    1657             :           nil)
    1658           0 :          ((not override)
    1659             :           ;; Cannot override existing fontification.
    1660           0 :           (or (text-property-not-all start end 'face nil)
    1661           0 :               (put-text-property start end 'face val)))
    1662           0 :          ((eq override t)
    1663             :           ;; Override existing fontification.
    1664           0 :           (put-text-property start end 'face val))
    1665           0 :          ((eq override 'prepend)
    1666             :           ;; Prepend to existing fontification.
    1667           0 :           (font-lock-prepend-text-property start end 'face val))
    1668           0 :          ((eq override 'append)
    1669             :           ;; Append to existing fontification.
    1670           0 :           (font-lock-append-text-property start end 'face val))
    1671           0 :          ((eq override 'keep)
    1672             :           ;; Keep existing fontification.
    1673           0 :           (font-lock-fillin-text-property start end 'face val)))))))
    1674             : 
    1675             : (defsubst font-lock-fontify-anchored-keywords (keywords limit)
    1676             :   "Fontify according to KEYWORDS until LIMIT.
    1677             : KEYWORDS should be of the form MATCH-ANCHORED, see `font-lock-keywords',
    1678             : LIMIT can be modified by the value of its PRE-MATCH-FORM."
    1679           0 :   (let ((matcher (nth 0 keywords)) (lowdarks (nthcdr 3 keywords)) highlights
    1680           0 :         (lead-start (match-beginning 0))
    1681             :         ;; Evaluate PRE-MATCH-FORM.
    1682           0 :         (pre-match-value (eval (nth 1 keywords))))
    1683             :     ;; Set LIMIT to value of PRE-MATCH-FORM or the end of line.
    1684           0 :     (if (not (and (numberp pre-match-value) (> pre-match-value (point))))
    1685           0 :         (setq limit (line-end-position))
    1686           0 :       (setq limit pre-match-value)
    1687           0 :       (when (and font-lock-multiline (>= limit (line-beginning-position 2)))
    1688             :         ;; this is a multiline anchored match
    1689             :         ;; (setq font-lock-multiline t)
    1690           0 :         (put-text-property (if (= limit (line-beginning-position 2))
    1691           0 :                                (1- limit)
    1692           0 :                              (min lead-start (point)))
    1693           0 :                            limit
    1694           0 :                            'font-lock-multiline t)))
    1695           0 :     (save-match-data
    1696             :       ;; Find an occurrence of `matcher' before `limit'.
    1697           0 :       (while (and (< (point) limit)
    1698           0 :                   (if (stringp matcher)
    1699           0 :                       (re-search-forward matcher limit t)
    1700           0 :                     (funcall matcher limit)))
    1701             :         ;; Apply each highlight to this instance of `matcher'.
    1702           0 :         (setq highlights lowdarks)
    1703           0 :         (while highlights
    1704           0 :           (font-lock-apply-highlight (car highlights))
    1705           0 :           (setq highlights (cdr highlights)))))
    1706             :     ;; Evaluate POST-MATCH-FORM.
    1707           0 :     (eval (nth 2 keywords))))
    1708             : 
    1709             : (defun font-lock-fontify-keywords-region (start end &optional loudly)
    1710             :   "Fontify according to `font-lock-keywords' between START and END.
    1711             : START should be at the beginning of a line.
    1712             : LOUDLY, if non-nil, allows progress-meter bar."
    1713           0 :   (unless (eq (car font-lock-keywords) t)
    1714           0 :     (setq font-lock-keywords
    1715           0 :           (font-lock-compile-keywords font-lock-keywords)))
    1716           0 :   (let ((case-fold-search font-lock-keywords-case-fold-search)
    1717           0 :         (keywords (cddr font-lock-keywords))
    1718           0 :         (bufname (buffer-name)) (count 0)
    1719           0 :         (pos (make-marker))
    1720             :         keyword matcher highlights)
    1721             :     ;;
    1722             :     ;; Fontify each item in `font-lock-keywords' from `start' to `end'.
    1723           0 :     (while keywords
    1724           0 :       (if loudly (message "Fontifying %s... (regexps..%s)" bufname
    1725           0 :                           (make-string (cl-incf count) ?.)))
    1726             :       ;;
    1727             :       ;; Find an occurrence of `matcher' from `start' to `end'.
    1728           0 :       (setq keyword (car keywords) matcher (car keyword))
    1729           0 :       (goto-char start)
    1730           0 :       (while (and (< (point) end)
    1731           0 :                   (if (stringp matcher)
    1732           0 :                       (re-search-forward matcher end t)
    1733           0 :                     (funcall matcher end))
    1734             :                   ;; Beware empty string matches since they will
    1735             :                   ;; loop indefinitely.
    1736           0 :                   (or (> (point) (match-beginning 0))
    1737           0 :                       (progn (forward-char 1) t)))
    1738           0 :         (when (and font-lock-multiline
    1739           0 :                    (>= (point)
    1740           0 :                        (save-excursion (goto-char (match-beginning 0))
    1741           0 :                                        (forward-line 1) (point))))
    1742             :           ;; this is a multiline regexp match
    1743             :           ;; (setq font-lock-multiline t)
    1744           0 :           (put-text-property (if (= (point)
    1745           0 :                                     (save-excursion
    1746           0 :                                       (goto-char (match-beginning 0))
    1747           0 :                                       (forward-line 1) (point)))
    1748           0 :                                  (1- (point))
    1749           0 :                                (match-beginning 0))
    1750           0 :                              (point)
    1751           0 :                              'font-lock-multiline t))
    1752             :         ;; Apply each highlight to this instance of `matcher', which may be
    1753             :         ;; specific highlights or more keywords anchored to `matcher'.
    1754           0 :         (setq highlights (cdr keyword))
    1755           0 :         (while highlights
    1756           0 :           (if (numberp (car (car highlights)))
    1757           0 :               (font-lock-apply-highlight (car highlights))
    1758           0 :             (set-marker pos (point))
    1759           0 :             (font-lock-fontify-anchored-keywords (car highlights) end)
    1760             :             ;; Ensure forward progress.  `pos' is a marker because anchored
    1761             :             ;; keyword may add/delete text (this happens e.g. in grep.el).
    1762           0 :             (if (< (point) pos) (goto-char pos)))
    1763           0 :           (setq highlights (cdr highlights))))
    1764           0 :       (setq keywords (cdr keywords)))
    1765           0 :     (set-marker pos nil)))
    1766             : 
    1767             : ;;; End of Keyword regexp fontification functions.
    1768             : 
    1769             : ;; Various functions.
    1770             : 
    1771             : (defun font-lock-compile-keywords (keywords &optional syntactic-keywords)
    1772             :   "Compile KEYWORDS into the form (t KEYWORDS COMPILED...)
    1773             : Here each COMPILED is of the form (MATCHER HIGHLIGHT ...) as shown in the
    1774             : `font-lock-keywords' doc string.
    1775             : If SYNTACTIC-KEYWORDS is non-nil, it means these keywords are used for
    1776             : `font-lock-syntactic-keywords' rather than for `font-lock-keywords'."
    1777          72 :   (if (not font-lock-set-defaults)
    1778             :       ;; This should never happen.  But some external packages sometimes
    1779             :       ;; call font-lock in unexpected and incorrect ways.  It's important to
    1780             :       ;; stop processing at this point, otherwise we may end up changing the
    1781             :       ;; global value of font-lock-keywords and break highlighting in many
    1782             :       ;; other buffers.
    1783          72 :       (error "Font-lock trying to use keywords before setting them up"))
    1784          72 :   (if (eq (car-safe keywords) t)
    1785           0 :       keywords
    1786          72 :     (setq keywords
    1787          72 :           (cons t (cons keywords
    1788          72 :                         (mapcar #'font-lock-compile-keyword keywords))))
    1789          72 :     (if (and (not syntactic-keywords)
    1790          72 :              (let ((beg-function syntax-begin-function))
    1791          72 :                (or (eq beg-function #'beginning-of-defun)
    1792          72 :                    (if (symbolp beg-function)
    1793          72 :                        (get beg-function 'font-lock-syntax-paren-check))))
    1794          72 :              (not beginning-of-defun-function))
    1795             :         ;; Try to detect when a string or comment contains something that
    1796             :         ;; looks like a defun and would thus confuse font-lock.
    1797           0 :         (nconc keywords
    1798           0 :                `((,(if defun-prompt-regexp
    1799           0 :                        (concat "^\\(?:" defun-prompt-regexp "\\)?\\s(")
    1800           0 :                      "^\\s(")
    1801             :                   (0
    1802             :                    (if (memq (get-text-property (match-beginning 0) 'face)
    1803             :                              '(font-lock-string-face font-lock-doc-face
    1804             :                                font-lock-comment-face))
    1805             :                        (list 'face font-lock-warning-face
    1806             :                              'help-echo "Looks like a toplevel defun: escape the parenthesis"))
    1807          72 :                    prepend)))))
    1808          72 :     keywords))
    1809             : 
    1810             : (defun font-lock-compile-keyword (keyword)
    1811        1166 :   (cond ((or (functionp keyword) (nlistp keyword)) ; MATCHER
    1812         194 :          (list keyword '(0 font-lock-keyword-face)))
    1813         972 :         ((eq (car keyword) 'eval)               ; (eval . FORM)
    1814           0 :          (font-lock-compile-keyword (eval (cdr keyword))))
    1815         972 :         ((eq (car-safe (cdr keyword)) 'quote)   ; (MATCHER . 'FORM)
    1816             :          ;; If FORM is a FACENAME then quote it.  Otherwise ignore the quote.
    1817           0 :          (if (symbolp (nth 2 keyword))
    1818           0 :              (list (car keyword) (list 0 (cdr keyword)))
    1819           0 :            (font-lock-compile-keyword (cons (car keyword) (nth 2 keyword)))))
    1820         972 :         ((numberp (cdr keyword))                ; (MATCHER . MATCH)
    1821          72 :          (list (car keyword) (list (cdr keyword) 'font-lock-keyword-face)))
    1822         900 :         ((symbolp (cdr keyword))                ; (MATCHER . FACENAME)
    1823          72 :          (list (car keyword) (list 0 (cdr keyword))))
    1824         828 :         ((nlistp (nth 1 keyword))               ; (MATCHER . HIGHLIGHT)
    1825         144 :          (list (car keyword) (cdr keyword)))
    1826             :         (t                                      ; (MATCHER HIGHLIGHT ...)
    1827        1166 :          keyword)))
    1828             : 
    1829             : (defun font-lock-eval-keywords (keywords)
    1830             :   "Evaluate KEYWORDS if a function (funcall) or variable (eval) name."
    1831          72 :   (if (listp keywords)
    1832          36 :       keywords
    1833          36 :     (font-lock-eval-keywords (if (fboundp keywords)
    1834           0 :                                  (funcall keywords)
    1835          72 :                                (eval keywords)))))
    1836             : 
    1837             : (defun font-lock-value-in-major-mode (values)
    1838             :   "If VALUES is an list, use `major-mode' as a key and return the `assq' value.
    1839             : VALUES should then be an alist on the form ((MAJOR-MODE . VALUE) ...) where
    1840             : MAJOR-MODE may be t.
    1841             : If VALUES isn't a list, return VALUES."
    1842          36 :   (if (consp values)
    1843           0 :       (cdr (or (assq major-mode values) (assq t values)))
    1844          36 :     values))
    1845             : 
    1846             : (defun font-lock-choose-keywords (keywords level)
    1847             :   "Return LEVELth element of KEYWORDS.
    1848             : A LEVEL of nil is equal to a LEVEL of 0, a LEVEL of t is equal to
    1849             : \(1- (length KEYWORDS))."
    1850          36 :   (cond ((not (and (listp keywords) (symbolp (car keywords))))
    1851           0 :          keywords)
    1852          36 :         ((numberp level)
    1853           0 :          (or (nth level keywords) (car (last keywords))))
    1854          36 :         ((eq level t)
    1855          36 :          (car (last keywords)))
    1856             :         (t
    1857          36 :          (car keywords))))
    1858             : 
    1859             : (defun font-lock-refresh-defaults ()
    1860             :   "Restart fontification in current buffer after recomputing from defaults.
    1861             : Recompute fontification variables using `font-lock-defaults' and
    1862             : `font-lock-maximum-decoration'.  Then restart fontification.
    1863             : 
    1864             : Use this function when you have changed any of the above
    1865             : variables directly.
    1866             : 
    1867             : Note: This function will erase modifications done by
    1868             : `font-lock-add-keywords' or `font-lock-remove-keywords', but will
    1869             : preserve `hi-lock-mode' highlighting patterns."
    1870           0 :   (font-lock-mode -1)
    1871           0 :   (kill-local-variable 'font-lock-set-defaults)
    1872           0 :   (font-lock-mode 1))
    1873             : 
    1874             : (defvar font-lock-major-mode nil
    1875             :   "Major mode for which the font-lock settings have been setup.")
    1876             : (make-variable-buffer-local 'font-lock-major-mode)
    1877             : 
    1878             : (defun font-lock-set-defaults ()
    1879             :   "Set fontification defaults appropriately for this mode.
    1880             : Sets various variables using `font-lock-defaults' and
    1881             : `font-lock-maximum-decoration'."
    1882             :   ;; Set fontification defaults if not previously set for correct major mode.
    1883         448 :   (unless (and font-lock-set-defaults
    1884         448 :                (eq font-lock-major-mode major-mode))
    1885          36 :     (setq font-lock-major-mode major-mode)
    1886          36 :     (setq font-lock-set-defaults t)
    1887          36 :     (let* ((defaults font-lock-defaults)
    1888             :            (keywords
    1889          36 :             (font-lock-choose-keywords (nth 0 defaults)
    1890          36 :                                        (font-lock-value-in-major-mode font-lock-maximum-decoration)))
    1891          36 :            (local (cdr (assq major-mode font-lock-keywords-alist)))
    1892             :            (removed-keywords
    1893          36 :             (cdr-safe (assq major-mode font-lock-removed-keywords-alist))))
    1894             :       ;; Syntactic fontification?
    1895          36 :       (if (nth 1 defaults)
    1896           0 :           (set (make-local-variable 'font-lock-keywords-only) t)
    1897          36 :         (kill-local-variable 'font-lock-keywords-only))
    1898             :       ;; Case fold during regexp fontification?
    1899          36 :       (if (nth 2 defaults)
    1900           0 :           (set (make-local-variable 'font-lock-keywords-case-fold-search) t)
    1901          36 :         (kill-local-variable 'font-lock-keywords-case-fold-search))
    1902             :       ;; Syntax table for regexp and syntactic fontification?
    1903          36 :       (if (null (nth 3 defaults))
    1904          36 :           (kill-local-variable 'font-lock-syntax-table)
    1905           0 :         (set (make-local-variable 'font-lock-syntax-table)
    1906           0 :              (copy-syntax-table (syntax-table)))
    1907           0 :         (dolist (selem (nth 3 defaults))
    1908             :           ;; The character to modify may be a single CHAR or a STRING.
    1909           0 :           (let ((syntax (cdr selem)))
    1910           0 :             (dolist (char (if (numberp (car selem))
    1911           0 :                               (list (car selem))
    1912           0 :                             (mapcar #'identity (car selem))))
    1913          36 :               (modify-syntax-entry char syntax font-lock-syntax-table)))))
    1914             :       ;; (nth 4 defaults) used to hold `font-lock-beginning-of-syntax-function',
    1915             :       ;; but that was removed in 25.1, so if it's a cons cell, we assume that
    1916             :       ;; it's part of the variable alist.
    1917             :       ;; Variable alist?
    1918          36 :       (dolist (x (nthcdr (if (consp (nth 4 defaults)) 4 5) defaults))
    1919         108 :         (set (make-local-variable (car x)) (cdr x)))
    1920             :       ;; Set up `font-lock-keywords' last because its value might depend
    1921             :       ;; on other settings.
    1922          36 :       (set (make-local-variable 'font-lock-keywords)
    1923          36 :            (font-lock-eval-keywords keywords))
    1924             :       ;; Local fontification?
    1925         224 :       (while local
    1926         188 :         (font-lock-add-keywords nil (car (car local)) (cdr (car local)))
    1927         188 :         (setq local (cdr local)))
    1928          36 :       (when removed-keywords
    1929          36 :         (font-lock-remove-keywords nil removed-keywords))
    1930             :       ;; Now compile the keywords.
    1931          36 :       (unless (eq (car font-lock-keywords) t)
    1932          36 :         (setq font-lock-keywords
    1933          36 :               (font-lock-compile-keywords font-lock-keywords))))
    1934         448 :     (font-lock-flush)))
    1935             : 
    1936             : ;;; Color etc. support.
    1937             : 
    1938             : ;; Note that `defface' will not overwrite any faces declared above via
    1939             : ;; `custom-declare-face'.
    1940             : (defface font-lock-comment-face
    1941             :   '((((class grayscale) (background light))
    1942             :      :foreground "DimGray" :weight bold :slant italic)
    1943             :     (((class grayscale) (background dark))
    1944             :      :foreground "LightGray" :weight bold :slant italic)
    1945             :     (((class color) (min-colors 88) (background light))
    1946             :      :foreground "Firebrick")
    1947             :     (((class color) (min-colors 88) (background dark))
    1948             :      :foreground "chocolate1")
    1949             :     (((class color) (min-colors 16) (background light))
    1950             :      :foreground "red")
    1951             :     (((class color) (min-colors 16) (background dark))
    1952             :      :foreground "red1")
    1953             :     (((class color) (min-colors 8) (background light))
    1954             :      :foreground "red")
    1955             :     (((class color) (min-colors 8) (background dark))
    1956             :      :foreground "yellow")
    1957             :     (t :weight bold :slant italic))
    1958             :   "Font Lock mode face used to highlight comments."
    1959             :   :group 'font-lock-faces)
    1960             : 
    1961             : (defface font-lock-comment-delimiter-face
    1962             :   '((default :inherit font-lock-comment-face))
    1963             :   "Font Lock mode face used to highlight comment delimiters."
    1964             :   :group 'font-lock-faces)
    1965             : 
    1966             : (defface font-lock-string-face
    1967             :   '((((class grayscale) (background light)) :foreground "DimGray" :slant italic)
    1968             :     (((class grayscale) (background dark))  :foreground "LightGray" :slant italic)
    1969             :     (((class color) (min-colors 88) (background light)) :foreground "VioletRed4")
    1970             :     (((class color) (min-colors 88) (background dark))  :foreground "LightSalmon")
    1971             :     (((class color) (min-colors 16) (background light)) :foreground "RosyBrown")
    1972             :     (((class color) (min-colors 16) (background dark))  :foreground "LightSalmon")
    1973             :     (((class color) (min-colors 8)) :foreground "green")
    1974             :     (t :slant italic))
    1975             :   "Font Lock mode face used to highlight strings."
    1976             :   :group 'font-lock-faces)
    1977             : 
    1978             : (defface font-lock-doc-face
    1979             :   '((t :inherit font-lock-string-face))
    1980             :   "Font Lock mode face used to highlight documentation."
    1981             :   :group 'font-lock-faces)
    1982             : 
    1983             : (defface font-lock-keyword-face
    1984             :   '((((class grayscale) (background light)) :foreground "LightGray" :weight bold)
    1985             :     (((class grayscale) (background dark))  :foreground "DimGray" :weight bold)
    1986             :     (((class color) (min-colors 88) (background light)) :foreground "Purple")
    1987             :     (((class color) (min-colors 88) (background dark))  :foreground "Cyan1")
    1988             :     (((class color) (min-colors 16) (background light)) :foreground "Purple")
    1989             :     (((class color) (min-colors 16) (background dark))  :foreground "Cyan")
    1990             :     (((class color) (min-colors 8)) :foreground "cyan" :weight bold)
    1991             :     (t :weight bold))
    1992             :   "Font Lock mode face used to highlight keywords."
    1993             :   :group 'font-lock-faces)
    1994             : 
    1995             : (defface font-lock-builtin-face
    1996             :   '((((class grayscale) (background light)) :foreground "LightGray" :weight bold)
    1997             :     (((class grayscale) (background dark))  :foreground "DimGray" :weight bold)
    1998             :     (((class color) (min-colors 88) (background light)) :foreground "dark slate blue")
    1999             :     (((class color) (min-colors 88) (background dark))  :foreground "LightSteelBlue")
    2000             :     (((class color) (min-colors 16) (background light)) :foreground "Orchid")
    2001             :     (((class color) (min-colors 16) (background dark)) :foreground "LightSteelBlue")
    2002             :     (((class color) (min-colors 8)) :foreground "blue" :weight bold)
    2003             :     (t :weight bold))
    2004             :   "Font Lock mode face used to highlight builtins."
    2005             :   :group 'font-lock-faces)
    2006             : 
    2007             : (defface font-lock-function-name-face
    2008             :   '((((class color) (min-colors 88) (background light)) :foreground "Blue1")
    2009             :     (((class color) (min-colors 88) (background dark))  :foreground "LightSkyBlue")
    2010             :     (((class color) (min-colors 16) (background light)) :foreground "Blue")
    2011             :     (((class color) (min-colors 16) (background dark))  :foreground "LightSkyBlue")
    2012             :     (((class color) (min-colors 8)) :foreground "blue" :weight bold)
    2013             :     (t :inverse-video t :weight bold))
    2014             :   "Font Lock mode face used to highlight function names."
    2015             :   :group 'font-lock-faces)
    2016             : 
    2017             : (defface font-lock-variable-name-face
    2018             :   '((((class grayscale) (background light))
    2019             :      :foreground "Gray90" :weight bold :slant italic)
    2020             :     (((class grayscale) (background dark))
    2021             :      :foreground "DimGray" :weight bold :slant italic)
    2022             :     (((class color) (min-colors 88) (background light)) :foreground "sienna")
    2023             :     (((class color) (min-colors 88) (background dark))  :foreground "LightGoldenrod")
    2024             :     (((class color) (min-colors 16) (background light)) :foreground "DarkGoldenrod")
    2025             :     (((class color) (min-colors 16) (background dark))  :foreground "LightGoldenrod")
    2026             :     (((class color) (min-colors 8)) :foreground "yellow" :weight light)
    2027             :     (t :weight bold :slant italic))
    2028             :   "Font Lock mode face used to highlight variable names."
    2029             :   :group 'font-lock-faces)
    2030             : 
    2031             : (defface font-lock-type-face
    2032             :   '((((class grayscale) (background light)) :foreground "Gray90" :weight bold)
    2033             :     (((class grayscale) (background dark))  :foreground "DimGray" :weight bold)
    2034             :     (((class color) (min-colors 88) (background light)) :foreground "ForestGreen")
    2035             :     (((class color) (min-colors 88) (background dark))  :foreground "PaleGreen")
    2036             :     (((class color) (min-colors 16) (background light)) :foreground "ForestGreen")
    2037             :     (((class color) (min-colors 16) (background dark))  :foreground "PaleGreen")
    2038             :     (((class color) (min-colors 8)) :foreground "green")
    2039             :     (t :weight bold :underline t))
    2040             :   "Font Lock mode face used to highlight type and classes."
    2041             :   :group 'font-lock-faces)
    2042             : 
    2043             : (defface font-lock-constant-face
    2044             :   '((((class grayscale) (background light))
    2045             :      :foreground "LightGray" :weight bold :underline t)
    2046             :     (((class grayscale) (background dark))
    2047             :      :foreground "Gray50" :weight bold :underline t)
    2048             :     (((class color) (min-colors 88) (background light)) :foreground "dark cyan")
    2049             :     (((class color) (min-colors 88) (background dark))  :foreground "Aquamarine")
    2050             :     (((class color) (min-colors 16) (background light)) :foreground "CadetBlue")
    2051             :     (((class color) (min-colors 16) (background dark))  :foreground "Aquamarine")
    2052             :     (((class color) (min-colors 8)) :foreground "magenta")
    2053             :     (t :weight bold :underline t))
    2054             :   "Font Lock mode face used to highlight constants and labels."
    2055             :   :group 'font-lock-faces)
    2056             : 
    2057             : (defface font-lock-warning-face
    2058             :   '((t :inherit error))
    2059             :   "Font Lock mode face used to highlight warnings."
    2060             :   :group 'font-lock-faces)
    2061             : 
    2062             : (defface font-lock-negation-char-face
    2063             :   '((t nil))
    2064             :   "Font Lock mode face used to highlight easy to overlook negation."
    2065             :   :group 'font-lock-faces)
    2066             : 
    2067             : (defface font-lock-preprocessor-face
    2068             :   '((t :inherit font-lock-builtin-face))
    2069             :   "Font Lock mode face used to highlight preprocessor directives."
    2070             :   :group 'font-lock-faces)
    2071             : 
    2072             : (defface font-lock-regexp-grouping-backslash
    2073             :   '((t :inherit bold))
    2074             :   "Font Lock mode face for backslashes in Lisp regexp grouping constructs."
    2075             :   :group 'font-lock-faces)
    2076             : 
    2077             : (defface font-lock-regexp-grouping-construct
    2078             :   '((t :inherit bold))
    2079             :   "Font Lock mode face used to highlight grouping constructs in Lisp regexps."
    2080             :   :group 'font-lock-faces)
    2081             : 
    2082             : ;;; End of Color etc. support.
    2083             : 
    2084             : ;;; Menu support.
    2085             : 
    2086             : ;; This section of code is commented out because Emacs does not have real menu
    2087             : ;; buttons.  (We can mimic them by putting "( ) " or "(X) " at the beginning of
    2088             : ;; the menu entry text, but with Xt it looks both ugly and embarrassingly
    2089             : ;; amateur.)  If/When Emacs gets real menus buttons, put in menu-bar.el after
    2090             : ;; the entry for "Text Properties" something like:
    2091             : ;;
    2092             : ;; (define-key menu-bar-edit-menu [font-lock]
    2093             : ;;   (cons "Syntax Highlighting" font-lock-menu))
    2094             : ;;
    2095             : ;; and remove a single ";" from the beginning of each line in the rest of this
    2096             : ;; section.  Probably the mechanism for telling the menu code what are menu
    2097             : ;; buttons and when they are on or off needs tweaking.  I have assumed that the
    2098             : ;; mechanism is via `menu-toggle' and `menu-selected' symbol properties.  sm.
    2099             : 
    2100             : ;;;;;###autoload
    2101             : ;;(progn
    2102             : ;;  ;; Make the Font Lock menu.
    2103             : ;;  (defvar font-lock-menu (make-sparse-keymap "Syntax Highlighting"))
    2104             : ;;  ;; Add the menu items in reverse order.
    2105             : ;;  (define-key font-lock-menu [fontify-less]
    2106             : ;;    '("Less In Current Buffer" . font-lock-fontify-less))
    2107             : ;;  (define-key font-lock-menu [fontify-more]
    2108             : ;;    '("More In Current Buffer" . font-lock-fontify-more))
    2109             : ;;  (define-key font-lock-menu [font-lock-sep]
    2110             : ;;    '("--"))
    2111             : ;;  (define-key font-lock-menu [font-lock-mode]
    2112             : ;;    '("In Current Buffer" . font-lock-mode))
    2113             : ;;  (define-key font-lock-menu [global-font-lock-mode]
    2114             : ;;    '("In All Buffers" . global-font-lock-mode)))
    2115             : ;;
    2116             : ;;;;;###autoload
    2117             : ;;(progn
    2118             : ;;  ;; We put the appropriate `menu-enable' etc. symbol property values on when
    2119             : ;;  ;; font-lock.el is loaded, so we don't need to autoload the three variables.
    2120             : ;;  (put 'global-font-lock-mode 'menu-toggle t)
    2121             : ;;  (put 'font-lock-mode 'menu-toggle t)
    2122             : ;;  (put 'font-lock-fontify-more 'menu-enable '(identity))
    2123             : ;;  (put 'font-lock-fontify-less 'menu-enable '(identity)))
    2124             : ;;
    2125             : ;; ;; Put the appropriate symbol property values on now.  See above.
    2126             : ;;(put 'global-font-lock-mode 'menu-selected 'global-font-lock-mode)
    2127             : ;;(put 'font-lock-mode 'menu-selected 'font-lock-mode)
    2128             : ;;(put 'font-lock-fontify-more 'menu-enable '(nth 2 font-lock-fontify-level))
    2129             : ;;(put 'font-lock-fontify-less 'menu-enable '(nth 1 font-lock-fontify-level))
    2130             : ;;
    2131             : ;;(defvar font-lock-fontify-level nil)  ; For less/more fontification.
    2132             : ;;
    2133             : ;;(defun font-lock-fontify-level (level)
    2134             : ;;  (let ((font-lock-maximum-decoration level))
    2135             : ;;    (when font-lock-mode
    2136             : ;;      (font-lock-mode))
    2137             : ;;    (font-lock-mode)
    2138             : ;;    (when font-lock-verbose
    2139             : ;;      (message "Fontifying %s... level %d" (buffer-name) level))))
    2140             : ;;
    2141             : ;;(defun font-lock-fontify-less ()
    2142             : ;;  "Fontify the current buffer with less decoration.
    2143             : ;;See `font-lock-maximum-decoration'."
    2144             : ;;  (interactive)
    2145             : ;;  ;; Check in case we get called interactively.
    2146             : ;;  (if (nth 1 font-lock-fontify-level)
    2147             : ;;      (font-lock-fontify-level (1- (car font-lock-fontify-level)))
    2148             : ;;    (error "No less decoration")))
    2149             : ;;
    2150             : ;;(defun font-lock-fontify-more ()
    2151             : ;;  "Fontify the current buffer with more decoration.
    2152             : ;;See `font-lock-maximum-decoration'."
    2153             : ;;  (interactive)
    2154             : ;;  ;; Check in case we get called interactively.
    2155             : ;;  (if (nth 2 font-lock-fontify-level)
    2156             : ;;      (font-lock-fontify-level (1+ (car font-lock-fontify-level)))
    2157             : ;;    (error "No more decoration")))
    2158             : ;;
    2159             : ;; ;; This should be called by `font-lock-set-defaults'.
    2160             : ;;(defun font-lock-set-menu ()
    2161             : ;;  ;; Activate less/more fontification entries if there are multiple levels for
    2162             : ;;  ;; the current buffer.  Sets `font-lock-fontify-level' to be of the form
    2163             : ;;  ;; (CURRENT-LEVEL IS-LOWER-LEVEL-P IS-HIGHER-LEVEL-P) for menu activation.
    2164             : ;;  (let ((keywords (nth 0 font-lock-defaults))
    2165             : ;;      (level (font-lock-value-in-major-mode font-lock-maximum-decoration)))
    2166             : ;;    (make-local-variable 'font-lock-fontify-level)
    2167             : ;;    (if (or (symbolp keywords) (= (length keywords) 1))
    2168             : ;;      (font-lock-unset-menu)
    2169             : ;;      (cond ((eq level t)
    2170             : ;;           (setq level (1- (length keywords))))
    2171             : ;;          ((or (null level) (zerop level))
    2172             : ;;           ;; The default level is usually, but not necessarily, level 1.
    2173             : ;;           (setq level (- (length keywords)
    2174             : ;;                          (length (member (eval (car keywords))
    2175             : ;;                                          (mapcar #'eval (cdr keywords))))))))
    2176             : ;;      (setq font-lock-fontify-level (list level (> level 1)
    2177             : ;;                                        (< level (1- (length keywords))))))))
    2178             : ;;
    2179             : ;; ;; This should be called by `font-lock-unset-defaults'.
    2180             : ;;(defun font-lock-unset-menu ()
    2181             : ;;  ;; Deactivate less/more fontification entries.
    2182             : ;;  (setq font-lock-fontify-level nil))
    2183             : 
    2184             : ;;; End of Menu support.
    2185             : 
    2186             : ;;; Various regexp information shared by several modes.
    2187             : ;; ;; Information specific to a single mode should go in its load library.
    2188             : 
    2189             : ;; Font Lock support for C, C++, Objective-C and Java modes is now in
    2190             : ;; cc-fonts.el (and required by cc-mode.el).  However, the below function
    2191             : ;; should stay in font-lock.el, since it is used by other libraries.  sm.
    2192             : 
    2193             : (defun font-lock-match-c-style-declaration-item-and-skip-to-next (limit)
    2194             :   "Match, and move over, any declaration/definition item after point.
    2195             : Matches after point, but ignores leading whitespace and `*' characters.
    2196             : Does not move further than LIMIT.
    2197             : 
    2198             : The expected syntax of a declaration/definition item is `word' (preceded by
    2199             : optional whitespace and `*' characters and proceeded by optional whitespace)
    2200             : optionally followed by a `('.  Everything following the item (but belonging to
    2201             : it) is expected to be skip-able by `scan-sexps', and items are expected to be
    2202             : separated with a `,' and to be terminated with a `;'.
    2203             : 
    2204             : Thus the regexp matches after point:    word (
    2205             :                                         ^^^^ ^
    2206             : Where the match subexpressions are:       1  2
    2207             : 
    2208             : The item is delimited by (match-beginning 1) and (match-end 1).
    2209             : If (match-beginning 2) is non-nil, the item is followed by a `('.
    2210             : 
    2211             : This function could be MATCHER in a MATCH-ANCHORED `font-lock-keywords' item."
    2212           0 :   (when (looking-at "[ \n\t*]*\\(\\sw+\\)[ \t\n]*\\(((?\\)?")
    2213           0 :     (when (and (match-end 2) (> (- (match-end 2) (match-beginning 2)) 1))
    2214             :       ;; If `word' is followed by a double open-paren, it's probably
    2215             :       ;; a macro used for "int myfun P_ ((int arg1))".  Let's go back one
    2216             :       ;; word to try and match `myfun' rather than `P_'.
    2217           0 :       (let ((pos (point)))
    2218           0 :         (skip-chars-backward " \t\n")
    2219           0 :         (skip-syntax-backward "w")
    2220           0 :         (unless (looking-at "\\(\\sw+\\)[ \t\n]*\\sw+[ \t\n]*\\(((?\\)?")
    2221             :           ;; Looks like it was something else, so go back to where we
    2222             :           ;; were and reset the match data by rematching.
    2223           0 :           (goto-char pos)
    2224           0 :           (looking-at "[ \n\t*]*\\(\\sw+\\)[ \t\n]*\\(((?\\)?"))))
    2225           0 :     (save-match-data
    2226           0 :       (condition-case nil
    2227           0 :           (save-restriction
    2228             :             ;; Restrict to the LIMIT.
    2229           0 :             (narrow-to-region (point-min) limit)
    2230           0 :             (goto-char (match-end 1))
    2231             :             ;; Move over any item value, etc., to the next item.
    2232           0 :             (while (not (looking-at "[ \t\n]*\\(\\(,\\)\\|;\\|\\'\\)"))
    2233           0 :               (goto-char (or (scan-sexps (point) 1) (point-max))))
    2234           0 :             (if (match-end 2)
    2235           0 :                 (goto-char (match-end 2))))
    2236           0 :         (error t)))))
    2237             : 
    2238             : ;; C preprocessor(cpp) is used outside of C, C++ and Objective-C source file.
    2239             : ;; e.g. assembler code and GNU linker script in Linux kernel.
    2240             : ;; `cpp-font-lock-keywords' is handy for modes for the files.
    2241             : ;;
    2242             : ;; Here we cannot use `regexp-opt' because because regex-opt is not preloaded
    2243             : ;; while font-lock.el is preloaded to emacs. So values pre-calculated with
    2244             : ;; regexp-opt are used here.
    2245             : 
    2246             : ;; `cpp-font-lock-keywords-source-directives' is calculated from:
    2247             : ;;
    2248             : ;;          (regexp-opt
    2249             : ;;           '("define"  "elif" "else" "endif" "error" "file" "if" "ifdef"
    2250             : ;;             "ifndef" "import" "include" "line" "pragma" "undef" "warning"))
    2251             : ;;
    2252             : (defconst cpp-font-lock-keywords-source-directives
    2253             :   "define\\|e\\(?:l\\(?:if\\|se\\)\\|ndif\\|rror\\)\\|file\\|i\\(?:f\\(?:n?def\\)?\\|mport\\|nclude\\)\\|line\\|pragma\\|undef\\|warning"
    2254             :   "Regular expression used in `cpp-font-lock-keywords'.")
    2255             : 
    2256             : ;; `cpp-font-lock-keywords-source-depth' is calculated from:
    2257             : ;;
    2258             : ;;          (regexp-opt-depth (regexp-opt
    2259             : ;;                     '("define"  "elif" "else" "endif" "error" "file" "if" "ifdef"
    2260             : ;;                       "ifndef" "import" "include" "line" "pragma" "undef" "warning")))
    2261             : ;;
    2262             : (defconst cpp-font-lock-keywords-source-depth 0
    2263             :   "An integer representing regular expression depth of `cpp-font-lock-keywords-source-directives'.
    2264             : Used in `cpp-font-lock-keywords'.")
    2265             : 
    2266             : (defconst cpp-font-lock-keywords
    2267             :   (let* ((directives cpp-font-lock-keywords-source-directives)
    2268             :          (directives-depth cpp-font-lock-keywords-source-depth))
    2269             :     (list
    2270             :      ;;
    2271             :      ;; Fontify error directives.
    2272             :      '("^#[ \t]*\\(?:error\\|warning\\)[ \t]+\\(.+\\)" 1 font-lock-warning-face prepend)
    2273             :      ;;
    2274             :      ;; Fontify filenames in #include <...> preprocessor directives as strings.
    2275             :      '("^#[ \t]*\\(?:import\\|include\\)[ \t]*\\(<[^>\"\n]*>?\\)"
    2276             :        1 font-lock-string-face prepend)
    2277             :      ;;
    2278             :      ;; Fontify function macro names.
    2279             :      '("^#[ \t]*define[ \t]+\\([[:alpha:]_][[:alnum:]_$]*\\)("
    2280             :        (1 font-lock-function-name-face prepend)
    2281             :        ;;
    2282             :        ;; Macro arguments.
    2283             :        ((lambda (limit)
    2284             :           (re-search-forward
    2285             :            "\\(?:\\([[:alpha:]_][[:alnum:]_]*\\)[,]?\\)"
    2286             :            (or (save-excursion (re-search-forward ")" limit t))
    2287             :                limit)
    2288             :            t))
    2289             :         nil nil (1 font-lock-variable-name-face prepend)))
    2290             :      ;;
    2291             :      ;; Fontify symbol names in #elif or #if ... defined preprocessor directives.
    2292             :      '("^#[ \t]*\\(?:elif\\|if\\)\\>"
    2293             :        ("\\<\\(defined\\)\\>[ \t]*(?\\([[:alpha:]_][[:alnum:]_]*\\)?" nil nil
    2294             :         (1 font-lock-builtin-face prepend) (2 font-lock-variable-name-face prepend t)))
    2295             :      ;;
    2296             :      ;; Fontify otherwise as symbol names, and the preprocessor directive names.
    2297             :      (list
    2298             :       (concat "^\\(#[ \t]*\\(?:" directives
    2299             :               "\\)\\)\\>[ \t!]*\\([[:alpha:]_][[:alnum:]_]*\\)?")
    2300             :       '(1 font-lock-preprocessor-face prepend)
    2301             :       (list (+ 2 directives-depth)
    2302             :             'font-lock-variable-name-face nil t))))
    2303             :   "Font lock keywords for C preprocessor directives.
    2304             : `c-mode', `c++-mode' and `objc-mode' have their own font lock keywords
    2305             : for C preprocessor directives.  This definition is for the other modes
    2306             : in which C preprocessor directives are used. e.g. `asm-mode' and
    2307             : `ld-script-mode'.")
    2308             : 
    2309             : (provide 'font-lock)
    2310             : 
    2311             : ;;; font-lock.el ends here

Generated by: LCOV version 1.12