+@node Clickable Text
+@subsection Defining Clickable Text
+@cindex clickable text
+
+ There are two ways to set up @dfn{clickable text} in a buffer.
+There are typically two parts of this: to make the text highlight
+when the mouse is over it, and to make a mouse button do something
+when you click it on that part of the text.
+
+ Highlighting is done with the @code{mouse-face} text property.
+Here is an example of how Dired does it:
+
+@smallexample
+(condition-case nil
+ (if (dired-move-to-filename)
+ (put-text-property (point)
+ (save-excursion
+ (dired-move-to-end-of-filename)
+ (point))
+ 'mouse-face 'highlight))
+ (error nil))
+@end smallexample
+
+@noindent
+The first two arguments to @code{put-text-property} specify the
+beginning and end of the text.
+
+ The usual way to make the mouse do something when you click it
+on this text is to define @code{mouse-2} in the major mode's
+keymap. The job of checking whether the click was on clickable text
+is done by the command definition. Here is how Dired does it:
+
+@smallexample
+(defun dired-mouse-find-file-other-window (event)
+ "In dired, visit the file or directory name you click on."
+ (interactive "e")
+ (let (file)
+ (save-excursion
+ (set-buffer (window-buffer (posn-window (event-end event))))
+ (save-excursion
+ (goto-char (posn-point (event-end event)))
+ (setq file (dired-get-filename))))
+ (select-window (posn-window (event-end event)))
+ (find-file-other-window (file-name-sans-versions file t))))
+@end smallexample
+
+@noindent
+The reason for the outer @code{save-excursion} construct is to avoid
+changing the current buffer; the reason for the inner one is to avoid
+permanently altering point in the buffer you click on. In this case,
+Dired uses the function @code{dired-get-filename} to determine which
+file to visit, based on the position found in the event.
+
+ Instead of defining a mouse command for the major mode, you can define
+a key binding for the clickable text itself, using the @code{keymap}
+text property:
+
+@example
+(let ((map (make-sparse-keymap)))
+ (define-key map [mouse-2] 'operate-this-button)
+ (put-text-property (point)
+ (save-excursion
+ (dired-move-to-end-of-filename)
+ (point))
+ 'keymap map))
+@end example
+
+@noindent
+This method makes it possible to define different commands for various
+clickable pieces of text. Also, the major mode definition (or the
+global definition) remains available for the rest of the text in the
+buffer.
+
+@node Fields
+@subsection Defining and Using Fields
+@cindex fields
+
+ A field is a range of consecutive characters in the buffer that are
+identified by having the same value (comparing with @code{eq}) of the
+@code{field} property. This section describes special functions that
+are available for operating on fields.
+
+ You specify a field with a buffer position, @var{pos}. We think of
+each field as containing a range of buffer positions, so the position
+you specify stands for the field containing that position.
+
+ When the characters before and after @var{pos} are part of the same
+field, there is no doubt which field contains @var{pos}: the one those
+characters both belong to. When @var{pos} is at a boundary between
+fields, which field it belongs to depends on the stickiness of the
+@code{field} properties of the two surrounding characters (@pxref{Sticky
+Properties}). The field whose property would be inherited by text
+inserted at @var{pos} is the field that contains @var{pos}.
+
+ There is an anomalous case where newly inserted text at @var{pos}
+would not inherit the @code{field} property from either side. This
+happens if the previous character's @code{field} property is not
+rear-sticky, and the following character's @code{field} property is not
+front-sticky. In this case, @var{pos} belongs to neither the preceding
+field nor the following field; the field functions treat it as belonging
+to an empty field whose beginning and end are both at @var{pos}.
+
+ In all of these functions, if @var{pos} is omitted or @code{nil}, the
+value of point is used by default.
+
+@defun field-beginning &optional pos escape-from-edge
+@tindex field-beginning
+This function returns the beginning of the field specified by @var{pos}.
+
+If @var{pos} is at the end of a field, and @var{escape-from-edge} is
+non-@code{nil}, then the return value is always the beginning of the
+field that @emph{ends} at @var{pos}, regardless of the stickiness of the
+@code{field} properties around @var{pos}.
+@end defun
+
+@defun field-end &optional pos escape-from-edge
+@tindex field-end
+This function returns the end of the field specified by @var{pos}.
+
+If @var{pos} is at the beginning of a field, and @var{escape-from-edge}
+is non-@code{nil}, then the return value is always the end of the field
+that @emph{begins} at @var{pos}, regardless of the stickiness of the
+@code{field} properties around @var{pos}.
+@end defun
+
+@defun field-string &optional pos
+@tindex field-string
+This function returns the contents of the field specified by @var{pos},
+as a string.
+@end defun
+
+@defun field-string-no-properties &optional pos
+@tindex field-string-no-properties
+This function returns the contents of the field specified by @var{pos},
+as a string, discarding text properties.
+@end defun
+
+@defun delete-field &optional pos
+@tindex delete-field
+This function deletes the text of the field specified by @var{pos}.
+@end defun
+
+@deffn beginning-of-line-or-field &optional count
+@tindex beginning-of-line-or-field
+Like @code{beginning-of-line}, except that this function does not move
+across a field boundary (@pxref{Fields}), unless it moves to another
+line beyond the one that contains the field boundary. Therefore, if
+@var{count} is zero, and point is initially at a field boundary, point
+does not move.
+@end deffn
+
+@deffn end-of-line-or-field &optional count
+@tindex end-of-line-or-field
+Like @code{end-of-line}, except that this function does not move
+across a field boundary (@pxref{Fields}), unless it moves to another
+line beyond the one that contains the field boundary.
+@end deffn
+
+@defun constrain-to-field new-pos old-pos &optional escape-from-edge only-in-line
+@tindex constrain-to-field
+This function ``constrains'' @var{new-pos} to the field that
+@var{old-pos} belongs to---in other words, it returns the position
+closest to @var{new-pos} that is in the same field as @var{old-pos}.
+
+If @var{new-pos} is @code{nil}, then @code{constrain-to-field} uses
+the value of point instead, and moves point to the resulting position.
+
+If @var{old-pos} is at the boundary of two fields, then the acceptable
+positions for @var{new-pos} depend on the value of the optional argument
+@var{escape-from-edge}. If @var{escape-from-edge} is @code{nil}, then
+@var{new-pos} is constrained to the field that has the same @code{field}
+text-property that new characters inserted at @var{old-pos} would get.
+(This depends on the stickiness of the @code{field} property for the
+characters before and after @var{old-pos}.) If @var{escape-from-edge}
+is non-@code{nil}, @var{new-pos} is constrained to the union of the two
+adjacent fields.
+
+If the optional argument @var{only-in-line} is non-@code{nil}, and
+constraining @var{new-pos} in the usual way would move it to a different
+line, @var{new-pos} is returned unconstrained. This used in commands
+that move by line, such as @code{next-line} and
+@code{beginning-of-line}, so that they respect field boundaries only in
+the case where they can still move to the right line.
+@end defun
+