]> code.delx.au - gnu-emacs/blobdiff - lisp/font-lock.el
Use grep-find-ignored-directories instead of vc-directory-exclusion-list
[gnu-emacs] / lisp / font-lock.el
index 6ec6c9f11964cd111c391254fe93e9621417f55e..8ee9f69fc1a8a19094e54280eef0a757e7465636 100644 (file)
@@ -1,6 +1,6 @@
 ;;; font-lock.el --- Electric font lock mode
 
 ;;; font-lock.el --- Electric font lock mode
 
-;; Copyright (C) 1992-2015 Free Software Foundation, Inc.
+;; Copyright (C) 1992-2016 Free Software Foundation, Inc.
 
 ;; Author: Jamie Zawinski
 ;;     Richard Stallman
 
 ;; Author: Jamie Zawinski
 ;;     Richard Stallman
@@ -364,105 +364,125 @@ Each element in a user-level keywords list should have one of these forms:
  (MATCHER HIGHLIGHT ...)
  (eval . FORM)
 
  (MATCHER HIGHLIGHT ...)
  (eval . FORM)
 
-where MATCHER can be either the regexp to search for, or the function name to
-call to make the search (called with one argument, the limit of the search;
-it should return non-nil, move point, and set `match-data' appropriately if
-it succeeds; like `re-search-forward' would).
-MATCHER regexps can be generated via the function `regexp-opt'.
+where MATCHER can be either the regexp to search for, or the
+function name to call to make the search (called with one
+argument, the limit of the search; it should return non-nil, move
+point, and set `match-data' appropriately if it succeeds; like
+`re-search-forward' would).  MATCHER regexps can be generated via
+the function `regexp-opt'.
 
 
-FORM is an expression, whose value should be a keyword element, evaluated when
-the keyword is (first) used in a buffer.  This feature can be used to provide a
-keyword that can only be generated when Font Lock mode is actually turned on.
+FORM is an expression, whose value should be a keyword element,
+evaluated when the keyword is (first) used in a buffer.  This
+feature can be used to provide a keyword that can only be
+generated when Font Lock mode is actually turned on.
 
 HIGHLIGHT should be either MATCH-HIGHLIGHT or MATCH-ANCHORED.
 
 
 HIGHLIGHT should be either MATCH-HIGHLIGHT or MATCH-ANCHORED.
 
-For highlighting single items, for example each instance of the word \"foo\",
-typically only MATCH-HIGHLIGHT is required.
-However, if an item or (typically) items are to be highlighted following the
-instance of another item (the anchor), for example each instance of the
-word \"bar\" following the word \"anchor\" then MATCH-ANCHORED may be required.
+For highlighting single items, for example each instance of the
+word \"foo\", typically only MATCH-HIGHLIGHT is required.
+However, if an item or (typically) items are to be highlighted
+following the instance of another item (the anchor), for example
+each instance of the word \"bar\" following the word \"anchor\"
+then MATCH-ANCHORED may be required.
 
 MATCH-HIGHLIGHT should be of the form:
 
  (SUBEXP FACENAME [OVERRIDE [LAXMATCH]])
 
 
 MATCH-HIGHLIGHT should be of the form:
 
  (SUBEXP FACENAME [OVERRIDE [LAXMATCH]])
 
-SUBEXP is the number of the subexpression of MATCHER to be highlighted.
+SUBEXP is the number of the subexpression of MATCHER to be
+highlighted.
 
 FACENAME is an expression whose value is the face name to use.
 
 FACENAME is an expression whose value is the face name to use.
-Instead of a face, FACENAME can evaluate to a property list
-of the form (face FACE PROP1 VAL1 PROP2 VAL2 ...)
-in which case all the listed text-properties will be set rather than
-just FACE.  In such a case, you will most likely want to put those
-properties in `font-lock-extra-managed-props' or to override
+Instead of a face, FACENAME can evaluate to a property list of
+the form (face FACE PROP1 VAL1 PROP2 VAL2 ...)  in which case all
+the listed text-properties will be set rather than just FACE.  In
+such a case, you will most likely want to put those properties in
+`font-lock-extra-managed-props' or to override
 `font-lock-unfontify-region-function'.
 
 `font-lock-unfontify-region-function'.
 
-OVERRIDE and LAXMATCH are flags.  If OVERRIDE is t, existing fontification can
-be overwritten.  If `keep', only parts not already fontified are highlighted.
-If `prepend' or `append', existing fontification is merged with the new, in
-which the new or existing fontification, respectively, takes precedence.
-If LAXMATCH is non-nil, that means don't signal an error if there is
+OVERRIDE and LAXMATCH are flags.  If OVERRIDE is t, existing
+fontification can be overwritten.  If `keep', only parts not
+already fontified are highlighted.  If `prepend' or `append',
+existing fontification is merged with the new, in which the new
+or existing fontification, respectively, takes precedence.  If
+LAXMATCH is non-nil, that means don't signal an error if there is
 no match for SUBEXP in MATCHER.
 
 no match for SUBEXP in MATCHER.
 
-For example, an element of the form highlights (if not already highlighted):
+For example, an element of the form highlights (if not already
+highlighted):
+
+ \"\\\\\\=<foo\\\\\\=>\"
+  Discrete occurrences of \"foo\" in the value of the variable
+  `font-lock-keyword-face'.
+
+ (\"fu\\\\(bar\\\\)\" . 1)
+  Substring \"bar\" within all occurrences of \"fubar\" in the
+  value of `font-lock-keyword-face'.
+
+ (\"fubar\" . fubar-face)
+  Occurrences of \"fubar\" in the value of `fubar-face'.
 
 
- \"\\\\\\=<foo\\\\\\=>\"               discrete occurrences of \"foo\" in the value of the
-                       variable `font-lock-keyword-face'.
- (\"fu\\\\(bar\\\\)\" . 1)     substring \"bar\" within all occurrences of \"fubar\" in
-                       the value of `font-lock-keyword-face'.
- (\"fubar\" . fubar-face)      Occurrences of \"fubar\" in the value of `fubar-face'.
  (\"foo\\\\|bar\" 0 foo-bar-face t)
  (\"foo\\\\|bar\" 0 foo-bar-face t)
-                       occurrences of either \"foo\" or \"bar\" in the value
-                       of `foo-bar-face', even if already highlighted.
+  Occurrences of either \"foo\" or \"bar\" in the value of
+  `foo-bar-face', even if already highlighted.
+
  (fubar-match 1 fubar-face)
  (fubar-match 1 fubar-face)
-                       the first subexpression within all occurrences of
-                       whatever the function `fubar-match' finds and matches
-                       in the value of `fubar-face'.
+  The first subexpression within all occurrences of whatever the
+  function `fubar-match' finds and matches in the value of
+  `fubar-face'.
 
 MATCH-ANCHORED should be of the form:
 
  (MATCHER PRE-MATCH-FORM POST-MATCH-FORM MATCH-HIGHLIGHT ...)
 
 
 MATCH-ANCHORED should be of the form:
 
  (MATCHER PRE-MATCH-FORM POST-MATCH-FORM MATCH-HIGHLIGHT ...)
 
-where MATCHER is a regexp to search for or the function name to call to make
-the search, as for MATCH-HIGHLIGHT above, but with one exception; see below.
-PRE-MATCH-FORM and POST-MATCH-FORM are evaluated before the first, and after
-the last, instance MATCH-ANCHORED's MATCHER is used.  Therefore they can be
-used to initialize before, and cleanup after, MATCHER is used.  Typically,
-PRE-MATCH-FORM is used to move to some position relative to the original
-MATCHER, before starting with MATCH-ANCHORED's MATCHER.  POST-MATCH-FORM might
-be used to move back, before resuming with MATCH-ANCHORED's parent's MATCHER.
-
-For example, an element of the form highlights (if not already highlighted):
-
- (\"\\\\\\=<anchor\\\\\\=>\" (0 anchor-face) (\"\\\\\\=<item\\\\\\=>\" nil nil (0 item-face)))
-
- discrete occurrences of \"anchor\" in the value of `anchor-face', and subsequent
- discrete occurrences of \"item\" (on the same line) in the value of `item-face'.
- (Here PRE-MATCH-FORM and POST-MATCH-FORM are nil.  Therefore \"item\" is
- initially searched for starting from the end of the match of \"anchor\", and
- searching for subsequent instances of \"anchor\" resumes from where searching
- for \"item\" concluded.)
-
-The above-mentioned exception is as follows.  The limit of the MATCHER search
-defaults to the end of the line after PRE-MATCH-FORM is evaluated.
-However, if PRE-MATCH-FORM returns a position greater than the position after
-PRE-MATCH-FORM is evaluated, that position is used as the limit of the search.
-It is generally a bad idea to return a position greater than the end of the
-line, i.e., cause the MATCHER search to span lines.
-
-These regular expressions can match text which spans lines, although
-it is better to avoid it if possible since updating them while editing
-text is slower, and it is not guaranteed to be always correct when using
-support modes like jit-lock or lazy-lock.
-
-This variable is set by major modes via the variable `font-lock-defaults'.
-Be careful when composing regexps for this list; a poorly written pattern can
-dramatically slow things down!
-
-A compiled keywords list starts with t.  It is produced internally
-by `font-lock-compile-keywords' from a user-level keywords list.
-Its second element is the user-level keywords list that was
-compiled.  The remaining elements have the same form as
-user-level keywords, but normally their values have been
+where MATCHER is a regexp to search for or the function name to
+call to make the search, as for MATCH-HIGHLIGHT above, but with
+one exception; see below.  PRE-MATCH-FORM and POST-MATCH-FORM are
+evaluated before the first, and after the last, instance
+MATCH-ANCHORED's MATCHER is used.  Therefore they can be used to
+initialize before, and cleanup after, MATCHER is used.
+Typically, PRE-MATCH-FORM is used to move to some position
+relative to the original MATCHER, before starting with
+MATCH-ANCHORED's MATCHER.  POST-MATCH-FORM might be used to move
+back, before resuming with MATCH-ANCHORED's parent's MATCHER.
+
+For example, an element of the form highlights (if not already
+highlighted):
+
+ (\"\\\\\\=<anchor\\\\\\=>\" (0 anchor-face)
+  (\"\\\\\\=<item\\\\\\=>\" nil nil (0 item-face)))
+
+  Discrete occurrences of \"anchor\" in the value of
+  `anchor-face', and subsequent discrete occurrences of
+  \"item\" (on the same line) in the value of `item-face'.
+  (Here PRE-MATCH-FORM and POST-MATCH-FORM are nil.  Therefore
+  \"item\" is initially searched for starting from the end of the
+  match of \"anchor\", and searching for subsequent instances of
+  \"anchor\" resumes from where searching for \"item\" concluded.)
+
+The above-mentioned exception is as follows.  The limit of the
+MATCHER search defaults to the end of the line after
+PRE-MATCH-FORM is evaluated.  However, if PRE-MATCH-FORM returns
+a position greater than the position after PRE-MATCH-FORM is
+evaluated, that position is used as the limit of the search.  It
+is generally a bad idea to return a position greater than the end
+of the line, i.e., cause the MATCHER search to span lines.
+
+These regular expressions can match text which spans lines,
+although it is better to avoid it if possible since updating them
+while editing text is slower, and it is not guaranteed to be
+always correct when using support modes like jit-lock or
+lazy-lock.
+
+This variable is set by major modes via the variable
+`font-lock-defaults'.  Be careful when composing regexps for this
+list; a poorly written pattern can dramatically slow things down!
+
+A compiled keywords list starts with t.  It is produced
+internally by `font-lock-compile-keywords' from a user-level
+keywords list.  Its second element is the user-level keywords
+list that was compiled.  The remaining elements have the same
+form as user-level keywords, but normally their values have been
 optimized.")
 
 (defvar font-lock-keywords-alist nil
 optimized.")
 
 (defvar font-lock-keywords-alist nil
@@ -538,12 +558,13 @@ and what they do:
  dollar-sign character.  Hash characters in other contexts will still
  follow whatever the syntax table says about the hash character.
 
  dollar-sign character.  Hash characters in other contexts will still
  follow whatever the syntax table says about the hash character.
 
- (\"\\\\('\\\\).\\\\('\\\\)\"
+ (\"\\\\(\\='\\\\).\\\\(\\='\\\\)\"
   (1 \"\\\"\")
   (2 \"\\\"\"))
 
   (1 \"\\\"\")
   (2 \"\\\"\"))
 
- gives a pair single-quotes, which surround a single character, a SYNTAX of
- \"\\\"\" (meaning string quote syntax).  Single-quote characters in other
+ gives a pair of apostrophes, which surround a single character, a
+ SYNTAX of \"\\\"\" (meaning string quote syntax).  Apostrophes in other
+
  contexts will not be affected.
 
 This is normally set via `font-lock-defaults'.")
  contexts will not be affected.
 
 This is normally set via `font-lock-defaults'.")
@@ -555,21 +576,6 @@ This is normally set via `font-lock-defaults'.")
 If this is nil, the major mode's syntax table is used.
 This is normally set via `font-lock-defaults'.")
 
 If this is nil, the major mode's syntax table is used.
 This is normally set via `font-lock-defaults'.")
 
-(defvar font-lock-beginning-of-syntax-function nil
-  "Non-nil means use this function to move back outside all constructs.
-When called with no args it should move point backward to a place which
-is not in a string or comment and not within any bracket-pairs (or else,
-a place such that any bracket-pairs outside it can be ignored for Emacs
-syntax analysis and fontification).
-
-If this is nil, Font Lock uses `syntax-begin-function' to move back
-outside of any comment, string, or sexp.  This variable is semi-obsolete;
-we recommend setting `syntax-begin-function' instead.
-
-This is normally set via `font-lock-defaults'.")
-(make-obsolete-variable 'font-lock-beginning-of-syntax-function
-                        'syntax-begin-function "23.3" 'set)
-
 (defvar font-lock-mark-block-function nil
   "Non-nil means use this function to mark a block of text.
 When called with no args it should leave point at the beginning of any
 (defvar font-lock-mark-block-function nil
   "Non-nil means use this function to mark a block of text.
 When called with no args it should leave point at the beginning of any
@@ -585,11 +591,14 @@ This is normally set via `font-lock-defaults'.")
 This is used when turning off Font Lock mode.
 This is normally set via `font-lock-defaults'.")
 
 This is used when turning off Font Lock mode.
 This is normally set via `font-lock-defaults'.")
 
-(defvar font-lock-fontify-region-function 'font-lock-default-fontify-region
+(defvar font-lock-fontify-region-function #'font-lock-default-fontify-region
   "Function to use for fontifying a region.
 It should take two args, the beginning and end of the region, and an optional
 third arg VERBOSE.  If VERBOSE is non-nil, the function should print status
   "Function to use for fontifying a region.
 It should take two args, the beginning and end of the region, and an optional
 third arg VERBOSE.  If VERBOSE is non-nil, the function should print status
-messages.  This is normally set via `font-lock-defaults'.")
+messages.  This is normally set via `font-lock-defaults'.
+If it fontifies a larger region, it should ideally return a list of the form
+\(jit-lock-bounds BEG . END) indicating the bounds of the region actually
+fontified.")
 
 (defvar font-lock-unfontify-region-function 'font-lock-default-unfontify-region
   "Function to use for unfontifying a region.
 
 (defvar font-lock-unfontify-region-function 'font-lock-default-unfontify-region
   "Function to use for unfontifying a region.
@@ -600,6 +609,7 @@ This is normally set via `font-lock-defaults'.")
   "List of Font Lock mode related modes that should not be turned on.
 Currently, valid mode names are `fast-lock-mode', `jit-lock-mode' and
 `lazy-lock-mode'.  This is normally set via `font-lock-defaults'.")
   "List of Font Lock mode related modes that should not be turned on.
 Currently, valid mode names are `fast-lock-mode', `jit-lock-mode' and
 `lazy-lock-mode'.  This is normally set via `font-lock-defaults'.")
+(make-obsolete-variable 'font-lock-inhibit-thing-lock nil "25.1")
 
 (defvar-local font-lock-multiline nil
   "Whether font-lock should cater to multiline keywords.
 
 (defvar-local font-lock-multiline nil
   "Whether font-lock should cater to multiline keywords.
@@ -679,9 +689,9 @@ end of the current highlighting list.
 
 For example:
 
 
 For example:
 
- (font-lock-add-keywords 'c-mode
-  '((\"\\\\\\=<\\\\(FIXME\\\\):\" 1 'font-lock-warning-face prepend)
-    (\"\\\\\\=<\\\\(and\\\\|or\\\\|not\\\\)\\\\\\=>\" . 'font-lock-keyword-face)))
+ (font-lock-add-keywords \\='c-mode
+  \\='((\"\\\\\\=<\\\\(FIXME\\\\):\" 1 \\='font-lock-warning-face prepend)
+    (\"\\\\\\=<\\\\(and\\\\|or\\\\|not\\\\)\\\\\\=>\" . \\='font-lock-keyword-face)))
 
 adds two fontification patterns for C mode, to fontify `FIXME:' words, even in
 comments, and to fontify `and', `or' and `not' words as keywords.
 
 adds two fontification patterns for C mode, to fontify `FIXME:' words, even in
 comments, and to fontify `and', `or' and `not' words as keywords.
@@ -692,12 +702,12 @@ pass nil for MODE and add the call to c-mode-hook.
 
 For example:
 
 
 For example:
 
- (add-hook 'c-mode-hook
+ (add-hook \\='c-mode-hook
   (lambda ()
    (font-lock-add-keywords nil
   (lambda ()
    (font-lock-add-keywords nil
-    '((\"\\\\\\=<\\\\(FIXME\\\\):\" 1 'font-lock-warning-face prepend)
+    \\='((\"\\\\\\=<\\\\(FIXME\\\\):\" 1 \\='font-lock-warning-face prepend)
       (\"\\\\\\=<\\\\(and\\\\|or\\\\|not\\\\)\\\\\\=>\" .
       (\"\\\\\\=<\\\\(and\\\\|or\\\\|not\\\\)\\\\\\=>\" .
-       'font-lock-keyword-face)))))
+       \\='font-lock-keyword-face)))))
 
 The above procedure may fail to add keywords to derived modes if
 some involved major mode does not follow the standard conventions.
 
 The above procedure may fail to add keywords to derived modes if
 some involved major mode does not follow the standard conventions.
@@ -773,7 +783,7 @@ see the variables `c-font-lock-extra-types', `c++-font-lock-extra-types',
              (setq font-lock-removed-keywords-alist
                    (delq cell font-lock-removed-keywords-alist)))))))
 
              (setq font-lock-removed-keywords-alist
                    (delq cell font-lock-removed-keywords-alist)))))))
 
-;; Written by Anders Lindgren <andersl@andersl.com>.
+;; Written by Anders Lindgren
 ;;
 ;; Case study:
 ;; (I)  The keywords are removed from a major mode.
 ;;
 ;; Case study:
 ;; (I)  The keywords are removed from a major mode.
@@ -795,8 +805,11 @@ see the variables `c-font-lock-extra-types', `c++-font-lock-extra-types',
 (defun font-lock-remove-keywords (mode keywords)
   "Remove highlighting KEYWORDS for MODE.
 
 (defun font-lock-remove-keywords (mode keywords)
   "Remove highlighting KEYWORDS for MODE.
 
-MODE should be a symbol, the major mode command name, such as `c-mode'
-or nil.  If nil, highlighting keywords are removed for the current buffer.
+MODE should be a symbol, the major mode command name, such as
+`c-mode' or nil.  If nil, highlighting keywords are removed for
+the current buffer.
+
+For a description of KEYWORDS, see `font-lock-add-keywords'.
 
 To make the removal apply to modes derived from MODE as well,
 pass nil for MODE and add the call to MODE-hook.  This may fail
 
 To make the removal apply to modes derived from MODE as well,
 pass nil for MODE and add the call to MODE-hook.  This may fail
@@ -935,7 +948,7 @@ The value of this variable is used when Font Lock mode is turned on."
      ;; Don't fontify eagerly (and don't abort if the buffer is large).
      (set (make-local-variable 'font-lock-fontified) t)
      ;; Use jit-lock.
      ;; Don't fontify eagerly (and don't abort if the buffer is large).
      (set (make-local-variable 'font-lock-fontified) t)
      ;; Use jit-lock.
-     (jit-lock-register 'font-lock-fontify-region
+     (jit-lock-register #'font-lock-fontify-region
                         (not font-lock-keywords-only))
      ;; Tell jit-lock how we extend the region to refontify.
      (add-hook 'jit-lock-after-change-extend-region-functions
                         (not font-lock-keywords-only))
      ;; Tell jit-lock how we extend the region to refontify.
      (add-hook 'jit-lock-after-change-extend-region-functions
@@ -1075,7 +1088,8 @@ Called with two arguments BEG and END.")
 
 (defun font-lock-flush (&optional beg end)
   "Declare the region BEG...END's fontification as out-of-date.
 
 (defun font-lock-flush (&optional beg end)
   "Declare the region BEG...END's fontification as out-of-date.
-If the region is not specified, it defaults to the whole buffer."
+If the region is not specified, it defaults to the entire
+accessible portion of the current buffer."
   (and font-lock-mode
        font-lock-fontified
        (funcall font-lock-flush-function
   (and font-lock-mode
        font-lock-fontified
        (funcall font-lock-flush-function
@@ -1083,13 +1097,20 @@ If the region is not specified, it defaults to the whole buffer."
 
 (defvar font-lock-ensure-function
   (lambda (_beg _end)
 
 (defvar font-lock-ensure-function
   (lambda (_beg _end)
-    (unless font-lock-fontified (font-lock-default-fontify-buffer)))
+    (unless font-lock-fontified
+      (font-lock-default-fontify-buffer)
+      (unless font-lock-mode
+        ;; If font-lock is not enabled, we don't have the hooks in place to
+        ;; track modifications, so a subsequent call to font-lock-ensure can't
+        ;; assume that the fontification is still valid.
+        (setq font-lock-fontified nil))))
   "Function to make sure a region has been fontified.
 Called with two arguments BEG and END.")
 
 (defun font-lock-ensure (&optional beg end)
   "Make sure the region BEG...END has been fontified.
   "Function to make sure a region has been fontified.
 Called with two arguments BEG and END.")
 
 (defun font-lock-ensure (&optional beg end)
   "Make sure the region BEG...END has been fontified.
-If the region is not specified, it defaults to the whole buffer."
+If the region is not specified, it defaults to the entire accessible
+portion of the buffer."
   (font-lock-set-defaults)
   (funcall font-lock-ensure-function
            (or beg (point-min)) (or end (point-max))))
   (font-lock-set-defaults)
   (funcall font-lock-ensure-function
            (or beg (point-min)) (or end (point-max))))
@@ -1176,7 +1197,9 @@ Put first the functions more likely to cause a change and cheaper to compute.")
   (let ((changed nil))
     (goto-char font-lock-beg)
     (unless (bolp)
   (let ((changed nil))
     (goto-char font-lock-beg)
     (unless (bolp)
-      (setq changed t font-lock-beg (line-beginning-position)))
+      (setq changed t font-lock-beg
+            (let ((inhibit-field-text-motion t))
+              (line-beginning-position))))
     (goto-char font-lock-end)
     (unless (bolp)
       (unless (eq font-lock-end
     (goto-char font-lock-end)
     (unless (bolp)
       (unless (eq font-lock-end
@@ -1220,7 +1243,8 @@ This function is the default `font-lock-fontify-region-function'."
             (font-lock-fontify-syntactic-keywords-region start end)))
         (unless font-lock-keywords-only
           (font-lock-fontify-syntactically-region beg end loudly))
             (font-lock-fontify-syntactic-keywords-region start end)))
         (unless font-lock-keywords-only
           (font-lock-fontify-syntactically-region beg end loudly))
-        (font-lock-fontify-keywords-region beg end loudly)))))
+        (font-lock-fontify-keywords-region beg end loudly)
+        `(jit-lock-bounds ,beg . ,end)))))
 
 ;; The following must be rethought, since keywords can override fontification.
 ;;    ;; Now scan for keywords, but not if we are inside a comment now.
 
 ;; The following must be rethought, since keywords can override fontification.
 ;;    ;; Now scan for keywords, but not if we are inside a comment now.
@@ -1307,15 +1331,18 @@ This function does 2 things:
                       (point-min))))
       (when (< end (point-max))
         (setq end
                       (point-min))))
       (when (< end (point-max))
         (setq end
-              (if (get-text-property end 'font-lock-multiline)
-                  (or (text-property-any end (point-max)
-                                         'font-lock-multiline nil)
-                      (point-max))
+              (cond
+               ((get-text-property end 'font-lock-multiline)
+                (or (text-property-any end (point-max)
+                                       'font-lock-multiline nil)
+                    (point-max)))
+               ;; If `end' has been set by the function above, don't corrupt it.
+               (font-lock-extend-after-change-region-function end)
                 ;; Rounding up to a whole number of lines should include the
                 ;; line right after `end'.  Typical case: the first char of
                 ;; the line was deleted.  Or a \n was inserted in the middle
                 ;; of a line.
                 ;; Rounding up to a whole number of lines should include the
                 ;; line right after `end'.  Typical case: the first char of
                 ;; the line was deleted.  Or a \n was inserted in the middle
                 ;; of a line.
-                (1+ end))))
+               (t (1+ end)))))
       ;; Finally, pre-enlarge the region to a whole number of lines, to try
       ;; and anticipate what font-lock-default-fontify-region will do, so as to
       ;; avoid double-redisplay.
       ;; Finally, pre-enlarge the region to a whole number of lines, to try
       ;; and anticipate what font-lock-default-fontify-region will do, so as to
       ;; avoid double-redisplay.
@@ -1325,11 +1352,13 @@ This function does 2 things:
       (when (memq 'font-lock-extend-region-wholelines
                   font-lock-extend-region-functions)
         (goto-char beg)
       (when (memq 'font-lock-extend-region-wholelines
                   font-lock-extend-region-functions)
         (goto-char beg)
-        (setq jit-lock-start (min jit-lock-start (line-beginning-position)))
+        (setq beg (min jit-lock-start (line-beginning-position)))
         (goto-char end)
         (goto-char end)
-        (setq jit-lock-end
+        (setq end
               (max jit-lock-end
               (max jit-lock-end
-                   (if (bolp) (point) (line-beginning-position 2))))))))
+                   (if (bolp) (point) (line-beginning-position 2)))))
+      (setq jit-lock-start beg
+           jit-lock-end end))))
 
 (defun font-lock-fontify-block (&optional arg)
   "Fontify some lines the way `font-lock-fontify-buffer' would.
 
 (defun font-lock-fontify-block (&optional arg)
   "Fontify some lines the way `font-lock-fontify-buffer' would.
@@ -1339,11 +1368,11 @@ no ARG is given and `font-lock-mark-block-function' is nil.
 If `font-lock-mark-block-function' non-nil and no ARG is given, it is used to
 delimit the region to fontify."
   (interactive "P")
 If `font-lock-mark-block-function' non-nil and no ARG is given, it is used to
 delimit the region to fontify."
   (interactive "P")
-  (let ((inhibit-point-motion-hooks t) font-lock-beginning-of-syntax-function
+  (let ((inhibit-point-motion-hooks t)
        deactivate-mark)
     ;; Make sure we have the right `font-lock-keywords' etc.
     (if (not font-lock-mode) (font-lock-set-defaults))
        deactivate-mark)
     ;; Make sure we have the right `font-lock-keywords' etc.
     (if (not font-lock-mode) (font-lock-set-defaults))
-    (save-excursion
+    (save-mark-and-excursion
       (save-match-data
        (condition-case error-data
            (if (or arg (not font-lock-mark-block-function))
       (save-match-data
        (condition-case error-data
            (if (or arg (not font-lock-mark-block-function))
@@ -1416,37 +1445,33 @@ Optional argument OBJECT is the string or buffer containing the text."
       (put-text-property start next prop value object)
       (setq start (text-property-any next end prop nil object)))))
 
       (put-text-property start next prop value object)
       (setq start (text-property-any next end prop nil object)))))
 
-;; For completeness: this is to `remove-text-properties' as `put-text-property'
-;; is to `add-text-properties', etc.
-;;(defun remove-text-property (start end property &optional object)
-;;  "Remove a property from text from START to END.
-;;Argument PROPERTY is the property to remove.
-;;Optional argument OBJECT is the string or buffer containing the text.
-;;Return t if the property was actually removed, nil otherwise."
-;;  (remove-text-properties start end (list property) object))
-
-;; For consistency: maybe this should be called `remove-single-property' like
-;; `next-single-property-change' (not `next-single-text-property-change'), etc.
-;;(defun remove-single-text-property (start end prop value &optional object)
-;;  "Remove a specific property value from text from START to END.
-;;Arguments PROP and VALUE specify the property and value to remove.  The
-;;resulting property values are not equal to VALUE nor lists containing VALUE.
-;;Optional argument OBJECT is the string or buffer containing the text."
-;;  (let ((start (text-property-not-all start end prop nil object)) next prev)
-;;    (while start
-;;      (setq next (next-single-property-change start prop object end)
-;;         prev (get-text-property start prop object))
-;;      (cond ((and (symbolp prev) (eq value prev))
-;;          (remove-text-property start next prop object))
-;;         ((and (listp prev) (memq value prev))
-;;          (let ((new (delq value prev)))
-;;            (cond ((null new)
-;;                   (remove-text-property start next prop object))
-;;                  ((= (length new) 1)
-;;                   (put-text-property start next prop (car new) object))
-;;                  (t
-;;                   (put-text-property start next prop new object))))))
-;;      (setq start (text-property-not-all next end prop nil object)))))
+(defun font-lock--remove-face-from-text-property (start
+                                                 end
+                                                 prop value &optional object)
+  "Remove a specific property value from text from START to END.
+Arguments PROP and VALUE specify the property and value to remove.  The
+resulting property values are not `eq' to VALUE nor lists containing VALUE.
+Optional argument OBJECT is the string or buffer containing the text."
+  (let ((start (text-property-not-all start end prop nil object)) next prev)
+    (while start
+      (setq next (next-single-property-change start prop object end)
+           prev (get-text-property start prop object))
+      (cond ((or (atom prev)
+                (keywordp (car prev))
+                (eq (car prev) 'foreground-color)
+                (eq (car prev) 'background-color))
+            (when (eq value prev)
+              (remove-list-of-text-properties start next (list prop) object)))
+           ((memq value prev)          ;Assume prev is not dotted.
+            (let ((new (remq value prev)))
+              (cond ((null new)
+                     (remove-list-of-text-properties start next (list prop)
+                                                     object))
+                    ((= (length new) 1)
+                     (put-text-property start next prop (car new) object))
+                    (t
+                     (put-text-property start next prop new object))))))
+      (setq start (text-property-not-all next end prop nil object)))))
 
 ;;; End of Additional text property functions.
 \f
 
 ;;; End of Additional text property functions.
 \f
@@ -1761,11 +1786,10 @@ If SYNTACTIC-KEYWORDS is non-nil, it means these keywords are used for
          (cons t (cons keywords
                        (mapcar #'font-lock-compile-keyword keywords))))
     (if (and (not syntactic-keywords)
          (cons t (cons keywords
                        (mapcar #'font-lock-compile-keyword keywords))))
     (if (and (not syntactic-keywords)
-            (let ((beg-function
-                   (or font-lock-beginning-of-syntax-function
-                       syntax-begin-function)))
+            (let ((beg-function syntax-begin-function))
               (or (eq beg-function 'beginning-of-defun)
               (or (eq beg-function 'beginning-of-defun)
-                  (get beg-function 'font-lock-syntax-paren-check)))
+                   (if (symbolp beg-function)
+                       (get beg-function 'font-lock-syntax-paren-check))))
             (not beginning-of-defun-function))
        ;; Try to detect when a string or comment contains something that
        ;; looks like a defun and would thus confuse font-lock.
             (not beginning-of-defun-function))
        ;; Try to detect when a string or comment contains something that
        ;; looks like a defun and would thus confuse font-lock.
@@ -1886,17 +1910,14 @@ Sets various variables using `font-lock-defaults' and
                              (list (car selem))
                            (mapcar 'identity (car selem))))
              (modify-syntax-entry char syntax font-lock-syntax-table)))))
                              (list (car selem))
                            (mapcar 'identity (car selem))))
              (modify-syntax-entry char syntax font-lock-syntax-table)))))
-      ;; Syntax function for syntactic fontification?
-      (if (nth 4 defaults)
-       (set (make-local-variable 'font-lock-beginning-of-syntax-function)
-               (nth 4 defaults))
-        (kill-local-variable 'font-lock-beginning-of-syntax-function))
+      ;; (nth 4 defaults) used to hold `font-lock-beginning-of-syntax-function',
+      ;; but that was removed in 25.1, so if it's a cons cell, we assume that
+      ;; it's part of the variable alist.
       ;; Variable alist?
       ;; Variable alist?
-      (dolist (x (nthcdr 5 defaults))
+      (dolist (x (nthcdr (if (consp (nth 4 defaults)) 4 5) defaults))
        (set (make-local-variable (car x)) (cdr x)))
       ;; Set up `font-lock-keywords' last because its value might depend
        (set (make-local-variable (car x)) (cdr x)))
       ;; Set up `font-lock-keywords' last because its value might depend
-      ;; on other settings (e.g. font-lock-compile-keywords uses
-      ;; font-lock-beginning-of-syntax-function).
+      ;; on other settings.
       (set (make-local-variable 'font-lock-keywords)
           (font-lock-eval-keywords keywords))
       ;; Local fontification?
       (set (make-local-variable 'font-lock-keywords)
           (font-lock-eval-keywords keywords))
       ;; Local fontification?