;ELC   
;;; compiled by jwz@thalidomide on Sun Jan  2 21:09:08 1994
;;; from file /th/jwz/emacs19/lisp/utils/forms.el
;;; emacs version 19.9 Lucid (beta10).
;;; bytecomp version 2.22; 22-dec-93.
;;; optimization is on.
;;; this file uses opcodes which do not exist in Emacs 18.

(if (and (boundp 'emacs-version)
	 (or (and (boundp 'epoch::version) epoch::version)
	     (string-lessp emacs-version "19")))
    (error "This file was compiled for Emacs 19."))

(byte-code "!!" [provide forms forms-mode] 2)
(defconst forms-version (substring "!Revision: 2.3 !" 11 -2) "\
The version number of forms-mode (as string).  The complete RCS id is:

  !Id: forms.el,v 2.3 1993/10/21 00:43:51 rms Exp !")
(defvar forms-mode-hooks nil "\
Hook functions to be run upon entering Forms mode.")
(defvar forms-file nil "\
Name of the file holding the data.")
(defvar forms-format-list nil "\
List of formatting specifications.")
(defvar forms-number-of-fields nil "\
Number of fields per record.")
(defvar forms-field-sep "	" "\
Field separator character (default TAB).")
(defvar forms-read-only nil "\
Non-nil means: visit the file in view (read-only) mode.
(Defaults to the write access on the data file).")
(defvar forms-multi-line "" "\
If not nil: use this character to separate multi-line fields (default C-k).")
(defvar forms-forms-scroll nil "\
*Non-nil means replace scroll-up/down commands in Forms mode.
The replacement commands performs forms-next/prev-record.")
(defvar forms-forms-jump nil "\
*Non-nil means redefine beginning/end-of-buffer in Forms mode.
The replacement commands performs forms-first/last-record.")
(defvar forms-new-record-filter nil "\
The name of a function that is called when a new record is created.")
(defvar forms-modified-record-filter nil "\
The name of a function that is called when a record has been modified.")
(defvar forms-fields nil "\
List with fields of the current forms.  First field has number 1.
This variable is for use by the filter routines only. 
The contents may NOT be modified.")
(defvar forms-use-extents (fboundp 'set-extent-property) "\
*Non-nil means: use Lucid Emacs extents.
Defaults to t if this emacs is capable of handling text properties.")
(defvar forms-use-text-properties (byte-code "!\n?" [fboundp set-text-properties forms-use-extents] 2) "\
*Non-nil means: use emacs-19 text properties.
Defaults to t if this emacs is capable of handling text properties.")
(defvar forms-ro-face (byte-code "\n\"Çć" [string-match "Lucid" emacs-version forms-label-face default] 3) "\
The face (a symbol) that is used to display read-only text on the screen.")
(defvar forms-rw-face (byte-code "\n\"Çć" [string-match "Lucid" emacs-version forms-field-face region] 3) "\
The face (a symbol) that is used to display read-write text on the screen.")
(byte-code "!\"" [boundp forms--lemacs-p string-match "Lucid" emacs-version] 3)
(defvar forms--file-buffer nil "\
Buffer which holds the file data")
(defvar forms--total-records 0 "\
Total number of records in the data file.")
(defvar forms--current-record 0 "\
Number of the record currently on the screen.")
(defvar forms-mode-map nil "\
Keymap for form buffer.")
(defvar forms-mode-ro-map nil "\
Keymap for form buffer in view mode.")
(defvar forms-mode-edit-map nil "\
Keymap for form buffer in edit mode.")
(defvar forms--markers nil "\
Field markers in the screen.")
(defvar forms--dyntexts nil "\
Dynamic texts (resulting from function calls) on the screen.")
(defvar forms--the-record-list nil "\
List of strings of the current record, as parsed from the file.")
(defvar forms--search-regexp nil "\
Last regexp used by forms-search.")
(defvar forms--format nil "\
Formatting routine.")
(defvar forms--parser nil "\
Forms parser routine.")
(defvar forms--mode-setup nil "\
To keep track of forms-mode being set-up.")
(make-variable-buffer-local 'forms--mode-setup)
(defvar forms--dynamic-text nil "\
Array that holds dynamic texts to insert between fields.")
(defvar forms--elements nil "\
Array with the order in which the fields are displayed.")
(defvar forms--ro-face nil "\
Face used to represent read-only data on the screen.")
(defvar forms--rw-face nil "\
Face used to represent read-write data on the screen.")
(byte-code "!!!\"" [forms--lemacs-p make-face forms-field-face forms-label-face face-differs-from-default-p copy-face bold] 3)
(fset 'forms-mode #[(&optional primary) "	  !!!!!!!!!!!!! P!P!VP!;P!		;	G=	P!P! !!!! ! !P!!P!!!*!, !!!././!!!!!5 !080qp!,8ed\")18)=?Á@ !ȁA DC@B  C  D !2W2E 2!F G !H  " [primary forms--mode-setup kill-all-local-variables make-local-variable forms-file forms-number-of-fields forms-format-list forms-field-sep forms-read-only forms-multi-line forms-forms-scroll forms-forms-jump forms-new-record-filter forms-modified-record-filter nil fboundp make-face forms-ro-face forms-rw-face eval-current-buffer error "Forms control file error: " "'forms-file' has not been set" "'forms-number-of-fields' has not been set" 0 "'forms-number-of-fields' must be a number > 0" "'forms-field-sep' is not a string" 1 "'forms-multi-line' is equal to 'forms-field-sep'" "'forms-multi-line' must be nil or a one-character string" forms--process-format-list forms--format forms--markers forms--dyntexts forms--elements forms--make-format forms--parser forms--make-parser "'forms-new-record-filter' is not a function" "'forms-modified-record-filter' is not a function" forms-fields forms--dynamic-text buffer-file-name auto-save-mode buffer-read-only erase-buffer forms--ro-face forms--rw-face forms--file-buffer forms--total-records forms--current-record forms--the-record-list forms--search-regexp forms-mode-map forms--mode-commands find-file-noselect ro bury-buffer count-lines t forms-mode major-mode "Forms" mode-name minor-mode-alist " View" forms--set-keymaps forms--change-commands set-buffer-modified-p forms-jump-record run-hooks forms-mode-hooks forms--help] 3 "\
Major mode to visit files in a field-structured manner using a form.

Commands:                        Equivalent keys in read-only mode:

 TAB          forms-next-field           TAB
 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     q
 C-c C-o      forms-insert-record
 C-c C-l      forms-jump-record          l
 C-c C-n      forms-next-record          n
 C-c C-p      forms-prev-record          p
 C-c C-s      forms-search               s
 C-c C-x      forms-exit                 x" nil])
(fset 'forms--process-format-list #[nil "P!<P!\"\n 9!!;;P C# XVP#\nGVS\"\nSI\nT\nC#<!!Q!C#!Q!*( C#C#,\"" [forms-format-list error "Forms control file error: " "'forms-format-list' has not been set" "'forms-format-list' is not a list" make-vector forms-number-of-fields nil forms--elements 0 field-num prev-item this-item the-list rem el boundp eval append "Forms format error: " "field number %d out of range 1..%d" vconcat fboundp "not a function " prin1-to-string "invalid element " "\n" forms--debug] 6])
(defvar forms--iif-start nil "\
Record start of modification command.")
(defvar forms--iif-properties nil "\
Original properties of the character being overridden.")
(fset 'forms--iif-hook #[(begin end) "`T!XZ\"S!SF#)C\"щ" [forms--iif-start copy-marker 2 get-text-property read-only text-properties-at forms--iif-properties t inhibit-read-only set-text-properties face forms--rw-face front-sticky (face) append forms--iif-post-command-hook post-command-hook nil] 7 "\
`insert-in-front-hooks' function for read-only segments."])
(fset 'forms--iif-post-command-hook #[nil "\n\"S#)ȉ" [delq forms--iif-hook-post-command-hook post-command-hook forms--iif-start t inhibit-read-only set-text-properties forms--iif-properties nil] 4 "\
`post-command-hook' function for read-only segments."])
(fset 'forms--make-format #[nil "\"\"@?$F\"\"#\"\"\"\n\"	\"*!" [0 forms--dyntext forms--marker forms-use-text-properties lambda (arg) append (let ((inhibit-read-only t))) apply mapcar forms--make-format-elt-using-text-properties forms-format-list ((add-text-properties (point-min) (1+ (point-min)) '(front-sticky (read-only)))) ((remove-text-properties (1- (point)) (point) '(rear-nonsticky))) (setq forms--iif-start nil) forms-use-extents (lambda (arg)) forms--make-format-elt-using-extents ((map-extents (function (lambda (extent ignore) (cond ((not (extent-property extent 'forms)) nil) ((not (extent-property extent 'read-only)) (set-extent-property extent 'end-open nil)) ((= (point-min) (extent-start-position extent)) (set-extent-property extent 'start-open nil) (set-extent-property extent 'end-open t)) ((= (point-max) (extent-end-position extent)) (set-extent-property extent 'start-open t) (set-extent-property extent 'end-open nil)) (t (set-extent-property extent 'start-open t) (set-extent-property extent 'end-open t))) nil)) (current-buffer) (point-min) (point-max))) (lambda (arg)) forms--make-format-elt forms--format make-vector nil forms--markers forms--dyntexts forms--debug] 9 "\
Generate `forms--format' using the information in `forms-format-list'."])
(fset 'forms--make-format-elt-using-text-properties #[(el) ";DETC#FCTFSEDѯC<TFDETC#FC" [el set-text-properties (point) progn insert (point) append (list 'face forms--ro-face 'read-only) forms--marker ('insert-in-front-hooks '(forms--iif-hook) 'rear-nonsticky '(face read-only insert-in-front-hooks)) let ((here (point))) aset forms--markers (point-marker) elt arg (or (= (point) here) (set-text-properties here (point) (list 'face forms--rw-face 'front-sticky '(face)))) (point) forms--dyntexts forms--dyntext (point) (list 'face forms--ro-face 'read-only) ('insert-in-front-hooks '(forms--iif-hook) 'rear-nonsticky '(read-only face insert-in-front-hooks))] 8 "\
Helper routine to generate format function."])
(fset 'forms--make-format-elt-using-extents #[(el) ";DEEDCC#CTFSEDүC<TFDEEDCC#C" [el append (let) extent make-extent (point) progn insert (point) ((set-extent-face extent forms--ro-face) (set-extent-property extent 'forms t) (set-extent-property extent 'read-only t)) let ((here (point))) aset forms--markers forms--marker (point-marker) elt arg (if (= (point) here) nil (let ((extent (make-extent here (point)))) (set-extent-face extent forms--rw-face) (set-extent-property extent 'forms t))) (let) (point) forms--dyntexts forms--dyntext (point) ((set-extent-face extent forms--ro-face) (set-extent-property extent 'forms t) (set-extent-property extent 'read-only t))] 11 "\
Helper routine to generate format function."])
(fset 'forms--make-format-elt #[(el) ";DCFSEDDT<	FDC	T	" [el insert aset forms--markers forms--marker (point-marker) elt arg forms--dyntexts forms--dyntext] 5 "\
Helper routine to generate format function."])
(fset 'forms--make-parser #[nil "C\"\"\"\"E+!" [forms-use-text-properties forms--parser-using-text-properties nil 0 forms--dyntext forms--seen-text forms--field lambda append (let (here) (goto-char (point-min))) apply mapcar forms--make-parser-elt forms-format-list forms--parser forms--debug] 11 "\
Generate `forms--parser' from the information in `forms-format-list'."])
(fset 'forms--parser-using-text-properties #[nil "GWHb\"	HI\"	H\n{I	Hd{IT=+" [0 nil there here i forms--markers get-text-property read-only forms--recordv forms--elements next-single-property-change] 5 "\
Extract field info from forms when using text properties."])
(fset 'forms--make-parser-elt #[(el) ";	C#DEE	SGEEFE!DDEEGDD		#և		SFC<	EDD	SFFCEDCFCT" [el forms--field (setq here (point)) if not append (search-forward) (nil t nil) error "Parse error: cannot find \"%s\"" aset forms--recordv buffer-substring here - (point) looking-at regexp-quote "Parse error: not looking at \"%s\"" forward-char t forms--seen-text nil "Cannot parse adjacent fields %d and %d" (buffer-substring (point) (point-max)) let (here (point)) forms--dyntext aref forms--dyntexts (if (not (search-forward forms--dyntext nil t nil)) (error "Parse error: cannot find \"%s\"" forms--dyntext)) (buffer-substring here (- (point) (length forms--dyntext))) (if (not (looking-at (regexp-quote forms--dyntext))) (error "Parse error: not looking at \"%s\"" forms--dyntext)) (forward-char (length forms--dyntext))] 10 "\
Helper routine to generate forms parser function."])
(fset 'forms--set-keymaps #[nil "	\n!" [use-local-map forms-read-only forms-mode-ro-map forms-mode-edit-map] 2 "\
Set the keymaps used in this mode."])
(fset 'forms--mode-commands #[nil " 	#	#	#	#	#	#	#	#	#	#	#	#	# !	############! ''#'	#'!" [make-keymap forms-mode-map define-key "	" forms-next-field "" forms-delete-record "" forms-toggle-read-only "" forms-insert-record "" forms-jump-record "" forms-next-record "" forms-prev-record "" forms-search "" forms-exit "<" forms-first-record ">" forms-last-record "?" describe-mode "" forms-mode-ro-map suppress-keymap "" "q" "l" "n" "p" "s" "x" " " forms--mode-commands1 forms-mode-edit-map] 4 "\
Fill the Forms mode keymaps."])
(fset 'forms--mode-commands1 #[(map) "\n#\n#\n#\n#\n#\n#\n#\n#\n#" [forms--lemacs-p define-key map [tab] forms-next-field [(shift tab)] forms-prev-field [TAB] [S-tab] [next] forms-next-record [prior] forms-prev-record [begin] forms-first-record [last] forms-last-record [backtab]] 4 "\
Helper routine to define keys."])
(fset 'forms--change-commands #[nil " # # # #!\"!҇" [forms-forms-scroll substitute-key-definition scroll-up forms-next-record current-local-map scroll-down forms-prev-record forms-forms-jump beginning-of-buffer forms-first-record end-of-buffer forms-last-record make-local-variable local-write-file-hooks add-hook #[nil " 	q )Ç" [forms--checkmod forms--file-buffer save-buffer t] 1] revert-buffer-function forms-revert-buffer t] 4 "\
Localize some commands for Forms mode."])
(fset 'forms--help #[nil "ư!!" [message substitute-command-keys "\\[forms-next-record]:next" "   \\[forms-prev-record]:prev" "   \\[forms-first-record]:first" "   \\[forms-last-record]:last" "   \\[describe-mode]:help"] 7 "\
Initial help for Forms mode."])
(fset 'forms--trans #[(subj arg rep) "	G!!			#			I	T	f," [0 subj regexp-quote arg string-to-char rep k re x i string-match] 5 "\
Translate in SUBJ all chars ARG into char REP.  ARG and REP should
 be single-char strings."])
(fset 'forms--exit #[(query &optional save) "	! 	!	q )	q p!)\n! ! p!)" [buffer-name forms--file-buffer buf forms--checkmod save buffer-modified-p save-buffer delete-auto-save-file-if-necessary kill-buffer get-buffer beep message "Problem saving buffers?"] 2 "\
Internal exit from forms mode function."])
(fset 'forms--get-record #[nil "ny`	`{	b)" [0 here nil] 2 "\
Fetch the current record from the file buffer."])
(fset 'forms--show-record #[(the-record) "\nG	#	\nP	\n	#	OC\"\\)_,ed#) GU G#GWGZ\"\"C#!eb! \"R#" [nil 0 forms-field-sep field-sep-length found-pos start-pos the-result forms-multi-line forms--trans the-record "\n" string-match ent append forms--the-record-list buffer-read-only forms-use-text-properties t inhibit-read-only set-text-properties erase-buffer forms-number-of-fields beep message "Warning: this record has %d fields instead of %d" make-list "" forms-fields forms--format set-buffer-modified-p forms-read-only " " forms--current-record "/" forms--total-records mode-line-process] 5 "\
Format THE-RECORD and display it in the current buffer."])
(fset 'forms--parse-form #[nil "! )	\"!\"A)	\")" [nil forms--recordv vconcat forms--the-record-list forms--dynamic-text forms--parser forms-modified-record-filter [nil] the-fields append] 3 "\
Parse contents of form into list of strings."])
(fset 'forms--update #[nil "!  \n##\"! qy`)`)|cy))" [forms-read-only message "Read-only buffer!" beep nil the-record forms--parse-form forms--the-record-list mapconcat identity forms-field-sep forms-multi-line forms--trans "\n" string-match "Multi-line fields in this record - update refused!" forms--file-buffer 0] 4 "\
Update current record with contents of form.
As a side effect: sets `forms--the-record-list'."])
(fset 'forms--checkmod #[nil "!` !\nb)" [buffer-modified-p nil here forms--update set-buffer-modified-p] 2 "\
Check if this form has been modified, and call forms--update if so."])
(fset 'forms-find-file #[(fn) "	!\n!" [find-file-read-only fn forms--mode-setup forms-mode t] 2 "\
Visit a file in Forms mode." "fForms file: "])
(fset 'forms-find-file-other-window #[(fn) "	! !" [find-file-other-window fn eval-current-buffer forms--mode-setup forms-mode t] 2 "\
Visit a file in Forms mode in other window." "fFbrowse file in other window: "])
(fset 'forms-exit #[(query) "	\"" [forms--exit query t] 3 "\
Normal exit from Forms mode.  Modified buffers are saved." "P"])
(fset 'forms-exit-no-save #[(query) "	\"" [forms--exit query nil] 3 "\
Exit from Forms mode without saving buffers." "P"])
(fset 'forms-next-record #[(arg) "	!\\\"" [forms-jump-record forms--current-record prefix-numeric-value arg t] 4 "\
Advance to the ARGth following record." "P"])
(fset 'forms-prev-record #[(arg) "	!Z\"" [forms-jump-record forms--current-record prefix-numeric-value arg t] 4 "\
Advance to the ARGth previous record." "P"])
(fset 'forms-jump-record #[(arg &optional relative) "	VX ?	# Z	\nˊqy\nU	\ny[\\\\		\n![\\\\	 )!	U?	 	\"*" [arg forms--total-records 0 beep relative message "Record number %d out of range 1..%d" forms--checkmod forms--current-record cur disp forms--show-record forms--file-buffer goto-line forms--get-record "Stuck at record %d"] 5 "\
Jump to a random record." "NRecord number: "])
(fset 'forms-first-record #[nil "!" [forms-jump-record 1] 2 "\
Jump to first record." nil])
(fset 'forms-last-record #[nil "qed\")U \n\")!" [forms--file-buffer count-lines numrec forms--total-records beep message "Warning: number of records changed to %d" forms-jump-record] 4 "\
Jump to last record.
As a side effect: re-calculates the number of records in the data file." nil])
(fset 'forms-toggle-read-only #[(arg) "!Xq)\n\" ? )?  " [arg prefix-numeric-value 0 forms-read-only ro forms--file-buffer buffer-read-only t message "No write access to \"%s\"" forms-file beep nil forms-mode forms--checkmod] 3 "\
Toggles read-only mode of a forms mode buffer.
With an argument, enables read-only mode if the argument is positive.
Otherwise enables edit mode if the visited file is writeable." "P"])
(fset 'forms-insert-record #[(arg) "!Tŉ \nT\"\n!\"A)\"#q!!cy)+T!" [forms-read-only error "" arg forms--current-record nil the-record the-list ln forms--checkmod forms-new-record-filter make-vector forms-number-of-fields the-fields append make-list mapconcat identity forms-field-sep forms--file-buffer goto-line open-line 1 0 forms--total-records forms-jump-record] 4 "\
Create a new record before the current one.
With ARG: store the record after the current one.
If `forms-new-record-filter' contains the name of a function, 
it is called to fill (some of) the fields with default values." "P"])
(fset 'forms-delete-record #[(arg) "! !	q!y`)`T)|)SV!)!" [forms-read-only error "" forms--checkmod arg y-or-n-p "Really delete this record? " forms--current-record ln forms--file-buffer goto-line 0 nil forms--total-records forms-jump-record message] 2 "\
Deletes a record.  With a prefix argument: don't ask." "P"])
(fset 'forms-search #[(regexp) "\n ĉ	\nq`#bQ!Ī e`\"T	)	!#," [regexp "" forms--search-regexp forms--checkmod nil forms-field-sep fld-sep here the-record the-line forms--file-buffer re-search-forward t message "\"" "\" not found." forms--get-record count-lines forms--current-record forms--show-record] 4 "\
Search REGEXP in file buffer." (byte-code "\n\nQQ!C" [read-string "Search for" forms--search-regexp " (" ")" ": "] 5)])
(fset 'forms-revert-buffer #[(&optional arg noconfirm) "!!!" [noconfirm yes-or-no-p "Revert form to unmodified? " set-buffer-modified-p nil forms-jump-record forms--current-record] 2 "\
Reverts current form to un-modified." "P"])
(fset 'forms-next-field #[(arg) "`U\n\\ɍ?\nHb," [0 nil cnt there here i arg 1 done (byte-code "	GW	H\nXSX\nb\"TY" [i forms--markers there here cnt 0 throw done t] 4) forms--markers] 4 "\
Jump to ARG-th next field." "p"])
(fset 'forms-prev-field #[(arg) "G`U\\ʍ?GSHb," [forms--markers nil 0 cnt there here i arg 1 done (byte-code "VS\nHqYlSXdb\"Z" [i 0 forms--markers there here cnt throw done t] 3)] 4 "\
Jump to ARG-th previous field." "p"])
(fset 'forms-enumerate #[(the-fields) "\n	T\n\n	L)m	)" [0 the-index the-fields el] 2 "\
Take a quoted list of symbols, and set their values to sequential numbers.
The first symbol gets number 1, the second 2 and so on.
It returns the higest number.

Usage: (setq forms-number-of-fields
             (forms-enumerate
              '(field1 field2 field2 ...)))"])
(defvar forms--debug nil "\
*Enables forms-mode debugging if not nil.")
(fset 'forms--debug #[(&rest args) ";\nP\n!Q!!	\n	!Q)\nQ!\nK!Q)<!q U db\nc*" [forms--debug nil ret args el prin1-to-string " = " boundp eval vel "\n" "<unbound>" fboundp get-buffer-create "*forms-mode debug*" buffer-size 0 emacs-lisp-mode] 3 "\
Internal debugging routine."])
