jv@mh.nl (Johan Vromans) (05/20/91)
This is GNU Emacs 'forms-mode', version 1.2 (patchlevel 2). This GNU Emacs major mode implements editing a structured file (i.e. a file with 'records' and 'fields' in it) using a forms. It is fully documented in the source file 'forms.el' and in the texinfo file 'forms.ti'. Changes in forms-mode 1.2.1 to 1.2.2: * Correct a bug that prevented the modifications to the last field of a form to be handled correctly if that field is the last thing on the form. Submitted-by: jv@mh.nl Archive-name: forms/part01 ---- Cut Here and feed the following to sh ---- #!/bin/sh # This is forms, a shell archive (produced by shar 3.49) # To extract the files from this archive, save it to a file, remove # everything above the "!/bin/sh" line above, and type "sh file_name". # # made 05/20/1991 09:16 UTC by jv@mh.nl # Source directory /u1/users/jv/elisp/src/forms-mode/Work # # existing files will NOT be overwritten unless -c is specified # # This is part 1 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # # This shar contains: # length mode name # ------ ---------- ------------------------------------------ # 2545 -rw-r--r-- README # 47 -rw-r--r-- MANIFEST # 436 -rw-r--r-- demo1 # 475 -rw-r--r-- demo2 # 476 -rw-r--r-- demo2.dat # 21930 -r--r--r-- forms.ti # 36048 -r--r--r-- forms.el # if test -r _shar_seq_.tmp; then echo 'Must unpack archives in sequence!' echo Please unpack part `cat _shar_seq_.tmp` next exit 1 fi # ============= README ============== if test -f 'README' -a X"$1" != X"-c"; then echo 'x - skipping README (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting README (Text)' sed 's/^X//' << 'SHAR_EOF' > 'README' && This is GNU Emacs 'forms-mode', version 1.2 (patchlevel 2). X This GNU Emacs major mode implements editing a structured file (i.e. a file with 'records' and 'fields' in it) using a forms. It is fully documented in the source file 'forms.el' and in the texinfo file 'forms.ti'. X This kit contains: X X README - this file X MANIFEST - list of files X forms.el - the lisp source X forms.ti - texinfo file X demo1 - demo using /etc/passwd X demo2 - demo using 'demo2.dat' X demo2.dat - data for demo2 X Load the lisp source, and execute X X forms-find-file demo1 X to look at your password file in a unconventional (but read-only) way. X X forms-find-file demo2 X gives you something to clobber with data and multi-line fields. X This program has been donated to the Free Software Foundation to be part of their GNU Emacs programming system. X Have fun! X X Johan Vromans <jv@mh.nl> X HISTORY ------- X 1.2.2 Released: May 20, 1991 X X Fixed bug: X * The modifications to the last field of a form were not handled X correctly if that field was not followed by fixed text. X 1.2.1 Released: Sep 18, 1990 X X New feature: X * Is it now possible to define a function `forms-new-record-filter' in X the control file, that gets called when a new record is created. X It can be used to insert default values in fields. X Thanks to Harald Hanche-Olsen <hanche@imf.unit.no> . X X Fixed bugs: X * `save-buffer' was redefined as (interactive "P"). This should have X been (interactive "p"). X Thanks to Jonathan Kamens <jik@pit-manager.MIT.EDU> . X * `forms--checkmod' was not called often enough to prevent modified X records from getting lost in spurious situations. X Thanks to u502sou@mpirbn.uucp (Ignatios Souvatzis). X * When updating a new record, sometimes it got prepended to the next X record. X Thanks to several users. X X Other modifications: X * Harald Hanche-Olsen <hanche@imf.unit.no> rewrote X forms--make-format and forms--make-parser to use the more standard X backquote construct. X X And finally: X * Ignatios Souvatzis wrote a forms routine to sort a file on X selected fields. I did not include it because I don't think that X sorting belongs to the functionality of forms-mode. Ignatios X wrote me: X X as i didn't want to look up the man page for /bin/sort, i wrote X a sort function for you forms mode. You may include it in your X next distribution to the net or FSF, if you want (as long as X there remains a trace of who wrote that ~30 lines). Else tell me X please so that i can post the sort code myself. SHAR_EOF chmod 0644 README || echo 'restore of README failed' Wc_c="`wc -c < 'README'`" test 2545 -eq "$Wc_c" || echo 'README: original size 2545, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= MANIFEST ============== if test -f 'MANIFEST' -a X"$1" != X"-c"; then echo 'x - skipping MANIFEST (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting MANIFEST (Text)' sed 's/^X//' << 'SHAR_EOF' > 'MANIFEST' && README forms.el forms.ti demo1 demo2 demo2.dat SHAR_EOF chmod 0644 MANIFEST || echo 'restore of MANIFEST failed' Wc_c="`wc -c < 'MANIFEST'`" test 47 -eq "$Wc_c" || echo 'MANIFEST: original size 47, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= demo1 ============== if test -f 'demo1' -a X"$1" != X"-c"; then echo 'x - skipping demo1 (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting demo1 (Text)' sed 's/^X//' << 'SHAR_EOF' > 'demo1' && ;; demo for forms-mode ;; ;; This demo visits /etc/passwd. X (setq forms-file "/etc/passwd") (setq forms-read-only t) ; to make sure (setq forms-field-sep ":") (setq forms-number-of-fields 7) (setq forms-format-list X '("====== Visiting /etc/passwd ======\n\n" X "User : " 1 X " Uid: " 3 X " Gid: " 4 X "\n\n" X "Name : " 5 X "\n\n" X "Home : " 6 X "\n\n" X "Shell: " 7 X "\n")) SHAR_EOF chmod 0644 demo1 || echo 'restore of demo1 failed' Wc_c="`wc -c < 'demo1'`" test 436 -eq "$Wc_c" || echo 'demo1: original size 436, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= demo2 ============== if test -f 'demo2' -a X"$1" != X"-c"; then echo 'x - skipping demo2 (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting demo2 (Text)' sed 's/^X//' << 'SHAR_EOF' > 'demo2' && ;; test forms-mode -*- emacs-lisp -*- ;; (setq forms-file "demo2.dat") (setq forms-number-of-fields 11) (setq forms-format-list X '( X "====== Public Domain Software Archive ======\n\n" 5 X " - " 8 X "\n\n" X "Article: " 1 X "/" 4 X " Issue: " 3 X " Date: " 10 X "\n\n" X "Submitted by: " 7 X "\n\n" X "Keywords: " 9 X "\n\n" X "Parts: " 6 X "\n\n====== Remarks ======\n\n" 11 X )) SHAR_EOF chmod 0644 demo2 || echo 'restore of demo2 failed' Wc_c="`wc -c < 'demo2'`" test 475 -eq "$Wc_c" || echo 'demo2: original size 475, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= demo2.dat ============== if test -f 'demo2.dat' -a X"$1" != X"-c"; then echo 'x - skipping demo2.dat (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting demo2.dat (Text)' sed 's/^X//' << 'SHAR_EOF' > 'demo2.dat' && comp.sources.unix v11i008 269 getty-enable 1 tron@sc.nsc.com (Ronald S. Karr) Getty on/off programs for 4.[23] BSD 890505 comp.sources.unix 11 v11i022 283 syslog 1 emory!arnold (Arnold D. Robbins {EUCC}) Development version of syslog(3), for ATT, too 28/08/1987 comp.sources.unix 11 v11i033 290 less3 3 sun!intsc!convgt!mark The 'less' pager 02/09/1987 comp.sources.unix 11 v11i036 293 test.el 3 "Mark A. Ardis" <maa@sei.cmu.edu> Test system for GNU Emacs 10/09/1987 SHAR_EOF chmod 0644 demo2.dat || echo 'restore of demo2.dat failed' Wc_c="`wc -c < 'demo2.dat'`" test 476 -eq "$Wc_c" || echo 'demo2.dat: original size 476, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= forms.ti ============== if test -f 'forms.ti' -a X"$1" != X"-c"; then echo 'x - skipping forms.ti (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting forms.ti (Text)' sed 's/^X//' << 'SHAR_EOF' > 'forms.ti' && \input texinfo @c -*-texinfo-*- @(#)@ forms 1.2.2 @comment %**start of header (This is for running Texinfo on a region.) @setfilename forms.info @settitle Forms Mode User's Manual @iftex @finalout @setchapternewpage odd @end iftex @c @smallbook @comment %**end of header (This is for running Texinfo on a region.) X @tex \global\chapno=30 @end tex X @ifinfo This file documents forms-mode, a forms based major mode for GNU Emacs. X Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. X @ignore Permission is granted to process this file through TeX and print the results, provided the printed document carries copying permission notice identical to this one except for the removal of this paragraph (this paragraph not being relevant to the printed manual). X @end ignore @end ifinfo X @iftex @titlepage @sp 6 @center @titlefont{Forms Mode User's Manual} @sp 4 @center Forms-Mode version 1.2, patchlevel 2 @sp 1 @center May 1991 @sp 5 @center Johan Vromans @center @i{jv@@mh.nl} @page X @vskip 0pt plus 1filll Copyright @copyright{} 1989,1990,1991 Free Software Foundation, Inc. X Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. X @end titlepage @page @end iftex X @ifinfo @node Top, What is in a Forms, , (DIR) @end ifinfo X @iftex @chapter Forms mode @end iftex X Forms mode is an Emacs major mode for working with simple plain-text databases in a forms-oriented manner. In forms mode, the information in these files is presented in an Emacs window in a user-defined format, one record at a time. Forms can be inspected read-only (viewing) or modified and updated. @cindex forms-mode X Forms mode is not a simple major mode, but requires two files to do its job: a control file and a data file. The data file holds the actual data which will be presented. The control file describes how it will be presented. X @menu * What is in a Forms:: Introduction. * Data File Format:: How to format the data file. * Control File Format:: How to control forms mode. * Forms Format Description:: X How to define the forms layout. * Modifying Forms Contents:: X How to modify. * Forms Mode Commands:: The commands available, and how to use them. * Key Bindings:: Which keys are bound to what commands. * Miscellaneous:: Forms mode messages and other remarks. * Credits:: Thanks everyone. * Concept Index:: Index of Concepts * Variable Index:: Index of Variables. * Function Index:: Index of Functions. @end menu X @node What is in a Forms, Data File Format, Top, Top @section What is in a forms X Let's illustrate forms mode with an example. Suppose you are looking at your @file{/etc/passwd} file, and your screen looks as follows: X @example ====== /etc/passwd ====== X User : root Uid: 0 Gid: 1 X Name : Super User X Home : / X Shell: /bin/sh @end example X As you can see, the familiar fields from the entry for the super user are all there, but instead of one single line, they make up a forms. X The contents of the forms consists of the contents of the fields of the record (e.g. @code{root}, @code{0}, @code{1}, @code{Super User}) interspersed with normal text (e.g @code{User : }, @code{Uid: }). X You can define yourself how text and fields will be used to make up the forms. X When you modifiy the contents of the forms, it will be analyzed and the new contents of the fields of this record will be extracted. It possible, the file will be updated with the new contents. X @node Data File Format, Control File Format, What is in a Forms, Top @section Data file format X Files for use with forms mode are very simple -- each record forms the contents one form. Each record is supposed to consist of a number of fields. These fields are separated by the value of the string @code{forms-field-sep}, which is a @code{TAB} by default. X @cindex pseudo-newline Fields may contain text which shows up in the forms in multiple lines. These lines are separated in the field using a @var{pseudo-newline} character which is defined by the value of the string @code{forms-multi-line}. Its default value is a Control-K character. If it is set to @code{nil} multiple line fields are prohibited. X @node Control File Format, Forms Format Description, Data File Format, Top @section Control file format X The control file serves two purposes. X First, it defines the data file to use, and its properties. X Second, the Emacs buffer it occupies will be used by the forms mode to display the forms. X @findex eval-current-buffer The contents of the control file are evaluated using the Emacs command @code{eval-current-buffer}, hence must contain valid Emacs-lisp expressions. These expressions should set the following lisp variables to a suitable value: X @table @code @vindex forms-file @item forms-file This variable must be set to the name of the data file.@* Example: @example (setq forms-file "my/data-file") @end example X @item forms-format-list This variable describes the way the fields of the record are formatted on the screen. See the next section for details. X @vindex forms-field-sep @item forms-field-sep This variable may be used to designate the string which separates the fields in the records of the data file. If not set, it defaults to a string containing a single @code{TAB} character. @* Example: @example (setq forms-field-sep "\t") @end example X @vindex forms-number-of-fields @item forms-number-of-fields This variable holds the number of fields in each record of the data file.@* Example: @example (setq forms-number-of-fields 10) @end example X @vindex forms-read-only @item forms-read-only If set to a value other than @code{nil}, the data file is treated read-only. If the data file can not be written into, read-only mode is enforced. The default value for @code{forms-read-only} is derieved from the access permissions of the data file.@* Example: @example (set forms-read-only t) @end example X @vindex forms-multi-line @item forms-multi-line This variable may be set to allow multi-line text in fields. It should be set to a string of one character, which denotes the pseudo new-line character to be used to separate the text lines.@* Its default value is Control-K (octal 013). If set to @code{nil}, multi-line text fields are prohibited.@* It may not be a character contained in @code{forms-field-sep}.@* Example: @example (setq forms-multi-line "\C-k") @end example X @end table X Of these fields, only @code{forms-file}, @code{forms-number-of-fields} and @code{forms-format-list} are mandatory. An error will be given if one of these variables has not been set. All other variables have default values which are suitable for most applications. X Two more variables may be used: @code{forms-forms-scroll} and @code{forms-forms-jump}. @xref{Forms Mode Commands} for their descriptions. X @findex{forms-new-record-filter} Optionally, the control file may define a function @code{forms-new-record-filter}. If so, this function is called when a new record is created to supply default values for fields. X @node Forms Format Description, Modifying Forms Contents, Control File Format, Top @section The forms format description X @vindex forms-format-list The value of the variable @code{forms-format-list} is used to specify the format of the forms. It must be a @code{list} of formatting elements, each of which can be either a @code{string} or a @code{number}. The formatting elements are processed in the order they appear in the list. X A @code{string} formatting element is inserted in the forms ``as is''. X A @code{number} element selects a field of the record. The contents of this field are inserted. The first field of the record has number 1 (one). X If a record does not contain the number of fields as specified in @code{forms-number-of-fields}, a warning message will be printed. Excess fields are ignored, missing fields are set to empty. X The control file which shows your @file{/etc/passwd} file as demonstrated in the beginning of this document looks as follows: @example ;; This demo visits /etc/passwd. X (setq forms-file "/etc/passwd") (setq forms-number-of-fields 7) (setq forms-read-only t) ; to make sure (setq forms-field-sep ":") (setq forms-multi-line nil) ; not allowed X (setq forms-format-list X '("====== /etc/passwd ======\n\n" X "User : " 1 X " Uid: " 3 X " Gid: " 4 X "\n\n" X "Name : " 5 X "\n\n" X "Home : " 6 X "\n\n" X "Shell: " 7 X "\n")) @end example X Upon startup, the contents of @code{forms-format-list} are validated. If errors are encountered, processing is aborted with an error message which includes a descriptive text. @xref{Error Messages}, for a detailed list of error messages. X @node Modifying Forms Contents, Forms Mode Commands, Forms Format Description, Top @section Modifying The Forms Contents X If a forms is not read-only, it's contents can be modified. X All normal editor commands may be used to change the forms. There is no distinction between the ``fixed'' text and the text from the fields of the records. However, upon completion, the forms is parsed to extract the new contents of the fields. The ``fixed'' portions of the forms are used to delimit the fields, these portions should therefore not be modified to avoid the risk that the field contents cannot be determined. Moreover, ambiguous field contents, which can not be discriminated from ``fixed'' text, must be avoided. X If the contents of the forms cannot be recognized properly, this is signaled using a descriptive text. @xref{Error Messages}, for more info. The cursor will indicate the last part of the forms which was successfully parsed. X @node Forms Mode Commands, Key Bindings, Modifying Forms Contents, Top @section Forms mode commands X @table @kbd @findex forms-find-file @item M-x forms-find-file @var{file} @end table X Visits @var{file}, runs @code{eval-current-buffer} on it, and puts the buffer into forms-mode. The first record of the data file will be loaded and shown. X The modeline will display the major mode @code{"Forms"} followed by the minor mode @code{"View"} if the file is visited read-only. The number of the current record (@var{n}) and the total number of records (@var{t}) in the file is shown in the modeline as @code{"n/t"}.@* For example: @example --%%-Emacs: passwd-demo (Forms View 1/54)----All------- @end example X @table @kbd @findex forms-find-file-other-window @item M-x forms-find-file-other-window @var{file} @end table X This command is similar to @code{forms-find-file}, but visits the file in another window. X If the buffer is not read-only, you may change the buffer to modify the fields in the record. When the current record is left, e.g. by switching to another record, the contents of the buffer are parsed using the specifications in @code{forms-format-list}, and a new record is constructed which replaces the current record in the data file. Fields of the record which are not shown in the forms are not modified; they retain their original contents. X Most forms mode commands are bound to keys, and are accessible with the conventional @code{C-c} prefix. In read-only mode this prefix is not used. @xref{Key Bindings}, for the default key bindigs used by forms mode. X The following commands are available within forms mode. X @table @kbd @findex forms-next-record @item forms-next-record shows the next record. With a prefix argument, show the n-th next record. X @findex forms-prev-record @item forms-prev-record shows the previous record. With a prefix argument, show the n-th previous record. X @findex forms-jump-record @item forms-jump-record jumps to a record by number. A prefix argument is used for the record number to jump to. If no prefix argument is supplied, a record number is asked for in the minibuffer.@* If an invalid record number is supplied, an error message is displayed reading the offending record number, and the allowable range of numbers. X @findex forms-first-record @item forms-first-record jumps to the first record. X @findex forms-last-record @item forms-last-record jumps to the last record. Also re-counts the number of records in the data file. X @findex forms-next-field @item forms-next-field jumps to the next field in the forms. With a numeric argument: jumps that many fields, or to the first field if there are not that many fields left. X Jumping to fields is implemented using markers, which are placed in front of the fields. If the contents of the forms are modified, the markers are adjusted. However, if text around a marker has been deleted from the screen and inserted again it is possible that this marker no longer points at its field correctly. @xref{Markers,,Markers, emacs, the GNU Emacs Lisp Manual}, for more information on markers. X @findex forms-view-mode @item forms-view-mode switches to read-only mode. Forms mode commands may no longer be prefixed with @code{C-c}. X @findex forms-edit-mode @item forms-edit-mode switches to edit mode. Forms mode commands must be prefixed with @code{C-c}.@* Switching to edit mode is only possible if write access to the data file is allowed. X @findex forms-insert-record @item forms-insert-record create a new record, which is inserted before the current record. An empty form is presented, which can be filled in using familiar editor commands. With a prefix argument: the new record is created @i{after} the current one. X If a function @code{forms-new-record-filter} was defined in the control file, this function is called to fill in default values for fields. The function is passed a vector of empty strings, one for each field. For convenience, an additional element is added so the numbers of the elements are the same as the numbers used in the forms description. The function must return the (updated) vector. X Example: @example (defun forms-new-record-filter (fields) X (aset fields 5 (login-name)) X (aset fields 1 (current-time-string)) X ;; and return it X fields) @end example X @findex forms-delete-record @item forms-delete-record deletes the current record. You are prompted for confirmation before the record is deleted unless a prefix argument has been provided. X @findex forms-search @item forms-search @var{regexp} searches for @var{regexp} in all records following this one. If found, this record is shown.@* The next time it is invoked, the previous regexp is the default, so you can do repeated searches by simply pressing @key{RET} in response to the prompt. X @findex revert-buffer @item revert-buffer reverts a possibly modified forms to its original state. It only affect the record currently in the forms. X @findex forms-exit @item forms-exit terminates forms processing. The data file is saved if it has been modified. X @findex forms-exit-no-save @item forms-exit-no-save aborts forms processing. If the data file has been modified Emacs will ask questions. X @findex describe-mode @item describe-mode gives additional help. X @findex save-buffer @item save-buffer saves the changes in the data file, if modified. X @end table X @vindex forms-forms-scroll @findex scroll-up @findex scroll-down If the variable @code{forms-forms-scrolls} is set to a value other than @code{nil} (which it is, by default), the Emacs functions @code{scroll-up} and @code{scroll-down} will perform a @code{forms-next-record} and @code{forms-prev-record} when in forms mode. So you can use your favourite page commands to page through the data file. X @vindex forms-forms-jump @findex beginning-of-buffer @findex end-of-buffer Likewise, if the variable @code{forms-forms-jump} is not @code{nil} (which it is, by default), Emacs functions @code{beginning-of-buffer} and @code{end-of-buffer} will perform @code{forms-first-record} and @code{forms-last-record} when in forms mode. X @vindex forms-mode-hooks After forms mode is entered, functions contained in @code{forms-mode-hooks} are executed to perform user defined customization. X @node Key Bindings, Miscellaneous, Forms Mode Commands, Top @section Key bindings X This section describes the key bindings as they are defined when invoking forms mode.@* All commands must be prefixed with @kbd{C-c} when editing a forms. If a forms is read-only, @kbd{C-c} is not used. The only exception to this rule is @code{forms-next-field}, which is bound to @kbd{TAB} in all maps. X @table @kbd X @itemx C-c @key{TAB} @code{forms-next-field} X @itemx C-c @key{SPC} @code{forms-next-record} X @itemx C-c < @code{forms-first-record} X @itemx C-c > @code{forms-first-record} X @itemx C-c d @code{forms-delete-record} X @itemx C-c e @code{forms-edit-mode} X @itemx C-c i @code{forms-insert-record} X @itemx C-c j @code{forms-jump-record} X @itemx C-c n @code{forms-next-record} X @itemx C-c p @code{forms-prev-record} X @itemx C-c q @code{forms-exit} X @itemx C-c s @var{regexp} @code{forms-search} X @itemx C-c v @code{forms-view-mode} X @itemx C-c x @code{forms-exit-no-save} X @itemx C-c ? @code{describe-mode} X @itemx C-c @key{DEL} @code{forms-prev-record} SHAR_EOF true || echo 'restore of forms.ti failed' fi echo 'End of forms part 1' echo 'File forms.ti is continued in part 2' echo 2 > _shar_seq_.tmp exit 0 -- Johan Vromans jv@mh.nl via internet backbones Multihouse Automatisering bv uucp: ..!{uunet,hp4nl}!mh.nl!jv Doesburgweg 7, 2803 PL Gouda, The Netherlands phone/fax: +31 1820 62911/62500 ------------------------ "Arms are made for hugging" -------------------------