File: forms.el.html
Visit a file using a form. See etc/forms for examples.
=== Naming conventions
The names of all variables and functions start with 'forms-'. Names which start with 'forms--' are intended for internal use, and should *NOT* be used from the outside.
All variables are buffer-local, to enable multiple forms visits
simultaneously.
Variable forms--mode-setup is local to *ALL* buffers, for it
controls if forms-mode has been enabled in a buffer.
=== How it works ===
Forms mode means visiting a data file which is supposed to consist of records each containing a number of fields. The records are separated by a newline, the fields are separated by a user-defined field separator (default: TAB). When shown, a record is transferred to an Emacs buffer and presented using a user-defined form. One record is shown at a time.
Forms mode is a composite mode. It involves two files, and two buffers. The first file, called the control file, defines the name of the data file and the forms format. This file buffer will be used to present the forms. The second file holds the actual data. The buffer of this file will be buried, for it is never accessed directly.
Forms mode is invoked using M-x forms-find-file control-file.
Alternatively forms-find-file-other-window can be used.
You may also visit the control file, and switch to forms mode by hand
with M-x forms-mode.
Automatic mode switching is supported if you specify
"-*- forms -*-" in the first line of the control file.
The control file is visited, evaluated using eval-buffer,
and should set at least the following variables:
forms-file [string]
The name of the data file.
forms-number-of-fields [integer]
The number of fields in each record.
forms-format-list [list]
Formatting instructions.
forms-format-list should be a list, each element containing
- a string, e.g. "hello". The string is inserted in the forms
"as is".
- an integer, denoting a field number.
The contents of this field are inserted at this point.
Fields are numbered starting with number one.
- a function call, e.g. (insert "text").
This function call is dynamically evaluated and should return a
string. It should *NOT* have side-effects on the forms being
constructed. The current fields are available to the function
in the variable forms-fields, they should *NOT* be modified.
- a Lisp symbol, that must evaluate to one of the above.
Optional variables which may be set in the control file:
forms-field-sep [string, default TAB]
The field separator used to separate the
fields in the data file. It may be a string.
forms-read-only [bool, default nil]
Non-nil means that the data file is visited
read-only (view mode) as opposed to edit mode.
If no write access to the data file is
possible, view mode is enforced.
forms-check-number-of-fields [bool, default t]
If non-nil, a warning will be issued whenever
a record is found that does not have the number
of fields specified by forms-number-of-fields.
forms-multi-line [string, default "^K"]
If non-null, the records of the data file may
contain fields that can span multiple lines in
the form.
This variable denotes the separator string
to be used for this purpose. Upon display, all
occurrences of this string are translated
to newlines. Upon storage they are translated
back to the separator string.
forms-forms-scroll [bool, default nil]
Non-nil means: rebind locally the commands that
perform scroll-up or scroll-down to use
forms-next-field resp. forms-prev-field.
forms-forms-jump [bool, default nil]
Non-nil means: rebind locally the commands
beginning-of-buffer and end-of-buffer to
perform, respectively, forms-first-record and
forms-last-record instead.
forms-insert-after [bool, default nil]
Non-nil means: insertions of new records go after
current record, also initial position is at the
last record. The default is to insert before the
current record and the initial position is at the
first record.
forms-read-file-filter [symbol, default nil]
If not nil: this should be the name of a
function that is called after the forms data file
has been read. It can be used to transform
the contents of the file into a format more suitable
for forms-mode processing.
forms-write-file-filter [symbol, default nil]
If not nil: this should be the name of a
function that is called before the forms data file
is written (saved) to disk. It can be used to undo
the effects of forms-read-file-filter, if any.
forms-new-record-filter [symbol, default nil]
If not nil: this should be the name of a
function that is called when a new
record is created. It can be used to fill in
the new record with default fields, for example.
forms-modified-record-filter [symbol, default nil]
If not nil: this should be the name of a
function that is called when a record has
been modified. It is called after the fields
are parsed. It can be used to register
modification dates, for example.
forms-use-text-properties [bool, see text for default]
This variable controls if forms mode should use
text properties to protect the form text from being
modified (using text-property read-only).
Also, the read-write fields are shown using a
distinct face, if possible.
The intangible text property is used to
prevent moving into read-only fields.
This variable defaults to t.
The default face to show read-write fields is
copied from face region.
forms-ro-face [symbol, default 'default]
This is the face that is used to show
read-only text on the screen. If used, this
variable should be set to a symbol that is a
valid face.
E.g.
(make-face 'my-face)
(setq forms-ro-face 'my-face)
forms-rw-face [symbol, default 'region]
This is the face that is used to show
read-write text on the screen.
After evaluating the control file, its buffer is cleared and used
for further processing.
The data file (as designated by forms-file) is visited in a buffer
forms--file-buffer which normally will not be shown.
Great malfunctioning may be expected if this file/buffer is modified
outside of this package while it is being visited!
Normal operation is to transfer one line (record) from the data file,
split it into fields (into forms--the-record-list), and display it
using the specs in forms-format-list.
A format routine forms--format is built upon startup to format
the records according to forms-format-list.
When a form is changed the record is updated as soon as this form
is left. The contents of the form are parsed using information
obtained from forms-format-list, and the fields which are
deduced from the form are modified. Fields not shown on the forms
retain their original values. The newly formed record then
replaces the contents of the old record in forms--file-buffer.
A parse routine forms--parser is built upon startup to parse
the records.
Two exit functions exist: forms-exit and forms-exit-no-save.
forms-exit saves the data to the file, if modified.
forms-exit-no-save does not. However, if forms-exit-no-save
is executed and the file buffer has been modified, Emacs will ask
questions anyway.
Other functions provided by forms mode are:
paging (forward, backward) by record jumping (first, last, random number) searching creating and deleting records reverting the form (NOT the file buffer) switching edit <-> view mode v.v. jumping from field to field
As a documented side-effect: jumping to the last record in the file (using forms-last-record) will adjust forms--total-records if needed.
The forms buffer can be in one of two modes: edit mode or view mode. View mode is a read-only mode, whereby you cannot modify the contents of the buffer.
Edit mode commands:
TAB forms-next-field
\C-c TAB forms-next-field
\C-c < forms-first-record
\C-c > forms-last-record
\C-c ? describe-mode
\C-c \C-k forms-delete-record
\C-c \C-q forms-toggle-read-only
\C-c \C-o forms-insert-record
\C-c \C-l forms-jump-record
\C-c \C-n forms-next-record
\C-c \C-p forms-prev-record
\C-c \C-r forms-search-backward
\C-c \C-s forms-search-forward
\C-c \C-x forms-exit
Read-only mode commands:
SPC forms-next-record
DEL forms-prev-record
? describe-mode
\C-q forms-toggle-read-only
l forms-jump-record
n forms-next-record
p forms-prev-record
r forms-search-backward
s forms-search-forward
x forms-exit
Of course, it is also possible to use the \C-c prefix to obtain the same command keys as in edit mode.
The following bindings are available, independent of the mode:
[next] forms-next-record
[prior] forms-prev-record
[begin] forms-first-record
[end] forms-last-record
[S-TAB] forms-prev-field
[backtab] forms-prev-field
For convenience, TAB is always bound to forms-next-field, so you
don't need the C-c prefix for this command.
As mentioned above (see forms-forms-scroll and forms-forms-jump),
the bindings of standard functions scroll-up, scroll-down,
beginning-of-buffer and end-of-buffer can be locally replaced with
forms mode functions next/prev record and first/last
record.
write-file-functions is defined to save the actual data file
instead of the buffer data, revert-buffer-function is defined to
revert a forms to original.
Defined variables (39)
forms--current-record | Number of the record currently on the screen. |
forms--debug | If non-nil, enable Forms mode debugging. |
forms--dynamic-text | Array that holds dynamic texts to insert between fields. |
forms--dyntexts | Dynamic texts (resulting from function calls) on the screen. |
forms--elements | Array with the order in which the fields are displayed. |
forms--file-buffer | Buffer which holds the file data. |
forms--format | Formatting routine. |
forms--iif-properties | Original properties of the character being overridden. |
forms--iif-start | Record start of modification command. |
forms--markers | Field markers in the screen. |
forms--mode-setup | To keep track of ‘forms-mode’ being set-up. |
forms--parser | Forms parser routine. |
forms--ro-face | Face used to represent read-only data on the screen. |
forms--rw-face | Face used to represent read-write data on the screen. |
forms--search-regexp | Last regexp used by forms-search functions. |
forms--the-record-list | List of strings of the current record, as parsed from the file. |
forms--total-records | Total number of records in the data file. |
forms-check-number-of-fields | If non-nil, warn about records with wrong number of fields. |
forms-field-sep | Field separator character (default TAB). |
forms-fields | List with fields of the current forms. First field has number 1. |
forms-file | Name of the file holding the data. |
forms-format-list | List of formatting specifications. |
forms-forms-jump | Non-nil means redefine beginning/end-of-buffer in Forms mode. |
forms-forms-scroll | Non-nil means replace scroll-up/down commands in Forms mode. |
forms-insert-after | Non-nil means: inserts of new records go after current record. |
forms-mode-edit-map | Keymap for form buffer in edit mode. |
forms-mode-hook | Hook run upon entering Forms mode. |
forms-mode-map | Keymap for form buffer. |
forms-mode-ro-map | Keymap for form buffer in view mode. |
forms-modified-record-filter | The name of a function that is called when a record has been modified. |
forms-multi-line | If not nil: use this character to separate multi-line fields (default C-k). |
forms-new-record-filter | The name of a function that is called when a new record is created. |
forms-number-of-fields | Number of fields per record. |
forms-read-file-filter | The name of a function that is called after reading the data file. |
forms-read-only | Non-nil means: visit the file in view (read-only) mode. |
forms-ro-face | The face (a symbol) that is used to display read-only text on the screen. |
forms-rw-face | The face (a symbol) that is used to display read-write text on the screen. |
forms-use-text-properties | Non-nil means to use text properties. |
forms-write-file-filter | The name of a function that is called before writing the data file. |