1\input texinfo                  @c -*-texinfo-*-
2@c documentation for forms-mode
3@c Written by Johan Vromans, and edited by Richard Stallman
4
5@comment %**start of header (This is for running Texinfo on a region.)
6@setfilename ../../info/forms.info
7@settitle Forms Mode User's Manual
8@include docstyle.texi
9@include emacsver.texi
10@syncodeindex vr cp
11@syncodeindex fn cp
12@syncodeindex ky cp
13@iftex
14@finalout
15@setchapternewpage odd
16@end iftex
17@c      @smallbook
18@comment %**end of header (This is for running Texinfo on a region.)
19
20@copying
21This file documents Forms mode, a form-editing major mode for GNU Emacs.
22
23Copyright @copyright{} 1989, 1997, 2001--2021 Free Software Foundation,
24Inc.
25
26@quotation
27Permission is granted to copy, distribute and/or modify this document
28under the terms of the GNU Free Documentation License, Version 1.3 or
29any later version published by the Free Software Foundation; with no
30Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,''
31and with the Back-Cover Texts as in (a) below.  A copy of the license
32is included in the section entitled ``GNU Free Documentation License''.
33
34(a) The FSF's Back-Cover Text is: ``You have the freedom to copy and
35modify this GNU manual.''
36@end quotation
37@end copying
38
39@dircategory Emacs misc features
40@direntry
41* Forms: (forms).               Emacs package for editing data bases
42                                  by filling in forms.
43@end direntry
44
45@titlepage
46@sp 6
47@center @titlefont{Forms Mode User's Manual}
48@sp 4
49@center Forms-Mode version 2
50@sp 1
51@center for GNU Emacs @value{EMACSVER}
52@sp 1
53@center April 2007
54@sp 5
55@center Johan Vromans
56@center @i{jvromans@@squirrel.nl}
57@page
58@vskip 0pt plus 1filll
59@insertcopying
60@end titlepage
61
62@contents
63
64@ifnottex
65@node Top
66@top Forms Mode
67
68Forms mode is an Emacs major mode for working with simple textual data
69bases in a forms-oriented manner.  In Forms mode, the information in
70these files is presented in an Emacs window in a user-defined format,
71one record at a time.  The user can view records or modify their
72contents.
73
74Forms mode is not a simple major mode, but requires two files to do its
75job: a control file and a data file.  The data file holds the
76actual data to be presented.  The control file describes
77how to present it.
78
79@insertcopying
80
81@menu
82* Forms Example::               An example: editing the password data base.
83* Entering and Exiting Forms Mode::
84                                How to visit a file in Forms mode.
85* Forms Commands::              Special commands to use while in Forms mode.
86* Data File Format::            How to format the data file.
87* Control File Format::         How to control forms mode.
88* Format Description::          How to define the forms layout.
89* Modifying Forms Contents::    How to modify.
90* Miscellaneous::               Forms mode messages and other remarks.
91* Error Messages::              List of error messages forms mode can produce.
92* Long Example::                A more complex control file example.
93* Credits::                     Thanks everyone.
94* GNU Free Documentation License:: The license for this documentation.
95* Index::                       Index to this manual.
96@end menu
97@end ifnottex
98
99@node Forms Example
100@chapter Forms Example
101
102Let's illustrate Forms mode with an example.  Suppose you are looking at
103the @file{/etc/passwd} file, and the screen looks like this:
104
105@example
106====== /etc/passwd ======
107
108User : root   Uid: 0   Gid: 1
109
110Name : Super User
111
112Home : /
113
114Shell: /bin/sh
115@end example
116
117As you can see, the familiar fields from the entry for the super user
118are all there, but instead of being colon-separated on one single line,
119they make up a forms.
120
121The contents of the forms consist of the contents of the fields of the
122record (e.g., @samp{root}, @samp{0}, @samp{1}, @samp{Super User})
123interspersed with normal text (e.g., @samp{User : }, @samp{Uid: }).
124
125If you modify the contents of the fields, Forms mode will analyze your
126changes and update the file appropriately.  You cannot modify the
127interspersed explanatory text (unless you go to some trouble about it),
128because that is marked read-only (@pxref{Text Properties,,, elisp, The
129Emacs Lisp Reference Manual}).
130
131The Forms mode control file specifies the relationship between the
132format of @file{/etc/passwd} and what appears on the screen in Forms
133mode.  @xref{Control File Format}.
134
135@node Entering and Exiting Forms Mode
136@chapter Entering and Exiting Forms Mode
137
138@table @kbd
139@findex forms-find-file
140@item M-x forms-find-file @key{RET} @var{control-file} @key{RET}
141Visit a database using Forms mode.  Specify the name of the
142@strong{control file}, not the data file!
143
144@findex forms-find-file-other-window
145@item M-x forms-find-file-other-window @key{RET} @var{control-file} @key{RET}
146Similar, but displays the file in another window.
147@end table
148
149The command @code{forms-find-file} evaluates the file
150@var{control-file}, and also visits it in Forms mode.  What you see in
151its buffer is not the contents of this file, but rather a single record
152of the corresponding data file that is visited in its own buffer.  So
153there are two buffers involved in Forms mode: the @dfn{forms buffer}
154that is initially used to visit the control file and that shows the
155records being browsed, and the @dfn{data buffer} that holds the data
156file being visited.  The latter buffer is normally not visible.
157
158Initially, the first record is displayed in the forms buffer.
159The mode line displays the major mode name @samp{Forms}, followed by the
160minor mode @samp{View} if the data base is read-only.  The number of the
161current record (@var{n}) and the total number of records in the
162file(@var{t}) are shown in the mode line as @samp{@var{n}/@var{t}}.  For
163example:
164
165@example
166--%%-Emacs: passwd-demo          (Forms View 1/54)----All-------
167@end example
168
169If the buffer is not read-only, you may change the buffer to modify the
170fields in the record.  When you move to a different record, the contents
171of the buffer are parsed using the specifications in
172@code{forms-format-list}, and the data file is updated.  If the record
173has fields that aren't included in the display, they are not changed.
174
175@vindex forms-mode-hook
176Entering Forms mode runs the normal hook @code{forms-mode-hook} to
177perform user-defined customization.
178
179To save any modified data, you can use @kbd{C-x C-s}
180(@code{forms-save-buffer}).  This does not save the forms buffer (which would
181be rather useless), but instead saves the buffer visiting the data file.
182
183To terminate Forms mode, you can use @kbd{C-x C-s} (@code{forms-save-buffer})
184and then kill the forms buffer.  However, the data buffer will still
185remain.  If this is not desired, you have to kill this buffer too.
186
187@node Forms Commands
188@chapter Forms Commands
189
190The commands of Forms mode belong to the @kbd{C-c} prefix, with one
191exception: @key{TAB}, which moves to the next field.  Forms mode uses
192different key maps for normal mode and read-only mode.  In read-only
193Forms mode, you can access most of the commands without the @kbd{C-c}
194prefix, but you must type ordinary letters instead of control
195characters; for example, type @kbd{n} instead of @kbd{C-c C-n}.
196
197If your Emacs has been built with X-toolkit support, Forms mode will
198provide its own menu with a number of Forms mode commands.
199
200@table @kbd
201@findex forms-next-record
202@kindex C-c C-n
203@item C-c C-n
204Show the next record (@code{forms-next-record}).  With a numeric
205argument @var{n}, show the @var{n}th next record.
206
207@findex forms-prev-record
208@kindex C-c C-p
209@item C-c C-p
210Show the previous record (@code{forms-prev-record}).  With a numeric
211argument @var{n}, show the @var{n}th previous record.
212
213@findex forms-jump-record
214@kindex C-c C-l
215@item C-c C-l
216Jump to a record by number (@code{forms-jump-record}).   Specify
217the record number with a numeric argument.
218
219@findex forms-first-record
220@kindex C-c <
221@item C-c <
222Jump to the first record (@code{forms-first-record}).
223
224@findex forms-last-record
225@kindex C-c >
226@item C-c >
227Jump to the last record (@code{forms-last-record}).  This command also
228recalculates the number of records in the data file.
229
230@findex forms-next-field
231@kindex TAB
232@item @key{TAB}
233@kindex C-c TAB
234@itemx C-c @key{TAB}
235Jump to the next field in the current record (@code{forms-next-field}).
236With a numeric argument @var{n}, jump forward @var{n} fields.  If this command
237would move past the last field, it wraps around to the first field.
238
239@findex forms-toggle-read-only
240@kindex C-c C-q
241@item C-c C-q
242Toggles read-only mode (@code{forms-toggle-read-only}).  In read-only
243Forms mode, you cannot edit the fields; most Forms mode commands can be
244accessed without the prefix @kbd{C-c} if you use the normal letter
245instead (for example, type @kbd{n} instead of @kbd{C-c C-n}).  In edit
246mode, you can edit the fields and thus change the contents of the data
247base; you must begin Forms mode commands with @code{C-c}.  Switching
248to edit mode is allowed only if you have write access to the data file.
249
250@findex forms-insert-record
251@kindex C-c C-o
252@item C-c C-o
253Create a new record and insert it before the current record
254(@code{forms-insert-record}).  It starts out with empty (or default)
255contents for its fields; you can then edit the fields.  With a numeric
256argument, the new record is created @emph{after} the current one.
257See also @code{forms-modified-record-filter} in @ref{Modifying Forms
258Contents}.
259
260@findex forms-delete-record
261@kindex C-c C-k
262@item C-c C-k
263Delete the current record (@code{forms-delete-record}).  You are
264prompted for confirmation before the record is deleted unless a numeric
265argument has been provided.
266
267@findex forms-search-forward
268@kindex C-c C-s @var{regexp} RET
269@item C-c C-s @var{regexp} @key{RET}
270Search forward for @var{regexp} in all records following this one
271(@code{forms-search-forward}).  If found, this record is shown.
272If you give an empty argument, the previous regexp is used again.
273
274@findex forms-search-backward
275@kindex C-c C-r @var{regexp} RET
276@item C-c C-r @var{regexp} @key{RET}
277Search backward for @var{regexp} in all records following this one
278(@code{forms-search-backward}).  If found, this record is shown.
279If you give an empty argument, the previous regexp is used again.
280
281@ignore
282@findex forms-exit
283@kindex C-c C-x
284@item C-c C-x
285Terminate Forms mode processing (@code{forms-exit}).  The data file is
286saved if it has been modified.
287
288@findex forms-exit-no-save
289@item M-x forms-exit-no-save
290Terminates forms mode processing without saving modified data first.
291@end ignore
292
293@findex forms-prev-field
294@item M-x forms-prev-field
295Similar to @code{forms-next-field} but moves backwards.
296
297@findex forms-save-buffer
298@item M-x forms-save-buffer
299@kindex C-x C-s
300@itemx C-x C-s
301Forms mode replacement for @code{save-buffer}. When executed in the
302forms buffer it will save the contents of the (modified) data buffer
303instead. In Forms mode this function will be bound to @kbd{C-x C-s}.
304
305@findex forms-print
306@item M-x forms-print
307This command can be used to make a formatted print
308of the contents of the data file.
309
310@end table
311
312In addition the command @kbd{M-x revert-buffer} is useful in Forms mode
313just as in other modes.
314
315@ignore
316@vindex forms-forms-scroll
317@findex scroll-up
318@findex scroll-down
319If the variable @code{forms-forms-scrolls} is set to a value other
320than @code{nil} (which it is, by default), the Emacs functions
321@code{scroll-up} and @code{scroll-down} will perform a
322@code{forms-next-record} and @code{forms-prev-record} when in forms
323mode.  So you can use your favorite page commands to page through the
324data file.
325
326@vindex forms-forms-jump
327@findex beginning-of-buffer
328@findex end-of-buffer
329Likewise, if the variable @code{forms-forms-jump} is not @code{nil}
330(which it is, by default), Emacs functions @code{beginning-of-buffer}
331and @code{end-of-buffer} will perform @code{forms-first-record} and
332@code{forms-last-record} when in forms mode.
333@end ignore
334
335The following function key definitions are set up in Forms mode
336(whether read-only or not):
337
338@table @kbd
339@kindex NEXT
340@item @key{NEXT}
341forms-next-record
342
343@kindex PRIOR
344@item @key{PRIOR}
345forms-prev-record
346
347@kindex BEGIN
348@item @key{BEGIN}
349forms-first-record
350
351@kindex END
352@item @key{END}
353forms-last-record
354
355@kindex S-TAB
356@findex forms-prev-field
357@item S-@key{TAB}
358forms-prev-field
359@end table
360
361@node Data File Format
362@chapter Data File Format
363
364@cindex record
365@cindex field
366@vindex forms-field-sep
367Files for use with Forms mode are very simple---each @dfn{record}
368(usually one line) forms the contents of one form.  Each record consists
369of a number of @dfn{fields}, which are separated by the value of the
370string @code{forms-field-sep}, which is @code{"\t"} (a Tab) by default.
371
372@vindex forms-read-file-filter
373@vindex forms-write-file-filter
374If the format of the data file is not suitable enough you can define the
375filter functions @code{forms-read-file-filter} and
376@code{forms-write-file-filter}. @code{forms-read-file-filter} is called
377when the data file is read from disk into the data buffer. It operates
378on the data buffer, ignoring read-only protections. When the data file
379is saved to disk @code{forms-write-file-filter} is called to cancel the
380effects of @code{forms-read-file-filter}. After being saved,
381@code{forms-read-file-filter} is called again to prepare the data buffer
382for further processing.
383
384@cindex pseudo-newline
385@vindex forms-multi-line
386Fields may contain text which shows up in the forms in multiple lines.
387These lines are separated in the field using a ``pseudo-newline''
388character which is defined by the value of the string
389@code{forms-multi-line}.  Its default value is @code{"\^k"} (a Control-K
390character).  If it is
391set to @code{nil}, multiple line fields are prohibited.
392
393If the data file does not exist, it is automatically created.
394
395@node Control File Format
396@chapter Control File Format
397
398@cindex control file
399The Forms mode @dfn{control file} serves two purposes.  First, it names
400the data file to use, and defines its format and properties.  Second,
401the Emacs buffer it occupies is used by Forms mode to display the forms.
402
403The contents of the control file are evaluated as a Lisp program.  It
404should set the following Lisp variables to suitable values:
405
406@table @code
407@vindex forms-file
408@item forms-file
409This variable specifies the name of the data file.  Example:
410
411@example
412(setq forms-file "my/data-file")
413@end example
414
415If the control file doesn't set @code{forms-file}, Forms mode
416reports an error.
417
418@vindex forms-format-list
419@item forms-format-list
420This variable describes the way the fields of the record are formatted on
421the screen.  For details, see @ref{Format Description}.
422
423@vindex forms-number-of-fields
424@item forms-number-of-fields
425This variable holds the number of fields in each record of the data
426file.  Example:
427
428@example
429(setq forms-number-of-fields 10)
430@end example
431@end table
432
433If the control file does not set @code{forms-format-list} a default
434format is used.  In this situation, Forms mode will deduce the number of
435fields from the data file providing this file exists and
436@code{forms-number-of-fields} has not been set in the control file.
437
438The control file can optionally set the following additional Forms mode
439variables.  Most of them have default values that are good for most
440applications.
441
442@table @code
443@vindex forms-field-sep
444@item forms-field-sep
445This variable may be used to designate the string which separates the
446fields in the records of the data file.  If not set, it defaults to the
447string @code{"\t"} (a Tab character).  Example:
448
449@example
450(setq forms-field-sep "\t")
451@end example
452
453@vindex forms-read-only
454@item forms-read-only
455If the value is non-@code{nil}, the data file is treated read-only.  (Forms
456mode also treats the data file as read-only if you don't have access to
457write it.)  Example:
458
459@example
460(set forms-read-only t)
461@end example
462
463@vindex forms-multi-line
464@item forms-multi-line
465This variable specifies the @dfn{pseudo newline} separator that allows
466multi-line fields.  This separator goes between the ``lines'' within a
467field---thus, the field doesn't really contain multiple lines, but it
468appears that way when displayed in Forms mode.  If the value is
469@code{nil}, multi-line text fields are prohibited.  The pseudo newline
470must not be a character contained in @code{forms-field-sep}.
471
472The default value is @code{"\^k"}, the character Control-K@.  Example:
473
474@example
475(setq forms-multi-line "\^k")
476@end example
477
478@ignore
479@vindex forms-forms-scroll
480@item forms-forms-scroll
481@xref{Forms Mode Commands}, for details.
482
483@vindex forms-forms-jump
484@item forms-forms-jump
485@xref{Forms Mode Commands}, for details.
486@end ignore
487
488@findex forms-read-file-filter
489@item forms-read-file-filter
490This variable holds the name of a function to be called after the data
491file has been read in. This can be used to transform the contents of the
492data file into a format more suitable for forms processing.
493If it is @code{nil}, no function is called.  For example, to maintain a
494gzipped database:
495
496@example
497(defun gzip-read-file-filter ()
498  (shell-command-on-region (point-min) (point-max)
499                           "gzip -d" t t))
500(setq forms-read-file-filter 'gzip-read-file-filter)
501@end example
502
503@findex forms-write-file-filter
504@item forms-write-file-filter
505This variable holds the name of a function to be called before writing
506out the contents of the data file.
507This can be used to undo the effects of @code{forms-read-file-filter}.
508If it is @code{nil}, no function is called.  Example:
509
510@example
511(defun gzip-write-file-filter ()
512  (make-variable-buffer-local 'require-final-newline)
513  (setq require-final-newline nil)
514  (shell-command-on-region (point-min) (point-max)
515                           "gzip" t t))
516(setq forms-write-file-filter 'gzip-write-file-filter)
517@end example
518
519@findex forms-new-record-filter
520@item forms-new-record-filter
521This variable holds a function to be called whenever a new record is created
522to supply default values for fields.  If it is @code{nil}, no function is
523called.
524@xref{Modifying Forms Contents}, for details.
525
526@findex forms-modified-record-filter
527@item  forms-modified-record-filter
528This variable holds a function to be called whenever a record is
529modified, just before updating the Forms data file.  If it is
530@code{nil}, no function is called.
531@xref{Modifying Forms Contents}, for details.
532
533@findex forms-insert-after
534@item forms-insert-after
535If this variable is not @code{nil}, new records are created @emph{after} the
536current record. Also, upon visiting a file, the initial position will be
537at the last record instead of the first one.
538
539@findex forms-check-number-of-fields
540@item forms-check-number-of-fields
541Normally each record is checked to contain the correct number of fields.
542Under certain circumstances, this can be undesirable.
543If this variable is set to @code{nil}, these checks will be bypassed.
544@end table
545
546@node Format Description
547@chapter The Format Description
548
549@vindex forms-format-list
550  The variable @code{forms-format-list} specifies the format of the data
551in the data file, and how to convert the data for display in Forms mode.
552Its value must be a list of Forms mode @dfn{formatting elements}, each
553of which can be a string, a number, a Lisp list, or a Lisp symbol that
554evaluates to one of those.  The formatting elements are processed in the
555order they appear in the list.
556
557@table @var
558@item string
559A string formatting element is inserted in the forms ``as is,'' as text
560that the user cannot alter.
561
562@item number
563A number element selects a field of the record.  The contents of this
564field are inserted in the display at this point.  Field numbers count
565starting from 1 (one).
566
567@item list
568A formatting element that is a list specifies a function call.  This
569function is called every time a record is displayed, and its result,
570which must be a string, is inserted in the display text.  The function
571should do nothing but returning a string.
572
573@vindex forms-fields
574The function you call can access the fields of the record as a list in
575the variable
576@code{forms-fields}.
577
578@item symbol
579A symbol used as a formatting element should evaluate to a string, number,
580or list; the value is interpreted as a formatting element, as described
581above.
582@end table
583
584If a record does not contain the number of fields as specified in
585@code{forms-number-of-fields}, a warning message will be printed.  Excess
586fields are ignored, missing fields are set to empty.
587
588The control file which displays @file{/etc/passwd} file as demonstrated
589in the beginning of this manual might look as follows:
590
591@example
592;; @r{This demo visits @file{/etc/passwd}.}
593
594(setq forms-file "/etc/passwd")
595(setq forms-number-of-fields 7)
596(setq forms-read-only t)                 ; @r{to make sure}
597(setq forms-field-sep ":")
598;; @r{Don't allow multi-line fields.}
599(setq forms-multi-line nil)
600
601(setq forms-format-list
602      (list
603       "====== /etc/passwd ======\n\n"
604       "User : "    1
605       "   Uid: "   3
606       "   Gid: "   4
607       "\n\n"
608       "Name : "    5
609       "\n\n"
610       "Home : "    6
611       "\n\n"
612       "Shell: "    7
613       "\n"))
614@end example
615
616When you construct the value of  @code{forms-format-list}, you should
617usually either quote the whole value, like this,
618
619@example
620(setq forms-format-list
621     '(
622       "====== " forms-file " ======\n\n"
623       "User : "    1
624       (make-string 20 ?-)
625       @dots{}
626      ))
627@end example
628
629@noindent
630or quote the elements which are lists, like this:
631
632@example
633(setq forms-format-list
634      (list
635       "====== " forms-file " ======\n\n"
636       "User : "    1
637       '(make-string 20 ?-)
638       @dots{}
639      ))
640@end example
641
642Forms mode validates the contents of @code{forms-format-list} when you
643visit a database.  If there are errors, processing is aborted with an
644error message which includes a descriptive text.  @xref{Error Messages},
645for a detailed list of error messages.
646
647If no @code{forms-format-list} is specified, Forms mode will supply a
648default format list.  This list contains the name of the file being
649visited, and a simple label for each field indicating the field number.
650
651@node Modifying Forms Contents
652@chapter Modifying The Forms Contents
653
654If @code{forms-read-only} is @code{nil}, the user can modify the fields
655and records of the database.
656
657All normal editing commands are available for editing the contents of the
658displayed record.  You cannot delete or modify the fixed, explanatory
659text that comes from string formatting elements, but you can modify the
660actual field contents.
661
662If the variable @code{forms-modified-record-filter} is non-@code{nil},
663it is called as a function before the new data is written to the data
664file.  The function receives one argument, a vector that contains the
665contents of the fields of the record.
666
667The function can refer to fields with @code{aref} and modify them with
668@code{aset}.  The first field has number 1 (one); thus, element 0 of the
669vector is not used.  The function should return the same vector it was
670passed; the (possibly modified) contents of the vector determine what is
671actually written in the file.  Here is an example:
672
673@example
674(defun my-modified-record-filter (record)
675  ;; @r{Modify second field.}
676  (aset record 2 (current-time-string))
677  ;; @r{Return the field vector.}
678  record)
679
680(setq forms-modified-record-filter 'my-modified-record-filter)
681@end example
682
683If the variable @code{forms-new-record-filter} is non-@code{nil}, its
684value is a function to be called to fill in default values for the
685fields of a new record.  The function is passed a vector of empty
686strings, one for each field; it should return the same vector, with
687the desired field values stored in it.  Fields are numbered starting
688from 1 (one).  Example:
689
690@example
691(defun my-new-record-filter (fields)
692  (aset fields 5 (login-name))
693  (aset fields 1 (current-time-string))
694  fields)
695
696(setq forms-new-record-filter 'my-new-record-filter)
697@end example
698
699@node Miscellaneous
700@chapter Miscellaneous
701
702@vindex forms-version
703The global variable @code{forms-version} holds the version information
704of the Forms mode software.
705
706@findex forms-enumerate
707It is very convenient to use symbolic names for the fields in a record.
708The function @code{forms-enumerate} provides an elegant means to define
709a series of variables whose values are consecutive integers.  The
710function returns the highest number used, so it can be used to set
711@code{forms-number-of-fields} also.  For example:
712
713@example
714(setq forms-number-of-fields
715      (forms-enumerate
716       '(field1 field2 field3 @dots{})))
717@end example
718
719This sets @code{field1} to 1, @code{field2} to 2, and so on.
720
721Care has been taken to keep the Forms mode variables buffer-local, so it
722is possible to visit multiple files in Forms mode simultaneously, even
723if they have different properties.
724
725@findex forms-mode
726If you have visited the control file in normal fashion with
727@code{find-file} or a like command, you can switch to Forms mode with
728the command @code{M-x forms-mode}.  If you put @samp{-*- forms -*-} in
729the first line of the control file, then visiting it enables Forms mode
730automatically.  But this makes it hard to edit the control file itself,
731so you'd better think twice before using this.
732
733The default format for the data file, using @code{"\t"} to separate
734fields and @code{"\^k"} to separate lines within a field, matches the
735file format of some popular database programs, e.g., FileMaker.  So
736@code{forms-mode} can decrease the need to use proprietary software.
737
738@node Error Messages
739@chapter Error Messages
740
741This section describes all error messages which can be generated by
742forms mode.  Error messages that result from parsing the control file
743all start with the text @samp{Forms control file error}.  Messages
744generated while analyzing the definition of @code{forms-format-list}
745start with @samp{Forms format error}.
746
747@table @code
748@item Forms control file error: `forms-file' has not been set
749The variable @code{forms-file} was not set by the control file.
750
751@item Forms control file error: `forms-number-of-fields' has not been set
752The variable @code{forms-number-of-fields} was not set by the control
753file.
754
755@item Forms control file error: `forms-number-of-fields' must be a number > 0
756The variable @code{forms-number-of-fields} did not contain a positive
757number.
758
759@item Forms control file error: `forms-field-sep' is not a string
760@itemx Forms control file error: `forms-multi-line' must be nil or a one-character string
761The variable @code{forms-multi-line} was set to something other than
762@code{nil} or a single-character string.
763
764@item Forms control file error: `forms-multi-line' is equal to 'forms-field-sep'
765The variable @code{forms-multi-line} may not be equal to
766@code{forms-field-sep} for this would make it impossible to distinguish
767fields and the lines in the fields.
768
769@item Forms control file error: `forms-new-record-filter' is not a function
770@itemx Forms control file error: `forms-modified-record-filter' is not a function
771The variable has been set to something else than a function.
772
773@item Forms control file error: `forms-format-list' is not a list
774The variable @code{forms-format-list} was not set to a Lisp list
775by the control file.
776
777@item Forms format error: field number @var{xx} out of range 1..@var{nn}
778A field number was supplied in @code{forms-format-list} with a value of
779@var{xx}, which was not greater than zero and smaller than or equal to
780the number of fields in the forms, @var{nn}.
781
782@item Forms format error: @var{fun} is not a function
783The first element of a list which is an element of
784@code{forms-format-list} was not a valid Lisp function.
785
786@item Forms format error: invalid element @var{xx}
787A list element was supplied in @code{forms-format-list} which was not a
788string, number or list.
789
790@item Warning: this record has @var{xx} fields instead of @var{yy}
791The number of fields in this record in the data file did not match
792@code{forms-number-of-fields}.  Missing fields will be made empty.
793
794@item Multi-line fields in this record - update refused!
795The current record contains newline characters, hence can not be written
796back to the data file, for it would corrupt it.  Probably you inserted a
797newline in a field, while @code{forms-multi-line} was @code{nil}.
798
799@item Field separator occurs in record - update refused!
800The current record contains the field separator string inside one of the
801fields. It can not be written back to the data file, for it would
802corrupt it. Probably you inserted the field separator string in a field.
803
804@item Record number @var{xx} out of range 1..@var{yy}
805A jump was made to non-existing record @var{xx}.  @var{yy} denotes the
806number of records in the file.
807
808@item Stuck at record @var{xx}
809An internal error prevented a specific record from being retrieved.
810
811@item No write access to @code{"}@var{file}@code{"}
812An attempt was made to enable edit mode on a file that has been write
813protected.
814
815@item Search failed: @var{regexp}
816The @var{regexp} could not be found in the data file. Forward searching
817is done from the current location until the end of the file, then
818retrying from the beginning of the file until the current location.
819Backward searching is done from the current location until the beginning
820of the file, then retrying from the end of the file until the current
821location.
822
823@item Wrapped
824A search completed successfully after wrapping around.
825
826@item Warning: number of records changed to @var{nn}
827Forms mode's idea of the number of records has been adjusted to the
828number of records actually present in the data file.
829
830@item Problem saving buffers?
831An error occurred while saving the data file buffer. Most likely, Emacs
832did ask to confirm deleting the buffer because it had been modified, and
833you said ``no''.
834@end table
835
836@node Long Example
837@chapter Long Example
838
839The following example exploits most of the features of Forms mode.
840This example is included in the distribution as file @file{etc/forms/forms-d2.el}.
841
842@example
843;; demo2 -- demo forms-mode     -*- emacs-lisp -*-
844
845;; @r{This sample forms exploit most of the features of forms mode.}
846
847;; @r{Set the name of the data file.}
848(setq forms-file
849       (expand-file-name "forms/forms-d2.dat" data-directory))
850
851;; @r{Use @code{forms-enumerate} to set field names and number thereof.}
852(setq forms-number-of-fields
853      (forms-enumerate
854       '(arch-newsgroup                 ; 1
855         arch-volume                    ; 2
856         arch-issue                     ; and ...
857         arch-article                   ; ... so
858         arch-shortname                 ; ... ... on
859         arch-parts
860         arch-from
861         arch-longname
862         arch-keywords
863         arch-date
864         arch-remarks)))
865
866;; @r{The following functions are used by this form for layout purposes.}
867;;
868(defun arch-tocol (target &optional fill)
869  "Produces a string to skip to column TARGET.
870Prepends newline if needed.
871The optional FILL should be a character, used to fill to the column."
872  (if (null fill)
873      (setq fill ? ))
874  (if (< target (current-column))
875      (concat "\n" (make-string target fill))
876    (make-string (- target (current-column)) fill)))
877;;
878(defun arch-rj (target field &optional fill)
879  "Produces a string to skip to column TARGET\
880 minus the width of field FIELD.
881Prepends newline if needed.
882The optional FILL should be a character,
883used to fill to the column."
884  (arch-tocol (- target (length (nth field forms-fields))) fill))
885
886;; @r{Record filters.}
887;;
888(defun new-record-filter (the-record)
889  "Form a new record with some defaults."
890  (aset the-record arch-from (user-full-name))
891  (aset the-record arch-date (current-time-string))
892  the-record)                           ; return it
893(setq forms-new-record-filter 'new-record-filter)
894
895;; @r{The format list.}
896(setq forms-format-list
897     (list
898       "====== Public Domain Software Archive ======\n\n"
899       arch-shortname
900       " - "                    arch-longname
901       "\n\n"
902       "Article: "              arch-newsgroup
903       "/"                      arch-article
904       " "
905       '(arch-tocol 40)
906       "Issue: "                arch-issue
907       " "
908       '(arch-rj 73 10)
909       "Date: "                 arch-date
910       "\n\n"
911       "Submitted by: "         arch-from
912       "\n"
913       '(arch-tocol 79 ?-)
914       "\n"
915       "Keywords: "             arch-keywords
916       "\n\n"
917       "Parts: "                arch-parts
918       "\n\n====== Remarks ======\n\n"
919       arch-remarks
920     ))
921
922;; @r{That's all, folks!}
923@end example
924
925@node Credits
926@chapter Credits
927
928Bug fixes and other useful suggestions were supplied by
929Harald Hanche-Olsen (@code{hanche@@imf.unit.no}),
930@code{cwitty@@portia.stanford.edu},
931Jonathan I. Kamens,
932Per Cederqvist  (@code{ceder@@signum.se}),
933Michael Lipka (@code{lipka@@lip.hanse.de}),
934Andy Piper (@code{ajp@@eng.cam.ac.uk}),
935Frederic Pierresteguy  (@code{F.Pierresteguy@@frcl.bull.fr}),
936Ignatios Souvatzis
937and Richard Stallman (@code{rms@@gnu.org}).
938
939This documentation was slightly inspired by the documentation of ``rolo
940mode'' by Paul Davis at Schlumberger Cambridge Research
941(@code{davis%scrsu1%sdr.slb.com@@relay.cs.net}).
942
943None of this would have been possible without GNU Emacs of the Free
944Software Foundation.  Thanks, Richard!
945
946@node GNU Free Documentation License
947@appendix GNU Free Documentation License
948@include doclicense.texi
949
950@node Index
951@unnumbered Index
952@printindex cp
953
954@bye
955