mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-16 17:24:23 +00:00
Version 2.3.
Documentation: `forms-forms-scroll' and `forms-forms-jump' now default to nil. `forms-new-record-filter' and `forms-modified-record-filter' cannot be redefined as functions. Commands and keymaps are changed. Add function key defs. (forms-version): Docstring includes full RCS id. (forms-forms-scroll): Defaults to nil. (forms-forms-jump): Defaults to nil. (forms-mode-edit-map, forms-mode-ro-map): Additional keymaps for edit mode and read-only mode. (forms--new-record-filter, forms--modified-record-filter): Deleted. (forms-mode): Docstring now includes the key bindings, since both edit mode and read-only mode must be supported. Changed `forms-new-record-filter' and `forms-modified-record-filter' semantics: the variable must point to a function and may not be defined as a function anymore. Use three keymaps: `forms-mode-map' (C-c commands), `forms-mode-edit-map' (normal mode) and `forms-mode-ro-map' (read-only mode). The maps are not buffer local. Changed the text of error messages to be more descriptive, and onsistent with the documentation. Moved setting up write-file-hooks and revert-buffer-function to function `forms--change-commands'. (forms--process-format-list): Changed error messages to be more descriptive. (forms--set-keymaps): Setup the three keymaps. (forms--mode-commands): Use new command key bindings. (forms--mode-commands1): New helper function for `forms--mode-commands'. (forms--change-commands): Handle setup of local-write-file-hooks and revert-buffer-function. (forms--help): Show new command bindings. (forms--show-record): Replaced `forms--modified-record-filter' by `forms-modified-record-filter'. (forms-jump-record): Changed error message. (forms-toggle-read-only): New function, replaces `forms-view-mode' and `forms-edit-mode'. (forms-view-mode, forms-edit-mode): Deleted. (forms-insert-record): Replaced `forms--new-record-filter' by `forms-new-record-filter'. (forms-insert-record, forms-delete-record): Disallow in read-only mode. (forms-prev-field): New function.
This commit is contained in:
parent
8dff74b7f6
commit
2cc27dd3d2
1 changed files with 266 additions and 172 deletions
438
lisp/forms.el
438
lisp/forms.el
|
|
@ -2,7 +2,7 @@
|
|||
;;; Copyright (C) 1991, 1993 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Johan Vromans <jv@mh.nl>
|
||||
;; Version: 2.2
|
||||
;; Version: $Revision: 2.3 $
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
|
|
@ -113,32 +113,28 @@
|
|||
;;; to newlines. Upon storage they are translated
|
||||
;;; back to the separator character.
|
||||
;;;
|
||||
;;; forms-forms-scroll [bool, default t]
|
||||
;;; forms-forms-scroll [bool, default nil]
|
||||
;;; Non-nil means: rebind locally the commands that
|
||||
;;; perform `scroll-up' or `scroll-down' to use
|
||||
;;; `forms-next-field' resp. `forms-prev-field'.
|
||||
;;;
|
||||
;;; forms-forms-jump [bool, default t]
|
||||
;;; forms-forms-jump [bool, default nil]
|
||||
;;; Non-nil means: rebind locally the commands that
|
||||
;;; perform `beginning-of-buffer' or `end-of-buffer'
|
||||
;;; to perform `forms-first-field' resp. `forms-last-field'.
|
||||
;;;
|
||||
;;; forms-new-record-filter [symbol, no default]
|
||||
;;; If defined: this should be the name of a
|
||||
;;; forms-new-record-filter [symbol, default nil]
|
||||
;;; If not nil: this should be the name of a
|
||||
;;; function that is called when a new
|
||||
;;; record is created. It can be used to fill in
|
||||
;;; the new record with default fields, for example.
|
||||
;;; Instead of the name of the function, it may
|
||||
;;; be the function itself.
|
||||
;;;
|
||||
;;; forms-modified-record-filter [symbol, no default]
|
||||
;;; If defined: this should be the name of a
|
||||
;;; forms-modified-record-filter [symbol, default nil]
|
||||
;;; If not nil: this should be the name of a
|
||||
;;; function that is called when a record has
|
||||
;;; been modified. It is called after the fields
|
||||
;;; are parsed. It can be used to register
|
||||
;;; modification dates, for example.
|
||||
;;; Instead of the name of the function, it may
|
||||
;;; be the function itself.
|
||||
;;;
|
||||
;;; forms-use-text-properties [bool, see text for default]
|
||||
;;; This variable controls if forms mode should use
|
||||
|
|
@ -206,39 +202,56 @@
|
|||
;;; file (using forms-last-record) will adjust forms--total-records if
|
||||
;;; needed.
|
||||
;;;
|
||||
;;; Commands and keymaps:
|
||||
;;; The forms buffer can be in on eof two modes: edit mode or view
|
||||
;;; mode. View mode is a read-only mode, you cannot modify the
|
||||
;;; contents of the buffer.
|
||||
;;;
|
||||
;;; A local keymap `forms-mode-map' is used in the forms buffer.
|
||||
;;; If the forms is in view mode, this keymap is used so all forms mode
|
||||
;;; functions are accessible.
|
||||
;;; If the forms is in edit mode, this map can be accessed with C-c prefix.
|
||||
;;;
|
||||
;;; Default bindings:
|
||||
;;;
|
||||
;;; \C-c forms-mode-map
|
||||
;;; TAB forms-next-field
|
||||
;;; SPC forms-next-record
|
||||
;;; < forms-first-record
|
||||
;;; > forms-last-record
|
||||
;;; ? describe-mode
|
||||
;;; d forms-delete-record
|
||||
;;; e forms-edit-mode
|
||||
;;; i forms-insert-record
|
||||
;;; j forms-jump-record
|
||||
;;; n forms-next-record
|
||||
;;; p forms-prev-record
|
||||
;;; q forms-exit
|
||||
;;; s forms-search
|
||||
;;; v forms-view-mode
|
||||
;;; x forms-exit-no-save
|
||||
;;; DEL forms-prev-record
|
||||
;;; Edit mode commands:
|
||||
;;;
|
||||
;;; TAB forms-next-field
|
||||
;;; \C-c TAB forms-next-field
|
||||
;;; \C-c < forms-first-record
|
||||
;;; \C-c > forms-last-record
|
||||
;;; \C-c ? describe-mode
|
||||
;;; \C-c \C-k forms-delete-record
|
||||
;;; \C-c \C-q forms-toggle-read-only
|
||||
;;; \C-c \C-o forms-insert-record
|
||||
;;; \C-c \C-l forms-jump-record
|
||||
;;; \C-c \C-n forms-next-record
|
||||
;;; \C-c \C-p forms-prev-record
|
||||
;;; \C-c \C-s forms-search
|
||||
;;; \C-c \C-x forms-exit
|
||||
;;;
|
||||
;;; Read-only mode commands:
|
||||
;;;
|
||||
;;; SPC forms-next-record
|
||||
;;; DEL forms-prev-record
|
||||
;;; ? describe-mode
|
||||
;;; \C-q forms-toggle-read-only
|
||||
;;; l forms-jump-record
|
||||
;;; n forms-next-record
|
||||
;;; p forms-prev-record
|
||||
;;; s forms-search
|
||||
;;; x forms-exit
|
||||
;;;
|
||||
;;; Of course, it is also possible to use the \C-c prefix to obtain the
|
||||
;;; same command keys as in edit mode.
|
||||
;;;
|
||||
;;; The following bindings are available, independent of the mode:
|
||||
;;;
|
||||
;;; [next] forms-next-record
|
||||
;;; [prior] forms-prev-record
|
||||
;;; [begin] forms-first-record
|
||||
;;; [end] forms-last-record
|
||||
;;; [S-TAB] forms-prev-field
|
||||
;;; [backtab] forms-prev-field
|
||||
;;;
|
||||
;;; For convenience, TAB is always bound to `forms-next-field', so you
|
||||
;;; don't need the C-c prefix for this command.
|
||||
;;;
|
||||
;;; As mentioned above (see `forms-forms-scroll' and `forms-forms-jump')
|
||||
;;; the bindings of standard functions `scroll-up', `scroll-down',
|
||||
;;; `beginning-of-buffer' and `end-of-buffer' are locally replaced with
|
||||
;;; `beginning-of-buffer' and `end-of-buffer' can be locally replaced with
|
||||
;;; forms mode functions next/prev record and first/last
|
||||
;;; record.
|
||||
;;;
|
||||
|
|
@ -253,8 +266,10 @@
|
|||
(provide 'forms) ;;; official
|
||||
(provide 'forms-mode) ;;; for compatibility
|
||||
|
||||
(defconst forms-version "2.2"
|
||||
"Version of forms-mode implementation.")
|
||||
(defconst forms-version (substring "$Revision: 2.3 $" 11 -2)
|
||||
"The version number of forms-mode (as string). The complete RCS id is:
|
||||
|
||||
$Id: forms.el,v 2.3 1993/09/26 14:07:12 jv Exp $")
|
||||
|
||||
(defvar forms-mode-hooks nil
|
||||
"Hook functions to be run upon entering Forms mode.")
|
||||
|
|
@ -282,11 +297,11 @@
|
|||
(defvar forms-multi-line "\C-k"
|
||||
"If not nil: use this character to separate multi-line fields (default C-k).")
|
||||
|
||||
(defvar forms-forms-scroll t
|
||||
(defvar forms-forms-scroll nil
|
||||
"*Non-nil means replace scroll-up/down commands in Forms mode.
|
||||
The replacement commands performs forms-next/prev-record.")
|
||||
|
||||
(defvar forms-forms-jump t
|
||||
(defvar forms-forms-jump nil
|
||||
"*Non-nil means redefine beginning/end-of-buffer in Forms mode.
|
||||
The replacement commands performs forms-first/last-record.")
|
||||
|
||||
|
|
@ -322,8 +337,12 @@ Defaults to t if this emacs is capable of handling text properties.")
|
|||
(defvar forms--current-record 0
|
||||
"Number of the record currently on the screen.")
|
||||
|
||||
(defvar forms-mode-map nil ; yes - this one is global
|
||||
(defvar forms-mode-map nil
|
||||
"Keymap for form buffer.")
|
||||
(defvar forms-mode-ro-map nil
|
||||
"Keymap for form buffer in view mode.")
|
||||
(defvar forms-mode-edit-map nil
|
||||
"Keymap for form buffer in edit mode.")
|
||||
|
||||
(defvar forms--markers nil
|
||||
"Field markers in the screen.")
|
||||
|
|
@ -347,12 +366,6 @@ Defaults to t if this emacs is capable of handling text properties.")
|
|||
"To keep track of forms-mode being set-up.")
|
||||
(make-variable-buffer-local 'forms--mode-setup)
|
||||
|
||||
(defvar forms--new-record-filter nil
|
||||
"Set if a new record filter has been defined.")
|
||||
|
||||
(defvar forms--modified-record-filter nil
|
||||
"Set if a modified record filter has been defined.")
|
||||
|
||||
(defvar forms--dynamic-text nil
|
||||
"Array that holds dynamic texts to insert between fields.")
|
||||
|
||||
|
|
@ -369,10 +382,22 @@ Defaults to t if this emacs is capable of handling text properties.")
|
|||
(defun forms-mode (&optional primary)
|
||||
"Major mode to visit files in a field-structured manner using a form.
|
||||
|
||||
Commands (prefix with C-c if not in read-only mode):
|
||||
\\{forms-mode-map}"
|
||||
|
||||
(interactive) ; no - 'primary' is not prefix arg
|
||||
Commands: Equivalent keys in read-only mode:
|
||||
TAB forms-next-field TAB
|
||||
\\C-c TAB forms-next-field
|
||||
\\C-c < forms-first-record <
|
||||
\\C-c > forms-last-record >
|
||||
\\C-c ? describe-mode ?
|
||||
\\C-c \\C-k forms-delete-record
|
||||
\\C-c \\C-q forms-toggle-read-only q
|
||||
\\C-c \\C-o forms-insert-record
|
||||
\\C-c \\C-l forms-jump-record l
|
||||
\\C-c \\C-n forms-next-record n
|
||||
\\C-c \\C-p forms-prev-record p
|
||||
\\C-c \\C-s forms-search s
|
||||
\\C-c \\C-x forms-exit x
|
||||
"
|
||||
(interactive)
|
||||
|
||||
;; This is not a simple major mode, as usual. Therefore, forms-mode
|
||||
;; takes an optional argument `primary' which is used for the
|
||||
|
|
@ -403,12 +428,12 @@ Commands (prefix with C-c if not in read-only mode):
|
|||
(make-local-variable 'forms-forms-scroll)
|
||||
(make-local-variable 'forms-forms-jump)
|
||||
(make-local-variable 'forms-use-text-properties)
|
||||
(make-local-variable 'forms--new-record-filter)
|
||||
(make-local-variable 'forms--modified-record-filter)
|
||||
(make-local-variable 'forms-new-record-filter)
|
||||
(make-local-variable 'forms-modified-record-filter)
|
||||
|
||||
;; Make sure no filters exist.
|
||||
(fmakunbound 'forms-new-record-filter)
|
||||
(fmakunbound 'forms-modified-record-filter)
|
||||
(setq forms-new-record-filter nil)
|
||||
(setq forms-modified-record-filter nil)
|
||||
|
||||
;; If running Emacs 19 under X, setup faces to show read-only and
|
||||
;; read-write fields.
|
||||
|
|
@ -423,19 +448,26 @@ Commands (prefix with C-c if not in read-only mode):
|
|||
|
||||
;; check if the mandatory variables make sense.
|
||||
(or forms-file
|
||||
(error "'forms-file' has not been set"))
|
||||
(error (concat "Forms control file error: "
|
||||
"'forms-file' has not been set")))
|
||||
(or forms-number-of-fields
|
||||
(error "'forms-number-of-fields' has not been set"))
|
||||
(or (> forms-number-of-fields 0)
|
||||
(error "'forms-number-of-fields' must be > 0")
|
||||
(or (stringp forms-field-sep))
|
||||
(error "'forms-field-sep' is not a string"))
|
||||
(error (concat "Forms control file error: "
|
||||
"'forms-number-of-fields' has not been set")))
|
||||
(or (and (numberp forms-number-of-fields)
|
||||
(> forms-number-of-fields 0))
|
||||
(error (concat "Forms control file error: "
|
||||
"'forms-number-of-fields' must be a number > 0")))
|
||||
(or (stringp forms-field-sep)
|
||||
(error (concat "Forms control file error: "
|
||||
"'forms-field-sep' is not a string")))
|
||||
(if forms-multi-line
|
||||
(if (and (stringp forms-multi-line)
|
||||
(eq (length forms-multi-line) 1))
|
||||
(if (string= forms-multi-line forms-field-sep)
|
||||
(error "'forms-multi-line' is equal to 'forms-field-sep'"))
|
||||
(error "'forms-multi-line' must be nil or a one-character string")))
|
||||
(error (concat "Forms control file error: "
|
||||
"'forms-multi-line' is equal to 'forms-field-sep'")))
|
||||
(error (concat "Forms control file error: "
|
||||
"'forms-multi-line' must be nil or a one-character string"))))
|
||||
(or (fboundp 'set-text-properties)
|
||||
(setq forms-use-text-properties nil))
|
||||
|
||||
|
|
@ -456,22 +488,15 @@ Commands (prefix with C-c if not in read-only mode):
|
|||
;;(message "forms: building parser... done.")
|
||||
|
||||
;; Check if record filters are defined.
|
||||
(setq forms--new-record-filter
|
||||
(cond
|
||||
((fboundp 'forms-new-record-filter)
|
||||
(symbol-function 'forms-new-record-filter))
|
||||
((and (boundp 'forms-new-record-filter)
|
||||
(fboundp forms-new-record-filter))
|
||||
forms-new-record-filter)))
|
||||
(fmakunbound 'forms-new-record-filter)
|
||||
(setq forms--modified-record-filter
|
||||
(cond
|
||||
((fboundp 'forms-modified-record-filter)
|
||||
(symbol-function 'forms-modified-record-filter))
|
||||
((and (boundp 'forms-modified-record-filter)
|
||||
(fboundp forms-modified-record-filter))
|
||||
forms-modified-record-filter)))
|
||||
(fmakunbound 'forms-modified-record-filter)
|
||||
(if (and forms-new-record-filter
|
||||
(not (fboundp forms-new-record-filter)))
|
||||
(error (concat "Forms control file error: "
|
||||
"'forms-new-record-filter' is not a function")))
|
||||
|
||||
(if (and forms-modified-record-filter
|
||||
(not (fboundp forms-modified-record-filter)))
|
||||
(error (concat "Forms control file error: "
|
||||
"'forms-modified-record-filter' is not a function")))
|
||||
|
||||
;; The filters acces the contents of the forms using `forms-fields'.
|
||||
(make-local-variable 'forms-fields)
|
||||
|
|
@ -509,15 +534,14 @@ Commands (prefix with C-c if not in read-only mode):
|
|||
(make-local-variable 'forms--the-record-list)
|
||||
(make-local-variable 'forms--search-regexp)
|
||||
|
||||
;; A bug in the current Emacs release prevents a keymap
|
||||
;; which is buffer-local from being used by 'describe-mode'.
|
||||
;; Hence we'll leave it global.
|
||||
;;(make-local-variable 'forms-mode-map)
|
||||
; The keymaps are global, so multiple forms mode buffers can share them.
|
||||
;(make-local-variable 'forms-mode-map)
|
||||
;(make-local-variable 'forms-mode-ro-map)
|
||||
;(make-local-variable 'forms-mode-edit-map)
|
||||
(if forms-mode-map ; already defined
|
||||
nil
|
||||
;;(message "forms: building keymap...")
|
||||
(setq forms-mode-map (make-keymap))
|
||||
(forms--mode-commands forms-mode-map)
|
||||
(forms--mode-commands)
|
||||
;;(message "forms: building keymap... done.")
|
||||
)
|
||||
|
||||
|
|
@ -549,17 +573,12 @@ Commands (prefix with C-c if not in read-only mode):
|
|||
(forms--set-minor-mode)
|
||||
;;(message "forms: proceeding setup (keymaps)...")
|
||||
(forms--set-keymaps)
|
||||
(make-local-variable 'local-write-file-hooks)
|
||||
;;(message "forms: proceeding setup (commands)...")
|
||||
(forms--change-commands)
|
||||
|
||||
;;(message "forms: proceeding setup (buffer)...")
|
||||
(set-buffer-modified-p nil)
|
||||
|
||||
;; We have our own revert function - use it
|
||||
(make-local-variable 'revert-buffer-function)
|
||||
(setq revert-buffer-function 'forms-revert-buffer)
|
||||
|
||||
;; setup the first (or current) record to show
|
||||
(if (< forms--current-record 1)
|
||||
(setq forms--current-record 1))
|
||||
|
|
@ -590,10 +609,12 @@ Commands (prefix with C-c if not in read-only mode):
|
|||
|
||||
;; Verify that `forms-format-list' is not nil.
|
||||
(or forms-format-list
|
||||
(error "'forms-format-list' has not been set"))
|
||||
(error (concat "Forms control file error: "
|
||||
"'forms-format-list' has not been set")))
|
||||
;; It must be a list.
|
||||
(or (listp forms-format-list)
|
||||
(error "'forms-format-list' is not a list"))
|
||||
(error (concat "Forms control file error: "
|
||||
"'forms-format-list' is not a list")))
|
||||
|
||||
;; Assume every field is painted once.
|
||||
;; `forms--elements' will grow if needed.
|
||||
|
|
@ -633,9 +654,9 @@ Commands (prefix with C-c if not in read-only mode):
|
|||
;; Validate range.
|
||||
(if (or (<= el 0)
|
||||
(> el forms-number-of-fields))
|
||||
(error
|
||||
"Forms error: field number %d out of range 1..%d"
|
||||
el forms-number-of-fields))
|
||||
(error (concat "Forms format error: "
|
||||
"field number %d out of range 1..%d")
|
||||
el forms-number-of-fields))
|
||||
|
||||
;; Store forms order.
|
||||
(if (> field-num (length forms--elements))
|
||||
|
|
@ -653,9 +674,9 @@ Commands (prefix with C-c if not in read-only mode):
|
|||
|
||||
;; Validate.
|
||||
(or (fboundp (car-safe el))
|
||||
(error
|
||||
"Forms error: not a function: %s"
|
||||
(prin1-to-string (car-safe el))))
|
||||
(error (concat "Forms format error: "
|
||||
"not a function "
|
||||
(prin1-to-string (car-safe el)))))
|
||||
|
||||
;; Shift.
|
||||
(if prev-item
|
||||
|
|
@ -665,8 +686,9 @@ Commands (prefix with C-c if not in read-only mode):
|
|||
|
||||
;; else
|
||||
(t
|
||||
(error "Forms error: invalid element %s"
|
||||
(prin1-to-string el))))
|
||||
(error (concat "Forms format error: "
|
||||
"invalid element "
|
||||
(prin1-to-string el)))))
|
||||
|
||||
;; Advance to next element of the list.
|
||||
(setq the-list rem)))
|
||||
|
|
@ -1058,36 +1080,62 @@ Commands (prefix with C-c if not in read-only mode):
|
|||
(defun forms--set-keymaps ()
|
||||
"Set the keymaps used in this mode."
|
||||
|
||||
(if forms-read-only
|
||||
(use-local-map forms-mode-map)
|
||||
(use-local-map (make-sparse-keymap))
|
||||
(define-key (current-local-map) "\C-c" forms-mode-map)
|
||||
(define-key (current-local-map) "\t" 'forms-next-field)))
|
||||
(use-local-map (if forms-read-only
|
||||
forms-mode-ro-map
|
||||
forms-mode-edit-map)))
|
||||
|
||||
(defun forms--mode-commands (map)
|
||||
"Fill map with all Forms mode commands."
|
||||
(defun forms--mode-commands ()
|
||||
"Fill the Forms mode keymaps."
|
||||
|
||||
(define-key map "\t" 'forms-next-field)
|
||||
(define-key map " " 'forms-next-record)
|
||||
(define-key map "d" 'forms-delete-record)
|
||||
(define-key map "e" 'forms-edit-mode)
|
||||
(define-key map "i" 'forms-insert-record)
|
||||
(define-key map "j" 'forms-jump-record)
|
||||
(define-key map "n" 'forms-next-record)
|
||||
(define-key map "p" 'forms-prev-record)
|
||||
(define-key map "q" 'forms-exit)
|
||||
(define-key map "s" 'forms-search)
|
||||
(define-key map "v" 'forms-view-mode)
|
||||
(define-key map "x" 'forms-exit-no-save)
|
||||
(define-key map "<" 'forms-first-record)
|
||||
(define-key map ">" 'forms-last-record)
|
||||
(define-key map "?" 'describe-mode)
|
||||
(define-key map "\177" 'forms-prev-record)
|
||||
;(define-key map "\C-c" map)
|
||||
;(define-key map "\e" 'ESC-prefix)
|
||||
;(define-key map "\C-x" ctl-x-map)
|
||||
;(define-key map "\C-u" 'universal-argument)
|
||||
;(define-key map "\C-h" help-map)
|
||||
;; `forms-mode-map' is always accessible via \C-c prefix.
|
||||
(setq forms-mode-map (make-keymap))
|
||||
(define-key forms-mode-map "\t" 'forms-next-field)
|
||||
(define-key forms-mode-map "\C-k" 'forms-delete-record)
|
||||
(define-key forms-mode-map "\C-q" 'forms-toggle-read-only)
|
||||
(define-key forms-mode-map "\C-o" 'forms-insert-record)
|
||||
(define-key forms-mode-map "\C-l" 'forms-jump-record)
|
||||
(define-key forms-mode-map "\C-n" 'forms-next-record)
|
||||
(define-key forms-mode-map "\C-p" 'forms-prev-record)
|
||||
(define-key forms-mode-map "\C-s" 'forms-search)
|
||||
(define-key forms-mode-map "\C-x" 'forms-exit)
|
||||
(define-key forms-mode-map "<" 'forms-first-record)
|
||||
(define-key forms-mode-map ">" 'forms-last-record)
|
||||
(define-key forms-mode-map "?" 'describe-mode)
|
||||
(define-key forms-mode-map "\C-?" 'forms-prev-record)
|
||||
|
||||
;; `forms-mode-ro-map' replaces the local map when in read-only mode.
|
||||
(setq forms-mode-ro-map (make-keymap))
|
||||
(suppress-keymap forms-mode-ro-map)
|
||||
(define-key forms-mode-ro-map "\C-c" forms-mode-map)
|
||||
(define-key forms-mode-ro-map "\t" 'forms-next-field)
|
||||
(define-key forms-mode-ro-map "q" 'forms-toggle-read-only)
|
||||
(define-key forms-mode-ro-map "l" 'forms-jump-record)
|
||||
(define-key forms-mode-ro-map "n" 'forms-next-record)
|
||||
(define-key forms-mode-ro-map "p" 'forms-prev-record)
|
||||
(define-key forms-mode-ro-map "s" 'forms-search)
|
||||
(define-key forms-mode-ro-map "x" 'forms-exit)
|
||||
(define-key forms-mode-ro-map "<" 'forms-first-record)
|
||||
(define-key forms-mode-ro-map ">" 'forms-last-record)
|
||||
(define-key forms-mode-ro-map "?" 'describe-mode)
|
||||
(define-key forms-mode-ro-map " " 'forms-next-record)
|
||||
(forms--mode-commands1 forms-mode-ro-map)
|
||||
|
||||
;; This is the normal, local map.
|
||||
(setq forms-mode-edit-map (make-keymap))
|
||||
(define-key forms-mode-edit-map "\t" 'forms-next-field)
|
||||
(define-key forms-mode-edit-map "\C-c" forms-mode-map)
|
||||
(forms--mode-commands1 forms-mode-edit-map)
|
||||
)
|
||||
|
||||
(defun forms--mode-commands1 (map)
|
||||
"Helper routine to define keys."
|
||||
(define-key map [TAB] 'forms-next-field)
|
||||
(define-key map [S-tab] 'forms-prev-field)
|
||||
(define-key map [next] 'forms-next-record)
|
||||
(define-key map [prior] 'forms-prev-record)
|
||||
(define-key map [begin] 'forms-first-record)
|
||||
(define-key map [last] 'forms-last-record)
|
||||
(define-key map [backtab] 'forms-prev-field)
|
||||
)
|
||||
|
||||
;;; Changed functions
|
||||
|
|
@ -1118,6 +1166,7 @@ Commands (prefix with C-c if not in read-only mode):
|
|||
(current-global-map))))
|
||||
;;
|
||||
;; save-buffer -> forms--save-buffer
|
||||
(make-local-variable 'local-write-file-hooks)
|
||||
(add-hook 'local-write-file-hooks
|
||||
(function
|
||||
(lambda (nil)
|
||||
|
|
@ -1125,22 +1174,27 @@ Commands (prefix with C-c if not in read-only mode):
|
|||
(save-excursion
|
||||
(set-buffer forms--file-buffer)
|
||||
(save-buffer))
|
||||
t))))
|
||||
t)))
|
||||
;; We have our own revert function - use it
|
||||
(make-local-variable 'revert-buffer-function)
|
||||
(setq revert-buffer-function 'forms-revert-buffer)
|
||||
|
||||
t)
|
||||
|
||||
(defun forms--help ()
|
||||
"Initial help for Forms mode."
|
||||
;; We should use
|
||||
;;(message (substitute-command-keys (concat
|
||||
;;"\\[forms-next-record]:next"
|
||||
;;" \\[forms-prev-record]:prev"
|
||||
;;" \\[forms-first-record]:first"
|
||||
;;" \\[forms-last-record]:last"
|
||||
;;" \\[describe-mode]:help"
|
||||
;;" \\[forms-exit]:exit")))
|
||||
;; but it's too slow ....
|
||||
(if forms-read-only
|
||||
(message "SPC:next DEL:prev <:first >:last ?:help q:exit")
|
||||
(message "C-c n:next C-c p:prev C-c <:first C-c >:last C-c ?:help C-c q:exit")))
|
||||
(message (substitute-command-keys (concat
|
||||
"\\[forms-next-record]:next"
|
||||
" \\[forms-prev-record]:prev"
|
||||
" \\[forms-first-record]:first"
|
||||
" \\[forms-last-record]:last"
|
||||
" \\[describe-mode]:help"))))
|
||||
; but it's too slow ....
|
||||
; (if forms-read-only
|
||||
; (message "SPC:next DEL:prev <:first >:last ?:help q:exit")
|
||||
; (message "C-c n:next C-c p:prev C-c <:first C-c >:last C-c ?:help C-c q:exit"))
|
||||
; )
|
||||
|
||||
(defun forms--trans (subj arg rep)
|
||||
"Translate in SUBJ all chars ARG into char REP. ARG and REP should
|
||||
|
|
@ -1217,7 +1271,7 @@ Commands (prefix with C-c if not in read-only mode):
|
|||
(if (= (length forms--the-record-list) forms-number-of-fields)
|
||||
nil
|
||||
(beep)
|
||||
(message "Record has %d fields instead of %d."
|
||||
(message "Warning: this record has %d fields instead of %d"
|
||||
(length forms--the-record-list) forms-number-of-fields)
|
||||
(if (< (length forms--the-record-list) forms-number-of-fields)
|
||||
(setq forms--the-record-list
|
||||
|
|
@ -1256,11 +1310,11 @@ Commands (prefix with C-c if not in read-only mode):
|
|||
(let ((forms--dynamic-text forms--dynamic-text))
|
||||
(funcall forms--parser))
|
||||
|
||||
(if forms--modified-record-filter
|
||||
(if forms-modified-record-filter
|
||||
;; As a service to the user, we add a zeroth element so she
|
||||
;; can use the same indices as in the forms definition.
|
||||
(let ((the-fields (vconcat [nil] forms--recordv)))
|
||||
(setq the-fields (funcall forms--modified-record-filter the-fields))
|
||||
(setq the-fields (funcall forms-modified-record-filter the-fields))
|
||||
(cdr (append the-fields nil)))
|
||||
|
||||
;; Transform to a list and return.
|
||||
|
|
@ -1392,7 +1446,7 @@ As a side effect: sets `forms--the-record-list'."
|
|||
(progn
|
||||
(setq forms--current-record cur)
|
||||
(beep)
|
||||
(message "Stuck at record %d." cur))))))
|
||||
(message "Stuck at record %d" cur))))))
|
||||
|
||||
(defun forms-first-record ()
|
||||
"Jump to first record."
|
||||
|
|
@ -1412,34 +1466,43 @@ As a side effect: re-calculates the number of records in the data file."
|
|||
nil
|
||||
(beep)
|
||||
(setq forms--total-records numrec)
|
||||
(message "Number of records reset to %d." forms--total-records)))
|
||||
(message "Warning: number of records changed to %d" forms--total-records)))
|
||||
(forms-jump-record forms--total-records))
|
||||
|
||||
;;; Other commands
|
||||
|
||||
(defun forms-view-mode ()
|
||||
"Visit buffer read-only."
|
||||
(interactive)
|
||||
(if forms-read-only
|
||||
nil
|
||||
(forms--checkmod) ; sync
|
||||
(setq forms-read-only t)
|
||||
(forms-mode)))
|
||||
(defun forms-toggle-read-only (arg)
|
||||
"Toggles read-only mode of a forms mode buffer.
|
||||
With an argument, enables read-only mode if the argument is positive.
|
||||
Otherwise enables edit mode if the visited file is writeable."
|
||||
|
||||
(defun forms-edit-mode ()
|
||||
"Make form suitable for editing, if possible."
|
||||
(interactive)
|
||||
(let ((ro forms-read-only))
|
||||
(if (save-excursion
|
||||
(set-buffer forms--file-buffer)
|
||||
buffer-read-only)
|
||||
(progn
|
||||
(setq forms-read-only t)
|
||||
(message "No write access to \"%s\"" forms-file)
|
||||
(beep))
|
||||
(setq forms-read-only nil))
|
||||
(if (equal ro forms-read-only)
|
||||
(interactive "P")
|
||||
|
||||
(if (if arg
|
||||
;; Negative arg means switch it off.
|
||||
(<= (prefix-numeric-value arg) 0)
|
||||
;; No arg means toggle.
|
||||
forms-read-only)
|
||||
|
||||
;; Enable edit mode, if possible.
|
||||
(let ((ro forms-read-only))
|
||||
(if (save-excursion
|
||||
(set-buffer forms--file-buffer)
|
||||
buffer-read-only)
|
||||
(progn
|
||||
(setq forms-read-only t)
|
||||
(message "No write access to \"%s\"" forms-file)
|
||||
(beep))
|
||||
(setq forms-read-only nil))
|
||||
(if (equal ro forms-read-only)
|
||||
nil
|
||||
(forms-mode)))
|
||||
|
||||
;; Enable view mode.
|
||||
(if forms-read-only
|
||||
nil
|
||||
(forms--checkmod) ; sync
|
||||
(setq forms-read-only t)
|
||||
(forms-mode))))
|
||||
|
||||
;; Sample:
|
||||
|
|
@ -1453,22 +1516,23 @@ As a side effect: re-calculates the number of records in the data file."
|
|||
(defun forms-insert-record (arg)
|
||||
"Create a new record before the current one.
|
||||
With ARG: store the record after the current one.
|
||||
If a function `forms-new-record-filter' is defined, or
|
||||
`forms-new-record-filter' contains the name of a function,
|
||||
If `forms-new-record-filter' contains the name of a function,
|
||||
it is called to fill (some of) the fields with default values."
|
||||
; The above doc is not true, but for documentary purposes only
|
||||
|
||||
(interactive "P")
|
||||
|
||||
(if forms-read-only
|
||||
(error ""))
|
||||
|
||||
(let ((ln (if arg (1+ forms--current-record) forms--current-record))
|
||||
the-list the-record)
|
||||
|
||||
(forms--checkmod)
|
||||
(if forms--new-record-filter
|
||||
(if forms-new-record-filter
|
||||
;; As a service to the user, we add a zeroth element so she
|
||||
;; can use the same indices as in the forms definition.
|
||||
(let ((the-fields (make-vector (1+ forms-number-of-fields) "")))
|
||||
(setq the-fields (funcall forms--new-record-filter the-fields))
|
||||
(setq the-fields (funcall forms-new-record-filter the-fields))
|
||||
(setq the-list (cdr (append the-fields nil))))
|
||||
(setq the-list (make-list forms-number-of-fields "")))
|
||||
|
||||
|
|
@ -1493,6 +1557,10 @@ it is called to fill (some of) the fields with default values."
|
|||
(defun forms-delete-record (arg)
|
||||
"Deletes a record. With a prefix argument: don't ask."
|
||||
(interactive "P")
|
||||
|
||||
(if forms-read-only
|
||||
(error ""))
|
||||
|
||||
(forms--checkmod)
|
||||
(if (or arg
|
||||
(y-or-n-p "Really delete this record? "))
|
||||
|
|
@ -1577,6 +1645,31 @@ it is called to fill (some of) the fields with default values."
|
|||
nil
|
||||
(goto-char (aref forms--markers 0)))))
|
||||
|
||||
(defun forms-prev-field (arg)
|
||||
"Jump to ARG-th previous field."
|
||||
(interactive "p")
|
||||
|
||||
(let ((i (length forms--markers))
|
||||
(here (point))
|
||||
there
|
||||
(cnt 0))
|
||||
|
||||
(if (zerop arg)
|
||||
(setq cnt 1)
|
||||
(setq cnt (+ cnt arg)))
|
||||
|
||||
(if (catch 'done
|
||||
(while (> i 0)
|
||||
(setq i ( 1- i))
|
||||
(if (or (null (setq there (aref forms--markers i)))
|
||||
(>= there here))
|
||||
nil
|
||||
(if (<= (setq cnt (1- cnt)) 0)
|
||||
(progn
|
||||
(goto-char there)
|
||||
(throw 'done t))))))
|
||||
nil
|
||||
(goto-char (aref forms--markers (1- (length forms--markers)))))))
|
||||
;;;
|
||||
;;; Special service
|
||||
;;;
|
||||
|
|
@ -1627,3 +1720,4 @@ Usage: (setq forms-number-of-fields
|
|||
(insert ret)))))
|
||||
|
||||
;;; forms.el ends here.
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue