aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1991-07-01 18:06:13 +0000
committerRichard M. Stallman1991-07-01 18:06:13 +0000
commit01a453133b73e130ac2415f07f6e9f63794d9efb (patch)
treec57f4e8f180e136a4a864f4e2cd032dee1e38e00
parent5dd353d2d79162c2277aa43d231aa34171c5f95b (diff)
downloademacs-01a453133b73e130ac2415f07f6e9f63794d9efb.tar.gz
emacs-01a453133b73e130ac2415f07f6e9f63794d9efb.zip
*** empty log message ***
-rw-r--r--lisp/forms.el363
1 files changed, 262 insertions, 101 deletions
diff --git a/lisp/forms.el b/lisp/forms.el
index b0598da72f4..3690c7e9a4a 100644
--- a/lisp/forms.el
+++ b/lisp/forms.el
@@ -1,9 +1,13 @@
1;;; Forms Mode - A GNU Emacs Major Mode ; @(#)@ forms 1.2.2 1;;; forms.el -- Forms Mode - A GNU Emacs Major Mode
2;;; Created 1989 - Johan Vromans <jv@mh.nl> 2;;; SCCS Status : @(#)@ forms 1.2.7
3;;; See the docs for a list of other contributors. 3;;; Author : Johan Vromans
4;;; 4;;; Created On : 1989
5;;; This file is part of GNU Emacs. 5;;; Last Modified By: Johan Vromans
6;;; Last Modified On: Mon Jul 1 14:13:20 1991
7;;; Update Count : 15
8;;; Status : OK
6 9
10;;; This file is part of GNU Emacs.
7;;; GNU Emacs is distributed in the hope that it will be useful, 11;;; GNU Emacs is distributed in the hope that it will be useful,
8;;; but WITHOUT ANY WARRANTY. No author or distributor 12;;; but WITHOUT ANY WARRANTY. No author or distributor
9;;; accepts responsibility to anyone for the consequences of using it 13;;; accepts responsibility to anyone for the consequences of using it
@@ -20,6 +24,21 @@
20;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 24;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21;;; 25;;;
22 26
27;;; HISTORY
28;;; 1-Jul-1991 Johan Vromans
29;;; Normalized error messages.
30;;; 30-Jun-1991 Johan Vromans
31;;; Add support for forms-modified-record-filter.
32;;; Allow the filter functions to be the name of a function.
33;;; Fix: parse--format used forms--dynamic-text destructively.
34;;; Internally optimized the forms-format-list.
35;;; Added support for debugging.
36;;; Stripped duplicate documentation.
37;;;
38;;; 29-Jun-1991 Johan Vromans
39;;; Add support for functions and lisp symbols in forms-format-list.
40;;; Add function forms-enumerate.
41
23(provide 'forms-mode) 42(provide 'forms-mode)
24 43
25;;; Visit a file using a form. 44;;; Visit a file using a form.
@@ -75,12 +94,20 @@
75;;; 94;;;
76;;; The forms-format-list should be a list, each element containing 95;;; The forms-format-list should be a list, each element containing
77;;; 96;;;
78;;; - either a string, e.g. "hello" (which is inserted \"as is\"), 97;;; - a string, e.g. "hello" (which is inserted \"as is\"),
79;;; 98;;;
80;;; - an integer, denoting a field number. The contents of the field 99;;; - an integer, denoting a field number. The contents of the field
81;;; are inserted at this point. 100;;; are inserted at this point.
82;;; The first field has number one. 101;;; The first field has number one.
83;;; 102;;;
103;;; - a function call, e.g. (insert "text"). This function call is
104;;; dynamically evaluated and should return a string. It should *NOT*
105;;; have side-effects on the forms being constructed.
106;;; The current fields are available to the function in the variable
107;;; forms-fields, they should *NOT* be modified.
108;;;
109;;; - a lisp symbol, that must evaluate to one of the above.
110;;;
84;;; Optional variables which may be set in the control file: 111;;; Optional variables which may be set in the control file:
85;;; 112;;;
86;;; forms-field-sep [string, default TAB] 113;;; forms-field-sep [string, default TAB]
@@ -111,10 +138,22 @@
111;;; to performs forms-first/last-field if in 138;;; to performs forms-first/last-field if in
112;;; forms mode. 139;;; forms mode.
113;;; 140;;;
114;;; forms-new-record-filter [function, no default] 141;;; forms-new-record-filter [symbol, no default]
115;;; If defined: this function is called when a new 142;;; If defined: this should be the name of a
143;;; function that is called when a new
116;;; record is created. It can be used to fill in 144;;; record is created. It can be used to fill in
117;;; the new record with default fields, for example. 145;;; the new record with default fields, for example.
146;;; Instead of the name of the function, it may
147;;; be the function itself.
148;;;
149;;; forms-modified-record-filter [symbol, no default]
150;;; If defined: this should be the name of a
151;;; function that is called when a record has
152;;; been modified. It is called after the fields
153;;; are parsed. It can be used to register
154;;; modification dates, for example.
155;;; Instead of the name of the function, it may
156;;; be the function itself.
118;;; 157;;;
119;;; After evaluating the control file, its buffer is cleared and used 158;;; After evaluating the control file, its buffer is cleared and used
120;;; for further processing. 159;;; for further processing.
@@ -126,7 +165,7 @@
126;;; A record from the data file is transferred from the data file, 165;;; A record from the data file is transferred from the data file,
127;;; split into fields (into forms--the-record-list), and displayed using 166;;; split into fields (into forms--the-record-list), and displayed using
128;;; the specs in forms-format-list. 167;;; the specs in forms-format-list.
129;;; A format routine 'forms--format' is build upon startup to format 168;;; A format routine 'forms--format' is built upon startup to format
130;;; the records. 169;;; the records.
131;;; 170;;;
132;;; When a form is changed the record is updated as soon as this form 171;;; When a form is changed the record is updated as soon as this form
@@ -135,7 +174,7 @@
135;;; fields not shown on the forms retain their origional values. 174;;; fields not shown on the forms retain their origional values.
136;;; The newly formed record and replaces the contents of the 175;;; The newly formed record and replaces the contents of the
137;;; old record in forms--file-buffer. 176;;; old record in forms--file-buffer.
138;;; A parse routine 'forms--parser' is build upon startup to parse 177;;; A parse routine 'forms--parser' is built upon startup to parse
139;;; the records. 178;;; the records.
140;;; 179;;;
141;;; Two exit functions exist: forms-exit (which saves) and forms-exit-no-save 180;;; Two exit functions exist: forms-exit (which saves) and forms-exit-no-save
@@ -196,7 +235,7 @@
196;;; 235;;;
197;;; Global variables and constants 236;;; Global variables and constants
198 237
199(defconst forms-version "1.2.2" 238(defconst forms-version "1.2.7"
200 "Version of forms-mode implementation") 239 "Version of forms-mode implementation")
201 240
202(defvar forms-forms-scrolls t 241(defvar forms-forms-scrolls t
@@ -211,19 +250,10 @@
211;;; Mandatory variables - must be set by evaluating the control file 250;;; Mandatory variables - must be set by evaluating the control file
212 251
213(defvar forms-file nil 252(defvar forms-file nil
214 "Name of the file holding the data.") 253 "Name of the file holding the data.")
215 254
216(defvar forms-format-list nil 255(defvar forms-format-list nil
217 "Formatting specifications: 256 "List of formatting specifications.")
218
219It should be a list, each element containing
220
221 - either a string, e.g. "hello" (which is inserted \"as is\"),
222
223 - an integer, denoting the number of a field which contents are
224 inserted at this point.
225 The first field has number one.
226")
227 257
228(defvar forms-number-of-fields nil 258(defvar forms-number-of-fields nil
229 "Number of fields per record.") 259 "Number of fields per record.")
@@ -288,6 +318,15 @@ It should be a list, each element containing
288(defvar forms--new-record-filter nil 318(defvar forms--new-record-filter nil
289 "Internal - set if a new record filter has been defined.") 319 "Internal - set if a new record filter has been defined.")
290 320
321(defvar forms--modified-record-filter nil
322 "Internal - set if a modified record filter has been defined.")
323
324(defvar forms--dynamic-text nil
325 "Internal - holds dynamic text to insert between fields.")
326
327(defvar forms-fields nil
328 "List with fields of the current forms. First field has number 1.")
329
291;;; 330;;;
292;;; forms-mode 331;;; forms-mode
293;;; 332;;;
@@ -359,13 +398,29 @@ It should be a list, each element containing
359 (make-local-variable 'forms--parser) 398 (make-local-variable 'forms--parser)
360 (forms--make-parser) 399 (forms--make-parser)
361 400
362 ;; check if a new record filter was defined 401 ;; check if record filters are defined
363 (make-local-variable 'forms--new-record-filter) 402 (make-local-variable 'forms--new-record-filter)
364 (setq forms--new-record-filter 403 (setq forms--new-record-filter
365 (and (fboundp 'forms-new-record-filter) 404 (cond
366 (symbol-function 'forms-new-record-filter))) 405 ((fboundp 'forms-new-record-filter)
406 (symbol-function 'forms-new-record-filter))
407 ((and (boundp 'forms-new-record-filter)
408 (fboundp forms-new-record-filter))
409 forms-new-record-filter)))
367 (fmakunbound 'forms-new-record-filter) 410 (fmakunbound 'forms-new-record-filter)
368 411 (make-local-variable 'forms--modified-record-filter)
412 (setq forms--modified-record-filter
413 (cond
414 ((fboundp 'forms-modified-record-filter)
415 (symbol-function 'forms-modified-record-filter))
416 ((and (boundp 'forms-modified-record-filter)
417 (fboundp forms-modified-record-filter))
418 forms-modified-record-filter)))
419 (fmakunbound 'forms-modified-record-filter)
420
421 ;; dynamic text support
422 (make-local-variable 'forms--dynamic-text)
423 (make-local-variable 'forms-fields)
369 424
370 ;; prepare this buffer for further processing 425 ;; prepare this buffer for further processing
371 (setq buffer-read-only nil) 426 (setq buffer-read-only nil)
@@ -445,6 +500,9 @@ It should be a list, each element containing
445(defun forms--process-format-list () 500(defun forms--process-format-list ()
446 "Validate forms-format-list and set some global variables." 501 "Validate forms-format-list and set some global variables."
447 502
503 (forms--debug "forms-forms-list before 1st pass:\n"
504 'forms-format-list)
505
448 ;; it must be non-nil 506 ;; it must be non-nil
449 (or forms-format-list 507 (or forms-format-list
450 (error "'forms-format-list' has not been set")) 508 (error "'forms-format-list' has not been set"))
@@ -455,65 +513,65 @@ It should be a list, each element containing
455 (setq forms--number-of-markers 0) 513 (setq forms--number-of-markers 0)
456 514
457 (let ((the-list forms-format-list) ; the list of format elements 515 (let ((the-list forms-format-list) ; the list of format elements
516 (this-item 0) ; element in list
458 (field-num 0)) ; highest field number 517 (field-num 0)) ; highest field number
459 518
519 (setq forms-format-list nil) ; gonna rebuild
520
460 (while the-list 521 (while the-list
461 522
462 (let ((el (car-safe the-list)) 523 (let ((el (car-safe the-list))
463 (rem (cdr-safe the-list))) 524 (rem (cdr-safe the-list)))
464 525
526 ;; if it is a symbol, eval it first
527 (if (and (symbolp el)
528 (boundp el))
529 (setq el (eval el)))
530
465 (cond 531 (cond
466 532
467 ;; try string ... 533 ;; try string ...
468 ((stringp el)) ; string is OK 534 ((stringp el)) ; string is OK
469 535
470 ;; try int ... 536 ;; try numeric ...
471 ((numberp el) ; check it 537 ((numberp el)
472 538
473 (if (or (<= el 0) 539 (if (or (<= el 0)
474 (> el forms-number-of-fields)) 540 (> el forms-number-of-fields))
475 (error 541 (error
476 "forms error: field number %d out of range 1..%d" 542 "Forms error: field number %d out of range 1..%d"
477 el forms-number-of-fields)) 543 el forms-number-of-fields))
478 544
479 (setq forms--number-of-markers (1+ forms--number-of-markers)) 545 (setq forms--number-of-markers (1+ forms--number-of-markers))
480 (if (> el field-num) 546 (if (> el field-num)
481 (setq field-num el))) 547 (setq field-num el)))
482 548
549 ;; try function
550 ((listp el)
551 (or (fboundp (car-safe el))
552 (error
553 "Forms error: not a function: %s"
554 (prin1-to-string (car-safe el)))))
555
483 ;; else 556 ;; else
484 (t 557 (t
485 (error "invalid element in 'forms-format-list': %s" 558 (error "Invalid element in 'forms-format-list': %s"
486 (prin1-to-string el))) 559 (prin1-to-string el))))
487
488 ;; dead code - we'll need it in the future
489 ((consp el) ; check it
490
491 (let ((str (car-safe el))
492 (idx (cdr-safe el)))
493
494 (cond
495 560
496 ;; car must be string 561 ;; advance to next element of the list
497 ((not (stringp str)) 562 (setq the-list rem)
498 (error "forms error: car of cons %s must be string" 563 (setq forms-format-list
499 (prin1-to-string el))) 564 (append forms-format-list (list el) nil)))))
500 565
501 ;; cdr must be number, > zero 566 (forms--debug "forms-forms-list after 1st pass:\n"
502 ((or (not (numberp idx)) 567 'forms-format-list)
503 (<= idx 0)
504 (> idx forms-number-of-fields))
505 (error
506 "forms error: cdr of cons %s must be a number between 1 and %d"
507 (prin1-to-string el)
508 forms-number-of-fields)))
509 568
510 ;; passed the test - handle it 569 ;; concat adjacent strings
511 (setq forms--number-of-markers (1+ forms--number-of-markers)) 570 (setq forms-format-list (forms--concat-adjacent forms-format-list))
512 (if (> idx field-num)
513 (setq field-num idx)))))
514 571
515 ;; advance to next element of the list 572 (forms--debug "forms-forms-list after 2nd pass:\n"
516 (setq the-list rem)))) 573 'forms-format-list
574 'forms--number-of-markers)
517 575
518 (setq forms--markers (make-vector forms--number-of-markers nil))) 576 (setq forms--markers (make-vector forms--number-of-markers nil)))
519 577
@@ -524,7 +582,7 @@ It should be a list, each element containing
524;;; The format routine (forms--format) will look like 582;;; The format routine (forms--format) will look like
525;;; 583;;;
526;;; (lambda (arg) 584;;; (lambda (arg)
527;;; 585;;; (setq forms--dynamic-text nil)
528;;; ;; "text: " 586;;; ;; "text: "
529;;; (insert "text: ") 587;;; (insert "text: ")
530;;; ;; 6 588;;; ;; 6
@@ -532,6 +590,11 @@ It should be a list, each element containing
532;;; (insert (elt arg 5)) 590;;; (insert (elt arg 5))
533;;; ;; "\nmore text: " 591;;; ;; "\nmore text: "
534;;; (insert "\nmore text: ") 592;;; (insert "\nmore text: ")
593;;; ;; (tocol 40)
594;;; (let ((the-dyntext (tocol 40)))
595;;; (insert the-dyntext)
596;;; (setq forms--dynamic-text (append forms--dynamic-text
597;;; (list the-dyntext))))
535;;; ;; 9 598;;; ;; 9
536;;; (aset forms--markers 1 (point-marker)) 599;;; (aset forms--markers 1 (point-marker))
537;;; (insert (elt arg 8)) 600;;; (insert (elt arg 8))
@@ -540,16 +603,17 @@ It should be a list, each element containing
540;;; 603;;;
541 604
542(defun forms--make-format () 605(defun forms--make-format ()
543 "Generate parser function for forms" 606 "Generate format function for forms"
544 (setq forms--format (forms--format-maker forms-format-list))) 607 (setq forms--format (forms--format-maker forms-format-list))
608 (forms--debug 'forms--format))
545 609
546(defun forms--format-maker (the-format-list) 610(defun forms--format-maker (the-format-list)
547 "Returns the parser function for forms" 611 "Returns the parser function for forms"
548 (let ((the-marker 0)) 612 (let ((the-marker 0))
549 (` (lambda (arg) 613 (` (lambda (arg)
614 (setq forms--dynamic-text nil)
550 (,@ (apply 'append 615 (,@ (apply 'append
551 (mapcar 'forms--make-format-elt 616 (mapcar 'forms--make-format-elt the-format-list)))))))
552 (forms--concat-adjacent the-format-list))))))))
553 617
554(defun forms--make-format-elt (el) 618(defun forms--make-format-elt (el)
555 (cond ((stringp el) 619 (cond ((stringp el)
@@ -558,7 +622,15 @@ It should be a list, each element containing
558 (prog1 622 (prog1
559 (` ((aset forms--markers (, the-marker) (point-marker)) 623 (` ((aset forms--markers (, the-marker) (point-marker))
560 (insert (elt arg (, (1- el)))))) 624 (insert (elt arg (, (1- el))))))
561 (setq the-marker (1+ the-marker)))))) 625 (setq the-marker (1+ the-marker))))
626 ((listp el)
627 (prog1
628 (` ((let ((the-dyntext (, el)))
629 (insert the-dyntext)
630 (setq forms--dynamic-text (append forms--dynamic-text
631 (list the-dyntext)))))
632 )))
633 ))
562 634
563 635
564(defun forms--concat-adjacent (the-list) 636(defun forms--concat-adjacent (the-list)
@@ -584,16 +656,22 @@ It should be a list, each element containing
584;;; 656;;;
585;;; ;; "text: " 657;;; ;; "text: "
586;;; (if (not (looking-at "text: ")) 658;;; (if (not (looking-at "text: "))
587;;; (error "parse error: cannot find \"text: \"")) 659;;; (error "Parse error: cannot find \"text: \""))
588;;; (forward-char 6) ; past "text: " 660;;; (forward-char 6) ; past "text: "
589;;; 661;;;
590;;; ;; 6 662;;; ;; 6
591;;; ;; "\nmore text: " 663;;; ;; "\nmore text: "
592;;; (setq here (point)) 664;;; (setq here (point))
593;;; (if (not (search-forward "\nmore text: " nil t nil)) 665;;; (if (not (search-forward "\nmore text: " nil t nil))
594;;; (error "parse error: cannot find \"\\nmore text: \"")) 666;;; (error "Parse error: cannot find \"\\nmore text: \""))
595;;; (aset the-recordv 5 (buffer-substring here (- (point) 12))) 667;;; (aset the-recordv 5 (buffer-substring here (- (point) 12)))
596;;; ... 668;;;
669;;; ;; (tocol 40)
670;;; (let ((the-dyntext (car-safe forms--dynamic-text)))
671;;; (if (not (looking-at (regexp-quote the-dyntext)))
672;;; (error "Parse error: not looking at \"%s\"" the-dyntext))
673;;; (forward-char (length the-dyntext))
674;;; (setq forms--dynamic-text (cdr-safe forms--dynamic-text)))
597;;; ... 675;;; ...
598;;; ;; final flush (due to terminator sentinel, see below) 676;;; ;; final flush (due to terminator sentinel, see below)
599;;; (aset the-recordv 7 (buffer-substring (point) (point-max))) 677;;; (aset the-recordv 7 (buffer-substring (point) (point-max)))
@@ -601,16 +679,16 @@ It should be a list, each element containing
601 679
602(defun forms--make-parser () 680(defun forms--make-parser ()
603 "Generate parser function for forms" 681 "Generate parser function for forms"
604 (setq forms--parser (forms--parser-maker forms-format-list))) 682 (setq forms--parser (forms--parser-maker forms-format-list))
683 (forms--debug 'forms--parser))
605 684
606(defun forms--parser-maker (the-format-list) 685(defun forms--parser-maker (the-format-list)
607 "Returns the parser function for forms" 686 "Returns the parser function for forms"
608 (let ((the-field nil) 687 (let ((the-field nil)
609 (seen-text nil) 688 (seen-text nil)
610 the--format-list) 689 the--format-list)
611 ;; concat adjacent strings and add a terminator sentinel 690 ;; add a terminator sentinel
612 (setq the--format-list 691 (setq the--format-list (append the-format-list (list nil)))
613 (append (forms--concat-adjacent the-format-list) (list nil)))
614 (` (lambda nil 692 (` (lambda nil
615 (let (here) 693 (let (here)
616 (goto-char (point-min)) 694 (goto-char (point-min))
@@ -618,30 +696,50 @@ It should be a list, each element containing
618 (mapcar 'forms--make-parser-elt the--format-list)))))))) 696 (mapcar 'forms--make-parser-elt the--format-list))))))))
619 697
620(defun forms--make-parser-elt (el) 698(defun forms--make-parser-elt (el)
621 (cond ((stringp el) 699 (cond
622 (prog1 700 ((stringp el)
623 (if the-field 701 (prog1
624 (` ((setq here (point)) 702 (if the-field
625 (if (not (search-forward (, el) nil t nil)) 703 (` ((setq here (point))
626 (error "Parse error: cannot find %s" (, el))) 704 (if (not (search-forward (, el) nil t nil))
627 (aset the-recordv (, (1- the-field)) 705 (error "Parse error: cannot find \"%s\"" (, el)))
628 (buffer-substring here 706 (aset the-recordv (, (1- the-field))
629 (- (point) (, (length el))))))) 707 (buffer-substring here
630 (` ((if (not (looking-at (, (regexp-quote el)))) 708 (- (point) (, (length el)))))))
631 (error "Parse error: not looking at %s" (, el))) 709 (` ((if (not (looking-at (, (regexp-quote el))))
632 (forward-char (, (length el)))))) 710 (error "Parse error: not looking at \"%s\"" (, el)))
633 (setq seen-text t) 711 (forward-char (, (length el))))))
634 (setq the-field nil))) 712 (setq seen-text t)
635 ((numberp el) 713 (setq the-field nil)))
636 (if the-field 714 ((numberp el)
637 (error "Cannot parse adjacent fields %d and %d" 715 (if the-field
638 the-field el) 716 (error "Cannot parse adjacent fields %d and %d"
639 (setq the-field el) 717 the-field el)
640 nil)) 718 (setq the-field el)
641 ((null el) 719 nil))
642 (if the-field 720 ((null el)
643 (` ((aset the-recordv (, (1- the-field)) 721 (if the-field
644 (buffer-substring (point) (point-max))))))))) 722 (` ((aset the-recordv (, (1- the-field))
723 (buffer-substring (point) (point-max)))))))
724 ((listp el)
725 (prog1
726 (if the-field
727 (` ((let ((here (point))
728 (the-dyntext (car-safe forms--dynamic-text)))
729 (if (not (search-forward the-dyntext nil t nil))
730 (error "Parse error: cannot find \"%s\"" the-dyntext))
731 (aset the-recordv (, (1- the-field))
732 (buffer-substring here
733 (- (point) (length the-dyntext))))
734 (setq forms--dynamic-text (cdr-safe forms--dynamic-text)))))
735 (` ((let ((the-dyntext (car-safe forms--dynamic-text)))
736 (if (not (looking-at (regexp-quote the-dyntext)))
737 (error "Parse error: not looking at \"%s\"" the-dyntext))
738 (forward-char (length the-dyntext))
739 (setq forms--dynamic-text (cdr-safe forms--dynamic-text))))))
740 (setq seen-text t)
741 (setq the-field nil)))
742 ))
645;;; 743;;;
646 744
647(defun forms--set-minor-mode () 745(defun forms--set-minor-mode ()
@@ -699,7 +797,7 @@ It should be a list, each element containing
699 nil 797 nil
700 (fset 'forms--scroll-down (symbol-function 'scroll-down)) 798 (fset 'forms--scroll-down (symbol-function 'scroll-down))
701 (fset 'scroll-down 799 (fset 'scroll-down
702 '(lambda (arg) 800 '(lambda (&optional arg)
703 (interactive "P") 801 (interactive "P")
704 (if (and forms--mode-setup 802 (if (and forms--mode-setup
705 forms-forms-scroll) 803 forms-forms-scroll)
@@ -712,7 +810,7 @@ It should be a list, each element containing
712 nil 810 nil
713 (fset 'forms--scroll-up (symbol-function 'scroll-up)) 811 (fset 'forms--scroll-up (symbol-function 'scroll-up))
714 (fset 'scroll-up 812 (fset 'scroll-up
715 '(lambda (arg) 813 '(lambda (&optional arg)
716 (interactive "P") 814 (interactive "P")
717 (if (and forms--mode-setup 815 (if (and forms--mode-setup
718 forms-forms-scroll) 816 forms-forms-scroll)
@@ -860,6 +958,7 @@ It should be a list, each element containing
860 ""))))) 958 "")))))
861 959
862 ;; call the formatter function 960 ;; call the formatter function
961 (setq forms-fields (append (list nil) forms--the-record-list nil))
863 (funcall forms--format forms--the-record-list) 962 (funcall forms--format forms--the-record-list)
864 963
865 ;; prepare 964 ;; prepare
@@ -884,10 +983,18 @@ It should be a list, each element containing
884 (setq the-recordv (vconcat forms--the-record-list)) 983 (setq the-recordv (vconcat forms--the-record-list))
885 984
886 ;; parse the form and update the vector 985 ;; parse the form and update the vector
887 (funcall forms--parser) 986 (let ((forms--dynamic-text forms--dynamic-text))
987 (funcall forms--parser))
888 988
889 ;; transform to a list and return 989 (if forms--modified-record-filter
890 (append the-recordv nil))) 990 ;; As a service to the user, we add a zeroth element so she
991 ;; can use the same indices as in the forms definition.
992 (let ((the-fields (vconcat [nil] the-recordv)))
993 (setq the-fields (funcall forms--modified-record-filter the-fields))
994 (cdr (append the-fields nil)))
995
996 ;; transform to a list and return
997 (append the-recordv nil))))
891 998
892(defun forms--update () 999(defun forms--update ()
893 "Update current record with contents of form. As a side effect: sets 1000 "Update current record with contents of form. As a side effect: sets
@@ -1065,16 +1172,18 @@ forms--the-record-list ."
1065 (forms-mode)))) 1172 (forms-mode))))
1066 1173
1067;; Sample: 1174;; Sample:
1068;; (defun forms-new-record-filter (the-fields) 1175;; (defun my-new-record-filter (the-fields)
1069;; ;; numbers are relative to 1 1176;; ;; numbers are relative to 1
1070;; (aset the-fields 4 (current-time-string)) 1177;; (aset the-fields 4 (current-time-string))
1071;; (aset the-fields 6 (user-login-name)) 1178;; (aset the-fields 6 (user-login-name))
1072;; the-list) 1179;; the-list)
1180;; (setq forms-new-record-filter 'my-new-record-filter)
1073 1181
1074(defun forms-insert-record (arg) 1182(defun forms-insert-record (arg)
1075 "Create a new record before the current one. With ARG: store the 1183 "Create a new record before the current one. With ARG: store the
1076 record after the current one. 1184 record after the current one.
1077 If a function forms-new-record-filter is defined, is is called to 1185 If a function forms-new-record-filter is defined, or forms-new-record-filter
1186 contains the name of a function, it is called to
1078 fill (some of) the fields with default values." 1187 fill (some of) the fields with default values."
1079 ; The above doc is not true, but for documentary purposes only 1188 ; The above doc is not true, but for documentary purposes only
1080 1189
@@ -1193,3 +1302,55 @@ forms--the-record-list ."
1193 (setq i (1+ i)))) 1302 (setq i (1+ i))))
1194 nil 1303 nil
1195 (goto-char (aref forms--markers 0))))) 1304 (goto-char (aref forms--markers 0)))))
1305
1306;;;
1307;;; Special service
1308;;;
1309(defun forms-enumerate (the-fields)
1310 "Take a quoted list of symbols, and set their values to the numbers
13111, 2 and so on. Returns the higest number.
1312
1313Usage: (setq forms-number-of-fields
1314 (forms-enumerate
1315 '(field1 field2 field2 ...)))"
1316
1317 (let ((the-index 0))
1318 (while the-fields
1319 (setq the-index (1+ the-index))
1320 (let ((el (car-safe the-fields)))
1321 (setq the-fields (cdr-safe the-fields))
1322 (set el the-index)))
1323 the-index))
1324
1325;;;
1326;;; Debugging
1327;;;
1328(defvar forms--debug nil
1329 "*Enables forms-mode debugging if not nil.")
1330
1331(defun forms--debug (&rest args)
1332 "Internal - debugging routine"
1333 (if forms--debug
1334 (let ((ret nil))
1335 (while args
1336 (let ((el (car-safe args)))
1337 (setq args (cdr-safe args))
1338 (if (stringp el)
1339 (setq ret (concat ret el))
1340 (setq ret (concat ret (prin1-to-string el) " = "))
1341 (if (boundp el)
1342 (let ((vel (eval el)))
1343 (setq ret (concat ret (prin1-to-string vel) "\n")))
1344 (setq ret (concat ret "<unbound>" "\n")))
1345 (if (fboundp el)
1346 (setq ret (concat ret (prin1-to-string (symbol-function el))
1347 "\n"))))))
1348 (save-excursion
1349 (set-buffer (get-buffer-create "*forms-mode debug*"))
1350 (goto-char (point-max))
1351 (insert ret)))))
1352
1353;;; Local Variables:
1354;;; eval: (headers)
1355;;; eval: (setq comment-start ";;; ")
1356;;; End: