From bacchus.pa.dec.com!decwrl!elroy.jpl.nasa.gov!usc!cs.utexas.edu!uunet!allbery Sat Jun 16 11:53:32 PDT 1990
Article 1645 of comp.sources.misc:
Path: bacchus.pa.dec.com!decwrl!elroy.jpl.nasa.gov!usc!cs.utexas.edu!uunet!allbery
From: jv@mh.nl (Johan Vromans)
Newsgroups: comp.sources.misc
Subject: v13i050: Emacs forms mode 1.1 - part 02 of 03
Message-ID: <93337@uunet.UU.NET>
Date: 15 Jun 90 23:00:41 GMT
Sender: allbery@uunet.UU.NET
Lines: 826
Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)

Posting-number: Volume 13, Issue 50
Submitted-by: jv@mh.nl (Johan Vromans)
Archive-name: forms.el/part02

---- Cut Here and unpack ----
#!/bin/sh
# this is forms.02 (part 2 of a multipart archive)
# do not concatenate these parts, unpack them in order with /bin/sh
# file forms.el continued
#
if touch 2>&1 | fgrep '[-amc]' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
if test ! -r shar3_seq_.tmp; then
	echo "Please unpack part 1 first!"
	exit 1
fi
(read Scheck
 if test "$Scheck" != 2; then
	echo "Please unpack part $Scheck next!"
	exit 1
 else
	exit 0
 fi
) < shar3_seq_.tmp || exit 1
echo "x - Continuing file forms.el"
sed 's/^X//' << 'SHAR_EOF' >> forms.el &&
X		(setq the-result
X		      (concat the-result
X			      "(aset the-recordv "
X			      (1- pending-field)
X			      " (buffer-substring (point) (point-max))) "))))
X
X	  (setq pending-text nil)
X	  (setq pending-field el)))
X
X	;; advance to next element of the list
X	(setq the-list rem)))
X
X    (or (zerop pending-field)
X	(error "forms--make-parser failed - field %d pending" pending-field))
X    (or (null pending-text)
X	(error "forms--make-parser failed - text %s pending"
X	       (prin1-to-string pending-text)))
X
X    (setq the-result (concat the-result "))"))
X
X    ;; use the lisp reader to evalute the string to a function
X    (let ((res (read-from-string the-result))
X	  (len (length the-result)))
X      ;; has the whole string been parsed?
X      (if (= (cdr res) len)
X	  (setq forms--parser (car res))
X	;; pity
X	(error "forms--make-parser failed at %d [of %d]" (cdr res) len)))))
X
X;;;
X
X(defun forms--set-minor-mode ()
X  (setq minor-mode-alist
X	(if forms-read-only
X	    " View"
X	  nil)))
X
X(defun forms--set-keymaps ()
X  "Set the keymaps used in this mode."
X
X  (if forms-read-only
X      (use-local-map forms-mode-map)
X    (use-local-map (make-sparse-keymap))
X    (define-key (current-local-map) "\C-c" forms-mode-map)
X    (define-key (current-local-map) "\t"   'forms-next-field)))
X
X(defun forms--mode-commands (map)
X  "Fill map with all commands."
X  (define-key map "\t" 'forms-next-field)
X  (define-key map " " 'forms-next-record)
X  (define-key map "d" 'forms-delete-record)
X  (define-key map "e" 'forms-edit-mode)
X  (define-key map "i" 'forms-insert-record)
X  (define-key map "j" 'forms-jump-record)
X  (define-key map "n" 'forms-next-record)
X  (define-key map "p" 'forms-prev-record)
X  (define-key map "q" 'forms-exit)
X  (define-key map "s" 'forms-search)
X  (define-key map "v" 'forms-view-mode)
X  (define-key map "x" 'forms-exit-no-save)
X  (define-key map "<" 'forms-first-record)
X  (define-key map ">" 'forms-last-record)
X  (define-key map "?" 'describe-mode)
X  (define-key map "\177" 'forms-prev-record)
X ;  (define-key map "\C-c" map)
X  (define-key map "\e" 'ESC-prefix)
X  (define-key map "\C-x" ctl-x-map)
X  (define-key map "\C-u" 'universal-argument)
X  (define-key map "\C-h" help-map)
X  )
X;;;
X;;; Changed functions
X;;;
X;;; Emacs (as of 18.54) lacks the functionality of buffer-local
X;;; funtions. Therefore we save the original meaning of some handy
X;;; functions, and replace them with a wrapper.
X
X(defun forms--change-commands ()
X  "Localize some commands."
X  ;;
X  ;; scroll-down -> forms-prev-record
X  ;;
X  (if (fboundp 'forms--scroll-down)
X      nil
X    (fset 'forms--scroll-down (symbol-function 'scroll-down))
X    (fset 'scroll-down
X	  '(lambda (arg) 
X	     (interactive "P")
X	     (if (and forms--mode-setup
X		      forms-forms-scroll)
X		 (forms-prev-record arg)
X	       (forms--scroll-down arg)))))
X  ;;
X  ;; scroll-up -> forms-next-record
X  ;;
X  (if (fboundp 'forms--scroll-up)
X      nil
X    (fset 'forms--scroll-up   (symbol-function 'scroll-up))
X    (fset 'scroll-up
X	  '(lambda (arg) 
X	     (interactive "P")
X	     (if (and forms--mode-setup
X		      forms-forms-scroll)
X		 (forms-next-record arg)
X	       (forms--scroll-up arg)))))
X  ;;
X  ;; beginning-of-buffer -> forms-first-record
X  ;;
X  (if (fboundp 'forms--beginning-of-buffer)
X      nil
X    (fset 'forms--beginning-of-buffer (symbol-function 'beginning-of-buffer))
X    (fset 'beginning-of-buffer
X	  '(lambda ()
X	     (interactive)
X	     (if (and forms--mode-setup
X		      forms-forms-jump)
X		 (forms-first-record)
X	       (forms--beginning-of-buffer)))))
X  ;;
X  ;; end-of-buffer -> forms-end-record
X  ;;
X  (if (fboundp 'forms--end-of-buffer)
X      nil
X    (fset 'forms--end-of-buffer (symbol-function 'end-of-buffer))
X    (fset 'end-of-buffer
X	  '(lambda ()
X	     (interactive)
X	     (if (and forms--mode-setup
X		      forms-forms-jump)
X		 (forms-last-record)
X	       (forms--end-of-buffer)))))
X  ;;
X  ;; save-buffer -> forms--save-buffer
X  ;;
X  (if (fboundp 'forms--save-buffer)
X      nil
X    (fset 'forms--save-buffer (symbol-function 'save-buffer))
X    (fset 'save-buffer
X	  '(lambda (&optional arg)
X	     (interactive "P")
X	     (if forms--mode-setup
X		 (progn
X		   (forms--checkmod)
X		   (save-excursion
X		     (set-buffer forms--file-buffer)
X		     (forms--save-buffer arg)))
X	       (forms--save-buffer arg)))))
X  ;;
X  )
X
X(defun forms--help ()
X  "Initial help."
X  ;; We should use
X  ;;(message (substitute-command-keys (concat
X  ;;"\\[forms-next-record]:next"
X  ;;"   \\[forms-prev-record]:prev"
X  ;;"   \\[forms-first-record]:first"
X  ;;"   \\[forms-last-record]:last"
X  ;;"   \\[describe-mode]:help"
X  ;;"   \\[forms-exit]:exit")))
X  ;; but it's too slow ....
X  (if forms-read-only
X      (message "SPC:next   DEL:prev   <:first   >:last   ?:help   q:exit")
X    (message "C-c n:next   C-c p:prev   C-c <:first   C-c >:last   C-c ?:help   C-c q:exit")))
X
X(defun forms--trans (subj arg rep)
X  "Translate in SUBJ all chars ARG into char REP. ARG and REP should
X be single-char strings."
X  (let ((i 0)
X	(x (length subj))
X	(re (regexp-quote arg))
X	(k (string-to-char rep)))
X    (while (setq i (string-match re subj i))
X      (aset subj i k)
X      (setq i (1+ i)))))
X
X(defun forms--exit (query &optional save)
X  (let ((buf (buffer-name forms--file-buffer)))
X    (forms--checkmod)
X    (if (and save
X	     (buffer-modified-p forms--file-buffer))
X	(save-excursion
X	  (set-buffer forms--file-buffer)
X	  (save-buffer)))
X    (save-excursion
X      (set-buffer forms--file-buffer)
X      (delete-auto-save-file-if-necessary)
X      (kill-buffer (current-buffer)))
X    (if (get-buffer buf)	; not killed???
X      (if save
X	  (progn
X	    (beep)
X	    (message "Problem saving buffers?")))
X      (delete-auto-save-file-if-necessary)
X      (kill-buffer (current-buffer)))))
X
X(defun forms--get-record ()
X  "Fetch the current record from the file buffer."
X  ;;
X  ;; This function is executed in the context of the forms--file-buffer.
X  ;;
X  (or (bolp)
X      (beginning-of-line nil))
X  (let ((here (point)))
X    (prog2
X     (end-of-line)
X     (buffer-substring here (point))
X     (goto-char here))))
X
X(defun forms--show-record (the-record)
X  "Format THE-RECORD according to forms-format-list,
X and display it in the current buffer."
X
X  ;; split the-record
X  (let (the-result
X	(start-pos 0)
X	found-pos
X	(field-sep-length (length forms-field-sep)))
X    (if forms-multi-line
X	(forms--trans the-record forms-multi-line "\n"))
X    ;; add an extra separator (makes splitting easy)
X    (setq the-record (concat the-record forms-field-sep))
X    (while (setq found-pos (string-match forms-field-sep the-record start-pos))
X      (let ((ent (substring the-record start-pos found-pos)))
X	(setq the-result
X	      (append the-result (list ent)))
X	(setq start-pos (+ field-sep-length found-pos))))
X    (setq forms--the-record-list the-result))
X
X  (setq buffer-read-only nil)
X  (erase-buffer)
X
X  ;; verify the number of fields, extend forms--the-record-list if needed
X  (if (= (length forms--the-record-list) forms-number-of-fields)
X      nil
X    (beep)
X    (message "Record has %d fields instead of %d."
X	     (length forms--the-record-list) forms-number-of-fields)
X    (if (< (length forms--the-record-list) forms-number-of-fields)
X	(setq forms--the-record-list 
X	      (append forms--the-record-list
X		      (make-list 
X		       (- forms-number-of-fields 
X			  (length forms--the-record-list))
X		       "")))))
X
X  ;; call the formatter function
X  (funcall forms--format forms--the-record-list)
X
X  ;; prepare
X  (goto-char (point-min))
X  (set-buffer-modified-p nil)
X  (setq buffer-read-only forms-read-only)
X  (setq mode-line-process
X	(concat " " forms--current-record "/" forms--total-records)))
X
X(defun forms--parse-form ()
X  "Parse contents of form into list of strings."
X  ;; The contents of the form are parsed, and a new list of strings
X  ;; is constructed.
X  ;; A vector with the strings from the original record is 
X  ;; constructed, which is updated with the new contents. Therefore
X  ;; fields which were not in the form are not modified.
X  ;; Finally, the vector is transformed into a list for further processing.
X
X  (let (the-recordv)
X
X    ;; build the vector
X    (setq the-recordv (vconcat forms--the-record-list))
X
X    ;; parse the form and update the vector
X    (funcall forms--parser)
X
X    ;; transform to a list and return
X    (append the-recordv nil)))
X
X(defun forms--update ()
X  "Update current record with contents of form. As a side effect: sets
Xforms--the-record-list ."
X  (if forms-read-only
X      (progn
X	(message "Read-only buffer!")
X	(beep))
X
X    (let (the-record)
X      ;; build new record
X      (setq forms--the-record-list (forms--parse-form))
X      (setq the-record
X	    (mapconcat 'identity forms--the-record-list forms-field-sep))
X
X      ;; handle multi-line fields, if allowed
X      (if forms-multi-line
X	  (forms--trans the-record "\n" forms-multi-line))
X
X      ;; a final sanity check before updating
X      (if (string-match "\n" the-record)
X	  (progn
X	    (message "Multi-line fields in this record - update refused!")
X	    (beep))
X
X	(save-excursion
X	  (set-buffer forms--file-buffer)
X	  (kill-line nil)
X	  (insert the-record)
X	  (beginning-of-line))))))
X
X(defun forms--checkmod ()
X  "Check if this form has been modified, and call forms--update if so."
X  (if (buffer-modified-p nil)
X      (let ((here (point)))
X	(forms--update)
X	(set-buffer-modified-p nil)
X	(goto-char here))))
X
X;;;
X;;; Start and exit
X(defun forms-find-file (fn)
X  "Visit file FN in forms mode"
X  (interactive "fForms file: ")
X  (find-file-read-only fn)
X  (or forms--mode-setup (forms-mode t)))
X
X(defun forms-find-file-other-window (fn)
X  "Visit file FN in form mode in other window"
X  (interactive "fFbrowse file in other window: ")
X  (find-file-other-window fn)
X  (eval-current-buffer)
X  (or forms--mode-setup (forms-mode t)))
X
X(defun forms-exit (query)
X  "Normal exit. Modified buffers are saved."
X  (interactive "P")
X  (forms--exit query t))
X
X(defun forms-exit-no-save (query)
X  "Exit without saving buffers."
X  (interactive "P")
X  (forms--exit query nil))
X
X;;;
X;;; Navigating commands
X
X(defun forms-next-record (arg)
X  "Advance to the ARGth following record."
X  (interactive "P")
X  (forms-jump-record (+ forms--current-record (prefix-numeric-value arg)) t))
X
X(defun forms-prev-record (arg)
X  "Advance to the ARGth previous record."
X  (interactive "P")
X  (forms-jump-record (- forms--current-record (prefix-numeric-value arg)) t))
X
X(defun forms-jump-record (arg &optional relative)
X  "Jump to a random record."
X  (interactive "NRecord number: ")
X
X  ;; verify that the record number is within range
X  (if (or (> arg forms--total-records)
X	  (<= arg 0))
X    (progn
X      (beep)
X      ;; don't give the message if just paging
X      (if (not relative)
X	  (message "Record number %d out of range 1..%d"
X		   arg forms--total-records))
X      )
X
X    ;; flush
X    (forms--checkmod)
X
X    ;; calculate displacement
X    (let ((disp (- arg forms--current-record))
X	  (cur forms--current-record))
X
X      ;; forms--show-record needs it now
X      (setq forms--current-record arg)
X
X      ;; get the record and show it
X      (forms--show-record
X       (save-excursion
X	 (set-buffer forms--file-buffer)
X	 (beginning-of-line)
X
X	 ;; move, and adjust the amount if needed (shouldn't happen)
X	 (if relative
X	     (if (zerop disp)
X		 nil
X	       (setq cur (+ cur disp (- (forward-line disp)))))
X	   (setq cur (+ cur disp (- (goto-line arg)))))
X
X	 (forms--get-record)))
X
X      ;; this shouldn't happen
X      (if (/= forms--current-record cur)
X	  (progn
X	    (setq forms--current-record cur)
X	    (beep)
X	    (message "Stuck at record %d." cur))))))
X
X(defun forms-first-record ()
X  "Jump to first record."
X  (interactive)
X  (forms-jump-record 1))
X
X(defun forms-last-record ()
X  "Jump to last record. As a side effect: re-calculates the number
X of records in the data file."
X  (interactive)
X  (let
X      ((numrec 
X	(save-excursion
X	  (set-buffer forms--file-buffer)
X	  (count-lines (point-min) (point-max)))))
X    (if (= numrec forms--total-records)
X	nil
X      (beep)
X      (setq forms--total-records numrec)
X      (message "Number of records reset to %d." forms--total-records)))
X  (forms-jump-record forms--total-records))
X
X;;;
X;;; Other commands
X(defun forms-view-mode ()
X  "Visit buffer read-only."
X  (interactive)
X  (if forms-read-only
X      nil
X    (forms--checkmod)			; sync
X    (setq forms-read-only t)
X    (forms-mode)))
X
X(defun forms-edit-mode ()
X  "Make form suitable for editing, if possible."
X  (interactive)
X  (let ((ro forms-read-only))
X    (if (save-excursion
X	  (set-buffer forms--file-buffer)
X	  buffer-read-only)
X	(progn
X	  (setq forms-read-only t)
X	  (message "No write access to \"%s\"" forms-file)
X	  (beep))
X      (setq forms-read-only nil))
X    (if (equal ro forms-read-only)
X	nil
X      (forms-mode))))
X
X(defun forms-insert-record (arg)
X  "Create a new record before the current one. With ARG: store the
X record after the current one."
X
X  (interactive "P")
X
X  (let ((ln (if arg (1+ forms--current-record) forms--current-record))
X        (the-record
X	 (mapconcat
X	  'identity
X	  (make-list forms-number-of-fields "")
X	  forms-field-sep)))
X
X    (save-excursion
X      (set-buffer forms--file-buffer)
X      (goto-line ln)
X      (open-line 1)
X      (insert the-record)
X      (beginning-of-line))
X    
X    (setq forms--current-record ln))
X
X  (setq forms--total-records (1+ forms--total-records))
X  (forms-jump-record forms--current-record))
X
X(defun forms-delete-record (arg)
X  "Deletes a record. With ARG: don't ask."
X  (interactive "P")
X  (if (or arg
X	  (y-or-n-p "Really delete this record? "))
X      (let ((ln forms--current-record))
X	(save-excursion
X	  (set-buffer forms--file-buffer)
X	  (goto-line ln)
X	  (kill-line 1))
X	(setq forms--total-records (1- forms--total-records))
X	(if (> forms--current-record forms--total-records)
X	    (setq forms--current-record forms--total-records))
X	(forms-jump-record forms--current-record)))
X  (message ""))
X
X(defun forms-search (regexp)
X  "Search REGEXP in file buffer."
X  (interactive 
X   (list (read-string (concat "Search for" 
X				  (if forms--search-regexp
X				   (concat " ("
X					   forms--search-regexp
X					   ")"))
X				  ": "))))
X  (if (equal "" regexp)
X      (setq regexp forms--search-regexp))
X
X  (let (the-line the-record here
X		 (fld-sep forms-field-sep))
X    (if (save-excursion
X	  (set-buffer forms--file-buffer)
X	  (setq here (point))
X	  (end-of-line)
X	  (if (null (re-search-forward regexp nil t))
X	      (progn
X		(goto-char here)
X		(message (concat "\"" regexp "\" not found."))
X		nil)
X	    (setq the-record (forms--get-record))
X	    (setq the-line (1+ (count-lines (point-min) (point))))))
X	(progn
X	  (setq forms--current-record the-line)
X	  (forms--show-record the-record)
X	  (re-search-forward regexp nil t))))
X  (setq forms--search-regexp regexp))
X
X(defun forms-revert-buffer (&optional arg noconfirm)
X  "Reverts current form to un-modified."
X  (interactive "P")
X  (if (or noconfirm
X	  (yes-or-no-p "Revert form to unmodified? "))
X      (progn
X	(set-buffer-modified-p nil)
X	(forms-jump-record forms--current-record))))
X
X(defun forms-next-field (arg)
X  "Jump to ARG-th next field."
X  (interactive "p")
X
X  (let ((i 0)
X	(here (point))
X	there
X	(cnt 0))
X
X    (if (zerop arg)
X	(setq cnt 1)
X      (setq cnt (+ cnt arg)))
X
X    (if (catch 'done
X	  (while (< i forms--number-of-markers)
X	    (if (or (null (setq there (aref forms--markers i)))
X		    (<= there here))
X		nil
X	      (if (<= (setq cnt (1- cnt)) 0)
X		  (progn
X		    (goto-char there)
X		    (throw 'done t))))
X	    (setq i (1+ i))))
X	nil
X      (goto-char (aref forms--markers 0)))))
SHAR_EOF
echo "File forms.el is complete" &&
$TOUCH -am 0610122590 forms.el &&
chmod 0444 forms.el ||
echo "restore of forms.el failed"
set `wc -c forms.el`;Wc_c=$1
if test "$Wc_c" != "36688"; then
	echo original size 36688, current size $Wc_c
fi
# ============= forms.ti ==============
echo "x - extracting forms.ti (Text)"
sed 's/^X//' << 'SHAR_EOF' > forms.ti &&
X\input texinfo			@c -*-texinfo-*- @(#)@ forms 1.1.2
X@comment %**start of header (This is for running Texinfo on a region.)
X@setfilename forms.info
X@settitle Forms Mode User's Manual
X@iftex
X@finalout
X@end iftex
X@setchapternewpage odd
X@c      @smallbook
X@comment %**end of header (This is for running Texinfo on a region.)
X
X@tex
X\global\chapno=30
X@end tex
X
X@ifinfo
XThis file documents forms-mode, a forms based major mode for GNU Emacs.
X
XPermission is granted to make and distribute verbatim copies of this
Xmanual provided the copyright notice and this permission notice are
Xpreserved on all copies.
X
X@ignore
XPermission is granted to process this file through TeX and print the
Xresults, provided the printed document carries copying permission notice
Xidentical to this one except for the removal of this paragraph (this
Xparagraph not being relevant to the printed manual).
X
X@end ignore
X@end ifinfo
X
X@iftex
X@titlepage
X@sp 6
X@center @titlefont{Forms Mode User's Manual}
X@sp 4
X@center First Release, Forms-Mode version 1.1
X@sp 1
X@center June 1990
X@sp 5
X@center Johan Vromans
X@center @i{jv@@mh.nl}
X@page
X
X@vskip 0pt plus 1filll
XCopyright @copyright{} 1989,1990 Free Software Foundation, Inc.
X
XPermission is granted to make and distribute verbatim copies of
Xthis manual provided the copyright notice and this permission notice
Xare preserved on all copies.
X
X@end titlepage
X@page
X@end iftex
X
X@ifinfo
X@node Top, What is in a Forms, , (DIR)
X@end ifinfo
X
X@iftex
X@chapter Forms mode
X@end iftex
X
XForms mode is an Emacs major mode for working with simple plain-text
Xdatabases in a forms-oriented manner. In forms mode, the information in
Xthese files is presented in an Emacs window in a user-defined format,
Xone record at a time. Forms can be inspected read-only (viewing) or
Xmodified and updated.
X@cindex forms-mode
X
XForms mode is not a simple major mode, but requires @dfn{two} files to do its
Xjob: a @dfn{control file} and a @dfn{data file}. The data file holds the
Xactual data which will be presented. The control file describes
X@dfn{how} it will be presented.
X
X@menu
X* What is in a Forms::	Introduction.
X* Data File Format::	How to format the data file.
X* Control File Format::	How to control forms mode.
X* Forms Format Description::
X			How to define the forms layout.
X* Modifying Forms Contents::
X			How to modify.
X* Forms Mode Commands::	The commands available, and how to use them.
X* Key Bindings::	Which keys are bound to what commands.
X* Miscellaneous::	Forms mode messages and other remarks.
X* Credits::		Thanks everyone.
X* Concept Index::	Index of Concepts
X* Variable Index::	Index of Variables.
X* Function Index::	Index of Functions.
X@end menu
X
X@node What is in a Forms, Data File Format, Top, Top
X@section What is in a forms
X
XLet's illustrate forms mode with an example. Suppose you are looking at
Xyour @file{/etc/passwd} file, and your screen looks as follows:
X
X@example
X====== /etc/passwd ======
X
XUser : root   Uid: 0   Gid: 1
X
XName : Super User
X
XHome : /
X
XShell: /bin/sh
X@end example
X
XAs you can see, the familiar fields from the entry for the super user
Xare all there, but instead of one single line, they make up a forms.
X
XThe contents of the forms consists of the contents of the fields of the
Xrecord (e.g. @code{root}, @code{0}, @code{1}, @code{Super User})
Xinterspersed with normal text (e.g @code{User : }, @code{Uid: }).
X
XYou can define yourself how text and fields will be used to make up the
Xforms.
X
XWhen you modifiy the contents of the forms, it will be analyzed and the
Xnew contents of the fields of this record will be extracted. It
Xpossible, the file will be updated with the new contents.
X
X@node Data File Format, Control File Format, What is in a Forms, Top
X@section Data file format
X
XFiles for use with forms mode are very simple -- each record forms the
Xcontents one form.  Each record is supposed to consist of a number of
Xfields. These fields are separated by the value of the string
X@code{forms-field-sep}, which is a @code{TAB} by default.
X
X@cindex pseudo-newline
XFields may contain text which shows up in the forms in multiple lines.
XThese lines are separated in the field using a @var{pseudo-newline}
Xcharacter which is defined by the value of the string
X@code{forms-multi-line}. Its default value is a Control-K character. If
Xit is set to @code{nil} multiple line fields are prohibited.
X
X@node Control File Format, Forms Format Description, Data File Format, Top
X@section Control file format
X
XThe control file serves two purposes.
X
XFirst, it defines the data file to use, and its properties.
X
XSecond, the Emacs buffer it occupies will be used by the forms mode to
Xdisplay the forms.
X
X@findex eval-current-buffer
XThe contents of the control file are evaluated using the Emacs command
X@code{eval-current-buffer}, hence must contain valid Emacs-lisp expressions.
XThese expressions should set the following lisp variables to a suitable
Xvalue:
X
X@table @code
X@vindex forms-file
X@item forms-file
XThis variable must be set to the name of the data file.@*
XExample:
X@example
X(setq forms-file "my/data-file")
X@end example
X
X@item forms-format-list
XThis variable describes the way the fields of the record are formatted on
Xthe screen. See the next section for details.
X
X@vindex forms-field-sep
X@item forms-field-sep
XThis variable may be used to designate the string which separates the fields
Xin the records of the data file. If not set, it defaults to a string
Xcontaining a single @code{TAB} character. @*
XExample:
X@example
X(setq forms-field-sep "\t")
X@end example
X
X@vindex forms-number-of-fields
X@item forms-number-of-fields
XThis variable holds the number of fields in each record of the data
Xfile.@*
XExample:
X@example
X(setq forms-number-of-fields 10)
X@end example
X
X@vindex forms-read-only
X@item forms-read-only
XIf set to a value other than @code{nil}, the data file is treated
Xread-only. If the data file can not be written into, read-only mode is
Xenforced. The default value for @code{forms-read-only} is derieved from
Xthe access permissions of the data file.@*
XExample:
X@example
X(set forms-read-only t)
X@end example
X
X@vindex forms-multi-line
X@item forms-multi-line
XThis variable may be set to allow multi-line text in fields. It should
Xbe set to a string of one character, which denotes the pseudo new-line
Xcharacter to be used to separate the text lines.@*
XIts default value is Control-K (octal 013). If set to @code{nil},
Xmulti-line text fields are prohibited.@*
XIt may not be a character contained in @code{forms-field-sep}.@*
XExample:
X@example
X(setq forms-multi-line "\C-k")
X@end example
X
X@end table
X
XOf these fields, only @code{forms-file}, @code{forms-number-of-fields}
Xand @code{forms-format-list} are mandatory. An error will be given if
Xone of these variables has not been set. All other variables have
Xdefault values which are suitable for most applications.
X
XTwo more variables may be used:
X@code{forms-forms-scroll} and @code{forms-forms-jump}.
X@xref{Forms Mode Commands} for their descriptions.
X
X@node Forms Format Description, Modifying Forms Contents, Control File Format, Top
X@section The forms format description
X
X@vindex forms-format-list
XThe value of the variable @code{forms-format-list} is used to specify
Xthe format of the forms. It must be a @code{list} of formatting elements,
SHAR_EOF
echo "End of  part 2"
echo "File forms.ti is continued in part 3"
echo "3" > shar3_seq_.tmp
exit 0


