(A-compU+26612): New abstract node.
[chise/xemacs-chise.git.1] / man / widget.texi
index 367ebd0..50bbc14 100644 (file)
@@ -1,7 +1,7 @@
 \input texinfo.tex
 
 @c %**start of header
-@setfilename ../info/widget
+@setfilename ../info/widget.info
 @settitle The Emacs Widget Library
 @iftex
 @afourpaper
@@ -9,6 +9,13 @@
 @end iftex
 @c %**end of header
 
+@ifinfo
+@dircategory XEmacs Editor
+@direntry
+* Widgets: (widget).            The Emacs Widget Library.
+@end direntry
+@end ifinfo
+
 @node Top, Introduction, (dir), (dir)
 @comment  node-name,  next,  previous,  up
 @top The Emacs Widget Library
@@ -26,6 +33,7 @@
 * Widget Minor Mode::           
 * Utilities::                   
 * Widget Wishlist::             
+* Widget Internals::
 @end menu
 
 @node  Introduction, User Interface, Top, Top
@@ -62,7 +70,7 @@ visible in the buffer.
 A simple constant widget intended to be used in the @code{menu-choice} and
 @code{radio-button-choice} widgets. 
 @item choice-item
-An button item only intended for use in choices.  When invoked, the user
+A button item only intended for use in choices.  When invoked, the user
 will be asked to select another option from the choice widget.
 @item toggle
 A simple @samp{on}/@samp{off} switch.
@@ -87,7 +95,7 @@ implement forms are:
 
 @enumerate
 @item
-More complex field than just editable text are supported. 
+More complex fields than just editable text are supported. 
 @item
 You can give the user immediate feedback if he enters invalid data in a
 text field, and sometimes prevent entering invalid data.
@@ -113,7 +121,7 @@ create any widgets, the code has been split in two files:
 @table @file
 @item widget.el
 This will declare the user variables, define the function
-@code{widget-define}, and autoload the function @code{widget-create}. 
+@code{define-widget}, and autoload the function @code{widget-create}. 
 @item wid-edit.el
 Everything else is here, there is no reason to load it explicitly, as
 it will be autoloaded when needed.
@@ -123,11 +131,11 @@ it will be autoloaded when needed.
 @comment  node-name,  next,  previous,  up
 @section User Interface
 
-A form consist of read only text for documentation and some fields,
-where each the fields contain two parts, as tag and a value.  The tags
-are used to identify the fields, so the documentation can refer to the
-foo field, meaning the field tagged with @samp{Foo}. Here is an example
-form:
+A form consists of read only text for documentation and some fields,
+where each of the fields contains two parts, a tag and a value.  The
+tags are used to identify the fields, so the documentation can refer to
+the foo field, meaning the field tagged with @samp{Foo}. Here is an
+example form:
 
 @example
 Here is some documentation.
@@ -219,7 +227,7 @@ between a number of different options.  This is how you edit an option
 field.  Option fields are created by the @code{menu-choice} widget.  In
 the example, @samp{@b{Choose}} is an option field tag.
 @item The @samp{@b{[INS]}} and @samp{@b{[DEL]}} buttons.
-Activating these will insert or delete elements from a editable list.
+Activating these will insert or delete elements from an editable list.
 The list is created by the @code{editable-list} widget. 
 @item Embedded Buttons.
 The @samp{@b{_other work_}} is an example of an embedded
@@ -291,69 +299,69 @@ Interface}).
   (make-local-variable 'widget-example-repeat)
   (widget-insert "Here is some documentation.\n\nName: ")
   (widget-create 'editable-field
-                :size 13
-                "My Name")
+                 :size 13
+                 "My Name")
   (widget-create 'menu-choice
-                :tag "Choose"
-                :value "This"
-                :help-echo "Choose me, please!"
-                :notify (lambda (widget &rest ignore)
-                          (message "%s is a good choice!"
-                                   (widget-value widget)))
-                '(item :tag "This option" :value "This")
-                '(choice-item "That option")
-                '(editable-field :menu-tag "No option" "Thus option"))
+                 :tag "Choose"
+                 :value "This"
+                 :help-echo "Choose me, please!"
+                 :notify (lambda (widget &rest ignore)
+                           (message "%s is a good choice!"
+                                    (widget-value widget)))
+                 '(item :tag "This option" :value "This")
+                 '(choice-item "That option")
+                 '(editable-field :menu-tag "No option" "Thus option"))
   (widget-insert "Address: ")
   (widget-create 'editable-field
-                "Some Place\nIn some City\nSome country.")
+                 "Some Place\nIn some City\nSome country.")
   (widget-insert "\nSee also ")
   (widget-create 'link
-                :notify (lambda (&rest ignore)
-                          (widget-value-set widget-example-repeat 
-                                            '("En" "To" "Tre"))
-                          (widget-setup))
-                "other work")
+                 :notify (lambda (&rest ignore)
+                           (widget-value-set widget-example-repeat 
+                                             '("En" "To" "Tre"))
+                           (widget-setup))
+                 "other work")
   (widget-insert " for more information.\n\nNumbers: count to three below\n")
   (setq widget-example-repeat
-       (widget-create 'editable-list
-                      :entry-format "%i %d %v"
-                      :notify (lambda (widget &rest ignore)
-                                (let ((old (widget-get widget
-                                                       ':example-length))
-                                      (new (length (widget-value widget))))
-                                  (unless (eq old new)
-                                    (widget-put widget ':example-length new)
-                                    (message "You can count to %d." new))))
-                      :value '("One" "Eh, two?" "Five!")
-                      '(editable-field :value "three")))
+        (widget-create 'editable-list
+                       :entry-format "%i %d %v"
+                       :notify (lambda (widget &rest ignore)
+                                 (let ((old (widget-get widget
+                                                        ':example-length))
+                                       (new (length (widget-value widget))))
+                                   (unless (eq old new)
+                                     (widget-put widget ':example-length new)
+                                     (message "You can count to %d." new))))
+                       :value '("One" "Eh, two?" "Five!")
+                       '(editable-field :value "three")))
   (widget-insert "\n\nSelect multiple:\n\n")
   (widget-create 'checkbox t)
   (widget-insert " This\n")
   (widget-create 'checkbox nil)
   (widget-insert " That\n")
   (widget-create 'checkbox
-                :notify (lambda (&rest ignore) (message "Tickle"))
-                t)
+                 :notify (lambda (&rest ignore) (message "Tickle"))
+                 t)
   (widget-insert " Thus\n\nSelect one:\n\n")
   (widget-create 'radio-button-choice
-                :value "One"
-                :notify (lambda (widget &rest ignore)
-                          (message "You selected %s"
-                                   (widget-value widget)))
-                '(item "One") '(item "Another One.") '(item "A Final One."))
+                 :value "One"
+                 :notify (lambda (widget &rest ignore)
+                           (message "You selected %s"
+                                    (widget-value widget)))
+                 '(item "One") '(item "Another One.") '(item "A Final One."))
   (widget-insert "\n")
   (widget-create 'push-button
-                :notify (lambda (&rest ignore) 
-                          (if (= (length (widget-value widget-example-repeat))
-                                 3)
-                              (message "Congratulation!")
-                            (error "Three was the count!")))
-                "Apply Form")
+                 :notify (lambda (&rest ignore) 
+                           (if (= (length (widget-value widget-example-repeat))
+                                  3)
+                               (message "Congratulation!")
+                             (error "Three was the count!")))
+                 "Apply Form")
   (widget-insert " ")
   (widget-create 'push-button
-                :notify (lambda (&rest ignore)
-                          (widget-example))
-                "Reset Form")
+                 :notify (lambda (&rest ignore)
+                           (widget-example))
+                 "Reset Form")
   (widget-insert "\n")
   (use-local-map widget-keymap)
   (widget-setup))
@@ -423,7 +431,7 @@ NAME ::= (NAME [KEYWORD ARGUMENT]... ARGS)
      |   NAME
 @end example
 
-Where, @var{name} is a widget name, @var{keyword} is the name of a
+where @var{name} is a widget name, @var{keyword} is the name of a
 property, @var{argument} is the value of the property, and @var{args}
 are interpreted in a widget specific way.
 
@@ -455,11 +463,11 @@ String to suffix buttons.
 
 @item %@{
 @itemx %@}
-The text inside will be displayed with the face specified by
-@code{:sample-face}. 
+The text inside will be displayed in the face specified by
+@code{:sample-face}.
 
 @item %v
-This will be replaces with the buffer representation of the widgets
+This will be replaced with the buffer representation of the widget's
 value.  What this is depends on the widget type.
 
 @item %d
@@ -503,7 +511,7 @@ The value of the symbol is expanded according to this table.
 @end table
 
 @item :doc
-The string inserted by the @samp{%d} escape in the format
+The string inserted by the @samp{%d} or @samp{%h} escape in the format
 string.  
 
 @item :tag
@@ -535,7 +543,9 @@ A function called each time the widget or a nested widget is changed.
 The function is called with two or three arguments.  The first argument
 is the widget itself, the second argument is the widget that was
 changed, and the third argument is the event leading to the change, if
-any. 
+any.  In editable fields, this includes all insertions, deletions,
+@emph{etc}.  To watch only for ``final'' actions, redefine the
+@code{:action} callback.
 
 @item :menu-tag
 Tag used in the menu when the widget is used as an option in a
@@ -552,9 +562,9 @@ Should be a function called with two arguments, the widget and a value,
 and returning non-nil if the widget can represent the specified value.
 
 @item :validate
-A function which takes a widget as an argument, and return nil if the
-widgets current value is valid for the widget.  Otherwise, it should
-return the widget containing the invalid data, and set that widgets
+A function which takes a widget as an argument, and returns nil if the
+widget's current value is valid for the widget.  Otherwise it should
+return the widget containing the invalid data, and set that widget's
 @code{:error} property to a string explaining the error.
 
 The following predefined function can be used:
@@ -584,7 +594,7 @@ in the buffer with a positive tabbing order, or @code{nil}
 
 @item :parent
 The parent of a nested widget (e.g. a @code{menu-choice} item or an
-element of a @code{editable-list} widget).
+element of an @code{editable-list} widget).
 
 @item :sibling-args
 This keyword is only used for members of a @code{radio-button-choice} or
@@ -715,8 +725,10 @@ The following extra properties are recognized.
 
 @table @code
 @item :size
-The width of the editable field.@*
-By default the field will reach to the end of the line.
+The minimum width of the editable field.@*
+By default the field will reach to the end of the line.  If the
+content is too large, the displayed representation will expand to
+contain it.  The content is not truncated to size.
 
 @item :value-face
 Face used for highlighting the editable field.  Default is
@@ -735,7 +747,7 @@ which matches everything.
 @item :keymap
 Keymap used in the editable field.  The default value is
 @code{widget-field-keymap}, which allows you to use all the normal
-editing commands, even if the buffers major mode suppress some of them.
+editing commands, even if the buffer's major mode suppress some of them.
 Pressing return invokes the function specified by @code{:action}. 
 @end table
 
@@ -757,10 +769,10 @@ Syntax:
 TYPE ::= (menu-choice [KEYWORD ARGUMENT]... TYPE ... )
 @end example
 
-The @var{type} arguments represents each possible choice.  The widgets
-value of will be the value of the chosen @var{type} argument.  This
-widget will match any value that matches at least one of the specified
-@var{type} arguments.
+The @var{type} argument represents each possible choice.  The widget's
+value will be that of the chosen @var{type} argument.  This widget will
+match any value matching at least one of the specified @var{type}
+arguments.
 
 @table @code
 @item :void 
@@ -792,10 +804,10 @@ Syntax:
 TYPE ::= (radio-button-choice [KEYWORD ARGUMENT]...  TYPE ... )
 @end example
 
-The @var{type} arguments represents each possible choice.  The widgets
-value of will be the value of the chosen @var{type} argument.  This
-widget will match any value that matches at least one of the specified
-@var{type} arguments.
+The @var{type} argument represents each possible choice.  The widget's
+value will be that of the chosen @var{type} argument.  This widget will
+match any value matching at least one of the specified @var{type}
+arguments.
 
 The following extra properties are recognized.
 
@@ -882,8 +894,8 @@ Syntax:
 TYPE ::= (toggle [KEYWORD ARGUMENT]...)
 @end example
 
-The widget has two possible states, `on' and `off', which corresponds to
-a @code{t} or @code{nil} value.
+The widget has two possible states, `on' and `off', which correspond to
+a @code{t} or @code{nil} value respectively.
 
 The following extra properties are recognized.
 
@@ -923,10 +935,10 @@ Syntax:
 TYPE ::= (checklist [KEYWORD ARGUMENT]...  TYPE ... )
 @end example
 
-The @var{type} arguments represents each checklist item.  The widgets
-value of will be a list containing the value of each ticked @var{type}
-argument.  The checklist widget will match a list whose elements all
-matches at least one of the specified @var{type} arguments.
+The @var{type} arguments represents each checklist item.  The widget's
+value will be a list containing the values of all ticked @var{type}
+arguments.  The checklist widget will match a list whose elements all
+match at least one of the specified @var{type} arguments.
 
 The following extra properties are recognized.
 
@@ -944,11 +956,11 @@ Insert a literal @samp{%}.
 @end table
 
 @item :greedy
-Usually, a checklist will only match if the items are in the exact
+Usually a checklist will only match if the items are in the exact
 sequence given in the specification.  By setting @code{:greedy} to
-non-nil, it will allow the items to come in any sequence.  However, if
-you extract the value they will be in the sequence given in the
-checklist. I.e. the original sequence is forgotten.
+non-nil, it will allow the items to appear in any sequence.  However, if
+you extract the values they will be in the sequence given in the
+checklist.  I.e. the original sequence is forgotten.
 
 @item button-args
 A list of keywords to pass to the checkboxes.  Useful for setting
@@ -1020,7 +1032,7 @@ List whose car is the type of the list elements.
 @comment  node-name,  next,  previous,  up
 @subsection The @code{group} Widget
 
-This widget simply group other widget together.
+This widget simply groups other widgets together.
 
 Syntax:
 
@@ -1049,8 +1061,8 @@ available.  These basically fall in the following categories.
 @subsection The Constant Widgets.
 
 The @code{const} widget can contain any lisp expression, but the user is
-prohibited from editing edit it, which is mainly useful as a component
-of one of the composite widgets.
+prohibited from editing it, which is mainly useful as a component of one
+of the composite widgets.
 
 The syntax for the @code{const} widget is
 
@@ -1229,13 +1241,13 @@ The value of a widget of this type will either have the form
 @samp{(file t)} or @code{(file string string)}.
 
 This concept of inline is probably hard to understand.  It was certainly
-hard to implement so instead of confuse you more by trying to explain it
-here, I'll just suggest you meditate over it for a while.
+hard to implement so instead of confusing you more by trying to explain
+it here, I'll just suggest you meditate over it for a while.
 
 @deffn Widget choice
-Allows you to edit a sexp which may have one of fixed set of types.  It
-is currently implemented with the @code{choice-menu} basic widget, and
-has a similar syntax.
+Allows you to edit a sexp which may have one of a fixed set of types.
+It is currently implemented with the @code{choice-menu} basic widget,
+and has a similar syntax.
 @end deffn
 
 @deffn Widget set
@@ -1319,9 +1331,9 @@ You can query or set the state with the following code:
 (widget-apply @var{widget} :activate)
 @end lisp
 
-A widget is inactive if itself, or any of its ancestors (found by
+A widget is inactive if itself or any of its ancestors (found by
 following the @code{:parent} link) have been deactivated.  To make sure
-a widget is really active, you must therefore activate both itself, and
+a widget is really active, you must therefore activate both itself and
 all its ancestors.
 
 @lisp
@@ -1331,12 +1343,12 @@ all its ancestors.
 @end lisp
 
 You can check if a widget has been made inactive by examining the value
-of @code{:inactive} keyword.  If this is non-nil, the widget itself has
-been deactivated.  This is different from using the @code{:active}
-keyword, in that the later tell you if the widget @strong{or} any of its
-ancestors have been deactivated.   Do not attempt to set the
+of the @code{:inactive} keyword.  If this is non-nil, the widget itself
+has been deactivated.  This is different from using the @code{:active}
+keyword, in that the latter tells you if the widget @strong{or} any of
+its ancestors have been deactivated.  Do not attempt to set the
 @code{:inactive} keyword directly.  Use the @code{:activate}
-@code{:deactivated} keywords instead.
+@code{:deactivate} keywords instead.
 
 
 @node Defining New Widgets, Widget Browser, Widget Properties, Top
@@ -1344,11 +1356,11 @@ ancestors have been deactivated.   Do not attempt to set the
 @section Defining New Widgets
 
 You can define specialized widgets with @code{define-widget}.  It allows
-you to create a shorthand for more complex widgets, including specifying
-component widgets and default new default values for the keyword
-arguments. 
+you to create a shorthand for more complex widgets.  This includes
+specifying component widgets and new default values for the keyword
+arguments.
 
-@defun widget-define name class doc &rest args
+@defun define-widget name class doc &rest args
 Define a new widget type named @var{name} from @code{class}.
 
 @var{name} and class should both be symbols, @code{class} should be one
@@ -1356,7 +1368,7 @@ of the existing widget types.
 
 The third argument @var{DOC} is a documentation string for the widget.
 
-After the new widget has been defined, the following two calls will
+After the new widget has been defined the following two calls will
 create identical widgets:
 
 @itemize @bullet
@@ -1373,35 +1385,52 @@ create identical widgets:
 
 @end defun
 
-Using @code{widget-define} does just store the definition of the widget
-type in the @code{widget-type} property of @var{name}, which is what
+Using @code{define-widget} just stores the definition of the widget type
+in the @code{widget-type} property of @var{name}, which is what
 @code{widget-create} uses.
 
 If you just want to specify defaults for keywords with no complex
-conversions, you can use @code{identity} as your conversion function.
+conversions, you can use @code{identity} as your @code{:convert-widget}
+function.
 
 The following additional keyword arguments are useful when defining new
 widgets: 
 @table @code
 @item :convert-widget
-Function to convert a widget type before creating a widget of that
-type.  It takes a widget type as an argument, and returns the converted
-widget type.  When a widget is created, this function is called for the
-widget type and all the widgets parent types, most derived first. 
+Method to convert type-specific components of a widget type before
+instantiating a widget of that type.  Not normally called from user
+code, it is invoked by @code{widget-convert}.  Typical operations
+include converting types of child widgets to widget instances and
+converting values from external format (@emph{i.e.}, as expected by the
+calling code) to internal format (which is often different for the
+convenience of widget manipulation).  It takes a widget type as an
+argument, and returns the converted widget type.  When a widget is
+created, the value of this property is called for the widget type, then
+for all the widget's parent types, most derived first.  (The property is
+reevaluated for each parent type.)
 
 The following predefined functions can be used here:
 
 @defun widget-types-convert-widget widget
-Convert @code{:args} as widget types in @var{widget}.
+Convert each member of @code{:args} in @var{widget} from a widget type
+to a widget.
 @end defun
 
 @defun widget-value-convert-widget widget
-Initialize @code{:value} from @code{:args} in @var{widget}.
+Initialize @code{:value} from @code{(car :args)} in @var{widget}, and
+reset @code{:args}.
 @end defun
 
+@item :copy
+A method to implement deep copying of the type.  Any member of the
+widget which might be changed in place (rather than replaced) should be
+copied by this method.  (@code{widget-copy} uses @code{copy-sequence} to
+ensure that the top-level list is a copy.)  This particularly applies to
+child widgets.
+
 @item :value-to-internal
 Function to convert the value to the internal format.  The function
-takes two arguments, a widget and an external value, and returns the
+takes two arguments, a widget and an external value.  It returns the
 internal value.  The function is called on the present @code{:value}
 when the widget is created, and on any value set later with
 @code{widget-value-set}.
@@ -1415,8 +1444,14 @@ when the widget is created, and on any value set later with
 
 @item :create
 Function to create a widget from scratch.  The function takes one
-argument, a widget type, and create a widget of that type, insert it in
-the buffer, and return a widget object.
+argument, a widget, and inserts it in the buffer.  Not normally called
+from user code.  Instead, call @code{widget-create} or related
+functions, which take a type argument, (usually) convert it to a widget,
+call the @code{:create} function to insert it in the buffer, and then
+return the (possibly converted) widget.
+
+The default, @code{widget-default-create}, is invariably appropriate.
+(None of the standard widgets specify @code{:create}.)
 
 @item :delete
 Function to delete a widget.  The function takes one argument, a widget,
@@ -1424,14 +1459,14 @@ and should remove all traces of the widget from the buffer.
 
 @item :value-create
 Function to expand the @samp{%v} escape in the format string.  It will
-be called with the widget as its argument.  Should
-insert a representation of the widgets value in the buffer.
+be called with the widget as its argument and should insert a
+representation of the widget's value in the buffer.
 
 @item :value-delete
-Should remove the representation of the widgets value from the buffer.
+Should remove the representation of the widget's value from the buffer.
 It will be called with the widget as its argument.  It doesn't have to
 remove the text, but it should release markers and delete nested widgets
-if such has been used.
+if such have been used.
 
 The following predefined function can be used here:
 
@@ -1455,12 +1490,14 @@ will be called with the widget and the escape character as arguments.
 You can set this to allow your widget to handle non-standard escapes.
 
 You should end up calling @code{widget-default-format-handler} to handle
-unknown escape sequences, which will handle the @samp{%h} and any future
-escape sequences, as well as give an error for unknown escapes.
+unknown escape sequences.  It will handle the @samp{%h} and any future
+escape sequences as well as give an error for unknown escapes.
 
 @item :action
 Function to handle user initiated events.  By default, @code{:notify}
-the parent. 
+the parent.  Actions normally do not include mere edits, but refer to
+things like invoking buttons or hitting enter in an editable field.  To
+watch for any change, redefine the @code{:notify} callback.
 
 The following predefined function can be used here:
 
@@ -1474,9 +1511,9 @@ Function to prompt for a value in the minibuffer.  The function should
 take four arguments, @var{widget}, @var{prompt}, @var{value}, and
 @var{unbound} and should return a value for widget entered by the user.
 @var{prompt} is the prompt to use.  @var{value} is the default value to
-use, unless @var{unbound} is non-nil in which case there are no default
+use, unless @var{unbound} is non-nil.  In this case there is no default
 value.  The function should read the value using the method most natural
-for this widget, and does not have to check that it matches.
+for this widget and does not have to check whether it matches.
 @end table
 
 If you want to define a new widget from scratch, use the @code{default}
@@ -1489,6 +1526,43 @@ It provides most of the functionality that is referred to as ``by
 default'' in this text. 
 @end deffn
 
+In implementing complex hierarchical widgets (@emph{e.g.}, using the
+@samp{group} widget), the following functions may be useful.
+The syntax for the @var{type} arguments to these functions is described
+in @ref{Basic Types}.
+
+@defun widget-create-child-and-convert parent type &rest args
+As a child of @var{parent}, create a widget with type @var{type} and
+value @var{value}.  @var{type} is copied, and the @code{:widget-contvert}
+method is applied to the optional keyword arguments from @var{args}.
+@end defun
+
+@defun widget-create-child parent type
+As a child of @var{parent}, create a widget with type @var{type}.
+@var{type} is copied, but no conversion method is applied.
+@end defun
+
+@defun widget-create-child-value parent type value
+As a child of @var{parent}, create a widget with type @var{type} and
+value @var{value}.  @var{type} is copied, but no conversion method is
+applied.
+@end defun
+
+@defun widget-convert type &rest args
+Convert @var{type} to a widget without inserting it in the buffer.
+The optional @var{args} are additional keyword arguments.
+
+The widget's @code{:args} property is set from the longest tail of
+@var{args} whose @samp{cdr} is not a keyword, or if that is null, from
+the longest tail of @var{type}'s @code{:args} property whose cdr is not
+a keyword.  Keyword arguments from @var{args} are set, and the
+@code{:value} property (if any) is converted from external to internal
+format.
+@end defun
+
+@code{widget-convert} is typically not called from user code; rather it
+is called implicitly through the @samp{widget-create*} functions.
+
 @node Widget Browser, Widget Minor Mode, Defining New Widgets, Top
 @comment  node-name,  next,  previous,  up
 @section Widget Browser
@@ -1545,7 +1619,7 @@ Get the item @var{widget} is assumed to toggle.@*
 This is only meaningful for radio buttons or checkboxes in a list.
 @end defun
 
-@node  Widget Wishlist,  , Utilities, Top
+@node Widget Wishlist, Widget Internals, Utilities, Top
 @comment  node-name,  next,  previous,  up
 @section Wishlist
 
@@ -1607,7 +1681,7 @@ A mailto widget.
 the field, not the end of the field itself. 
 
 @item
-Use and overlay instead of markers to delimit the widget.  Create
+Use an overlay instead of markers to delimit the widget.  Create
 accessors for the end points.
 
 @item
@@ -1618,5 +1692,35 @@ symbol, it should pop up a menu.
 
 @end itemize
 
+@node Widget Internals, , Widget Wishlist, Top
+@section Internals
+
+This (very brief!) section provides a few notes on the internal
+structure and implementation of Emacs widgets.  Avoid relying on this
+information.  (We intend to improve it, but this will take some time.)
+To the extent that it actually describes APIs, the information will be
+moved to appropriate sections of the manual in due course.
+
+@subsection The @dfn{Widget} and @dfn{Type} Structures
+
+Widgets and types are currently both implemented as lists.
+
+A symbol may be defined as a @dfn{type name} using @code{define-widget}.
+@xref{Defining New Widgets}.  A @dfn{type} is a list whose car is a
+previously defined type name, nil, or (recursively) a type.  The car is
+the @dfn{class} or parent type of the type, and properties which are not
+specified in the new type will be inherited from ancestors.  Probably
+the only type without a class should be the @code{default} type.  The
+cdr of a type is a plist whose keys are widget property keywords.
+
+A type or type name may also be referred to as an @dfn{unconverted
+widget}.
+
+A @dfn{converted widget} or @dfn{widget instance} is a list whose car is
+a type name or a type, and whose cdr is a property list.  Furthermore,
+all children of the converted widget must be converted.  Finally, in the
+process of appropriate parts of the list structure are copied to ensure
+that changes in values of one instance do not affect another's.
+
 @contents
 @bye