annotate lisp/forms.el @ 276:e7eb71cbf478

Initial revision
author Brian Preble <rassilon@gnu.org>
date Mon, 20 May 1991 20:35:19 +0000
parents
children 7fede845e304
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
276
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1 ;;; Forms Mode - A GNU Emacs Major Mode ; @(#)@ forms 1.2.2
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
2 ;;; Created 1989 - Johan Vromans <jv@mh.nl>
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
3 ;;; See the docs for a list of other contributors.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
4 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
5 ;;; This file is part of GNU Emacs.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
6
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
7 ;;; GNU Emacs is distributed in the hope that it will be useful,
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
8 ;;; but WITHOUT ANY WARRANTY. No author or distributor
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
9 ;;; accepts responsibility to anyone for the consequences of using it
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
10 ;;; or for whether it serves any particular purpose or works at all,
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
11 ;;; unless he says so in writing. Refer to the GNU Emacs General Public
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
12 ;;; License for full details.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
13
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
14 ;;; Everyone is granted permission to copy, modify and redistribute
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
15 ;;; GNU Emacs, but only under the conditions described in the
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
16 ;;; GNU Emacs General Public License. A copy of this license is
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
17 ;;; supposed to have been given to you along with GNU Emacs so you
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
18 ;;; can know your rights and responsibilities.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
19 ;;; If you don't have this copy, write to the Free Software
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
20 ;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
21 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
22
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
23 (provide 'forms-mode)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
24
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
25 ;;; Visit a file using a form.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
26 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
27 ;;; === Naming conventions
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
28 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
29 ;;; The names of all variables and functions start with 'form-'.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
30 ;;; Names which start with 'form--' are intended for internal use, and
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
31 ;;; should *NOT* be used from the outside.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
32 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
33 ;;; All variables are buffer-local, to enable multiple forms visits
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
34 ;;; simultaneously.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
35 ;;; Variable 'forms--mode-setup' is local to *ALL* buffers, for it
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
36 ;;; controls if forms-mode has been enabled in a buffer.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
37 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
38 ;;; === How it works ===
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
39 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
40 ;;; Forms mode means visiting a data file which is supposed to consist
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
41 ;;; of records each containing a number of fields. The records are
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
42 ;;; separated by a newline, the fields are separated by a user-defined
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
43 ;;; field separater (default: TAB).
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
44 ;;; When shown, a record is transferred to an emacs buffer and
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
45 ;;; presented using a user-defined form. One record is shown at a
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
46 ;;; time.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
47 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
48 ;;; Forms mode is a composite mode. It involves two files, and two
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
49 ;;; buffers.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
50 ;;; The first file, called the control file, defines the name of the
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
51 ;;; data file and the forms format. This file buffer will be used to
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
52 ;;; present the forms.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
53 ;;; The second file holds the actual data. The buffer of this file
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
54 ;;; will be buried, for it is never accessed directly.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
55 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
56 ;;; Forms mode is invoked using "forms-find-file control-file".
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
57 ;;; Alternativily forms-find-file-other-window can be used.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
58 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
59 ;;; You may also visit the control file, and switch to forms mode by hand
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
60 ;;; with M-x forms-mode .
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
61 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
62 ;;; Automatic mode switching is supported, so you may use "find-file"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
63 ;;; if you specify "-*- forms -*-" in the first line of the control file.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
64 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
65 ;;; The control file is visited, evaluated using
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
66 ;;; eval-current-buffer, and should set at least the following
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
67 ;;; variables:
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
68 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
69 ;;; forms-file [string] the name of the data file.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
70 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
71 ;;; forms-number-of-fields [integer]
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
72 ;;; The number of fields in each record.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
73 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
74 ;;; forms-format-list [list] formatting instructions.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
75 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
76 ;;; The forms-format-list should be a list, each element containing
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
77 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
78 ;;; - either a string, e.g. "hello" (which is inserted \"as is\"),
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
79 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
80 ;;; - an integer, denoting a field number. The contents of the field
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
81 ;;; are inserted at this point.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
82 ;;; The first field has number one.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
83 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
84 ;;; Optional variables which may be set in the control file:
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
85 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
86 ;;; forms-field-sep [string, default TAB]
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
87 ;;; The field separator used to separate the
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
88 ;;; fields in the data file. It may be a string.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
89 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
90 ;;; forms-read-only [bool, default nil]
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
91 ;;; 't' means that the data file is visited read-only.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
92 ;;; If no write access to the data file is
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
93 ;;; possible, read-only mode is enforced.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
94 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
95 ;;; forms-multi-line [string, default "^K"]
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
96 ;;; If non-null the records of the data file may
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
97 ;;; contain fields which span multiple lines in
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
98 ;;; the form.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
99 ;;; This variable denoted the separator character
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
100 ;;; to be used for this purpose. Upon display, all
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
101 ;;; occurrencies of this character are translated
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
102 ;;; to newlines. Upon storage they are translated
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
103 ;;; back to the separator.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
104 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
105 ;;; forms-forms-scroll [bool, default t]
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
106 ;;; If non-nil: redefine scroll-up/down to perform
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
107 ;;; forms-next/prev-field if in forms mode.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
108 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
109 ;;; forms-forms-jump [bool, default t]
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
110 ;;; If non-nil: redefine beginning/end-of-buffer
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
111 ;;; to performs forms-first/last-field if in
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
112 ;;; forms mode.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
113 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
114 ;;; forms-new-record-filter [function, no default]
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
115 ;;; If defined: this function is called when a new
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
116 ;;; record is created. It can be used to fill in
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
117 ;;; the new record with default fields, for example.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
118 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
119 ;;; After evaluating the control file, its buffer is cleared and used
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
120 ;;; for further processing.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
121 ;;; The data file (as designated by "forms-file") is visited in a buffer
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
122 ;;; (forms--file-buffer) which will not normally be shown.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
123 ;;; Great malfunctioning may be expected if this file/buffer is modified
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
124 ;;; outside of this package while it's being visited!
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
125 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
126 ;;; A record from the data file is transferred from the data file,
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
127 ;;; split into fields (into forms--the-record-list), and displayed using
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
128 ;;; the specs in forms-format-list.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
129 ;;; A format routine 'forms--format' is build upon startup to format
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
130 ;;; the records.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
131 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
132 ;;; When a form is changed the record is updated as soon as this form
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
133 ;;; is left. The contents of the form are parsed using forms-format-list,
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
134 ;;; and the fields which are deduced from the form are modified. So,
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
135 ;;; fields not shown on the forms retain their origional values.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
136 ;;; The newly formed record and replaces the contents of the
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
137 ;;; old record in forms--file-buffer.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
138 ;;; A parse routine 'forms--parser' is build upon startup to parse
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
139 ;;; the records.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
140 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
141 ;;; Two exit functions exist: forms-exit (which saves) and forms-exit-no-save
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
142 ;;; (which doesn't). However, if forms-exit-no-save is executed and the file
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
143 ;;; buffer has been modified, emacs will ask questions.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
144 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
145 ;;; Other functions are:
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
146 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
147 ;;; paging (forward, backward) by record
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
148 ;;; jumping (first, last, random number)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
149 ;;; searching
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
150 ;;; creating and deleting records
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
151 ;;; reverting the form (NOT the file buffer)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
152 ;;; switching edit <-> view mode v.v.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
153 ;;; jumping from field to field
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
154 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
155 ;;; As an documented side-effect: jumping to the last record in the
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
156 ;;; file (using forms-last-record) will adjust forms--total-records if
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
157 ;;; needed.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
158 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
159 ;;; Commands and keymaps:
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
160 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
161 ;;; A local keymap 'forms-mode-map' is used in the forms buffer.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
162 ;;; As conventional, this map can be accessed with C-c prefix.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
163 ;;; In read-only mode, the C-c prefix must be omitted.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
164 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
165 ;;; Default bindings:
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
166 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
167 ;;; \C-c forms-mode-map
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
168 ;;; TAB forms-next-field
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
169 ;;; SPC forms-next-record
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
170 ;;; < forms-first-record
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
171 ;;; > forms-last-record
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
172 ;;; ? describe-mode
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
173 ;;; d forms-delete-record
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
174 ;;; e forms-edit-mode
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
175 ;;; i forms-insert-record
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
176 ;;; j forms-jump-record
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
177 ;;; n forms-next-record
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
178 ;;; p forms-prev-record
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
179 ;;; q forms-exit
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
180 ;;; s forms-search
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
181 ;;; v forms-view-mode
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
182 ;;; x forms-exit-no-save
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
183 ;;; DEL forms-prev-record
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
184 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
185 ;;; Standard functions scroll-up, scroll-down, beginning-of-buffer and
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
186 ;;; end-of-buffer are wrapped with re-definitions, which map them to
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
187 ;;; next/prev record and first/last record.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
188 ;;; Buffer-local variables forms-forms-scroll and forms-forms-jump
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
189 ;;; may be used to control these redefinitions.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
190 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
191 ;;; Function save-buffer is also wrapped to perform a sensible action.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
192 ;;; A revert-file-hook is defined to revert a forms to original.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
193 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
194 ;;; For convenience, TAB is always bound to forms-next-field, so you
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
195 ;;; don't need the C-c prefix for this command.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
196 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
197 ;;; Global variables and constants
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
198
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
199 (defconst forms-version "1.2.2"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
200 "Version of forms-mode implementation")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
201
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
202 (defvar forms-forms-scrolls t
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
203 "If non-null: redefine scroll-up/down to be used with forms-mode.")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
204
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
205 (defvar forms-forms-jumps t
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
206 "If non-null: redefine beginning/end-of-buffer to be used with forms-mode.")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
207
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
208 (defvar forms-mode-hooks nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
209 "Hook functions to be run upon entering forms mode.")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
210 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
211 ;;; Mandatory variables - must be set by evaluating the control file
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
212
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
213 (defvar forms-file nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
214 "Name of the file holding the data.")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
215
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
216 (defvar forms-format-list nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
217 "Formatting specifications:
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
218
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
219 It should be a list, each element containing
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
220
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
221 - either a string, e.g. "hello" (which is inserted \"as is\"),
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
222
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
223 - an integer, denoting the number of a field which contents are
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
224 inserted at this point.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
225 The first field has number one.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
226 ")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
227
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
228 (defvar forms-number-of-fields nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
229 "Number of fields per record.")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
230
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
231 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
232 ;;; Optional variables with default values
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
233
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
234 (defvar forms-field-sep "\t"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
235 "Field separator character (default TAB)")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
236
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
237 (defvar forms-read-only nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
238 "Read-only mode (defaults to the write access on the data file).")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
239
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
240 (defvar forms-multi-line "\C-k"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
241 "Character to separate multi-line fields (default ^K)")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
242
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
243 (defvar forms-forms-scroll t
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
244 "Redefine scroll-up/down to perform forms-next/prev-record when in
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
245 forms mode.")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
246
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
247 (defvar forms-forms-jump t
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
248 "Redefine beginning/end-of-buffer to perform forms-first/last-record
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
249 when in forms mode.")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
250
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
251 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
252 ;;; Internal variables.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
253
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
254 (defvar forms--file-buffer nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
255 "Buffer which holds the file data")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
256
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
257 (defvar forms--total-records 0
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
258 "Total number of records in the data file.")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
259
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
260 (defvar forms--current-record 0
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
261 "Number of the record currently on the screen.")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
262
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
263 (defvar forms-mode-map nil ; yes - this one is global
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
264 "Keymap for form buffer.")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
265
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
266 (defvar forms--markers nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
267 "Field markers in the screen.")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
268
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
269 (defvar forms--number-of-markers 0
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
270 "Number of fields on screen.")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
271
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
272 (defvar forms--the-record-list nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
273 "List of strings of the current record, as parsed from the file.")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
274
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
275 (defvar forms--search-regexp nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
276 "Last regexp used by forms-search.")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
277
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
278 (defvar forms--format nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
279 "Formatting routine.")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
280
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
281 (defvar forms--parser nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
282 "Forms parser routine.")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
283
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
284 (defvar forms--mode-setup nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
285 "Internal - keeps track of forms-mode being set-up.")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
286 (make-variable-buffer-local 'forms--mode-setup)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
287
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
288 (defvar forms--new-record-filter nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
289 "Internal - set if a new record filter has been defined.")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
290
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
291 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
292 ;;; forms-mode
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
293 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
294 ;;; This is not a simple major mode, as usual. Therefore, forms-mode
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
295 ;;; takes an optional argument 'primary' which is used for the initial
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
296 ;;; set-up. Normal use would leave 'primary' to nil.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
297 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
298 ;;; A global buffer-local variable 'forms--mode-setup' has the same effect
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
299 ;;; but makes it possible to auto-invoke forms-mode using find-file.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
300 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
301 ;;; Note: although it seems logical to have (make-local-variable) executed
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
302 ;;; where the variable is first needed, I deliberately placed all calls
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
303 ;;; in the forms-mode function.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
304
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
305 (defun forms-mode (&optional primary)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
306 "Major mode to visit files in a field-structured manner using a form.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
307
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
308 Commands (prefix with C-c if not in read-only mode):
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
309 \\{forms-mode-map}"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
310
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
311 (interactive) ; no - 'primary' is not prefix arg
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
312
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
313 ;; Primary set-up: evaluate buffer and check if the mandatory
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
314 ;; variables have been set.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
315 (if (or primary (not forms--mode-setup))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
316 (progn
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
317 (kill-all-local-variables)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
318
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
319 ;; make mandatory variables
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
320 (make-local-variable 'forms-file)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
321 (make-local-variable 'forms-number-of-fields)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
322 (make-local-variable 'forms-format-list)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
323
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
324 ;; make optional variables
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
325 (make-local-variable 'forms-field-sep)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
326 (make-local-variable 'forms-read-only)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
327 (make-local-variable 'forms-multi-line)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
328 (make-local-variable 'forms-forms-scroll)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
329 (make-local-variable 'forms-forms-jump)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
330 (fmakunbound 'forms-new-record-filter)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
331
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
332 ;; eval the buffer, should set variables
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
333 (eval-current-buffer)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
334
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
335 ;; check if the mandatory variables make sense.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
336 (or forms-file
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
337 (error "'forms-file' has not been set"))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
338 (or forms-number-of-fields
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
339 (error "'forms-number-of-fields' has not been set"))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
340 (or (> forms-number-of-fields 0)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
341 (error "'forms-number-of-fields' must be > 0")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
342 (or (stringp forms-field-sep))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
343 (error "'forms-field-sep' is not a string"))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
344 (if forms-multi-line
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
345 (if (and (stringp forms-multi-line)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
346 (eq (length forms-multi-line) 1))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
347 (if (string= forms-multi-line forms-field-sep)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
348 (error "'forms-multi-line' is equal to 'forms-field-sep'"))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
349 (error "'forms-multi-line' must be nil or a one-character string")))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
350
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
351 ;; validate and process forms-format-list
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
352 (make-local-variable 'forms--number-of-markers)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
353 (make-local-variable 'forms--markers)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
354 (forms--process-format-list)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
355
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
356 ;; build the formatter and parser
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
357 (make-local-variable 'forms--format)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
358 (forms--make-format)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
359 (make-local-variable 'forms--parser)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
360 (forms--make-parser)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
361
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
362 ;; check if a new record filter was defined
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
363 (make-local-variable 'forms--new-record-filter)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
364 (setq forms--new-record-filter
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
365 (and (fboundp 'forms-new-record-filter)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
366 (symbol-function 'forms-new-record-filter)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
367 (fmakunbound 'forms-new-record-filter)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
368
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
369
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
370 ;; prepare this buffer for further processing
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
371 (setq buffer-read-only nil)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
372
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
373 ;; prevent accidental overwrite of the control file and autosave
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
374 (setq buffer-file-name nil)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
375 (auto-save-mode nil)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
376
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
377 ;; and clean it
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
378 (erase-buffer)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
379
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
380 ;; make local variables
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
381 (make-local-variable 'forms--file-buffer)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
382 (make-local-variable 'forms--total-records)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
383 (make-local-variable 'forms--current-record)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
384 (make-local-variable 'forms--the-record-list)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
385 (make-local-variable 'forms--search-rexexp)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
386
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
387 ;; A bug in the current Emacs release prevents a keymap
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
388 ;; which is buffer-local from being used by 'describe-mode'.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
389 ;; Hence we'll leave it global.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
390 ;;(make-local-variable 'forms-mode-map)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
391 (if forms-mode-map ; already defined
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
392 nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
393 (setq forms-mode-map (make-keymap))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
394 (forms--mode-commands forms-mode-map)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
395 (forms--change-commands))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
396
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
397 ;; find the data file
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
398 (setq forms--file-buffer (find-file-noselect forms-file))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
399
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
400 ;; count the number of records, and set see if it may be modified
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
401 (let (ro)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
402 (setq forms--total-records
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
403 (save-excursion
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
404 (set-buffer forms--file-buffer)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
405 (bury-buffer (current-buffer))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
406 (setq ro buffer-read-only)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
407 (count-lines (point-min) (point-max))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
408 (if ro
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
409 (setq forms-read-only t)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
410
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
411 ;; set the major mode indicator
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
412 (setq major-mode 'forms-mode)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
413 (setq mode-name "Forms")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
414 (make-local-variable 'minor-mode-alist) ; needed?
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
415 (forms--set-minor-mode)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
416 (forms--set-keymaps)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
417
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
418 (set-buffer-modified-p nil)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
419
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
420 ;; We have our own revert function - use it
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
421 (make-local-variable 'revert-buffer-function)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
422 (setq revert-buffer-function 'forms-revert-buffer)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
423
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
424 ;; setup the first (or current) record to show
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
425 (if (< forms--current-record 1)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
426 (setq forms--current-record 1))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
427 (forms-jump-record forms--current-record)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
428
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
429 ;; user customising
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
430 (run-hooks 'forms-mode-hooks)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
431
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
432 ;; be helpful
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
433 (forms--help)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
434
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
435 ;; initialization done
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
436 (setq forms--mode-setup t))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
437
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
438 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
439 ;;; forms-process-format-list
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
440 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
441 ;;; Validates forms-format-list.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
442 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
443 ;;; Sets forms--number-of-markers and forms--markers.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
444
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
445 (defun forms--process-format-list ()
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
446 "Validate forms-format-list and set some global variables."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
447
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
448 ;; it must be non-nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
449 (or forms-format-list
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
450 (error "'forms-format-list' has not been set"))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
451 ;; it must be a list ...
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
452 (or (listp forms-format-list)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
453 (error "'forms-format-list' is not a list"))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
454
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
455 (setq forms--number-of-markers 0)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
456
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
457 (let ((the-list forms-format-list) ; the list of format elements
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
458 (field-num 0)) ; highest field number
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
459
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
460 (while the-list
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
461
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
462 (let ((el (car-safe the-list))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
463 (rem (cdr-safe the-list)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
464
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
465 (cond
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
466
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
467 ;; try string ...
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
468 ((stringp el)) ; string is OK
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
469
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
470 ;; try int ...
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
471 ((numberp el) ; check it
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
472
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
473 (if (or (<= el 0)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
474 (> el forms-number-of-fields))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
475 (error
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
476 "forms error: field number %d out of range 1..%d"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
477 el forms-number-of-fields))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
478
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
479 (setq forms--number-of-markers (1+ forms--number-of-markers))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
480 (if (> el field-num)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
481 (setq field-num el)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
482
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
483 ;; else
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
484 (t
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
485 (error "invalid element in 'forms-format-list': %s"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
486 (prin1-to-string el)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
487
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
488 ;; dead code - we'll need it in the future
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
489 ((consp el) ; check it
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
490
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
491 (let ((str (car-safe el))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
492 (idx (cdr-safe el)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
493
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
494 (cond
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
495
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
496 ;; car must be string
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
497 ((not (stringp str))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
498 (error "forms error: car of cons %s must be string"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
499 (prin1-to-string el)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
500
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
501 ;; cdr must be number, > zero
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
502 ((or (not (numberp idx))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
503 (<= idx 0)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
504 (> idx forms-number-of-fields))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
505 (error
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
506 "forms error: cdr of cons %s must be a number between 1 and %d"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
507 (prin1-to-string el)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
508 forms-number-of-fields)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
509
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
510 ;; passed the test - handle it
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
511 (setq forms--number-of-markers (1+ forms--number-of-markers))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
512 (if (> idx field-num)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
513 (setq field-num idx)))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
514
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
515 ;; advance to next element of the list
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
516 (setq the-list rem))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
517
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
518 (setq forms--markers (make-vector forms--number-of-markers nil)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
519
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
520
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
521 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
522 ;;; Build the format routine from forms-format-list.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
523 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
524 ;;; The format routine (forms--format) will look like
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
525 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
526 ;;; (lambda (arg)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
527 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
528 ;;; ;; "text: "
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
529 ;;; (insert "text: ")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
530 ;;; ;; 6
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
531 ;;; (aset forms--markers 0 (point-marker))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
532 ;;; (insert (elt arg 5))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
533 ;;; ;; "\nmore text: "
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
534 ;;; (insert "\nmore text: ")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
535 ;;; ;; 9
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
536 ;;; (aset forms--markers 1 (point-marker))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
537 ;;; (insert (elt arg 8))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
538 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
539 ;;; ... )
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
540 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
541
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
542 (defun forms--make-format ()
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
543 "Generate parser function for forms"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
544 (setq forms--format (forms--format-maker forms-format-list)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
545
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
546 (defun forms--format-maker (the-format-list)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
547 "Returns the parser function for forms"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
548 (let ((the-marker 0))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
549 (` (lambda (arg)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
550 (,@ (apply 'append
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
551 (mapcar 'forms--make-format-elt
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
552 (forms--concat-adjacent the-format-list))))))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
553
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
554 (defun forms--make-format-elt (el)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
555 (cond ((stringp el)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
556 (` ((insert (, el)))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
557 ((numberp el)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
558 (prog1
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
559 (` ((aset forms--markers (, the-marker) (point-marker))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
560 (insert (elt arg (, (1- el))))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
561 (setq the-marker (1+ the-marker))))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
562
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
563
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
564 (defun forms--concat-adjacent (the-list)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
565 "Concatenate adjacent strings in the-list and return the resulting list"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
566 (if (consp the-list)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
567 (let ((the-rest (forms--concat-adjacent (cdr the-list))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
568 (if (and (stringp (car the-list)) (stringp (car the-rest)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
569 (cons (concat (car the-list) (car the-rest))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
570 (cdr the-rest))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
571 (cons (car the-list) the-rest)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
572 the-list))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
573 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
574 ;;; forms--make-parser.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
575 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
576 ;;; Generate parse routine from forms-format-list.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
577 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
578 ;;; The parse routine (forms--parser) will look like (give or take
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
579 ;;; a few " " .
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
580 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
581 ;;; (lambda nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
582 ;;; (let (here)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
583 ;;; (goto-char (point-min))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
584 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
585 ;;; ;; "text: "
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
586 ;;; (if (not (looking-at "text: "))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
587 ;;; (error "parse error: cannot find \"text: \""))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
588 ;;; (forward-char 6) ; past "text: "
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
589 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
590 ;;; ;; 6
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
591 ;;; ;; "\nmore text: "
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
592 ;;; (setq here (point))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
593 ;;; (if (not (search-forward "\nmore text: " nil t nil))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
594 ;;; (error "parse error: cannot find \"\\nmore text: \""))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
595 ;;; (aset the-recordv 5 (buffer-substring here (- (point) 12)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
596 ;;; ...
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
597 ;;; ...
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
598 ;;; ;; final flush (due to terminator sentinel, see below)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
599 ;;; (aset the-recordv 7 (buffer-substring (point) (point-max)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
600 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
601
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
602 (defun forms--make-parser ()
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
603 "Generate parser function for forms"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
604 (setq forms--parser (forms--parser-maker forms-format-list)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
605
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
606 (defun forms--parser-maker (the-format-list)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
607 "Returns the parser function for forms"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
608 (let ((the-field nil)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
609 (seen-text nil)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
610 the--format-list)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
611 ;; concat adjacent strings and add a terminator sentinel
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
612 (setq the--format-list
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
613 (append (forms--concat-adjacent the-format-list) (list nil)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
614 (` (lambda nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
615 (let (here)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
616 (goto-char (point-min))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
617 (,@ (apply 'append
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
618 (mapcar 'forms--make-parser-elt the--format-list))))))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
619
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
620 (defun forms--make-parser-elt (el)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
621 (cond ((stringp el)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
622 (prog1
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
623 (if the-field
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
624 (` ((setq here (point))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
625 (if (not (search-forward (, el) nil t nil))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
626 (error "Parse error: cannot find %s" (, el)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
627 (aset the-recordv (, (1- the-field))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
628 (buffer-substring here
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
629 (- (point) (, (length el)))))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
630 (` ((if (not (looking-at (, (regexp-quote el))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
631 (error "Parse error: not looking at %s" (, el)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
632 (forward-char (, (length el))))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
633 (setq seen-text t)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
634 (setq the-field nil)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
635 ((numberp el)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
636 (if the-field
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
637 (error "Cannot parse adjacent fields %d and %d"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
638 the-field el)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
639 (setq the-field el)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
640 nil))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
641 ((null el)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
642 (if the-field
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
643 (` ((aset the-recordv (, (1- the-field))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
644 (buffer-substring (point) (point-max)))))))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
645 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
646
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
647 (defun forms--set-minor-mode ()
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
648 (setq minor-mode-alist
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
649 (if forms-read-only
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
650 " View"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
651 nil)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
652
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
653 (defun forms--set-keymaps ()
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
654 "Set the keymaps used in this mode."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
655
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
656 (if forms-read-only
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
657 (use-local-map forms-mode-map)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
658 (use-local-map (make-sparse-keymap))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
659 (define-key (current-local-map) "\C-c" forms-mode-map)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
660 (define-key (current-local-map) "\t" 'forms-next-field)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
661
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
662 (defun forms--mode-commands (map)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
663 "Fill map with all commands."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
664 (define-key map "\t" 'forms-next-field)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
665 (define-key map " " 'forms-next-record)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
666 (define-key map "d" 'forms-delete-record)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
667 (define-key map "e" 'forms-edit-mode)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
668 (define-key map "i" 'forms-insert-record)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
669 (define-key map "j" 'forms-jump-record)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
670 (define-key map "n" 'forms-next-record)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
671 (define-key map "p" 'forms-prev-record)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
672 (define-key map "q" 'forms-exit)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
673 (define-key map "s" 'forms-search)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
674 (define-key map "v" 'forms-view-mode)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
675 (define-key map "x" 'forms-exit-no-save)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
676 (define-key map "<" 'forms-first-record)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
677 (define-key map ">" 'forms-last-record)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
678 (define-key map "?" 'describe-mode)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
679 (define-key map "\177" 'forms-prev-record)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
680 ; (define-key map "\C-c" map)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
681 (define-key map "\e" 'ESC-prefix)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
682 (define-key map "\C-x" ctl-x-map)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
683 (define-key map "\C-u" 'universal-argument)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
684 (define-key map "\C-h" help-map)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
685 )
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
686 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
687 ;;; Changed functions
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
688 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
689 ;;; Emacs (as of 18.55) lacks the functionality of buffer-local
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
690 ;;; funtions. Therefore we save the original meaning of some handy
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
691 ;;; functions, and replace them with a wrapper.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
692
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
693 (defun forms--change-commands ()
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
694 "Localize some commands."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
695 ;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
696 ;; scroll-down -> forms-prev-record
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
697 ;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
698 (if (fboundp 'forms--scroll-down)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
699 nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
700 (fset 'forms--scroll-down (symbol-function 'scroll-down))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
701 (fset 'scroll-down
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
702 '(lambda (arg)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
703 (interactive "P")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
704 (if (and forms--mode-setup
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
705 forms-forms-scroll)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
706 (forms-prev-record arg)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
707 (forms--scroll-down arg)))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
708 ;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
709 ;; scroll-up -> forms-next-record
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
710 ;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
711 (if (fboundp 'forms--scroll-up)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
712 nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
713 (fset 'forms--scroll-up (symbol-function 'scroll-up))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
714 (fset 'scroll-up
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
715 '(lambda (arg)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
716 (interactive "P")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
717 (if (and forms--mode-setup
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
718 forms-forms-scroll)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
719 (forms-next-record arg)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
720 (forms--scroll-up arg)))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
721 ;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
722 ;; beginning-of-buffer -> forms-first-record
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
723 ;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
724 (if (fboundp 'forms--beginning-of-buffer)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
725 nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
726 (fset 'forms--beginning-of-buffer (symbol-function 'beginning-of-buffer))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
727 (fset 'beginning-of-buffer
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
728 '(lambda ()
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
729 (interactive)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
730 (if (and forms--mode-setup
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
731 forms-forms-jump)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
732 (forms-first-record)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
733 (forms--beginning-of-buffer)))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
734 ;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
735 ;; end-of-buffer -> forms-end-record
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
736 ;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
737 (if (fboundp 'forms--end-of-buffer)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
738 nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
739 (fset 'forms--end-of-buffer (symbol-function 'end-of-buffer))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
740 (fset 'end-of-buffer
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
741 '(lambda ()
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
742 (interactive)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
743 (if (and forms--mode-setup
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
744 forms-forms-jump)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
745 (forms-last-record)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
746 (forms--end-of-buffer)))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
747 ;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
748 ;; save-buffer -> forms--save-buffer
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
749 ;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
750 (if (fboundp 'forms--save-buffer)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
751 nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
752 (fset 'forms--save-buffer (symbol-function 'save-buffer))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
753 (fset 'save-buffer
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
754 '(lambda (&optional arg)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
755 (interactive "p")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
756 (if forms--mode-setup
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
757 (progn
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
758 (forms--checkmod)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
759 (save-excursion
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
760 (set-buffer forms--file-buffer)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
761 (forms--save-buffer arg)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
762 (forms--save-buffer arg)))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
763 ;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
764 )
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
765
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
766 (defun forms--help ()
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
767 "Initial help."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
768 ;; We should use
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
769 ;;(message (substitute-command-keys (concat
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
770 ;;"\\[forms-next-record]:next"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
771 ;;" \\[forms-prev-record]:prev"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
772 ;;" \\[forms-first-record]:first"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
773 ;;" \\[forms-last-record]:last"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
774 ;;" \\[describe-mode]:help"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
775 ;;" \\[forms-exit]:exit")))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
776 ;; but it's too slow ....
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
777 (if forms-read-only
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
778 (message "SPC:next DEL:prev <:first >:last ?:help q:exit")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
779 (message "C-c n:next C-c p:prev C-c <:first C-c >:last C-c ?:help C-c q:exit")))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
780
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
781 (defun forms--trans (subj arg rep)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
782 "Translate in SUBJ all chars ARG into char REP. ARG and REP should
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
783 be single-char strings."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
784 (let ((i 0)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
785 (x (length subj))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
786 (re (regexp-quote arg))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
787 (k (string-to-char rep)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
788 (while (setq i (string-match re subj i))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
789 (aset subj i k)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
790 (setq i (1+ i)))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
791
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
792 (defun forms--exit (query &optional save)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
793 (let ((buf (buffer-name forms--file-buffer)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
794 (forms--checkmod)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
795 (if (and save
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
796 (buffer-modified-p forms--file-buffer))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
797 (save-excursion
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
798 (set-buffer forms--file-buffer)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
799 (save-buffer)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
800 (save-excursion
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
801 (set-buffer forms--file-buffer)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
802 (delete-auto-save-file-if-necessary)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
803 (kill-buffer (current-buffer)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
804 (if (get-buffer buf) ; not killed???
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
805 (if save
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
806 (progn
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
807 (beep)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
808 (message "Problem saving buffers?")))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
809 (delete-auto-save-file-if-necessary)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
810 (kill-buffer (current-buffer)))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
811
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
812 (defun forms--get-record ()
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
813 "Fetch the current record from the file buffer."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
814 ;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
815 ;; This function is executed in the context of the forms--file-buffer.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
816 ;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
817 (or (bolp)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
818 (beginning-of-line nil))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
819 (let ((here (point)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
820 (prog2
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
821 (end-of-line)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
822 (buffer-substring here (point))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
823 (goto-char here))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
824
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
825 (defun forms--show-record (the-record)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
826 "Format THE-RECORD according to forms-format-list,
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
827 and display it in the current buffer."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
828
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
829 ;; split the-record
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
830 (let (the-result
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
831 (start-pos 0)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
832 found-pos
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
833 (field-sep-length (length forms-field-sep)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
834 (if forms-multi-line
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
835 (forms--trans the-record forms-multi-line "\n"))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
836 ;; add an extra separator (makes splitting easy)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
837 (setq the-record (concat the-record forms-field-sep))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
838 (while (setq found-pos (string-match forms-field-sep the-record start-pos))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
839 (let ((ent (substring the-record start-pos found-pos)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
840 (setq the-result
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
841 (append the-result (list ent)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
842 (setq start-pos (+ field-sep-length found-pos))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
843 (setq forms--the-record-list the-result))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
844
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
845 (setq buffer-read-only nil)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
846 (erase-buffer)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
847
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
848 ;; verify the number of fields, extend forms--the-record-list if needed
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
849 (if (= (length forms--the-record-list) forms-number-of-fields)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
850 nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
851 (beep)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
852 (message "Record has %d fields instead of %d."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
853 (length forms--the-record-list) forms-number-of-fields)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
854 (if (< (length forms--the-record-list) forms-number-of-fields)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
855 (setq forms--the-record-list
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
856 (append forms--the-record-list
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
857 (make-list
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
858 (- forms-number-of-fields
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
859 (length forms--the-record-list))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
860 "")))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
861
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
862 ;; call the formatter function
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
863 (funcall forms--format forms--the-record-list)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
864
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
865 ;; prepare
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
866 (goto-char (point-min))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
867 (set-buffer-modified-p nil)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
868 (setq buffer-read-only forms-read-only)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
869 (setq mode-line-process
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
870 (concat " " forms--current-record "/" forms--total-records)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
871
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
872 (defun forms--parse-form ()
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
873 "Parse contents of form into list of strings."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
874 ;; The contents of the form are parsed, and a new list of strings
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
875 ;; is constructed.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
876 ;; A vector with the strings from the original record is
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
877 ;; constructed, which is updated with the new contents. Therefore
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
878 ;; fields which were not in the form are not modified.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
879 ;; Finally, the vector is transformed into a list for further processing.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
880
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
881 (let (the-recordv)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
882
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
883 ;; build the vector
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
884 (setq the-recordv (vconcat forms--the-record-list))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
885
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
886 ;; parse the form and update the vector
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
887 (funcall forms--parser)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
888
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
889 ;; transform to a list and return
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
890 (append the-recordv nil)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
891
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
892 (defun forms--update ()
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
893 "Update current record with contents of form. As a side effect: sets
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
894 forms--the-record-list ."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
895 (if forms-read-only
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
896 (progn
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
897 (message "Read-only buffer!")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
898 (beep))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
899
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
900 (let (the-record)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
901 ;; build new record
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
902 (setq forms--the-record-list (forms--parse-form))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
903 (setq the-record
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
904 (mapconcat 'identity forms--the-record-list forms-field-sep))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
905
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
906 ;; handle multi-line fields, if allowed
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
907 (if forms-multi-line
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
908 (forms--trans the-record "\n" forms-multi-line))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
909
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
910 ;; a final sanity check before updating
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
911 (if (string-match "\n" the-record)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
912 (progn
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
913 (message "Multi-line fields in this record - update refused!")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
914 (beep))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
915
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
916 (save-excursion
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
917 (set-buffer forms--file-buffer)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
918 ;; Insert something before kill-line is called. See kill-line
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
919 ;; doc. Bugfix provided by Ignatios Souvatzis.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
920 (insert "*")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
921 (beginning-of-line)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
922 (kill-line nil)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
923 (insert the-record)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
924 (beginning-of-line))))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
925
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
926 (defun forms--checkmod ()
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
927 "Check if this form has been modified, and call forms--update if so."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
928 (if (buffer-modified-p nil)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
929 (let ((here (point)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
930 (forms--update)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
931 (set-buffer-modified-p nil)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
932 (goto-char here))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
933
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
934 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
935 ;;; Start and exit
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
936 (defun forms-find-file (fn)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
937 "Visit file FN in forms mode"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
938 (interactive "fForms file: ")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
939 (find-file-read-only fn)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
940 (or forms--mode-setup (forms-mode t)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
941
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
942 (defun forms-find-file-other-window (fn)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
943 "Visit file FN in form mode in other window"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
944 (interactive "fFbrowse file in other window: ")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
945 (find-file-other-window fn)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
946 (eval-current-buffer)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
947 (or forms--mode-setup (forms-mode t)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
948
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
949 (defun forms-exit (query)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
950 "Normal exit. Modified buffers are saved."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
951 (interactive "P")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
952 (forms--exit query t))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
953
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
954 (defun forms-exit-no-save (query)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
955 "Exit without saving buffers."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
956 (interactive "P")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
957 (forms--exit query nil))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
958
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
959 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
960 ;;; Navigating commands
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
961
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
962 (defun forms-next-record (arg)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
963 "Advance to the ARGth following record."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
964 (interactive "P")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
965 (forms-jump-record (+ forms--current-record (prefix-numeric-value arg)) t))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
966
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
967 (defun forms-prev-record (arg)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
968 "Advance to the ARGth previous record."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
969 (interactive "P")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
970 (forms-jump-record (- forms--current-record (prefix-numeric-value arg)) t))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
971
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
972 (defun forms-jump-record (arg &optional relative)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
973 "Jump to a random record."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
974 (interactive "NRecord number: ")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
975
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
976 ;; verify that the record number is within range
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
977 (if (or (> arg forms--total-records)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
978 (<= arg 0))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
979 (progn
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
980 (beep)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
981 ;; don't give the message if just paging
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
982 (if (not relative)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
983 (message "Record number %d out of range 1..%d"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
984 arg forms--total-records))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
985 )
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
986
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
987 ;; flush
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
988 (forms--checkmod)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
989
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
990 ;; calculate displacement
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
991 (let ((disp (- arg forms--current-record))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
992 (cur forms--current-record))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
993
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
994 ;; forms--show-record needs it now
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
995 (setq forms--current-record arg)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
996
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
997 ;; get the record and show it
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
998 (forms--show-record
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
999 (save-excursion
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1000 (set-buffer forms--file-buffer)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1001 (beginning-of-line)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1002
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1003 ;; move, and adjust the amount if needed (shouldn't happen)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1004 (if relative
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1005 (if (zerop disp)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1006 nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1007 (setq cur (+ cur disp (- (forward-line disp)))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1008 (setq cur (+ cur disp (- (goto-line arg)))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1009
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1010 (forms--get-record)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1011
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1012 ;; this shouldn't happen
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1013 (if (/= forms--current-record cur)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1014 (progn
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1015 (setq forms--current-record cur)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1016 (beep)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1017 (message "Stuck at record %d." cur))))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1018
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1019 (defun forms-first-record ()
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1020 "Jump to first record."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1021 (interactive)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1022 (forms-jump-record 1))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1023
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1024 (defun forms-last-record ()
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1025 "Jump to last record. As a side effect: re-calculates the number
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1026 of records in the data file."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1027 (interactive)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1028 (let
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1029 ((numrec
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1030 (save-excursion
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1031 (set-buffer forms--file-buffer)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1032 (count-lines (point-min) (point-max)))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1033 (if (= numrec forms--total-records)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1034 nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1035 (beep)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1036 (setq forms--total-records numrec)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1037 (message "Number of records reset to %d." forms--total-records)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1038 (forms-jump-record forms--total-records))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1039
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1040 ;;;
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1041 ;;; Other commands
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1042 (defun forms-view-mode ()
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1043 "Visit buffer read-only."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1044 (interactive)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1045 (if forms-read-only
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1046 nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1047 (forms--checkmod) ; sync
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1048 (setq forms-read-only t)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1049 (forms-mode)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1050
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1051 (defun forms-edit-mode ()
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1052 "Make form suitable for editing, if possible."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1053 (interactive)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1054 (let ((ro forms-read-only))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1055 (if (save-excursion
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1056 (set-buffer forms--file-buffer)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1057 buffer-read-only)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1058 (progn
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1059 (setq forms-read-only t)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1060 (message "No write access to \"%s\"" forms-file)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1061 (beep))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1062 (setq forms-read-only nil))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1063 (if (equal ro forms-read-only)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1064 nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1065 (forms-mode))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1066
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1067 ;; Sample:
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1068 ;; (defun forms-new-record-filter (the-fields)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1069 ;; ;; numbers are relative to 1
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1070 ;; (aset the-fields 4 (current-time-string))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1071 ;; (aset the-fields 6 (user-login-name))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1072 ;; the-list)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1073
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1074 (defun forms-insert-record (arg)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1075 "Create a new record before the current one. With ARG: store the
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1076 record after the current one.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1077 If a function forms-new-record-filter is defined, is is called to
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1078 fill (some of) the fields with default values."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1079 ; The above doc is not true, but for documentary purposes only
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1080
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1081 (interactive "P")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1082
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1083 (let ((ln (if arg (1+ forms--current-record) forms--current-record))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1084 the-list the-record)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1085
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1086 (forms--checkmod)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1087 (if forms--new-record-filter
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1088 ;; As a service to the user, we add a zeroth element so she
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1089 ;; can use the same indices as in the forms definition.
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1090 (let ((the-fields (make-vector (1+ forms-number-of-fields) "")))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1091 (setq the-fields (funcall forms--new-record-filter the-fields))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1092 (setq the-list (cdr (append the-fields nil))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1093 (setq the-list (make-list forms-number-of-fields "")))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1094
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1095 (setq the-record
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1096 (mapconcat
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1097 'identity
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1098 the-list
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1099 forms-field-sep))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1100
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1101 (save-excursion
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1102 (set-buffer forms--file-buffer)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1103 (goto-line ln)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1104 (open-line 1)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1105 (insert the-record)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1106 (beginning-of-line))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1107
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1108 (setq forms--current-record ln))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1109
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1110 (setq forms--total-records (1+ forms--total-records))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1111 (forms-jump-record forms--current-record))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1112
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1113 (defun forms-delete-record (arg)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1114 "Deletes a record. With ARG: don't ask."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1115 (interactive "P")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1116 (forms--checkmod)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1117 (if (or arg
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1118 (y-or-n-p "Really delete this record? "))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1119 (let ((ln forms--current-record))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1120 (save-excursion
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1121 (set-buffer forms--file-buffer)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1122 (goto-line ln)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1123 (kill-line 1))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1124 (setq forms--total-records (1- forms--total-records))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1125 (if (> forms--current-record forms--total-records)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1126 (setq forms--current-record forms--total-records))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1127 (forms-jump-record forms--current-record)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1128 (message ""))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1129
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1130 (defun forms-search (regexp)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1131 "Search REGEXP in file buffer."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1132 (interactive
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1133 (list (read-string (concat "Search for"
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1134 (if forms--search-regexp
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1135 (concat " ("
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1136 forms--search-regexp
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1137 ")"))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1138 ": "))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1139 (if (equal "" regexp)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1140 (setq regexp forms--search-regexp))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1141 (forms--checkmod)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1142
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1143 (let (the-line the-record here
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1144 (fld-sep forms-field-sep))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1145 (if (save-excursion
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1146 (set-buffer forms--file-buffer)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1147 (setq here (point))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1148 (end-of-line)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1149 (if (null (re-search-forward regexp nil t))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1150 (progn
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1151 (goto-char here)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1152 (message (concat "\"" regexp "\" not found."))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1153 nil)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1154 (setq the-record (forms--get-record))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1155 (setq the-line (1+ (count-lines (point-min) (point))))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1156 (progn
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1157 (setq forms--current-record the-line)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1158 (forms--show-record the-record)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1159 (re-search-forward regexp nil t))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1160 (setq forms--search-regexp regexp))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1161
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1162 (defun forms-revert-buffer (&optional arg noconfirm)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1163 "Reverts current form to un-modified."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1164 (interactive "P")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1165 (if (or noconfirm
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1166 (yes-or-no-p "Revert form to unmodified? "))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1167 (progn
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1168 (set-buffer-modified-p nil)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1169 (forms-jump-record forms--current-record))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1170
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1171 (defun forms-next-field (arg)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1172 "Jump to ARG-th next field."
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1173 (interactive "p")
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1174
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1175 (let ((i 0)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1176 (here (point))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1177 there
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1178 (cnt 0))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1179
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1180 (if (zerop arg)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1181 (setq cnt 1)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1182 (setq cnt (+ cnt arg)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1183
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1184 (if (catch 'done
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1185 (while (< i forms--number-of-markers)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1186 (if (or (null (setq there (aref forms--markers i)))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1187 (<= there here))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1188 nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1189 (if (<= (setq cnt (1- cnt)) 0)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1190 (progn
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1191 (goto-char there)
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1192 (throw 'done t))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1193 (setq i (1+ i))))
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1194 nil
e7eb71cbf478 Initial revision
Brian Preble <rassilon@gnu.org>
parents:
diff changeset
1195 (goto-char (aref forms--markers 0)))))