elisp: Search-based Fontification

 
 22.6.2 Search-based Fontification
 ---------------------------------
 
 The variable which directly controls search-based fontification is
 ‘font-lock-keywords’, which is typically specified via the KEYWORDS
 element in ‘font-lock-defaults’.
 
  -- Variable: font-lock-keywords
      The value of this variable is a list of the keywords to highlight.
      Lisp programs should not set this variable directly.  Normally, the
      value is automatically set by Font Lock mode, using the KEYWORDS
      element in ‘font-lock-defaults’.  The value can also be altered
      using the functions ‘font-lock-add-keywords’ and
      ‘font-lock-remove-keywords’ (SeeCustomizing Keywords).
 
    Each element of ‘font-lock-keywords’ specifies how to find certain
 cases of text, and how to highlight those cases.  Font Lock mode
 processes the elements of ‘font-lock-keywords’ one by one, and for each
 element, it finds and handles all matches.  Ordinarily, once part of the
 text has been fontified already, this cannot be overridden by a
 subsequent match in the same text; but you can specify different
 behavior using the OVERRIDE element of a SUBEXP-HIGHLIGHTER.
 
    Each element of ‘font-lock-keywords’ should have one of these forms:
 
 ‘REGEXP’
      Highlight all matches for REGEXP using ‘font-lock-keyword-face’.
      For example,
 
           ;; Highlight occurrences of the word ‘foo’
           ;; using ‘font-lock-keyword-face’.
           "\\<foo\\>"
 
      Be careful when composing these regular expressions; a poorly
      written pattern can dramatically slow things down!  The function
      ‘regexp-opt’ (SeeRegexp Functions) is useful for calculating
      optimal regular expressions to match several keywords.
 
 ‘FUNCTION’
      Find text by calling FUNCTION, and highlight the matches it finds
      using ‘font-lock-keyword-face’.
 
      When FUNCTION is called, it receives one argument, the limit of the
      search; it should begin searching at point, and not search beyond
      the limit.  It should return non-‘nil’ if it succeeds, and set the
      match data to describe the match that was found.  Returning ‘nil’
      indicates failure of the search.
 
      Fontification will call FUNCTION repeatedly with the same limit,
      and with point where the previous invocation left it, until
      FUNCTION fails.  On failure, FUNCTION need not reset point in any
      particular way.
 
 ‘(MATCHER . SUBEXP)’
      In this kind of element, MATCHER is either a regular expression or
      a function, as described above.  The CDR, SUBEXP, specifies which
      subexpression of MATCHER should be highlighted (instead of the
      entire text that MATCHER matched).
 
           ;; Highlight the ‘bar’ in each occurrence of ‘fubar’,
           ;; using ‘font-lock-keyword-face’.
           ("fu\\(bar\\)" . 1)
 
      If you use ‘regexp-opt’ to produce the regular expression MATCHER,
      you can use ‘regexp-opt-depth’ (SeeRegexp Functions) to
      calculate the value for SUBEXP.
 
 ‘(MATCHER . FACESPEC)’
      In this kind of element, FACESPEC is an expression whose value
      specifies the face to use for highlighting.  In the simplest case,
      FACESPEC is a Lisp variable (a symbol) whose value is a face name.
 
           ;; Highlight occurrences of ‘fubar’,
           ;; using the face which is the value of ‘fubar-face’.
           ("fubar" . fubar-face)
 
      However, FACESPEC can also evaluate to a list of this form:
 
           (face FACE PROP1 VAL1 PROP2 VAL2...)
 
      to specify the face FACE and various additional text properties to
      put on the text that matches.  If you do this, be sure to add the
      other text property names that you set in this way to the value of
      ‘font-lock-extra-managed-props’ so that the properties will also be
      cleared out when they are no longer appropriate.  Alternatively,
      you can set the variable ‘font-lock-unfontify-region-function’ to a
      function that clears these properties.  SeeOther Font Lock
      Variables.
 
 ‘(MATCHER . SUBEXP-HIGHLIGHTER)’
      In this kind of element, SUBEXP-HIGHLIGHTER is a list which
      specifies how to highlight matches found by MATCHER.  It has the
      form:
 
           (SUBEXP FACESPEC [OVERRIDE [LAXMATCH]])
 
      The CAR, SUBEXP, is an integer specifying which subexpression of
      the match to fontify (0 means the entire matching text).  The
      second subelement, FACESPEC, is an expression whose value specifies
      the face, as described above.
 
      The last two values in SUBEXP-HIGHLIGHTER, OVERRIDE and LAXMATCH,
      are optional flags.  If OVERRIDE is ‘t’, this element can override
      existing fontification made by previous elements of
      ‘font-lock-keywords’.  If it is ‘keep’, then each character is
      fontified if it has not been fontified already by some other
      element.  If it is ‘prepend’, the face specified by FACESPEC is
      added to the beginning of the ‘font-lock-face’ property.  If it is
      ‘append’, the face is added to the end of the ‘font-lock-face’
      property.
 
      If LAXMATCH is non-‘nil’, it means there should be no error if
      there is no subexpression numbered SUBEXP in MATCHER.  Obviously,
      fontification of the subexpression numbered SUBEXP will not occur.
      However, fontification of other subexpressions (and other regexps)
      will continue.  If LAXMATCH is ‘nil’, and the specified
      subexpression is missing, then an error is signaled which
      terminates search-based fontification.
 
      Here are some examples of elements of this kind, and what they do:
 
           ;; Highlight occurrences of either ‘foo’ or ‘bar’, using
           ;; ‘foo-bar-face’, even if they have already been highlighted.
           ;; ‘foo-bar-face’ should be a variable whose value is a face.
           ("foo\\|bar" 0 foo-bar-face t)
 
           ;; Highlight the first subexpression within each occurrence
           ;; that the function ‘fubar-match’ finds,
           ;; using the face which is the value of ‘fubar-face’.
           (fubar-match 1 fubar-face)
 
 ‘(MATCHER . ANCHORED-HIGHLIGHTER)’
      In this kind of element, ANCHORED-HIGHLIGHTER specifies how to
      highlight text that follows a match found by MATCHER.  So a match
      found by MATCHER acts as the anchor for further searches specified
      by ANCHORED-HIGHLIGHTER.  ANCHORED-HIGHLIGHTER is a list of the
      following form:
 
           (ANCHORED-MATCHER PRE-FORM POST-FORM
                                   SUBEXP-HIGHLIGHTERS...)
 
      Here, ANCHORED-MATCHER, like MATCHER, is either a regular
      expression or a function.  After a match of MATCHER is found, point
      is at the end of the match.  Now, Font Lock evaluates the form
      PRE-FORM.  Then it searches for matches of ANCHORED-MATCHER and
      uses SUBEXP-HIGHLIGHTERS to highlight these.  A SUBEXP-HIGHLIGHTER
      is as described above.  Finally, Font Lock evaluates POST-FORM.
 
      The forms PRE-FORM and POST-FORM can be used to initialize before,
      and cleanup after, ANCHORED-MATCHER is used.  Typically, PRE-FORM
      is used to move point to some position relative to the match of
      MATCHER, before starting with ANCHORED-MATCHER.  POST-FORM might be
      used to move back, before resuming with MATCHER.
 
      After Font Lock evaluates PRE-FORM, it does not search for
      ANCHORED-MATCHER beyond the end of the line.  However, if PRE-FORM
      returns a buffer position that is greater than the position of
      point after PRE-FORM is evaluated, then the position returned by
      PRE-FORM is used as the limit of the search instead.  It is
      generally a bad idea to return a position greater than the end of
      the line; in other words, the ANCHORED-MATCHER search should not
      span lines.
 
      For example,
 
           ;; Highlight occurrences of the word ‘item’ following
           ;; an occurrence of the word ‘anchor’ (on the same line)
           ;; in the value of ‘item-face’.
           ("\\<anchor\\>" "\\<item\\>" nil nil (0 item-face))
 
      Here, PRE-FORM and POST-FORM are ‘nil’.  Therefore searching for
      ‘item’ starts at the end of the match of ‘anchor’, and searching
      for subsequent instances of ‘anchor’ resumes from where searching
      for ‘item’ concluded.
 
 ‘(MATCHER HIGHLIGHTERS...)’
      This sort of element specifies several HIGHLIGHTER lists for a
      single MATCHER.  A HIGHLIGHTER list can be of the type
      SUBEXP-HIGHLIGHTER or ANCHORED-HIGHLIGHTER as described above.
 
      For example,
 
           ;; Highlight occurrences of the word ‘anchor’ in the value
           ;; of ‘anchor-face’, and subsequent occurrences of the word
           ;; ‘item’ (on the same line) in the value of ‘item-face’.
           ("\\<anchor\\>" (0 anchor-face)
                           ("\\<item\\>" nil nil (0 item-face)))
 
 ‘(eval . FORM)’
      Here FORM is an expression to be evaluated the first time this
      value of ‘font-lock-keywords’ is used in a buffer.  Its value
      should have one of the forms described in this table.
 
    *Warning:* Do not design an element of ‘font-lock-keywords’ to match
 text which spans lines; this does not work reliably.  For details, see
 SeeMultiline Font Lock.
 
    You can use CASE-FOLD in ‘font-lock-defaults’ to specify the value of
 ‘font-lock-keywords-case-fold-search’ which says whether search-based
 fontification should be case-insensitive.
 
  -- Variable: font-lock-keywords-case-fold-search
      Non-‘nil’ means that regular expression matching for the sake of
      ‘font-lock-keywords’ should be case-insensitive.