• Home
  • History
  • Annotate
  • Raw
  • Download
  • only in /macosx-10.10.1/emacs-93/emacs/lisp/

Lines Matching defs:forms

0 ;;; forms.el --- Forms mode: edit a file as a form to fill in
31 ;; The names of all variables and functions start with 'forms-'.
32 ;; Names which start with 'forms--' are intended for internal use, and
35 ;; All variables are buffer-local, to enable multiple forms visits
37 ;; Variable `forms--mode-setup' is local to *ALL* buffers, for it
38 ;; controls if forms-mode has been enabled in a buffer.
53 ;; data file and the forms format. This file buffer will be used to
54 ;; present the forms.
58 ;; Forms mode is invoked using M-x `forms-find-file' control-file.
59 ;; Alternatively `forms-find-file-other-window' can be used.
61 ;; You may also visit the control file, and switch to forms mode by hand
62 ;; with M-x `forms-mode'.
65 ;; "-*- forms -*-" in the first line of the control file.
70 ;; forms-file [string]
73 ;; forms-number-of-fields [integer]
76 ;; forms-format-list [list]
79 ;; `forms-format-list' should be a list, each element containing
81 ;; - a string, e.g. "hello". The string is inserted in the forms
90 ;; string. It should *NOT* have side-effects on the forms being
92 ;; in the variable `forms-fields', they should *NOT* be modified.
98 ;; forms-field-sep [string, default TAB]
102 ;; forms-read-only [bool, default nil]
108 ;; forms-check-number-of-fields [bool, default t]
111 ;; of fields specified by `forms-number-of-fields'.
113 ;; forms-multi-line [string, default "^K"]
123 ;; forms-forms-scroll [bool, default nil]
126 ;; `forms-next-field' resp. `forms-prev-field'.
128 ;; forms-forms-jump [bool, default nil]
131 ;; perform, respectively, `forms-first-record' and
132 ;; `forms-last-record' instead.
134 ;; forms-insert-after [bool, default nil]
141 ;; forms-read-file-filter [symbol, default nil]
143 ;; function that is called after the forms data file
146 ;; for forms-mode processing.
148 ;; forms-write-file-filter [symbol, default nil]
150 ;; function that is called before the forms data file
152 ;; the effects of `forms-read-file-filter', if any.
154 ;; forms-new-record-filter [symbol, default nil]
160 ;; forms-modified-record-filter [symbol, default nil]
167 ;; forms-use-text-properties [bool, see text for default]
168 ;; This variable controls if forms mode should use
180 ;; forms-ro-face [symbol, default 'default]
187 ;; (setq forms-ro-face 'my-face)
189 ;; forms-rw-face [symbol, default 'region]
195 ;; The data file (as designated by `forms-file') is visited in a buffer
196 ;; `forms--file-buffer' which normally will not be shown.
201 ;; split it into fields (into `forms--the-record-list'), and display it
202 ;; using the specs in `forms-format-list'.
203 ;; A format routine `forms--format' is built upon startup to format
204 ;; the records according to `forms-format-list'.
208 ;; obtained from `forms-format-list', and the fields which are
209 ;; deduced from the form are modified. Fields not shown on the forms
211 ;; replaces the contents of the old record in `forms--file-buffer'.
212 ;; A parse routine `forms--parser' is built upon startup to parse
215 ;; Two exit functions exist: `forms-exit' and `forms-exit-no-save'.
216 ;; `forms-exit' saves the data to the file, if modified.
217 ;; `forms-exit-no-save' does not. However, if `forms-exit-no-save'
221 ;; Other functions provided by forms mode are:
232 ;; file (using forms-last-record) will adjust forms--total-records if
235 ;; The forms buffer can be in one of two modes: edit mode or view
241 ;; TAB forms-next-field
242 ;; \C-c TAB forms-next-field
243 ;; \C-c < forms-first-record
244 ;; \C-c > forms-last-record
246 ;; \C-c \C-k forms-delete-record
247 ;; \C-c \C-q forms-toggle-read-only
248 ;; \C-c \C-o forms-insert-record
249 ;; \C-c \C-l forms-jump-record
250 ;; \C-c \C-n forms-next-record
251 ;; \C-c \C-p forms-prev-record
252 ;; \C-c \C-r forms-search-backward
253 ;; \C-c \C-s forms-search-forward
254 ;; \C-c \C-x forms-exit
258 ;; SPC forms-next-record
259 ;; DEL forms-prev-record
261 ;; \C-q forms-toggle-read-only
262 ;; l forms-jump-record
263 ;; n forms-next-record
264 ;; p forms-prev-record
265 ;; r forms-search-backward
266 ;; s forms-search-forward
267 ;; x forms-exit
274 ;; [next] forms-next-record
275 ;; [prior] forms-prev-record
276 ;; [begin] forms-first-record
277 ;; [end] forms-last-record
278 ;; [S-TAB] forms-prev-field
279 ;; [backtab] forms-prev-field
281 ;; For convenience, TAB is always bound to `forms-next-field', so you
284 ;; As mentioned above (see `forms-forms-scroll' and `forms-forms-jump'),
287 ;; forms mode functions next/prev record and first/last
292 ;; revert a forms to original.
297 (defgroup forms nil
303 (provide 'forms) ;;; official
304 (provide 'forms-mode) ;;; for compatibility
306 (defcustom forms-mode-hook nil
308 :group 'forms
314 (defvar forms-file nil
317 (defvar forms-format-list nil
320 (defvar forms-number-of-fields nil
326 (defcustom forms-check-number-of-fields t
328 :group 'forms
331 (defvar forms-field-sep "\t"
334 (defvar forms-read-only nil
338 (defvar forms-multi-line "\C-k" "\
341 (defcustom forms-forms-scroll nil
343 The replacement commands performs forms-next/prev-record."
344 :group 'forms
347 (defcustom forms-forms-jump nil
349 The replacement commands performs forms-first/last-record."
350 :group 'forms
353 (defvar forms-read-file-filter nil
356 suitable for forms processing.")
358 (defvar forms-write-file-filter nil
362 (defvar forms-new-record-filter nil
365 (defvar forms-modified-record-filter nil
368 (defvar forms-fields nil
369 "List with fields of the current forms. First field has number 1.
373 (defcustom forms-use-text-properties t
376 :group 'forms
379 (defcustom forms-insert-after nil
382 :group 'forms
385 (defcustom forms-ro-face 'default
387 :group 'forms
390 (defcustom forms-rw-face 'region
392 :group 'forms
398 (defvar forms--file-buffer nil
401 (defvar forms--total-records 0
404 (defvar forms--current-record 0
407 (defvar forms-mode-map nil
409 (defvar forms-mode-ro-map nil
411 (defvar forms-mode-edit-map nil
414 (defvar forms--markers nil
417 (defvar forms--dyntexts nil
420 (defvar forms--the-record-list nil
423 (defvar forms--search-regexp nil
424 "Last regexp used by forms-search functions.")
426 (defvar forms--format nil
429 (defvar forms--parser nil
432 (defvar forms--mode-setup nil
433 "To keep track of forms-mode being set-up.")
434 (make-variable-buffer-local 'forms--mode-setup)
436 (defvar forms--dynamic-text nil
439 (defvar forms--elements nil
442 (defvar forms--ro-face nil
445 (defvar forms--rw-face nil
450 (defun forms-mode (&optional primary)
454 TAB forms-next-field TAB
455 C-c TAB forms-next-field
456 C-c < forms-first-record <
457 C-c > forms-last-record >
459 C-c C-k forms-delete-record
460 C-c C-q forms-toggle-read-only q
461 C-c C-o forms-insert-record
462 C-c C-l forms-jump-record l
463 C-c C-n forms-next-record n
464 C-c C-p forms-prev-record p
465 C-c C-r forms-search-reverse r
466 C-c C-s forms-search-forward s
467 C-c C-x forms-exit x
471 ;; This is not a simple major mode, as usual. Therefore, forms-mode
474 ;; A global buffer-local variable `forms--mode-setup' has the same
475 ;; effect but makes it possible to auto-invoke forms-mode using
483 (if (or primary (not forms--mode-setup))
485 ;;(message "forms: setting up...")
489 (make-local-variable 'forms-file)
490 (make-local-variable 'forms-number-of-fields)
491 (make-local-variable 'forms-format-list)
494 (make-local-variable 'forms-field-sep)
495 (make-local-variable 'forms-read-only)
496 (make-local-variable 'forms-multi-line)
497 (make-local-variable 'forms-forms-scroll)
498 (make-local-variable 'forms-forms-jump)
499 (make-local-variable 'forms-insert-after)
500 (make-local-variable 'forms-use-text-properties)
503 (make-local-variable 'forms-read-file-filter)
504 (make-local-variable 'forms-write-file-filter)
505 (make-local-variable 'forms-new-record-filter)
506 (make-local-variable 'forms-modified-record-filter)
509 (setq forms-read-file-filter nil)
510 (setq forms-write-file-filter nil)
511 (setq forms-new-record-filter nil)
512 (setq forms-modified-record-filter nil)
518 (make-local-variable 'forms-ro-face)
519 (make-local-variable 'forms-rw-face)))
522 ;;(message "forms: processing control file...")
527 (buffer-name) " to display forms? ")))
532 (or forms-file
534 "`forms-file' has not been set")))
536 ;; Check forms-field-sep first, since it can be needed to
538 (or (stringp forms-field-sep)
540 "`forms-field-sep' is not a string")))
542 (if forms-number-of-fields
543 (or (and (numberp forms-number-of-fields)
544 (> forms-number-of-fields 0))
546 "`forms-number-of-fields' must be a number > 0")))
547 (or (null forms-format-list)
549 "`forms-number-of-fields' has not been set"))))
551 (or forms-format-list
552 (forms--intuit-from-file))
554 (if forms-multi-line
555 (if (and (stringp forms-multi-line)
556 (eq (length forms-multi-line) 1))
557 (if (string= forms-multi-line forms-field-sep)
559 "`forms-multi-line' is equal to `forms-field-sep'")))
561 "`forms-multi-line' must be nil or a one-character string"))))
563 (setq forms-use-text-properties nil))
565 ;; Validate and process forms-format-list.
566 ;;(message "forms: pre-processing format list...")
567 (make-local-variable 'forms--elements)
568 (forms--process-format-list)
571 ;;(message "forms: building formatter...")
572 (make-local-variable 'forms--format)
573 (make-local-variable 'forms--markers)
574 (make-local-variable 'forms--dyntexts)
575 ;;(message "forms: building parser...")
576 (forms--make-format)
577 (make-local-variable 'forms--parser)
578 (forms--make-parser)
579 ;;(message "forms: building parser... done.")
582 (if (and forms-new-record-filter
583 (not (fboundp forms-new-record-filter)))
585 "`forms-new-record-filter' is not a function")))
587 (if (and forms-modified-record-filter
588 (not (fboundp forms-modified-record-filter)))
590 "`forms-modified-record-filter' is not a function")))
592 ;; The filters acces the contents of the forms using `forms-fields'.
593 (make-local-variable 'forms-fields)
596 (make-local-variable 'forms--dynamic-text)
605 ;;(message "forms: setting up... done.")
609 (setq forms--mode-setup t)
611 ;; Copy desired faces to the actual variables used by the forms formatter.
614 (make-local-variable 'forms--ro-face)
615 (make-local-variable 'forms--rw-face)
616 (if forms-read-only
618 (setq forms--ro-face forms-ro-face)
619 (setq forms--rw-face forms-ro-face))
620 (setq forms--ro-face forms-ro-face)
621 (setq forms--rw-face forms-rw-face))))
624 (make-local-variable 'forms--file-buffer)
625 (make-local-variable 'forms--total-records)
626 (make-local-variable 'forms--current-record)
627 (make-local-variable 'forms--the-record-list)
628 (make-local-variable 'forms--search-regexp)
630 ; The keymaps are global, so multiple forms mode buffers can share them.
631 ;(make-local-variable 'forms-mode-map)
632 ;(make-local-variable 'forms-mode-ro-map)
633 ;(make-local-variable 'forms-mode-edit-map)
634 (if forms-mode-map ; already defined
636 ;;(message "forms: building keymap...")
637 (forms--mode-commands)
638 ;;(message "forms: building keymap... done.")
642 (setq major-mode 'forms-mode)
646 (setq forms--file-buffer (find-file-noselect forms-file))
649 (let ((read-file-filter forms-read-file-filter)
650 (write-file-filter forms-write-file-filter))
652 (with-current-buffer forms--file-buffer
660 (with-current-buffer forms--file-buffer
665 (setq forms--total-records
666 (with-current-buffer forms--file-buffer
669 ;;(message "forms: counting records...")
673 ;;(message "forms: counting records... done.")
676 (setq forms-read-only t)))
678 ;;(message "forms: proceeding setup...")
681 ;; directly to get the text " View " into forms-read-only form buffers. For
684 (setq minor-mode-alist (list (list 'forms-read-only " View")))
686 ;;(message "forms: proceeding setup (keymaps)...")
687 (forms--set-keymaps)
688 ;;(message "forms: proceeding setup (commands)...")
689 (forms--change-commands)
691 ;;(message "forms: proceeding setup (buffer)...")
694 (if (= forms--total-records 0)
695 ;;(message "forms: proceeding setup (new file)...")
699 (if (file-exists-p forms-file)
700 (concat "No records available in file `" forms-file "'\n\n")
702 forms-file forms-number-of-fields
703 (if (= 1 forms-number-of-fields) "" "s")))
704 "Use " (substitute-command-keys "\\[forms-insert-record]")
706 (setq forms--current-record 1)
711 (if (< forms--current-record 1)
712 (setq forms--current-record 1))
713 (forms-jump-record forms--current-record)
715 (if forms-insert-after
716 (forms-last-record)
717 (forms-first-record))
721 ;;(message "forms: proceeding setup (user hooks)...")
722 (run-mode-hooks 'forms-mode-hook 'forms-mode-hooks)
723 ;;(message "forms: setting up... done.")
726 (forms--help)
730 (defun forms--process-format-list ()
731 ;; Validate `forms-format-list' and set some global variables.
734 ;; Array `forms--elements' is constructed that contains the order
736 ;; `forms--parser-using-text-properties' to extract the fields data
738 ;; Upon completion, `forms-format-list' is guaranteed correct, so
739 ;; `forms--make-format' and `forms--make-parser' do not need to perform
742 ;; Verify that `forms-format-list' is not nil.
743 (or forms-format-list
745 "`forms-format-list' has not been set")))
747 (or (listp forms-format-list)
749 "`forms-format-list' is not a list")))
752 ;; `forms--elements' will grow if needed.
753 (setq forms--elements (make-vector forms-number-of-fields nil))
755 (let ((the-list forms-format-list) ; the list of format elements
759 (setq forms-format-list nil) ; gonna rebuild
778 (setq forms-format-list
779 (append forms-format-list (list prev-item) nil)))
787 (> el forms-number-of-fields))
790 el forms-number-of-fields))
792 ;; Store forms order.
793 (if (>= field-num (length forms--elements))
794 (setq forms--elements (vconcat forms--elements (1- el)))
795 (aset forms--elements field-num (1- el)))
799 (setq forms-format-list
800 (append forms-format-list (list prev-item) nil)))
814 (setq forms-format-list
815 (append forms-format-list (list prev-item) nil)))
830 (setq forms-format-list
831 (append forms-format-list (list prev-item) nil))
836 (setq forms-format-list
837 (append forms-format-list (list "\n") nil))))))
839 (forms--debug 'forms-format-list
840 'forms--elements))
853 (defvar forms--iif-start nil
855 (defvar forms--iif-properties nil
858 (defun forms--iif-hook (begin end)
864 (or forms--iif-start
865 (setq forms--iif-start (copy-marker (1+ (point)))))
868 (if (or (<= forms--iif-start 2)
869 (get-text-property (- forms--iif-start 2)
873 (setq forms--iif-properties
874 (text-properties-at (1- forms--iif-start)))
879 (1- forms--iif-start) forms--iif-start
880 (list 'face forms--rw-face 'front-sticky '(face))))
884 (append (list 'forms--iif-post-command-hook) post-command-hook)))
887 (setq forms--iif-start nil)))
889 (defun forms--iif-post-command-hook ()
894 (delq 'forms--iif-hook-post-command-hook post-command-hook))
897 (if forms--iif-start
900 (1- forms--iif-start) forms--iif-start
901 forms--iif-properties)))
904 (setq forms--iif-start nil))
907 (defvar forms--marker)
908 (defvar forms--dyntext)
910 (defun forms--make-format ()
911 "Generate `forms--format' using the information in `forms-format-list'."
913 ;; The real work is done using a mapcar of `forms--make-format-elt' on
914 ;; `forms-format-list'.
918 (let ((forms--marker 0)
919 (forms--dyntext 0))
921 forms--format
922 (if forms-use-text-properties
926 (mapcar 'forms--make-format-elt-using-text-properties
927 forms-format-list))
929 ,@(if (numberp (car forms-format-list))
936 (setq forms--iif-start nil))
939 (mapcar 'forms--make-format-elt forms-format-list)))))
943 (setq forms--markers (make-vector forms--marker nil))
944 (setq forms--dyntexts (make-vector forms--dyntext nil)))
945 (forms--debug 'forms--format))
947 (defun forms--make-format-elt-using-text-properties (el)
950 ;; The format routine `forms--format' will look like
960 ;; (list 'face forms--ro-face
962 ;; 'insert-in-front-hooks 'forms--iif-hook
967 ;; (aset forms--markers 0 (point-marker))
972 ;; (list 'face forms--rw-face
979 ;; (list 'face forms--ro-face
981 ;; 'insert-in-front-hooks 'forms--iif-hook
988 ;; (insert (aset forms--dyntexts 0 (tocol 40)))
990 ;; (list 'face forms--ro-face
992 ;; 'insert-in-front-hooks 'forms--iif-hook
1003 ;; (setq forms--iif-start nil)
1014 (list 'face forms--ro-face ; read-only appearance
1015 'read-only ,@(list (1+ forms--marker))
1016 'intangible ,@(list (1+ forms--marker))
1017 'insert-in-front-hooks '(forms--iif-hook)
1023 (aset forms--markers
1024 ,(prog1 forms--marker
1025 (setq forms--marker (1+ forms--marker)))
1031 (list 'face forms--rw-face
1038 (insert (aset forms--dyntexts
1039 ,(prog1 forms--dyntext
1040 (setq forms--dyntext (1+ forms--dyntext)))
1043 (list 'face forms--ro-face
1044 'read-only ,@(list (1+ forms--marker))
1045 'intangible ,@(list (1+ forms--marker))
1046 'insert-in-front-hooks '(forms--iif-hook)
1053 (defun forms--make-format-elt (el)
1057 ;; `forms--format' will look like
1063 ;; (aset forms--markers 0 (point-marker))
1068 ;; (insert (aset forms--dyntexts 0 (tocol 40)))
1076 `((aset forms--markers ,forms--marker (point-marker))
1078 (setq forms--marker (1+ forms--marker))))
1081 `((insert (aset forms--dyntexts ,forms--dyntext ,el)))
1082 (setq forms--dyntext (1+ forms--dyntext))))))
1085 (defvar forms--field)
1086 (defvar forms--recordv)
1087 (defvar forms--seen-text)
1089 (defun forms--make-parser ()
1090 "Generate `forms--parser' from the information in `forms-format-list'."
1093 ;; `forms--parser-using-text-properties'.
1095 ;; `forms--make-parser-elt on `forms-format-list'.
1098 forms--parser
1099 (if forms-use-text-properties
1100 (function forms--parser-using-text-properties)
1101 (let ((forms--field nil)
1102 (forms--seen-text nil)
1103 (forms--dyntext 0))
1106 ;; see `forms--make-parser-elt' for details.
1112 'forms--make-parser-elt
1113 (append forms-format-list (list nil)))))))))
1115 (forms--debug 'forms--parser))
1117 (defun forms--parser-using-text-properties ()
1118 "Extract field info from forms when using text properties."
1125 (while (< i (length forms--markers))
1126 (goto-char (setq here (aref forms--markers i)))
1128 (aset forms--recordv (aref forms--elements i) nil)
1131 (aset forms--recordv (aref forms--elements i)
1133 (aset forms--recordv (aref forms--elements i)
1137 (defun forms--make-parser-elt (el)
1138 "Helper routine to generate forms parser function."
1156 ;; (aset forms--recordv 5 (buffer-substring-no-properties here (- (point) 12)))
1159 ;; (let ((forms--dyntext (car-safe forms--dynamic-text)))
1160 ;; (if (not (looking-at (regexp-quote forms--dyntext)))
1161 ;; (error "Parse error: not looking at \"%s\"" forms--dyntext))
1162 ;; (forward-char (length forms--dyntext))
1163 ;; (setq forms--dynamic-text (cdr-safe forms--dynamic-text)))
1166 ;; (aset forms--recordv 7 (buffer-substring-no-properties (point) (point-max)))
1171 (if forms--field
1175 (aset forms--recordv ,(1- forms--field)
1181 (setq forms--seen-text t)
1182 (setq forms--field nil)))
1184 (if forms--field
1186 forms--field el)
1187 (setq forms--field el)
1190 (if forms--field
1191 `((aset forms--recordv ,(1- forms--field)
1195 (if forms--field
1197 (forms--dyntext (aref forms--dyntexts ,forms--dyntext)))
1198 (if (not (search-forward forms--dyntext nil t nil))
1199 (error "Parse error: cannot find `%s'" forms--dyntext))
1200 (aset forms--recordv ,(1- forms--field)
1202 (- (point) (length forms--dyntext))))))
1203 `((let ((forms--dyntext (aref forms--dyntexts ,forms--dyntext)))
1204 (if (not (looking-at (regexp-quote forms--dyntext)))
1205 (error "Parse error: not looking at `%s'" forms--dyntext))
1206 (forward-char (length forms--dyntext)))))
1207 (setq forms--dyntext (1+ forms--dyntext))
1208 (setq forms--seen-text t)
1209 (setq forms--field nil)))
1213 (defun forms--intuit-from-file ()
1216 ;; If `forms-number-of-fields' is not set, get it from the data file.
1217 (if (null forms-number-of-fields)
1220 (if (not (file-exists-p forms-file))
1221 (error "Need existing file or explicit `forms-number-of-fields'")
1224 (setq forms--file-buffer (find-file-noselect forms-file))
1225 (let ((read-file-filter forms-read-file-filter)
1228 (with-current-buffer forms--file-buffer
1232 (forms--get-record)))
1236 (kill-buffer forms--file-buffer)
1241 (field-sep-length (length forms-field-sep)))
1242 (setq forms-number-of-fields 1)
1244 (string-match forms-field-sep the-record start-pos))
1246 (setq forms-number-of-fields (1+ forms-number-of-fields))
1250 (setq forms-format-list (list "Forms file \"" forms-file "\".\n\n"))
1252 (while (<= (setq i (1+ i)) forms-number-of-fields)
1253 (setq forms-format-list
1254 (append forms-format-list
1258 (defun forms--set-keymaps ()
1261 (use-local-map (if forms-read-only
1262 forms-mode-ro-map
1263 forms-mode-edit-map)))
1265 (defun forms--mode-commands ()
1268 ;; `forms-mode-map' is always accessible via \C-c prefix.
1269 (setq forms-mode-map (make-keymap))
1270 (define-key forms-mode-map "\t" 'forms-next-field)
1271 (define-key forms-mode-map "\C-k" 'forms-delete-record)
1272 (define-key forms-mode-map "\C-q" 'forms-toggle-read-only)
1273 (define-key forms-mode-map "\C-o" 'forms-insert-record)
1274 (define-key forms-mode-map "\C-l" 'forms-jump-record)
1275 (define-key forms-mode-map "\C-n" 'forms-next-record)
1276 (define-key forms-mode-map "\C-p" 'forms-prev-record)
1277 (define-key forms-mode-map "\C-r" 'forms-search-backward)
1278 (define-key forms-mode-map "\C-s" 'forms-search-forward)
1279 (define-key forms-mode-map "\C-x" 'forms-exit)
1280 (define-key forms-mode-map "<" 'forms-first-record)
1281 (define-key forms-mode-map ">" 'forms-last-record)
1282 (define-key forms-mode-map "\C-?" 'forms-prev-record)
1284 ;; `forms-mode-ro-map' replaces the local map when in read-only mode.
1285 (setq forms-mode-ro-map (make-keymap))
1286 (suppress-keymap forms-mode-ro-map)
1287 (define-key forms-mode-ro-map "\C-c" forms-mode-map)
1288 (define-key forms-mode-ro-map "q" 'forms-toggle-read-only)
1289 (define-key forms-mode-ro-map "l" 'forms-jump-record)
1290 (define-key forms-mode-ro-map "n" 'forms-next-record)
1291 (define-key forms-mode-ro-map "p" 'forms-prev-record)
1292 (define-key forms-mode-ro-map "r" 'forms-search-backward)
1293 (define-key forms-mode-ro-map "s" 'forms-search-forward)
1294 (define-key forms-mode-ro-map "x" 'forms-exit)
1295 (define-key forms-mode-ro-map "<" 'forms-first-record)
1296 (define-key forms-mode-ro-map ">" 'forms-last-record)
1297 (define-key forms-mode-ro-map "?" 'describe-mode)
1298 (define-key forms-mode-ro-map " " 'forms-next-record)
1299 (forms--mode-commands1 forms-mode-ro-map)
1300 (forms--mode-menu-ro forms-mode-ro-map)
1303 (setq forms-mode-edit-map (make-keymap))
1304 (define-key forms-mode-edit-map "\C-c" forms-mode-map)
1305 (forms--mode-commands1 forms-mode-edit-map)
1306 (forms--mode-menu-edit forms-mode-edit-map)
1309 (defun forms--mode-menu-ro (map)
1312 (define-key map [menu-bar forms]
1314 (define-key map [menu-bar forms menu-forms-exit]
1315 '("Exit Forms Mode" . forms-exit))
1316 (define-key map [menu-bar forms menu-forms-sep1]
1318 (define-key map [menu-bar forms menu-forms-save]
1319 '("Save Data" . forms-save-buffer))
1320 (define-key map [menu-bar forms menu-forms-print]
1321 '("Print Data" . forms-print))
1322 (define-key map [menu-bar forms menu-forms-describe]
1324 (define-key map [menu-bar forms menu-forms-toggle-ro]
1325 '("Toggle View/Edit" . forms-toggle-read-only))
1326 (define-key map [menu-bar forms menu-forms-jump-record]
1327 '("Jump" . forms-jump-record))
1328 (define-key map [menu-bar forms menu-forms-search-backward]
1329 '("Search Backward" . forms-search-backward))
1330 (define-key map [menu-bar forms menu-forms-search-forward]
1331 '("Search Forward" . forms-search-forward))
1332 (define-key map [menu-bar forms menu-forms-delete-record]
1333 '("Delete" . forms-delete-record))
1334 (define-key map [menu-bar forms menu-forms-insert-record]
1335 '("Insert" . forms-insert-record))
1336 (define-key map [menu-bar forms menu-forms-sep2]
1338 (define-key map [menu-bar forms menu-forms-last-record]
1339 '("Last Record" . forms-last-record))
1340 (define-key map [menu-bar forms menu-forms-first-record]
1341 '("First Record" . forms-first-record))
1342 (define-key map [menu-bar forms menu-forms-prev-record]
1343 '("Previous Record" . forms-prev-record))
1344 (define-key map [menu-bar forms menu-forms-next-record]
1345 '("Next Record" . forms-next-record))
1346 (define-key map [menu-bar forms menu-forms-sep3]
1348 (define-key map [menu-bar forms menu-forms-prev-field]
1349 '("Previous Field" . forms-prev-field))
1350 (define-key map [menu-bar forms menu-forms-next-field]
1351 '("Next Field" . forms-next-field))
1352 (put 'forms-insert-record 'menu-enable '(not forms-read-only))
1353 (put 'forms-delete-record 'menu-enable '(not forms-read-only))
1355 (defun forms--mode-menu-edit (map)
1358 (define-key map [menu-bar forms]
1360 (define-key map [menu-bar forms menu-forms-edit--exit]
1361 '("Exit" . forms-exit))
1362 (define-key map [menu-bar forms menu-forms-edit-sep1]
1364 (define-key map [menu-bar forms menu-forms-edit-save]
1365 '("Save Data" . forms-save-buffer))
1366 (define-key map [menu-bar forms menu-forms-edit-print]
1367 '("Print Data" . forms-print))
1368 (define-key map [menu-bar forms menu-forms-edit-describe]
1370 (define-key map [menu-bar forms menu-forms-edit-toggle-ro]
1371 '("Toggle View/Edit" . forms-toggle-read-only))
1372 (define-key map [menu-bar forms menu-forms-edit-jump-record]
1373 '("Jump" . forms-jump-record))
1374 (define-key map [menu-bar forms menu-forms-edit-search-backward]
1375 '("Search Backward" . forms-search-backward))
1376 (define-key map [menu-bar forms menu-forms-edit-search-forward]
1377 '("Search Forward" . forms-search-forward))
1378 (define-key map [menu-bar forms menu-forms-edit-delete-record]
1379 '("Delete" . forms-delete-record))
1380 (define-key map [menu-bar forms menu-forms-edit-insert-record]
1381 '("Insert" . forms-insert-record))
1382 (define-key map [menu-bar forms menu-forms-edit-sep2]
1384 (define-key map [menu-bar forms menu-forms-edit-last-record]
1385 '("Last Record" . forms-last-record))
1386 (define-key map [menu-bar forms menu-forms-edit-first-record]
1387 '("First Record" . forms-first-record))
1388 (define-key map [menu-bar forms menu-forms-edit-prev-record]
1389 '("Previous Record" . forms-prev-record))
1390 (define-key map [menu-bar forms menu-forms-edit-next-record]
1391 '("Next Record" . forms-next-record))
1392 (define-key map [menu-bar forms menu-forms-edit-sep3]
1394 (define-key map [menu-bar forms menu-forms-edit-prev-field]
1395 '("Previous Field" . forms-prev-field))
1396 (define-key map [menu-bar forms menu-forms-edit-next-field]
1397 '("Next Field" . forms-next-field))
1398 (put 'forms-insert-record 'menu-enable '(not forms-read-only))
1399 (put 'forms-delete-record 'menu-enable '(not forms-read-only))
1402 (defun forms--mode-commands1 (map)
1404 (define-key map "\t" 'forms-next-field)
1405 (define-key map [S-tab] 'forms-prev-field)
1406 (define-key map [next] 'forms-next-record)
1407 (define-key map [prior] 'forms-prev-record)
1408 (define-key map [begin] 'forms-first-record)
1409 (define-key map [last] 'forms-last-record)
1410 (define-key map [backtab] 'forms-prev-field)
1416 (defun forms--change-commands ()
1419 ;; scroll-down -> forms-prev-record
1420 ;; scroll-up -> forms-next-record
1421 (if forms-forms-scroll
1423 (local-set-key [remap scroll-up] 'forms-next-record)
1424 (local-set-key [remap scroll-down] 'forms-prev-record)))
1426 ;; beginning-of-buffer -> forms-first-record
1427 ;; end-of-buffer -> forms-end-record
1428 (if forms-forms-jump
1430 (local-set-key [remap beginning-of-buffer] 'forms-first-record)
1431 (local-set-key [remap end-of-buffer] 'forms-last-record)))
1434 (local-set-key "\C-x\C-s" 'forms-save-buffer)
1438 (setq revert-buffer-function 'forms--revert-buffer)
1442 (defun forms--help ()
1445 "\\[forms-next-record]:next"
1446 " \\[forms-prev-record]:prev"
1447 " \\[forms-first-record]:first"
1448 " \\[forms-last-record]:last"
1451 (defun forms--trans (subj arg rep)
1461 (defun forms--exit (&optional save)
1462 "Internal exit from forms mode function."
1464 (let ((buf (buffer-name forms--file-buffer)))
1465 (forms--checkmod)
1467 (buffer-modified-p forms--file-buffer))
1468 (forms-save-buffer))
1469 (with-current-buffer forms--file-buffer
1478 (defun forms--get-record ()
1481 ;; This function is executed in the context of the `forms--file-buffer'.
1491 (defun forms--show-record (the-record)
1498 (field-sep-length (length forms-field-sep)))
1499 (if forms-multi-line
1500 (forms--trans the-record forms-multi-line "\n"))
1502 (setq the-record (concat the-record forms-field-sep))
1503 (while (setq found-pos (string-match forms-field-sep the-record start-pos))
1508 (setq forms--the-record-list the-result))
1511 (if forms-use-text-properties
1516 ;; Verify the number of fields, extend forms--the-record-list if needed.
1517 (if (= (length forms--the-record-list) forms-number-of-fields)
1519 (if (null forms-check-number-of-fields)
1522 (length forms--the-record-list) forms-number-of-fields))
1523 (if (< (length forms--the-record-list) forms-number-of-fields)
1524 (setq forms--the-record-list
1525 (append forms--the-record-list
1527 (- forms-number-of-fields
1528 (length forms--the-record-list))
1532 (setq forms-fields (append (list nil) forms--the-record-list nil))
1533 (funcall forms--format forms--the-record-list)
1538 (setq buffer-read-only forms-read-only)
1540 (concat " " (int-to-string forms--current-record)
1541 "/" (int-to-string forms--total-records))))
1543 (defun forms--parse-form ()
1552 (let (forms--recordv)
1555 (setq forms--recordv (vconcat forms--the-record-list))
1558 (let ((forms--dynamic-text forms--dynamic-text))
1559 (funcall forms--parser))
1561 (if forms-modified-record-filter
1563 ;; can use the same indices as in the forms definition.
1564 (let ((the-fields (vconcat [nil] forms--recordv)))
1565 (setq the-fields (funcall forms-modified-record-filter the-fields))
1569 (append forms--recordv nil))))
1571 (defun forms--update ()
1573 As a side effect: sets `forms--the-record-list'."
1575 (if forms-read-only
1580 (setq forms--the-record-list (forms--parse-form))
1582 (mapconcat 'identity forms--the-record-list forms-field-sep))
1584 (if (string-match (regexp-quote forms-field-sep)
1585 (mapconcat 'identity forms--the-record-list ""))
1589 (if forms-multi-line
1590 (forms--trans the-record "\n" forms-multi-line))
1596 (with-current-buffer forms--file-buffer
1603 (defun forms--checkmod ()
1604 "Check if this form has been modified, and call forms--update if so."
1607 (forms--update)
1615 (defun forms-find-file (fn)
1621 (or forms--mode-setup (forms-mode t))))
1624 (defun forms-find-file-other-window (fn)
1630 (or forms--mode-setup (forms-mode t))))
1632 (defun forms-exit ()
1635 (forms--exit t))
1637 (defun forms-exit-no-save ()
1640 (forms--exit nil))
1645 (defun forms-next-record (arg)
1648 (forms-jump-record (+ forms--current-record (prefix-numeric-value arg)) t))
1650 (defun forms-prev-record (arg)
1653 (forms-jump-record (- forms--current-record (prefix-numeric-value arg)) t))
1655 (defun forms--goto-record (rn &optional current)
1665 (defun forms-jump-record (arg &optional relative)
1670 (if (or (> arg forms--total-records)
1676 arg forms--total-records)
1680 (forms--checkmod)
1683 (let ((cur forms--current-record))
1685 ;; `forms--show-record' needs it now.
1686 (setq forms--current-record arg)
1689 (forms--show-record
1690 (with-current-buffer forms--file-buffer
1694 (setq cur (- arg (forms--goto-record arg (if relative cur))))
1696 (forms--get-record)))
1699 (if (/= forms--current-record cur)
1701 (setq forms--current-record cur)
1704 (defun forms-first-record ()
1707 (forms-jump-record 1))
1709 (defun forms-last-record ()
1715 (with-current-buffer forms--file-buffer
1717 (if (= numrec forms--total-records)
1719 (setq forms--total-records numrec)
1720 (message "Warning: number of records changed to %d" forms--total-records)))
1721 (forms-jump-record forms--total-records))
1726 (defun forms-toggle-read-only (arg)
1727 "Toggles read-only mode of a forms mode buffer.
1737 forms-read-only)
1740 (let ((ro forms-read-only))
1741 (if (with-current-buffer forms--file-buffer
1744 (setq forms-read-only t)
1745 (message "No write access to `%s'" forms-file))
1746 (setq forms-read-only nil))
1747 (if (equal ro forms-read-only)
1749 (forms-mode)))
1752 (if forms-read-only
1754 (forms--checkmod) ; sync
1755 (setq forms-read-only t)
1756 (forms-mode))))
1764 ;; (setq forms-new-record-filter 'my-new-record-filter)
1766 (defun forms-insert-record (arg)
1769 If `forms-new-record-filter' contains the name of a function,
1771 If `forms-insert-after is non-nil, the default behavior is to insert
1776 (if forms-read-only
1781 (if (or (and arg forms-insert-after)
1782 (and (not arg) (not forms-insert-after)))
1783 (setq ln forms--current-record)
1784 (setq ln (1+ forms--current-record)))
1786 (forms--checkmod)
1787 (if forms-new-record-filter
1789 ;; can use the same indices as in the forms definition.
1790 (let ((the-fields (make-vector (1+ forms-number-of-fields) "")))
1791 (setq the-fields (funcall forms-new-record-filter the-fields))
1793 (setq the-list (make-list forms-number-of-fields "")))
1799 forms-field-sep))
1801 (with-current-buffer forms--file-buffer
1802 (forms--goto-record ln)
1807 (setq forms--current-record ln))
1809 (setq forms--total-records (1+ forms--total-records))
1810 (forms-jump-record forms--current-record))
1812 (defun forms-delete-record (arg)
1816 (if forms-read-only
1819 (forms--checkmod)
1822 (let ((ln forms--current-record))
1823 (with-current-buffer forms--file-buffer
1824 (forms--goto-record ln)
1829 (setq forms--total-records (1- forms--total-records))
1830 (if (> forms--current-record forms--total-records)
1831 (setq forms--current-record forms--total-records))
1832 (forms-jump-record forms--current-record)))
1835 (defun forms-search-forward (regexp)
1839 (if forms--search-regexp
1841 forms--search-regexp
1845 (setq regexp forms--search-regexp))
1846 (forms--checkmod)
1849 (with-current-buffer forms--file-buffer
1858 (setq the-record (forms--get-record))
1864 (setq forms--current-record the-line)
1865 (forms--show-record the-record))
1867 (setq forms--search-regexp regexp))
1869 (defun forms-search-backward (regexp)
1873 (if forms--search-regexp
1875 forms--search-regexp
1879 (setq regexp forms--search-regexp))
1880 (forms--checkmod)
1883 (with-current-buffer forms--file-buffer
1892 (setq the-record (forms--get-record))
1898 (setq forms--current-record the-line)
1899 (forms--show-record the-record))
1901 (setq forms--search-regexp regexp))
1903 (defun forms-save-buffer (&optional args)
1905 It saves the data buffer instead of the forms buffer.
1906 Calls `forms-write-file-filter' before, and `forms-read-file-filter'
1909 (forms--checkmod)
1910 (let ((write-file-filter forms-write-file-filter)
1911 (read-file-filter forms-read-file-filter)
1912 (cur forms--current-record))
1913 (with-current-buffer forms--file-buffer
1935 (forms-jump-record cur))
1938 (defun forms--revert-buffer (&optional arg noconfirm)
1945 (forms-jump-record forms--current-record))))
1947 (defun forms-next-field (arg)
1962 (while (< i (length forms--markers))
1963 (if (or (null (setq there (aref forms--markers i)))
1972 (goto-char (aref forms--markers 0)))))
1974 (defun forms-prev-field (arg)
1978 (let ((i (length forms--markers))
1991 (if (or (null (setq there (aref forms--markers i)))
1999 (goto-char (aref forms--markers (1- (length forms--markers)))))))
2001 (defun forms-print ()
2005 (save-record forms--current-record)
2006 (total-nb-records forms--total-records)
2009 (while (<= nb-record forms--total-records)
2010 (forms-jump-record nb-record)
2012 (with-current-buffer (get-buffer-create "*forms-print*")
2020 (with-current-buffer "*forms-print*"
2024 (forms-jump-record save-record)))
2029 (defun forms-enumerate (the-fields)
2034 Usage: (setq forms-number-of-fields
2035 (forms-enumerate
2049 (defvar forms--debug nil
2050 "*Enables forms-mode debugging if not nil.")
2052 (defun forms--debug (&rest args)
2054 (if forms--debug
2069 (with-current-buffer (get-buffer-create "*forms-mode debug*")
2076 ;;; forms.el ends here