changeset 70289:608b16c56304

(Multiline Font Lock): Renamed from Multi line Font Lock Elements. Much clarification. (Font Lock Multiline, Region to Fontify): Much clarification.
author Richard M. Stallman <rms@gnu.org>
date Sun, 30 Apr 2006 02:35:35 +0000
parents 45b7cad845ee
children 98e4db27f6c7
files lispref/modes.texi
diffstat 1 files changed, 106 insertions(+), 115 deletions(-) [+]
line wrap: on
line diff
--- a/lispref/modes.texi	Sun Apr 30 01:36:19 2006 +0000
+++ b/lispref/modes.texi	Sun Apr 30 02:35:35 2006 +0000
@@ -2345,8 +2345,8 @@
 * Syntactic Font Lock::         Fontification based on syntax tables.
 * Setting Syntax Properties::   Defining character syntax based on context
                                   using the Font Lock mechanism.
-* Multi line Font Lock Elements:: How to coerce Font Lock into properly
-                                  highlighting multiline elements.
+* Multiline Font Lock::         How to coerce Font Lock into properly
+                                  highlighting multiline constructs.
 @end menu
 
 @node Font Lock Basics
@@ -2625,7 +2625,7 @@
 
 @strong{Warning:} Do not design an element of @code{font-lock-keywords}
 to match text which spans lines; this does not work reliably.
-For details, see @xref{Multi line Font Lock Elements}.
+For details, see @xref{Multiline Font Lock}.
 
 You can use @var{case-fold} in @code{font-lock-defaults} to specify
 the value of @code{font-lock-keywords-case-fold-search} which says
@@ -2944,8 +2944,8 @@
 
 This can be used to highlighting different kinds of strings or
 comments differently.  It is also sometimes abused together with
-@code{font-lock-syntactic-keywords} to highlight elements that span
-multiple lines, but this is too obscure to document in this manual.
+@code{font-lock-syntactic-keywords} to highlight constructs that span
+multiple lines, but this is too esoteric to document here.
 
 Specify this variable using @var{other-vars} in
 @code{font-lock-defaults}.
@@ -3015,64 +3015,60 @@
 @code{font-lock-defaults}.
 @end defvar
 
-@node Multi line Font Lock Elements
-@subsection Multi line Font Lock Elements
-@cindex multi line font lock
-
-Normally, Font Lock elements specified via @code{font-lock-keywords}
-should not match across multiple lines.  If they do, Font Lock may
-fail to highlight them properly.  This is fundamentally due to the
-fact that Font Lock does not always look at the whole buffer at
-a time, for obvious performance reasons, and instead only looks
-at a small chunk at a time.  In order for the highlight to be correct,
-a chunk should not straddle an element matched by
-@code{font-lock-keywords}.  The default heuristic used for this is to
-start and end chunks at the beginning resp. end of a line.
-
-In order for Font Lock to properly highlight elements that span
-multiple lines, the package author has to ensure two things: correct
-@emph{discovery} and correct @emph{re}highlighting.  The first ensures
-that Font Lock finds all multiline elements.  The second ensures that
-Font Lock will correctly re-highlight all the relevant text when
-a multiline element is changed, e.g. causing some of the text that was
-previously part of a multiline element to not be part of it any more.
-The two aspects are closely related and often getting one of the two
-to work will appear to make the other also work.  But both aspects
-have to be taken care of for the multiline elements to be
-reliably highlighted.
-
-Correct @emph{re}highlighting of multiline elements can be done in the
-following ways:
+@node Multiline Font Lock
+@subsection Multiline Font Lock Constructs
+@cindex multiline font lock
+
+  Normally, elements of @code{font-lock-keywords} should not match
+across multiple lines; that doesn't work reliably, because Font Lock
+usually scans just part of the buffer, and it can miss a multi-line
+construct that crosses the line boundary where the scan starts.  (The
+scan normally starts at the beginning of a line.)
+
+  Making elements that match multiline constructs work properly has
+two aspects: correct @emph{identification} and correct
+@emph{rehighlighting}.  The first means that Font Lock finds all
+multiline constructs.  The second means that Font Lock will correctly
+rehighlight all the relevant text when a multiline construct is
+changed---for example, if some of the text that was previously part of
+a multiline construct ceases to be part of it.  The two aspects are
+closely related, and often getting one of them to work will appear to
+make the other also work.  However, for reliable results you must
+attend explicitly to both aspects.
+
+  There are two ways to ensure correct identification of multiline
+constructs:
+
 @itemize
 @item
-Apply the @code{font-lock-multiline} property to the element.
-This will ensure that the whole element will always be immediately
-rehighlighted if any part of it is changed.  This can sometimes be
-done automatically by setting the @code{font-lock-multiline} variable.
+Place a @code{font-lock-multiline} or @code{jit-lock-defer-multiline}
+property on the construct when it is added to the buffer.
 @item
-Rely on @code{jit-lock-contextually}.  This will only rehighlight the
-part of the element that follows the actual change, and will do it
-after a short delay.  This only works if the highlighting of the
-various parts of your multiline element never depends on text in
-subsequent lines.  Since @code{jit-lock-contextually} is activated by
-default, this can be an attractive solution.
-@item
-Apply the @code{jit-lock-defer-multiline} property to the element.
-This works only if @code{jit-lock-contextually} is used and allows it
-to also work when highlighting does depend on subsequent lines.
-@item
+Use @code{font-lock-fontify-region-function} hook to extend the scan
+so that the scanned text never starts or ends in the middle of a
+multiline construct.
 @end itemize
 
-Discovery of new multiline elements can be done in the following ways:
+  There are three ways to do rehighlighting of multiline constructs:
+
 @itemize
 @item
-Manually placing a @code{font-lock-multiline} or
-@code{jit-lock-defer-multiline} property on the element when it is
-added to the buffer.
+Place a @code{font-lock-multiline} property on the construct.  This
+will rehighlight the whole construct if any part of it is changed.  In
+some cases you can do this automatically by setting the
+@code{font-lock-multiline} variable.
 @item
-Using the @code{font-lock-fontify-region-function} hook to extend the
-highlighted chunks so that they never start or end in the middle of
-multiline element.
+Use @code{jit-lock-contextually}.  This will only rehighlight the part
+of the construct that follows the actual change, and will do it after
+a short delay.  This only works if the highlighting of the various
+parts of your multiline construct never depends on text in subsequent
+lines.  Since @code{jit-lock-contextually} is activated by default,
+this can be an attractive solution.
+@item
+Place a @code{jit-lock-defer-multiline} property on the construct.
+This works only if @code{jit-lock-contextually} is used, but it can
+handle the case where highlighting depends on subsequent lines.
+@item
 @end itemize
 
 @menu
@@ -3084,80 +3080,75 @@
 @node Font Lock Multiline
 @subsubsection Font Lock Multiline
 
-In order to make it possible to properly @emph{re}highlight elements that
-span multiple lines, Font Lock obeys a special text property
-@code{font-lock-multiline} which if non-@code{nil} indicates that this
-piece of text was highlighted as part of a multiline construct.
-So when Font Lock is asked to rehighlight a region, it first verifies
-the two boundaries and extends them as needed so they do not fall in
-the middle of a piece of text marked with the
-@code{font-lock-multiline} property.  Immediately after that, it also
-erases all @code{font-lock-multiline} properties from the region it is
-about to highlight, so it is the responsability of the highlighting
-specification (mostly @code{font-lock-keywords}) to make sure that
-this property is re-added where needed so as to inform the next round
-of Font Locking of the presence of a multiline construct.
-
-It is important to understand that the @code{font-lock-multiline}
-property should preferably only be used on Font Lock elements of
-moderate size: every time that text is modified within a multiline
-element (or nearby), the whole multiline element will be completely
-re-highlighted, so if its size is large, the time to font-lock may
-render editing painfully slow.
+  One way to ensure reliable rehighlighting of multiline Font Lock
+constructs is to put on the text property @code{font-lock-multiline}.
+It should be present and non-@code{nil} for text that is part of a
+multiline construct.
+
+  When Font Lock is about to highlight a range of text, it first
+extends the boundaries of the range as necessary so that they do not
+fall within text marked with the @code{font-lock-multiline} property.
+Then it removes any @code{font-lock-multiline} properties from the
+range, and highlights it.  The highlighting specification (mostly
+@code{font-lock-keywords}) must reinstall this property each time,
+whenever it is appropriate.
+
+  @strong{Warning:} don't use the @code{font-lock-multiline} property
+on large ranges of text, because that will make rehighlighting slow.
 
 @defvar font-lock-multiline
 If the @code{font-lock-multiline} variable is set to @code{t}, Font
-Lock will try to automatically add the @code{font-lock-multiline}
-property on the keywords that span several lines.  This is no silver
-bullet however since it slows down Font Lock somewhat, and may miss
-some cases or make the property larger or smaller than necessary,
-especially for keywords whose @var{MATCHER} is a function, in which
-case the function needs to make sure that the submatch 0 covers the
-whole relevant multiline entity even if only a small subpart will
-be highlighted.  It is often just as easy to add the
-@code{font-lock-multiline} property by hand.
+Lock will try to add the @code{font-lock-multiline} property
+automatically on multiline constructs.  This is not a universal
+solution, however, since it slows down Font Lock somewhat.  It can
+miss some multiline constructs, or make the property larger or smaller
+than necessary.
+
+For elements whose @var{matcher} is a function, the function should
+ensure that submatch 0 covers the whole relevant multiline construct,
+even if only a small subpart will be highlighted.  It is often just as
+easy to add the @code{font-lock-multiline} property by hand.
 @end defvar
 
-As mentioned, this property is mostly intended to ensure proper
-@emph{re}fontification.  It does not magically discover new
-multiline elements.  To discover new multiline elements, all that is
-required is that font-lock operate on large enough chunks at a time.
-This will happen by accident on many cases, which may give the
-impression that multiline elements magically work.  If you set the
-@code{font-lock-multiline} variable, this impression will be even
-stronger since the highlighting of those found elements will be
-properly preserved from then on.  But for such multiline elements to
-be found reliably, you will need to either manually put the
-@code{font-lock-multiline} property from some appropriate piece of
-code run before Font Lock, or hook into
-@code{font-lock-fontify-region-function} to manually extend the chunks
-of text that Font Lock highlights so they never start or stop in the
-middle of a multiline element.
+  The @code{font-lock-multiline} property is meant to ensure proper
+refontification; it does not automatically identify new multiline
+constructs.  Identifying the requires that Font-Lock operate on large
+enough chunks at a time.  This will happen by accident on many cases,
+which may give the impression that multiline constructs magically work.
+If you set the @code{font-lock-multiline} variable non-@code{nil},
+this impression will be even stronger, since the highlighting of those
+constructs which are found will be properly updated from then on.
+But that does not work reliably.
+
+  To find multiline constructs reliably, you must either manually
+place the @code{font-lock-multiline} property on the text before
+Font-Lock looks at it, or use
+@code{font-lock-fontify-region-function}.
 
 @node Region to Fontify
 @subsubsection Region to Fontify after a Buffer Change
 
-  When a buffer is changed, the region that Font Lock refontifies is by
-default the smallest sequence of whole lines that spans the change.
+  When a buffer is changed, the region that Font Lock refontifies is
+by default the smallest sequence of whole lines that spans the change.
 While this works well most of the time, sometimes it doesn't---for
-example, when a buffer change has changed the syntactic meaning of text
-on an earlier line.
-
-You can enlarge (or even reduce) the region to fontify by setting @c either of
-the following variables:
+example, when a change alters the syntactic meaning of text on an
+earlier line.
+
+  You can enlarge (or even reduce) the region to fontify by setting
+one the following variables:
 
 @defvar font-lock-extend-region-function
-This buffer-local variable is either @code{nil} or is a function that
-determines the region to fontify, which Emacs then calls after each
-buffer change.
+This buffer-local variable is either @code{nil} or a function for
+Font-Lock to call to determine the region to scan and fontify.
 
 The function is given three parameters, the standard @var{beg},
-@var{end}, and @var{old-len} from after-change-functions (@pxref{Change
-Hooks}).  It should return either a cons of the beginning and end buffer
-positions (in that order) of the region to fontify, or @code{nil} (which
-directs the caller to fontify the default region).  This function needs
-to preserve point, the match-data, and the current restriction.
-The region it returns may start or end in the middle of a line.
+@var{end}, and @var{old-len} from after-change-functions
+(@pxref{Change Hooks}).  It should return either a cons of the
+beginning and end buffer positions (in that order) of the region to
+fontify, or @code{nil} (which means choose the region in the standard
+way).  This function needs to preserve point, the match-data, and the
+current restriction.  The region it returns may start or end in the
+middle of a line.
 
 Since this function is called after every buffer change, it should be
 reasonably fast.