home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3375 < prev    next >
Encoding:
Internet Message Format  |  1991-05-21  |  19.0 KB

  1. From: jv@mh.nl (Johan Vromans)
  2. Newsgroups: gnu.emacs.sources,alt.sources
  3. Subject: GNU Emacs forms-mode version 1.2.2, part 3 of 3
  4. Message-ID: <1991May20.093208.1555@pronto.mh.nl>
  5. Date: 20 May 91 09:32:08 GMT
  6.  
  7. Submitted-by: jv@mh.nl
  8. Archive-name: forms/part03
  9.  
  10. ---- Cut Here and feed the following to sh ----
  11. #!/bin/sh
  12. # this is forms.shr.03 (part 3 of forms)
  13. # do not concatenate these parts, unpack them in order with /bin/sh
  14. # file forms.el continued
  15. #
  16. if test ! -r _shar_seq_.tmp; then
  17.     echo 'Please unpack part 1 first!'
  18.     exit 1
  19. fi
  20. (read Scheck
  21.  if test "$Scheck" != 3; then
  22.     echo Please unpack part "$Scheck" next!
  23.     exit 1
  24.  else
  25.     exit 0
  26.  fi
  27. ) < _shar_seq_.tmp || exit 1
  28. if test ! -f _shar_wnt_.tmp; then
  29.     echo 'x - still skipping forms.el'
  30. else
  31. echo 'x - continuing file forms.el'
  32. sed 's/^X//' << 'SHAR_EOF' >> 'forms.el' &&
  33. ;;;     (forward-char 6)    ; past "text: "
  34. ;;; 
  35. ;;;     ;;  6
  36. ;;;    ;;  "\nmore text: "
  37. ;;;     (setq here (point))
  38. ;;;     (if (not (search-forward "\nmore text: " nil t nil))
  39. ;;;         (error "parse error: cannot find \"\\nmore text: \""))
  40. ;;;     (aset the-recordv 5 (buffer-substring here (- (point) 12)))
  41. ;;;     ...
  42. ;;;     ... 
  43. ;;;     ;; final flush (due to terminator sentinel, see below)
  44. ;;;    (aset the-recordv 7 (buffer-substring (point) (point-max)))
  45. ;;; 
  46. X
  47. (defun forms--make-parser ()
  48. X  "Generate parser function for forms"
  49. X  (setq forms--parser (forms--parser-maker forms-format-list)))
  50. X
  51. (defun forms--parser-maker (the-format-list)
  52. X  "Returns the parser function for forms"
  53. X  (let ((the-field nil)
  54. X    (seen-text nil)
  55. X    the--format-list)
  56. X    ;; concat adjacent strings and add a terminator sentinel
  57. X    (setq the--format-list 
  58. X      (append (forms--concat-adjacent the-format-list) (list nil)))
  59. X    (` (lambda nil
  60. X     (let (here)
  61. X       (goto-char (point-min))
  62. X     (,@ (apply 'append
  63. X            (mapcar 'forms--make-parser-elt the--format-list))))))))
  64. X
  65. (defun forms--make-parser-elt (el)
  66. X  (cond ((stringp el)
  67. X     (prog1
  68. X         (if the-field
  69. X         (` ((setq here (point))
  70. X             (if (not (search-forward (, el) nil t nil))
  71. X             (error "Parse error: cannot find %s" (, el)))
  72. X             (aset the-recordv (, (1- the-field))
  73. X               (buffer-substring here
  74. X                         (- (point) (, (length el)))))))
  75. X         (` ((if (not (looking-at (, (regexp-quote el))))
  76. X             (error "Parse error: not looking at %s" (, el)))
  77. X             (forward-char (, (length el))))))
  78. X       (setq seen-text t)
  79. X       (setq the-field nil)))
  80. X    ((numberp el)
  81. X     (if the-field
  82. X         (error "Cannot parse adjacent fields %d and %d"
  83. X            the-field el)
  84. X         (setq the-field el)
  85. X         nil))
  86. X    ((null el)
  87. X     (if the-field
  88. X         (` ((aset the-recordv (, (1- the-field))
  89. X               (buffer-substring (point) (point-max)))))))))
  90. ;;;
  91. X
  92. (defun forms--set-minor-mode ()
  93. X  (setq minor-mode-alist
  94. X    (if forms-read-only
  95. X        " View"
  96. X      nil)))
  97. X
  98. (defun forms--set-keymaps ()
  99. X  "Set the keymaps used in this mode."
  100. X
  101. X  (if forms-read-only
  102. X      (use-local-map forms-mode-map)
  103. X    (use-local-map (make-sparse-keymap))
  104. X    (define-key (current-local-map) "\C-c" forms-mode-map)
  105. X    (define-key (current-local-map) "\t"   'forms-next-field)))
  106. X
  107. (defun forms--mode-commands (map)
  108. X  "Fill map with all commands."
  109. X  (define-key map "\t" 'forms-next-field)
  110. X  (define-key map " " 'forms-next-record)
  111. X  (define-key map "d" 'forms-delete-record)
  112. X  (define-key map "e" 'forms-edit-mode)
  113. X  (define-key map "i" 'forms-insert-record)
  114. X  (define-key map "j" 'forms-jump-record)
  115. X  (define-key map "n" 'forms-next-record)
  116. X  (define-key map "p" 'forms-prev-record)
  117. X  (define-key map "q" 'forms-exit)
  118. X  (define-key map "s" 'forms-search)
  119. X  (define-key map "v" 'forms-view-mode)
  120. X  (define-key map "x" 'forms-exit-no-save)
  121. X  (define-key map "<" 'forms-first-record)
  122. X  (define-key map ">" 'forms-last-record)
  123. X  (define-key map "?" 'describe-mode)
  124. X  (define-key map "\177" 'forms-prev-record)
  125. X ;  (define-key map "\C-c" map)
  126. X  (define-key map "\e" 'ESC-prefix)
  127. X  (define-key map "\C-x" ctl-x-map)
  128. X  (define-key map "\C-u" 'universal-argument)
  129. X  (define-key map "\C-h" help-map)
  130. X  )
  131. ;;;
  132. ;;; Changed functions
  133. ;;;
  134. ;;; Emacs (as of 18.55) lacks the functionality of buffer-local
  135. ;;; funtions. Therefore we save the original meaning of some handy
  136. ;;; functions, and replace them with a wrapper.
  137. X
  138. (defun forms--change-commands ()
  139. X  "Localize some commands."
  140. X  ;;
  141. X  ;; scroll-down -> forms-prev-record
  142. X  ;;
  143. X  (if (fboundp 'forms--scroll-down)
  144. X      nil
  145. X    (fset 'forms--scroll-down (symbol-function 'scroll-down))
  146. X    (fset 'scroll-down
  147. X      '(lambda (arg) 
  148. X         (interactive "P")
  149. X         (if (and forms--mode-setup
  150. X              forms-forms-scroll)
  151. X         (forms-prev-record arg)
  152. X           (forms--scroll-down arg)))))
  153. X  ;;
  154. X  ;; scroll-up -> forms-next-record
  155. X  ;;
  156. X  (if (fboundp 'forms--scroll-up)
  157. X      nil
  158. X    (fset 'forms--scroll-up   (symbol-function 'scroll-up))
  159. X    (fset 'scroll-up
  160. X      '(lambda (arg) 
  161. X         (interactive "P")
  162. X         (if (and forms--mode-setup
  163. X              forms-forms-scroll)
  164. X         (forms-next-record arg)
  165. X           (forms--scroll-up arg)))))
  166. X  ;;
  167. X  ;; beginning-of-buffer -> forms-first-record
  168. X  ;;
  169. X  (if (fboundp 'forms--beginning-of-buffer)
  170. X      nil
  171. X    (fset 'forms--beginning-of-buffer (symbol-function 'beginning-of-buffer))
  172. X    (fset 'beginning-of-buffer
  173. X      '(lambda ()
  174. X         (interactive)
  175. X         (if (and forms--mode-setup
  176. X              forms-forms-jump)
  177. X         (forms-first-record)
  178. X           (forms--beginning-of-buffer)))))
  179. X  ;;
  180. X  ;; end-of-buffer -> forms-end-record
  181. X  ;;
  182. X  (if (fboundp 'forms--end-of-buffer)
  183. X      nil
  184. X    (fset 'forms--end-of-buffer (symbol-function 'end-of-buffer))
  185. X    (fset 'end-of-buffer
  186. X      '(lambda ()
  187. X         (interactive)
  188. X         (if (and forms--mode-setup
  189. X              forms-forms-jump)
  190. X         (forms-last-record)
  191. X           (forms--end-of-buffer)))))
  192. X  ;;
  193. X  ;; save-buffer -> forms--save-buffer
  194. X  ;;
  195. X  (if (fboundp 'forms--save-buffer)
  196. X      nil
  197. X    (fset 'forms--save-buffer (symbol-function 'save-buffer))
  198. X    (fset 'save-buffer
  199. X      '(lambda (&optional arg)
  200. X         (interactive "p")
  201. X         (if forms--mode-setup
  202. X         (progn
  203. X           (forms--checkmod)
  204. X           (save-excursion
  205. X             (set-buffer forms--file-buffer)
  206. X             (forms--save-buffer arg)))
  207. X           (forms--save-buffer arg)))))
  208. X  ;;
  209. X  )
  210. X
  211. (defun forms--help ()
  212. X  "Initial help."
  213. X  ;; We should use
  214. X  ;;(message (substitute-command-keys (concat
  215. X  ;;"\\[forms-next-record]:next"
  216. X  ;;"   \\[forms-prev-record]:prev"
  217. X  ;;"   \\[forms-first-record]:first"
  218. X  ;;"   \\[forms-last-record]:last"
  219. X  ;;"   \\[describe-mode]:help"
  220. X  ;;"   \\[forms-exit]:exit")))
  221. X  ;; but it's too slow ....
  222. X  (if forms-read-only
  223. X      (message "SPC:next   DEL:prev   <:first   >:last   ?:help   q:exit")
  224. X    (message "C-c n:next   C-c p:prev   C-c <:first   C-c >:last   C-c ?:help   C-c q:exit")))
  225. X
  226. (defun forms--trans (subj arg rep)
  227. X  "Translate in SUBJ all chars ARG into char REP. ARG and REP should
  228. X be single-char strings."
  229. X  (let ((i 0)
  230. X    (x (length subj))
  231. X    (re (regexp-quote arg))
  232. X    (k (string-to-char rep)))
  233. X    (while (setq i (string-match re subj i))
  234. X      (aset subj i k)
  235. X      (setq i (1+ i)))))
  236. X
  237. (defun forms--exit (query &optional save)
  238. X  (let ((buf (buffer-name forms--file-buffer)))
  239. X    (forms--checkmod)
  240. X    (if (and save
  241. X         (buffer-modified-p forms--file-buffer))
  242. X    (save-excursion
  243. X      (set-buffer forms--file-buffer)
  244. X      (save-buffer)))
  245. X    (save-excursion
  246. X      (set-buffer forms--file-buffer)
  247. X      (delete-auto-save-file-if-necessary)
  248. X      (kill-buffer (current-buffer)))
  249. X    (if (get-buffer buf)    ; not killed???
  250. X      (if save
  251. X      (progn
  252. X        (beep)
  253. X        (message "Problem saving buffers?")))
  254. X      (delete-auto-save-file-if-necessary)
  255. X      (kill-buffer (current-buffer)))))
  256. X
  257. (defun forms--get-record ()
  258. X  "Fetch the current record from the file buffer."
  259. X  ;;
  260. X  ;; This function is executed in the context of the forms--file-buffer.
  261. X  ;;
  262. X  (or (bolp)
  263. X      (beginning-of-line nil))
  264. X  (let ((here (point)))
  265. X    (prog2
  266. X     (end-of-line)
  267. X     (buffer-substring here (point))
  268. X     (goto-char here))))
  269. X
  270. (defun forms--show-record (the-record)
  271. X  "Format THE-RECORD according to forms-format-list,
  272. X and display it in the current buffer."
  273. X
  274. X  ;; split the-record
  275. X  (let (the-result
  276. X    (start-pos 0)
  277. X    found-pos
  278. X    (field-sep-length (length forms-field-sep)))
  279. X    (if forms-multi-line
  280. X    (forms--trans the-record forms-multi-line "\n"))
  281. X    ;; add an extra separator (makes splitting easy)
  282. X    (setq the-record (concat the-record forms-field-sep))
  283. X    (while (setq found-pos (string-match forms-field-sep the-record start-pos))
  284. X      (let ((ent (substring the-record start-pos found-pos)))
  285. X    (setq the-result
  286. X          (append the-result (list ent)))
  287. X    (setq start-pos (+ field-sep-length found-pos))))
  288. X    (setq forms--the-record-list the-result))
  289. X
  290. X  (setq buffer-read-only nil)
  291. X  (erase-buffer)
  292. X
  293. X  ;; verify the number of fields, extend forms--the-record-list if needed
  294. X  (if (= (length forms--the-record-list) forms-number-of-fields)
  295. X      nil
  296. X    (beep)
  297. X    (message "Record has %d fields instead of %d."
  298. X         (length forms--the-record-list) forms-number-of-fields)
  299. X    (if (< (length forms--the-record-list) forms-number-of-fields)
  300. X    (setq forms--the-record-list 
  301. X          (append forms--the-record-list
  302. X              (make-list 
  303. X               (- forms-number-of-fields 
  304. X              (length forms--the-record-list))
  305. X               "")))))
  306. X
  307. X  ;; call the formatter function
  308. X  (funcall forms--format forms--the-record-list)
  309. X
  310. X  ;; prepare
  311. X  (goto-char (point-min))
  312. X  (set-buffer-modified-p nil)
  313. X  (setq buffer-read-only forms-read-only)
  314. X  (setq mode-line-process
  315. X    (concat " " forms--current-record "/" forms--total-records)))
  316. X
  317. (defun forms--parse-form ()
  318. X  "Parse contents of form into list of strings."
  319. X  ;; The contents of the form are parsed, and a new list of strings
  320. X  ;; is constructed.
  321. X  ;; A vector with the strings from the original record is 
  322. X  ;; constructed, which is updated with the new contents. Therefore
  323. X  ;; fields which were not in the form are not modified.
  324. X  ;; Finally, the vector is transformed into a list for further processing.
  325. X
  326. X  (let (the-recordv)
  327. X
  328. X    ;; build the vector
  329. X    (setq the-recordv (vconcat forms--the-record-list))
  330. X
  331. X    ;; parse the form and update the vector
  332. X    (funcall forms--parser)
  333. X
  334. X    ;; transform to a list and return
  335. X    (append the-recordv nil)))
  336. X
  337. (defun forms--update ()
  338. X  "Update current record with contents of form. As a side effect: sets
  339. forms--the-record-list ."
  340. X  (if forms-read-only
  341. X      (progn
  342. X    (message "Read-only buffer!")
  343. X    (beep))
  344. X
  345. X    (let (the-record)
  346. X      ;; build new record
  347. X      (setq forms--the-record-list (forms--parse-form))
  348. X      (setq the-record
  349. X        (mapconcat 'identity forms--the-record-list forms-field-sep))
  350. X
  351. X      ;; handle multi-line fields, if allowed
  352. X      (if forms-multi-line
  353. X      (forms--trans the-record "\n" forms-multi-line))
  354. X
  355. X      ;; a final sanity check before updating
  356. X      (if (string-match "\n" the-record)
  357. X      (progn
  358. X        (message "Multi-line fields in this record - update refused!")
  359. X        (beep))
  360. X
  361. X    (save-excursion
  362. X      (set-buffer forms--file-buffer)
  363. X      ;; Insert something before kill-line is called. See kill-line
  364. X      ;; doc. Bugfix provided by Ignatios Souvatzis.
  365. X      (insert "*")
  366. X      (beginning-of-line)
  367. X      (kill-line nil)
  368. X      (insert the-record)
  369. X      (beginning-of-line))))))
  370. X
  371. (defun forms--checkmod ()
  372. X  "Check if this form has been modified, and call forms--update if so."
  373. X  (if (buffer-modified-p nil)
  374. X      (let ((here (point)))
  375. X    (forms--update)
  376. X    (set-buffer-modified-p nil)
  377. X    (goto-char here))))
  378. X
  379. ;;;
  380. ;;; Start and exit
  381. (defun forms-find-file (fn)
  382. X  "Visit file FN in forms mode"
  383. X  (interactive "fForms file: ")
  384. X  (find-file-read-only fn)
  385. X  (or forms--mode-setup (forms-mode t)))
  386. X
  387. (defun forms-find-file-other-window (fn)
  388. X  "Visit file FN in form mode in other window"
  389. X  (interactive "fFbrowse file in other window: ")
  390. X  (find-file-other-window fn)
  391. X  (eval-current-buffer)
  392. X  (or forms--mode-setup (forms-mode t)))
  393. X
  394. (defun forms-exit (query)
  395. X  "Normal exit. Modified buffers are saved."
  396. X  (interactive "P")
  397. X  (forms--exit query t))
  398. X
  399. (defun forms-exit-no-save (query)
  400. X  "Exit without saving buffers."
  401. X  (interactive "P")
  402. X  (forms--exit query nil))
  403. X
  404. ;;;
  405. ;;; Navigating commands
  406. X
  407. (defun forms-next-record (arg)
  408. X  "Advance to the ARGth following record."
  409. X  (interactive "P")
  410. X  (forms-jump-record (+ forms--current-record (prefix-numeric-value arg)) t))
  411. X
  412. (defun forms-prev-record (arg)
  413. X  "Advance to the ARGth previous record."
  414. X  (interactive "P")
  415. X  (forms-jump-record (- forms--current-record (prefix-numeric-value arg)) t))
  416. X
  417. (defun forms-jump-record (arg &optional relative)
  418. X  "Jump to a random record."
  419. X  (interactive "NRecord number: ")
  420. X
  421. X  ;; verify that the record number is within range
  422. X  (if (or (> arg forms--total-records)
  423. X      (<= arg 0))
  424. X    (progn
  425. X      (beep)
  426. X      ;; don't give the message if just paging
  427. X      (if (not relative)
  428. X      (message "Record number %d out of range 1..%d"
  429. X           arg forms--total-records))
  430. X      )
  431. X
  432. X    ;; flush
  433. X    (forms--checkmod)
  434. X
  435. X    ;; calculate displacement
  436. X    (let ((disp (- arg forms--current-record))
  437. X      (cur forms--current-record))
  438. X
  439. X      ;; forms--show-record needs it now
  440. X      (setq forms--current-record arg)
  441. X
  442. X      ;; get the record and show it
  443. X      (forms--show-record
  444. X       (save-excursion
  445. X     (set-buffer forms--file-buffer)
  446. X     (beginning-of-line)
  447. X
  448. X     ;; move, and adjust the amount if needed (shouldn't happen)
  449. X     (if relative
  450. X         (if (zerop disp)
  451. X         nil
  452. X           (setq cur (+ cur disp (- (forward-line disp)))))
  453. X       (setq cur (+ cur disp (- (goto-line arg)))))
  454. X
  455. X     (forms--get-record)))
  456. X
  457. X      ;; this shouldn't happen
  458. X      (if (/= forms--current-record cur)
  459. X      (progn
  460. X        (setq forms--current-record cur)
  461. X        (beep)
  462. X        (message "Stuck at record %d." cur))))))
  463. X
  464. (defun forms-first-record ()
  465. X  "Jump to first record."
  466. X  (interactive)
  467. X  (forms-jump-record 1))
  468. X
  469. (defun forms-last-record ()
  470. X  "Jump to last record. As a side effect: re-calculates the number
  471. X of records in the data file."
  472. X  (interactive)
  473. X  (let
  474. X      ((numrec 
  475. X    (save-excursion
  476. X      (set-buffer forms--file-buffer)
  477. X      (count-lines (point-min) (point-max)))))
  478. X    (if (= numrec forms--total-records)
  479. X    nil
  480. X      (beep)
  481. X      (setq forms--total-records numrec)
  482. X      (message "Number of records reset to %d." forms--total-records)))
  483. X  (forms-jump-record forms--total-records))
  484. X
  485. ;;;
  486. ;;; Other commands
  487. (defun forms-view-mode ()
  488. X  "Visit buffer read-only."
  489. X  (interactive)
  490. X  (if forms-read-only
  491. X      nil
  492. X    (forms--checkmod)            ; sync
  493. X    (setq forms-read-only t)
  494. X    (forms-mode)))
  495. X
  496. (defun forms-edit-mode ()
  497. X  "Make form suitable for editing, if possible."
  498. X  (interactive)
  499. X  (let ((ro forms-read-only))
  500. X    (if (save-excursion
  501. X      (set-buffer forms--file-buffer)
  502. X      buffer-read-only)
  503. X    (progn
  504. X      (setq forms-read-only t)
  505. X      (message "No write access to \"%s\"" forms-file)
  506. X      (beep))
  507. X      (setq forms-read-only nil))
  508. X    (if (equal ro forms-read-only)
  509. X    nil
  510. X      (forms-mode))))
  511. X
  512. ;; Sample:
  513. ;; (defun forms-new-record-filter (the-fields)
  514. ;;   ;; numbers are relative to 1
  515. ;;   (aset the-fields 4 (current-time-string))
  516. ;;   (aset the-fields 6 (user-login-name))
  517. ;;   the-list)
  518. X
  519. (defun forms-insert-record (arg)
  520. X  "Create a new record before the current one. With ARG: store the
  521. X record after the current one.
  522. X If a function forms-new-record-filter is defined, is is called to
  523. X fill (some of) the fields with default values."
  524. X ; The above doc is not true, but for documentary purposes only
  525. X
  526. X  (interactive "P")
  527. X
  528. X  (let ((ln (if arg (1+ forms--current-record) forms--current-record))
  529. X        the-list the-record)
  530. X
  531. X    (forms--checkmod)
  532. X    (if forms--new-record-filter
  533. X    ;; As a service to the user, we add a zeroth element so she
  534. X    ;; can use the same indices as in the forms definition.
  535. X    (let ((the-fields (make-vector (1+ forms-number-of-fields) "")))
  536. X      (setq the-fields (funcall forms--new-record-filter the-fields))
  537. X      (setq the-list (cdr (append the-fields nil))))
  538. X      (setq the-list (make-list forms-number-of-fields "")))
  539. X
  540. X    (setq the-record
  541. X      (mapconcat
  542. X      'identity
  543. X      the-list
  544. X      forms-field-sep))
  545. X
  546. X    (save-excursion
  547. X      (set-buffer forms--file-buffer)
  548. X      (goto-line ln)
  549. X      (open-line 1)
  550. X      (insert the-record)
  551. X      (beginning-of-line))
  552. X    
  553. X    (setq forms--current-record ln))
  554. X
  555. X  (setq forms--total-records (1+ forms--total-records))
  556. X  (forms-jump-record forms--current-record))
  557. X
  558. (defun forms-delete-record (arg)
  559. X  "Deletes a record. With ARG: don't ask."
  560. X  (interactive "P")
  561. X  (forms--checkmod)
  562. X  (if (or arg
  563. X      (y-or-n-p "Really delete this record? "))
  564. X      (let ((ln forms--current-record))
  565. X    (save-excursion
  566. X      (set-buffer forms--file-buffer)
  567. X      (goto-line ln)
  568. X      (kill-line 1))
  569. X    (setq forms--total-records (1- forms--total-records))
  570. X    (if (> forms--current-record forms--total-records)
  571. X        (setq forms--current-record forms--total-records))
  572. X    (forms-jump-record forms--current-record)))
  573. X  (message ""))
  574. X
  575. (defun forms-search (regexp)
  576. X  "Search REGEXP in file buffer."
  577. X  (interactive 
  578. X   (list (read-string (concat "Search for" 
  579. X                  (if forms--search-regexp
  580. X                   (concat " ("
  581. X                       forms--search-regexp
  582. X                       ")"))
  583. X                  ": "))))
  584. X  (if (equal "" regexp)
  585. X      (setq regexp forms--search-regexp))
  586. X  (forms--checkmod)
  587. X
  588. X  (let (the-line the-record here
  589. X         (fld-sep forms-field-sep))
  590. X    (if (save-excursion
  591. X      (set-buffer forms--file-buffer)
  592. X      (setq here (point))
  593. X      (end-of-line)
  594. X      (if (null (re-search-forward regexp nil t))
  595. X          (progn
  596. X        (goto-char here)
  597. X        (message (concat "\"" regexp "\" not found."))
  598. X        nil)
  599. X        (setq the-record (forms--get-record))
  600. X        (setq the-line (1+ (count-lines (point-min) (point))))))
  601. X    (progn
  602. X      (setq forms--current-record the-line)
  603. X      (forms--show-record the-record)
  604. X      (re-search-forward regexp nil t))))
  605. X  (setq forms--search-regexp regexp))
  606. X
  607. (defun forms-revert-buffer (&optional arg noconfirm)
  608. X  "Reverts current form to un-modified."
  609. X  (interactive "P")
  610. X  (if (or noconfirm
  611. X      (yes-or-no-p "Revert form to unmodified? "))
  612. X      (progn
  613. X    (set-buffer-modified-p nil)
  614. X    (forms-jump-record forms--current-record))))
  615. X
  616. (defun forms-next-field (arg)
  617. X  "Jump to ARG-th next field."
  618. X  (interactive "p")
  619. X
  620. X  (let ((i 0)
  621. X    (here (point))
  622. X    there
  623. X    (cnt 0))
  624. X
  625. X    (if (zerop arg)
  626. X    (setq cnt 1)
  627. X      (setq cnt (+ cnt arg)))
  628. X
  629. X    (if (catch 'done
  630. X      (while (< i forms--number-of-markers)
  631. X        (if (or (null (setq there (aref forms--markers i)))
  632. X            (<= there here))
  633. X        nil
  634. X          (if (<= (setq cnt (1- cnt)) 0)
  635. X          (progn
  636. X            (goto-char there)
  637. X            (throw 'done t))))
  638. X        (setq i (1+ i))))
  639. X    nil
  640. X      (goto-char (aref forms--markers 0)))))
  641. SHAR_EOF
  642. echo 'File forms.el is complete' &&
  643. chmod 0444 forms.el ||
  644. echo 'restore of forms.el failed'
  645. Wc_c="`wc -c < 'forms.el'`"
  646. test 36048 -eq "$Wc_c" ||
  647.     echo 'forms.el: original size 36048, current size' "$Wc_c"
  648. rm -f _shar_wnt_.tmp
  649. fi
  650. rm -f _shar_seq_.tmp
  651. echo You have unpacked the last part
  652. exit 0
  653. -- 
  654. Johan Vromans                       jv@mh.nl via internet backbones
  655. Multihouse Automatisering bv               uucp: ..!{uunet,hp4nl}!mh.nl!jv
  656. Doesburgweg 7, 2803 PL Gouda, The Netherlands  phone/fax: +31 1820 62911/62500
  657. ------------------------ "Arms are made for hugging" -------------------------
  658.