[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This chapter is only for people who are familiar with Emacs Lisp and wish to customize Hyperbole, to extend it, or to develop other systems using Hyperbole as a base.
10.1 Hook Variables | ||
10.2 Creating Types | ||
10.3 Explicit Button Technicalities | ||
10.4 Encapsulating Systems | ||
10.5 Embedding Hyperbole |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Hyperbole provides a number of hook variables that allow you to adjust its basic operations to meet your own needs, without requiring you to change the code for those operations.
We find it best to always set the value of hook variables either to nil or to a list of function names of no arguments, each of which will be called in sequence when the hook is triggered.
Given the name of a function, a Hyperbole hook variable triggered within
that function has the same name as the function with a -hook
appended. Hyperbole provides the following hook variables:
Hyperbole also makes use of a number of external Emacs hook variables.
Hyperbole mail and news facilities also utilize a number of external hook variables. These hide button data and highlight buttons if possible. See the various support files for details.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
To define or redefine a single Hyperbole type, you may either:
(eval-defun)
(only works in Emacs Lisp mode);
(eval-last-sexp)
(works in most modes).
The functions from the htype
class may be applied to any
Hyperbole types, if needed.
The following subsections explain the specifics of Hyperbole type definitions which are beyond standard practice for Emacs Lisp programming. See the definitions of the standard types in `hactypes.el' and `hibtypes.el' for examples.
10.2.1 Action Type Creation | ||
10.2.2 Implicit Button Types |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
New forms of explicit buttons may be created by adding new action types to a Hyperbole environment. The file, `hactypes.el', provides many examples of working action types.
An action type is created, i.e. loaded into the Hyperbole environment,
with the (defact)
function (which is an alias for
(actype:create)
). The calling signature for this function is
given in its documentation; it is the same as that of (defun)
except that a documentation string is required. (An interactive calling
form is also required if the action type has formal parameters and is to
be used in explicit button definitions. Implicit buttons never use an
action type's interactive form. It is good practice to include an
interactive form since the type creator cannot know how users may choose
to apply the type.)
An action type's parameters are used differently than those of a function being called. Its interactive calling form is used when an explicit button is created to prompt for type-specific button attributes. The rest of its body is used when a button with that action type is activated. Then the button attributes together with the action type body are used to form an action that is executed in response to the button activation. The action's result is returned to the action caller unless it returns nil, in which case t is returned to the caller to ensure that it registers the performance of the action.
An action type body may perform any computation using Emacs Lisp and Hyperbole functions.
The interactive calling form for an action type is of the same form as
that of a regular Emacs Lisp function definition (see the documentation
for the Emacs Lisp (interactive)
form). It may additionally use
Hyperbole command character extensions when the form is given as a
string. Each such extension character must be preceded by a plus
sign, +
, in order to be recognized since such characters may also
have standard interactive form meanings.
The present Hyperbole extension characters are:
Arguments are read by the functions in Hyperbole's hargs
class,
rather than the standard Lisp read
functions, in order to allow
direct selection of arguments via the Action Key.
If an action type create is successful, the symbol that Hyperbole uses
internally to reference the type is returned. Nil
is returned on
failure so that you may test whether or not the operation succeeds.
Once you have defined an action type within your present Hyperbole environment, you can create new explicit buttons which use it. There is no explicit button type beyond its action type, so no further work is necessary.
Call (actype:delete)
to remove an action type from a Hyperbole
environment. It takes a single parameter which should be the same type
symbol used in the type definition call (not the Hyperbole symbol
returned by the call).
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
An implicit button type is created or loaded via the (defib)
function (which is an alias for (ibtype:create)
). The calling
signature for this function is given in its documentation; it is the
same as that of (defun)
, but with a number of constraints. The
parameter list should always be empty since no parameters will be used.
A documentation string is required. The type's body follows this.
The body of an implicit button type is a predicate which determines
whether or not point is within an implicit button of the type. If not,
the predicate returns nil
. If so, it may optionally setup to
flash the button and then perform one or more actions. A call of the
form: (ibut:label-set label start-pos end-pos)
is used to setup
the button flashing, if desired. This is then typically immediately
followed by an action invocation of the form:
(hact 'actype &rest actype-arguments)
. It is imperative that all
actions (non-predicate code) be invoked through the (hact)
function rather than directly or your ibtypes will not work properly.
(Hyperbole first tests to see if any ibtype matches the current context
before activating any type, so it ensures that (hact)
calls are
disabled during this testing.) Any action types used may be created
before or after the implicit button type definition but obviously should
be defined before any implicit buttons of the given type are activated;
an error will result, otherwise.
If an implicit button type create is successful, the symbol that
Hyperbole uses internally to reference the type is returned. Nil
is returned on failure so that you may test whether or not the operation
succeeds. Implicit button type names and action type names may be the
same without any conflict. In fact, such naming is encouraged when an
implicit button type is the exclusive user of an action type.
Call (ibtype:delete)
to remove an implicit button type from a
Hyperbole environment. It takes a single parameter which should be the
same type symbol used in the type definition call (not the Hyperbole
symbol returned by the call). This will not delete the action type used
by the implicit button; that must be done separately.
By default, a request for help on an implicit button will display the
button's attributes in the same manner as is done for explicit buttons.
For some implicit button types, other forms of help will be more
appropriate. If an Emacs Lisp function is defined whose name is formed
from the concatenation of the type name followed by :help
, e.g.
my-ibtype:help
, it is used to respond to requests for
help on buttons of that type. Any such function should take a single
argument of an implicit button construct. (This is what
(ibut:at-p)
returns when point is within an implicit button
context.) The button may be queried for its attributes using functions
from the hbut
and hattr
classes. See the `hib-kbd.el'
file for an example of a custom help function.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
10.3.1 Button Label Normalization | ||
10.3.2 Operational and Storage Formats | ||
10.3.3 Programmatic Button Creation |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
(hbut:label-to-key)
for details of the normalization
process. The normalized form permits Hyperbole to recognize buttons that
are the same but whose labels appear different from one another, due to
text formatting conventions. For example, all of the following would
be recognized as the same button.
<(fake button)> <( fake button)> Pam> <(fake Pam> button)> ;; <(fake ;; button)> /* <( fake */ /* button )> */ |
The last three examples demonstrate how Hyperbole ignores common fill prefix patterns that happen to fall within the middle of a button label that spans multiple lines. As long as such buttons are selected with point at a location within the label's first line, the button will be recognized. The variable hbut:fill-prefix-regexps holds the list of fill prefixes recognized when embedded within button labels. All such prefixes are recognized (one per button label), regardless of the setting of the GNU Emacs variable, fill-prefix, so no user intervention is required.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Hyperbole uses a terse format to store explicit buttons and a more meaningful one to show users and to manipulate during editing. The terse format consists solely of button attribute values whereas the edit format includes an attribute name with each attribute value. A button in edit format consists of a Lisp symbol together with its attribute list which holds the attribute names and values. In this way, buttons may be passed along from function to function simply by passing the symbol to which the button is attached. Most functions utilize the pre-defined hbut:current symbol by default to store and retrieve the last encountered button in edit format.
The hbdata
class handles the terse, stored format. The
hbut
, ebut
, and ibut
classes work with the
name/value format. This separation permits the wholesale replacement of
the storage manager with another, with any interface changes hidden from
any Hyperbole client programming.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A common need when developing with Hyperbole is the ability to create or modify explicit buttons without user interaction. For example, an application might require the addition of an explicit summary button to a file for each new mail message a user reads that contains a set of keywords. The user could then check the summary file and jump to desired messages quickly.
The Hyperbole class ebut
supports programmatic access to explicit
buttons. See it within the `hbut.el' file for full details. The
documentation for (ebut:create)
explains the set of attributes
settings necessary to create an explicit button. For operations over
the whole set of buttons within the visible (non-narrowed) portion of a
buffer, use the (ebut:map)
function.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A powerful use of implicit button types is to provide a Hyperbole-based interface to external systems. The basic idea is to interpret patterns output by the application as implicit buttons.
See the `hsys-*' files for examples of how to do this. Encapsulations are provided for the following systems (the systems themselves are not included with Hyperbole):
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[NOTE: We have never done this ourselves, though we have done similar things which leads us to infer that the task should not be difficult.]
The standard Emacs-based Hyperbole user interface has purposely been separated from the Hyperbole backend to support the development of alternative interfaces and the embedding of Hyperbole functionality within other system prototypes. The Hyperbole backend functionality that system developers can make use of is called its Application Programming Interface (API). The API may be used to make server-based calls to Hyperbole when Emacs is run as a non-interactive (batch) process, with its input/output streams attached to another process.
The public functions and variables from the following files may be considered the present Hyperbole API:
`hact.el', `hargs.el', `hbmap.el', `hbut.el', `hhist.el', `hmail.el', `hmoccur.el', `hpath.el', `htz.el', `hypb.el', `set.el', `wconfig.el', `wrolo.el', and `wrolo-logic.el'.
Note when looking at these files, that they are divided into sections that separate one data abstraction (class) from another. A line of dashes within a class separates public parts of the class from the private parts that follow the line.
This API does not include the Hyperbole outliner, as it has been designed for interactive use, rather than programmatic extensibility. You can certainly study its code, below the `hyperbole/kotl/' directory and learn to program it, however.
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated by XEmacs shared group account on December, 19 2009
using texi2html 1.65.